mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 04:00:42 +00:00
- added GZDoom's menu script code.
This commit is contained in:
parent
82612a1330
commit
0b9c6fe559
19 changed files with 5664 additions and 2 deletions
|
@ -810,7 +810,7 @@ set (PCH_SOURCES
|
|||
common/audio/sound/oalsound.cpp
|
||||
common/audio/sound/s_environment.cpp
|
||||
common/audio/sound/s_sound.cpp
|
||||
#common/audio/sound/s_reverbedit.cpp
|
||||
common/audio/sound/s_reverbedit.cpp
|
||||
common/audio/music/music_midi_base.cpp
|
||||
common/audio/music/music.cpp
|
||||
common/audio/music/i_music.cpp
|
||||
|
|
|
@ -4,4 +4,18 @@ version "4.3"
|
|||
#include "zscript/constants.zs"
|
||||
#include "zscript/events.zs"
|
||||
#include "zscript/dictionary.zs"
|
||||
#include "zscript/gamescreen.zs"
|
||||
#include "zscript/gamescreen.zs"
|
||||
|
||||
#include "zscript/ui/menu/colorpickermenu.zs"
|
||||
#include "zscript/ui/menu/joystickmenu.zs"
|
||||
#include "zscript/ui/menu/listmenu.zs"
|
||||
#include "zscript/ui/menu/listmenuitems.zs"
|
||||
#include "zscript/ui/menu/loadsavemenu.zs"
|
||||
#include "zscript/ui/menu/menu.zs"
|
||||
#include "zscript/ui/menu/menuitembase.zs"
|
||||
#include "zscript/ui/menu/messagebox.zs"
|
||||
#include "zscript/ui/menu/optionmenu.zs"
|
||||
#include "zscript/ui/menu/optionmenuitems.zs"
|
||||
#include "zscript/ui/menu/readthis.zs"
|
||||
#include "zscript/ui/menu/reverbedit.zs"
|
||||
#include "zscript/ui/menu/textentermenu.zs"
|
||||
|
|
355
wadsrc/static/zscript/ui/menu/colorpickermenu.zs
Normal file
355
wadsrc/static/zscript/ui/menu/colorpickermenu.zs
Normal file
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
** colorpickermenu.txt
|
||||
** The color picker menu
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// This is only used by the color picker
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderVar : OptionMenuSliderBase
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
OptionMenuSliderVar Init(String label, int index, double min, double max, double step, int showval)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mIndex = index;
|
||||
return self;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
return ColorpickerMenu(Menu.GetCurrentMenu()).GetColor(mIndex);
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
ColorpickerMenu(Menu.GetCurrentMenu()).setColor(mIndex, val);
|
||||
}
|
||||
}
|
||||
|
||||
class ColorpickerMenu : OptionMenu
|
||||
{
|
||||
float mRed;
|
||||
float mGreen;
|
||||
float mBlue;
|
||||
|
||||
int mGridPosX;
|
||||
int mGridPosY;
|
||||
|
||||
int mStartItem;
|
||||
|
||||
CVar mCVar;
|
||||
|
||||
double GetColor(int index)
|
||||
{
|
||||
double v = index == 0? mRed : index == 1? mGreen : mBlue;
|
||||
return v;
|
||||
}
|
||||
|
||||
void SetColor(int index, double val)
|
||||
{
|
||||
if (index == 0) mRed = val;
|
||||
else if (index == 1) mGreen = val;
|
||||
else mBlue = val;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void Init(Menu parent, String name, OptionMenuDescriptor desc, CVar cv)
|
||||
{
|
||||
Super.Init(parent, desc);
|
||||
|
||||
mStartItem = mDesc.mItems.Size();
|
||||
mCVar = cv;
|
||||
|
||||
ResetColor();
|
||||
mGridPosX = 0;
|
||||
mGridPosY = 0;
|
||||
|
||||
// This menu uses some features that are hard to implement in an external control lump
|
||||
// so it creates its own list of menu items.
|
||||
mDesc.mItems.Resize(mStartItem+8);
|
||||
mDesc.mItems[mStartItem+0] = new ("OptionMenuItemStaticText").Init(name, false);
|
||||
mDesc.mItems[mStartItem+1] = new ("OptionMenuItemStaticText").Init(" ", false);
|
||||
mDesc.mItems[mStartItem+2] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_RED", 0, 0, 255, 15, 0);
|
||||
mDesc.mItems[mStartItem+3] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_GREEN", 1, 0, 255, 15, 0);
|
||||
mDesc.mItems[mStartItem+4] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_BLUE", 2, 0, 255, 15, 0);
|
||||
mDesc.mItems[mStartItem+5] = new ("OptionMenuItemStaticText").Init(" ", false);
|
||||
mDesc.mItems[mStartItem+6] = new ("OptionMenuItemCommand").Init("$TXT_UNDOCHANGES", "undocolorpic");
|
||||
mDesc.mItems[mStartItem+7] = new ("OptionMenuItemStaticText").Init(" ", false);
|
||||
mDesc.mSelectedItem = mStartItem + 2;
|
||||
mDesc.mIndent = 0;
|
||||
mDesc.CalcIndent();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Down:
|
||||
if (mDesc.mSelectedItem == mStartItem+6) // last valid item
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
mGridPosY = 0;
|
||||
// let it point to the last static item so that the super class code still has a valid item
|
||||
mDesc.mSelectedItem = mStartItem+7;
|
||||
return true;
|
||||
}
|
||||
else if (mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
if (mGridPosY < 15)
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
mGridPosY++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_Up:
|
||||
if (mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
if (mGridPosY > 0)
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
mGridPosY--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
mDesc.mSelectedItem = mStartItem+6;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_Left:
|
||||
if (mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
if (--mGridPosX < 0) mGridPosX = 15;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_Right:
|
||||
if (mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
if (++mGridPosX > 15) mGridPosX = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_Enter:
|
||||
if (mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
// Choose selected palette entry
|
||||
int index = mGridPosX + mGridPosY * 16;
|
||||
color col = Screen.PaletteColor(index);
|
||||
mRed = col.r;
|
||||
mGreen = col.g;
|
||||
mBlue = col.b;
|
||||
MenuSound ("menu/choose");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (mDesc.mSelectedItem >= 0 && mDesc.mSelectedItem < mStartItem+7)
|
||||
{
|
||||
if (mDesc.mItems[mDesc.mSelectedItem].MenuEvent(mkey, fromcontroller)) return true;
|
||||
}
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int mx, int my)
|
||||
{
|
||||
int olditem = mDesc.mSelectedItem;
|
||||
bool res = Super.MouseEvent(type, mx, my);
|
||||
|
||||
if (mDesc.mSelectedItem == -1 || mDesc.mSelectedItem == mStartItem+7)
|
||||
{
|
||||
int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * OptionMenuSettings.mLinespacing) * CleanYfac_1;
|
||||
int h = (screen.GetHeight() - y) / 16;
|
||||
int fh = OptionMenuSettings.mLinespacing * CleanYfac_1;
|
||||
int w = fh;
|
||||
int yy = y + 2 * CleanYfac_1;
|
||||
int indent = (screen.GetWidth() / 2);
|
||||
|
||||
if (h > fh) h = fh;
|
||||
else if (h < 4) return res; // no space to draw it.
|
||||
|
||||
int box_y = y - 2 * CleanYfac_1;
|
||||
int box_x = indent - 16*w;
|
||||
|
||||
if (mx >= box_x && mx < box_x + 16*w && my >= box_y && my < box_y + 16*h)
|
||||
{
|
||||
int cell_x = (mx - box_x) / w;
|
||||
int cell_y = (my - box_y) / h;
|
||||
|
||||
if (olditem != mStartItem+7 || cell_x != mGridPosX || cell_y != mGridPosY)
|
||||
{
|
||||
mGridPosX = cell_x;
|
||||
mGridPosY = cell_y;
|
||||
}
|
||||
mDesc.mSelectedItem = mStartItem+7;
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
MenuEvent(MKEY_Enter, true);
|
||||
if (m_use_mouse == 2) mDesc.mSelectedItem = -1;
|
||||
}
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer()
|
||||
{
|
||||
Super.Drawer();
|
||||
|
||||
if (mCVar == null) return;
|
||||
int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * OptionMenuSettings.mLinespacing) * CleanYfac_1;
|
||||
int fh = OptionMenuSettings.mLinespacing * CleanYfac_1;
|
||||
int h = (screen.GetHeight() - y) / 16;
|
||||
int w = fh;
|
||||
int yy = y;
|
||||
|
||||
if (h > fh) h = fh;
|
||||
else if (h < 4) return; // no space to draw it.
|
||||
|
||||
int indent = (screen.GetWidth() / 2);
|
||||
int p = 0;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
int box_x, box_y;
|
||||
int x1;
|
||||
|
||||
box_y = y - 2 * CleanYfac_1;
|
||||
box_x = indent - 16*w;
|
||||
for (x1 = 0; x1 < 16; ++x1)
|
||||
{
|
||||
screen.Clear (box_x, box_y, box_x + w, box_y + h, 0, p);
|
||||
if ((mDesc.mSelectedItem == mStartItem+7) &&
|
||||
(/*p == CurrColorIndex ||*/ (i == mGridPosY && x1 == mGridPosX)))
|
||||
{
|
||||
int r, g, b;
|
||||
Color col;
|
||||
double blinky;
|
||||
if (i == mGridPosY && x1 == mGridPosX)
|
||||
{
|
||||
r = 255; g = 128; b = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 200; g = 200; b = 255;
|
||||
}
|
||||
// Make sure the cursors stand out against similar colors
|
||||
// by pulsing them.
|
||||
blinky = abs(sin(MSTime()/1000.0)) * 0.5 + 0.5;
|
||||
col = Color(255, int(r*blinky), int(g*blinky), int(b*blinky));
|
||||
|
||||
screen.Clear (box_x, box_y, box_x + w, box_y + 1, col);
|
||||
screen.Clear (box_x, box_y + h-1, box_x + w, box_y + h, col);
|
||||
screen.Clear (box_x, box_y, box_x + 1, box_y + h, col);
|
||||
screen.Clear (box_x + w - 1, box_y, box_x + w, box_y + h, col);
|
||||
}
|
||||
box_x += w;
|
||||
p++;
|
||||
}
|
||||
y += h;
|
||||
}
|
||||
y = yy;
|
||||
color newColor = Color(255, int(mRed), int(mGreen), int(mBlue));
|
||||
color oldColor = mCVar.GetInt() | 0xFF000000;
|
||||
|
||||
int x = screen.GetWidth()*2/3;
|
||||
|
||||
screen.Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, oldColor);
|
||||
screen.Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, newColor);
|
||||
|
||||
y += 49*CleanYfac_1;
|
||||
screen.DrawText (SmallFont, Font.CR_GRAY, x+(48-SmallFont.StringWidth("---->")/2)*CleanXfac_1, y, "---->", DTA_CleanNoMove_1, true);
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
if (mStartItem >= 0)
|
||||
{
|
||||
mDesc.mItems.Resize(mStartItem);
|
||||
if (mCVar != null)
|
||||
{
|
||||
mCVar.SetInt(Color(int(mRed), int(mGreen), int(mBlue)));
|
||||
}
|
||||
mStartItem = -1;
|
||||
}
|
||||
}
|
||||
|
||||
override void ResetColor()
|
||||
{
|
||||
if (mCVar != null)
|
||||
{
|
||||
Color clr = Color(mCVar.GetInt());
|
||||
mRed = clr.r;
|
||||
mGreen = clr.g;
|
||||
mBlue = clr.b;
|
||||
}
|
||||
}
|
||||
}
|
312
wadsrc/static/zscript/ui/menu/joystickmenu.zs
Normal file
312
wadsrc/static/zscript/ui/menu/joystickmenu.zs
Normal file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
** joystickmenu.cpp
|
||||
** The joystick configuration menus
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoySensitivity : OptionMenuSliderBase
|
||||
{
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuSliderJoySensitivity Init(String label, double min, double max, double step, int showval, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
return mJoy.GetSensitivity();
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
mJoy.SetSensitivity(val);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoyScale : OptionMenuSliderBase
|
||||
{
|
||||
int mAxis;
|
||||
int mNeg;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuSliderJoyScale Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mAxis = axis;
|
||||
mNeg = 1;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
double d = mJoy.GetAxisScale(mAxis);
|
||||
mNeg = d < 0? -1:1;
|
||||
return d;
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
mJoy.SetAxisScale(mAxis, val * mNeg);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase
|
||||
{
|
||||
int mAxis;
|
||||
int mNeg;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuSliderJoyDeadZone Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mAxis = axis;
|
||||
mNeg = 1;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
double d = mJoy.GetAxisDeadZone(mAxis);
|
||||
mNeg = d < 0? -1:1;
|
||||
return d;
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
mJoy.SetAxisDeadZone(mAxis, val * mNeg);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemJoyMap : OptionMenuItemOptionBase
|
||||
{
|
||||
int mAxis;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuItemJoyMap Init(String label, int axis, Name values, int center, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, 'none', values, null, center);
|
||||
mAxis = axis;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override int GetSelection()
|
||||
{
|
||||
double f = mJoy.GetAxisMap(mAxis);
|
||||
let opt = OptionValues.GetCount(mValues);
|
||||
if (opt > 0)
|
||||
{
|
||||
// Map from joystick axis to menu selection.
|
||||
for(int i = 0; i < opt; i++)
|
||||
{
|
||||
if (f ~== OptionValues.GetValue(mValues, i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
override void SetSelection(int selection)
|
||||
{
|
||||
let opt = OptionValues.GetCount(mValues);
|
||||
// Map from menu selection to joystick axis.
|
||||
if (opt == 0 || selection >= opt)
|
||||
{
|
||||
selection = JoystickConfig.JOYAXIS_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = int(OptionValues.GetValue(mValues, selection));
|
||||
}
|
||||
mJoy.SetAxisMap(mAxis, selection);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemInverter : OptionMenuItemOptionBase
|
||||
{
|
||||
int mAxis;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuItemInverter Init(String label, int axis, int center, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, "none", "YesNo", NULL, center);
|
||||
mAxis = axis;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override int GetSelection()
|
||||
{
|
||||
float f = mJoy.GetAxisScale(mAxis);
|
||||
return f > 0? 0:1;
|
||||
}
|
||||
|
||||
override void SetSelection(int Selection)
|
||||
{
|
||||
let f = abs(mJoy.GetAxisScale(mAxis));
|
||||
if (Selection) f*=-1;
|
||||
mJoy.SetAxisScale(mAxis, f);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Executes a CCMD, action is a CCMD name
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemJoyConfigMenu : OptionMenuItemSubmenu
|
||||
{
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuItemJoyConfigMenu Init(String label, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, "JoystickConfigMenu");
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool Activate()
|
||||
{
|
||||
let desc = OptionMenuDescriptor(MenuDescriptor.GetDescriptor('JoystickConfigMenu'));
|
||||
if (desc != NULL)
|
||||
{
|
||||
SetController(OptionMenuDescriptor(desc), mJoy);
|
||||
}
|
||||
let res = Super.Activate();
|
||||
let joymenu = JoystickConfigMenu(Menu.GetCurrentMenu());
|
||||
if (res && joymenu != null) joymenu.mJoy = mJoy;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void SetController(OptionMenuDescriptor opt, JoystickConfig joy)
|
||||
{
|
||||
OptionMenuItem it;
|
||||
opt.mItems.Clear();
|
||||
if (joy == NULL)
|
||||
{
|
||||
opt.mTitle = "$JOYMNU_CONFIG";
|
||||
it = new("OptionMenuItemStaticText").Init("$JOYMNU_INVALID", false);
|
||||
opt.mItems.Push(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it = new("OptionMenuItemStaticText").Init(joy.GetName(), false);
|
||||
it = new("OptionMenuItemStaticText").Init("", false);
|
||||
|
||||
it = new("OptionMenuSliderJoySensitivity").Init("$JOYMNU_OVRSENS", 0, 2, 0.1, 3, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuItemStaticText").Init(" ", false);
|
||||
opt.mItems.Push(it);
|
||||
|
||||
if (joy.GetNumAxes() > 0)
|
||||
{
|
||||
it = new("OptionMenuItemStaticText").Init("$JOYMNU_AXIS", true);
|
||||
opt.mItems.Push(it);
|
||||
|
||||
for (int i = 0; i < joy.GetNumAxes(); ++i)
|
||||
{
|
||||
it = new("OptionMenuItemStaticText").Init(" ", false);
|
||||
opt.mItems.Push(it);
|
||||
|
||||
it = new("OptionMenuItemJoyMap").Init(joy.GetAxisName(i), i, "JoyAxisMapNames", false, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyScale").Init("$JOYMNU_OVRSENS", i, 0, 4, 0.1, 3, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuItemInverter").Init("$JOYMNU_INVERT", i, false, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyDeadZone").Init("$JOYMNU_DEADZONE", i, 0, 0.9, 0.05, 3, joy);
|
||||
opt.mItems.Push(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it = new("OptionMenuItemStaticText").Init("$JOYMNU_NOAXES", false);
|
||||
opt.mItems.Push(it);
|
||||
}
|
||||
}
|
||||
opt.mScrollPos = 0;
|
||||
opt.mSelectedItem = -1;
|
||||
opt.mIndent = 0;
|
||||
opt.mPosition = -25;
|
||||
opt.CalcIndent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class JoystickConfigMenu : OptionMenu
|
||||
{
|
||||
JoystickConfig mJoy;
|
||||
}
|
||||
|
279
wadsrc/static/zscript/ui/menu/listmenu.zs
Normal file
279
wadsrc/static/zscript/ui/menu/listmenu.zs
Normal file
|
@ -0,0 +1,279 @@
|
|||
|
||||
|
||||
class ListMenuDescriptor : MenuDescriptor native
|
||||
{
|
||||
enum EScale
|
||||
{
|
||||
CleanScale = -1,
|
||||
OptCleanScale = -2
|
||||
};
|
||||
native Array<ListMenuItem> mItems;
|
||||
native int mSelectedItem;
|
||||
native double mSelectOfsX;
|
||||
native double mSelectOfsY;
|
||||
native TextureID mSelector;
|
||||
native int mDisplayTop;
|
||||
native double mXpos, mYpos;
|
||||
native int mWLeft, mWRight;
|
||||
native int mLinespacing; // needs to be stored for dynamically created menus
|
||||
native int mAutoselect; // this can only be set by internal menu creation functions
|
||||
native Font mFont;
|
||||
native int mFontColor;
|
||||
native int mFontColor2;
|
||||
native bool mCenter;
|
||||
native int mVirtWidth, mVirtHeight;
|
||||
|
||||
native void Reset();
|
||||
int DisplayWidth()
|
||||
{
|
||||
if (mVirtWidth == OptCleanScale) return m_cleanscale ? CleanScale : 320;
|
||||
return mVirtWidth;
|
||||
}
|
||||
int DisplayHeight()
|
||||
{
|
||||
if (mVirtWidth == OptCleanScale) return m_cleanscale ? CleanScale : 200;
|
||||
return mVirtHeight;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// list menu class runs a menu described by a DListMenuDescriptor
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenu : Menu
|
||||
{
|
||||
ListMenuDescriptor mDesc;
|
||||
MenuItemBase mFocusControl;
|
||||
|
||||
virtual void Init(Menu parent = NULL, ListMenuDescriptor desc = NULL)
|
||||
{
|
||||
Super.Init(parent);
|
||||
mDesc = desc;
|
||||
if (desc.mCenter)
|
||||
{
|
||||
double center = 160;
|
||||
for(int i=0; i < mDesc.mItems.Size(); i++)
|
||||
{
|
||||
double xpos = mDesc.mItems[i].GetX();
|
||||
int width = mDesc.mItems[i].GetWidth();
|
||||
double curx = mDesc.mSelectOfsX;
|
||||
|
||||
if (width > 0 && mDesc.mItems[i].Selectable())
|
||||
{
|
||||
double left = 160 - (width - curx) / 2 - curx;
|
||||
if (left < center) center = left;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
int width = mDesc.mItems[i].GetWidth();
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
mDesc.mItems[i].SetX(center);
|
||||
}
|
||||
}
|
||||
}
|
||||
// notify all items that the menu was just created.
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
mDesc.mItems[i].OnMenuCreated();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
ListMenuItem GetItem(Name name)
|
||||
{
|
||||
for(int i = 0; i < mDesc.mItems.Size(); i++)
|
||||
{
|
||||
Name nm = mDesc.mItems[i].GetAction();
|
||||
if (nm == name) return mDesc.mItems[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.Type == UIEvent.Type_KeyDown && ev.KeyChar > 0)
|
||||
{
|
||||
// tolower
|
||||
int ch = ev.KeyChar;
|
||||
ch = ch >= 65 && ch < 91 ? ch + 32 : ch;
|
||||
|
||||
for(int i = mDesc.mSelectedItem + 1; i < mDesc.mItems.Size(); i++)
|
||||
{
|
||||
if (mDesc.mitems[i].Selectable() && mDesc.mItems[i].CheckHotkey(ch))
|
||||
{
|
||||
mDesc.mSelectedItem = i;
|
||||
MenuSound("menu/cursor");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < mDesc.mSelectedItem; i++)
|
||||
{
|
||||
if (mDesc.mitems[i].Selectable() && mDesc.mItems[i].CheckHotkey(ch))
|
||||
{
|
||||
mDesc.mSelectedItem = i;
|
||||
MenuSound("menu/cursor");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
int oldSelect = mDesc.mSelectedItem;
|
||||
int startedAt = mDesc.mSelectedItem;
|
||||
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Up:
|
||||
do
|
||||
{
|
||||
if (--mDesc.mSelectedItem < 0) mDesc.mSelectedItem = mDesc.mItems.Size()-1;
|
||||
}
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt);
|
||||
if (mDesc.mSelectedItem == startedAt) mDesc.mSelectedItem = oldSelect;
|
||||
MenuSound("menu/cursor");
|
||||
return true;
|
||||
|
||||
case MKEY_Down:
|
||||
do
|
||||
{
|
||||
if (++mDesc.mSelectedItem >= mDesc.mItems.Size()) mDesc.mSelectedItem = 0;
|
||||
}
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt);
|
||||
if (mDesc.mSelectedItem == startedAt) mDesc.mSelectedItem = oldSelect;
|
||||
MenuSound("menu/cursor");
|
||||
return true;
|
||||
|
||||
case MKEY_Enter:
|
||||
if (mDesc.mSelectedItem >= 0 && mDesc.mItems[mDesc.mSelectedItem].Activate())
|
||||
{
|
||||
MenuSound("menu/choose");
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
int sel = -1;
|
||||
|
||||
// convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture
|
||||
x = ((x - (screen.GetWidth() / 2)) / CleanXfac) + 160;
|
||||
y = ((y - (screen.GetHeight() / 2)) / CleanYfac) + 100;
|
||||
|
||||
if (mFocusControl != NULL)
|
||||
{
|
||||
mFocusControl.MouseEvent(type, x, y);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((mDesc.mWLeft <= 0 || x > mDesc.mWLeft) &&
|
||||
(mDesc.mWRight <= 0 || x < mDesc.mWRight))
|
||||
{
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
if (mDesc.mItems[i].CheckCoordinate(x, y))
|
||||
{
|
||||
if (i != mDesc.mSelectedItem)
|
||||
{
|
||||
//MenuSound("menu/cursor");
|
||||
}
|
||||
mDesc.mSelectedItem = i;
|
||||
mDesc.mItems[i].MouseEvent(type, x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mDesc.mSelectedItem = -1;
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Ticker ()
|
||||
{
|
||||
Super.Ticker();
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
mDesc.mItems[i].Ticker();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
if (mDesc.mItems[i].mEnabled) mDesc.mItems[i].Draw(mDesc.mSelectedItem == i, mDesc);
|
||||
}
|
||||
if (mDesc.mSelectedItem >= 0 && mDesc.mSelectedItem < mDesc.mItems.Size())
|
||||
mDesc.mItems[mDesc.mSelectedItem].DrawSelector(mDesc.mSelectOfsX, mDesc.mSelectOfsY, mDesc.mSelector, mDesc);
|
||||
Super.Drawer();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void SetFocus(MenuItemBase fc)
|
||||
{
|
||||
mFocusControl = fc;
|
||||
}
|
||||
override bool CheckFocus(MenuItemBase fc)
|
||||
{
|
||||
return mFocusControl == fc;
|
||||
}
|
||||
override void ReleaseFocus()
|
||||
{
|
||||
mFocusControl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
342
wadsrc/static/zscript/ui/menu/listmenuitems.zs
Normal file
342
wadsrc/static/zscript/ui/menu/listmenuitems.zs
Normal file
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
** listmenu.cpp
|
||||
** A simple menu consisting of a list of items
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
class ListMenuItem : MenuItemBase
|
||||
{
|
||||
protected void DrawText(ListMenuDescriptor desc, Font fnt, int color, double x, double y, String text, bool ontop = false)
|
||||
{
|
||||
int w = desc ? desc.DisplayWidth() : ListMenuDescriptor.CleanScale;
|
||||
int h = desc ? desc.DisplayHeight() : -1;
|
||||
if (w == ListMenuDescriptor.CleanScale)
|
||||
{
|
||||
screen.DrawText(fnt, color, x, y, text, ontop? DTA_CleanTop : DTA_Clean, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawText(fnt, color, x, y, text, DTA_VirtualWidth, w, DTA_VirtualHeight, h, DTA_FullscreenScale, FSMode_ScaleToFit43);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawTexture(ListMenuDescriptor desc, TextureID tex, double x, double y, bool ontop = false)
|
||||
{
|
||||
int w = desc ? desc.DisplayWidth() : ListMenuDescriptor.CleanScale;
|
||||
int h = desc ? desc.DisplayHeight() : -1;
|
||||
if (w == ListMenuDescriptor.CleanScale)
|
||||
{
|
||||
screen.DrawTexture(tex, true, x, y, ontop ? DTA_CleanTop : DTA_Clean, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawTexture(tex, true, x, y, DTA_VirtualWidth, w, DTA_VirtualHeight, h, DTA_FullscreenScale, FSMode_ScaleToFit43);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DrawSelector(double xofs, double yofs, TextureID tex, ListMenuDescriptor desc = null)
|
||||
{
|
||||
if (tex.isNull())
|
||||
{
|
||||
if ((Menu.MenuTime() % 8) < 6)
|
||||
{
|
||||
DrawText(desc, ConFont, OptionMenuSettings.mFontColorSelection, mXpos + xofs, mYpos + yofs + 8, "\xd");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(desc, tex, mXpos + xofs, mYpos + yofs);
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot extend Drawer here because it is inherited from the parent class.
|
||||
virtual void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
Drawer(selected); // fall back to the legacy version, if not overridden
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// static patch
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenuItemStaticPatch : ListMenuItem
|
||||
{
|
||||
TextureID mTexture;
|
||||
bool mCentered;
|
||||
String mSubstitute;
|
||||
Font mFont;
|
||||
int mColor;
|
||||
|
||||
void Init(ListMenuDescriptor desc, double x, double y, TextureID patch, bool centered = false, String substitute = "")
|
||||
{
|
||||
Super.Init(x, y);
|
||||
mTexture = patch;
|
||||
mCentered = centered;
|
||||
mSubstitute = substitute;
|
||||
mFont = desc.mFont;
|
||||
mColor = desc.mFontColor;
|
||||
|
||||
}
|
||||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
if (!mTexture.Exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double x = mXpos;
|
||||
Vector2 vec = TexMan.GetScaledSize(mTexture);
|
||||
|
||||
if (mSubstitute == "" || TexMan.OkForLocalization(mTexture, mSubstitute))
|
||||
{
|
||||
if (mCentered) x -= vec.X / 2;
|
||||
DrawTexture(desc, mTexture, x, abs(mYpos), mYpos < 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
let font = generic_ui ? NewSmallFont : mFont;
|
||||
if (mCentered) x -= font.StringWidth(mSubstitute) / 2;
|
||||
DrawText(desc, font, mColor, x, abs(mYpos), mSubstitute, mYpos < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ListMenuItemStaticPatchCentered : ListMenuItemStaticPatch
|
||||
{
|
||||
void Init(ListMenuDescriptor desc, double x, double y, TextureID patch)
|
||||
{
|
||||
Super.Init(desc, x, y, patch, true);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// static text
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenuItemStaticText : ListMenuItem
|
||||
{
|
||||
String mText;
|
||||
Font mFont;
|
||||
int mColor;
|
||||
bool mCentered;
|
||||
|
||||
void Init(ListMenuDescriptor desc, double x, double y, String text, int color = -1)
|
||||
{
|
||||
Super.Init(x, y);
|
||||
mText = text;
|
||||
mFont = desc.mFont;
|
||||
mColor = color >= 0? color : desc.mFontColor;
|
||||
mCentered = false;
|
||||
}
|
||||
|
||||
void InitDirect(double x, double y, String text, Font font, int color = Font.CR_UNTRANSLATED, bool centered = false)
|
||||
{
|
||||
Super.Init(x, y);
|
||||
mText = text;
|
||||
mFont = font;
|
||||
mColor = color;
|
||||
mCentered = centered;
|
||||
}
|
||||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
if (mText.Length() != 0)
|
||||
{
|
||||
let font = generic_ui? NewSmallFont : mFont;
|
||||
|
||||
String text = Stringtable.Localize(mText);
|
||||
|
||||
double x = mXpos;
|
||||
if (mCentered) x -= font.StringWidth(text) / 2;
|
||||
DrawText(desc, font, mColor, x, abs(mYpos), text, mYpos < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ListMenuItemStaticTextCentered : ListMenuItemStaticText
|
||||
{
|
||||
void Init(ListMenuDescriptor desc, double x, double y, String text, int color = -1)
|
||||
{
|
||||
Super.Init(desc, x, y, text, color);
|
||||
mCentered = true;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// selectable items
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenuItemSelectable : ListMenuItem
|
||||
{
|
||||
int mHotkey;
|
||||
int mHeight;
|
||||
int mParam;
|
||||
|
||||
protected void Init(double x, double y, int height, Name childmenu, int param = -1)
|
||||
{
|
||||
Super.Init(x, y, childmenu);
|
||||
mHeight = height;
|
||||
mParam = param;
|
||||
mHotkey = 0;
|
||||
}
|
||||
|
||||
override bool CheckCoordinate(int x, int y)
|
||||
{
|
||||
return mEnabled && y >= mYpos && y < mYpos + mHeight; // no x check here
|
||||
}
|
||||
|
||||
override bool Selectable()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
override bool CheckHotkey(int c)
|
||||
{
|
||||
return c > 0 && c == mHotkey;
|
||||
}
|
||||
|
||||
override bool Activate()
|
||||
{
|
||||
Menu.SetMenu(mAction, mParam);
|
||||
return true;
|
||||
}
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (type == Menu.MOUSE_Release)
|
||||
{
|
||||
let m = Menu.GetCurrentMenu();
|
||||
if (m != NULL && m.MenuEvent(Menu.MKEY_Enter, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override Name, int GetAction()
|
||||
{
|
||||
return mAction, mParam;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// text item
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenuItemTextItem : ListMenuItemSelectable
|
||||
{
|
||||
String mText;
|
||||
Font mFont;
|
||||
int mColor;
|
||||
int mColorSelected;
|
||||
|
||||
void Init(ListMenuDescriptor desc, String text, String hotkey, Name child, int param = 0)
|
||||
{
|
||||
Super.Init(desc.mXpos, desc.mYpos, desc.mLinespacing, child, param);
|
||||
mText = text;
|
||||
mFont = desc.mFont;
|
||||
mColor = desc.mFontColor;
|
||||
mColorSelected = desc.mFontcolor2;
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
}
|
||||
|
||||
void InitDirect(double x, double y, int height, String hotkey, String text, Font font, int color, int color2, Name child, int param = 0)
|
||||
{
|
||||
Super.Init(x, y, height, child, param);
|
||||
mText = text;
|
||||
mFont = font;
|
||||
mColor = color;
|
||||
mColorSelected = color2;
|
||||
int pos = 0;
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
}
|
||||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
let font = generic_ui ? NewSmallFont : mFont;
|
||||
DrawText(desc, font, selected ? mColorSelected : mColor, mXpos, mYpos, mText);
|
||||
}
|
||||
|
||||
override int GetWidth()
|
||||
{
|
||||
let font = generic_ui? NewSmallFont : mFont;
|
||||
return max(1, font.StringWidth(StringTable.Localize(mText)));
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// patch item
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ListMenuItemPatchItem : ListMenuItemSelectable
|
||||
{
|
||||
TextureID mTexture;
|
||||
|
||||
void Init(ListMenuDescriptor desc, TextureID patch, String hotkey, Name child, int param = 0)
|
||||
{
|
||||
Super.Init(desc.mXpos, desc.mYpos, desc.mLinespacing, child, param);
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
mTexture = patch;
|
||||
}
|
||||
|
||||
void InitDirect(double x, double y, int height, TextureID patch, String hotkey, Name child, int param = 0)
|
||||
{
|
||||
Super.Init(x, y, height, child, param);
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
mTexture = patch;
|
||||
}
|
||||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
DrawTexture(desc, mTexture, mXpos, mYpos);
|
||||
}
|
||||
|
||||
override int GetWidth()
|
||||
{
|
||||
return TexMan.GetSize(mTexture);
|
||||
}
|
||||
|
||||
}
|
||||
|
644
wadsrc/static/zscript/ui/menu/loadsavemenu.zs
Normal file
644
wadsrc/static/zscript/ui/menu/loadsavemenu.zs
Normal file
|
@ -0,0 +1,644 @@
|
|||
/*
|
||||
** loacpp
|
||||
** The load game and save game menus
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2001-2010 Randy Heit
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
struct SaveGameNode native
|
||||
{
|
||||
native String SaveTitle;
|
||||
native readonly String Filename;
|
||||
native bool bOldVersion;
|
||||
native bool bMissingWads;
|
||||
native bool bNoDelete;
|
||||
}
|
||||
|
||||
struct SavegameManager native ui
|
||||
{
|
||||
native int WindowSize;
|
||||
native SaveGameNode quickSaveSlot;
|
||||
native readonly String SaveCommentString;
|
||||
|
||||
native static SavegameManager GetManager();
|
||||
native void ReadSaveStrings();
|
||||
native void UnloadSaveData();
|
||||
|
||||
native int RemoveSaveSlot(int index);
|
||||
native void LoadSavegame(int Selected);
|
||||
native void DoSave(int Selected, String savegamestring);
|
||||
native int ExtractSaveData(int index);
|
||||
native void ClearSaveStuff();
|
||||
native bool DrawSavePic(int x, int y, int w, int h);
|
||||
deprecated("4.0") void DrawSaveComment(Font font, int cr, int x, int y, int scalefactor)
|
||||
{
|
||||
// Unfortunately, this was broken beyond repair so it now prints nothing.
|
||||
}
|
||||
native void SetFileInfo(int Selected);
|
||||
native int SavegameCount();
|
||||
native SaveGameNode GetSavegame(int i);
|
||||
native void InsertNewSaveNode();
|
||||
native bool RemoveNewSaveNode();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class LoadSaveMenu : ListMenu
|
||||
{
|
||||
SavegameManager manager;
|
||||
int TopItem;
|
||||
int Selected;
|
||||
|
||||
int savepicLeft;
|
||||
int savepicTop;
|
||||
int savepicWidth;
|
||||
int savepicHeight;
|
||||
int rowHeight;
|
||||
int listboxLeft;
|
||||
int listboxTop;
|
||||
int listboxWidth;
|
||||
|
||||
int listboxRows;
|
||||
int listboxHeight;
|
||||
int listboxRight;
|
||||
int listboxBottom;
|
||||
|
||||
int commentLeft;
|
||||
int commentTop;
|
||||
int commentWidth;
|
||||
int commentHeight;
|
||||
int commentRight;
|
||||
int commentBottom;
|
||||
int commentRows;
|
||||
|
||||
bool mEntering;
|
||||
TextEnterMenu mInput;
|
||||
double FontScale;
|
||||
|
||||
BrokenLines BrokenSaveComment;
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent, ListMenuDescriptor desc)
|
||||
{
|
||||
Super.Init(parent, desc);
|
||||
manager = SavegameManager.GetManager();
|
||||
manager.ReadSaveStrings();
|
||||
|
||||
savepicLeft = 10;
|
||||
savepicTop = 54*CleanYfac;
|
||||
savepicWidth = 216*screen.GetWidth() / 640;
|
||||
savepicHeight = 135*screen.GetHeight() / 400;
|
||||
|
||||
FontScale = max(screen.GetHeight() / 480, 1);
|
||||
rowHeight = int(max((NewConsoleFont.GetHeight() + 1) * FontScale, 1));
|
||||
|
||||
listboxLeft = savepicLeft + savepicWidth + 14;
|
||||
listboxTop = savepicTop;
|
||||
listboxWidth = screen.GetWidth() - listboxLeft - 10;
|
||||
int listboxHeight1 = screen.GetHeight() - listboxTop - 10;
|
||||
listboxRows = (listboxHeight1 - 1) / rowHeight;
|
||||
listboxHeight = listboxRows * rowHeight + 1;
|
||||
listboxRight = listboxLeft + listboxWidth;
|
||||
listboxBottom = listboxTop + listboxHeight;
|
||||
|
||||
commentLeft = savepicLeft;
|
||||
commentTop = savepicTop + savepicHeight + 16;
|
||||
commentWidth = savepicWidth;
|
||||
//commentHeight = (51+(screen.GetHeight()>200?10:0))*CleanYfac;
|
||||
commentHeight = listboxHeight - savepicHeight - 16;
|
||||
commentRight = commentLeft + commentWidth;
|
||||
commentBottom = commentTop + commentHeight;
|
||||
commentRows = commentHeight / rowHeight;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
//manager.ClearSaveStuff ();
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
Super.Drawer();
|
||||
|
||||
SaveGameNode node;
|
||||
int i;
|
||||
int j;
|
||||
bool didSeeSelected = false;
|
||||
|
||||
// Draw picture area
|
||||
if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Screen.DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight);
|
||||
if (!manager.DrawSavePic(savepicLeft, savepicTop, savepicWidth, savepicHeight))
|
||||
{
|
||||
screen.Clear (savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0, 0);
|
||||
|
||||
if (manager.SavegameCount() > 0)
|
||||
{
|
||||
String text = (Selected == -1 || !manager.GetSavegame(Selected).bOldVersion)? Stringtable.Localize("$MNU_NOPICTURE") : Stringtable.Localize("$MNU_DIFFVERSION");
|
||||
int textlen = NewSmallFont.StringWidth(text) * CleanXfac;
|
||||
|
||||
screen.DrawText (NewSmallFont, Font.CR_GOLD, savepicLeft+(savepicWidth-textlen)/2,
|
||||
savepicTop+(savepicHeight-rowHeight)/2, text, DTA_CleanNoMove, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw comment area
|
||||
Screen.DrawFrame (commentLeft, commentTop, commentWidth, commentHeight);
|
||||
screen.Clear (commentLeft, commentTop, commentRight, commentBottom, 0, 0);
|
||||
|
||||
int numlinestoprint = min(commentRows, BrokenSaveComment? BrokenSaveComment.Count() : 0);
|
||||
for(int i = 0; i < numlinestoprint; i++)
|
||||
{
|
||||
screen.DrawText(NewConsoleFont, Font.CR_ORANGE, commentLeft / FontScale, (commentTop + rowHeight * i) / FontScale, BrokenSaveComment.StringAt(i),
|
||||
DTA_VirtualWidthF, screen.GetWidth() / FontScale, DTA_VirtualHeightF, screen.GetHeight() / FontScale, DTA_KeepRatio, true);
|
||||
}
|
||||
|
||||
|
||||
// Draw file area
|
||||
Screen.DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight);
|
||||
screen.Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0);
|
||||
|
||||
if (manager.SavegameCount() == 0)
|
||||
{
|
||||
String text = Stringtable.Localize("$MNU_NOFILES");
|
||||
int textlen = int(NewConsoleFont.StringWidth(text) * FontScale);
|
||||
|
||||
screen.DrawText (NewConsoleFont, Font.CR_GOLD, (listboxLeft+(listboxWidth-textlen)/2) / FontScale, (listboxTop+(listboxHeight-rowHeight)/2) / FontScale, text,
|
||||
DTA_VirtualWidthF, screen.GetWidth() / FontScale, DTA_VirtualHeightF, screen.GetHeight() / FontScale, DTA_KeepRatio, true);
|
||||
return;
|
||||
}
|
||||
|
||||
j = TopItem;
|
||||
for (i = 0; i < listboxRows && j < manager.SavegameCount(); i++)
|
||||
{
|
||||
int colr;
|
||||
node = manager.GetSavegame(j);
|
||||
if (node.bOldVersion)
|
||||
{
|
||||
colr = Font.CR_RED;
|
||||
}
|
||||
else if (node.bMissingWads)
|
||||
{
|
||||
colr = Font.CR_YELLOW;
|
||||
}
|
||||
else if (j == Selected)
|
||||
{
|
||||
colr = Font.CR_WHITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
colr = Font.CR_TAN;
|
||||
}
|
||||
|
||||
screen.SetClipRect(listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1));
|
||||
|
||||
if (j == Selected)
|
||||
{
|
||||
screen.Clear (listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1), mEntering ? Color(255,255,0,0) : Color(255,0,0,255));
|
||||
didSeeSelected = true;
|
||||
if (!mEntering)
|
||||
{
|
||||
screen.DrawText (NewConsoleFont, colr, (listboxLeft+1) / FontScale, (listboxTop+rowHeight*i + FontScale) / FontScale, node.SaveTitle,
|
||||
DTA_VirtualWidthF, screen.GetWidth() / FontScale, DTA_VirtualHeightF, screen.GetHeight() / FontScale, DTA_KeepRatio, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
String s = mInput.GetText() .. NewConsoleFont.GetCursor();
|
||||
int length = int(NewConsoleFont.StringWidth(s) * FontScale);
|
||||
int displacement = min(0, listboxWidth - 2 - length);
|
||||
screen.DrawText (NewConsoleFont, Font.CR_WHITE, (listboxLeft + 1 + displacement) / FontScale, (listboxTop+rowHeight*i + FontScale) / FontScale, s,
|
||||
DTA_VirtualWidthF, screen.GetWidth() / FontScale, DTA_VirtualHeightF, screen.GetHeight() / FontScale, DTA_KeepRatio, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawText (NewConsoleFont, colr, (listboxLeft+1) / FontScale, (listboxTop+rowHeight*i + FontScale) / FontScale, node.SaveTitle,
|
||||
DTA_VirtualWidthF, screen.GetWidth() / FontScale, DTA_VirtualHeightF, screen.GetHeight() / FontScale, DTA_KeepRatio, true);
|
||||
}
|
||||
screen.ClearClipRect();
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSaveComment()
|
||||
{
|
||||
BrokenSaveComment = NewConsoleFont.BreakLines(manager.SaveCommentString, int(commentWidth / FontScale));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Up:
|
||||
if (manager.SavegameCount() > 1)
|
||||
{
|
||||
if (Selected == -1) Selected = TopItem;
|
||||
else
|
||||
{
|
||||
if (--Selected < 0) Selected = manager.SavegameCount()-1;
|
||||
if (Selected < TopItem) TopItem = Selected;
|
||||
else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1);
|
||||
}
|
||||
manager.UnloadSaveData ();
|
||||
manager.ExtractSaveData (Selected);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Down:
|
||||
if (manager.SavegameCount() > 1)
|
||||
{
|
||||
if (Selected == -1) Selected = TopItem;
|
||||
else
|
||||
{
|
||||
if (++Selected >= manager.SavegameCount()) Selected = 0;
|
||||
if (Selected < TopItem) TopItem = Selected;
|
||||
else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1);
|
||||
}
|
||||
manager.UnloadSaveData ();
|
||||
manager.ExtractSaveData (Selected);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_PageDown:
|
||||
if (manager.SavegameCount() > 1)
|
||||
{
|
||||
if (TopItem >= manager.SavegameCount() - listboxRows)
|
||||
{
|
||||
TopItem = 0;
|
||||
if (Selected != -1) Selected = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TopItem = MIN(TopItem + listboxRows, manager.SavegameCount() - listboxRows);
|
||||
if (TopItem > Selected && Selected != -1) Selected = TopItem;
|
||||
}
|
||||
manager.UnloadSaveData ();
|
||||
manager.ExtractSaveData (Selected);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_PageUp:
|
||||
if (manager.SavegameCount() > 1)
|
||||
{
|
||||
if (TopItem == 0)
|
||||
{
|
||||
TopItem = MAX(0, manager.SavegameCount() - listboxRows);
|
||||
if (Selected != -1) Selected = TopItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
TopItem = MAX(TopItem - listboxRows, 0);
|
||||
if (Selected >= TopItem + listboxRows) Selected = TopItem;
|
||||
}
|
||||
manager.UnloadSaveData ();
|
||||
manager.ExtractSaveData (Selected);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Enter:
|
||||
return false; // This event will be handled by the subclasses
|
||||
|
||||
case MKEY_MBYes:
|
||||
{
|
||||
if (Selected < manager.SavegameCount())
|
||||
{
|
||||
Selected = manager.RemoveSaveSlot (Selected);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (x >= listboxLeft && x < listboxLeft + listboxWidth &&
|
||||
y >= listboxTop && y < listboxTop + listboxHeight)
|
||||
{
|
||||
int lineno = (y - listboxTop) / rowHeight;
|
||||
|
||||
if (TopItem + lineno < manager.SavegameCount())
|
||||
{
|
||||
Selected = TopItem + lineno;
|
||||
manager.UnloadSaveData ();
|
||||
manager.ExtractSaveData (Selected);
|
||||
UpdateSaveComment();
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
if (MenuEvent(MKEY_Enter, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else Selected = -1;
|
||||
}
|
||||
else Selected = -1;
|
||||
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.Type == UIEvent.Type_KeyDown)
|
||||
{
|
||||
if (Selected != -1 && Selected < manager.SavegameCount())
|
||||
{
|
||||
switch (ev.KeyChar)
|
||||
{
|
||||
case UIEvent.Key_F1:
|
||||
manager.SetFileInfo(Selected);
|
||||
UpdateSaveComment();
|
||||
return true;
|
||||
|
||||
case UIEvent.Key_DEL:
|
||||
{
|
||||
String EndString;
|
||||
EndString = String.Format("%s%s%s%s?\n\n%s", Stringtable.Localize("$MNU_DELETESG"), TEXTCOLOR_WHITE, manager.GetSavegame(Selected).SaveTitle, TEXTCOLOR_NORMAL, Stringtable.Localize("$PRESSYN"));
|
||||
StartMessage (EndString, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ev.Type == UIEvent.Type_WheelUp)
|
||||
{
|
||||
if (TopItem > 0) TopItem--;
|
||||
return true;
|
||||
}
|
||||
else if (ev.Type == UIEvent.Type_WheelDown)
|
||||
{
|
||||
if (TopItem < manager.SavegameCount() - listboxRows) TopItem++;
|
||||
return true;
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class SaveMenu : LoadSaveMenu
|
||||
{
|
||||
String mSaveName;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent, ListMenuDescriptor desc)
|
||||
{
|
||||
Super.Init(parent, desc);
|
||||
manager.InsertNewSaveNode();
|
||||
TopItem = 0;
|
||||
Selected = manager.ExtractSaveData (-1);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
if (manager.RemoveNewSaveNode())
|
||||
{
|
||||
Selected--;
|
||||
}
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
if (Super.MenuEvent(mkey, fromcontroller))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (Selected == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mkey == MKEY_Enter)
|
||||
{
|
||||
String SavegameString = (Selected != 0)? manager.GetSavegame(Selected).SaveTitle : "";
|
||||
mInput = TextEnterMenu.OpenTextEnter(self, Menu.OptionFont(), SavegameString, -1, fromcontroller);
|
||||
mInput.ActivateMenu();
|
||||
mEntering = true;
|
||||
}
|
||||
else if (mkey == MKEY_Input)
|
||||
{
|
||||
// Do not start the save here, it would cause some serious execution ordering problems.
|
||||
mEntering = false;
|
||||
mSaveName = mInput.GetText();
|
||||
mInput = null;
|
||||
}
|
||||
else if (mkey == MKEY_Abort)
|
||||
{
|
||||
mEntering = false;
|
||||
mInput = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (mSaveName.Length() > 0)
|
||||
{
|
||||
// Do not process events when saving is in progress to avoid update of the current index,
|
||||
// i.e. Selected member variable must remain unchanged
|
||||
return true;
|
||||
}
|
||||
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.Type == UIEvent.Type_KeyDown)
|
||||
{
|
||||
if (Selected != -1)
|
||||
{
|
||||
switch (ev.KeyChar)
|
||||
{
|
||||
case UIEvent.Key_DEL:
|
||||
// cannot delete 'new save game' item
|
||||
if (Selected == 0) return true;
|
||||
break;
|
||||
|
||||
case 78://'N':
|
||||
Selected = TopItem = 0;
|
||||
manager.UnloadSaveData ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Ticker()
|
||||
{
|
||||
if (mSaveName.Length() > 0)
|
||||
{
|
||||
manager.DoSave(Selected, mSaveName);
|
||||
mSaveName = "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class LoadMenu : LoadSaveMenu
|
||||
{
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent, ListMenuDescriptor desc)
|
||||
{
|
||||
Super.Init(parent, desc);
|
||||
TopItem = 0;
|
||||
Selected = manager.ExtractSaveData (-1);
|
||||
UpdateSaveComment();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
if (Super.MenuEvent(mkey, fromcontroller))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (Selected == -1 || manager.SavegameCount() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mkey == MKEY_Enter)
|
||||
{
|
||||
manager.LoadSavegame(Selected);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
334
wadsrc/static/zscript/ui/menu/menu.zs
Normal file
334
wadsrc/static/zscript/ui/menu/menu.zs
Normal file
|
@ -0,0 +1,334 @@
|
|||
|
||||
struct KeyBindings native version("2.4")
|
||||
{
|
||||
native static String NameKeys(int k1, int k2);
|
||||
|
||||
native int, int GetKeysForCommand(String cmd);
|
||||
native void SetBind(int key, String cmd);
|
||||
native void UnbindACommand (String str);
|
||||
}
|
||||
|
||||
struct OptionValues native version("2.4")
|
||||
{
|
||||
native static int GetCount(Name group);
|
||||
native static String GetText(Name group, int index);
|
||||
native static double GetValue(Name group, int index);
|
||||
native static String GetTextValue(Name group, int index);
|
||||
}
|
||||
|
||||
struct JoystickConfig native version("2.4")
|
||||
{
|
||||
enum EJoyAxis
|
||||
{
|
||||
JOYAXIS_None = -1,
|
||||
JOYAXIS_Yaw,
|
||||
JOYAXIS_Pitch,
|
||||
JOYAXIS_Forward,
|
||||
JOYAXIS_Side,
|
||||
JOYAXIS_Up,
|
||||
// JOYAXIS_Roll, // Ha ha. No roll for you.
|
||||
NUM_JOYAXIS,
|
||||
};
|
||||
|
||||
native float GetSensitivity();
|
||||
native void SetSensitivity(float scale);
|
||||
|
||||
native float GetAxisScale(int axis);
|
||||
native void SetAxisScale(int axis, float scale);
|
||||
|
||||
native float GetAxisDeadZone(int axis);
|
||||
native void SetAxisDeadZone(int axis, float zone);
|
||||
|
||||
native int GetAxisMap(int axis);
|
||||
native void SetAxisMap(int axis, int gameaxis);
|
||||
|
||||
native String GetName();
|
||||
native int GetNumAxes();
|
||||
native String GetAxisName(int axis);
|
||||
|
||||
}
|
||||
|
||||
class Menu : Object native ui version("2.4")
|
||||
{
|
||||
enum EMenuKey
|
||||
{
|
||||
MKEY_Up,
|
||||
MKEY_Down,
|
||||
MKEY_Left,
|
||||
MKEY_Right,
|
||||
MKEY_PageUp,
|
||||
MKEY_PageDown,
|
||||
MKEY_Enter,
|
||||
MKEY_Back,
|
||||
MKEY_Clear,
|
||||
NUM_MKEYS,
|
||||
|
||||
// These are not buttons but events sent from other menus
|
||||
|
||||
MKEY_Input,
|
||||
MKEY_Abort,
|
||||
MKEY_MBYes,
|
||||
MKEY_MBNo,
|
||||
}
|
||||
|
||||
enum EMenuMouse
|
||||
{
|
||||
MOUSE_Click,
|
||||
MOUSE_Move,
|
||||
MOUSE_Release
|
||||
};
|
||||
|
||||
enum EMenuState
|
||||
{
|
||||
Off, // Menu is closed
|
||||
On, // Menu is opened
|
||||
WaitKey, // Menu is opened and waiting for a key in the controls menu
|
||||
OnNoPause, // Menu is opened but does not pause the game
|
||||
};
|
||||
|
||||
native Menu mParentMenu;
|
||||
native bool mMouseCapture;
|
||||
native bool mBackbuttonSelected;
|
||||
native bool DontDim;
|
||||
native bool DontBlur;
|
||||
|
||||
native static int MenuTime();
|
||||
native static Menu GetCurrentMenu();
|
||||
native static clearscope void SetMenu(Name mnu, int param = 0); // This is not 100% safe but needs to be available - but always make sure to check that only the desired player opens it!
|
||||
native static void StartMessage(String msg, int mode = 0, Name command = 'none');
|
||||
native static void SetMouseCapture(bool on);
|
||||
native void Close();
|
||||
native void ActivateMenu();
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void Init(Menu parent)
|
||||
{
|
||||
mParentMenu = parent;
|
||||
mMouseCapture = false;
|
||||
mBackbuttonSelected = false;
|
||||
DontDim = false;
|
||||
DontBlur = false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Back:
|
||||
Close();
|
||||
MenuSound (GetCurrentMenu() != null? "menu/backup" : "menu/clear");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
protected bool MouseEventBack(int type, int x, int y)
|
||||
{
|
||||
if (m_show_backbutton >= 0)
|
||||
{
|
||||
let tex = TexMan.CheckForTexture(gameinfo.mBackButton, TexMan.Type_MiscPatch);
|
||||
if (tex.IsValid())
|
||||
{
|
||||
Vector2 v = TexMan.GetScaledSize(tex);
|
||||
int w = int(v.X + 0.5) * CleanXfac;
|
||||
int h = int(v.Y + 0.5) * CleanYfac;
|
||||
if (m_show_backbutton&1) x -= screen.GetWidth() - w;
|
||||
if (m_show_backbutton&2) y -= screen.GetHeight() - h;
|
||||
mBackbuttonSelected = ( x >= 0 && x < w && y >= 0 && y < h);
|
||||
if (mBackbuttonSelected && type == MOUSE_Release)
|
||||
{
|
||||
if (m_use_mouse == 2) mBackbuttonSelected = false;
|
||||
MenuEvent(MKEY_Back, true);
|
||||
}
|
||||
return mBackbuttonSelected;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
bool res = false;
|
||||
int y = ev.MouseY;
|
||||
if (ev.type == UIEvent.Type_LButtonDown)
|
||||
{
|
||||
res = MouseEventBack(MOUSE_Click, ev.MouseX, y);
|
||||
// make the menu's mouse handler believe that the current coordinate is outside the valid range
|
||||
if (res) y = -1;
|
||||
res |= MouseEvent(MOUSE_Click, ev.MouseX, y);
|
||||
if (res)
|
||||
{
|
||||
SetCapture(true);
|
||||
}
|
||||
|
||||
}
|
||||
else if (ev.type == UIEvent.Type_MouseMove)
|
||||
{
|
||||
BackbuttonTime = 4*Thinker.TICRATE;
|
||||
if (mMouseCapture || m_use_mouse == 1)
|
||||
{
|
||||
res = MouseEventBack(MOUSE_Move, ev.MouseX, y);
|
||||
if (res) y = -1;
|
||||
res |= MouseEvent(MOUSE_Move, ev.MouseX, y);
|
||||
}
|
||||
}
|
||||
else if (ev.type == UIEvent.Type_LButtonUp)
|
||||
{
|
||||
if (mMouseCapture)
|
||||
{
|
||||
SetCapture(false);
|
||||
res = MouseEventBack(MOUSE_Release, ev.MouseX, y);
|
||||
if (res) y = -1;
|
||||
res |= MouseEvent(MOUSE_Release, ev.MouseX, y);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool OnInputEvent(InputEvent ev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual void Drawer ()
|
||||
{
|
||||
if (self == GetCurrentMenu() && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse)
|
||||
{
|
||||
let tex = TexMan.CheckForTexture(gameinfo.mBackButton, TexMan.Type_MiscPatch);
|
||||
if (tex.IsValid())
|
||||
{
|
||||
Vector2 v = TexMan.GetScaledSize(tex);
|
||||
int w = int(v.X + 0.5) * CleanXfac;
|
||||
int h = int(v.Y + 0.5) * CleanYfac;
|
||||
int x = (!(m_show_backbutton&1))? 0:screen.GetWidth() - w;
|
||||
int y = (!(m_show_backbutton&2))? 0:screen.GetHeight() - h;
|
||||
if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1))
|
||||
{
|
||||
screen.DrawTexture(tex, true, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, Color(40, 255,255,255));
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawTexture(tex, true, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void SetCapture(bool on)
|
||||
{
|
||||
if (mMouseCapture != on)
|
||||
{
|
||||
mMouseCapture = on;
|
||||
SetMouseCapture(on);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual bool TranslateKeyboardEvents() { return true; }
|
||||
virtual void SetFocus(MenuItemBase fc) {}
|
||||
virtual bool CheckFocus(MenuItemBase fc) { return false; }
|
||||
virtual void ReleaseFocus() {}
|
||||
virtual void ResetColor() {}
|
||||
virtual bool MouseEvent(int type, int mx, int my) { return true; }
|
||||
virtual void Ticker() {}
|
||||
virtual void OnReturn() {}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static void MenuSound(Sound snd)
|
||||
{
|
||||
S_StartSound (snd, CHAN_VOICE, CHANF_MAYBE_LOCAL|CHAN_UI, snd_menuvolume, ATTN_NONE);
|
||||
}
|
||||
|
||||
deprecated("4.0") static void DrawConText (int color, int x, int y, String str)
|
||||
{
|
||||
screen.DrawText (ConFont, color, x, y, str, DTA_CellX, 8 * CleanXfac, DTA_CellY, 8 * CleanYfac);
|
||||
}
|
||||
|
||||
static Font OptionFont()
|
||||
{
|
||||
return NewSmallFont;
|
||||
}
|
||||
|
||||
static int OptionHeight()
|
||||
{
|
||||
return OptionFont().GetHeight();
|
||||
}
|
||||
|
||||
static int OptionWidth(String s)
|
||||
{
|
||||
return OptionFont().StringWidth(s);
|
||||
}
|
||||
|
||||
static void DrawOptionText(int x, int y, int color, String text, bool grayed = false)
|
||||
{
|
||||
String label = Stringtable.Localize(text);
|
||||
int overlay = grayed? Color(96,48,0,0) : 0;
|
||||
screen.DrawText (OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MenuDescriptor : Object native ui version("2.4")
|
||||
{
|
||||
native Name mMenuName;
|
||||
native String mNetgameMessage;
|
||||
native Class<Menu> mClass;
|
||||
|
||||
native static MenuDescriptor GetDescriptor(Name n);
|
||||
}
|
||||
|
||||
// This class is only needed to give it a virtual Init method that doesn't belong to Menu itself
|
||||
class GenericMenu : Menu
|
||||
{
|
||||
virtual void Init(Menu parent)
|
||||
{
|
||||
Super.Init(parent);
|
||||
}
|
||||
}
|
50
wadsrc/static/zscript/ui/menu/menuitembase.zs
Normal file
50
wadsrc/static/zscript/ui/menu/menuitembase.zs
Normal file
|
@ -0,0 +1,50 @@
|
|||
//=============================================================================
|
||||
//
|
||||
// base class for menu items
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class MenuItemBase : Object native ui version("2.4")
|
||||
{
|
||||
protected native double mXpos, mYpos;
|
||||
protected native Name mAction;
|
||||
native bool mEnabled;
|
||||
|
||||
void Init(double xpos = 0, double ypos = 0, Name actionname = 'None')
|
||||
{
|
||||
mXpos = xpos;
|
||||
mYpos = ypos;
|
||||
mAction = actionname;
|
||||
mEnabled = true;
|
||||
}
|
||||
|
||||
virtual bool CheckCoordinate(int x, int y) { return false; }
|
||||
virtual void Ticker() {}
|
||||
virtual void Drawer(bool selected) {}
|
||||
virtual bool Selectable() {return false; }
|
||||
virtual bool Activate() { return false; }
|
||||
virtual Name, int GetAction() { return mAction, 0; }
|
||||
virtual bool SetString(int i, String s) { return false; }
|
||||
virtual bool, String GetString(int i) { return false, ""; }
|
||||
virtual bool SetValue(int i, int value) { return false; }
|
||||
virtual bool, int GetValue(int i) { return false, 0; }
|
||||
virtual void Enable(bool on) { mEnabled = on; }
|
||||
virtual bool MenuEvent (int mkey, bool fromcontroller) { return false; }
|
||||
virtual bool MouseEvent(int type, int x, int y) { return false; }
|
||||
virtual bool CheckHotkey(int c) { return false; }
|
||||
virtual int GetWidth() { return 0; }
|
||||
virtual int GetIndent() { return 0; }
|
||||
virtual int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) { return indent; }
|
||||
|
||||
void OffsetPositionY(double ydelta) { mYpos += ydelta; }
|
||||
double GetY() { return mYpos; }
|
||||
double GetX() { return mXpos; }
|
||||
void SetX(double x) { mXpos = x; }
|
||||
virtual void OnMenuCreated() {}
|
||||
}
|
||||
|
||||
// this is only used to parse font color ranges in MENUDEF
|
||||
enum MenudefColorRange
|
||||
{
|
||||
NO_COLOR = -1
|
||||
}
|
318
wadsrc/static/zscript/ui/menu/messagebox.zs
Normal file
318
wadsrc/static/zscript/ui/menu/messagebox.zs
Normal file
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
** messagebox.cpp
|
||||
** Confirmation, notification screens
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
class MessageBoxMenu : Menu
|
||||
{
|
||||
BrokenLines mMessage;
|
||||
voidptr Handler;
|
||||
int mMessageMode;
|
||||
int messageSelection;
|
||||
int mMouseLeft, mMouseRight, mMouseY;
|
||||
Name mAction;
|
||||
|
||||
Font textFont, arrowFont;
|
||||
int destWidth, destHeight;
|
||||
String selector;
|
||||
|
||||
native static void CallHandler(voidptr hnd);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual void Init(Menu parent, String message, int messagemode, bool playsound = false, Name cmd = 'None', voidptr native_handler = null)
|
||||
{
|
||||
Super.Init(parent);
|
||||
mAction = cmd;
|
||||
messageSelection = 0;
|
||||
mMouseLeft = 140;
|
||||
mMouseY = 0x80000000;
|
||||
textFont = null;
|
||||
|
||||
if (!generic_ui)
|
||||
{
|
||||
if (SmallFont && SmallFont.CanPrint(message) && SmallFont.CanPrint("$TXT_YES") && SmallFont.CanPrint("$TXT_NO")) textFont = SmallFont;
|
||||
else if (OriginalSmallFont && OriginalSmallFont.CanPrint(message) && OriginalSmallFont.CanPrint("$TXT_YES") && OriginalSmallFont.CanPrint("$TXT_NO")) textFont = OriginalSmallFont;
|
||||
}
|
||||
|
||||
if (!textFont)
|
||||
{
|
||||
arrowFont = textFont = NewSmallFont;
|
||||
int factor = (CleanXfac+1) / 2;
|
||||
destWidth = screen.GetWidth() / factor;
|
||||
destHeight = screen.GetHeight() / factor;
|
||||
selector = "▶";
|
||||
}
|
||||
else
|
||||
{
|
||||
arrowFont = ConFont;
|
||||
destWidth = CleanWidth;
|
||||
destHeight = CleanHeight;
|
||||
selector = "\xd";
|
||||
}
|
||||
|
||||
int mr1 = destWidth/2 + 10 + textFont.StringWidth(Stringtable.Localize("$TXT_YES"));
|
||||
int mr2 = destWidth/2 + 10 + textFont.StringWidth(Stringtable.Localize("$TXT_NO"));
|
||||
mMouseRight = MAX(mr1, mr2);
|
||||
mParentMenu = parent;
|
||||
mMessage = textFont.BreakLines(Stringtable.Localize(message), generic_ui? 600 : 300);
|
||||
mMessageMode = messagemode;
|
||||
if (playsound)
|
||||
{
|
||||
MenuSound ("menu/prompt");
|
||||
}
|
||||
Handler = native_handler;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
int i, y;
|
||||
int fontheight = textFont.GetHeight();
|
||||
|
||||
y = destHeight / 2;
|
||||
|
||||
int c = mMessage.Count();
|
||||
y -= c * fontHeight / 2;
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
screen.DrawText (textFont, Font.CR_UNTRANSLATED, destWidth/2 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true);
|
||||
y += fontheight;
|
||||
}
|
||||
|
||||
if (mMessageMode == 0)
|
||||
{
|
||||
y += fontheight;
|
||||
mMouseY = y;
|
||||
screen.DrawText(textFont, messageSelection == 0? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, destWidth / 2, y, Stringtable.Localize("$TXT_YES"), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true);
|
||||
screen.DrawText(textFont, messageSelection == 1? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, destWidth / 2, y + fontheight, Stringtable.Localize("$TXT_NO"), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true);
|
||||
|
||||
if (messageSelection >= 0)
|
||||
{
|
||||
if ((MenuTime() % 8) < 6)
|
||||
{
|
||||
screen.DrawText(arrowFont, OptionMenuSettings.mFontColorSelection,
|
||||
destWidth/2 - 11, y + fontheight * messageSelection, selector, DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
protected void CloseSound()
|
||||
{
|
||||
MenuSound (GetCurrentMenu() != NULL? "menu/backup" : "menu/dismiss");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual void HandleResult(bool res)
|
||||
{
|
||||
if (Handler != null)
|
||||
{
|
||||
if (res)
|
||||
{
|
||||
CallHandler(Handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
CloseSound();
|
||||
}
|
||||
}
|
||||
else if (mParentMenu != NULL)
|
||||
{
|
||||
if (mMessageMode == 0)
|
||||
{
|
||||
if (mAction == 'None')
|
||||
{
|
||||
mParentMenu.MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
if (res) SetMenu(mAction, -1);
|
||||
}
|
||||
CloseSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.type == UIEvent.Type_KeyDown)
|
||||
{
|
||||
if (mMessageMode == 0)
|
||||
{
|
||||
// tolower
|
||||
int ch = ev.KeyChar;
|
||||
ch = ch >= 65 && ch <91? ch + 32 : ch;
|
||||
|
||||
if (ch == 110 /*'n'*/ || ch == 32)
|
||||
{
|
||||
HandleResult(false);
|
||||
return true;
|
||||
}
|
||||
else if (ch == 121 /*'y'*/)
|
||||
{
|
||||
HandleResult(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
override bool OnInputEvent(InputEvent ev)
|
||||
{
|
||||
if (ev.type == InputEvent.Type_KeyDown)
|
||||
{
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
return Super.OnInputEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mMessageMode == 0)
|
||||
{
|
||||
if (mkey == MKEY_Up || mkey == MKEY_Down)
|
||||
{
|
||||
MenuSound("menu/cursor");
|
||||
messageSelection = !messageSelection;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Enter)
|
||||
{
|
||||
// 0 is yes, 1 is no
|
||||
HandleResult(!messageSelection);
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Back)
|
||||
{
|
||||
HandleResult(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
CloseSound();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (mMessageMode == 1)
|
||||
{
|
||||
if (type == MOUSE_Click)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sel = -1;
|
||||
int fh = textFont.GetHeight() + 1;
|
||||
|
||||
// convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture
|
||||
x = x * destWidth / screen.GetWidth();
|
||||
y = y * destHeight / screen.GetHeight();
|
||||
|
||||
if (x >= mMouseLeft && x <= mMouseRight && y >= mMouseY && y < mMouseY + 2 * fh)
|
||||
{
|
||||
sel = y >= mMouseY + fh;
|
||||
}
|
||||
messageSelection = sel;
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
601
wadsrc/static/zscript/ui/menu/optionmenu.zs
Normal file
601
wadsrc/static/zscript/ui/menu/optionmenu.zs
Normal file
|
@ -0,0 +1,601 @@
|
|||
/*
|
||||
** optionmenu.cpp
|
||||
** Handler class for the option menus and associated items
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
struct FOptionMenuSettings native version("2.4")
|
||||
{
|
||||
int mTitleColor;
|
||||
int mFontColor;
|
||||
int mFontColorValue;
|
||||
int mFontColorMore;
|
||||
int mFontColorHeader;
|
||||
int mFontColorHighlight;
|
||||
int mFontColorSelection;
|
||||
int mLinespacing;
|
||||
}
|
||||
|
||||
class OptionMenuDescriptor : MenuDescriptor native
|
||||
{
|
||||
native Array<OptionMenuItem> mItems;
|
||||
native String mTitle;
|
||||
native int mSelectedItem;
|
||||
native int mDrawTop;
|
||||
native int mScrollTop;
|
||||
native int mScrollPos;
|
||||
native int mIndent;
|
||||
native int mPosition;
|
||||
native bool mDontDim;
|
||||
native Font mFont;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
// Reset the default settings (ignore all other values in the struct)
|
||||
mPosition = 0;
|
||||
mScrollTop = 0;
|
||||
mIndent = 0;
|
||||
mDontDim = 0;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void CalcIndent()
|
||||
{
|
||||
// calculate the menu indent
|
||||
int widest = 0, thiswidth;
|
||||
|
||||
for (int i = 0; i < mItems.Size(); i++)
|
||||
{
|
||||
thiswidth = mItems[i].GetIndent();
|
||||
if (thiswidth > widest) widest = thiswidth;
|
||||
}
|
||||
mIndent = widest + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OptionMenu : Menu
|
||||
{
|
||||
OptionMenuDescriptor mDesc;
|
||||
bool CanScrollUp;
|
||||
bool CanScrollDown;
|
||||
int VisBottom;
|
||||
OptionMenuItem mFocusControl;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
mParentMenu = parent;
|
||||
mDesc = desc;
|
||||
DontDim = desc.mDontDim;
|
||||
|
||||
let itemCount = mDesc.mItems.size();
|
||||
if (itemCount > 0)
|
||||
{
|
||||
let last = mDesc.mItems[itemCount - 1];
|
||||
bool lastIsText = (last is "OptionMenuItemStaticText");
|
||||
if (lastIsText)
|
||||
{
|
||||
String text = last.mLabel;
|
||||
bool lastIsSpace = (text == "" || text == " ");
|
||||
if (lastIsSpace)
|
||||
{
|
||||
mDesc.mItems.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mDesc.mSelectedItem == -1) mDesc.mSelectedItem = FirstSelectable();
|
||||
mDesc.CalcIndent();
|
||||
|
||||
// notify all items that the menu was just created.
|
||||
for(int i=0;i<mDesc.mItems.Size(); i++)
|
||||
{
|
||||
mDesc.mItems[i].OnMenuCreated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
OptionMenuItem GetItem(Name name)
|
||||
{
|
||||
for(int i = 0; i < mDesc.mItems.Size(); i++)
|
||||
{
|
||||
Name nm = mDesc.mItems[i].GetAction();
|
||||
if (nm == name) return mDesc.mItems[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
int FirstSelectable()
|
||||
{
|
||||
// Go down to the first selectable item
|
||||
int i = -1;
|
||||
do
|
||||
{
|
||||
i++;
|
||||
}
|
||||
while (i < mDesc.mItems.Size() && !mDesc.mItems[i].Selectable());
|
||||
if (i>=0 && i < mDesc.mItems.Size()) return i;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.type == UIEvent.Type_WheelUp)
|
||||
{
|
||||
int scrollamt = MIN(2, mDesc.mScrollPos);
|
||||
mDesc.mScrollPos -= scrollamt;
|
||||
return true;
|
||||
}
|
||||
else if (ev.type == UIEvent.Type_WheelDown)
|
||||
{
|
||||
if (CanScrollDown)
|
||||
{
|
||||
if (VisBottom >= 0 && VisBottom < (mDesc.mItems.Size()-2))
|
||||
{
|
||||
mDesc.mScrollPos += 2;
|
||||
VisBottom += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDesc.mScrollPos++;
|
||||
VisBottom++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
int startedAt = mDesc.mSelectedItem;
|
||||
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Up:
|
||||
if (mDesc.mSelectedItem == -1)
|
||||
{
|
||||
mDesc.mSelectedItem = FirstSelectable();
|
||||
break;
|
||||
}
|
||||
do
|
||||
{
|
||||
--mDesc.mSelectedItem;
|
||||
|
||||
if (mDesc.mScrollPos > 0 &&
|
||||
mDesc.mSelectedItem <= mDesc.mScrollTop + mDesc.mScrollPos)
|
||||
{
|
||||
mDesc.mScrollPos = MAX(mDesc.mSelectedItem - mDesc.mScrollTop - 1, 0);
|
||||
}
|
||||
|
||||
if (mDesc.mSelectedItem < 0)
|
||||
{
|
||||
// Figure out how many lines of text fit on the menu
|
||||
int y = mDesc.mPosition;
|
||||
|
||||
if (y <= 0)
|
||||
{
|
||||
let font = generic_ui || !mDesc.mFont? NewSmallFont : mDesc.mFont;
|
||||
if (font && mDesc.mTitle.Length() > 0)
|
||||
{
|
||||
y = -y + font.GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
y = -y;
|
||||
}
|
||||
}
|
||||
y *= CleanYfac_1;
|
||||
int rowheight = OptionMenuSettings.mLinespacing * CleanYfac_1;
|
||||
int maxitems = (screen.GetHeight() - rowheight - y) / rowheight + 1;
|
||||
|
||||
mDesc.mScrollPos = MAX (0, mDesc.mItems.Size() - maxitems + mDesc.mScrollTop);
|
||||
mDesc.mSelectedItem = mDesc.mItems.Size()-1;
|
||||
}
|
||||
}
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt);
|
||||
break;
|
||||
|
||||
case MKEY_Down:
|
||||
if (mDesc.mSelectedItem == -1)
|
||||
{
|
||||
mDesc.mSelectedItem = FirstSelectable();
|
||||
break;
|
||||
}
|
||||
do
|
||||
{
|
||||
++mDesc.mSelectedItem;
|
||||
|
||||
if (CanScrollDown && mDesc.mSelectedItem == VisBottom)
|
||||
{
|
||||
mDesc.mScrollPos++;
|
||||
VisBottom++;
|
||||
}
|
||||
if (mDesc.mSelectedItem >= mDesc.mItems.Size())
|
||||
{
|
||||
if (startedAt == -1)
|
||||
{
|
||||
mDesc.mSelectedItem = -1;
|
||||
mDesc.mScrollPos = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDesc.mSelectedItem = 0;
|
||||
mDesc.mScrollPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt);
|
||||
break;
|
||||
|
||||
case MKEY_PageUp:
|
||||
if (mDesc.mScrollPos > 0)
|
||||
{
|
||||
mDesc.mScrollPos -= VisBottom - mDesc.mScrollPos - mDesc.mScrollTop;
|
||||
if (mDesc.mScrollPos < 0)
|
||||
{
|
||||
mDesc.mScrollPos = 0;
|
||||
}
|
||||
if (mDesc.mSelectedItem != -1)
|
||||
{
|
||||
mDesc.mSelectedItem = mDesc.mScrollTop + mDesc.mScrollPos + 1;
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable())
|
||||
{
|
||||
if (++mDesc.mSelectedItem >= mDesc.mItems.Size())
|
||||
{
|
||||
mDesc.mSelectedItem = 0;
|
||||
}
|
||||
}
|
||||
if (mDesc.mScrollPos > mDesc.mSelectedItem)
|
||||
{
|
||||
mDesc.mScrollPos = mDesc.mSelectedItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_PageDown:
|
||||
if (CanScrollDown)
|
||||
{
|
||||
int pagesize = VisBottom - mDesc.mScrollPos - mDesc.mScrollTop;
|
||||
mDesc.mScrollPos += pagesize;
|
||||
if (mDesc.mScrollPos + mDesc.mScrollTop + pagesize > mDesc.mItems.Size())
|
||||
{
|
||||
mDesc.mScrollPos = mDesc.mItems.Size() - mDesc.mScrollTop - pagesize;
|
||||
}
|
||||
if (mDesc.mSelectedItem != -1)
|
||||
{
|
||||
mDesc.mSelectedItem = mDesc.mScrollTop + mDesc.mScrollPos;
|
||||
while (!mDesc.mItems[mDesc.mSelectedItem].Selectable())
|
||||
{
|
||||
if (++mDesc.mSelectedItem >= mDesc.mItems.Size())
|
||||
{
|
||||
mDesc.mSelectedItem = 0;
|
||||
}
|
||||
}
|
||||
if (mDesc.mScrollPos > mDesc.mSelectedItem)
|
||||
{
|
||||
mDesc.mScrollPos = mDesc.mSelectedItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MKEY_Enter:
|
||||
if (mDesc.mSelectedItem >= 0 && mDesc.mItems[mDesc.mSelectedItem].Activate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// fall through to default
|
||||
default:
|
||||
if (mDesc.mSelectedItem >= 0 &&
|
||||
mDesc.mItems[mDesc.mSelectedItem].MenuEvent(mkey, fromcontroller)) return true;
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
if (mDesc.mSelectedItem != startedAt)
|
||||
{
|
||||
MenuSound ("menu/cursor");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
y = (y / CleanYfac_1) - mDesc.mDrawTop;
|
||||
|
||||
if (mFocusControl)
|
||||
{
|
||||
mFocusControl.MouseEvent(type, x, y);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int yline = (y / OptionMenuSettings.mLinespacing);
|
||||
if (yline >= mDesc.mScrollTop)
|
||||
{
|
||||
yline += mDesc.mScrollPos;
|
||||
}
|
||||
if (yline >= 0 && yline < mDesc.mItems.Size() && mDesc.mItems[yline].Selectable())
|
||||
{
|
||||
if (yline != mDesc.mSelectedItem)
|
||||
{
|
||||
mDesc.mSelectedItem = yline;
|
||||
}
|
||||
mDesc.mItems[yline].MouseEvent(type, x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mDesc.mSelectedItem = -1;
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Ticker ()
|
||||
{
|
||||
Super.Ticker();
|
||||
for(int i = 0; i < mDesc.mItems.Size(); i++)
|
||||
{
|
||||
mDesc.mItems[i].Ticker();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual int GetIndent()
|
||||
{
|
||||
int indent = max(0, (mDesc.mIndent + 40) - CleanWidth_1 / 2);
|
||||
return screen.GetWidth() / 2 + indent * CleanXfac_1;
|
||||
}
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
int y = mDesc.mPosition;
|
||||
|
||||
if (y <= 0)
|
||||
{
|
||||
let font = generic_ui || !mDesc.mFont? NewSmallFont : mDesc.mFont;
|
||||
if (font && mDesc.mTitle.Length() > 0)
|
||||
{
|
||||
let tt = Stringtable.Localize(mDesc.mTitle);
|
||||
screen.DrawText (font, OptionMenuSettings.mTitleColor,
|
||||
(screen.GetWidth() - font.StringWidth(tt) * CleanXfac_1) / 2, 10*CleanYfac_1,
|
||||
tt, DTA_CleanNoMove_1, true);
|
||||
y = -y + font.GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
y = -y;
|
||||
}
|
||||
}
|
||||
mDesc.mDrawTop = y;
|
||||
int fontheight = OptionMenuSettings.mLinespacing * CleanYfac_1;
|
||||
y *= CleanYfac_1;
|
||||
|
||||
int indent = GetIndent();
|
||||
|
||||
int ytop = y + mDesc.mScrollTop * 8 * CleanYfac_1;
|
||||
int lastrow = screen.GetHeight() - OptionHeight() * CleanYfac_1;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < mDesc.mItems.Size() && y <= lastrow; i++)
|
||||
{
|
||||
// Don't scroll the uppermost items
|
||||
if (i == mDesc.mScrollTop)
|
||||
{
|
||||
i += mDesc.mScrollPos;
|
||||
if (i >= mDesc.mItems.Size()) break; // skipped beyond end of menu
|
||||
}
|
||||
bool isSelected = mDesc.mSelectedItem == i;
|
||||
int cur_indent = mDesc.mItems[i].Draw(mDesc, y, indent, isSelected);
|
||||
if (cur_indent >= 0 && isSelected && mDesc.mItems[i].Selectable())
|
||||
{
|
||||
if (((MenuTime() % 8) < 6) || GetCurrentMenu() != self)
|
||||
{
|
||||
DrawOptionText(cur_indent + 3 * CleanXfac_1, y, OptionMenuSettings.mFontColorSelection, "◄");
|
||||
}
|
||||
}
|
||||
y += fontheight;
|
||||
}
|
||||
|
||||
CanScrollUp = (mDesc.mScrollPos > 0);
|
||||
CanScrollDown = (i < mDesc.mItems.Size());
|
||||
VisBottom = i - 1;
|
||||
|
||||
if (CanScrollUp)
|
||||
{
|
||||
DrawOptionText(screen.GetWidth() - 11 * CleanXfac_1, ytop, OptionMenuSettings.mFontColorSelection, "▲");
|
||||
}
|
||||
if (CanScrollDown)
|
||||
{
|
||||
DrawOptionText(screen.GetWidth() - 11 * CleanXfac_1 , y - 8*CleanYfac_1, OptionMenuSettings.mFontColorSelection, "▼");
|
||||
}
|
||||
Super.Drawer();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void SetFocus(MenuItemBase fc)
|
||||
{
|
||||
mFocusControl = OptionMenuItem(fc);
|
||||
}
|
||||
|
||||
override bool CheckFocus(MenuItemBase fc)
|
||||
{
|
||||
return mFocusControl == fc;
|
||||
}
|
||||
|
||||
override void ReleaseFocus()
|
||||
{
|
||||
mFocusControl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GameplayMenu : OptionMenu
|
||||
{
|
||||
override void Drawer ()
|
||||
{
|
||||
Super.Drawer();
|
||||
|
||||
String s = String.Format("dmflags = %d dmflags2 = %d", dmflags, dmflags2);
|
||||
screen.DrawText (OptionFont(), OptionMenuSettings.mFontColorValue,
|
||||
(screen.GetWidth() - OptionWidth (s) * CleanXfac_1) / 2, 35 * CleanXfac_1, s,
|
||||
DTA_CleanNoMove_1, true);
|
||||
}
|
||||
}
|
||||
|
||||
class CompatibilityMenu : OptionMenu
|
||||
{
|
||||
override void Drawer ()
|
||||
{
|
||||
Super.Drawer();
|
||||
|
||||
String s = String.Format("compatflags = %d compatflags2 = %d", compatflags, compatflags2);
|
||||
screen.DrawText (OptionFont(), OptionMenuSettings.mFontColorValue,
|
||||
(screen.GetWidth() - OptionWidth (s) * CleanXfac_1) / 2, 35 * CleanXfac_1, s,
|
||||
DTA_CleanNoMove_1, true);
|
||||
}
|
||||
}
|
||||
|
||||
class GLTextureGLOptions : OptionMenu
|
||||
{
|
||||
private int mWarningIndex;
|
||||
private string mWarningLabel;
|
||||
|
||||
override void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
super.Init(parent, desc);
|
||||
|
||||
// Find index of warning item placeholder
|
||||
mWarningIndex = -1;
|
||||
mWarningLabel = "!HQRESIZE_WARNING!";
|
||||
|
||||
for (int i=0; i < mDesc.mItems.Size(); ++i)
|
||||
{
|
||||
if (mDesc.mItems[i].mLabel == mWarningLabel)
|
||||
{
|
||||
mWarningIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
// Restore warning item placeholder
|
||||
if (mWarningIndex >= 0)
|
||||
{
|
||||
mDesc.mItems[mWarningIndex].mLabel = mWarningLabel;
|
||||
}
|
||||
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
override void Ticker()
|
||||
{
|
||||
Super.Ticker();
|
||||
|
||||
if (mWarningIndex >= 0)
|
||||
{
|
||||
string message;
|
||||
|
||||
if (gl_texture_hqresizemult > 1 && gl_texture_hqresizemode > 0)
|
||||
{
|
||||
int multiplier = gl_texture_hqresizemult * gl_texture_hqresizemult;
|
||||
|
||||
message = StringTable.Localize("$GLTEXMNU_HQRESIZEWARN");
|
||||
string mult = String.Format("%d", multiplier);
|
||||
message.Replace("%d", mult);
|
||||
}
|
||||
|
||||
mDesc.mItems[mWarningIndex].mLabel = Font.TEXTCOLOR_CYAN .. message;
|
||||
}
|
||||
}
|
||||
}
|
1275
wadsrc/static/zscript/ui/menu/optionmenuitems.zs
Normal file
1275
wadsrc/static/zscript/ui/menu/optionmenuitems.zs
Normal file
File diff suppressed because it is too large
Load diff
125
wadsrc/static/zscript/ui/menu/readthis.zs
Normal file
125
wadsrc/static/zscript/ui/menu/readthis.zs
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
** readthis.cpp
|
||||
** Help screens
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2001-2010 Randy Heit
|
||||
** Copyright 2010 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
class ReadThisMenu : GenericMenu
|
||||
{
|
||||
int mScreen;
|
||||
int mInfoTic;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent)
|
||||
{
|
||||
Super.Init(parent);
|
||||
mScreen = 1;
|
||||
mInfoTic = gametic;
|
||||
}
|
||||
|
||||
override void Drawer()
|
||||
{
|
||||
double alpha;
|
||||
TextureID tex, prevpic;
|
||||
|
||||
// Did the mapper choose a custom help page via MAPINFO?
|
||||
if (Level.F1Pic.Length() != 0)
|
||||
{
|
||||
tex = TexMan.CheckForTexture(Level.F1Pic, TexMan.Type_MiscPatch);
|
||||
mScreen = 1;
|
||||
}
|
||||
|
||||
if (!tex.IsValid())
|
||||
{
|
||||
tex = TexMan.CheckForTexture(gameinfo.infoPages[mScreen-1], TexMan.Type_MiscPatch);
|
||||
}
|
||||
|
||||
if (mScreen > 1)
|
||||
{
|
||||
prevpic = TexMan.CheckForTexture(gameinfo.infoPages[mScreen-2], TexMan.Type_MiscPatch);
|
||||
}
|
||||
|
||||
screen.Dim(0, 1.0, 0,0, screen.GetWidth(), screen.GetHeight());
|
||||
alpha = MIN((gametic - mInfoTic) * (3. / Thinker.TICRATE), 1.);
|
||||
if (alpha < 1. && prevpic.IsValid())
|
||||
{
|
||||
screen.DrawTexture (prevpic, false, 0, 0, DTA_Fullscreen, true);
|
||||
}
|
||||
else alpha = 1;
|
||||
screen.DrawTexture (tex, false, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mkey == MKEY_Enter)
|
||||
{
|
||||
MenuSound("menu/choose");
|
||||
mScreen++;
|
||||
mInfoTic = gametic;
|
||||
if (Level.F1Pic.Length() != 0 || mScreen > gameinfo.infoPages.Size())
|
||||
{
|
||||
Close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
if (type == MOUSE_Click)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
258
wadsrc/static/zscript/ui/menu/reverbedit.zs
Normal file
258
wadsrc/static/zscript/ui/menu/reverbedit.zs
Normal file
|
@ -0,0 +1,258 @@
|
|||
|
||||
class ReverbEdit : OptionMenu
|
||||
{
|
||||
static native double GetValue(int index);
|
||||
static native double SetValue(int index, double value);
|
||||
static native bool GrayCheck();
|
||||
static native string, int GetSelectedEnvironment();
|
||||
static native void FillSelectMenu(String ccmd, OptionMenuDescriptor desc);
|
||||
static native void FillSaveMenu(OptionMenuDescriptor desc);
|
||||
static native int GetSaveSelection(int num);
|
||||
static native void ToggleSaveSelection(int num);
|
||||
|
||||
override void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
super.Init(parent, desc);
|
||||
OnReturn();
|
||||
}
|
||||
|
||||
override void OnReturn()
|
||||
{
|
||||
string env;
|
||||
int id;
|
||||
|
||||
[env, id] = GetSelectedEnvironment();
|
||||
|
||||
let li = GetItem('EvironmentName');
|
||||
if (li != NULL)
|
||||
{
|
||||
if (id != -1)
|
||||
{
|
||||
li.SetValue(0, 1);
|
||||
li.SetString(0, env);
|
||||
}
|
||||
else
|
||||
{
|
||||
li.SetValue(0, 0);
|
||||
}
|
||||
}
|
||||
li = GetItem('EvironmentID');
|
||||
if (li != NULL)
|
||||
{
|
||||
if (id != -1)
|
||||
{
|
||||
li.SetValue(0, 1);
|
||||
li.SetString(0, String.Format("%d, %d", (id >> 8) & 255, id & 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
li.SetValue(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ReverbSelect : OptionMenu
|
||||
{
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
ReverbEdit.FillSelectMenu("selectenvironment", desc);
|
||||
super.Init(parent, desc);
|
||||
}
|
||||
}
|
||||
|
||||
class ReverbSave : OptionMenu
|
||||
{
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
ReverbEdit.FillSaveMenu(desc);
|
||||
super.Init(parent, desc);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Change a CVAR, command is the CVAR name
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemReverbSaveSelect : OptionMenuItemOptionBase
|
||||
{
|
||||
int mValIndex;
|
||||
|
||||
OptionMenuItemReverbSaveSelect Init(String label, int index, Name values)
|
||||
{
|
||||
Super.Init(label, 'None', values, null, 0);
|
||||
mValIndex = index;
|
||||
return self;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
override int GetSelection()
|
||||
{
|
||||
return ReverbEdit.GetSaveSelection(mValIndex);
|
||||
}
|
||||
|
||||
override void SetSelection(int Selection)
|
||||
{
|
||||
ReverbEdit.ToggleSaveSelection(mValIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// opens a submenu, command is a submenu name
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemReverbSelect : OptionMenuItemSubMenu
|
||||
{
|
||||
OptionMenuItemReverbSelect Init(String label, Name command)
|
||||
{
|
||||
Super.init(label, command, 0, false);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected)
|
||||
{
|
||||
int x = drawLabel(indent, y, selected? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor);
|
||||
|
||||
String text = ReverbEdit.GetSelectedEnvironment();
|
||||
drawValue(indent, y, OptionMenuSettings.mFontColorValue, text);
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemReverbOption : OptionMenuItemOptionBase
|
||||
{
|
||||
int mValIndex;
|
||||
|
||||
OptionMenuItemReverbOption Init(String label, int valindex, Name values)
|
||||
{
|
||||
Super.Init(label, "", values, null, false);
|
||||
mValIndex = valindex;
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool isGrayed()
|
||||
{
|
||||
return ReverbEdit.GrayCheck();
|
||||
}
|
||||
|
||||
override int GetSelection()
|
||||
{
|
||||
return int(ReverbEdit.GetValue(mValIndex));
|
||||
}
|
||||
|
||||
override void SetSelection(int Selection)
|
||||
{
|
||||
ReverbEdit.SetValue(mValIndex, Selection);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemSliderReverbEditOption : OptionMenuSliderBase
|
||||
{
|
||||
int mValIndex;
|
||||
String mEditValue;
|
||||
TextEnterMenu mEnter;
|
||||
|
||||
OptionMenuItemSliderReverbEditOption Init(String label, double min, double max, double step, int showval, int valindex)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mValIndex = valindex;
|
||||
mEnter = null;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
return ReverbEdit.GetValue(mValIndex);
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
ReverbEdit.SetValue(mValIndex, val);
|
||||
}
|
||||
|
||||
override bool Selectable()
|
||||
{
|
||||
return !ReverbEdit.GrayCheck();
|
||||
}
|
||||
|
||||
virtual String Represent()
|
||||
{
|
||||
return mEnter.GetText() .. Menu.OptionFont().GetCursor();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected)
|
||||
{
|
||||
drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, ReverbEdit.GrayCheck());
|
||||
|
||||
mDrawX = indent + CursorSpace();
|
||||
if (mEnter)
|
||||
{
|
||||
drawText(mDrawX, y, OptionMenuSettings.mFontColorValue, Represent());
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent);
|
||||
}
|
||||
return indent;
|
||||
}
|
||||
|
||||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mkey == Menu.MKEY_Enter)
|
||||
{
|
||||
Menu.MenuSound("menu/choose");
|
||||
mEnter = TextEnterMenu.OpenTextEnter(Menu.GetCurrentMenu(), Menu.OptionFont(), String.Format("%.3f", GetSliderValue()), -1, fromcontroller);
|
||||
mEnter.ActivateMenu();
|
||||
return true;
|
||||
}
|
||||
else if (mkey == Menu.MKEY_Input)
|
||||
{
|
||||
String val = mEnter.GetText();
|
||||
SetSliderValue(val.toDouble());
|
||||
mEnter = null;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == Menu.MKEY_Abort)
|
||||
{
|
||||
mEnter = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
}
|
||||
|
33
wadsrc/static/zscript/ui/menu/search/anyoralloption.zs
Normal file
33
wadsrc/static/zscript/ui/menu/search/anyoralloption.zs
Normal file
|
@ -0,0 +1,33 @@
|
|||
//=============================================================================
|
||||
//
|
||||
// os_AnyOrAllOption class represents an Option Item for Option Search menu.
|
||||
// Changing the value of this option causes the menu to refresh the search
|
||||
// results.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class os_AnyOrAllOption : OptionMenuItemOption
|
||||
{
|
||||
os_AnyOrAllOption Init(os_Menu menu)
|
||||
{
|
||||
Super.Init("", "os_isanyof", "os_isanyof_values");
|
||||
|
||||
mMenu = menu;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
bool result = Super.MenuEvent(mkey, fromcontroller);
|
||||
|
||||
if (mKey == Menu.MKEY_Left || mKey == Menu.MKEY_Right || mkey == Menu.MKEY_Enter)
|
||||
{
|
||||
mMenu.search();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private os_Menu mMenu;
|
||||
}
|
218
wadsrc/static/zscript/ui/menu/search/menu.zs
Normal file
218
wadsrc/static/zscript/ui/menu/search/menu.zs
Normal file
|
@ -0,0 +1,218 @@
|
|||
//=============================================================================
|
||||
//
|
||||
// Option Search Menu class.
|
||||
// This menu contains search field, and is dynamically filled with search
|
||||
// results.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class os_Menu : OptionMenu
|
||||
{
|
||||
override void Init(Menu parent, OptionMenuDescriptor desc)
|
||||
{
|
||||
Super.Init(parent, desc);
|
||||
|
||||
mDesc.mItems.clear();
|
||||
|
||||
addSearchField();
|
||||
|
||||
mDesc.mScrollPos = 0;
|
||||
mDesc.mSelectedItem = 0;
|
||||
mDesc.CalcIndent();
|
||||
}
|
||||
|
||||
void search()
|
||||
{
|
||||
string text = mSearchField.GetText();
|
||||
let query = os_Query.fromString(text);
|
||||
bool isAnyTermMatches = mIsAnyOfItem.mCVar.GetBool();
|
||||
|
||||
mDesc.mItems.clear();
|
||||
|
||||
addSearchField(text);
|
||||
|
||||
bool found = listOptions(mDesc, "MainMenu", query, "", isAnyTermMatches);
|
||||
|
||||
if (!found) { addNoResultsItem(mDesc); }
|
||||
|
||||
mDesc.CalcIndent();
|
||||
}
|
||||
|
||||
private void addSearchField(string query = "")
|
||||
{
|
||||
string searchLabel = StringTable.Localize("$OS_LABEL");
|
||||
|
||||
mSearchField = new("os_SearchField").Init(searchLabel, self, query);
|
||||
mIsAnyOfItem = new("os_AnyOrAllOption").Init(self);
|
||||
|
||||
mDesc.mItems.push(mSearchField);
|
||||
mDesc.mItems.push(mIsAnyOfItem);
|
||||
addEmptyLine(mDesc);
|
||||
}
|
||||
|
||||
private static bool listOptions(OptionMenuDescriptor targetDesc,
|
||||
string menuName,
|
||||
os_Query query,
|
||||
string path,
|
||||
bool isAnyTermMatches)
|
||||
{
|
||||
let desc = MenuDescriptor.GetDescriptor(menuName);
|
||||
let listMenuDesc = ListMenuDescriptor(desc);
|
||||
|
||||
if (listMenuDesc)
|
||||
{
|
||||
return listOptionsListMenu(listMenuDesc, targetDesc, query, path, isAnyTermMatches);
|
||||
}
|
||||
|
||||
let optionMenuDesc = OptionMenuDescriptor(desc);
|
||||
|
||||
if (optionMenuDesc)
|
||||
{
|
||||
return listOptionsOptionMenu(optionMenuDesc, targetDesc, query, path, isAnyTermMatches);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool listOptionsListMenu(ListMenuDescriptor sourceDesc,
|
||||
OptionMenuDescriptor targetDesc,
|
||||
os_Query query,
|
||||
string path,
|
||||
bool isAnyTermMatches)
|
||||
{
|
||||
int nItems = sourceDesc.mItems.size();
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < nItems; ++i)
|
||||
{
|
||||
let item = sourceDesc.mItems[i];
|
||||
string actionN = item.GetAction();
|
||||
let textItem = ListMenuItemTextItem(item);
|
||||
string newPath = textItem
|
||||
? makePath(path, StringTable.Localize(textItem.mText))
|
||||
: path;
|
||||
|
||||
found |= listOptions(targetDesc, actionN, query, newPath, isAnyTermMatches);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private static bool listOptionsOptionMenu(OptionMenuDescriptor sourceDesc,
|
||||
OptionMenuDescriptor targetDesc,
|
||||
os_Query query,
|
||||
string path,
|
||||
bool isAnyTermMatches)
|
||||
{
|
||||
if (sourceDesc == targetDesc) { return false; }
|
||||
|
||||
int nItems = sourceDesc.mItems.size();
|
||||
bool first = true;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < nItems; ++i)
|
||||
{
|
||||
let item = sourceDesc.mItems[i];
|
||||
|
||||
if (item is "OptionMenuItemStaticText") { continue; }
|
||||
|
||||
string label = StringTable.Localize(item.mLabel);
|
||||
|
||||
if (!query.matches(label, isAnyTermMatches)) { continue; }
|
||||
|
||||
found = true;
|
||||
|
||||
if (first)
|
||||
{
|
||||
addEmptyLine(targetDesc);
|
||||
addPathItem(targetDesc, path);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
let itemOptionBase = OptionMenuItemOptionBase(item);
|
||||
|
||||
if (itemOptionBase)
|
||||
{
|
||||
itemOptionBase.mCenter = false;
|
||||
}
|
||||
|
||||
targetDesc.mItems.push(item);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nItems; ++i)
|
||||
{
|
||||
let item = sourceDesc.mItems[i];
|
||||
string label = StringTable.Localize(item.mLabel);
|
||||
string optionSearchTitle = StringTable.Localize("$OS_TITLE");
|
||||
|
||||
if (label == optionSearchTitle) { continue; }
|
||||
|
||||
if (item is "OptionMenuItemSubMenu")
|
||||
{
|
||||
string newPath = makePath(path, label);
|
||||
|
||||
found |= listOptions(targetDesc, item.GetAction(), query, newPath, isAnyTermMatches);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private static string makePath(string path, string label)
|
||||
{
|
||||
if (path.length() == 0) { return label; }
|
||||
|
||||
int pathWidth = SmallFont.StringWidth(path .. "/" .. label);
|
||||
int screenWidth = Screen.GetWidth();
|
||||
bool isTooWide = (pathWidth > screenWidth / 3);
|
||||
string newPath = isTooWide
|
||||
? path .. "/" .. "\n" .. label
|
||||
: path .. "/" .. label;
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
private static void addPathItem(OptionMenuDescriptor desc, string path)
|
||||
{
|
||||
Array<String> lines;
|
||||
path.split(lines, "\n");
|
||||
|
||||
int nLines = lines.size();
|
||||
|
||||
for (int i = 0; i < nLines; ++i)
|
||||
{
|
||||
OptionMenuItemStaticText text = new("OptionMenuItemStaticText").Init(lines[i], 1);
|
||||
|
||||
desc.mItems.push(text);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEmptyLine(OptionMenuDescriptor desc)
|
||||
{
|
||||
int nItems = desc.mItems.size();
|
||||
|
||||
if (nItems > 0)
|
||||
{
|
||||
let staticText = OptionMenuItemStaticText(desc.mItems[nItems - 1]);
|
||||
|
||||
if (staticText != null && staticText.mLabel == "") { return; }
|
||||
}
|
||||
|
||||
let item = new("OptionMenuItemStaticText").Init("");
|
||||
|
||||
desc.mItems.push(item);
|
||||
}
|
||||
|
||||
private static void addNoResultsItem(OptionMenuDescriptor desc)
|
||||
{
|
||||
string noResults = StringTable.Localize("$OS_NO_RESULTS");
|
||||
let text = new("OptionMenuItemStaticText").Init(noResults, 0);
|
||||
|
||||
addEmptyLine(desc);
|
||||
desc.mItems.push(text);
|
||||
}
|
||||
|
||||
private os_AnyOrAllOption mIsAnyOfItem;
|
||||
private os_SearchField mSearchField;
|
||||
}
|
73
wadsrc/static/zscript/ui/menu/search/query.zs
Normal file
73
wadsrc/static/zscript/ui/menu/search/query.zs
Normal file
|
@ -0,0 +1,73 @@
|
|||
//=============================================================================
|
||||
//
|
||||
// Option Search Query class represents a search query.
|
||||
// A search query consists constists of one or more terms (words).
|
||||
//
|
||||
// Query matching deponds on "os_is_any_of" variable.
|
||||
// If this variable is "true", the text matches the query if any of the terms
|
||||
// matches the query.
|
||||
// If this variable is "false", the text matches the query only if all the
|
||||
// terms match the query.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class os_Query
|
||||
{
|
||||
static os_Query fromString(string str)
|
||||
{
|
||||
let query = new("os_Query");
|
||||
|
||||
str.Split(query.mQueryParts, " ", TOK_SKIPEMPTY);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
bool matches(string text, bool isSearchForAny)
|
||||
{
|
||||
return isSearchForAny
|
||||
? matchesAny(text)
|
||||
: matchesAll(text);
|
||||
}
|
||||
|
||||
// private: //////////////////////////////////////////////////////////////////
|
||||
|
||||
private bool matchesAny(string text)
|
||||
{
|
||||
int nParts = mQueryParts.size();
|
||||
|
||||
for (int i = 0; i < nParts; ++i)
|
||||
{
|
||||
string queryPart = mQueryParts[i];
|
||||
|
||||
if (contains(text, queryPart)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool matchesAll(string text)
|
||||
{
|
||||
int nParts = mQueryParts.size();
|
||||
|
||||
for (int i = 0; i < nParts; ++i)
|
||||
{
|
||||
string queryPart = mQueryParts[i];
|
||||
|
||||
if (!contains(text, queryPart)) { return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool contains(string str, string substr)
|
||||
{
|
||||
let lowerstr = str .MakeLower();
|
||||
let lowersubstr = substr.MakeLower();
|
||||
|
||||
bool contains = (lowerstr.IndexOf(lowersubstr) != -1);
|
||||
|
||||
return contains;
|
||||
}
|
||||
|
||||
private Array<String> mQueryParts;
|
||||
}
|
52
wadsrc/static/zscript/ui/menu/search/searchfield.zs
Normal file
52
wadsrc/static/zscript/ui/menu/search/searchfield.zs
Normal file
|
@ -0,0 +1,52 @@
|
|||
//=============================================================================
|
||||
//
|
||||
// Option Search Field class.
|
||||
//
|
||||
// When the search query is entered, makes Search Menu perform a search.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class os_SearchField : OptionMenuItemTextField
|
||||
{
|
||||
os_SearchField Init(String label, os_Menu menu, string query)
|
||||
{
|
||||
Super.Init(label, "");
|
||||
|
||||
mMenu = menu;
|
||||
|
||||
mText = query;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mkey == Menu.MKEY_Enter)
|
||||
{
|
||||
Menu.MenuSound("menu/choose");
|
||||
mEnter = TextEnterMenu.OpenTextEnter(Menu.GetCurrentMenu(), Menu.OptionFont(), mText, -1, fromcontroller);
|
||||
mEnter.ActivateMenu();
|
||||
return true;
|
||||
}
|
||||
if (mkey == Menu.MKEY_Input)
|
||||
{
|
||||
mtext = mEnter.GetText();
|
||||
|
||||
mMenu.search();
|
||||
}
|
||||
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
override String Represent()
|
||||
{
|
||||
return mEnter
|
||||
? mEnter.GetText() .. NewSmallFont.GetCursor()
|
||||
: mText;
|
||||
}
|
||||
|
||||
String GetText() { return mText; }
|
||||
|
||||
private os_Menu mMenu;
|
||||
private string mText;
|
||||
}
|
379
wadsrc/static/zscript/ui/menu/textentermenu.zs
Normal file
379
wadsrc/static/zscript/ui/menu/textentermenu.zs
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
** menuinput.cpp
|
||||
** The string input code
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2001-2010 Randy Heit
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
class TextEnterMenu : Menu
|
||||
{
|
||||
const INPUTGRID_WIDTH = 13;
|
||||
const INPUTGRID_HEIGHT = 5;
|
||||
|
||||
const Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-=.,!?@'\":;[]()<>^#$%&*/_ \b";
|
||||
|
||||
String mEnterString;
|
||||
int mEnterSize;
|
||||
int mEnterPos;
|
||||
bool mInputGridOkay;
|
||||
int InputGridX;
|
||||
int InputGridY;
|
||||
int CursorSize;
|
||||
bool AllowColors;
|
||||
Font displayFont;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
// [TP] Added allowcolors
|
||||
private void Init(Menu parent, Font dpf, String textbuffer, int maxlen, bool showgrid, bool allowcolors)
|
||||
{
|
||||
Super.init(parent);
|
||||
mEnterString = textbuffer;
|
||||
mEnterSize = maxlen;
|
||||
mInputGridOkay = (showgrid && (m_showinputgrid == 0)) || (m_showinputgrid >= 1);
|
||||
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]
|
||||
displayFont = dpf;
|
||||
CursorSize = displayFont.StringWidth(displayFont.GetCursor());
|
||||
}
|
||||
|
||||
// This had to be deprecated because the unit for maxlen is 8 pixels.
|
||||
deprecated("3.8") static TextEnterMenu Open(Menu parent, String textbuffer, int maxlen, int sizemode, bool showgrid = false, bool allowcolors = false)
|
||||
{
|
||||
let me = new("TextEnterMenu");
|
||||
me.Init(parent, Menu.OptionFont(), textbuffer, maxlen*8, showgrid, allowcolors);
|
||||
return me;
|
||||
}
|
||||
|
||||
static TextEnterMenu OpenTextEnter(Menu parent, Font displayfnt, String textbuffer, int maxlen, bool showgrid = false, bool allowcolors = false)
|
||||
{
|
||||
let me = new("TextEnterMenu");
|
||||
me.Init(parent, displayfnt, textbuffer, maxlen, showgrid, allowcolors);
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
String GetText()
|
||||
{
|
||||
return mEnterString;
|
||||
}
|
||||
|
||||
override bool TranslateKeyboardEvents()
|
||||
{
|
||||
return mInputGridOkay;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
// Save game and player name string input
|
||||
if (ev.Type == UIEvent.Type_Char)
|
||||
{
|
||||
mInputGridOkay = false;
|
||||
AppendChar(ev.KeyChar);
|
||||
return true;
|
||||
}
|
||||
int ch = ev.KeyChar;
|
||||
if ((ev.Type == UIEvent.Type_KeyDown || ev.Type == UIEvent.Type_KeyRepeat) && ch == 8)
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
mEnterString.DeleteLastCharacter();
|
||||
}
|
||||
}
|
||||
else if (ev.Type == UIEvent.Type_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.Type == UIEvent.Type_KeyDown || ev.Type == UIEvent.Type_KeyRepeat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
int cell_width = 18 * CleanXfac_1;
|
||||
int cell_height = 16 * CleanYfac_1;
|
||||
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);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
private void AppendChar(int ch)
|
||||
{
|
||||
String newstring = String.Format("%s%c%s", mEnterString, ch, displayFont.GetCursor());
|
||||
if (mEnterSize < 0 || displayFont.StringWidth(newstring) < mEnterSize)
|
||||
{
|
||||
mEnterString.AppendCharacter(ch);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
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.DeleteLastCharacter();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Enter:
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
int ch = InputGridChars.ByteAt(InputGridX + InputGridY * INPUTGRID_WIDTH);
|
||||
if (ch == 0) // end
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
Menu parent = mParentMenu;
|
||||
parent.MenuEvent(MKEY_Input, false);
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (ch == 8) // bs
|
||||
{
|
||||
if (mEnterString.Length() > 0)
|
||||
{
|
||||
mEnterString.DeleteLastCharacter();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendChar(ch);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
mParentMenu.Drawer();
|
||||
if (mInputGridOkay)
|
||||
{
|
||||
String InputGridChars = Chars;
|
||||
int cell_width = 18 * CleanXfac_1;
|
||||
int cell_height = 16 * CleanYfac_1;
|
||||
int top_padding = cell_height / 2 - displayFont.GetHeight() * CleanYfac_1 / 2;
|
||||
|
||||
// Darken the background behind the character grid.
|
||||
screen.Dim(0, 0.8, 0, screen.GetHeight() - INPUTGRID_HEIGHT * cell_height, screen.GetWidth(), INPUTGRID_HEIGHT * cell_height);
|
||||
|
||||
if (InputGridX >= 0 && InputGridY >= 0)
|
||||
{
|
||||
// Highlight the background behind the selected character.
|
||||
screen.Dim(Color(255,248,220), 0.6,
|
||||
InputGridX * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen.GetWidth() / 2,
|
||||
InputGridY * cell_height - INPUTGRID_HEIGHT * cell_height + screen.GetHeight(),
|
||||
cell_width, cell_height);
|
||||
}
|
||||
|
||||
for (int y = 0; y < INPUTGRID_HEIGHT; ++y)
|
||||
{
|
||||
int yy = y * cell_height - INPUTGRID_HEIGHT * cell_height + screen.GetHeight();
|
||||
for (int x = 0; x < INPUTGRID_WIDTH; ++x)
|
||||
{
|
||||
int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen.GetWidth() / 2;
|
||||
int ch = InputGridChars.ByteAt(y * INPUTGRID_WIDTH + x);
|
||||
int width = displayFont.GetCharWidth(ch);
|
||||
|
||||
// The highlighted character is yellow; the rest are dark gray.
|
||||
int colr = (x == InputGridX && y == InputGridY) ? Font.CR_YELLOW : Font.CR_DARKGRAY;
|
||||
Color palcolor = (x == InputGridX && y == InputGridY) ? Color(160, 120, 0) : Color(120, 120, 120);
|
||||
|
||||
if (ch > 32)
|
||||
{
|
||||
// Draw a normal character.
|
||||
screen.DrawChar(displayFont, colr, xx + cell_width/2 - width*CleanXfac_1/2, yy + top_padding, ch, DTA_CleanNoMove_1, true);
|
||||
}
|
||||
else if (ch == 32)
|
||||
{
|
||||
// Draw the space as a box outline. We also draw it 50% wider than it really is.
|
||||
int x1 = xx + cell_width/2 - width * CleanXfac_1 * 3 / 4;
|
||||
int x2 = x1 + width * 3 * CleanXfac_1 / 2;
|
||||
int y1 = yy + top_padding;
|
||||
int y2 = y1 + displayFont.GetHeight() * CleanYfac_1;
|
||||
screen.Clear(x1, y1, x2, y1+CleanYfac_1, palcolor); // top
|
||||
screen.Clear(x1, y2, x2, y2+CleanYfac_1, palcolor); // bottom
|
||||
screen.Clear(x1, y1+CleanYfac_1, x1+CleanXfac_1, y2, palcolor); // left
|
||||
screen.Clear(x2-CleanXfac_1, y1+CleanYfac_1, x2, y2, palcolor); // right
|
||||
}
|
||||
else if (ch == 8 || ch == 0)
|
||||
{
|
||||
// Draw the backspace and end "characters".
|
||||
String str = ch == 8 ? "BS" : "ED";
|
||||
screen.DrawText(displayFont, colr,
|
||||
xx + cell_width/2 - displayFont.StringWidth(str)*CleanXfac_1/2,
|
||||
yy + top_padding, str, DTA_CleanNoMove_1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Super.Drawer();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue