2 // Menu class & supporting structs/classes
10 static const char separator[] = "--------------------------------------------------------";
14 Menu::Menu(uint32 x/*= 0*/, uint32 y/*= 0*/, uint32 w/*= 0*/, uint32 h/*= FONT_HEIGHT*/,
15 uint32 fgc/*= 0xFF7F0000*/, uint32 bgc/*= 0xFFFF3F3F*/, uint32 fgch/*= 0xFFFF3F3F*/,
16 uint32 bgch/*= 0xFFFF8787*/):
17 Element(x, y, w, h), activated(false), clicked(false), inside(0), insidePopup(0),
18 fgColor(fgc), bgColor(bgc), fgColorHL(fgch), bgColorHL(bgch), menuChosen(-1),
23 void Menu::HandleKey(SDLKey key)
25 for(uint32 i=0; i<itemList.size(); i++)
27 for(uint32 j=0; j<itemList[i].item.size(); j++)
29 if (itemList[i].item[j].hotKey == key)
32 event.type = SDL_USEREVENT;
33 event.user.code = MENU_ITEM_CHOSEN;
34 event.user.data1 = (void *)itemList[i].item[j].action;
35 SDL_PushEvent(&event);
37 clicked = false, menuChosen = menuItemChosen = -1;
44 void Menu::HandleMouseMove(uint32 x, uint32 y)
46 inside = insidePopup = 0;
50 // Find out *where* we are inside the menu bar
51 uint32 xpos = extents.x;
53 for(uint32 i=0; i<itemList.size(); i++)
55 uint32 width = (itemList[i].title.length() + 2) * FONT_WIDTH;
57 if (x >= xpos && x < xpos + width)
68 if (!Inside(x, y) && !clicked)
73 if (itemList[menuChosen].Inside(x, y) && clicked)
75 insidePopup = ((y - itemList[menuChosen].extents.y) / FONT_HEIGHT) + 1;
76 menuItemChosen = insidePopup - 1;
80 void Menu::HandleMouseButton(uint32 x, uint32 y, bool mouseDown)
89 menuChosen = -1; // clicked is already false...!
92 else // clicked == true
94 if (insidePopup && !mouseDown) // I.e., mouse-button-up
97 if (itemList[menuChosen].item[menuItemChosen].action != NULL)
99 // itemList[menuChosen].item[menuItemChosen].action();
101 event.type = SDL_USEREVENT;
102 event.user.code = MENU_ITEM_CHOSEN;
103 event.user.data1 = (void *)itemList[menuChosen].item[menuItemChosen].action;
104 SDL_PushEvent(&event);
106 clicked = false, menuChosen = menuItemChosen = -1;
109 while (SDL_PollEvent(&event)); // Flush the event queue...
110 event.type = SDL_MOUSEMOTION;
112 SDL_GetMouseState(&mx, &my);
113 event.motion.x = mx, event.motion.y = my;
114 SDL_PushEvent(&event); // & update mouse position...!
118 if (!inside && !insidePopup && mouseDown)
119 clicked = false, menuChosen = menuItemChosen = -1;
123 void Menu::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/)
125 uint32 xpos = extents.x + offsetX;
127 for(uint32 i=0; i<itemList.size(); i++)
129 // uint16 color1 = fgColor, color2 = bgColor;
130 uint32 color1 = fgColor, color2 = bgColor;
131 if (inside == (i + 1) || (menuChosen != -1 && (uint32)menuChosen == i))
132 color1 = fgColorHL, color2 = bgColorHL;
134 DrawStringOpaque(screenBuffer, xpos, extents.y + offsetY, color1, color2,
135 " %s ", itemList[i].title.c_str());
136 xpos += (itemList[i].title.length() + 2) * FONT_WIDTH;
139 // Draw sub menu (but only if active)
142 uint32 ypos = extents.y + FONT_HEIGHT + 1;
144 for(uint32 i=0; i<itemList[menuChosen].item.size(); i++)
146 // uint16 color1 = fgColor, color2 = bgColor;
147 uint32 color1 = fgColor, color2 = bgColor;
149 if (insidePopup == i + 1)
150 color1 = fgColorHL, color2 = bgColorHL, menuItemChosen = i;
152 if (itemList[menuChosen].item[i].name.length() > 0)
153 DrawStringOpaque(screenBuffer, itemList[menuChosen].extents.x, ypos,
154 color1, color2, " %-*.*s ", itemList[menuChosen].charLength,
155 itemList[menuChosen].charLength, itemList[menuChosen].item[i].name.c_str());
157 DrawStringOpaque(screenBuffer, itemList[menuChosen].extents.x, ypos,
158 fgColor, bgColor, "%.*s", itemList[menuChosen].charLength + 2, separator);
165 void Menu::Add(MenuItems mi)
167 for(uint32 i=0; i<mi.item.size(); i++)
168 if (mi.item[i].name.length() > mi.charLength)
169 mi.charLength = mi.item[i].name.length();
171 // Set extents here as well...
172 mi.extents.x = extents.x + extents.w, mi.extents.y = extents.y + FONT_HEIGHT + 1;
173 mi.extents.w = (mi.charLength + 2) * FONT_WIDTH, mi.extents.h = mi.item.size() * FONT_HEIGHT;
175 itemList.push_back(mi);
176 extents.w += (mi.title.length() + 2) * FONT_WIDTH;