diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 2fd4f79f1..25517255d 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.5: +- Refactored setupmenu code to use generic widgets - Michael - Support UTF-8 chars in mineral names (bug #770) - SvdB - Modified scalers to use surface pitch instead of width - reported to fix bug #740 - Michael diff --git a/sc2/src/sc2code/libs/graphics/widgets.c b/sc2/src/sc2code/libs/graphics/widgets.c index 26fbc499a..46325096a 100644 --- a/sc2/src/sc2code/libs/graphics/widgets.c +++ b/sc2/src/sc2code/libs/graphics/widgets.c @@ -1,5 +1,9 @@ #include "graphics/gfx_common.h" #include "graphics/widgets.h" +#include "setup.h" +#include "units.h" + +WIDGET *widget_focus = NULL; void DrawShadowedBox(PRECT r, COLOR bg, COLOR dark, COLOR medium) @@ -39,3 +43,341 @@ DrawShadowedBox(PRECT r, COLOR bg, COLOR dark, COLOR medium) SetContextForeGroundColor (oldcolor); UnbatchGraphics (); } + +static void +Widget_DrawToolTips (int numlines, const char **tips) +{ + RECT r; + FONT oldfont = SetContextFont (StarConFont); + FONTEFFECT oldFontEffect = SetContextFontEffect (0, 0, 0); + COLOR oldtext = SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); + TEXT t; + int i; + + r.corner.x = 2; + r.corner.y = 2; + r.extent.width = SCREEN_WIDTH - 4; + r.extent.height = SCREEN_HEIGHT - 4; + + t.align = ALIGN_CENTER; + t.valign = VALIGN_BOTTOM; + t.baseline.x = r.corner.x + (r.extent.width >> 1); + t.baseline.y = r.corner.y + (r.extent.height - 8 - 8 * numlines); + + for (i = 0; i < numlines; i++) + { + t.pStr = tips[i]; + font_DrawText(&t); + t.baseline.y += 8; + } + + SetContextFontEffect (oldFontEffect.type, oldFontEffect.from, oldFontEffect.to); + SetContextFont (oldfont); + SetContextForeGroundColor (oldtext); +} + +void +Widget_DrawMenuScreen (WIDGET *_self, int x, int y) +{ + RECT r; + COLOR title, oldtext; + COLOR inactive, default_color, selected; + FONT oldfont = SetContextFont (StarConFont); + FONTEFFECT oldFontEffect = SetContextFontEffect (0, 0, 0); + TEXT t; + int widget_index, height, widget_y; + + WIDGET_MENU_SCREEN *self = (WIDGET_MENU_SCREEN *)_self; + + r.corner.x = 2; + r.corner.y = 2; + r.extent.width = SCREEN_WIDTH - 4; + r.extent.height = SCREEN_HEIGHT - 4; + + title = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F); + selected = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x00), 0x0E); + inactive = BUILD_COLOR (MAKE_RGB15 (0x18, 0x18, 0x1F), 0x07); + default_color = title; + + DrawStamp (&self->bgStamp); + + oldtext = SetContextForeGroundColor (title); + t.baseline.x = r.corner.x + (r.extent.width >> 1); + t.baseline.y = r.corner.y + 8; + t.pStr = self->title; + t.align = ALIGN_CENTER; + t.valign = VALIGN_BOTTOM; + t.CharCount = ~0; + font_DrawText (&t); + t.baseline.y += 8; + t.pStr = self->subtitle; + font_DrawText (&t); + + height = 0; + for (widget_index = 0; widget_index < self->num_children; widget_index++) + { + WIDGET *child = self->child[widget_index]; + height += (*child->height)(child); + height += 8; /* spacing */ + } + + height -= 8; + + widget_y = (SCREEN_HEIGHT - height) >> 1; + for (widget_index = 0; widget_index < self->num_children; widget_index++) + { + WIDGET *c = self->child[widget_index]; + (*c->draw)(c, 0, widget_y); + widget_y += (*c->height)(c) + 8; + } + + SetContextFontEffect (oldFontEffect.type, oldFontEffect.from, oldFontEffect.to); + SetContextFont (oldfont); + SetContextForeGroundColor (oldtext); +} + +void +Widget_DrawChoice (WIDGET *_self, int x, int y) +{ + WIDGET_CHOICE *self = (WIDGET_CHOICE *)_self; + COLOR oldtext; + COLOR inactive, default_color, selected; + FONT oldfont = SetContextFont (StarConFont); + FONTEFFECT oldFontEffect = SetContextFontEffect (0, 0, 0); + TEXT t; + int i, home_x, home_y; + + default_color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F); + selected = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x00), 0x0E); + inactive = BUILD_COLOR (MAKE_RGB15 (0x18, 0x18, 0x1F), 0x07); + + t.baseline.x = x; + t.baseline.y = y; + t.align = ALIGN_LEFT; + t.valign = VALIGN_BOTTOM; + t.pStr = self->category; + if (widget_focus == _self) + { + oldtext = SetContextForeGroundColor (selected); + } + else + { + oldtext = SetContextForeGroundColor (default_color); + } + font_DrawText (&t); + + home_x = t.baseline.x + 3 * (SCREEN_WIDTH / 8); + home_y = t.baseline.y; + t.align = ALIGN_CENTER; + for (i = 0; i < self->numopts; i++) + { + t.baseline.x = home_x + ((i % 3) * (SCREEN_WIDTH / 4)); + t.baseline.y = home_y + (8 * (i / 3)); + t.pStr = self->options[i].optname; + if ((widget_focus == _self) && + (self->highlighted == i)) + { + SetContextForeGroundColor (selected); + Widget_DrawToolTips (3, self->options[i].tooltip); + } + else if (i == self->selected) + { + SetContextForeGroundColor (default_color); + } + else + { + SetContextForeGroundColor (inactive); + } + font_DrawText (&t); + } + SetContextFontEffect (oldFontEffect.type, oldFontEffect.from, oldFontEffect.to); + SetContextFont (oldfont); + SetContextForeGroundColor (oldtext); +} + +void +Widget_DrawButton (WIDGET *_self, int x, int y) +{ + WIDGET_BUTTON *self = (WIDGET_BUTTON *)_self; + COLOR oldtext; + COLOR inactive, selected; + FONT oldfont = SetContextFont (StarConFont); + FONTEFFECT oldFontEffect = SetContextFontEffect (0, 0, 0); + TEXT t; + int i, home_x, home_y; + + selected = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x00), 0x0E); + inactive = BUILD_COLOR (MAKE_RGB15 (0x18, 0x18, 0x1F), 0x07); + + t.baseline.x = 160; + t.baseline.y = y; + t.align = ALIGN_CENTER; + t.valign = VALIGN_BOTTOM; + t.pStr = self->name; + if (widget_focus == _self) + { + oldtext = SetContextForeGroundColor (selected); + Widget_DrawToolTips (3, self->tooltip); + + } + else + { + oldtext = SetContextForeGroundColor (inactive); + } + font_DrawText (&t); + SetContextFontEffect (oldFontEffect.type, oldFontEffect.from, oldFontEffect.to); + SetContextFont (oldfont); + SetContextForeGroundColor (oldtext); +} + +int +Widget_HeightChoice (WIDGET *_self) +{ + return ((((WIDGET_CHOICE *)_self)->numopts + 2) / 3) * 8; +} + +int +Widget_HeightFullScreen (WIDGET *_self) +{ + return SCREEN_HEIGHT; +} + +int +Widget_HeightOneLine (WIDGET *_self) +{ + return 8; +} + +int Widget_WidthFullScreen (WIDGET *_self) +{ + return SCREEN_WIDTH; +} + +int +Widget_ReceiveFocusButton (WIDGET *_self, int event) +{ + widget_focus = _self; + return TRUE; +} + +int +Widget_ReceiveFocusChoice (WIDGET *_self, int event) +{ + WIDGET_CHOICE *self = (WIDGET_CHOICE *)_self; + widget_focus = _self; + self->highlighted = self->selected; + return TRUE; +} + +int +Widget_ReceiveFocusMenuScreen (WIDGET *_self, int event) +{ + WIDGET_MENU_SCREEN *self = (WIDGET_MENU_SCREEN *)_self; + int x, last_x, dx; + for (x = 0; x < self->num_children; x++) + { + self->child[x]->parent = _self; + } + if (event == WIDGET_EVENT_UP) + { + x = self->num_children - 1; + dx = -1; + last_x = -1; + } + else + { + x = 0; + dx = 1; + last_x = self->num_children; + } + for ( ; x != last_x; x += dx) + { + WIDGET *child = self->child[x]; + if ((*child->receiveFocus)(child, event)) + { + self->highlighted = x; + return TRUE; + } + } + return FALSE; +} + +int +Widget_HandleEventIgnoreAll (WIDGET *self, int event) +{ + return FALSE; +} + +int +Widget_HandleEventChoice (WIDGET *_self, int event) +{ + WIDGET_CHOICE *self = (WIDGET_CHOICE *)_self; + switch (event) + { + case WIDGET_EVENT_LEFT: + self->highlighted -= 1; + if (self->highlighted < 0) + self->highlighted = self->numopts - 1; + return TRUE; + case WIDGET_EVENT_RIGHT: + self->highlighted += 1; + if (self->highlighted >= self->numopts) + self->highlighted = 0; + return TRUE; + case WIDGET_EVENT_SELECT: + self->selected = self->highlighted; + return TRUE; + default: + return FALSE; + } +} + + +int +Widget_HandleEventMenuScreen (WIDGET *_self, int event) +{ + WIDGET_MENU_SCREEN *self = (WIDGET_MENU_SCREEN *)_self; + int x, last_x, dx; + switch (event) + { + case WIDGET_EVENT_UP: + dx = -1; + break; + case WIDGET_EVENT_DOWN: + dx = 1; + break; + default: + return FALSE; + } + last_x = self->highlighted; + x = self->highlighted + dx; + while (x != last_x) + { + WIDGET *child; + if (x == -1) + x = self->num_children - 1; + if (x == self->num_children) + x = 0; + child = self->child[x]; + if ((*child->receiveFocus)(child, event)) + { + self->highlighted = x; + return TRUE; + } + x += dx; + } + return FALSE; +} + +int +Widget_Event (int event) +{ + WIDGET *widget = widget_focus; + while (widget != NULL) + { + if ((*widget->handleEvent)(widget, event)) + return TRUE; + widget = widget->parent; + } + return FALSE; +} diff --git a/sc2/src/sc2code/libs/graphics/widgets.h b/sc2/src/sc2code/libs/graphics/widgets.h index 5ac7580a9..2ef43ec31 100644 --- a/sc2/src/sc2code/libs/graphics/widgets.h +++ b/sc2/src/sc2code/libs/graphics/widgets.h @@ -19,6 +19,93 @@ #ifndef _WIDGETS_H #define _WIDGETS_H -void DrawShadowedBox(PRECT r, COLOR bg, COLOR dark, COLOR medium); +#include "libs/gfxlib.h" + +enum { + WIDGET_EVENT_UP, + WIDGET_EVENT_DOWN, + WIDGET_EVENT_LEFT, + WIDGET_EVENT_RIGHT, + WIDGET_EVENT_SELECT, + WIDGET_EVENT_CANCEL, + NUM_WIDGET_EVENTS +}; + +typedef struct _widget { + struct _widget *parent; + int (*handleEvent)(struct _widget *self, int event); + int (*receiveFocus)(struct _widget *self, int event); + void (*draw)(struct _widget *self, int x, int y); + int (*height)(struct _widget *self); + int (*width)(struct _widget *self); +} WIDGET; + +typedef struct _widget_menu_screen { + struct _widget *parent; + int (*handleEvent)(struct _widget *self, int event); + int (*receiveFocus)(struct _widget *self, int event); + void (*draw)(struct _widget *self, int x, int y); + int (*height)(struct _widget *self); + int (*width)(struct _widget *self); + const char *title; + const char *subtitle; + STAMP bgStamp; + int num_children; + struct _widget **child; + int highlighted; +} WIDGET_MENU_SCREEN; + +typedef struct { + const char *optname; + const char *tooltip[3]; +} CHOICE_OPTION; + +typedef struct _widget_choice { + struct _widget *parent; + int (*handleEvent)(struct _widget *self, int event); + int (*receiveFocus)(struct _widget *self, int event); + void (*draw)(struct _widget *self, int x, int y); + int (*height)(struct _widget *self); + int (*width)(struct _widget *self); + const char *category; + int numopts; + CHOICE_OPTION *options; + int selected, highlighted; +} WIDGET_CHOICE; + +typedef struct _widget_button { + struct _widget *parent; + int (*handleEvent)(struct _widget *self, int event); + int (*receiveFocus)(struct _widget *self, int event); + void (*draw)(struct _widget *self, int x, int y); + int (*height)(struct _widget *self); + int (*width)(struct _widget *self); + const char *name; + const char *tooltip[3]; +} WIDGET_BUTTON; + +void DrawShadowedBox (PRECT r, COLOR bg, COLOR dark, COLOR medium); + +int Widget_Event (int event); + +/* Methods for filling in widgets with */ + +int Widget_ReceiveFocusMenuScreen (WIDGET *_self, int event); +int Widget_ReceiveFocusChoice (WIDGET *_self, int event); +int Widget_ReceiveFocusButton (WIDGET *_self, int event); + +int Widget_HandleEventMenuScreen (WIDGET *_self, int event); +int Widget_HandleEventChoice (WIDGET *_self, int event); +int Widget_HandleEventIgnoreAll (WIDGET *_self, int event); + +int Widget_HeightChoice (WIDGET *_self); +int Widget_HeightFullScreen (WIDGET *_self); +int Widget_HeightOneLine (WIDGET *_self); + +int Widget_WidthFullScreen (WIDGET *_self); + +void Widget_DrawMenuScreen (WIDGET *_self, int x, int y); +void Widget_DrawChoice (WIDGET *_self, int x, int y); +void Widget_DrawButton (WIDGET *_self, int x, int y); #endif /* _WIDGETS_H */ diff --git a/sc2/src/sc2code/setupmenu.c b/sc2/src/sc2code/setupmenu.c index 9a4cebc57..0f864eafe 100644 --- a/sc2/src/sc2code/setupmenu.c +++ b/sc2/src/sc2code/setupmenu.c @@ -35,28 +35,13 @@ typedef struct setup_menu_state { BOOLEAN initialized; int anim_frame_count; DWORD NextTime; - int category; - int option; } SETUP_MENU_STATE; typedef SETUP_MENU_STATE *PSETUP_MENU_STATE; -typedef struct { - const char *optname; - const char *tooltip[3]; -} OPTION; - -typedef struct { - const char *category; - int numopts; - OPTION *options; - int selected; -} MENU_CATEGORY; - static BOOLEAN DoSetupMenu (PSETUP_MENU_STATE pInputState); -static STAMP bkgStamp = { {0, 0}, NULL }; -static OPTION scaler_opts[] = { +static CHOICE_OPTION scaler_opts[] = { { "None", { "No scaling.", "Simulates the original 320x240 display.", @@ -83,7 +68,7 @@ static OPTION scaler_opts[] = { "Based on the Scale2x algorithm.", } } }; -static OPTION scanlines_opts[] = { +static CHOICE_OPTION scanlines_opts[] = { { "Disabled", { "Do not attempt to simulate an interlaced display.", "", @@ -95,7 +80,7 @@ static OPTION scanlines_opts[] = { "" } } }; -static OPTION music_opts[] = { +static CHOICE_OPTION music_opts[] = { { "PC", { "Uses the music from the Original PC version.", "Prefers .MOD files to .OGG files.", @@ -107,7 +92,7 @@ static OPTION music_opts[] = { "Prefers .OGG files over .MOD." } } }; -static OPTION menu_opts[] = { +static CHOICE_OPTION menu_opts[] = { { "Text", { "In-game menus resemble the Original PC version.", "", @@ -119,7 +104,7 @@ static OPTION menu_opts[] = { "" } } }; -static OPTION font_opts[] = { +static CHOICE_OPTION font_opts[] = { { "Gradients", { "Certain menu texts and dialogs use gradients,", "as per the original PC version.", @@ -131,7 +116,7 @@ static OPTION font_opts[] = { "Easier to read." } } }; -static OPTION scan_opts[] = { +static CHOICE_OPTION scan_opts[] = { { "Text", { "Displays planet scan information as text,", "as per the original PC version.", @@ -143,7 +128,7 @@ static OPTION scan_opts[] = { "" } } }; -static OPTION scroll_opts[] = { +static CHOICE_OPTION scroll_opts[] = { { "Per-Page", { "When fast-forwarding or rewinding conversations", "in-game, advance one screen of subtitles at a time.", @@ -155,7 +140,7 @@ static OPTION scroll_opts[] = { "This mimics the 3do version." } } }; -static OPTION subtitles_opts[] = { +static CHOICE_OPTION subtitles_opts[] = { { "Disabled", { "Do not subtitle alien speech.", "", @@ -167,7 +152,7 @@ static OPTION subtitles_opts[] = { "" } } }; -static OPTION resdriver_opts[] = { +static CHOICE_OPTION resdriver_opts[] = { { "320x240", { "320x240 resolution.", "Uses the SDL frame buffer directly.", @@ -207,7 +192,7 @@ static OPTION resdriver_opts[] = { #endif }; -static OPTION bpp_opts[] = { +static CHOICE_OPTION bpp_opts[] = { { "16", { "16-bit color depth.", "", @@ -224,12 +209,6 @@ static OPTION bpp_opts[] = { "" } } }; -//static char *title_str = "Ur-Quan Masters Setup"; -//static char *subtitle_str = "Graphics Options"; -static const char *title_str = "Use arrows and fire to select options"; -static const char *subtitle_str = "Press cancel when done"; -static const char **tooltip; - #ifdef HAVE_OPENGL #define RES_OPTS 6 #else @@ -238,17 +217,40 @@ static const char **tooltip; #define NUM_OPTS 9 -static MENU_CATEGORY cmdline_opts[] = { - { "Resolution", RES_OPTS, resdriver_opts, 0 }, - { "Color depth", 3, bpp_opts, 0 }, - { "Scaler", 5, scaler_opts, 0 }, - { "Scanlines", 2, scanlines_opts, 0 }, - { "Menu Style", 2, menu_opts, 0 }, - { "Font Style", 2, font_opts, 0 }, - { "Scan Style", 2, scan_opts, 0 }, - { "Scroll Style", 2, scroll_opts, 0 }, - { "Subtitles", 2, subtitles_opts, 0 }, - { NULL, 0, NULL, 0 } }; +#define CHOICE_PREFACE NULL, Widget_HandleEventChoice, Widget_ReceiveFocusChoice, Widget_DrawChoice, Widget_HeightChoice, Widget_WidthFullScreen + +static WIDGET_CHOICE cmdline_opts[] = { + { CHOICE_PREFACE, "Resolution", RES_OPTS, resdriver_opts, 0, 0}, + { CHOICE_PREFACE, "Color depth", 3, bpp_opts, 0, 0 }, + { CHOICE_PREFACE, "Scaler", 5, scaler_opts, 0, 0 }, + { CHOICE_PREFACE, "Scanlines", 2, scanlines_opts, 0, 0 }, + { CHOICE_PREFACE, "Menu Style", 2, menu_opts, 0, 0 }, + { CHOICE_PREFACE, "Font Style", 2, font_opts, 0, 0 }, + { CHOICE_PREFACE, "Scan Style", 2, scan_opts, 0, 0 }, + { CHOICE_PREFACE, "Scroll Style", 2, scroll_opts, 0, 0 }, + { CHOICE_PREFACE, "Subtitles", 2, subtitles_opts, 0, 0 } }; + +static WIDGET *opt_widgets[] = { + (WIDGET *)(&cmdline_opts[0]), + (WIDGET *)(&cmdline_opts[1]), + (WIDGET *)(&cmdline_opts[2]), + (WIDGET *)(&cmdline_opts[3]), + (WIDGET *)(&cmdline_opts[4]), + (WIDGET *)(&cmdline_opts[5]), + (WIDGET *)(&cmdline_opts[6]), + (WIDGET *)(&cmdline_opts[7]), + (WIDGET *)(&cmdline_opts[8]) } ; + +static WIDGET_MENU_SCREEN menu = { + NULL, Widget_HandleEventMenuScreen, Widget_ReceiveFocusMenuScreen, + Widget_DrawMenuScreen, Widget_HeightFullScreen, Widget_WidthFullScreen, + // "Ur-Quan Masters Setup", + // "Graphics Options", + "Use arrows and fire to select options", + "Press cancel when done", + { {0, 0}, NULL }, + 9, opt_widgets, + 0 }; #define NUM_STEPS 20 #define X_STEP (SCREEN_WIDTH / NUM_STEPS) @@ -297,176 +299,46 @@ PropagateResults (void) SetGlobalOptions (&opts); } -static void -DrawMenu (PSETUP_MENU_STATE pInputState) -{ - RECT r; - COLOR title, oldtext; - COLOR inactive, default_color, selected; - FONT oldfont = SetContextFont (StarConFont); - FONTEFFECT oldFontEffect = SetContextFontEffect (0, 0, 0); - TEXT t; - MENU_CATEGORY *menu; - int cat_index; - - r.corner.x = 2; - r.corner.y = 2; - r.extent.width = SCREEN_WIDTH - 4; - r.extent.height = SCREEN_HEIGHT - 4; - - title = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F); - selected = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x00), 0x0E); - inactive = BUILD_COLOR (MAKE_RGB15 (0x18, 0x18, 0x1F), 0x07); - default_color = title; - - if (!bkgStamp.frame) - { - bkgStamp.origin.x = 0; - bkgStamp.origin.y = 0; - bkgStamp.frame = CaptureDrawable (LoadCelFile (MENU_BKG)); - } - - DrawStamp (&bkgStamp); - - oldtext = SetContextForeGroundColor (title); - t.baseline.x = r.corner.x + (r.extent.width >> 1); - t.baseline.y = r.corner.y + 8; - t.pStr = title_str; - t.align = ALIGN_CENTER; - t.valign = VALIGN_BOTTOM; - t.CharCount = ~0; - font_DrawText (&t); - t.baseline.y += 8; - t.pStr = subtitle_str; - font_DrawText (&t); - - t.baseline.y += 8; - menu = cmdline_opts; - cat_index = 0; - - while (menu->category) - { - int i, home_x, home_y; - - t.baseline.x = r.corner.x; // + (r.extent.width / 8); - t.baseline.y += 16; - t.align = ALIGN_LEFT; - t.pStr = menu->category; - if (pInputState->category == cat_index) - { - SetContextForeGroundColor (selected); - } - else - { - SetContextForeGroundColor (title); - } - font_DrawText (&t); - - home_x = t.baseline.x + 3 * (r.extent.width / 8); - home_y = t.baseline.y; - t.align = ALIGN_CENTER; - for (i = 0; i < menu->numopts; i++) - { - t.baseline.x = home_x + ((i % 3) * (r.extent.width / 4)); - t.baseline.y = home_y + (8 * (i / 3)); - t.pStr = menu->options[i].optname; - if ((pInputState->category == cat_index) && - (pInputState->option == i)) - { - SetContextForeGroundColor (selected); - tooltip = menu->options[i].tooltip; - } - else if (i == menu->selected) - { - SetContextForeGroundColor (default_color); - } - else - { - SetContextForeGroundColor (inactive); - } - font_DrawText (&t); - } - menu++; - cat_index++; - } - t.baseline.x = r.corner.x + (r.extent.width >> 1); - t.baseline.y = r.corner.y + (r.extent.height - 32); - t.pStr = tooltip[0]; - SetContextForeGroundColor (title); - font_DrawText(&t); - t.baseline.y += 8; - t.pStr = tooltip[1]; - font_DrawText(&t); - t.baseline.y += 8; - t.pStr = tooltip[2]; - font_DrawText(&t); - - SetContextFontEffect (oldFontEffect.type, oldFontEffect.from, oldFontEffect.to); - SetContextFont (oldfont); - SetContextForeGroundColor (oldtext); -} - static BOOLEAN DoSetupMenu (PSETUP_MENU_STATE pInputState) { - int opt, cat; - MENU_CATEGORY *menu = cmdline_opts; - if (!pInputState->initialized) { SetDefaultMenuRepeatDelay (); SetTransitionSource (NULL); pInputState->NextTime = GetTimeCounter (); - pInputState->category = 0; SetDefaults (); - pInputState->option = menu[0].selected; + (*menu.receiveFocus) ((WIDGET *)(&menu), WIDGET_EVENT_DOWN); + } + if (!menu.bgStamp.frame) + { + menu.bgStamp.origin.x = 0; + menu.bgStamp.origin.y = 0; + menu.bgStamp.frame = CaptureDrawable (LoadCelFile (MENU_BKG)); } BatchGraphics (); - DrawMenu (pInputState); - cat = pInputState->category; - opt = pInputState->option; + (*menu.draw)((WIDGET *)(&menu), 0, 0); if (PulsedInputState.key[KEY_MENU_UP]) { - cat--; - if (cat < 0) - { - cat = NUM_OPTS-1; - } - /* Preserve column if possible */ - opt = menu[cat].selected; + Widget_Event (WIDGET_EVENT_UP); } else if (PulsedInputState.key[KEY_MENU_DOWN]) { - cat++; - if (cat >= NUM_OPTS) - { - cat = 0; - } - opt = menu[cat].selected; + Widget_Event (WIDGET_EVENT_DOWN); } else if (PulsedInputState.key[KEY_MENU_LEFT]) { - opt--; - if (opt < 0) - { - opt = menu[cat].numopts - 1; - } + Widget_Event (WIDGET_EVENT_LEFT); } else if (PulsedInputState.key[KEY_MENU_RIGHT]) { - opt++; - if (opt >= menu[cat].numopts) - { - opt = 0; - } + Widget_Event (WIDGET_EVENT_RIGHT); } - pInputState->category = cat; - pInputState->option = opt; if (PulsedInputState.key[KEY_MENU_SELECT]) { - cmdline_opts[cat].selected = opt; + Widget_Event (WIDGET_EVENT_SELECT); } if (!pInputState->initialized)