Skip to content

Commit 1c21160

Browse files
author
tthomps
committed
Continue expanding Start Menu implementation.
Commit missing GUI_PopupMenu files.
1 parent 9c6f11d commit 1c21160

File tree

6 files changed

+230
-1
lines changed

6 files changed

+230
-1
lines changed

MyOS_GUI_Shell/GUI_Object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const SDL_Color SDL_DARKGRAY = { 40, 40, 40, 255 };
2222
const uint32_t RGB_BLACK = 0x000000;
2323
const SDL_Color SDL_WHITE = { 255, 255, 255, 255 };
2424
const SDL_Color SDL_DEFAULT_BUTTON_COLOR = { 200, 200, 200, 255 };
25+
const SDL_Color SDL_SYS_MENU_COLOR = { SYSTEM_MENU_COLOR_R, SYSTEM_MENU_COLOR_G, SYSTEM_MENU_COLOR_B, 255 };
2526

2627
class GUI_Object
2728
{

MyOS_GUI_Shell/GUI_PopupMenu.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#include "GUI_PopupMenu.h"
2+
#include "GUI_Window.h"
3+
#include "SDL_picofont.h"
4+
#include "MyOS_GUI_Shell.h"
5+
#include <string.h>
6+
7+
GUI_PopupMenu::GUI_PopupMenu(GUI_Window *pOwner, MENU_HANDLER menuHandler, POPUP_TYPE popupType) : GUI_Control(pOwner, -1)
8+
{
9+
choices = 0;
10+
handlerCallback = menuHandler;
11+
shown = false;
12+
this->popupType = popupType;
13+
pSurface = NULL;
14+
}
15+
16+
GUI_PopupMenu::~GUI_PopupMenu()
17+
{
18+
}
19+
20+
void GUI_PopupMenu::AddMenuItem(char * choiceText, int choiceID)
21+
{
22+
choiceIDs[choices] = choiceID;
23+
memset(choiceStrings[choices], 0, MENU_MAX_CHOICE_LENGTH);
24+
strncpy(choiceStrings[choices++], choiceText, MENU_MAX_CHOICE_LENGTH - 1);
25+
26+
CreateSurface();
27+
}
28+
29+
void GUI_PopupMenu::CreateSurface()
30+
{
31+
if (pSurface)
32+
{
33+
SDL_FreeSurface;
34+
pSurface = NULL;
35+
}
36+
37+
// determine maximum width of menu
38+
int maxChoiceLength = 1;
39+
for (int i = 0; i < choices; ++i)
40+
{
41+
if (strlen(choiceStrings[i]) > maxChoiceLength)
42+
maxChoiceLength = strlen(choiceStrings[i]);
43+
}
44+
45+
int menuWidth = (maxChoiceLength * FNT_FONTWIDTH) + (2 * FNT_LEFTRIGHTMARGIN);
46+
choiceHeight = FNT_FONTHEIGHT;
47+
int menuHeight = (choices * choiceHeight) + ((choices - 1) * FNT_ROWSPACING) + (2 * FNT_TOPBOTTOMMARGIN);
48+
49+
pSurface = SDL_CreateRGBSurface(0,
50+
menuWidth,
51+
menuHeight,
52+
32,
53+
0xFF000000,
54+
0x00FF0000,
55+
0x0000FF00,
56+
0x000000FF);
57+
58+
dimensions.width = menuWidth;
59+
dimensions.height = menuHeight;
60+
61+
Draw(-1);
62+
}
63+
64+
void GUI_PopupMenu::Draw(int selectedChoice)
65+
{
66+
// Fill the surface with the default color
67+
FillSurface(pSurface, SDL_DEFAULT_BUTTON_COLOR);
68+
69+
// Draw the choices to the surface
70+
SDL_Rect textDest = { FNT_LEFTRIGHTMARGIN, FNT_TOPBOTTOMMARGIN, 0, 0 };
71+
72+
int selectionY = FNT_TOPBOTTOMMARGIN;
73+
74+
for (int i = 0; i < choices; ++i)
75+
{
76+
SDL_Surface *pFont;
77+
78+
if (i == selectedChoice)
79+
{
80+
// Draw a box for the selection
81+
SDL_Rect selectedDim = { 1, selectionY, dimensions.width - 3, choiceHeight };
82+
SDL_FillRect(pSurface, &selectedDim, SDL_MapRGB(pSurface->format,
83+
SDL_SYS_MENU_COLOR.r,
84+
SDL_SYS_MENU_COLOR.g,
85+
SDL_SYS_MENU_COLOR.b));
86+
// Draw the text in white
87+
pFont = FNT_Render(choiceStrings[i], SDL_WHITE);
88+
}
89+
else
90+
{
91+
pFont = FNT_Render(choiceStrings[i], SDL_BLACK);
92+
selectionY += choiceHeight + FNT_ROWSPACING;
93+
}
94+
95+
textDest.w = pFont->w;
96+
textDest.h = pFont->h;
97+
98+
SDL_BlitSurface(pFont, NULL, pSurface, &textDest);
99+
100+
textDest.y += choiceHeight + FNT_ROWSPACING;
101+
102+
SDL_FreeSurface(pFont);
103+
}
104+
105+
// Draw a border around the menu
106+
Draw3D_Box(pSurface, 0, 0, dimensions.width, dimensions.height);
107+
}
108+
109+
bool GUI_PopupMenu::MouseOver(int relX, int relY)
110+
{
111+
if (relX < 0 || relY < 0 || relX > dimensions.width || relY > dimensions.height)
112+
{
113+
MessageBox("Menu called with mouse out of position\n", "ERROR");
114+
return false;
115+
}
116+
117+
// Highlight the appropriate option
118+
int heightPerOption = dimensions.height / choices;
119+
int selection = relY / heightPerOption;
120+
121+
Draw(selection);
122+
123+
return true;
124+
}
125+
126+
void GUI_PopupMenu::PaintToSurface(SDL_Surface * pTargetSurface)
127+
{
128+
if (!shown)
129+
return;
130+
131+
SDL_BlitSurface(pSurface, NULL, pTargetSurface, dimensions.GetSDL_Rect());
132+
}
133+
134+
void GUI_PopupMenu::RegisterMenuHandler(MENU_HANDLER handler)
135+
{
136+
handlerCallback = handler;
137+
}
138+
139+
void GUI_PopupMenu::ShowMenu(SDL_Point origin)
140+
{
141+
if (!pSurface)
142+
return;
143+
144+
dimensions.left = origin.x;
145+
146+
if (popupType == ABOVE_AND_RIGHT_OF_ORIGIN)
147+
dimensions.top = origin.y - dimensions.height;
148+
149+
shown = true;
150+
}

MyOS_GUI_Shell/GUI_PopupMenu.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
#include "GUI_Control.h"
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif /* __cplusplus */
7+
8+
#define MENU_MAX_CHOICES 16
9+
#define MENU_MAX_CHOICE_LENGTH 32
10+
11+
typedef enum POPUP_TYPE
12+
{
13+
ABOVE_AND_RIGHT_OF_ORIGIN = 0
14+
}POPUP_TYPE;
15+
16+
typedef void(*MENU_HANDLER)(int choiceID);
17+
18+
class GUI_PopupMenu :
19+
public GUI_Control
20+
{
21+
public:
22+
GUI_PopupMenu(GUI_Window *pOwner, MENU_HANDLER menuHandler, POPUP_TYPE popupType);
23+
~GUI_PopupMenu();
24+
25+
void AddMenuItem(char *Choice, int choiceID);
26+
void CreateSurface();
27+
void Draw(int selectedChoice);
28+
bool MouseOver(int relX, int relY);
29+
void PaintToSurface(SDL_Surface *pTargetSurface);
30+
void RegisterMenuHandler(MENU_HANDLER handler);
31+
void ShowMenu(SDL_Point origin);
32+
33+
char choiceStrings[MENU_MAX_CHOICES][MENU_MAX_CHOICE_LENGTH];
34+
int choiceIDs[MENU_MAX_CHOICES];
35+
int choices;
36+
MENU_HANDLER handlerCallback;
37+
bool shown;
38+
POPUP_TYPE popupType;
39+
SDL_Surface *pSurface;
40+
41+
protected:
42+
int choiceHeight;
43+
};
44+
45+
46+
#ifdef __cplusplus
47+
}
48+
#endif /* __cplusplus */
49+

MyOS_GUI_Shell/GUI_Taskbar.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ GUI_Taskbar::GUI_Taskbar(uint32_t desktopWidth, uint32_t desktopHeight) :
2828

2929
// Create the start menu
3030
pStartMenu = new GUI_PopupMenu(this, StartMenuHandler, ABOVE_AND_RIGHT_OF_ORIGIN);
31+
32+
pStartMenu->AddMenuItem("Option 1", 1);
33+
pStartMenu->AddMenuItem("Option 2", 2);
3134
pStartMenu->AddMenuItem("Run", 0);
3235

3336
windowButtons = 0;
@@ -156,6 +159,19 @@ void GUI_Taskbar::PaintToSurface(SDL_Surface * pTargetSurface)
156159
pStartMenu->PaintToSurface(pTargetSurface);
157160
}
158161

162+
// TODO: For now we assume the taskbar is always in the same position
163+
/*bool GUI_Taskbar::PointInBounds(int x, int y)
164+
{
165+
if (GUI_Object::PointInBounds(x, y))
166+
return true;
167+
168+
// Check start menu
169+
if (pStartMenu->shown && pStartMenu->PointInBounds(x, y))
170+
return true;
171+
172+
return false;
173+
}*/
174+
159175
void GUI_Taskbar::RemoveWindow(uint32_t windowID)
160176
{
161177
// Find the control ID

MyOS_GUI_Shell/GUI_Taskbar.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ class GUI_Taskbar :
3535
void ControlClicked(uint32_t controlID);
3636
void OnDrag(int startRelX, int startRelY, int relX, int relY);
3737
void PaintToSurface(SDL_Surface *pTargetSurface);
38+
//bool PointInBounds(int x, int y);
3839
void RemoveWindow(uint32_t windowID);
3940
void WindowActivated(uint32_t windowID);
41+
GUI_PopupMenu *pStartMenu;
4042

4143
protected:
4244
int windowButtons;
4345
GUI_TaskbarButton *pActiveWindowButton;
44-
GUI_PopupMenu *pStartMenu;
4546
};
4647

MyOS_GUI_Shell/MyOS_GUI_Shell.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ int main(int argc, char* argv[])
500500
oldMousePos.x = cursorRect.x;
501501
oldMousePos.y = cursorRect.y;
502502
}
503+
else
504+
{
505+
if (pTaskbar->pStartMenu->PointInBounds(cursorRect.x, cursorRect.y))
506+
pTaskbar->pStartMenu->MouseOver(cursorRect.x - pTaskbar->pStartMenu->dimensions.left,
507+
cursorRect.y - pTaskbar->pStartMenu->dimensions.top);
508+
}
503509

504510
break;
505511

@@ -516,6 +522,12 @@ int main(int argc, char* argv[])
516522
pTaskbar->OnClick(cursorRect.x, cursorRect.y - pTaskbar->dimensions.top);
517523
pDraggedWindow = pTaskbar;
518524
}
525+
// What about the start menu?
526+
else if (pTaskbar->pStartMenu->PointInBounds(cursorRect.x, cursorRect.y))
527+
{
528+
pTaskbar->pStartMenu->OnClick(cursorRect.x - pTaskbar->pStartMenu->dimensions.left,
529+
cursorRect.y - pTaskbar->pStartMenu->dimensions.top);
530+
}
519531
else if (pStackEntryUnderCursor)
520532
{
521533
BringWindowToFront(pStackEntryUnderCursor);// ->pWindow->SetBackgroundColor(red);

0 commit comments

Comments
 (0)