diff --git a/src/menu/menu.h b/src/menu/menu.h index 3712c9065..561953d1c 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -644,9 +644,13 @@ class DTextEnterMenu : public DMenu int InputGridX; int InputGridY; + // [TP] + bool AllowColors; + public: - DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid); + // [TP] Added allowcolors + DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false); void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 819ba96ba..73101a76e 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -830,6 +830,63 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) FOptionMenuItem *it = new FOptionMenuScreenResolutionLine(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; + } + + FOptionMenuItem* it = new FOptionMenuTextField( 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; + } + } + } + + FOptionMenuItem* it = new FOptionMenuNumberField( label, cvar, + minimum, maximum, step, check ); + desc->mItems.Push( it ); + } else { sc.ScriptError("Unknown keyword '%s'", sc.String); diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index 0f35b7e1f..dc58b54ca 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -40,6 +40,8 @@ #include "d_gui.h" #include "v_font.h" #include "v_palette.h" +// [TP] New #includes +#include "v_text.h" IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu) @@ -64,7 +66,8 @@ CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //============================================================================= -DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid) +// [TP] Added allowcolors +DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors) : DMenu(parent) { mEnterString = textbuffer; @@ -83,6 +86,7 @@ DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int InputGridX = 0; InputGridY = 0; } + AllowColors = allowcolors; // [TP] } //============================================================================= @@ -140,6 +144,10 @@ bool DTextEnterMenu::Responder(event_t *ev) { if (mEnterString[0]) { + // [TP] If we allow color codes, colorize the string now. + if (AllowColors) + strbin(mEnterString); + DMenu *parent = mParentMenu; Close(); parent->MenuEvent(MKEY_Input, false); diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 439ed7ffc..5bc015369 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -31,6 +31,7 @@ **--------------------------------------------------------------------------- ** */ +#include "v_text.h" void M_DrawConText (int color, int x, int y, const char *str); @@ -943,6 +944,207 @@ public: } }; + +//============================================================================= +// +// [TP] FOptionMenuFieldBase +// +// Base class for input fields +// +//============================================================================= + +class FOptionMenuFieldBase : public FOptionMenuItem +{ +public: + FOptionMenuFieldBase ( const char* label, const char* menu, const char* graycheck ) : + FOptionMenuItem ( label, menu ), + mCVar ( FindCVar( mAction, NULL )), + mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {} + + const char* GetCVarString() + { + if ( mCVar == NULL ) + return ""; + + return mCVar->GetGenericRep( CVAR_String ).String; + } + + virtual FString Represent() + { + return GetCVarString(); + } + + int Draw ( FOptionMenuDescriptor*, 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; +}; + +//============================================================================= +// +// [TP] FOptionMenuTextField +// +// A text input field widget, for use with string CVars. +// +//============================================================================= + +class FOptionMenuTextField : public FOptionMenuFieldBase +{ +public: + FOptionMenuTextField ( const char *label, const char* menu, const char* graycheck ) : + FOptionMenuFieldBase ( label, menu, graycheck ), + mEntering ( false ) {} + + FString Represent() + { + FString text = mEntering ? mEditName : GetCVarString(); + + if ( mEntering ) + text += ( gameinfo.gametype & GAME_DoomStrifeChex ) ? '_' : '['; + + return text; + } + + 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 FOptionMenuItem::MenuEvent( mkey, fromcontroller ); + } + +private: + bool mEntering; + char mEditName[128]; +}; + +//============================================================================= +// +// [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 FOptionMenuNumberField : public FOptionMenuFieldBase +{ +public: + FOptionMenuNumberField ( const char *label, const char* menu, float minimum, float maximum, + float step, const char* graycheck ) + : FOptionMenuFieldBase ( 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 FOptionMenuItem::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 CCMD(am_restorecolors) {