mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Initial pass to rework and cleanup the main UI interface
Implements interface buttons that react to input type and visually display keybinds Updates the T3D icon and splash screen
This commit is contained in:
parent
157b114ec7
commit
bc27125e90
188 changed files with 2553 additions and 758 deletions
|
|
@ -25,6 +25,9 @@
|
|||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#include "sim\actionMap.h"
|
||||
#include "core\strings\stringUnit.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GuiGameListMenuCtrl
|
||||
|
|
@ -33,7 +36,8 @@
|
|||
GuiGameListMenuCtrl::GuiGameListMenuCtrl()
|
||||
: mSelected(NO_ROW),
|
||||
mDebugRender(false),
|
||||
mHighlighted(NO_ROW)
|
||||
mHighlighted(NO_ROW),
|
||||
mCallbackOnInputs(false)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(mRows);
|
||||
|
||||
|
|
@ -93,7 +97,7 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|||
U32 buttonTextureIndex;
|
||||
S32 iconIndex = (*row)->mIconIndex;
|
||||
bool useHighlightIcon = (*row)->mUseHighlightIcon;
|
||||
if (! (*row)->mEnabled)
|
||||
if (!(*row)->mEnabled)
|
||||
{
|
||||
buttonTextureIndex = Profile::TEX_DISABLED;
|
||||
fontColor = profile->mFontColorNA;
|
||||
|
|
@ -127,7 +131,7 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|||
drawUtil->drawBitmapStretchSR(profile->mTextureObject, RectI(currentOffset, rowExtent), profile->getBitmapArrayRect(buttonTextureIndex));
|
||||
|
||||
// render the row icon if it has one
|
||||
if ((iconIndex != NO_ICON) && profileHasIcons && (! profile->getBitmapArrayRect((U32)iconIndex).extent.isZero()))
|
||||
if ((iconIndex != NO_ICON) && profileHasIcons && (!profile->getBitmapArrayRect((U32)iconIndex).extent.isZero()))
|
||||
{
|
||||
iconIndex += Profile::TEX_FIRST_ICON;
|
||||
drawUtil->clearBitmapModulation();
|
||||
|
|
@ -137,6 +141,11 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|||
// render the row text
|
||||
drawUtil->setBitmapModulation(fontColor);
|
||||
renderJustifiedText(currentOffset + textOffset, textExtent, (*row)->mLabel);
|
||||
|
||||
if ((*row)->mMode == Row::Mode::OptionList)
|
||||
{
|
||||
onRenderOptionList((*row), currentOffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (mDebugRender)
|
||||
|
|
@ -147,6 +156,92 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|||
renderChildControls(offset, updateRect);
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::onRenderOptionList(Row* row, Point2I currentOffset)
|
||||
{
|
||||
GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
|
||||
|
||||
F32 xScale = (float)getWidth() / profile->getRowWidth();
|
||||
|
||||
S32 rowHeight = profile->getRowHeight();
|
||||
|
||||
bool profileHasArrows = profile->hasArrows();
|
||||
Point2I arrowExtent;
|
||||
S32 arrowOffsetY(0);
|
||||
if (profileHasArrows)
|
||||
{
|
||||
arrowExtent = profile->getArrowExtent();
|
||||
|
||||
// icon is centered vertically
|
||||
arrowOffsetY = (rowHeight - arrowExtent.y) >> 1;
|
||||
}
|
||||
|
||||
GFXDrawUtil* drawer = GFX->getDrawUtil();
|
||||
|
||||
Point2I arrowOffset;
|
||||
S32 columnSplit = profile->mColumnSplit * xScale;
|
||||
|
||||
S32 iconIndex;
|
||||
bool hasOptions = (row->mOptions.size() > 0) && row->mSelectedOption > -1;
|
||||
if (hasOptions)
|
||||
{
|
||||
bool isRowSelected = (getSelected() != NO_ROW) && (row == mRows[getSelected()]);
|
||||
bool isRowHighlighted = (getHighlighted() != NO_ROW) ? ((row == mRows[getHighlighted()]) && (row->mEnabled)) : false;
|
||||
if (profileHasArrows)
|
||||
{
|
||||
// render the left arrow
|
||||
bool arrowOnL = (isRowSelected || isRowHighlighted) && (row->mWrapOptions || (row->mSelectedOption > 0));
|
||||
iconIndex = (arrowOnL) ? Profile::TEX_L_ARROW_ON : Profile::TEX_L_ARROW_OFF;
|
||||
arrowOffset.x = currentOffset.x + columnSplit;
|
||||
arrowOffset.y = currentOffset.y + arrowOffsetY;
|
||||
|
||||
drawer->clearBitmapModulation();
|
||||
drawer->drawBitmapStretchSR(profile->mTextureObject, RectI(arrowOffset, arrowExtent), profile->getBitmapArrayRect((U32)iconIndex));
|
||||
|
||||
// render the right arrow
|
||||
bool arrowOnR = (isRowSelected || isRowHighlighted) && (row->mWrapOptions || (row->mSelectedOption < row->mOptions.size() - 1));
|
||||
iconIndex = (arrowOnR) ? Profile::TEX_R_ARROW_ON : Profile::TEX_R_ARROW_OFF;
|
||||
arrowOffset.x = currentOffset.x + (profile->mHitAreaLowerRight.x - profile->mRightPad) * xScale - arrowExtent.x;
|
||||
arrowOffset.y = currentOffset.y + arrowOffsetY;
|
||||
|
||||
drawer->clearBitmapModulation();
|
||||
drawer->drawBitmapStretchSR(profile->mTextureObject, RectI(arrowOffset, arrowExtent), profile->getBitmapArrayRect((U32)iconIndex));
|
||||
}
|
||||
|
||||
// get the appropriate font color
|
||||
ColorI fontColor;
|
||||
if (!row->mEnabled)
|
||||
{
|
||||
fontColor = profile->mFontColorNA;
|
||||
}
|
||||
else if (isRowSelected)
|
||||
{
|
||||
fontColor = profile->mFontColorSEL;
|
||||
}
|
||||
else if (isRowHighlighted)
|
||||
{
|
||||
fontColor = profile->mFontColorHL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fontColor = profile->mFontColor;
|
||||
}
|
||||
|
||||
// calculate text to be at the center between the arrows
|
||||
GFont* font = profile->mFont;
|
||||
StringTableEntry text = row->mOptions[row->mSelectedOption];
|
||||
S32 textWidth = font->getStrWidth(text);
|
||||
S32 columnWidth = profile->mHitAreaLowerRight.x * xScale - profile->mRightPad - columnSplit;
|
||||
S32 columnCenter = columnSplit + (columnWidth >> 1);
|
||||
S32 textStartX = columnCenter - (textWidth >> 1);
|
||||
Point2I textOffset(textStartX, 0);
|
||||
|
||||
// render the option text itself
|
||||
Point2I textExtent(columnWidth, rowHeight);
|
||||
drawer->setBitmapModulation(fontColor);
|
||||
renderJustifiedText(currentOffset + textOffset, textExtent, text);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::onDebugRender(Point2I offset)
|
||||
{
|
||||
GuiGameListMenuProfile * profile = (GuiGameListMenuProfile *) mProfile;
|
||||
|
|
@ -197,13 +292,13 @@ void GuiGameListMenuCtrl::onDebugRender(Point2I offset)
|
|||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::addRow(const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled)
|
||||
void GuiGameListMenuCtrl::addRow(const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode)
|
||||
{
|
||||
Row * row = new Row();
|
||||
addRow(row, label, callback, icon, yPad, useHighlightIcon, enabled);
|
||||
addRow(row, label, callback, icon, yPad, useHighlightIcon, enabled, mode);
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled)
|
||||
void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode)
|
||||
{
|
||||
row->mLabel = StringTable->insert(label, true);
|
||||
row->mScriptCallback = (dStrlen(callback) > 0) ? StringTable->insert(callback, true) : NULL;
|
||||
|
|
@ -211,6 +306,7 @@ void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callb
|
|||
row->mHeightPad = yPad;
|
||||
row->mUseHighlightIcon = useHighlightIcon;
|
||||
row->mEnabled = enabled;
|
||||
row->mMode = (Row::Mode)mode;
|
||||
|
||||
mRows.push_back(row);
|
||||
|
||||
|
|
@ -222,6 +318,24 @@ void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callb
|
|||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::addRow(const char* label, const char* optionsList, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled)
|
||||
{
|
||||
static StringTableEntry DELIM = StringTable->insert("\t", true);
|
||||
Row* row = new Row();
|
||||
Vector<StringTableEntry> options(__FILE__, __LINE__);
|
||||
S32 count = StringUnit::getUnitCount(optionsList, DELIM);
|
||||
for (S32 i = 0; i < count; ++i)
|
||||
{
|
||||
const char* option = StringUnit::getUnit(optionsList, i, DELIM);
|
||||
options.push_back(StringTable->insert(option, true));
|
||||
}
|
||||
row->mOptions = options;
|
||||
bool hasOptions = row->mOptions.size() > 0;
|
||||
row->mSelectedOption = (hasOptions) ? 0 : NO_OPTION;
|
||||
row->mWrapOptions = wrapOptions;
|
||||
addRow(row, label, callback, icon, yPad, true, (hasOptions) ? enabled : false, Row::Mode::OptionList);
|
||||
}
|
||||
|
||||
Point2I GuiGameListMenuCtrl::getMinExtent() const
|
||||
{
|
||||
Point2I parentMin = Parent::getMinExtent();
|
||||
|
|
@ -280,12 +394,12 @@ bool GuiGameListMenuCtrl::onWake()
|
|||
if( !hasValidProfile() )
|
||||
return false;
|
||||
|
||||
if( mRows.empty() )
|
||||
/*if( mRows.empty() )
|
||||
{
|
||||
Con::errorf( "GuiGameListMenuCtrl: %s can't be woken up without any rows. Please use \"addRow\" to add at least one row to the control before pushing it to the canvas.",
|
||||
getName() );
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
enforceConstraints();
|
||||
|
||||
|
|
@ -349,7 +463,15 @@ void GuiGameListMenuCtrl::onMouseUp(const GuiEvent &event)
|
|||
S32 hitRow = getRow(event.mousePoint);
|
||||
if ((hitRow != NO_ROW) && isRowEnabled(hitRow) && (hitRow == getSelected()))
|
||||
{
|
||||
activateRow();
|
||||
if (mRows[hitRow]->mMode == Row::Mode::Default)
|
||||
{
|
||||
activateRow();
|
||||
}
|
||||
else if (mRows[hitRow]->mMode == Row::Mode::OptionList)
|
||||
{
|
||||
S32 xPos = globalToLocalCoord(event.mousePoint).x;
|
||||
clickOption((Row*)mRows[getSelected()], xPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -425,6 +547,13 @@ void GuiGameListMenuCtrl::setSelected(S32 index)
|
|||
}
|
||||
|
||||
mSelected = mClamp(index, 0, mRows.size() - 1);
|
||||
|
||||
//If we're childed to a scroll container, make sure us changing rows has our new position visible
|
||||
GuiScrollCtrl* scroll = dynamic_cast<GuiScrollCtrl*>(getParent());
|
||||
if (scroll)
|
||||
{
|
||||
scroll->scrollRectVisible(getRowBounds(mSelected));
|
||||
}
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::isRowEnabled(S32 index) const
|
||||
|
|
@ -470,6 +599,63 @@ void GuiGameListMenuCtrl::selectFirstEnabledRow()
|
|||
}
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::onInputEvent(const InputEventInfo& event)
|
||||
{
|
||||
if (mCallbackOnInputs)
|
||||
{
|
||||
char deviceString[32];
|
||||
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
|
||||
return false;
|
||||
|
||||
if (event.action == SI_MAKE || event.action == SI_BREAK)
|
||||
{
|
||||
bool isModifier = false;
|
||||
|
||||
switch (event.objInst)
|
||||
{
|
||||
case KEY_LCONTROL:
|
||||
case KEY_RCONTROL:
|
||||
case KEY_LALT:
|
||||
case KEY_RALT:
|
||||
case KEY_LSHIFT:
|
||||
case KEY_RSHIFT:
|
||||
case KEY_MAC_LOPT:
|
||||
case KEY_MAC_ROPT:
|
||||
isModifier = true;
|
||||
}
|
||||
|
||||
if ((event.objType == SI_KEY) && isModifier)
|
||||
{
|
||||
char keyString[32];
|
||||
if (!ActionMap::getKeyString(event.objInst, keyString))
|
||||
return false;
|
||||
|
||||
onInputEvent_callback(deviceString, keyString, event.action);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* actionString = ActionMap::buildActionString(&event);
|
||||
onInputEvent_callback(deviceString, actionString, event.action);
|
||||
}
|
||||
}
|
||||
else if (event.objType == SI_AXIS || event.objType == SI_INT || event.objType == SI_FLOAT)
|
||||
{
|
||||
F32 fValue = event.fValue;
|
||||
if (event.objType == SI_INT)
|
||||
fValue = (F32)event.iValue;
|
||||
|
||||
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
|
||||
return false;
|
||||
|
||||
const char* actionString = ActionMap::buildActionString(&event);
|
||||
|
||||
onAxisEvent_callback(deviceString, actionString, fValue);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::onKeyDown(const GuiEvent &event)
|
||||
{
|
||||
switch (event.keyCode)
|
||||
|
|
@ -528,6 +714,18 @@ bool GuiGameListMenuCtrl::onGamepadAxisDown(const GuiEvent &event)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::onGamepadAxisLeft(const GuiEvent& event)
|
||||
{
|
||||
changeOption(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::onGamepadAxisRight(const GuiEvent& event)
|
||||
{
|
||||
changeOption(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::doScriptCommand(StringTableEntry command)
|
||||
{
|
||||
if (command && command[0])
|
||||
|
|
@ -589,10 +787,179 @@ void GuiGameListMenuCtrl::setRowLabel(S32 rowIndex, const char * label)
|
|||
mRows[rowIndex]->mLabel = StringTable->insert(label, true);
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::clearRows()
|
||||
{
|
||||
mRows.clear();
|
||||
}
|
||||
|
||||
RectI GuiGameListMenuCtrl::getRowBounds(S32 rowIndex)
|
||||
{
|
||||
GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
|
||||
|
||||
F32 xScale = (float)getWidth() / profile->getRowWidth();
|
||||
S32 rowHeight = profile->getRowHeight();
|
||||
|
||||
Point2I currentOffset = Point2I::Zero;
|
||||
Point2I extent = getExtent();
|
||||
Point2I rowExtent(extent.x, rowHeight);
|
||||
|
||||
for (U32 i = 1; i <= rowIndex; i++)
|
||||
{
|
||||
//the top row can't pad, so we'll ignore it
|
||||
GuiGameListMenuCtrl::Row* row = mRows[i];
|
||||
|
||||
// rows other than the first can have padding above them
|
||||
currentOffset.y += row->mHeightPad;
|
||||
currentOffset.y += rowHeight;
|
||||
}
|
||||
|
||||
return RectI(currentOffset, rowExtent);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Console stuff (GuiGameListMenuCtrl)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry GuiGameListMenuCtrl::getCurrentOption(S32 rowIndex) const
|
||||
{
|
||||
if (isValidRowIndex(rowIndex))
|
||||
{
|
||||
Row* row = (Row*)mRows[rowIndex];
|
||||
if (row->mSelectedOption != NO_OPTION)
|
||||
{
|
||||
return row->mOptions[row->mSelectedOption];
|
||||
}
|
||||
}
|
||||
return StringTable->insert("", false);
|
||||
}
|
||||
|
||||
bool GuiGameListMenuCtrl::selectOption(S32 rowIndex, const char* theOption)
|
||||
{
|
||||
if (!isValidRowIndex(rowIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Row* row = (Row*)mRows[rowIndex];
|
||||
|
||||
for (Vector<StringTableEntry>::iterator anOption = row->mOptions.begin(); anOption < row->mOptions.end(); ++anOption)
|
||||
{
|
||||
if (dStrcmp(*anOption, theOption) == 0)
|
||||
{
|
||||
S32 newIndex = anOption - row->mOptions.begin();
|
||||
row->mSelectedOption = newIndex;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::setOptions(S32 rowIndex, const char* optionsList)
|
||||
{
|
||||
static StringTableEntry DELIM = StringTable->insert("\t", true);
|
||||
|
||||
if (!isValidRowIndex(rowIndex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Row* row = (Row*)mRows[rowIndex];
|
||||
|
||||
S32 count = StringUnit::getUnitCount(optionsList, DELIM);
|
||||
row->mOptions.setSize(count);
|
||||
for (S32 i = 0; i < count; ++i)
|
||||
{
|
||||
const char* option = StringUnit::getUnit(optionsList, i, DELIM);
|
||||
row->mOptions[i] = StringTable->insert(option, true);
|
||||
}
|
||||
|
||||
if (row->mSelectedOption >= row->mOptions.size())
|
||||
{
|
||||
row->mSelectedOption = row->mOptions.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::clickOption(Row* row, S32 xPos)
|
||||
{
|
||||
GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
|
||||
if (!profile->hasArrows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
F32 xScale = (float)getWidth() / profile->getRowWidth();
|
||||
|
||||
S32 bitmapArrowWidth = mProfile->getBitmapArrayRect(Profile::TEX_FIRST_ARROW).extent.x;
|
||||
|
||||
S32 leftArrowX1 = profile->mColumnSplit * xScale;
|
||||
S32 leftArrowX2 = leftArrowX1 + bitmapArrowWidth;
|
||||
|
||||
S32 rightArrowX2 = (profile->mHitAreaLowerRight.x - profile->mRightPad) * xScale;
|
||||
S32 rightArrowX1 = rightArrowX2 - bitmapArrowWidth;
|
||||
|
||||
if ((leftArrowX1 <= xPos) && (xPos <= leftArrowX2))
|
||||
{
|
||||
changeOption(row, -1);
|
||||
}
|
||||
else if ((rightArrowX1 <= xPos) && (xPos <= rightArrowX2))
|
||||
{
|
||||
changeOption(row, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::changeOption(S32 delta)
|
||||
{
|
||||
if (getSelected() != NO_ROW)
|
||||
{
|
||||
Row* row = (Row*)mRows[getSelected()];
|
||||
changeOption(row, delta);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameListMenuCtrl::changeOption(Row* row, S32 delta)
|
||||
{
|
||||
S32 optionCount = row->mOptions.size();
|
||||
|
||||
S32 newSelection = row->mSelectedOption + delta;
|
||||
if (optionCount == 0)
|
||||
{
|
||||
newSelection = NO_OPTION;
|
||||
}
|
||||
else if (!row->mWrapOptions)
|
||||
{
|
||||
newSelection = mClamp(newSelection, 0, optionCount - 1);
|
||||
}
|
||||
else if (newSelection < 0)
|
||||
{
|
||||
newSelection = optionCount - 1;
|
||||
}
|
||||
else if (newSelection >= optionCount)
|
||||
{
|
||||
newSelection = 0;
|
||||
}
|
||||
row->mSelectedOption = newSelection;
|
||||
|
||||
static StringTableEntry LEFT = StringTable->insert("LEFT", true);
|
||||
static StringTableEntry RIGHT = StringTable->insert("RIGHT", true);
|
||||
|
||||
if (row->mScriptCallback != NULL)
|
||||
{
|
||||
setThisControl();
|
||||
StringTableEntry direction = NULL;
|
||||
if (delta < 0)
|
||||
{
|
||||
direction = LEFT;
|
||||
}
|
||||
else if (delta > 0)
|
||||
{
|
||||
direction = RIGHT;
|
||||
}
|
||||
if ((direction != NULL) && (Con::isFunction(row->mScriptCallback)))
|
||||
{
|
||||
Con::executef(row->mScriptCallback, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
IMPLEMENT_CONOBJECT(GuiGameListMenuCtrl);
|
||||
|
||||
ConsoleDocClass( GuiGameListMenuCtrl,
|
||||
|
|
@ -622,6 +989,20 @@ ConsoleDocClass( GuiGameListMenuCtrl,
|
|||
IMPLEMENT_CALLBACK( GuiGameListMenuCtrl, onChange, void, (), (),
|
||||
"Called when the selected row changes." );
|
||||
|
||||
IMPLEMENT_CALLBACK(GuiGameListMenuCtrl, onInputEvent, void, (const char* device, const char* action, bool state),
|
||||
(device, action, state),
|
||||
"@brief Callback that occurs when an input is triggered on this control\n\n"
|
||||
"@param device The device type triggering the input, such as keyboard, mouse, etc\n"
|
||||
"@param action The actual event occuring, such as a key or button\n"
|
||||
"@param state True if the action is being pressed, false if it is being release\n\n");
|
||||
|
||||
IMPLEMENT_CALLBACK(GuiGameListMenuCtrl, onAxisEvent, void, (const char* device, const char* action, F32 axisValue),
|
||||
(device, action, axisValue),
|
||||
"@brief Callback that occurs when an axis event is triggered on this control\n\n"
|
||||
"@param device The device type triggering the input, such as mouse, joystick, gamepad, etc\n"
|
||||
"@param action The ActionMap code for the axis\n"
|
||||
"@param axisValue The current value of the axis\n\n");
|
||||
|
||||
void GuiGameListMenuCtrl::initPersistFields()
|
||||
{
|
||||
addField("debugRender", TypeBool, Offset(mDebugRender, GuiGameListMenuCtrl),
|
||||
|
|
@ -639,21 +1020,25 @@ void GuiGameListMenuCtrl::initPersistFields()
|
|||
addField("callbackOnY", TypeString, Offset(mCallbackOnY, GuiGameListMenuCtrl),
|
||||
"Script callback when the 'Y' button is pressed. 'Y' inputs are Keyboard: Y; Gamepad: Y" );
|
||||
|
||||
addField("callbackOnInputs", TypeBool, Offset(mCallbackOnInputs, GuiGameListMenuCtrl),
|
||||
"Script callback when any inputs are detected, even if they aren't the regular 4 face buttons. Useful for secondary/speciality handling of menu navigation.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiGameListMenuCtrl, addRow, void,
|
||||
( const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled ),
|
||||
( -1, 0, true, true ),
|
||||
( const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, int mode ),
|
||||
( -1, 0, true, true, 0 ),
|
||||
"Add a row to the list control.\n\n"
|
||||
"@param label The text to display on the row as a label.\n"
|
||||
"@param callback Name of a script function to use as a callback when this row is activated.\n"
|
||||
"@param icon [optional] Index of the icon to use as a marker.\n"
|
||||
"@param yPad [optional] An extra amount of height padding before the row. Does nothing on the first row.\n"
|
||||
"@param useHighlightIcon [optional] Does this row use the highlight icon?.\n"
|
||||
"@param enabled [optional] If this row is initially enabled." )
|
||||
"@param enabled [optional] If this row is initially enabled.\n"
|
||||
"@param mode [optional] What option mode the row is in. 0 = Default, 1 = OptionList, 2 == Keybind")
|
||||
{
|
||||
object->addRow( label, callback, icon, yPad, useHighlightIcon, enabled );
|
||||
object->addRow( label, callback, icon, yPad, useHighlightIcon, enabled, mode);
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiGameListMenuCtrl, isRowEnabled, bool, ( S32 row ),,
|
||||
|
|
@ -715,16 +1100,65 @@ DefineEngineMethod( GuiGameListMenuCtrl, getSelectedRow, S32, (),,
|
|||
return object->getSelected();
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiGameListMenuCtrl, clearRows, void, (), ,
|
||||
"Gets the index of the currently selected row.\n\n"
|
||||
"@return Index of the selected row.")
|
||||
{
|
||||
return object->clearRows();
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiGameListMenuCtrl, addOptionRow, void,
|
||||
(const char* label, const char* options, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled),
|
||||
(-1, 0, true),
|
||||
"Add a row to the list control.\n\n"
|
||||
"@param label The text to display on the row as a label.\n"
|
||||
"@param options A tab separated list of options.\n"
|
||||
"@param wrapOptions Specify true to allow options to wrap at each end or false to prevent wrapping.\n"
|
||||
"@param callback Name of a script function to use as a callback when this row is activated.\n"
|
||||
"@param icon [optional] Index of the icon to use as a marker.\n"
|
||||
"@param yPad [optional] An extra amount of height padding before the row. Does nothing on the first row.\n"
|
||||
"@param enabled [optional] If this row is initially enabled.")
|
||||
{
|
||||
object->addRow(label, options, wrapOptions, callback, icon, yPad, enabled);
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiGameListMenuCtrl, getCurrentOption, const char*, (S32 row), ,
|
||||
"Gets the text for the currently selected option of the given row.\n\n"
|
||||
"@param row Index of the row to get the option from.\n"
|
||||
"@return A string representing the text currently displayed as the selected option on the given row. If there is no such displayed text then the empty string is returned.")
|
||||
{
|
||||
return object->getCurrentOption(row);
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiGameListMenuCtrl, selectOption, bool, (S32 row, const char* option), ,
|
||||
"Set the row's current option to the one specified\n\n"
|
||||
"@param row Index of the row to set an option on.\n"
|
||||
"@param option The option to be made active.\n"
|
||||
"@return True if the row contained the option and was set, false otherwise.")
|
||||
{
|
||||
return object->selectOption(row, option);
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiGameListMenuCtrl, setOptions, void, (S32 row, const char* optionsList), ,
|
||||
"Sets the list of options on the given row.\n\n"
|
||||
"@param row Index of the row to set options on."
|
||||
"@param optionsList A tab separated list of options for the control.")
|
||||
{
|
||||
object->setOptions(row, optionsList);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GuiGameListMenuProfile
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
GuiGameListMenuProfile::GuiGameListMenuProfile()
|
||||
: mHitAreaUpperLeft(0, 0),
|
||||
mHitAreaLowerRight(0, 0),
|
||||
mIconOffset(0, 0),
|
||||
mRowSize(0, 0),
|
||||
mRowScale(1.0f, 1.0f)
|
||||
: mHitAreaUpperLeft(0, 0),
|
||||
mHitAreaLowerRight(0, 0),
|
||||
mIconOffset(0, 0),
|
||||
mRowSize(0, 0),
|
||||
mRowScale(1.0f, 1.0f),
|
||||
mColumnSplit(0),
|
||||
mRightPad(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -775,6 +1209,12 @@ void GuiGameListMenuProfile::enforceConstraints()
|
|||
Point2I rowTexExtent = getBitmapArrayRect(TEX_NORMAL).extent;
|
||||
mRowScale.x = (float) getRowWidth() / rowTexExtent.x;
|
||||
mRowScale.y = (float) getRowHeight() / rowTexExtent.y;
|
||||
|
||||
if (mHitAreaUpperLeft.x > mColumnSplit || mColumnSplit > mHitAreaLowerRight.x)
|
||||
Con::errorf("GuiGameListOptionsProfile: You can't create %s with a ColumnSplit outside the hit area. You set the split to %d. Please change the ColumnSplit to be in the range [%d, %d].",
|
||||
getName(), mColumnSplit, mHitAreaUpperLeft.x, mHitAreaLowerRight.x);
|
||||
|
||||
mColumnSplit = mClamp(mColumnSplit, mHitAreaUpperLeft.x, mHitAreaLowerRight.x);
|
||||
}
|
||||
|
||||
Point2I GuiGameListMenuProfile::getIconExtent()
|
||||
|
|
@ -827,6 +1267,8 @@ ConsoleDocClass( GuiGameListMenuProfile,
|
|||
" hitAreaLowerRight = \"190 18\";\n"
|
||||
" iconOffset = \"10 2\";\n"
|
||||
" rowSize = \"200 20\";\n"
|
||||
" columnSplit = \"100\";\n"
|
||||
" rightPad = \"4\";\n"
|
||||
" //Properties not specific to this control have been omitted from this example.\n"
|
||||
"};\n"
|
||||
"@endtsexample\n\n"
|
||||
|
|
@ -848,6 +1290,12 @@ void GuiGameListMenuProfile::initPersistFields()
|
|||
addField( "rowSize", TypePoint2I, Offset(mRowSize, GuiGameListMenuProfile),
|
||||
"The base size (\"width height\") of a row" );
|
||||
|
||||
addField("columnSplit", TypeS32, Offset(mColumnSplit, GuiGameListMenuProfile),
|
||||
"Padding between the leftmost edge of the control, and the row's left arrow.");
|
||||
|
||||
addField("rightPad", TypeS32, Offset(mRightPad, GuiGameListMenuProfile),
|
||||
"Padding between the rightmost edge of the control and the row's right arrow.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
removeField("tab");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue