From 99e87b81739a1235214af36b703fcdf216b0bf49 Mon Sep 17 00:00:00 2001 From: ariclone <> Date: Sun, 28 May 2000 11:14:31 +0000 Subject: [PATCH] Implemented Pulldown-Selector type menu items More work on the scenario select requested fixed some minor menukey issues --- src/ui/menus.cpp | 277 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 234 insertions(+), 43 deletions(-) diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp index b1dfcc94e..bbbdfbd4c 100644 --- a/src/ui/menus.cpp +++ b/src/ui/menus.cpp @@ -37,6 +37,10 @@ #include "cursor.h" #include "new_video.h" +#ifndef NEW_VIDEO +#error ONLY WORKS WITH NEW VIDEO! +#endif + /*---------------------------------------------------------------------------- -- Prototypes for action handlers ----------------------------------------------------------------------------*/ @@ -57,14 +61,8 @@ local struct { const char* File[PlayerMaxRaces]; /// Width of button int Width, Height; - -#ifdef NEW_VIDEO /// sprite : FILLED Graphic* Sprite; -#else - /// sprite : FILLED - RleSprite* RleSprite; -#endif } MenuButtonGfx = { { "interface/buttons 1.png" ,"interface/buttons 2.png" }, 300, 7632 @@ -84,19 +82,19 @@ local int MenuButtonCurSel = -1; local Menuitem GameMenuItems[] = { { MI_TYPE_TEXT, { text:{ 128, 11, MI_FLAGS_CENTERED, LargeFont, "Game Menu"} } }, { MI_TYPE_BUTTON, { button:{ 16, 40, MenuButtonDisabled, LargeFont, - "Save (~<F11~>)", 106, 27, MBUTTON_GM_HALF, KeyCodeF11, GameMenuSave} } }, + "Save (~<F11~>)", 106, 27, MBUTTON_GM_HALF, GameMenuSave, KeyCodeF11} } }, { MI_TYPE_BUTTON, { button:{ 16 + 12 + 106, 40, MenuButtonDisabled, LargeFont, - "Load (~<F12~>)", 106, 27, MBUTTON_GM_HALF, KeyCodeF12, NULL} } }, + "Load (~<F12~>)", 106, 27, MBUTTON_GM_HALF, NULL, KeyCodeF12} } }, { MI_TYPE_BUTTON, { button:{ 16, 40 + 36, MenuButtonDisabled, LargeFont, - "Options (~<F5~>)", 224, 27, MBUTTON_GM_FULL, KeyCodeF5, NULL} } }, + "Options (~<F5~>)", 224, 27, MBUTTON_GM_FULL, NULL, KeyCodeF5} } }, { MI_TYPE_BUTTON, { button:{ 16, 40 + 36 + 36, MenuButtonDisabled, LargeFont, - "Help (~<F1~>)", 224, 27, MBUTTON_GM_FULL, KeyCodeF1, NULL} } }, + "Help (~<F1~>)", 224, 27, MBUTTON_GM_FULL, NULL, KeyCodeF1} } }, { MI_TYPE_BUTTON, { button:{ 16, 40 + 36 + 36 + 36, MenuButtonDisabled, LargeFont, - "Scenario ~!Objectives", 224, 27, MBUTTON_GM_FULL, 'o', NULL} } }, + "Scenario ~!Objectives", 224, 27, MBUTTON_GM_FULL, NULL, 'o'} } }, { MI_TYPE_BUTTON, { button:{ 16, 40 + 36 + 36 + 36 + 36, 0, LargeFont, - "~!End Scenario", 224, 27, MBUTTON_GM_FULL, 'e', GameMenuEnd} } }, + "~!End Scenario", 224, 27, MBUTTON_GM_FULL, GameMenuEnd, 'e'} } }, { MI_TYPE_BUTTON, { button:{ 16, 288-40, MenuButtonSelected, LargeFont, - "Return to Game (~<Esc~>)", 224, 27, MBUTTON_GM_FULL, '\033', GameMenuReturn} } }, + "Return to Game (~<Esc~>)", 224, 27, MBUTTON_GM_FULL, GameMenuReturn, '\033'} } }, }; /** @@ -106,9 +104,9 @@ local Menuitem VictoryMenuItems[] = { { MI_TYPE_TEXT, { text:{ 144, 11, MI_FLAGS_CENTERED, LargeFont, "Congratulations!"} } }, { MI_TYPE_TEXT, { text:{ 144, 32, MI_FLAGS_CENTERED, LargeFont, "You are victorious!"} } }, { MI_TYPE_BUTTON, { button:{ 32, 90, MenuButtonSelected, LargeFont, - "~!Victory", 106, 27, MBUTTON_GM_FULL, 'v', GameMenuEnd} } }, + "~!Victory", 224, 27, MBUTTON_GM_FULL, GameMenuEnd, 'v'} } }, { MI_TYPE_BUTTON, { button:{ 32, 56, MenuButtonDisabled, LargeFont, - "Save Game (~<F11~>)", 224, 27, MBUTTON_GM_FULL, KeyCodeF11, NULL} } }, + "Save Game (~<F11~>)", 224, 27, MBUTTON_GM_FULL, NULL, KeyCodeF11} } }, }; /** @@ -118,18 +116,37 @@ local Menuitem LostMenuItems[] = { { MI_TYPE_TEXT, { text:{ 144, 11, MI_FLAGS_CENTERED, LargeFont, "You failed to"} } }, { MI_TYPE_TEXT, { text:{ 144, 32, MI_FLAGS_CENTERED, LargeFont, "achieve victory!"} } }, { MI_TYPE_BUTTON, { button:{ 32, 90, MenuButtonSelected, LargeFont, - "~!OK", 106, 27, MBUTTON_GM_FULL, 'o', GameMenuEnd} } }, + "~!OK", 224, 27, MBUTTON_GM_FULL, GameMenuEnd, 'o'} } }, }; /** -** Items for the SelectScen Menu - (WIP) +** Items for the SelectScen Menu */ +local unsigned char *ssmtoptions[] = { + "Built-in scenario", + "Custom scenario" +}; + +local unsigned char *ssmsoptions[] = { + "Any size", + "32 x 32", + "64 x 64", + "96 x 96", + "128 x 128", +}; + local Menuitem SelectScenMenuItems[] = { { MI_TYPE_TEXT, { text:{ 176, 8, MI_FLAGS_CENTERED, LargeFont, "Select scenario"} } }, + { MI_TYPE_TEXT, { text:{ 132, 40, MI_FLAGS_RALIGN, LargeFont, "Type:"} } }, + { MI_TYPE_PULLDOWN, { pulldown:{ 140, 40, 0, GameFont, ssmtoptions, + 192, 20, MBUTTON_PULLDOWN, NULL, 2, 1, 1, 0} } }, + { MI_TYPE_TEXT, { text:{ 132, 80, MI_FLAGS_RALIGN, LargeFont, "Map size:"} } }, + { MI_TYPE_PULLDOWN, { pulldown:{ 140, 80, 0, GameFont, ssmsoptions, + 192, 20, MBUTTON_PULLDOWN, NULL, 5, 0, 0, 0} } }, { MI_TYPE_BUTTON, { button:{ 48, 318, MenuButtonSelected, LargeFont, - "OK", 106, 27, MBUTTON_GM_HALF, 0, NULL} } }, + "OK", 106, 27, MBUTTON_GM_HALF, NULL, 0} } }, { MI_TYPE_BUTTON, { button:{ 198, 318, 0, LargeFont, - "Cancel", 106, 27, MBUTTON_GM_HALF, 0, NULL} } }, + "Cancel", 106, 27, MBUTTON_GM_HALF, NULL, 0} } }, }; /** @@ -169,7 +186,7 @@ global Menu Menus[] = { (480-352)/2, 352, 352, ImagePanel5, - 1, 3, + 5, 7, SelectScenMenuItems }, }; @@ -212,11 +229,7 @@ global void DrawMenuButton(MenuButtonId button,unsigned flags,unsigned w,unsigne SetDefaultTextColors(rc,rc); } } -#ifdef NEW_VIDEO VideoDraw(MenuButtonGfx.Sprite, rb, x, y); -#else - DrawRleSprite(MenuButtonGfx.RleSprite, rb, x, y); -#endif if (text) { DrawTextCentered(s+x+w/2,s+y+(font == GameFont ? 4 : 7),font,text); } @@ -227,6 +240,73 @@ global void DrawMenuButton(MenuButtonId button,unsigned flags,unsigned w,unsigne SetDefaultTextColors(nc,rc); } +/** +** Draw pulldown 'button' on menu mx, my +** +** @param mi menuitem pointer +** @param mx menu X display position (offset) +** @param my menu Y display position (offset) +*/ +local void DrawPulldown(Menuitem *mi, unsigned mx, unsigned my) +{ + int i, nc, rc; + char *text; + MenuButtonId rb = mi->d.pulldown.button; + unsigned flags = mi->d.pulldown.flags; + unsigned w, h, x, y, oh; + w = mi->d.pulldown.xsize; + x = mx+mi->d.pulldown.xofs; + y = my+mi->d.pulldown.yofs; + oh = h = mi->d.pulldown.ysize - 2; + + GetDefaultTextColors(&nc, &rc); + if (flags&MenuButtonClicked) { + y -= mi->d.pulldown.curopt * h; + i = mi->d.pulldown.noptions; + h *= i; + while (i--) { + PushClipping(); + SetClipping(0,0,x+w,VideoHeight); + VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1 + oh*i); + PopClipping(); + text = mi->d.pulldown.options[i]; + if (text) { + if (i == mi->d.pulldown.cursel) + SetDefaultTextColors(rc,rc); + else + SetDefaultTextColors(nc,rc); + DrawText(x+2,y+2 + oh*i ,mi->d.pulldown.font,text); + } + } + w += 2; + } else { + h = mi->d.pulldown.ysize; + y = my+mi->d.pulldown.yofs; + if (flags&MenuButtonDisabled) { + rb--; + SetDefaultTextColors(FontGrey,FontGrey); + } else { + if (flags&MenuButtonActive) { + SetDefaultTextColors(rc,rc); + } + } + + PushClipping(); + SetClipping(0,0,x+w-20,VideoHeight); + VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1); + PopClipping(); + VideoDraw(MenuButtonGfx.Sprite, MBUTTON_DOWN_ARROW + rb - MBUTTON_PULLDOWN, x-1 + w-20, y-2); + text = mi->d.pulldown.options[mi->d.pulldown.curopt]; + if (text) { + DrawText(x+2,y+2,mi->d.pulldown.font,text); + } + } + if (flags&MenuButtonSelected) { + VideoDrawRectangle(ColorYellow,x-2,y-2,w,h); + /// FIXME: use ColorGrey if selected button is disabled! + } + SetDefaultTextColors(nc,rc); +} /** ** Draw menu 'menu' @@ -235,7 +315,7 @@ global void DrawMenuButton(MenuButtonId button,unsigned flags,unsigned w,unsigne */ global void DrawMenu(int MenuId) { - int i, n; + int i, n, l; Menu *menu; Menuitem *mi; @@ -254,7 +334,11 @@ global void DrawMenu(int MenuId) if (mi->d.text.flags&MI_FLAGS_CENTERED) DrawTextCentered(menu->x+mi->d.text.xofs,menu->y+mi->d.text.yofs, mi->d.text.font,mi->d.text.text); - else + else if (mi->d.text.flags&MI_FLAGS_RALIGN) { + l = TextLength(mi->d.text.font,mi->d.text.text); + DrawText(menu->x+mi->d.text.xofs-l,menu->y+mi->d.text.yofs, + mi->d.text.font,mi->d.text.text); + } else DrawText(menu->x+mi->d.text.xofs,menu->y+mi->d.text.yofs, mi->d.text.font,mi->d.text.text); break; @@ -264,6 +348,9 @@ global void DrawMenu(int MenuId) menu->x+mi->d.button.xofs,menu->y+mi->d.button.yofs, mi->d.button.font,mi->d.button.text); break; + case MI_TYPE_PULLDOWN: + DrawPulldown(mi,menu->x,menu->y); + break; default: break; } @@ -341,8 +428,28 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ } } break; - case 9: /// TAB // FIXME: Add Shift-TAB + case KeyCodeUp: case KeyCodeDown: if (MenuButtonCurSel != -1) { + mi = menu->items + MenuButtonCurSel; + if (mi->mitype == MI_TYPE_PULLDOWN && !(mi->d.pulldown.flags&MenuButtonClicked)) { + if (key == KeyCodeDown) { + if (mi->d.pulldown.curopt + 1 < mi->d.pulldown.noptions) + mi->d.pulldown.curopt++; + else + break; + } else { + if (mi->d.pulldown.curopt > 0) + mi->d.pulldown.curopt--; + else + break; + } + MustRedraw |= RedrawMenu; + // FIXME: DISPLAY-ACTION HERE ..... + } + } + break; + case 9: /// TAB // FIXME: Add Shift-TAB + if (MenuButtonCurSel != -1 && !(menu->items[MenuButtonCurSel].d.button.flags&MenuButtonClicked)) { n = menu->nitems; for (i = 0; i < n; ++i) { mi = menu->items + ((MenuButtonCurSel + i + 1) % n); @@ -358,13 +465,23 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ MenuButtonCurSel = mi - menu->items; MustRedraw |= RedrawMenu; return 1; + case MI_TYPE_PULLDOWN: + if (mi->d.pulldown.flags & MenuButtonDisabled) { + break; + } + mi->d.pulldown.flags |= MenuButtonSelected; + menu->items[MenuButtonCurSel].d.button.flags &= ~MenuButtonSelected; + // FIXME: maybe different union member, not button! + MenuButtonCurSel = mi - menu->items; + MustRedraw |= RedrawMenu; + return 1; default: break; } } } break; - case 'q': + case 'Q': Exit(0); default: DebugLevel3("Key %d\n",key); @@ -382,7 +499,7 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ */ global void MenuHandleMouseMove(int x,int y) { - int i, n, xs, ys; + int h, i, j, n, xs, ys; Menuitem *mi; Menu *menu = Menus + CurrentMenu; int RedrawFlag = 0; @@ -413,6 +530,42 @@ global void MenuHandleMouseMove(int x,int y) MenuButtonUnderCursor = i; } break; + case MI_TYPE_PULLDOWN: + if (!(mi->d.pulldown.flags&MenuButtonDisabled)) { + xs = menu->x + mi->d.pulldown.xofs; + if (mi->d.pulldown.flags&MenuButtonClicked) { + ys = menu->y + mi->d.pulldown.yofs; + h = mi->d.pulldown.ysize - 2; + ys -= mi->d.pulldown.curopt * h; + if (x<xs || x>xs + mi->d.pulldown.xsize || y<ys || y>ys + h*mi->d.pulldown.noptions) { + continue; + } + j = (y - ys) / h; + if (j != mi->d.pulldown.cursel) { + mi->d.pulldown.cursel = j; + RedrawFlag = 1; + // FIXME: DISPLAY-ACTION HERE ..... + } + } else { + ys = menu->y + mi->d.pulldown.yofs; + if (x<xs || x>xs + mi->d.pulldown.xsize || y<ys || y>ys + mi->d.pulldown.ysize) { + if (!(mi->d.pulldown.flags&MenuButtonClicked)) { + if (mi->d.pulldown.flags&MenuButtonActive) { + RedrawFlag = 1; + mi->d.pulldown.flags &= ~MenuButtonActive; + } + } + continue; + } + } + if (!(mi->d.pulldown.flags&MenuButtonActive)) { + RedrawFlag = 1; + mi->d.pulldown.flags |= MenuButtonActive; + } + DebugLevel3("On menu pulldown %d\n", i); + MenuButtonUnderCursor = i; + } + break; default: break; } @@ -435,12 +588,31 @@ global void MenuHandleButtonDown(int b) if (MouseButtons&LeftButton) { if (MenuButtonUnderCursor != -1) { mi = menu->items + MenuButtonUnderCursor; - if (!(mi->d.button.flags&MenuButtonClicked)) { - if (MenuButtonCurSel != -1) { - menu->items[MenuButtonCurSel].d.button.flags &= ~MenuButtonSelected; - } - mi->d.button.flags |= MenuButtonClicked|MenuButtonSelected; - MustRedraw |= RedrawMenu; + switch (mi->mitype) { + case MI_TYPE_BUTTON: + if (!(mi->d.button.flags&MenuButtonClicked)) { + if (MenuButtonCurSel != -1) { + // FIXME: maybe different union member, not button! + menu->items[MenuButtonCurSel].d.button.flags &= ~MenuButtonSelected; + } + MenuButtonCurSel = MenuButtonUnderCursor; + mi->d.button.flags |= MenuButtonClicked|MenuButtonSelected; + MustRedraw |= RedrawMenu; + } + break; + case MI_TYPE_PULLDOWN: + if (!(mi->d.pulldown.flags&MenuButtonClicked)) { + if (MenuButtonCurSel != -1) { + // FIXME: maybe different union member, not button! + menu->items[MenuButtonCurSel].d.button.flags &= ~MenuButtonSelected; + } + MenuButtonCurSel = MenuButtonUnderCursor; + mi->d.pulldown.flags |= MenuButtonClicked|MenuButtonSelected; + mi->d.pulldown.cursel = mi->d.pulldown.curopt; + MustRedraw |= RedrawMenu; + } + default: + break; } } } @@ -475,6 +647,22 @@ global void MenuHandleButtonUp(int b) } } break; + case MI_TYPE_PULLDOWN: + if (mi->d.pulldown.flags&MenuButtonClicked) { + RedrawFlag = 1; + mi->d.pulldown.flags &= ~MenuButtonClicked; + if (MenuButtonUnderCursor == i) { + MenuButtonUnderCursor = -1; + if (mi->d.pulldown.cursel != mi->d.pulldown.curopt) { + mi->d.pulldown.curopt = mi->d.pulldown.cursel; + if (mi->d.button.handler) { + (*mi->d.button.handler)(); + } + } + } + mi->d.pulldown.cursel = 0; + } + break; default: break; } @@ -517,6 +705,17 @@ global void ProcessMenu(int MenuId, int Loop) } // FIXME: Maybe activate if mouse-pointer is over it right now? break; + case MI_TYPE_PULLDOWN: + mi->d.pulldown.flags &= ~(MenuButtonClicked|MenuButtonActive|MenuButtonSelected); + mi->d.pulldown.cursel = 0; + if (mi->d.pulldown.defopt != -1) + mi->d.pulldown.curopt = mi->d.pulldown.defopt; + if (i == menu->defsel) { + mi->d.pulldown.flags |= MenuButtonSelected; + MenuButtonCurSel = i; + } + // FIXME: Maybe activate if mouse-pointer is over it right now? + break; default: break; } @@ -554,21 +753,13 @@ global void InitMenus(unsigned int race) if (race == last_race) // same race? already loaded! return; if (last_race != -1) { // free previous sprites for different race -#ifdef NEW_VIDEO VideoFree(MenuButtonGfx.Sprite); -#else - FreeRleSprite(MenuButtonGfx.RleSprite); -#endif } last_race = race; file = MenuButtonGfx.File[race]; buf = alloca(strlen(file) + 9 + 1); file = strcat(strcpy(buf, "graphic/"), file); -#ifdef NEW_VIDEO MenuButtonGfx.Sprite = LoadSprite(file, 0, 144); -#else - MenuButtonGfx.RleSprite = LoadRleSprite(file, 0, 144); -#endif } //@}