- almost done with TextEnterMenu.

This commit is contained in:
Christoph Oelckers 2017-02-18 21:18:23 +01:00
commit f5a0f6b3bf
8 changed files with 255 additions and 256 deletions

View file

@ -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)

View file

@ -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() {}
};

View file

@ -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);

View file

@ -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));
}

View file

@ -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