From 2a5b26c27cd967faf46bbb3e52e0838028d5ee5f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Feb 2017 21:28:48 +0100 Subject: [PATCH] - removed native option menu controls. Note that this commit will not compile! --- src/d_main.cpp | 8 +- src/menu/colorpickermenu.cpp | 16 +- src/menu/joystickmenu.cpp | 242 +--- src/menu/menu.cpp | 21 +- src/menu/menu.h | 40 +- src/menu/menudef.cpp | 312 ++--- src/menu/optionmenu.cpp | 51 +- src/menu/optionmenuitems.h | 1208 ----------------- src/menu/videomenu.cpp | 41 +- wadsrc/static/zscript/menu/joystickmenu.txt | 2 +- wadsrc/static/zscript/menu/menuitembase.txt | 3 + .../static/zscript/menu/optionmenuitems.txt | 23 +- 12 files changed, 236 insertions(+), 1731 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index e0cbcbefa..b5d5e7032 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2523,7 +2523,10 @@ void D_DoomMain (void) // Create replacements for dehacked pickups FinishDehPatch(); - + + if (!batchrun) Printf("M_Init: Init menus.\n"); + M_Init(); + // clean up the compiler symbols which are not needed any longer. RemoveUnusedSymbols(); @@ -2541,9 +2544,6 @@ void D_DoomMain (void) bglobal.spawn_tries = 0; bglobal.wanted_botnum = bglobal.getspawned.Size(); - if (!batchrun) Printf ("M_Init: Init menus.\n"); - M_Init (); - if (!batchrun) Printf ("P_Init: Init Playloop state.\n"); StartScreen->LoadingStatus ("Init game engine", 0x3f); AM_StaticInit(); diff --git a/src/menu/colorpickermenu.cpp b/src/menu/colorpickermenu.cpp index d337eb82a..d0718c1a9 100644 --- a/src/menu/colorpickermenu.cpp +++ b/src/menu/colorpickermenu.cpp @@ -81,14 +81,14 @@ public: // This menu uses some featurs that are hard to implement in an external control lump // so it creates its own list of menu items. desc->mItems.Resize(mStartItem+8); - desc->mItems[mStartItem+0] = new DOptionMenuItemStaticText_(name, false); - desc->mItems[mStartItem+1] = new DOptionMenuItemStaticText_(" ", false); - desc->mItems[mStartItem+2] = new DOptionMenuSliderVar_("Red", &mRed, 0, 255, 15, 0); - desc->mItems[mStartItem+3] = new DOptionMenuSliderVar_("Green", &mGreen, 0, 255, 15, 0); - desc->mItems[mStartItem+4] = new DOptionMenuSliderVar_("Blue", &mBlue, 0, 255, 15, 0); - desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText_(" ", false); - desc->mItems[mStartItem+6] = new DOptionMenuItemCommand_("Undo changes", "undocolorpic"); - desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText_(" ", false); + desc->mItems[mStartItem+0] = CreateOptionMenuItemStaticText(name, false); + desc->mItems[mStartItem+1] = CreateOptionMenuItemStaticText(" ", false); + desc->mItems[mStartItem+2] = CreateOptionMenuSliderVar("Red", 0, 0, 255, 15, 0); + desc->mItems[mStartItem+3] = CreateOptionMenuSliderVar("Green", 1, 0, 255, 15, 0); + desc->mItems[mStartItem+4] = CreateOptionMenuSliderVar("Blue", 2, 0, 255, 15, 0); + desc->mItems[mStartItem+5] = CreateOptionMenuItemStaticText(" ", false); + desc->mItems[mStartItem+6] = CreateOptionMenuItemCommand("Undo changes", "undocolorpic"); + desc->mItems[mStartItem+7] = CreateOptionMenuItemStaticText(" ", false); for (auto &p : desc->mItems) { GC::WriteBarrier(p); diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 50f49463c..24474bc43 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -128,177 +128,6 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisMap) DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderJoySensitivity_ : public DOptionMenuSliderBase_ -{ -public: - DOptionMenuSliderJoySensitivity_(const char *label, double min, double max, double step, int showval) - : DOptionMenuSliderBase_(label, min, max, step, showval) - { - } - - double GetSliderValue() - { - return SELECTED_JOYSTICK->GetSensitivity(); - } - - void SetSliderValue(double val) - { - SELECTED_JOYSTICK->SetSensitivity(float(val)); - } -}; - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderJoyScale_ : public DOptionMenuSliderBase_ -{ - int mAxis; - int mNeg; - -public: - DOptionMenuSliderJoyScale_(const char *label, int axis, double min, double max, double step, int showval) - : DOptionMenuSliderBase_(label, min, max, step, showval) - { - mAxis = axis; - mNeg = 1; - } - - double GetSliderValue() - { - double d = SELECTED_JOYSTICK->GetAxisScale(mAxis); - mNeg = d < 0? -1:1; - return d; - } - - void SetSliderValue(double val) - { - SELECTED_JOYSTICK->SetAxisScale(mAxis, float(val * mNeg)); - } -}; - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderJoyDeadZone_ : public DOptionMenuSliderBase_ -{ - int mAxis; - int mNeg; - -public: - DOptionMenuSliderJoyDeadZone_(const char *label, int axis, double min, double max, double step, int showval) - : DOptionMenuSliderBase_(label, min, max, step, showval) - { - mAxis = axis; - mNeg = 1; - } - - double GetSliderValue() - { - double d = SELECTED_JOYSTICK->GetAxisDeadZone(mAxis); - mNeg = d < 0? -1:1; - return d; - } - - void SetSliderValue(double val) - { - SELECTED_JOYSTICK->SetAxisDeadZone(mAxis, float(val * mNeg)); - } -}; - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuItemJoyMap_ : public DOptionMenuItemOptionBase_ -{ - int mAxis; -public: - - DOptionMenuItemJoyMap_(const char *label, int axis, const char *values, int center) - : DOptionMenuItemOptionBase_(label, "none", values, NULL, center) - { - mAxis = axis; - } - - int GetSelection() - { - double f = SELECTED_JOYSTICK->GetAxisMap(mAxis); - FOptionValues **opt = OptionValues.CheckKey(mValues); - if (opt != NULL && *opt != NULL) - { - // Map from joystick axis to menu selection. - for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) - { - if (fabs(f - (*opt)->mValues[i].Value) < FLT_EPSILON) - { - return i; - } - } - } - return -1; - } - - void SetSelection(int selection) - { - FOptionValues **opt = OptionValues.CheckKey(mValues); - // Map from menu selection to joystick axis. - if (opt == NULL || *opt == NULL || (unsigned)selection >= (*opt)->mValues.Size()) - { - selection = JOYAXIS_None; - } - else - { - selection = (int)(*opt)->mValues[selection].Value; - } - SELECTED_JOYSTICK->SetAxisMap(mAxis, (EJoyAxis)selection); - } -}; - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuItemInverter_ : public DOptionMenuItemOptionBase_ -{ - int mAxis; -public: - - DOptionMenuItemInverter_(const char *label, int axis, int center) - : DOptionMenuItemOptionBase_(label, "none", "YesNo", NULL, center) - { - mAxis = axis; - } - - int GetSelection() - { - float f = SELECTED_JOYSTICK->GetAxisScale(mAxis); - return f > 0? 0:1; - } - - void SetSelection(int Selection) - { - float f = fabsf(SELECTED_JOYSTICK->GetAxisScale(mAxis)); - if (Selection) f*=-1; - SELECTED_JOYSTICK->SetAxisScale(mAxis, f); - } -}; - class DJoystickConfigMenu : public DOptionMenu { DECLARE_CLASS(DJoystickConfigMenu, DOptionMenu) @@ -306,33 +135,6 @@ class DJoystickConfigMenu : public DOptionMenu IMPLEMENT_CLASS(DJoystickConfigMenu, false, false) -//============================================================================= -// -// Executes a CCMD, action is a CCMD name -// -//============================================================================= - -class DOptionMenuItemJoyConfigMenu_ : public DOptionMenuItemSubmenu_ -{ - DECLARE_CLASS(DOptionMenuItemJoyConfigMenu_, DOptionMenuItemSubmenu_) - IJoystickConfig *mJoy; -public: - DOptionMenuItemJoyConfigMenu_(const char *label = nullptr, IJoystickConfig *joy = nullptr) - : DOptionMenuItemSubmenu_(label, "JoystickConfigMenu") - { - mJoy = joy; - } - - bool Activate() - { - UpdateJoystickConfigMenu(mJoy); - return DOptionMenuItemSubmenu_::Activate(); - } -}; - -IMPLEMENT_CLASS(DOptionMenuItemJoyConfigMenu_, false, false) - - /*======================================= * * Joystick Menu @@ -345,12 +147,12 @@ DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; - DOptionMenuItem *it; + DMenuItemBase *it; opt->mItems.Clear(); if (joy == NULL) { opt->mTitle = "Configure Controller"; - it = new DOptionMenuItemStaticText_("Invalid controller specified for menu", false); + it = CreateOptionMenuItemStaticText("Invalid controller specified for menu", false); opt->mItems.Push(it); } else @@ -359,34 +161,34 @@ DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) SELECTED_JOYSTICK = joy; - it = new DOptionMenuSliderJoySensitivity_("Overall sensitivity", 0, 2, 0.1, 3); + it = CreateOptionMenuSliderJoySensitivity("Overall sensitivity", 0, 2, 0.1, 3); opt->mItems.Push(it); - it = new DOptionMenuItemStaticText_(" ", false); + it = CreateOptionMenuItemStaticText(" ", false); opt->mItems.Push(it); if (joy->GetNumAxes() > 0) { - it = new DOptionMenuItemStaticText_("Axis Configuration", true); + it = CreateOptionMenuItemStaticText("Axis Configuration", true); opt->mItems.Push(it); for (int i = 0; i < joy->GetNumAxes(); ++i) { - it = new DOptionMenuItemStaticText_(" ", false); + it = CreateOptionMenuItemStaticText(" ", false); opt->mItems.Push(it); - it = new DOptionMenuItemJoyMap_(joy->GetAxisName(i), i, "JoyAxisMapNames", false); + it = CreateOptionMenuItemJoyMap(joy->GetAxisName(i), i, "JoyAxisMapNames", false); opt->mItems.Push(it); - it = new DOptionMenuSliderJoyScale_("Overall sensitivity", i, 0, 4, 0.1, 3); + it = CreateOptionMenuSliderJoyScale("Overall sensitivity", i, 0, 4, 0.1, 3); opt->mItems.Push(it); - it = new DOptionMenuItemInverter_("Invert", i, false); + it = CreateOptionMenuItemInverter("Invert", i, false); opt->mItems.Push(it); - it = new DOptionMenuSliderJoyDeadZone_("Dead Zone", i, 0, 0.9, 0.05, 3); + it = CreateOptionMenuSliderJoyDeadZone("Dead Zone", i, 0, 0.9, 0.05, 3); opt->mItems.Push(it); } } else { - it = new DOptionMenuItemStaticText_("No configurable axes", false); + it = CreateOptionMenuItemStaticText("No configurable axes", false); opt->mItems.Push(it); } } @@ -412,7 +214,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; - DOptionMenuItem *it; + DMenuItemBase *it; opt->mItems.Clear(); int i; @@ -436,40 +238,40 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } // Todo: Block joystick for changing this one. - it = new DOptionMenuItemOption_("Enable controller support", "use_joystick", "YesNo", NULL, false); + it = CreateOptionMenuItemOption("Enable controller support", "use_joystick", "YesNo", NULL, false); opt->mItems.Push(it); #ifdef _WIN32 - it = new DOptionMenuItemOption_("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); + it = CreateOptionMenuItemOption("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); opt->mItems.Push(it); - it = new DOptionMenuItemOption_("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); + it = CreateOptionMenuItemOption("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); opt->mItems.Push(it); - it = new DOptionMenuItemOption_("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); + it = CreateOptionMenuItemOption("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); opt->mItems.Push(it); #endif - it = new DOptionMenuItemStaticText_(" ", false); + it = CreateOptionMenuItemStaticText(" ", false); opt->mItems.Push(it); if (Joysticks.Size() == 0) { - it = new DOptionMenuItemStaticText_("No controllers detected", false); + it = CreateOptionMenuItemStaticText("No controllers detected", false); opt->mItems.Push(it); if (!use_joystick) { - it = new DOptionMenuItemStaticText_("Controller support must be", false); + it = CreateOptionMenuItemStaticText("Controller support must be", false); opt->mItems.Push(it); - it = new DOptionMenuItemStaticText_("enabled to detect any", false); + it = CreateOptionMenuItemStaticText("enabled to detect any", false); opt->mItems.Push(it); } } else { - it = new DOptionMenuItemStaticText_("Configure controllers:", false); + it = CreateOptionMenuItemStaticText("Configure controllers:", false); opt->mItems.Push(it); for (int i = 0; i < (int)Joysticks.Size(); ++i) { - it = new DOptionMenuItemJoyConfigMenu_(Joysticks[i]->GetName(), Joysticks[i]); + it = CreateOptionMenuItemJoyConfigMenu(Joysticks[i]->GetName(), Joysticks[i]); opt->mItems.Push(it); if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index d28bc5496..98c2de36d 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -1093,7 +1093,6 @@ CCMD(reset2saved) //native void OptionMenuDescriptor.CalcIndent(); //native OptionMenuItem OptionMenuDescriptor.GetItem(Name iname); -//native void OptionMenuItem.drawLabel(int indent, int y, EColorRange color, bool grayed = false); DEFINE_FIELD(DMenuDescriptor, mMenuName) DEFINE_FIELD(DMenuDescriptor, mNetgameMessage) @@ -1131,8 +1130,8 @@ DEFINE_FIELD(DOptionMenuDescriptor, mIndent) DEFINE_FIELD(DOptionMenuDescriptor, mPosition) DEFINE_FIELD(DOptionMenuDescriptor, mDontDim) -DEFINE_FIELD(DOptionMenuItem, mLabel) -DEFINE_FIELD(DOptionMenuItem, mCentered) +//DEFINE_FIELD(DMenuItemBase, mLabel) +//DEFINE_FIELD(DMenuItemBase, mCentered) DEFINE_FIELD(DOptionMenu, CanScrollUp) DEFINE_FIELD(DOptionMenu, CanScrollDown) @@ -1148,3 +1147,19 @@ DEFINE_FIELD(FOptionMenuSettings, mFontColorHeader) DEFINE_FIELD(FOptionMenuSettings, mFontColorHighlight) DEFINE_FIELD(FOptionMenuSettings, mFontColorSelection) DEFINE_FIELD(FOptionMenuSettings, mLinespacing) + + +struct IJoystickConfig; +DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v); +DMenuItemBase * CreateOptionMenuSliderVar(const char *name, int index, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuItemCommand(const char * label, FName cmd); +DMenuItemBase * CreateOptionMenuItemOption(const char * label, FName cmd, FName values, FBaseCVar *graycheck, bool center); +DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy); +DMenuItemBase * CreateOptionMenuItemJoyMap(const char *label, int axis, FName values, bool center); +DMenuItemBase * CreateOptionMenuSliderJoySensitivity(const char * label, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuItemInverter(const char *label, int axis, int center); +DMenuItemBase * CreateOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval); + +DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center); +DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings); diff --git a/src/menu/menu.h b/src/menu/menu.h index 7ffb1aab8..429a2b4f4 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -118,7 +118,6 @@ public: }; class DMenuItemBase; -class DOptionMenuItem; class DListMenuDescriptor : public DMenuDescriptor { @@ -176,7 +175,7 @@ class DOptionMenuDescriptor : public DMenuDescriptor DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor) public: - TArray mItems; + TArray mItems; FString mTitle; int mSelectedItem; int mDrawTop; @@ -187,7 +186,7 @@ public: bool mDontDim; void CalcIndent(); - DOptionMenuItem *GetItem(FName name); + DMenuItemBase *GetItem(FName name); void Reset() { // Reset the default settings (ignore all other values in the struct) @@ -330,11 +329,14 @@ public: virtual bool MouseEvent(int type, int x, int y); virtual bool CheckHotkey(int c); virtual int GetWidth(); + virtual int GetIndent() { return 0; } + virtual int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { return indent; } void DrawSelector(int xofs, int yofs, FTextureID tex); void OffsetPositionY(int ydelta) { mYpos += ydelta; } int GetY() { return mYpos; } int GetX() { return mXpos; } void SetX(int x) { mXpos = x; } + }; class DListMenuItemStaticPatch_ : public DMenuItemBase @@ -598,16 +600,17 @@ public: // //============================================================================= -class DOptionMenuItem : public DMenuItemBase +/* +class DMenuItemBase : public DMenuItemBase { - DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase) + DECLARE_ABSTRACT_CLASS(DMenuItemBase, DMenuItemBase) public: FString mLabel; bool mCentered; void drawLabel(int indent, int y, EColorRange color, bool grayed = false); - DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false) + DMenuItemBase(const char *text = nullptr, FName action = NAME_None, bool center = false) : DMenuItemBase(0, 0, action) { mLabel = text; @@ -618,7 +621,8 @@ public: virtual bool Selectable(); virtual int GetIndent(); virtual bool MouseEvent(int type, int x, int y); -}; +}; +*/ //============================================================================= // @@ -657,11 +661,11 @@ public: // needs to be public for script access bool CanScrollUp; bool CanScrollDown; int VisBottom; - DOptionMenuItem *mFocusControl; + DMenuItemBase *mFocusControl; DOptionMenuDescriptor *mDesc; //public: - DOptionMenuItem *GetItem(FName name); + DMenuItemBase *GetItem(FName name); DOptionMenu(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL); int FirstSelectable(); @@ -671,11 +675,11 @@ public: // needs to be public for script access void Ticker (); void Drawer (); const DOptionMenuDescriptor *GetDescriptor() const { return mDesc; } - void SetFocus(DOptionMenuItem *fc) + void SetFocus(DMenuItemBase *fc) { mFocusControl = fc; } - bool CheckFocus(DOptionMenuItem *fc) + bool CheckFocus(DMenuItemBase *fc) { return mFocusControl == fc; } @@ -745,4 +749,18 @@ void M_InitVideoModesMenu (); void M_MarkMenus(); +struct IJoystickConfig; +DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v); +DMenuItemBase * CreateOptionMenuSliderVar(const char *name, int index, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuItemCommand(const char * label, FName cmd); +DMenuItemBase * CreateOptionMenuItemOption(const char * label, FName cmd, FName values, FBaseCVar *graycheck, bool center); +DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center); +DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings); +DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy); +DMenuItemBase * CreateOptionMenuItemJoyMap(const char *label, int axis, FName values, bool center); +DMenuItemBase * CreateOptionMenuSliderJoySensitivity(const char * label, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval); +DMenuItemBase * CreateOptionMenuItemInverter(const char *label, int axis, int center); +DMenuItemBase * CreateOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval); + #endif diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 86f168747..51f2e4788 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -785,198 +785,114 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) sc.MustGetNumber(); desc->mIndent = sc.Number; } - else if (sc.Compare("Submenu")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemSubmenu_(label, sc.String); - desc->mItems.Push(it); - } - else if (sc.Compare("Option")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FString cvar = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FString values = sc.String; - FString check; - int center = 0; - if (sc.CheckString(",")) - { - sc.MustGetString(); - if (*sc.String != 0) check = sc.String; - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - center = sc.Number; - } - } - DOptionMenuItem *it = new DOptionMenuItemOption_(label, cvar, values, check, center); - desc->mItems.Push(it); - } - else if (sc.Compare("Command")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemCommand_(label, sc.String); - desc->mItems.Push(it); - } - else if (sc.Compare("SafeCommand")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FString command = sc.String; - FString prompt; - // Check for optional custom prompt - if (sc.CheckString(",")) - { - sc.MustGetString(); - prompt = sc.String; - } - DOptionMenuItem *it = new DOptionMenuItemSafeCommand_(label, command, prompt); - desc->mItems.Push(it); - } - else if (sc.Compare("Control") || sc.Compare("MapControl")) - { - bool map = sc.Compare("MapControl"); - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemControl_(label, sc.String, map? &AutomapBindings : &Bindings); - desc->mItems.Push(it); - } - else if (sc.Compare("ColorPicker")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuItemColorPicker_(label, sc.String); - desc->mItems.Push(it); - } - else if (sc.Compare("StaticText")) - { - sc.MustGetString(); - FString label = sc.String; - EColorRange cr = ParseOptionColor(sc, desc); - DOptionMenuItem *it = new DOptionMenuItemStaticText_(label, cr); - desc->mItems.Push(it); - } - else if (sc.Compare("StaticTextSwitchable")) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FString label2 = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FName action = sc.String; - EColorRange cr = ParseOptionColor(sc, desc); - DOptionMenuItem *it = new DOptionMenuItemStaticTextSwitchable_(label, label2, action, cr); - desc->mItems.Push(it); - } - else if (sc.Compare("Slider")) - { - sc.MustGetString(); - FString text = sc.String; - sc.MustGetStringName(","); - sc.MustGetString(); - FString action = sc.String; - sc.MustGetStringName(","); - sc.MustGetFloat(); - double min = sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - double max = sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - double step = sc.Float; - int showvalue = 1; - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - showvalue = sc.Number; - } - DOptionMenuItem *it = new DOptionMenuSliderCVar_(text, action, min, max, step, showvalue); - desc->mItems.Push(it); - } - else if (sc.Compare("screenresolution")) - { - sc.MustGetString(); - DOptionMenuItem *it = new DOptionMenuScreenResolutionLine_(sc.String); - desc->mItems.Push(it); - } - // [TP] -- Text input widget - else if ( sc.Compare( "TextField" )) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName( "," ); - sc.MustGetString(); - FString cvar = sc.String; - FString check; - - if ( sc.CheckString( "," )) - { - sc.MustGetString(); - check = sc.String; - } - - DOptionMenuItem* it = new DOptionMenuTextField_( label, cvar, check ); - desc->mItems.Push( it ); - } - // [TP] -- Number input widget - else if ( sc.Compare( "NumberField" )) - { - sc.MustGetString(); - FString label = sc.String; - sc.MustGetStringName( "," ); - sc.MustGetString(); - FString cvar = sc.String; - float minimum = 0.0f; - float maximum = 100.0f; - float step = 1.0f; - FString check; - - if ( sc.CheckString( "," )) - { - sc.MustGetFloat(); - minimum = (float) sc.Float; - sc.MustGetStringName( "," ); - sc.MustGetFloat(); - maximum = (float) sc.Float; - - if ( sc.CheckString( "," )) - { - sc.MustGetFloat(); - step = (float) sc.Float; - - if ( sc.CheckString( "," )) - { - sc.MustGetString(); - check = sc.String; - } - } - } - - DOptionMenuItem* it = new DOptionMenuNumberField_( label, cvar, - minimum, maximum, step, check ); - desc->mItems.Push( it ); - } else { - sc.ScriptError("Unknown keyword '%s'", sc.String); + bool success = false; + FStringf buildname("OptionMenuItem%s", sc.String); + // Handle one special case: MapControl maps to Control with one parameter different + FKeyBindings *bind = sc.Compare("MapControl") ? &AutomapBindings : &Bindings; + PClass *cls = PClass::FindClass(buildname); + if (cls != nullptr && cls->IsDescendantOf("OptionMenuItem")) + { + auto func = dyn_cast(cls->Symbols.FindSymbol("Init", false)); + if (func != nullptr && !(func->Variants[0].Flags & (VARF_Protected | VARF_Private))) // skip internal classes which have a protexted init method. + { + auto &args = func->Variants[0].Proto->ArgumentTypes; + TArray params; + + params.Push(0); + auto TypeCVar = NewPointer(NewNativeStruct("CVar", nullptr)); + auto TypeBind = NewPointer(NewNativeStruct("KeyBindings", nullptr)); + for (unsigned i = 1; i < args.Size(); i++) + { + sc.MustGetString(); + if (args[i] == TypeString) + { + params.Push(sc.String); + } + else if (args[i] == TypeName) + { + params.Push(FName(sc.String).GetIndex()); + } + else if (args[i] == TypeColor) + { + params.Push(V_GetColor(nullptr, sc)); + } + else if (args[i]->IsKindOf(RUNTIME_CLASS(PInt))) + { + char *endp; + int v = (int)strtoll(sc.String, &endp, 0); + if (*endp != 0) + { + // special check for font color ranges. + v = V_FindFontColor(sc.String); + if (v == CR_UNTRANSLATED && !sc.Compare("untranslated")) + { + // todo: check other data types that may get used. + sc.ScriptError("Integer expected, got %s", sc.String); + } + } + if (args[i] == TypeBool) v = !!v; + params.Push(v); + } + else if (args[i]->IsKindOf(RUNTIME_CLASS(PInt))) + { + char *endp; + double v = strtod(sc.String, &endp); + if (*endp != 0) + { + sc.ScriptError("Float expected, got %s", sc.String); + } + params.Push(v); + } + else if (args[i] == TypeCVar) + { + auto cv = FindCVar(sc.String, nullptr); + if (cv == nullptr && *sc.String) + { + sc.ScriptError("Unknown CVar %s", sc.String); + } + params.Push(cv); + } + else + { + sc.ScriptError("Invalid parameter type %s for menu item", args[i]->DescriptiveName()); + } + if (sc.CheckString(",")) + { + if (i == args.Size() - 1) + { + sc.ScriptError("Too many parameters for %s", cls->TypeName.GetChars()); + } + } + else + { + if (args[i + 1] == TypeBind) + { + // Bindings are not parsed, they just get tacked on. + params.Push(bind); + i++; + } + if (i < args.Size() - 1 && !(func->Variants[0].ArgFlags[i + 1] & VARF_Optional)) + { + sc.ScriptError("Insufficient parameters for %s", cls->TypeName.GetChars()); + } + break; + } + } + /* + DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew(); + params[0] = item; + GlobalVMStack.Call(func->Variants[0].Implementation, ¶ms[0], params.Size(), nullptr, 0); + desc->mItems.Push((DMenuItemBase*)item); + */ + success = true; + } + } + if (!success) + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } } } for (auto &p : desc->mItems) @@ -1185,7 +1101,7 @@ static void BuildEpisodeMenu() GC::WriteBarrier(od); for(unsigned i = 0; i < AllEpisodes.Size(); i++) { - DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_(AllEpisodes[i].mEpisodeName, "Skillmenu", i); + auto it = CreateOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); od->mItems.Push(it); GC::WriteBarrier(od, it); } @@ -1324,13 +1240,13 @@ static void BuildPlayerclassMenu() const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); if (pname != nullptr) { - DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_(pname, "Episodemenu", i); + auto it = CreateOptionMenuItemSubmenu(pname, "Episodemenu", i); od->mItems.Push(it); GC::WriteBarrier(od, it); } } } - DOptionMenuItemSubmenu_ *it = new DOptionMenuItemSubmenu_("Random", "Episodemenu", -1); + auto it = CreateOptionMenuItemSubmenu("Random", "Episodemenu", -1); od->mItems.Push(it); GC::WriteBarrier(od, it); } @@ -1411,14 +1327,14 @@ static void InitKeySections() for (unsigned i = 0; i < KeySections.Size(); i++) { FKeySection *sect = &KeySections[i]; - DOptionMenuItem *item = new DOptionMenuItemStaticText_(" ", false); + DMenuItemBase *item = CreateOptionMenuItemStaticText(" ", false); menu->mItems.Push(item); - item = new DOptionMenuItemStaticText_(sect->mTitle, true); + item = CreateOptionMenuItemStaticText(sect->mTitle, true); menu->mItems.Push(item); for (unsigned j = 0; j < sect->mActions.Size(); j++) { FKeyAction *act = §->mActions[j]; - item = new DOptionMenuItemControl_(act->mTitle, act->mAction, &Bindings); + item = CreateOptionMenuItemControl(act->mTitle, act->mAction, &Bindings); menu->mItems.Push(item); } } @@ -1599,7 +1515,7 @@ fail: for(unsigned int i = 0; i < AllSkills.Size(); i++) { FSkillInfo &skill = AllSkills[i]; - DOptionMenuItem *li; + DMenuItemBase *li; // Using a different name for skills that must be confirmed makes handling this easier. const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? "StartgameConfirm" : "Startgame"; @@ -1609,7 +1525,7 @@ fail: { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } - li = new DOptionMenuItemSubmenu_(pItemText? *pItemText : skill.MenuName, action, i); + li = CreateOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); od->mItems.Push(li); GC::WriteBarrier(od, li); if (!done) diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index a7f4acc7f..bc4c7974e 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -129,10 +129,8 @@ int DOptionMenu::FirstSelectable() // // //============================================================================= -IMPLEMENT_CLASS(DOptionMenuItem, true, false) - -DOptionMenuItem *DOptionMenu::GetItem(FName name) +DMenuItemBase *DOptionMenu::GetItem(FName name) { for(unsigned i=0;imItems.Size(); i++) { @@ -476,51 +474,6 @@ void DOptionMenu::Drawer () Super::Drawer(); } -int DOptionMenuItem::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) -{ - return indent; -} - -bool DOptionMenuItem::Selectable() -{ - return true; -} - -bool DOptionMenuItem::MouseEvent(int type, int x, int y) -{ - if (Selectable() && type == DMenu::MOUSE_Release) - { - return DMenu::CurrentMenu->CallMenuEvent(MKEY_Enter, true); - } - return false; -} - -int DOptionMenuItem::GetIndent() -{ - if (mCentered) - { - return 0; - } - const char *label = mLabel.GetChars(); - if (*label == '$') label = GStrings(label+1); - return SmallFont->StringWidth(label); -} - -void DOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed) -{ - const char *label = mLabel.GetChars(); - if (*label == '$') label = GStrings(label+1); - - int overlay = grayed? MAKEARGB(96,48,0,0) : 0; - - int x; - int w = SmallFont->StringWidth(label) * CleanXfac_1; - if (!mCentered) x = indent - w; - else x = (screen->GetWidth() - w) / 2; - screen->DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); -} - - void DOptionMenuDescriptor::CalcIndent() { // calculate the menu indent @@ -540,7 +493,7 @@ void DOptionMenuDescriptor::CalcIndent() // //============================================================================= -DOptionMenuItem *DOptionMenuDescriptor::GetItem(FName name) +DMenuItemBase *DOptionMenuDescriptor::GetItem(FName name) { for(unsigned i=0;i= (int)(*opt)->mValues.Size()) s = 0; - SetSelection(s); // readjust the CVAR if its value is outside the range now - return true; - } - } - return false; - } - - //============================================================================= - virtual int GetSelection() = 0; - virtual void SetSelection(int Selection) = 0; - - //============================================================================= - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool); - - if (mCenter) - { - indent = (screen->GetWidth() / 2); - } - drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed); - - int overlay = grayed? MAKEARGB(96,48,0,0) : 0; - const char *text; - int Selection = GetSelection(); - FOptionValues **opt = OptionValues.CheckKey(mValues); - if (Selection < 0 || opt == NULL || *opt == NULL) - { - text = "Unknown"; - } - else - { - text = (*opt)->mValues[Selection].Text; - } - if (*text == '$') text = GStrings(text + 1); - screen->DrawText (SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, - text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); - return indent; - } - - //============================================================================= - bool MenuEvent (int mkey, bool fromcontroller) - { - FOptionValues **opt = OptionValues.CheckKey(mValues); - if (opt != NULL && *opt != NULL && (*opt)->mValues.Size() > 0) - { - int Selection = GetSelection(); - if (mkey == MKEY_Left) - { - if (Selection == -1) Selection = 0; - else if (--Selection < 0) Selection = (*opt)->mValues.Size()-1; - } - else if (mkey == MKEY_Right || mkey == MKEY_Enter) - { - if (++Selection >= (int)(*opt)->mValues.Size()) Selection = 0; - } - else - { - return DOptionMenuItem::MenuEvent(mkey, fromcontroller); - } - SetSelection(Selection); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); - } - else - { - return DOptionMenuItem::MenuEvent(mkey, fromcontroller); - } - return true; - } - - bool Selectable() - { - return !(mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool)); - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemOptionBase_, true, false) -#endif - -//============================================================================= -// -// Change a CVAR, action is the CVAR name -// -//============================================================================= - -class DOptionMenuItemOption_ : public DOptionMenuItemOptionBase_ -{ - DECLARE_CLASS(DOptionMenuItemOption_, DOptionMenuItemOptionBase_) - // action is a CVAR - FBaseCVar *mCVar; - - DOptionMenuItemOption_() {} -public: - - DOptionMenuItemOption_(const char *label, const char *menu, const char *values, const char *graycheck, int center) - : DOptionMenuItemOptionBase_(label, menu, values, graycheck, center) - { - mCVar = FindCVar(mAction, NULL); - } - - //============================================================================= - int GetSelection() - { - int Selection = -1; - FOptionValues **opt = OptionValues.CheckKey(mValues); - if (opt != NULL && *opt != NULL && mCVar != NULL && (*opt)->mValues.Size() > 0) - { - if ((*opt)->mValues[0].TextValue.IsEmpty()) - { - UCVarValue cv = mCVar->GetGenericRep(CVAR_Float); - for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) - { - if (fabs(cv.Float - (*opt)->mValues[i].Value) < FLT_EPSILON) - { - Selection = i; - break; - } - } - } - else - { - const char *cv = mCVar->GetHumanString(); - for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) - { - if ((*opt)->mValues[i].TextValue.CompareNoCase(cv) == 0) - { - Selection = i; - break; - } - } - } - } - return Selection; - } - - void SetSelection(int Selection) - { - UCVarValue value; - FOptionValues **opt = OptionValues.CheckKey(mValues); - if (opt != NULL && *opt != NULL && mCVar != NULL && (*opt)->mValues.Size() > 0) - { - if ((*opt)->mValues[0].TextValue.IsEmpty()) - { - value.Float = (float)(*opt)->mValues[Selection].Value; - mCVar->SetGenericRep (value, CVAR_Float); - } - else - { - value.String = (*opt)->mValues[Selection].TextValue.LockBuffer(); - mCVar->SetGenericRep (value, CVAR_String); - (*opt)->mValues[Selection].TextValue.UnlockBuffer(); - } - } - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemOption_, false, false) -#endif - //============================================================================= // // This class is used to capture the key to be used as the new key binding @@ -434,879 +102,3 @@ public: IMPLEMENT_CLASS(DEnterKey, true, false) #endif -//============================================================================= -// -// // Edit a key binding, Action is the CCMD to bind -// -//============================================================================= - -class DOptionMenuItemControl_ : public DOptionMenuItem -{ - DECLARE_CLASS(DOptionMenuItemControl_, DOptionMenuItemOption_) - FKeyBindings *mBindings; - int mInput; - bool mWaiting; - - DOptionMenuItemControl_() {} -public: - - DOptionMenuItemControl_(const char *label, const char *menu, FKeyBindings *bindings) - : DOptionMenuItem(label, menu) - { - mBindings = bindings; - mWaiting = false; - } - - - //============================================================================= - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight: - (selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor)); - - char description[64]; - int Key1, Key2; - - mBindings->GetKeysForCommand(mAction, &Key1, &Key2); - C_NameKeys (description, Key1, Key2); - if (description[0]) - { - M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description); - } - else - { - screen->DrawText(SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---", - DTA_CleanNoMove_1, true, TAG_DONE); - } - return indent; - } - - //============================================================================= - bool MenuEvent(int mkey, bool fromcontroller) - { - if (mkey == MKEY_Input) - { - mWaiting = false; - mBindings->SetBind(mInput, mAction); - return true; - } - else if (mkey == MKEY_Clear) - { - mBindings->UnbindACommand(mAction); - return true; - } - else if (mkey == MKEY_Abort) - { - mWaiting = false; - return true; - } - return false; - } - - bool Activate() - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - mWaiting = true; - DMenu *input = new DEnterKey(DMenu::CurrentMenu, &mInput); - M_ActivateMenu(input); - return true; - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemControl_, false, false) -#endif -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuItemStaticText_ : public DOptionMenuItem -{ - DECLARE_CLASS(DOptionMenuItemStaticText_, DOptionMenuItem) - EColorRange mColor; - - DOptionMenuItemStaticText_() {} -public: - DOptionMenuItemStaticText_(const char *label, bool header) - : DOptionMenuItem(label, NAME_None, true) - { - mColor = header ? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; - } - - DOptionMenuItemStaticText_(const char *label, EColorRange cr) - : DOptionMenuItem(label, NAME_None, true) - { - mColor = cr; - } - - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - drawLabel(indent, y, mColor); - return -1; - } - - bool Selectable() - { - return false; - } - -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemStaticText_, false, false) -#endif - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuItemStaticTextSwitchable_ : public DOptionMenuItem -{ - DECLARE_CLASS(DOptionMenuItemStaticTextSwitchable_, DOptionMenuItem) - EColorRange mColor; - FString mAltText; - int mCurrent; - - DOptionMenuItemStaticTextSwitchable_() {} -public: - DOptionMenuItemStaticTextSwitchable_(const char *label, const char *label2, FName action, EColorRange cr) - : DOptionMenuItem(label, action, true) - { - mColor = cr; - mAltText = label2; - mCurrent = 0; - } - - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars(); - if (*txt == '$') txt = GStrings(txt + 1); - int w = SmallFont->StringWidth(txt) * CleanXfac_1; - int x = (screen->GetWidth() - w) / 2; - screen->DrawText (SmallFont, mColor, x, y, txt, DTA_CleanNoMove_1, true, TAG_DONE); - return -1; - } - - bool SetValue(int i, int val) - { - if (i == 0) - { - mCurrent = val; - return true; - } - return false; - } - - bool SetString(int i, const char *newtext) - { - if (i == 0) - { - mAltText = newtext; - return true; - } - return false; - } - - bool Selectable() - { - return false; - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemStaticTextSwitchable_, false, false) -#endif - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderBase_ : public DOptionMenuItem -{ - DECLARE_ABSTRACT_CLASS(DOptionMenuSliderBase_, DOptionMenuItem) - // action is a CVAR - double mMin, mMax, mStep; - int mShowValue; - int mDrawX; - int mSliderShort; - -protected: - DOptionMenuSliderBase_() {} -public: - DOptionMenuSliderBase_(const char *label, double min, double max, double step, int showval) - : DOptionMenuItem(label, NAME_None) - { - mMin = min; - mMax = max; - mStep = step; - mShowValue = showval; - mDrawX = 0; - mSliderShort = 0; - } - - virtual double GetSliderValue() = 0; - virtual void SetSliderValue(double val) = 0; - - //============================================================================= - // - // Draw a slider. Set fracdigits negative to not display the current value numerically. - // - //============================================================================= - - void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) - { - char textbuf[16]; - double range; - int maxlen = 0; - int right = x + (12*8 + 4) * CleanXfac_1; - int cy = y + (OptionSettings.mLinespacing-8)*CleanYfac_1; - - range = max - min; - double ccur = clamp(cur, min, max) - min; - - if (fracdigits >= 0) - { - mysnprintf(textbuf, countof(textbuf), "%.*f", fracdigits, max); - maxlen = SmallFont->StringWidth(textbuf) * CleanXfac_1; - } - - mSliderShort = right + maxlen > screen->GetWidth(); - - if (!mSliderShort) - { - M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); - } - else - { - // On 320x200 we need a shorter slider - M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); - right -= 5*8*CleanXfac_1; - } - - if (fracdigits >= 0 && right + maxlen <= screen->GetWidth()) - { - mysnprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur); - screen->DrawText(SmallFont, CR_DARKGRAY, right, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE); - } - } - - - //============================================================================= - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); - mDrawX = indent + CURSORSPACE; - DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); - return indent; - } - - //============================================================================= - bool MenuEvent (int mkey, bool fromcontroller) - { - double value = GetSliderValue(); - - if (mkey == MKEY_Left) - { - value -= mStep; - } - else if (mkey == MKEY_Right) - { - value += mStep; - } - else - { - return DOptionMenuItem::MenuEvent(mkey, fromcontroller); - } - if (fabs(value) < FLT_EPSILON) value = 0; - SetSliderValue(clamp(value, mMin, mMax)); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); - return true; - } - - bool MouseEvent(int type, int x, int y) - { - DOptionMenu *lm = static_cast(DMenu::CurrentMenu); - if (type != DMenu::MOUSE_Click) - { - if (!lm->CheckFocus(this)) return false; - } - if (type == DMenu::MOUSE_Release) - { - lm->ReleaseFocus(); - } - - int slide_left = mDrawX+8*CleanXfac_1; - int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 12 char cells with 8 pixels each. - - if (type == DMenu::MOUSE_Click) - { - if (x < slide_left || x >= slide_right) return true; - } - - x = clamp(x, slide_left, slide_right); - double v = mMin + ((x - slide_left) * (mMax - mMin)) / (slide_right - slide_left); - if (v != GetSliderValue()) - { - SetSliderValue(v); - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); - } - if (type == DMenu::MOUSE_Click) - { - lm->SetFocus(this); - } - return true; - } - -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderBase_, true, false) -#endif - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderCVar_ : public DOptionMenuSliderBase_ -{ - DECLARE_CLASS(DOptionMenuSliderCVar_, DOptionMenuSliderBase_) - FBaseCVar *mCVar; - - DOptionMenuSliderCVar_() {} -public: - DOptionMenuSliderCVar_(const char *label, const char *menu, double min, double max, double step, int showval) - : DOptionMenuSliderBase_(label, min, max, step, showval) - { - mCVar = FindCVar(menu, NULL); - } - - double GetSliderValue() - { - if (mCVar != NULL) - { - return mCVar->GetGenericRep(CVAR_Float).Float; - } - else - { - return 0; - } - } - - void SetSliderValue(double val) - { - if (mCVar != NULL) - { - UCVarValue value; - value.Float = (float)val; - mCVar->SetGenericRep(value, CVAR_Float); - } - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderCVar_, false, false) -#endif - -//============================================================================= -// -// -// -//============================================================================= - -class DOptionMenuSliderVar_ : public DOptionMenuSliderBase_ -{ - DECLARE_CLASS(DOptionMenuSliderVar_, DOptionMenuSliderBase_) - float *mPVal; - - DOptionMenuSliderVar_() {} -public: - - DOptionMenuSliderVar_(const char *label, float *pVal, double min, double max, double step, int showval) - : DOptionMenuSliderBase_(label, min, max, step, showval) - { - mPVal = pVal; - } - - double GetSliderValue() - { - return *mPVal; - } - - void SetSliderValue(double val) - { - *mPVal = (float)val; - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuSliderVar_, false, false) -#endif - -//============================================================================= -// -// // Edit a key binding, Action is the CCMD to bind -// -//============================================================================= - -class DOptionMenuItemColorPicker_ : public DOptionMenuItem -{ - DECLARE_CLASS(DOptionMenuItemColorPicker_, DOptionMenuItem) - FColorCVar *mCVar; - - DOptionMenuItemColorPicker_() {} -public: - - enum - { - CPF_RESET = 0x20001, - }; - - DOptionMenuItemColorPicker_(const char *label, const char *menu) - : DOptionMenuItem(label, menu) - { - FBaseCVar *cv = FindCVar(menu, NULL); - if (cv != NULL && cv->GetRealType() == CVAR_Color) - { - mCVar = (FColorCVar*)cv; - } - else mCVar = NULL; - } - - //============================================================================= - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); - - if (mCVar != NULL) - { - int box_x = indent + CURSORSPACE; - int box_y = y + CleanYfac_1; - screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + OptionSettings.mLinespacing*CleanYfac_1, - -1, (uint32)*mCVar | 0xff000000); - } - return indent; - } - - bool SetValue(int i, int v) - { - if (i == CPF_RESET && mCVar != NULL) - { - mCVar->ResetToDefault(); - return true; - } - return false; - } - - bool Activate() - { - if (mCVar != NULL) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - DMenu *picker = StartPickerMenu(DMenu::CurrentMenu, mLabel, mCVar); - if (picker != NULL) - { - M_ActivateMenu(picker); - return true; - } - } - return false; - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuItemColorPicker_, false, false) -#endif - -class DOptionMenuScreenResolutionLine_ : public DOptionMenuItem -{ - DECLARE_CLASS(DOptionMenuScreenResolutionLine_, DOptionMenuItem) - - FString mResTexts[3]; - int mSelection; - int mHighlight; - int mMaxValid; - - DOptionMenuScreenResolutionLine_() {} -public: - - enum - { - SRL_INDEX = 0x30000, - SRL_SELECTION = 0x30003, - SRL_HIGHLIGHT = 0x30004, - }; - - DOptionMenuScreenResolutionLine_(const char *action) - : DOptionMenuItem("", action) - { - mSelection = 0; - mHighlight = -1; - } - - bool SetValue(int i, int v) - { - if (i == SRL_SELECTION) - { - mSelection = v; - return true; - } - else if (i == SRL_HIGHLIGHT) - { - mHighlight = v; - return true; - } - return false; - } - - bool GetValue(int i, int *v) - { - if (i == SRL_SELECTION) - { - *v = mSelection; - return true; - } - return false; - } - - bool SetString(int i, const char *newtext) - { - if (i >= SRL_INDEX && i <= SRL_INDEX+2) - { - mResTexts[i-SRL_INDEX] = newtext; - if (mResTexts[0].IsEmpty()) mMaxValid = -1; - else if (mResTexts[1].IsEmpty()) mMaxValid = 0; - else if (mResTexts[2].IsEmpty()) mMaxValid = 1; - else mMaxValid = 2; - return true; - } - return false; - } - - bool GetString(int i, char *s, int len) - { - if (i >= SRL_INDEX && i <= SRL_INDEX+2) - { - strncpy(s, mResTexts[i-SRL_INDEX], len-1); - s[len-1] = 0; - return true; - } - return false; - } - - bool MenuEvent (int mkey, bool fromcontroller) - { - if (mkey == MKEY_Left) - { - if (--mSelection < 0) mSelection = mMaxValid; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - } - else if (mkey == MKEY_Right) - { - if (++mSelection > mMaxValid) mSelection = 0; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - } - else - { - return DOptionMenuItem::MenuEvent(mkey, fromcontroller); - } - return false; - } - - bool MouseEvent(int type, int x, int y) - { - int colwidth = screen->GetWidth() / 3; - mSelection = x / colwidth; - return DOptionMenuItem::MouseEvent(type, x, y); - } - - bool Activate() - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - M_SetVideoMode(); - return true; - } - - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) - { - int colwidth = screen->GetWidth() / 3; - EColorRange color; - - for (int x = 0; x < 3; x++) - { - if (selected && mSelection == x) - color = OptionSettings.mFontColorSelection; - else if (x == mHighlight) - color = OptionSettings.mFontColorHighlight; - else - color = OptionSettings.mFontColorValue; - - screen->DrawText (SmallFont, color, colwidth * x + 20 * CleanXfac_1, y, mResTexts[x], DTA_CleanNoMove_1, true, TAG_DONE); - } - return colwidth * mSelection + 20 * CleanXfac_1 - CURSORSPACE; - } - - bool Selectable() - { - return mMaxValid >= 0; - } - - void Ticker() - { - if (Selectable() && mSelection > mMaxValid) - { - mSelection = mMaxValid; - } - } -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuScreenResolutionLine_, false, false) -#endif - -//============================================================================= -// -// [TP] DOptionMenuFieldBase_ -// -// Base class for input fields -// -//============================================================================= - -class DOptionMenuFieldBase_ : public DOptionMenuItem -{ - DECLARE_ABSTRACT_CLASS(DOptionMenuFieldBase_, DOptionMenuItem) - -protected: - DOptionMenuFieldBase_() {} -public: - DOptionMenuFieldBase_ ( const char* label, const char* menu, const char* graycheck ) : - DOptionMenuItem ( label, menu ), - mCVar ( FindCVar( mAction, NULL )), - mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {} - - const char* GetCVarString() - { - if ( mCVar == NULL ) - return ""; - - return mCVar->GetHumanString(); - } - - virtual FString Represent() - { - return GetCVarString(); - } - - int Draw ( DOptionMenuDescriptor*, int y, int indent, bool selected ) - { - bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool ); - drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); - int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0; - - screen->DrawText( SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, - Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE ); - return indent; - } - - bool GetString ( int i, char* s, int len ) - { - if ( i == 0 ) - { - strncpy( s, GetCVarString(), len ); - s[len - 1] = '\0'; - return true; - } - - return false; - } - - bool SetString ( int i, const char* s ) - { - if ( i == 0 ) - { - if ( mCVar ) - { - UCVarValue vval; - vval.String = s; - mCVar->SetGenericRep( vval, CVAR_String ); - } - - return true; - } - - return false; - } - -protected: - // Action is a CVar in this class and derivatives. - FBaseCVar* mCVar; - FBaseCVar* mGrayCheck; -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuFieldBase_, true, false) -#endif - -//============================================================================= -// -// [TP] DOptionMenuTextField_ -// -// A text input field widget, for use with string CVars. -// -//============================================================================= - -class DOptionMenuTextField_ : public DOptionMenuFieldBase_ -{ - DECLARE_CLASS(DOptionMenuTextField_, DOptionMenuFieldBase_) - - DOptionMenuTextField_() {} -public: - DOptionMenuTextField_ ( const char *label, const char* menu, const char* graycheck ) : - DOptionMenuFieldBase_ ( label, menu, graycheck ), - mEntering ( false ) {} - - FString Represent() - { - FString text = mEntering ? mEditName : GetCVarString(); - - if ( mEntering ) - text += ( gameinfo.gametype & GAME_DoomStrifeChex ) ? '_' : '['; - - return text; - } - - int Draw(DOptionMenuDescriptor*desc, int y, int indent, bool selected) - { - if (mEntering) - { - // reposition the text so that the cursor is visible when in entering mode. - FString text = Represent(); - int tlen = SmallFont->StringWidth(text) * CleanXfac_1; - int newindent = screen->GetWidth() - tlen - CURSORSPACE; - if (newindent < indent) indent = newindent; - } - return DOptionMenuFieldBase_::Draw(desc, y, indent, selected); - } - - bool MenuEvent ( int mkey, bool fromcontroller ) - { - if ( mkey == MKEY_Enter ) - { - S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE ); - strcpy( mEditName, GetCVarString() ); - mEntering = true; - DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); - M_ActivateMenu( input ); - return true; - } - else if ( mkey == MKEY_Input ) - { - if ( mCVar ) - { - UCVarValue vval; - vval.String = mEditName; - mCVar->SetGenericRep( vval, CVAR_String ); - } - - mEntering = false; - return true; - } - else if ( mkey == MKEY_Abort ) - { - mEntering = false; - return true; - } - - return DOptionMenuItem::MenuEvent( mkey, fromcontroller ); - } - -private: - bool mEntering; - char mEditName[128]; -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuTextField_, false, false) -#endif - -//============================================================================= -// -// [TP] FOptionMenuNumberField -// -// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e. -// where the user is interested in the exact value specifically) -// -//============================================================================= - -class DOptionMenuNumberField_ : public DOptionMenuFieldBase_ -{ - DECLARE_CLASS(DOptionMenuNumberField_, DOptionMenuFieldBase_) - - DOptionMenuNumberField_() {} -public: - DOptionMenuNumberField_ ( const char *label, const char* menu, float minimum, float maximum, - float step, const char* graycheck ) - : DOptionMenuFieldBase_ ( label, menu, graycheck ), - mMinimum ( minimum ), - mMaximum ( maximum ), - mStep ( step ) - { - if ( mMaximum <= mMinimum ) - swapvalues( mMinimum, mMaximum ); - - if ( mStep <= 0 ) - mStep = 1; - } - - bool MenuEvent ( int mkey, bool fromcontroller ) - { - if ( mCVar ) - { - float value = mCVar->GetGenericRep( CVAR_Float ).Float; - - if ( mkey == MKEY_Left ) - { - value -= mStep; - - if ( value < mMinimum ) - value = mMaximum; - } - else if ( mkey == MKEY_Right || mkey == MKEY_Enter ) - { - value += mStep; - - if ( value > mMaximum ) - value = mMinimum; - } - else - return DOptionMenuItem::MenuEvent( mkey, fromcontroller ); - - UCVarValue vval; - vval.Float = value; - mCVar->SetGenericRep( vval, CVAR_Float ); - S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE ); - } - - return true; - } - -private: - float mMinimum; - float mMaximum; - float mStep; -}; - -#ifndef NO_IMP -IMPLEMENT_CLASS(DOptionMenuNumberField_, false, false) -#endif diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 882e8b593..0ecb23b87 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -101,19 +101,21 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE) CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { + const int OptionMenuItemOptionBase_OP_VALUES = 0x11001; + DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) { - DOptionMenuItem *it = opt->GetItem("menu_screenratios"); + DMenuItemBase *it = opt->GetItem("menu_screenratios"); if (it != NULL) { if (self) { - it->SetString(DOptionMenuItemOptionBase_::OP_VALUES, "RatiosTFT"); + it->SetString(OptionMenuItemOptionBase_OP_VALUES, "RatiosTFT"); } else { - it->SetString(DOptionMenuItemOptionBase_::OP_VALUES, "Ratios"); + it->SetString(OptionMenuItemOptionBase_OP_VALUES, "Ratios"); } } } @@ -131,6 +133,15 @@ CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //============================================================================= +struct OptionMenuItemScreenResolution // temporary workaround +{ + enum EValues + { + SRL_INDEX = 0x30000, + SRL_SELECTION = 0x30003, + SRL_HIGHLIGHT = 0x30004, + }; +}; class DVideoModeMenu : public DOptionMenu { DECLARE_CLASS(DVideoModeMenu, DOptionMenu) @@ -148,9 +159,9 @@ public: mDesc->mSelectedItem < (int)mDesc->mItems.Size()) { int sel; - bool selected = mDesc->mItems[mDesc->mSelectedItem]->GetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, &sel); + bool selected = mDesc->mItems[mDesc->mSelectedItem]->GetValue(OptionMenuItemScreenResolution::SRL_SELECTION, &sel); bool res = Super::MenuEvent(mkey, fromcontroller); - if (selected) mDesc->mItems[mDesc->mSelectedItem]->SetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, sel); + if (selected) mDesc->mItems[mDesc->mSelectedItem]->SetValue(OptionMenuItemScreenResolution::SRL_SELECTION, sel); return res; } return Super::MenuEvent(mkey, fromcontroller); @@ -236,10 +247,10 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) { for (i = NAME_res_0; i<= NAME_res_9; i++) { - DOptionMenuItem *it = opt->GetItem((ENamedName)i); + DMenuItemBase *it = opt->GetItem((ENamedName)i); if (it != NULL) { - it->SetValue(DOptionMenuScreenResolutionLine_::SRL_HIGHLIGHT, -1); + it->SetValue(OptionMenuItemScreenResolution::SRL_HIGHLIGHT, -1); for (c = 0; c < 3; c++) { bool haveMode = false; @@ -260,16 +271,16 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) { if (width == hiwidth && height == hiheight) { - it->SetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, c); - it->SetValue(DOptionMenuScreenResolutionLine_::SRL_HIGHLIGHT, c); + it->SetValue(OptionMenuItemScreenResolution::SRL_SELECTION, c); + it->SetValue(OptionMenuItemScreenResolution::SRL_HIGHLIGHT, c); } mysnprintf (strtemp, countof(strtemp), "%dx%d%s", width, height, letterbox?TEXTCOLOR_BROWN" LB":""); - it->SetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+c, strtemp); + it->SetString(OptionMenuItemScreenResolution::SRL_INDEX+c, strtemp); } else { - it->SetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+c, ""); + it->SetString(OptionMenuItemScreenResolution::SRL_INDEX+c, ""); } } } @@ -359,12 +370,12 @@ static bool GetSelectedSize (int *width, int *height) { int line = opt->mSelectedItem; int hsel; - DOptionMenuItem *it = opt->mItems[line]; - if (it->GetValue(DOptionMenuScreenResolutionLine_::SRL_SELECTION, &hsel)) + DMenuItemBase *it = opt->mItems[line]; + if (it->GetValue(OptionMenuItemScreenResolution::SRL_SELECTION, &hsel)) { char buffer[32]; char *breakpt; - if (it->GetString(DOptionMenuScreenResolutionLine_::SRL_INDEX+hsel, buffer, sizeof(buffer))) + if (it->GetString(OptionMenuItemScreenResolution::SRL_INDEX+hsel, buffer, sizeof(buffer))) { *width = (int)strtoll (buffer, &breakpt, 10); *height = (int)strtoll (breakpt+1, NULL, 10); @@ -428,7 +439,7 @@ static void SetModesMenu (int w, int h, int bits) DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) { - DOptionMenuItem *it; + DMenuItemBase *it; if (testingmode <= 1) { it = opt->GetItem(NAME_VMEnterText); diff --git a/wadsrc/static/zscript/menu/joystickmenu.txt b/wadsrc/static/zscript/menu/joystickmenu.txt index 57f5226e7..2e37aadf6 100644 --- a/wadsrc/static/zscript/menu/joystickmenu.txt +++ b/wadsrc/static/zscript/menu/joystickmenu.txt @@ -129,7 +129,7 @@ class OptionMenuItemJoyMap : OptionMenuItemOptionBase { int mAxis; - void Init(String label, int axis, String values, int center) + void Init(String label, int axis, Name values, int center) { Super.Init(label, 'none', values, null, center); mAxis = axis; diff --git a/wadsrc/static/zscript/menu/menuitembase.txt b/wadsrc/static/zscript/menu/menuitembase.txt index 2840b41b9..6123cabd8 100644 --- a/wadsrc/static/zscript/menu/menuitembase.txt +++ b/wadsrc/static/zscript/menu/menuitembase.txt @@ -38,5 +38,8 @@ native virtual bool MenuEvent (int mkey, bool fromcontroller);// { return false; virtual int GetY() { return mYpos; } virtual int GetX() { return mXpos; } virtual void SetX(int x) { mXpos = x; } + virtual int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) { return indent; } + + } diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index 85687d715..c3e6e0bd1 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -57,11 +57,6 @@ class OptionMenuItem : MenuItemBase native screen.DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); } - virtual int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) - { - return indent; - } - int CursorSpace() { return (14 * CleanXfac_1); @@ -195,7 +190,7 @@ class OptionMenuItemOptionBase : OptionMenuItem const OP_VALUES = 0x11001; - void Init(String label, Name command, Name values, CVar graycheck, int center) + protected void Init(String label, Name command, Name values, CVar graycheck, int center) { Super.Init(label, command); mValues = values; @@ -295,7 +290,7 @@ class OptionMenuItemOption : OptionMenuItemOptionBase { CVar mCVar; - void Init(String label, Name command, String values, CVar graycheck, int center) + void Init(String label, Name command, Name values, CVar graycheck = null, int center = 0) { Super.Init(label, command, values, graycheck, center); mCVar = CVar.FindCVar(mAction); @@ -590,7 +585,7 @@ class OptionMenuSliderBase : OptionMenuItem int mDrawX; int mSliderShort; - void Init(String label, double min, double max, double step, int showval) + protected void Init(String label, double min, double max, double step, int showval) { Super.Init(label, 'None'); mMin = min; @@ -731,11 +726,11 @@ class OptionMenuSliderBase : OptionMenuItem // //============================================================================= -class OptionMenuSliderCVar : OptionMenuSliderBase +class OptionMenuItemSlider : OptionMenuSliderBase { CVar mCVar; - void Init(String label, Name command, double min, double max, double step, int showval) + void Init(String label, Name command, double min, double max, double step, int showval = 1) { Super.Init(label, min, max, step, showval); mCVar =CVar.FindCVar(command); @@ -825,7 +820,7 @@ class OptionMenuItemColorPicker : OptionMenuItem } -class OptionMenuScreenResolutionLine : OptionMenuItem +class OptionMenuItemScreenResolution : OptionMenuItem { String mResTexts[3]; int mSelection; @@ -1033,7 +1028,7 @@ class OptionMenuFieldBase : OptionMenuItem // //============================================================================= -class OptionMenuTextField : OptionMenuFieldBase +class OptionMenuItemTextField : OptionMenuFieldBase { void Init (String label, Name command, CVar graycheck = null) { @@ -1102,9 +1097,9 @@ class OptionMenuTextField : OptionMenuFieldBase // //============================================================================= -class OptionMenuNumberField : OptionMenuFieldBase +class OptionMenuItemNumberField : OptionMenuFieldBase { - void Init (String label, Name command, float minimum, float maximum, float step, CVar graycheck = null) + void Init (String label, Name command, float minimum = 0, float maximum = 100, float step = 1, CVar graycheck = null) { Super.Init(label, command, graycheck); mMinimum = min(minimum, maximum);