mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- almost done with TextEnterMenu.
This commit is contained in:
parent
0c41a9dee7
commit
f5a0f6b3bf
8 changed files with 255 additions and 256 deletions
|
@ -1195,6 +1195,8 @@ CCMD(undocolorpic)
|
|||
|
||||
|
||||
DEFINE_FIELD(DMenu, mParentMenu)
|
||||
DEFINE_FIELD(DMenu, mMouseCapture);
|
||||
DEFINE_FIELD(DMenu, mBackbuttonSelected);
|
||||
|
||||
DEFINE_FIELD(DMenuDescriptor, mMenuName)
|
||||
DEFINE_FIELD(DMenuDescriptor, mNetgameMessage)
|
||||
|
|
|
@ -253,9 +253,7 @@ class DMenu : public DObject
|
|||
DECLARE_CLASS (DMenu, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
protected:
|
||||
bool mMouseCapture;
|
||||
bool mBackbuttonSelected;
|
||||
|
||||
|
||||
public:
|
||||
enum
|
||||
|
@ -271,6 +269,8 @@ public:
|
|||
};
|
||||
|
||||
TObjPtr<DMenu> mParentMenu;
|
||||
bool mMouseCapture;
|
||||
bool mBackbuttonSelected;
|
||||
|
||||
DMenu(DMenu *parent = NULL);
|
||||
virtual bool Responder (event_t *ev);
|
||||
|
@ -354,7 +354,7 @@ extern FOptionMap OptionValues;
|
|||
|
||||
class DTextEnterMenu : public DMenu
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu)
|
||||
DECLARE_CLASS(DTextEnterMenu, DMenu)
|
||||
|
||||
public:
|
||||
FString mEnterString;
|
||||
|
@ -370,12 +370,7 @@ public:
|
|||
bool AllowColors;
|
||||
|
||||
|
||||
// [TP] Added allowcolors
|
||||
DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false);
|
||||
|
||||
bool MenuEvent (int mkey, bool fromcontroller);
|
||||
bool Responder(event_t *ev);
|
||||
bool MouseEvent(int type, int x, int y);
|
||||
DTextEnterMenu() {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,249 +44,10 @@
|
|||
// [TP] New #includes
|
||||
#include "v_text.h"
|
||||
|
||||
IMPLEMENT_CLASS(DTextEnterMenu, true, false)
|
||||
|
||||
#define INPUTGRID_WIDTH 13
|
||||
#define INPUTGRID_HEIGHT 5
|
||||
|
||||
// Heretic and Hexen do not, by default, come with glyphs for all of these
|
||||
// characters. Oh well. Doom and Strife do.
|
||||
static const char InputGridChars[INPUTGRID_WIDTH * INPUTGRID_HEIGHT] =
|
||||
"ABCDEFGHIJKLM"
|
||||
"NOPQRSTUVWXYZ"
|
||||
"0123456789+-="
|
||||
".,!?@'\":;[]()"
|
||||
"<>^#$%&*/_ \b";
|
||||
|
||||
IMPLEMENT_CLASS(DTextEnterMenu, false, false)
|
||||
|
||||
CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
// [TP] Added allowcolors
|
||||
DTextEnterMenu::DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors)
|
||||
: DMenu(parent)
|
||||
{
|
||||
mEnterString = textbuffer;
|
||||
mEnterSize = maxlen < 0 ? UINT_MAX : unsigned(maxlen);
|
||||
mSizeMode = sizemode;
|
||||
mInputGridOkay = showgrid || m_showinputgrid;
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
InputGridX = INPUTGRID_WIDTH - 1;
|
||||
InputGridY = INPUTGRID_HEIGHT - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are naming a new save, don't start the cursor on "end".
|
||||
InputGridX = 0;
|
||||
InputGridY = 0;
|
||||
}
|
||||
AllowColors = allowcolors; // [TP]
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool DTextEnterMenu::Responder(event_t *ev)
|
||||
{
|
||||
if (ev->type == EV_GUI_Event)
|
||||
{
|
||||
// Save game and player name string input
|
||||
if (ev->subtype == EV_GUI_Char)
|
||||
{
|
||||
mInputGridOkay = false;
|
||||
if (mEnterString.Len() < mEnterSize &&
|
||||
(mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8))
|
||||
{
|
||||
mEnterString.AppendFormat("%c", (char)ev->data1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
char ch = (char)ev->data1;
|
||||
if ((ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) && ch == '\b')
|
||||
{
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Len() - 1);
|
||||
}
|
||||
}
|
||||
else if (ev->subtype == EV_GUI_KeyDown)
|
||||
{
|
||||
if (ch == GK_ESCAPE)
|
||||
{
|
||||
DMenu *parent = mParentMenu;
|
||||
Close();
|
||||
parent->CallMenuEvent(MKEY_Abort, false);
|
||||
return true;
|
||||
}
|
||||
else if (ch == '\r')
|
||||
{
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
// [TP] If we allow color codes, colorize the string now.
|
||||
if (AllowColors)
|
||||
mEnterString = strbin1(mEnterString);
|
||||
|
||||
DMenu *parent = mParentMenu;
|
||||
parent->CallMenuEvent(MKEY_Input, false);
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Super::Responder(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool DTextEnterMenu::MouseEvent(int type, int x, int y)
|
||||
{
|
||||
const int cell_width = 18 * CleanXfac;
|
||||
const int cell_height = 12 * CleanYfac;
|
||||
const int screen_y = screen->GetHeight() - INPUTGRID_HEIGHT * cell_height;
|
||||
const int screen_x = (screen->GetWidth() - INPUTGRID_WIDTH * cell_width) / 2;
|
||||
|
||||
if (x >= screen_x && x < screen_x + INPUTGRID_WIDTH * cell_width && y >= screen_y)
|
||||
{
|
||||
InputGridX = (x - screen_x) / cell_width;
|
||||
InputGridY = (y - screen_y) / cell_height;
|
||||
if (type == DMenu::MOUSE_Release)
|
||||
{
|
||||
if (CallMenuEvent(MKEY_Enter, true))
|
||||
{
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
|
||||
if (m_use_mouse == 2) InputGridX = InputGridY = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InputGridX = InputGridY = -1;
|
||||
}
|
||||
return Super::MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller)
|
||||
{
|
||||
if (key == MKEY_Back)
|
||||
{
|
||||
mParentMenu->CallMenuEvent(MKEY_Abort, false);
|
||||
return Super::MenuEvent(key, fromcontroller);
|
||||
}
|
||||
if (fromcontroller)
|
||||
{
|
||||
mInputGridOkay = true;
|
||||
}
|
||||
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (InputGridX == -1 || InputGridY == -1)
|
||||
{
|
||||
InputGridX = InputGridY = 0;
|
||||
}
|
||||
switch (key)
|
||||
{
|
||||
case MKEY_Down:
|
||||
InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT;
|
||||
return true;
|
||||
|
||||
case MKEY_Up:
|
||||
InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT;
|
||||
return true;
|
||||
|
||||
case MKEY_Right:
|
||||
InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH;
|
||||
return true;
|
||||
|
||||
case MKEY_Left:
|
||||
InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH;
|
||||
return true;
|
||||
|
||||
case MKEY_Clear:
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Len() - 1);
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Enter:
|
||||
assert(unsigned(InputGridX) < INPUTGRID_WIDTH && unsigned(InputGridY) < INPUTGRID_HEIGHT);
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
ch = InputGridChars[InputGridX + InputGridY * INPUTGRID_WIDTH];
|
||||
if (ch == 0) // end
|
||||
{
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
DMenu *parent = mParentMenu;
|
||||
Close();
|
||||
parent->CallMenuEvent(MKEY_Input, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (ch == '\b') // bs
|
||||
{
|
||||
if (mEnterString.IsNotEmpty())
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Len() - 1);
|
||||
}
|
||||
}
|
||||
else if (mEnterString.Len() < mEnterSize &&
|
||||
(mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8))
|
||||
{
|
||||
mEnterString += char(ch);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
break; // Keep GCC quiet
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DTextEnterMenu, Open)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_OBJECT(parent, DMenu);
|
||||
PARAM_STRING(text);
|
||||
PARAM_INT(maxlen);
|
||||
PARAM_INT(sizemode);
|
||||
PARAM_BOOL(fromcontroller);
|
||||
auto m = new DTextEnterMenu(parent, text.GetChars(), maxlen, sizemode, fromcontroller, false);
|
||||
M_ActivateMenu(m);
|
||||
ACTION_RETURN_OBJECT(m);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DTextEnterMenu, mEnterString);
|
||||
DEFINE_FIELD(DTextEnterMenu, mEnterSize);
|
||||
DEFINE_FIELD(DTextEnterMenu, mEnterPos);
|
||||
|
|
|
@ -1213,10 +1213,12 @@ DEFINE_ACTION_FUNCTION(FStringStruct, Mid)
|
|||
ACTION_RETURN_STRING(s);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Len)
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Truncate)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
ACTION_RETURN_INT((int)self->Len());
|
||||
PARAM_UINT(len);
|
||||
self->Truncate(len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CharAt and CharCodeAt is how JS does it, and JS is similar here in that it doesn't have char type as int.
|
||||
|
@ -1239,3 +1241,10 @@ DEFINE_ACTION_FUNCTION(FStringStruct, CharCodeAt)
|
|||
ACTION_RETURN_INT(0);
|
||||
ACTION_RETURN_INT((*self)[pos]);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Filter)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
ACTION_RETURN_STRING(strbin1(*self));
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "doomerrors.h"
|
||||
#include "memarena.h"
|
||||
|
||||
class DObject;
|
||||
|
||||
extern FMemArena ClassDataAllocator;
|
||||
|
||||
#define MAX_RETURNS 8 // Maximum number of results a function called by script code can return
|
||||
|
|
|
@ -578,9 +578,10 @@ struct StringStruct native
|
|||
|
||||
native void Replace(String pattern, String replacement);
|
||||
native String Mid(int pos = 0, int len = 2147483647);
|
||||
native int Len();
|
||||
native void Truncate(int newlen);
|
||||
native String CharAt(int pos);
|
||||
native int CharCodeAt(int pos);
|
||||
native String Filter();
|
||||
}
|
||||
|
||||
class Floor : Thinker native
|
||||
|
|
|
@ -87,6 +87,8 @@ class Menu : Object native
|
|||
};
|
||||
|
||||
native Menu mParentMenu;
|
||||
native bool mMouseCapture;
|
||||
native bool mBackbuttonSelected;
|
||||
|
||||
void Init(Menu parent)
|
||||
{
|
||||
|
|
|
@ -16,8 +16,46 @@ class TextEnterMenu : Menu native
|
|||
native int InputGridY;
|
||||
native bool AllowColors;
|
||||
|
||||
native static TextEnterMenu Open(Menu parent, String text, int maxlen, int sizemode, bool fromcontroller);
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
// [TP] Added allowcolors
|
||||
private void Init(Menu parent, String textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors)
|
||||
{
|
||||
Super.init(parent);
|
||||
mEnterString = textbuffer;
|
||||
mEnterSize = maxlen < 0 ? 0x7fffffff : maxlen;
|
||||
mSizeMode = sizemode;
|
||||
mInputGridOkay = showgrid || m_showinputgrid;
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
InputGridX = INPUTGRID_WIDTH - 1;
|
||||
InputGridY = INPUTGRID_HEIGHT - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are naming a new save, don't start the cursor on "end".
|
||||
InputGridX = 0;
|
||||
InputGridY = 0;
|
||||
}
|
||||
AllowColors = allowcolors; // [TP]
|
||||
}
|
||||
|
||||
static TextEnterMenu Open(Menu parent, String textbuffer, int maxlen, int sizemode, bool showgrid = false, bool allowcolors = false)
|
||||
{
|
||||
let me = new("TextEnterMenu");
|
||||
me.Init(parent, textbuffer, maxlen, sizemode, showgrid, allowcolors);
|
||||
return me;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
String GetText()
|
||||
{
|
||||
|
@ -29,6 +67,195 @@ class TextEnterMenu : Menu native
|
|||
return mInputGridOkay;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool Responder(InputEventData ev)
|
||||
{
|
||||
if (ev.type == InputEventData.GUI_Event)
|
||||
{
|
||||
// Save game and player name string input
|
||||
if (ev.subtype == InputEventData.GUI_Char)
|
||||
{
|
||||
mInputGridOkay = false;
|
||||
if (mEnterString.Length() < mEnterSize &&
|
||||
(mSizeMode == 2/*entering player name*/ || SmallFont.StringWidth(mEnterString) < (mEnterSize-1)*8))
|
||||
{
|
||||
mEnterString.AppendFormat("%c", ev.data1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int ch = ev.data1;
|
||||
if ((ev.subtype == InputEventData.GUI_KeyDown || ev.subtype == InputEventData.GUI_KeyRepeat) && ch == 8)
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Length() - 1);
|
||||
}
|
||||
}
|
||||
else if (ev.subtype == InputEventData.GUI_KeyDown)
|
||||
{
|
||||
if (ch == UIEvent.Key_ESCAPE)
|
||||
{
|
||||
Menu parent = mParentMenu;
|
||||
Close();
|
||||
parent.MenuEvent(MKEY_Abort, false);
|
||||
return true;
|
||||
}
|
||||
else if (ch == 13)
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
// [TP] If we allow color codes, colorize the string now.
|
||||
if (AllowColors)
|
||||
mEnterString = mEnterString.Filter();
|
||||
|
||||
Menu parent = mParentMenu;
|
||||
parent.MenuEvent(MKEY_Input, false);
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev.subtype == InputEventData.GUI_KeyDown || ev.subtype == InputEventData.GUI_KeyRepeat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Super.Responder(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (mMouseCapture || m_use_mouse == 1)
|
||||
{
|
||||
int cell_width = 18 * CleanXfac;
|
||||
int cell_height = 12 * CleanYfac;
|
||||
int screen_y = screen.GetHeight() - INPUTGRID_HEIGHT * cell_height;
|
||||
int screen_x = (screen.GetWidth() - INPUTGRID_WIDTH * cell_width) / 2;
|
||||
|
||||
if (x >= screen_x && x < screen_x + INPUTGRID_WIDTH * cell_width && y >= screen_y)
|
||||
{
|
||||
InputGridX = (x - screen_x) / cell_width;
|
||||
InputGridY = (y - screen_y) / cell_height;
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
if (MenuEvent(MKEY_Enter, true))
|
||||
{
|
||||
MenuSound("menu/choose");
|
||||
if (m_use_mouse == 2) InputGridX = InputGridY = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InputGridX = InputGridY = -1;
|
||||
}
|
||||
}
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int key, bool fromcontroller)
|
||||
{
|
||||
String InputGridChars = Chars;
|
||||
if (key == MKEY_Back)
|
||||
{
|
||||
mParentMenu.MenuEvent(MKEY_Abort, false);
|
||||
return Super.MenuEvent(key, fromcontroller);
|
||||
}
|
||||
if (fromcontroller)
|
||||
{
|
||||
mInputGridOkay = true;
|
||||
}
|
||||
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (InputGridX == -1 || InputGridY == -1)
|
||||
{
|
||||
InputGridX = InputGridY = 0;
|
||||
}
|
||||
switch (key)
|
||||
{
|
||||
case MKEY_Down:
|
||||
InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT;
|
||||
return true;
|
||||
|
||||
case MKEY_Up:
|
||||
InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT;
|
||||
return true;
|
||||
|
||||
case MKEY_Right:
|
||||
InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH;
|
||||
return true;
|
||||
|
||||
case MKEY_Left:
|
||||
InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH;
|
||||
return true;
|
||||
|
||||
case MKEY_Clear:
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Length() - 1);
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Enter:
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
String c = InputGridChars.CharAt(InputGridX + InputGridY * INPUTGRID_WIDTH);
|
||||
int ch = c.CharCodeAt(0);
|
||||
if (ch == 0) // end
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
Menu parent = mParentMenu;
|
||||
Close();
|
||||
parent.MenuEvent(MKEY_Input, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (ch == 8) // bs
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
mEnterString.Truncate(mEnterString.Length() - 1);
|
||||
}
|
||||
}
|
||||
else if (mEnterString.Length() < mEnterSize &&
|
||||
(mSizeMode == 2/*entering player name*/ || SmallFont.StringWidth(mEnterString) < (mEnterSize-1)*8))
|
||||
{
|
||||
mEnterString = mEnterString .. c;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
break; // Keep GCC quiet
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue