Forráskód Böngészése

Majority of options menu integration completed
Implemented keybind option type
Updated Pause menu to comply with new style

Areloch 5 éve
szülő
commit
3b47d41da2

+ 425 - 11
Engine/source/gui/controls/guiGameListMenuCtrl.cpp

@@ -144,7 +144,15 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
 
       if ((*row)->mMode == Row::Mode::OptionList)
       {
-         onRenderOptionList((*row), currentOffset);
+         onRenderListOption((*row), currentOffset);
+      }
+      else if ((*row)->mMode == Row::Mode::Slider)
+      {
+         onRenderSliderOption((*row), currentOffset);
+      }
+      else if ((*row)->mMode == Row::Mode::Keybind)
+      {
+         onRenderKeybindOption((*row), currentOffset);
       }
    }
 
@@ -156,7 +164,7 @@ void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
    renderChildControls(offset, updateRect);
 }
 
-void GuiGameListMenuCtrl::onRenderOptionList(Row* row, Point2I currentOffset)
+void GuiGameListMenuCtrl::onRenderListOption(Row* row, Point2I currentOffset)
 {
    GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
 
@@ -242,6 +250,165 @@ void GuiGameListMenuCtrl::onRenderOptionList(Row* row, Point2I currentOffset)
    }
 }
 
+void GuiGameListMenuCtrl::onRenderSliderOption(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 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->mValue > row->mRange.x);
+      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->mValue < row->mRange.y);
+      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));
+   }
+
+   //Draw the slider bar
+   if (row->mEnabled)
+   {
+      RectI sliderRect;
+
+      sliderRect.point.x = currentOffset.x + columnSplit + arrowExtent.x;
+      sliderRect.point.y = currentOffset.y + arrowOffsetY;
+
+      sliderRect.extent.x = (currentOffset.x + (profile->mHitAreaLowerRight.x - profile->mRightPad) * xScale - arrowExtent.x) - sliderRect.point.x;
+      sliderRect.extent.y = arrowExtent.y;
+
+      //Now adjust the bar to match-to our value
+
+      S32 barStart = sliderRect.point.x;
+      S32 barEnd = sliderRect.point.x + sliderRect.extent.x;
+
+      S32 xPosFill = (((row->mValue - row->mRange.x) * (barEnd - barStart)) / (row->mRange.y - row->mRange.x)) + barStart;
+
+      RectI fillRect = sliderRect;
+      fillRect.extent.x = xPosFill - sliderRect.point.x;
+
+      ColorI barColor;
+      ColorI barOutlineColor;
+      if (isRowSelected)
+      {
+         barColor = profile->mFillColorHL;
+         barOutlineColor = profile->mFillColor;
+      }
+      else
+      {
+         barColor = profile->mFillColor;
+         barOutlineColor = profile->mFillColorHL;
+      }
+
+      drawer->drawRectFill(fillRect, barColor);
+
+      drawer->drawRect(sliderRect, barOutlineColor);
+   }
+
+   // 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;
+
+   ConsoleValue val;
+   val.setFloatValue(row->mValue);
+
+   const char* stringVal = val.getStringValue();
+
+   S32 textWidth = font->getStrWidth(stringVal);
+   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, stringVal);
+}
+
+void GuiGameListMenuCtrl::onRenderKeybindOption(Row* row, Point2I currentOffset)
+{
+   GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
+   F32 xScale = (float)getWidth() / profile->getRowWidth();
+   S32 columnSplit = profile->mColumnSplit * xScale;
+
+   S32 rowHeight = profile->getRowHeight();
+
+   S32 optionWidth = xScale - columnSplit;
+
+   GFXDrawUtil* drawer = GFX->getDrawUtil();
+   //drawer->drawBitmap(row->mBitmap, )
+
+   Point2I button;
+   button.x = currentOffset.x + columnSplit + (columnSplit / 2)/* + (optionWidth / 2)*/;
+   button.y = currentOffset.y + (rowHeight / 4);
+
+   Point2I buttonSize;
+   buttonSize.x = rowHeight / 2;
+   buttonSize.y = rowHeight / 2;
+
+   if (row->mBitmapTex.isValid())
+   {
+      GFXTextureObject* texture = row->mBitmapTex;
+      RectI rect(button, buttonSize);
+      drawer->clearBitmapModulation();
+      drawer->drawBitmapStretch(texture, rect, GFXBitmapFlip_None, GFXTextureFilterLinear, false);
+   }
+
+   //drawer->drawRectFill(button, ColorI::BLUE);
+}
+
 void GuiGameListMenuCtrl::onDebugRender(Point2I offset)
 {
    GuiGameListMenuProfile * profile = (GuiGameListMenuProfile *) mProfile;
@@ -292,13 +459,13 @@ void GuiGameListMenuCtrl::onDebugRender(Point2I offset)
    }
 }
 
-void GuiGameListMenuCtrl::addRow(const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode)
+void GuiGameListMenuCtrl::addRow(const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode, const char* tooltip)
 {
    Row * row = new Row();
-   addRow(row, label, callback, icon, yPad, useHighlightIcon, enabled, mode);
+   addRow(row, label, callback, icon, yPad, useHighlightIcon, enabled, mode, tooltip);
 }
 
-void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode)
+void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode, const char* tooltip)
 {
    row->mLabel = StringTable->insert(label, true);
    row->mScriptCallback = (dStrlen(callback) > 0) ? StringTable->insert(callback, true) : NULL;
@@ -307,6 +474,7 @@ void GuiGameListMenuCtrl::addRow(Row * row, const char* label, const char* callb
    row->mUseHighlightIcon = useHighlightIcon;
    row->mEnabled = enabled;
    row->mMode = (Row::Mode)mode;
+   row->mTooltip = StringTable->insert(tooltip);
 
    mRows.push_back(row);
 
@@ -318,22 +486,51 @@ 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)
+void GuiGameListMenuCtrl::addRow(const char* label, const char* optionsList, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip, const char* defaultValue)
 {
    static StringTableEntry DELIM = StringTable->insert("\t", true);
    Row* row = new Row();
    Vector<StringTableEntry> options(__FILE__, __LINE__);
+
+   S32 defaultOption = 0;
+
    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));
+
+      if (dStrcmp(option, defaultValue) == 0)
+         defaultOption = options.size() - 1;
    }
    row->mOptions = options;
    bool hasOptions = row->mOptions.size() > 0;
-   row->mSelectedOption = (hasOptions) ? 0 : NO_OPTION;
+   row->mSelectedOption = (hasOptions) ? defaultOption : NO_OPTION;
    row->mWrapOptions = wrapOptions;
-   addRow(row, label, callback, icon, yPad, true, (hasOptions) ? enabled : false, Row::Mode::OptionList);
+   addRow(row, label, callback, icon, yPad, true, (hasOptions) ? enabled : false, Row::Mode::OptionList, tooltip);
+}
+
+void GuiGameListMenuCtrl::addRow(const char* label, F32 defaultValue, F32 increments, Point2F range, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip)
+{
+   static StringTableEntry DELIM = StringTable->insert("\t", true);
+   Row* row = new Row();
+   row->mValue = defaultValue;
+   row->mStepSize = increments;
+   row->mRange = range;
+
+   addRow(row, label, callback, icon, yPad, true, enabled, Row::Mode::Slider, tooltip);
+}
+
+void GuiGameListMenuCtrl::addRow(const char* label, const char* bitmapName, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip)
+{
+   static StringTableEntry DELIM = StringTable->insert("\t", true);
+   Row* row = new Row();
+   row->mBitmap = StringTable->insert(bitmapName);
+
+   if(row->mBitmap != StringTable->EmptyString())
+      row->mBitmapTex.set(row->mBitmap, &GFXDefaultGUIProfile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));
+
+   addRow(row, label, callback, icon, yPad, true, enabled, Row::Mode::Keybind, tooltip);
 }
 
 Point2I  GuiGameListMenuCtrl::getMinExtent() const
@@ -472,6 +669,16 @@ void GuiGameListMenuCtrl::onMouseUp(const GuiEvent &event)
          S32 xPos = globalToLocalCoord(event.mousePoint).x;
          clickOption((Row*)mRows[getSelected()], xPos);
       }
+      else if (mRows[hitRow]->mMode == Row::Mode::Slider)
+      {
+         S32 xPos = globalToLocalCoord(event.mousePoint).x;
+         clickSlider((Row*)mRows[getSelected()], xPos);
+      }
+      else if (mRows[hitRow]->mMode == Row::Mode::Keybind)
+      {
+         S32 xPos = globalToLocalCoord(event.mousePoint).x;
+         clickKeybind((Row*)mRows[getSelected()], xPos);
+      }
    }
 }
 
@@ -789,7 +996,20 @@ void GuiGameListMenuCtrl::setRowLabel(S32 rowIndex, const char * label)
 
 void GuiGameListMenuCtrl::clearRows()
 {
+   for (U32 i = 0; i < mRows.size(); i++)
+   {
+      if (mRows[i]->mBitmap != StringTable->EmptyString())
+         mRows[i]->mBitmapTex = nullptr;
+   }
+
    mRows.clear();
+   setSelected(-1);
+   setHeight(mMinExtent.y);
+}
+
+void GuiGameListMenuCtrl::refresh()
+{
+   enforceConstraints();
 }
 
 RectI GuiGameListMenuCtrl::getRowBounds(S32 rowIndex)
@@ -962,6 +1182,139 @@ void GuiGameListMenuCtrl::changeOption(Row* row, S32 delta)
 }
 IMPLEMENT_CONOBJECT(GuiGameListMenuCtrl);
 
+void GuiGameListMenuCtrl::clickSlider(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))
+   {
+      row->mValue -= row->mStepSize;
+
+      row->mValue = mRound(row->mValue / row->mStepSize) * row->mStepSize;
+
+      if (row->mValue < row->mRange.x)
+         row->mValue = row->mRange.x;
+
+   }
+   else if ((rightArrowX1 <= xPos) && (xPos <= rightArrowX2))
+   {
+      //F32 snap = row->mValue % row->mStepSize;
+      //row->mValue.y -= snap;
+
+      row->mValue += row->mStepSize;
+
+      row->mValue = mRound(row->mValue / row->mStepSize) * row->mStepSize;
+
+      if (row->mValue > row->mRange.y)
+         row->mValue = row->mRange.y;
+   }
+   else
+   {
+      //see if we clicked on the sliderbar itself
+      S32 barStart = leftArrowX2;
+      S32 barEnd = rightArrowX1;
+
+      if (xPos >= barStart && xPos <= barEnd)
+      {
+         //Yep, we clicked in it
+         Con::printf("CLICKED A SLIDERBAR");
+
+         //find the position
+         F32 newValue = (((xPos - barStart) * (row->mRange.y - row->mRange.x)) / (barEnd - barStart)) + row->mRange.x;
+
+         newValue = mRound(newValue / row->mStepSize) * row->mStepSize;
+
+         Con::printf("New value is %f", newValue);
+
+         row->mValue = newValue;
+      }
+   }
+}
+
+void GuiGameListMenuCtrl::clickKeybind(Row* row, S32 xPos)
+{
+   GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
+   F32 xScale = (float)getWidth() / profile->getRowWidth();
+   S32 columnSplit = profile->mColumnSplit * xScale;
+
+   S32 rowHeight = profile->getRowHeight();
+
+   S32 optionWidth = xScale - columnSplit;
+
+   GFXDrawUtil* drawer = GFX->getDrawUtil();
+   //drawer->drawBitmap(row->mBitmap, )
+
+   Point2I button;
+   button.x = columnSplit + (columnSplit / 2)/* + (optionWidth / 2)*/;
+   button.y = rowHeight / 4;
+
+   Point2I buttonSize;
+   buttonSize.x = rowHeight / 2;
+   buttonSize.y = rowHeight / 2;
+
+   GFXTextureObject* texture = row->mBitmapTex;
+   RectI rect(button, buttonSize);
+
+   if (rect.pointInRect(Point2I(xPos, rowHeight / 2)))
+   {
+      if (row->mScriptCallback != StringTable->EmptyString())
+      {
+         S32 rowId = getSelected();
+         Con::executef(row->mScriptCallback, rowId);
+      }
+   }
+}
+
+F32 GuiGameListMenuCtrl::getValue(S32 rowIndex)
+{
+   if (!isValidRowIndex(rowIndex))
+   {
+      return 0;
+   }
+
+   Row* row = (Row*)mRows[rowIndex];
+
+   return row->mValue;
+}
+
+void GuiGameListMenuCtrl::setValue(S32 rowIndex, F32 value)
+{
+   if (!isValidRowIndex(rowIndex))
+   {
+      return;
+   }
+
+   Row* row = (Row*)mRows[rowIndex];
+
+   row->mValue = value;
+}
+
+const char* GuiGameListMenuCtrl::getTooltip(S32 rowIndex)
+{
+   if (!isValidRowIndex(rowIndex))
+   {
+      return "";
+   }
+
+   Row* row = (Row*)mRows[rowIndex];
+
+   return row->mTooltip;
+}
+
 ConsoleDocClass( GuiGameListMenuCtrl,
    "@brief A base class for cross platform menu controls that are gamepad friendly.\n\n"
 
@@ -1107,9 +1460,16 @@ DefineEngineMethod(GuiGameListMenuCtrl, clearRows, void, (), ,
    return object->clearRows();
 }
 
+DefineEngineMethod(GuiGameListMenuCtrl, refresh, void, (), ,
+   "Gets the index of the currently selected row.\n\n"
+   "@return Index of the selected row.")
+{
+   return object->refresh();
+}
+
 DefineEngineMethod(GuiGameListMenuCtrl, addOptionRow, void,
-   (const char* label, const char* options, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled),
-   (-1, 0, true),
+   (const char* label, const char* options, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip, const char* defaultValue),
+   (-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"
@@ -1119,7 +1479,37 @@ DefineEngineMethod(GuiGameListMenuCtrl, addOptionRow, void,
    "@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);
+   object->addRow(label, options, wrapOptions, callback, icon, yPad, enabled, tooltip, defaultValue);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, addSliderRow, void,
+(const char* label, F32 defaultValue, F32 increment, Point2F range, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip),
+(-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, defaultValue, increment, range, callback, icon, yPad, enabled, tooltip);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, addKeybindRow, void,
+(const char* label, const char* bitmapName, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip),
+(-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, bitmapName, callback, icon, yPad, enabled, tooltip);
 }
 
 DefineEngineMethod(GuiGameListMenuCtrl, getCurrentOption, const char*, (S32 row), ,
@@ -1147,6 +1537,30 @@ DefineEngineMethod(GuiGameListMenuCtrl, setOptions, void, (S32 row, const char*
    object->setOptions(row, optionsList);
 }
 
+DefineEngineMethod(GuiGameListMenuCtrl, getValue, void, (S32 row), ,
+   "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->getValue(row);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, setValue, void, (S32 row, F32 value), ,
+   "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->setValue(row, value);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, getTooltip, const char*, (S32 row), ,
+   "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.")
+{
+   return object->getTooltip(row);
+}
+
 //-----------------------------------------------------------------------------
 // GuiGameListMenuProfile
 //-----------------------------------------------------------------------------

+ 66 - 6
Engine/source/gui/controls/guiGameListMenuCtrl.h

@@ -24,6 +24,7 @@
 #define _GuiGameListMenuCtrl_H_
 
 #include "gui/core/guiControl.h"
+#include "gui/controls/guiBitmapCtrl.h"
 
 class GuiGameListMenuProfile;
 
@@ -42,6 +43,7 @@ protected:
    {
       StringTableEntry mLabel;            ///< Text to display in the row as a label
       StringTableEntry mScriptCallback;   ///< Script callback when row is activated
+      StringTableEntry mTooltip;          ///< A descriptive tooltip message for what the row is
       S32 mIconIndex;                     ///< Index of the icon to display on the row (-1 = no icon)
       S32 mHeightPad;                     ///< Extra amount to pad above this row
       bool mUseHighlightIcon;             ///< Toggle the use of the highlight icon
@@ -51,6 +53,7 @@ protected:
       {
          Default = 0,
          OptionList,
+         Slider,
          Keybind
       };
 
@@ -61,8 +64,17 @@ protected:
       S32                        mSelectedOption;  ///< Index into mOptions pointing at the selected option
       bool                       mWrapOptions;     ///< Determines if options should "wrap around" at the ends
 
-      Row() : mLabel(StringTable->EmptyString()), mScriptCallback(StringTable->EmptyString()), mIconIndex(-1), mHeightPad(0), mUseHighlightIcon(false), mEnabled(true),
-         mSelectedOption(0), mWrapOptions(false), mMode(Mode::Default)
+      //Slider option
+      F32                        mValue;           ///< When working as a slider, this contains the value
+      F32                        mStepSize;        ///< When working as a slider, this is the increment levels in the range
+      Point2F                    mRange;           ///< When working as a slider, this sets our min/max range
+
+      //Keybind option
+      StringTableEntry           mBitmap;
+      GFXTexHandle               mBitmapTex;
+
+      Row() : mLabel(StringTable->EmptyString()), mScriptCallback(StringTable->EmptyString()), mTooltip(StringTable->EmptyString()), mIconIndex(-1), mHeightPad(0), mUseHighlightIcon(false), mEnabled(true),
+         mSelectedOption(0), mWrapOptions(false), mMode(Mode::Default), mValue(0), mStepSize(1), mRange(Point2F(0, 1)), mBitmap(StringTable->EmptyString()), mBitmapTex(nullptr)
       {
          VECTOR_SET_ASSOCIATION(mOptions);
       }
@@ -119,7 +131,7 @@ public:
    /// means no icon will be shown on this row.
    /// \param yPad [optional] An extra amount of height padding before the row.
    /// \param enabled [optional] If this row is initially enabled. Default true.
-   virtual void addRow(const char* label, const char* callback, S32 icon = -1, S32 yPad = 0, bool useHighlightIcon = true, bool enabled = true, S32 mode = 0);
+   virtual void addRow(const char* label, const char* callback, S32 icon = -1, S32 yPad = 0, bool useHighlightIcon = true, bool enabled = true, S32 mode = 0, const char* tooltip = "");
 
    /// Adds a row to the control.
    ///
@@ -133,7 +145,23 @@ public:
    /// means no icon will be shown on this row.
    /// \param yPad [optional] An extra amount of height padding before the row.
    /// \param enabled [optional] If this row is initially enabled. Default true.
-   void addRow(const char* label, const char* optionsList, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled);
+   void addRow(const char* label, const char* optionsList, bool wrapOptions, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip = "", const char* defaultValue = "");
+
+   /// Adds a row to the control.
+   ///
+   /// \param label The text to display on the row as a label.
+   /// \param defaultValue A float indicating the slider's default value
+   /// \param increments A float indicating the incremental values the slider snaps along between it's range
+   /// \param range A Point2F that indicates the minimum and maximum value range
+   /// \param callback [optional] Name of a script function to use as a callback
+   /// when this row is activated. Default NULL means no callback.
+   /// \param icon [optional] Index of the icon to use as a marker. Default -1
+   /// means no icon will be shown on this row.
+   /// \param yPad [optional] An extra amount of height padding before the row.
+   /// \param enabled [optional] If this row is initially enabled. Default true.
+   void addRow(const char* label, F32 defaultValue, F32 increments, Point2F range, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip = "");
+
+   void addRow(const char* label, const char* bitmapName, const char* callback, S32 icon, S32 yPad, bool enabled, const char* tooltip);
 
    /// Gets the text for the currently selected option of the given row.
    ///
@@ -166,12 +194,31 @@ public:
    /// \return The number of rows in this control.
    virtual S32 getRowCount() const { return mRows.size(); }
 
+   /// Gets the value of a row
+   ///
+   /// \param rowIndex Index of the row to get the value of.
+   F32 getValue(S32 rowIndex);
+
+   /// Sets the value of a row
+   ///
+   /// \param rowIndex Index of the row to set the value of.
+   /// \param value The new value to be set.
+   void setValue(S32 rowIndex, F32 value);
+
+   /// Gets the tooltip of a row
+   ///
+   /// \param rowIndex Index of the row to get the tooltip of.
+   const char* getTooltip(S32 rowIndex);
+
    GuiGameListMenuCtrl();
    ~GuiGameListMenuCtrl();
 
    void onRender(Point2I offset, const RectI &updateRect);
 
-   void onRenderOptionList(Row* row, Point2I currentOffset);
+   void onRenderListOption(Row* row, Point2I currentOffset);
+   void onRenderSliderOption(Row* row, Point2I currentOffset);
+
+   void onRenderKeybindOption(Row* row, Point2I currentOffset);
 
    /// Callback when the object is registered with the sim.
    ///
@@ -240,6 +287,8 @@ public:
 
    void clearRows();
 
+   void refresh();
+
    RectI getRowBounds(S32 rowIndex);
 
    DECLARE_CONOBJECT(GuiGameListMenuCtrl);
@@ -264,7 +313,7 @@ protected:
    /// means no icon will be shown on this row.
    /// \param yPad [optional] An extra amount of height padding before the row.
    /// \param enabled [optional] If this row is initially enabled. Default true.
-   virtual void addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode = 0);
+   virtual void addRow(Row * row, const char* label, const char* callback, S32 icon, S32 yPad, bool useHighlightIcon, bool enabled, S32 mode = 0, const char* tooltip = "");
 
    /// Determines if the given index is a valid row index. Any index pointing at
    /// an existing row is valid.
@@ -342,6 +391,17 @@ private:
    /// will be 1 or -1.
    void changeOption(Row* row, S32 delta);
 
+   /// Performs a click on the current slider row. The x position is used to
+   /// determine if the left or right arrow were clicked, or if it landed somewhere on the sliderbar.
+   /// If one was clicked, the option will be changed. If neither was clicked, the option is unaffected.
+   /// This method should only be called when there is an actively selected row.
+   ///
+   /// \param row The row to perform the click on.
+   /// \param xPos The x position of the the click, relative to the control.
+   void clickSlider(Row* row, S32 xPos);
+
+   void clickKeybind(Row* row, S32 xPos);
+
 private:
    /// Recalculates the height of this control based on the stored row height and
    /// and padding on the rows.

+ 9 - 17
Templates/BaseGame/game/data/ui/UI.cs

@@ -35,8 +35,6 @@ function UI::initClient(%this)
    //Profiles
    exec("./scripts/profiles.cs");
    
-   exec("./scripts/menu.keybinds.cs");
-   
    //Now gui files
    exec("./guis/guiGamepadButton.cs");
    exec("./guis/guiGamepadButton.gui");
@@ -44,37 +42,34 @@ function UI::initClient(%this)
    exec("./guis/mainMenu.cs");
    exec("./guis/mainMenu.gui");
    
-   exec("./guis/chooseLevelDlg.gui");
    exec("./guis/chooseLevelDlg.cs");
+   exec("./guis/chooseLevelDlg.gui");
    
-   exec("./guis/joinServerMenu.gui");
    exec("./guis/joinServerMenu.cs");
+   exec("./guis/joinServerMenu.gui");
    
    exec("./guis/loadingGui.gui");
    
    exec("./guis/optionsMenu.cs");
    exec("./guis/optionsMenu.gui");
    
-   exec("./guis/pauseMenu.gui");
    exec("./guis/pauseMenu.cs");
+   exec("./guis/pauseMenu.gui");
    
    exec("./guis/remapDlg.gui");
    exec("./guis/remapConfirmDlg.gui");
    
-   exec("./guis/profiler.gui");
    exec("./guis/profiler.cs");
+   exec("./guis/profiler.gui");
    
    exec("./guis/netGraphGui.gui");
    exec("./guis/RecordingsDlg.gui");
    
-   //exec("./guis/FileDialog.gui");
-   //exec("./guis/FileDialog.cs");
-   
-   exec("./guis/guiMusicPlayer.gui");
    exec("./guis/guiMusicPlayer.cs");
+   exec("./guis/guiMusicPlayer.gui");
    
-   exec("./guis/startupGui.gui");
    exec("./guis/startupGui.cs");
+   exec("./guis/startupGui.gui");
    
    // Load Editor Dialogs
    exec("./guis/messageBoxDlg.gui");
@@ -88,17 +83,14 @@ function UI::initClient(%this)
    exec("./scripts/messageBoxes.cs");
    exec("./scripts/help.cs");
    exec("./scripts/cursors.cs");
+   exec("./scripts/utility.cs");
+   
+   exec("./scripts/keybindEdit.cs");
    
    exec("./guis/menuGraphics.gui");
    exec("./guis/menuGraphics.cs");
    
-   //exec("./scripts/menu.keybinds.cs");
-   
-   //exec("./scripts/GuiTreeViewCtrl.cs");
-   
    loadStartup();
-   
-   //menuMoveMap.push();
 }
 
 function UI::onCreateClientConnection(%this){}

+ 0 - 306
Templates/BaseGame/game/data/ui/guis/FileDialog.cs

@@ -1,306 +0,0 @@
-function PlatformFileDialog::buildFilters(%this)
-{
-   %str = strreplace( %this.data.filters, "|", "\t");
-   %this.filterCount = getFieldCount( %str ) / 2;
-   //echo( "Filter count: " @  %str );
-   for( %i = 0; %i < %this.filterCount; %i++ )
-   {
-      %this.filterName[%i] = GetField( %str, (%i*2) + 0 );
-      %this.filter[%i] = strreplace( GetField( %str, (%i*2) + 1 ), ";", "\t");
-      //echo( "Filter: " @  %this.filterName[%i] @ " - " @ %this.filter[%i]);
-   }   
-}
-
-function PlatformFileDialog::handleFlags(%this, %flags)
-{
-   %this.FDS_OPEN = false;
-   %this.FDS_SAVE = false;
-   %this.FDS_OVERWRITEPROMPT = false;
-   %this.FDS_MUSTEXIST = false;
-   %this.FDS_BROWSEFOLDER = false;
-   
-   %flagCount = getFieldCount( %flags );
-   
-   //echo( "flag count: " @ %flagCount );   
-   
-   for( %i = 0; %i < %flagCount; %i++ )
-   {
-      %flag = GetField( %flags, %i );
-      //echo(%flag);
-      if( %flag $= "FDS_OPEN" )
-      {
-         %this.FDS_OPEN = true;
-         %this-->Button.setText( "OPEN" );
-         %this-->Button.command = "PlatformFileDialog.tryFile();";
-         %this-->window.text = "Select file to OPEN";
-      }
-      else if( %flag $= "FDS_SAVE" )
-      {
-         %this.FDS_SAVE = true;
-         %this-->Button.setText( "SAVE" );
-         %this-->Button.command = "PlatformFileDialog.tryFile();";
-         %this-->window.text = "Select file to Save";
-      }
-      else if( %flag $= "FDS_OVERWRITEPROMPT" )
-      {
-         %this.FDS_OVERWRITEPROMPT = true;
-      }
-      else if( %flag $= "FDS_MUSTEXIST" )
-      {
-         %this.FDS_MUSTEXIST = true;
-      }
-      else if( %flag $= "FDS_BROWSEFOLDER" )
-      {
-         %this.FDS_BROWSEFOLDER = true;
-         %this-->window.text = "Select folder to OPEN";
-      }
-   }   
-}
-
-function OpenPlatformFileDialog(%data, %flags)
-{
-   PlatformFileDialog.searchDir = "";
-   PlatformFileDialog-->fileNameEdit.setText( "" );
-   PlatformFileDialog.data = %data;
-   PlatformFileDialog.data.finished = 0;
-   
-   PlatformFileDialog.handleFlags( %flags );
-   
-   if( !isObject(PlatformFileDialog.freeItemSet) )
-   {
-      PlatformFileDialog.freeItemSet = new SimGroup();
-   }
-   
-   PlatformFileDialog.buildFilters();
-   
-   Canvas.pushDialog(PlatformFileDialog);
-}
-
-function PlatformFileDialog::changeDir( %this, %newDir )
-{     
-   %this.searchDir = %newDir;
-   %this.update();
-}
-
-function PlatformFileDialog::navigateUp( %this )
-{
-   //echo( "PlatformFileDialog::navigateUp " @ %this.searchDir );
-   if( %this.searchDir !$= "" )
-   {      
-      %str = strreplace( %this.searchDir, "/", "\t");
-      %count = getFieldCount( %str );
-      
-      if ( %count == 0 )
-         return;
-         
-      if ( %count == 1 )
-         %address = "";
-      else      
-         %address = getFields( %str, 0, %count - 2 );
-         
-      %newDir = strreplace( %address, "\t", "/" );
-      
-      if( %newDir !$= "" )
-         %newDir = %newDir @ "/";
-      
-      %this.changeDir( %newDir );
-      
-   }
-}
-
-function PlatformFileDialog::cancel( %this )
-{
-   %this.data.files[0] = "";
-   %this.data.fileCount = 0;
-   %this.data.finished = 1;
-   
-   Canvas.popDialog(%this);
-}
-
-function FileDialogItem::onClick( %this )
-{
-   PlatformFileDialog-->fileNameEdit.setText( "" );
-   
-   if( %this.isDir && %this.FDS_BROWSEFOLDER)
-   {
-      PlatformFileDialog-->fileNameEdit.setText( %this.text );
-   }
-   else if( !%this.isDir && !%this.FDS_BROWSEFOLDER )
-   {
-      PlatformFileDialog-->fileNameEdit.setText( %this.text );
-   }
-}
-
-function FileDialogItem::onDoubleClick( %this )
-{
-   PlatformFileDialog-->fileNameEdit.setText( "" );
-   
-   if( %this.isDir )
-   {
-      PlatformFileDialog.changeDir( PlatformFileDialog.searchDir @ %this.text @ "/" );
-   }
-}
-
-function PlatformFileDialog::tryFile( %this )
-{
-   %file = %this-->fileNameEdit.getText();
-   if( %file $= "" )
-      return;
-      
-   if( %this.FDS_OVERWRITEPROMPT )
-   {
-      %callback = "PlatformFileDialog.onFile( \"" @ %file @ "\" );";
-      MessageBoxOKCancel("Confirm overwrite", "Confirm overwrite", %callback, "");
-      return;
-   }
-   
-   %this.onFile( %file );
-}
-
-function PlatformFileDialog::onFile( %this, %file )
-{
-   %this.data.files[0] = "";
-   %this.data.fileCount = 0;   
-   
-   if( %file !$= "" )
-   {
-      %file = %this.searchDir @ %file;
-      %this.data.fileCount = 1;
-   }
-   
-   if( %this.FDS_BROWSEFOLDER && !isDirectory( %file ) )
-   {
-      echo("Select a directory");
-      return;
-   }
-   else if( !%this.FDS_BROWSEFOLDER && !isFile( %file ) )
-   {
-      echo("Select a file");
-      return;
-   }
-   
-   if( %this.FDS_MUSTEXIST )
-   {
-      if( !isFile( %file ) && !isDirectory( %file ) )
-      {
-         echo("Target must exist: " @ %file );
-         return;
-      }
-   }  
-   
-   %this.data.finished = 1;
-   %this.data.files[0] = %file;
-   
-   Canvas.popDialog(%this);
-   
-   %this-->fileNameEdit.setText( "" );
-}
-
-function PlatformFileDialog::clear( %this )
-{
-   %itemArray = %this-->itemArray;
-   
-   while( %itemArray.getCount() )
-   {
-      %item = %itemArray.getObject( 0 );
-      %this.freeItem( %item );      
-   }
-}
-
-function PlatformFileDialog::getNewItem( %this )
-{
-   if( %this.freeItemSet.getCount() )
-      %item = %this.freeItemSet.getObject( 0 );
-   
-   if( isObject(%item) )
-   {
-      %this.freeItemSet.remove( %item );
-   }
-   else
-   {
-      //create new
-      %item = new GuiIconButtonCtrl();
-      %item.className = "FileDialogItem";
-      %item.profile = "ToolsGuiIconButtonProfile";
-      %item.textLocation = "left";
-      %item.iconLocation = "left";
-      %item.iconBitmap = "";
-      %item.text = "";
-   }  
-   
-   return %item;
-}
-
-function PlatformFileDialog::freeItem( %this, %item )
-{
-   %this-->itemArray.remove( %item );
-   
-   //clear
-   %item.setText( "" );
-   %item.iconBitmap = "";
-   %item.textMargin = 0;
-   %item.textLocation = "left";
-   %item.iconLocation = "left";
-   %item.resetState();
-   
-   PlatformFileDialog.freeItemSet.add( %item );
-}
-
-function PlatformFileDialog::addDir( %this, %dir )
-{
-   //echo( "Dir: " @ %dir );
-   %item = %this.getNewItem();
-   %item.setText( %dir );
-   %item.isDir = true;
-   %item.iconBitmap = "core/art/gui/images/folder";
-   %item.textLocation = "left";
-   %item.iconLocation = "left";
-   %item.textMargin = 24;
-   %this-->itemArray.add( %item );
-}
-
-function PlatformFileDialog::addFile( %this, %file )
-{
-   //echo( "File: " @ %file );
-   %item = %this.getNewItem();
-   %item.text = strreplace( %file, %this.searchDir, "" );
-   %item.isDir = false;
-   %this-->itemArray.add( %item );
-}
-
-function PlatformFileDialog::onWake( %this )
-{
-   %this.update();
-}
-
-function PlatformFileDialog::onSleep( %this )
-{
-   %this.data.finished = 1;
-}
-
-function PlatformFileDialog::update( %this )
-{
-   %this.clear();
-   
-   %this-->popUpMenu.text = %this.searchDir;
-
-   // dirs
-   %dirList = getDirectoryList( %this.searchDir, 0 );
-   %wordCount = getFieldCount( %dirList );
-   for( %i = 0; %i < %wordCount; %i++ )
-   {
-      %dirItem = GetField( %dirList, %i );
-      %this.addDir( %dirItem );
-   }
-   
-   //files
-   %pattern = %this.filter[0];
-   //echo( %pattern );
-   %file = findFirstFileMultiExpr( %this.searchDir @ %pattern, false);
-   
-   while( %file !$= "" )
-   {      
-      %this.addFile( %file );
-      %file = findNextFileMultiExpr( %pattern );
-   }
-}

+ 0 - 293
Templates/BaseGame/game/data/ui/guis/FileDialog.gui

@@ -1,293 +0,0 @@
-//--- OBJECT WRITE BEGIN ---
-%guiContent = new GuiControl(PlatformFileDialog) {
-   position = "0 0";
-   extent = "1024 768";
-   minExtent = "8 2";
-   horizSizing = "right";
-   vertSizing = "bottom";
-   profile = "GuiDefaultProfile";
-   visible = "1";
-   active = "1";
-   tooltipProfile = "GuiToolTipProfile";
-   hovertime = "1000";
-   isContainer = "1";
-   canSave = "1";
-   canSaveDynamicFields = "1";
-
-   new GuiWindowCtrl() {
-      text = "";
-      resizeWidth = "1";
-      resizeHeight = "1";
-      canMove = "1";
-      canClose = "1";
-      canMinimize = "1";
-      canMaximize = "1";
-      canCollapse = "0";
-      closeCommand = "PlatformFileDialog.cancel();";
-      edgeSnap = "1";
-      margin = "0 0 0 0";
-      padding = "0 0 0 0";
-      anchorTop = "1";
-      anchorBottom = "0";
-      anchorLeft = "1";
-      anchorRight = "0";
-      position = "135 113";
-      extent = "727 623";
-      minExtent = "8 2";
-      horizSizing = "right";
-      vertSizing = "bottom";
-      profile = "GuiWindowProfile";
-      visible = "1";
-      active = "1";
-      tooltipProfile = "GuiToolTipProfile";
-      hovertime = "1000";
-      isContainer = "1";
-      internalName = "window";
-      canSave = "1";
-      canSaveDynamicFields = "0";
-
-      new GuiControl() {
-         position = "2 16";
-         extent = "717 37";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "bottom";
-         profile = "ToolsGuiDefaultProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "ToolsGuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "1";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-
-         new GuiBitmapButtonCtrl() {
-            bitmap = "tools/gui/images/folderUp";
-            bitmapMode = "Stretched";
-            autoFitExtents = "0";
-            useModifiers = "0";
-            useStates = "1";
-            groupNum = "0";
-            buttonType = "PushButton";
-            useMouseEvents = "0";
-            position = "9 9";
-            extent = "20 19";
-            minExtent = "8 2";
-            horizSizing = "right";
-            vertSizing = "bottom";
-            profile = "ToolsGuiButtonProfile";
-            visible = "1";
-            active = "1";
-            command = "PlatformFileDialog.navigateUp();";
-            tooltipProfile = "ToolsGuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            internalName = "folderUpButton";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiPopUpMenuCtrl() {
-            maxPopupHeight = "200";
-            sbUsesNAColor = "0";
-            reverseTextList = "0";
-            bitmapBounds = "16 16";
-            maxLength = "1024";
-            margin = "0 0 0 0";
-            padding = "0 0 0 0";
-            anchorTop = "1";
-            anchorBottom = "0";
-            anchorLeft = "1";
-            anchorRight = "0";
-            position = "36 9";
-            extent = "666 18";
-            minExtent = "8 2";
-            horizSizing = "width";
-            vertSizing = "bottom";
-            profile = "ToolsGuiPopUpMenuProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "ToolsGuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            internalName = "PopupMenu";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-      };
-      new GuiScrollCtrl() {
-         willFirstRespond = "1";
-         hScrollBar = "dynamic";
-         vScrollBar = "alwaysOff";
-         lockHorizScroll = "0";
-         lockVertScroll = "1";
-         constantThumbHeight = "0";
-         childMargin = "0 0";
-         mouseWheelScrollSpeed = "-1";
-         docking = "None";
-         margin = "0 0 0 0";
-         padding = "0 0 0 0";
-         anchorTop = "0";
-         anchorBottom = "1";
-         anchorLeft = "1";
-         anchorRight = "0";
-         position = "7 64";
-         extent = "712 509";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "height";
-         profile = "GuiScrollProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "ToolsGuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "1";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-
-         new GuiDynamicCtrlArrayControl() {
-            colCount = "1";
-            colSize = "64";
-            rowCount = "1";
-            rowSize = "258";
-            rowSpacing = "4";
-            colSpacing = "4";
-            frozen = "0";
-            autoCellSize = "1";
-            fillRowFirst = "0";
-            dynamicSize = "1";
-            padding = "0 0 0 0";
-            position = "1 1";
-            extent = "666 507";
-            minExtent = "8 2";
-            horizSizing = "width";
-            vertSizing = "height";
-            profile = "ToolsGuiTransparentProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "ToolsGuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            internalName = "itemArray";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-      };
-      new GuiContainer() {
-         docking = "Bottom";
-         margin = "0 0 0 0";
-         padding = "0 0 0 0";
-         anchorTop = "0";
-         anchorBottom = "1";
-         anchorLeft = "1";
-         anchorRight = "1";
-         position = "1 583";
-         extent = "725 37";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "bottom";
-         profile = "GuiDefaultProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "1";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-
-         new GuiTextCtrl() {
-            text = "File Name";
-            maxLength = "1024";
-            margin = "0 0 0 0";
-            padding = "0 0 0 0";
-            anchorTop = "1";
-            anchorBottom = "0";
-            anchorLeft = "1";
-            anchorRight = "0";
-            position = "10 -1";
-            extent = "51 30";
-            minExtent = "8 2";
-            horizSizing = "right";
-            vertSizing = "bottom";
-            profile = "GuiTextProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiTextEditCtrl() {
-            historySize = "0";
-            tabComplete = "0";
-            sinkAllKeyEvents = "0";
-            password = "0";
-            passwordMask = "*";
-            maxLength = "1024";
-            margin = "0 0 0 0";
-            padding = "0 0 0 0";
-            anchorTop = "1";
-            anchorBottom = "0";
-            anchorLeft = "1";
-            anchorRight = "0";
-            position = "58 5";
-            extent = "561 18";
-            minExtent = "8 2";
-            horizSizing = "width";
-            vertSizing = "bottom";
-            profile = "GuiTextEditProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            internalName = "fileNameEdit";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiContainer() {
-            docking = "Right";
-            margin = "0 0 0 0";
-            padding = "0 0 0 0";
-            anchorTop = "0";
-            anchorBottom = "0";
-            anchorLeft = "0";
-            anchorRight = "0";
-            position = "630 0";
-            extent = "95 37";
-            minExtent = "8 2";
-            horizSizing = "right";
-            vertSizing = "bottom";
-            profile = "GuiDefaultProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-
-            new GuiButtonCtrl() {
-               groupNum = "-1";
-               buttonType = "PushButton";
-               useMouseEvents = "1";
-               position = "6 1";
-               extent = "81 24";
-               minExtent = "8 2";
-               horizSizing = "right";
-               vertSizing = "bottom";
-               profile = "GuiButtonProfile";
-               visible = "1";
-               active = "1";
-               tooltipProfile = "GuiToolTipProfile";
-               hovertime = "1000";
-               isContainer = "0";
-               internalName = "Button";
-               canSave = "1";
-               canSaveDynamicFields = "0";
-            };
-         };
-      };
-   };
-};
-//--- OBJECT WRITE END ---

+ 0 - 123
Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsCtrl.taml

@@ -1,123 +0,0 @@
-<GuiContainer
-    margin="0 0 0 0"
-    padding="0 0 0 0"
-    anchorTop="true"
-    anchorBottom="false"
-    anchorLeft="true"
-    anchorRight="false"
-    position="0 105"
-    extent="739 35"
-    minExtent="8 2"
-    horizSizing="width"
-    vertSizing="bottom"
-    profile="GuiDefaultProfile"
-    visible="true"
-    active="true"
-    tooltipProfile="GuiToolTipProfile"
-    hovertime="1000"
-    isContainer="true"
-    class="GraphicsMenuSetting"
-    canSave="true"
-    canSaveDynamicFields="false">
-    <GuiBitmapCtrl
-        bitmap="data/ui/images/hudfill.png"
-        color="255 255 255 255"
-        wrap="false"
-        position="0 0"
-        extent="739 35"
-        minExtent="8 2"
-        horizSizing="relative"
-        vertSizing="bottom"
-        profile="GuiDefaultProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="false"
-        canSave="true"
-        canSaveDynamicFields="false" />
-    <GuiTextCtrl
-        text="Shadow Quality"
-        maxLength="1024"
-        margin="0 0 0 0"
-        padding="0 0 0 0"
-        anchorTop="true"
-        anchorBottom="false"
-        anchorLeft="true"
-        anchorRight="false"
-        position="0 0"
-        extent="350 35"
-        minExtent="8 2"
-        horizSizing="relative"
-        vertSizing="bottom"
-        profile="GuiMenuButtonProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="true"
-        internalName="nameText"
-        canSave="true"
-        canSaveDynamicFields="false" />
-    <GuiTextCtrl
-        text="High"
-        maxLength="1024"
-        margin="0 0 0 0"
-        padding="0 0 0 0"
-        anchorTop="true"
-        anchorBottom="false"
-        anchorLeft="true"
-        anchorRight="false"
-        position="350 0"
-        extent="350 35"
-        minExtent="8 2"
-        horizSizing="relative"
-        vertSizing="bottom"
-        profile="GuiMenuButtonProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="true"
-        internalName="SettingText"
-        canSave="true"
-        canSaveDynamicFields="false" />
-    <GuiButtonCtrl
-        text=">"
-        groupNum="-1"
-        buttonType="PushButton"
-        useMouseEvents="true"
-        position="682 0"
-        extent="36 35"
-        minExtent="8 8"
-        horizSizing="relative"
-        vertSizing="bottom"
-        profile="GuiMenuButtonProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="false"
-        class="OptionsMenuForwardSetting"
-        canSave="true"
-        canSaveDynamicFields="false" />
-    <GuiButtonCtrl
-        text="<"
-        groupNum="-1"
-        buttonType="PushButton"
-        useMouseEvents="true"
-        position="348 0"
-        extent="36 35"
-        minExtent="8 8"
-        horizSizing="relative"
-        vertSizing="bottom"
-        profile="GuiMenuButtonProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="false"
-        class="OptionsMenuBackSetting"
-        canSave="true"
-        canSaveDynamicFields="false" />
-</GuiContainer>

+ 0 - 142
Templates/BaseGame/game/data/ui/guis/graphicsMenuSettingsSlider.taml

@@ -1,142 +0,0 @@
-<GuiContainer
-    margin="0 0 0 0"
-    padding="0 0 0 0"
-    anchorTop="true"
-    anchorBottom="false"
-    anchorLeft="true"
-    anchorRight="false"
-    position="0 35"
-    extent="700 35"
-    minExtent="8 2"
-    horizSizing="right"
-    vertSizing="bottom"
-    profile="GuiDefaultProfile"
-    visible="true"
-    active="true"
-    tooltipProfile="GuiToolTipProfile"
-    hovertime="1000"
-    isContainer="true"
-    canSave="true"
-    canSaveDynamicFields="false">
-    <GuiBitmapCtrl
-        bitmap="data/ui/images/hudfill.png"
-        wrap="false"
-        position="0 0"
-        extent="450 35"
-        minExtent="8 2"
-        horizSizing="right"
-        vertSizing="bottom"
-        profile="GuiDefaultProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="false"
-        canSave="true"
-        canSaveDynamicFields="false" />
-    <GuiContainer
-        margin="0 0 0 0"
-        padding="0 0 0 0"
-        anchorTop="true"
-        anchorBottom="false"
-        anchorLeft="true"
-        anchorRight="false"
-        position="450 0"
-        extent="250 35"
-        minExtent="8 2"
-        horizSizing="right"
-        vertSizing="bottom"
-        profile="GuiDefaultProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="true"
-        canSave="true"
-        canSaveDynamicFields="false">
-        <GuiBitmapCtrl
-            bitmap="data/ui/images/hudfill.png"
-            wrap="false"
-            position="0 0"
-            extent="250 35"
-            minExtent="8 2"
-            horizSizing="right"
-            vertSizing="bottom"
-            profile="GuiDefaultProfile"
-            visible="true"
-            active="true"
-            tooltipProfile="GuiToolTipProfile"
-            hovertime="1000"
-            isContainer="false"
-            canSave="true"
-            canSaveDynamicFields="false" />
-        <GuiSliderCtrl
-            range="0.1 1"
-            ticks="9"
-            snap="false"
-            value="0.453571"
-            position="0 0"
-            extent="200 35"
-            minExtent="8 2"
-            horizSizing="right"
-            vertSizing="bottom"
-            profile="GuiSliderProfile"
-            visible="true"
-            active="true"
-            variable="$pref::Input::VertMouseSensitivity"
-            tooltipProfile="GuiToolTipProfile"
-            hovertime="1000"
-            isContainer="false"
-            internalName="slider"
-            canSave="true"
-            canSaveDynamicFields="false" 
-            renderTicks="false"
-            useFillBar="true" />
-        <GuiTextCtrl
-            text="5"
-            maxLength="1024"
-            margin="0 0 0 0"
-            padding="0 0 0 0"
-            anchorTop="true"
-            anchorBottom="false"
-            anchorLeft="true"
-            anchorRight="false"
-            position="200 0"
-            extent="50 35"
-            minExtent="8 2"
-            horizSizing="right"
-            vertSizing="bottom"
-            profile="GuiMenuButtonProfile"
-            visible="true"
-            active="true"
-            tooltipProfile="GuiToolTipProfile"
-            hovertime="1000"
-            isContainer="true"
-            internalName="valueText"
-            canSave="true"
-            canSaveDynamicFields="false" />
-    </GuiContainer>
-    <GuiTextCtrl
-        text="Vertical Sensitivity"
-        maxLength="1024"
-        margin="0 0 0 0"
-        padding="0 0 0 0"
-        anchorTop="true"
-        anchorBottom="false"
-        anchorLeft="true"
-        anchorRight="false"
-        position="0 0"
-        extent="450 35"
-        minExtent="8 2"
-        horizSizing="right"
-        vertSizing="bottom"
-        profile="GuiMenuButtonProfile"
-        visible="true"
-        active="true"
-        tooltipProfile="GuiToolTipProfile"
-        hovertime="1000"
-        isContainer="true"
-        internalName="nameText"
-        canSave="true"
-        canSaveDynamicFields="false" />
-</GuiContainer>

+ 0 - 1
Templates/BaseGame/game/data/ui/guis/mainMenu.cs

@@ -10,7 +10,6 @@ function MainMenuGui::onWake(%this)
 
 function MainMenuGui::onSleep(%this)
 {
-   menuMoveMap.pop();
 }
 
 function MainMenuButtonHolder::onWake(%this)

+ 0 - 60
Templates/BaseGame/game/data/ui/guis/messageBoxOK.gui

@@ -1,60 +0,0 @@
-//--- OBJECT WRITE BEGIN ---
-%guiContent = new GuiControl(MessageBoxOKDlg) {
-   profile = "GuiOverlayProfile";
-   horizSizing = "width";
-   vertSizing = "height";
-   position = "0 0";
-   extent = "640 480";
-   minExtent = "8 8";
-   visible = "1";
-   helpTag = "0";
-
-   new GuiWindowCtrl(MBOKFrame) {
-      profile = "GuiWindowProfile";
-      horizSizing = "center";
-      vertSizing = "center";
-      position = "170 175";
-      extent = "300 107";
-      minExtent = "48 95";
-      visible = "1";
-      helpTag = "0";
-      maxLength = "255";
-      resizeWidth = "1";
-      resizeHeight = "1";
-      canMove = "1";
-      canClose = "0";
-      canMinimize = "0";
-      canMaximize = "0";
-      minSize = "50 50";
-      text = "";
-
-      new GuiMLTextCtrl(MBOKText) {
-         profile = "GuiMLTextProfile";
-         horizSizing = "center";
-         vertSizing = "bottom";
-         position = "9 35";
-         extent = "281 24";
-         minExtent = "8 8";
-         visible = "1";
-         helpTag = "0";
-         lineSpacing = "2";
-         allowColorChars = "0";
-         maxChars = "-1";
-      };
-      new GuiButtonCtrl() {
-         profile = "GuiButtonProfile";
-         horizSizing = "right";
-         vertSizing = "top";
-         position = "111 75";
-         extent = "80 24";
-         minExtent = "8 8";
-         visible = "1";
-         command = "MessageCallback(MessageBoxOKDlg,MessageBoxOKDlg.callback);";
-         accelerator = "return";
-         helpTag = "0";
-         text = "Ok";
-            simpleStyle = "0";
-      };
-   };
-};
-//--- OBJECT WRITE END ---

+ 0 - 75
Templates/BaseGame/game/data/ui/guis/messageBoxYesNo.gui

@@ -1,75 +0,0 @@
-//--- OBJECT WRITE BEGIN ---
-%guiContent = new GuiControl(MessageBoxYesNoDlg) {
-	profile = "GuiOverlayProfile";
-	horizSizing = "width";
-	vertSizing = "height";
-	position = "0 0";
-	extent = "640 480";
-	minExtent = "8 8";
-	visible = "1";
-	helpTag = "0";
-
-	new GuiWindowCtrl(MBYesNoFrame) {
-      profile = "GuiWindowProfile";
-      horizSizing = "center";
-      vertSizing = "center";
-      position = "170 175";
-      extent = "300 100";
-      minExtent = "48 92";
-      visible = "1";
-      helpTag = "0";
-      maxLength = "255";
-      resizeWidth = "1";
-      resizeHeight = "1";
-      canMove = "1";
-      canClose = "1";
-      canMinimize = "0";
-      canMaximize = "0";
-      minSize = "50 50";
-      text = "";
-      closeCommand = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);";
-
-		new GuiMLTextCtrl(MBYesNoText) {
-         profile = "GuiMLTextProfile";
-         horizSizing = "center";
-         vertSizing = "bottom";
-         position = "11 38";
-         extent = "280 14";
-         minExtent = "8 8";
-         visible = "1";
-         helpTag = "0";
-         lineSpacing = "2";
-         allowColorChars = "0";
-         maxChars = "-1";
-		};
-		new GuiButtonCtrl() {
-         profile = "GuiButtonProfile";
-         horizSizing = "right";
-         vertSizing = "top";
-         position = "70 68";
-         extent = "80 22";
-         minExtent = "8 8";
-         visible = "1";
-			command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.yesCallback);";
-         accelerator = "return";
-         helpTag = "0";
-         text = "Yes";
-         simpleStyle = "0";
-		};
-		new GuiButtonCtrl() {
-         profile = "GuiButtonProfile";
-         horizSizing = "right";
-         vertSizing = "top";
-         position = "167 68";
-         extent = "80 22";
-         minExtent = "8 8";
-         visible = "1";
-			command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);";
-         accelerator = "escape";
-         helpTag = "0";
-         text = "No";
-         simpleStyle = "0";
-		};
-	};
-};
-//--- OBJECT WRITE END ---

+ 252 - 374
Templates/BaseGame/game/data/ui/guis/optionsMenu.cs

@@ -48,27 +48,6 @@
 
 function OptionsMenuSettingsList::onAdd(%this)
 {
-   %yesNoList = "No\tYes";
-   %onOffList = "Off\tOn";
-   %highMedLow = "Low\tMedium\tHigh";
-   %anisoFilter = "Off\t4\t8\t16";
-   OptionsMenuSettingsList.addOptionRow("Shadow Quality", "High\tMedium\tLow\tNone", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Mesh Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Texture Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Terrain Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Decal Lifetime", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Ground Cover Density", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Shader Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "4\t2\t1\tOff", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Refresh Rate", "75\t60\t30", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", -1, -30);
 }
 
 function OptionsMenu::onWake(%this)
@@ -95,13 +74,30 @@ function OptionsButtonHolder::refresh(%this)
    GamepadButtonsGui.setButton(1, "RB", "", "Next Tab", "OptionsMenu.nextTab();", true);
    GamepadButtonsGui.setButton(2, "Start", "Enter", "Apply", "OptionsMenu.apply();");
    GamepadButtonsGui.setButton(3, "B", "Esc", "Back", "OptionsMenu.backOut();");
-   GamepadButtonsGui.setButton(7, "Back", "R", "Reset", "OptionsMenu.backOut();");
+   GamepadButtonsGui.setButton(7, "Back", "R", "Reset", "OptionsMenu.resetToDefaults();");
    
    GamepadButtonsGui.refreshButtons();
 }
 
+function OptionsMenu::apply(%this)
+{
+   if(%this.pageTabIndex == 0)
+   {
+      %this.applyDisplaySettings();
+   }
+   else if(%this.pageTabIndex == 1)
+   {
+      %this.applyGraphicsSettings();
+   }
+}
+
 function OptionsMenuSettingsList::onChange(%this)
 {
+   %optionName = %this.getRowLabel(%this.getSelectedRow());
+   %tooltipText = %this.getTooltip(%this.getSelectedRow());
+   
+   OptionName.setText(%optionName);
+   OptionDescription.setText(%tooltipText);
    return;
    
    OptionsMenuSettingsList.clearOptions();
@@ -128,6 +124,8 @@ function OptionsMenuSettingsList::onChange(%this)
    {
       OptionsMenuList.populateGamepadSettingsList();
    }
+   
+   
 }
 
 function OptionsMenu::prevTab(%this)
@@ -171,69 +169,57 @@ function OptionsMenu::populateDisplaySettingsList(%this)
    %this.pageTabIndex = 0;
    OptionsMenuSettingsList.clearRows();
    
+   OptionName.setText("");
+   OptionDescription.setText("");
+   
    %resolutionList = getScreenResolutionList();
-   //OptionsMenuSettingsList.addOptionsRow("Resolution", %yesNoList, false, "", 0, -15);
-   OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "screenResolutionOptionChanged", -1, -30);
-}
-
-function _makePrettyResString( %resString, %giveAspectRation )
-{
-   %width = getWord( %resString, $WORD::RES_X );
-   %height = getWord( %resString, $WORD::RES_Y );
+   OptionsMenuSettingsList.addOptionRow("Display API", "D3D11\tOpenGL", false, "", -1, -30, true, "The display API used for rendering.", getDisplayDeviceInformation());
+   OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "screenResolutionOptionChanged", -1, -30, true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode ));
+   OptionsMenuSettingsList.addOptionRow("Fullscreen", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo($pref::Video::FullScreen));
+   OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync));
    
-   %aspect = %width / %height;
-   %aspect = mRound( %aspect * 100 ) * 0.01;            
+   OptionsMenuSettingsList.addOptionRow("Refresh Rate", "30\t60\t75", false, "", -1, -30, true, "", $pref::Video::RefreshRate);
    
-   switch$( %aspect )
-   {
-      case "1.33":
-         %aspect = "4:3";
-      case "1.78":
-         %aspect = "16:9";
-      default:
-         %aspect = "";
-   }
+   //move to gameplay tab
+   OptionsMenuSettingsList.addSliderRow("Field of View", 75, 5, "65 100", "", -1, -30);
    
-   %outRes = %width @ " x " @ %height;
-   if ( %giveAspectRation && %aspect !$= "" )
-      %outRes = %outRes @ "  (" @ %aspect @ ")";
-      
-   return %outRes;   
-}
-
-function getScreenResolutionList()
-{
-   %returnsList = "";
+   OptionsMenuSettingsList.addSliderRow("Brightness", 0.5, 0.1, "0 1", "", -1, -30);
+   OptionsMenuSettingsList.addSliderRow("Contrast", 0.5, 0.1, "0 1", "", -1, -30);
    
-   %resCount = Canvas.getModeCount();
-   for (%i = 0; %i < %resCount; %i++)
+   OptionsMenuSettingsList.refresh();
+}
+
+function OptionsMenu::applyDisplaySettings(%this)
+{
+   %newAdapter    = GraphicsMenuDriver.getText();
+	%numAdapters   = GFXInit::getAdapterCount();
+	%newDevice     = $pref::Video::displayDevice;
+							
+	for( %i = 0; %i < %numAdapters; %i ++ )
+	{
+	   if( GFXInit::getAdapterName( %i ) $= %newAdapter )
+	   {
+	      %newDevice = GFXInit::getAdapterType( %i );
+	      break;
+	   }
+	}
+	   
+   // Change the device.
+   if ( %newDevice !$= $pref::Video::displayDevice )
    {
-      %testResString = Canvas.getMode( %i );
-      %testRes = _makePrettyResString( %testResString );
-      
-      //sanitize
-      %found = false;
-      %retCount = getTokenCount(%returnsList, "\t");
-      for (%x = 0; %x < %retCount; %x++)
-      {
-         %existingEntry = getToken(%returnsList, "\t", %x);
-         if(%existingEntry $= %testRes)
-         {
-            %found = true;
-            break;  
-         }
-      }
-      
-      if(%found)
-         continue;
-                     
-      if(%i != 0)
-         %returnsList = %returnsList @ "\t" @ %testRes;
-      else
-         %returnsList = %testRes;
+      if ( %testNeedApply )
+         return true;
+         
+      $pref::Video::displayDevice = %newDevice;
+      if( %newAdapter !$= getDisplayDeviceInformation() )
+         MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." );
    }
    
-   return %returnsList;
+   updateDisplaySettings();
+   
+   echo("Exporting client prefs");
+   %prefPath = getPrefpath();
+   export("$pref::*", %prefPath @ "/clientPrefs.cs", false);
 }
 
 function screenResolutionOptionChanged()
@@ -246,27 +232,124 @@ function OptionsMenu::populateGraphicsSettingsList(%this)
    %this.pageTabIndex = 1;
    OptionsMenuSettingsList.clearRows();
    
+   OptionName.setText("");
+   OptionDescription.setText("");
+   
    %yesNoList = "No\tYes";
    %onOffList = "Off\tOn";
    %highMedLow = "Low\tMedium\tHigh";
    %anisoFilter = "Off\t4\t8\t16";
-   OptionsMenuSettingsList.addOptionRow("Shadow Quality", "High\tMedium\tLow\tNone", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Mesh Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Texture Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Terrain Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Decal Lifetime", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Ground Cover Density", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Shader Quality", %highMedLow, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "4\t2\t1\tOff", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Refresh Rate", "75\t60\t30", false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", -1, -30);
-   OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", -1, -30);
+   OptionsMenuSettingsList.addOptionRow("Shadow Quality", getQualityLevels(ShadowQualityList), false, "", -1, -30, true, "Shadow revolution quality", getCurrentQualityLevel(ShadowQualityList));
+   OptionsMenuSettingsList.addOptionRow("Soft Shadow Quality", getQualityLevels(SoftShadowList), false, "", -1, -30, true, "Amount of softening applied to shadowmaps", getCurrentQualityLevel(SoftShadowList));
+   OptionsMenuSettingsList.addOptionRow("Mesh Quality", getQualityLevels(MeshQualityGroup), false, "", -1, -30, true, "Fidelity of rendering of mesh objects", getCurrentQualityLevel(MeshQualityGroup));
+   OptionsMenuSettingsList.addOptionRow("Texture Quality", getQualityLevels(TextureQualityGroup), false, "", -1, -30, true, "Fidelity of textures", getCurrentQualityLevel(TextureQualityGroup));
+   OptionsMenuSettingsList.addOptionRow("Terrain Quality", getQualityLevels(TerrainQualityGroup), false, "", -1, -30, true, "Quality level of terrain objects", getCurrentQualityLevel(TerrainQualityGroup));
+   OptionsMenuSettingsList.addOptionRow("Decal Lifetime", getQualityLevels(DecalLifetimeGroup), false, "", -1, -30, true, "How long decals are rendered", getCurrentQualityLevel(DecalLifetimeGroup));
+   OptionsMenuSettingsList.addOptionRow("Ground Cover Density", getQualityLevels(GroundCoverDensityGroup), false, "", -1, -30, true, "Density of ground cover items, such as grass", getCurrentQualityLevel(GroundCoverDensityGroup));
+   OptionsMenuSettingsList.addOptionRow("Shader Quality", getQualityLevels(ShaderQualityGroup), false, "", -1, -30, true, "Dictates the overall shader quality level, adjusting what features are enabled.", getCurrentQualityLevel(ShaderQualityGroup));
+   OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", %anisoFilter, false, "", -1, -30, true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance", $pref::Video::defaultAnisotropy);
+   OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "4\t2\t1\tOff", false, "", -1, -30, true, "Amount of Post-Processing Anti-Aliasing applied to rendering", $pref::Video::AA);
+   OptionsMenuSettingsList.addOptionRow("Parallax", %onOffList, false, "", -1, -30, true, "Whether the surface parallax shader effect is enabled", convertBoolToOnOff(!$pref::Video::disableParallaxMapping));
+   OptionsMenuSettingsList.addOptionRow("Water Reflections", %onOffList, false, "", -1, -30, true, "Whether water reflections are enabled", convertBoolToOnOff(!$pref::Water::disableTrueReflections));
+   OptionsMenuSettingsList.addOptionRow("SSAO", %onOffList, false, "", -1, -30, true, "Whether Screen-Space Ambient Occlusion is enabled", convertBoolToOnOff($pref::PostFX::EnableSSAO));
+   OptionsMenuSettingsList.addOptionRow("Depth of Field", %onOffList, false, "", -1, -30, true, "Whether the Depth of Field effect is enabled", convertBoolToOnOff($pref::PostFX::EnableDOF));
+   OptionsMenuSettingsList.addOptionRow("Vignette", %onOffList, false, "", -1, -30, true, "Whether the vignette effect is enabled", convertBoolToOnOff($pref::PostFX::EnableVignette));
+   OptionsMenuSettingsList.addOptionRow("Light Rays", %onOffList, false, "", -1, -30, true, "Whether the light rays effect is enabled", convertBoolToOnOff($pref::PostFX::EnableLightRays));
+   
+   OptionsMenuSettingsList.refresh();
+}
+
+function OptionsMenu::applyGraphicsSettings(%this)
+{
+   ShadowQualityList.applySetting(OptionsMenuSettingsList.getCurrentOption(0));
+   SoftShadowList.applySetting(OptionsMenuSettingsList.getCurrentOption(1));
+   
+   MeshQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(2));
+   TextureQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(3));
+   TerrainQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(4));
+   DecalLifetimeGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(5));
+   GroundCoverDensityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(6));
+   ShaderQualityGroup.applySetting(OptionsMenuSettingsList.getCurrentOption(7));
+   
+   //Update Textures
+   reloadTextures();
+
+   //Update lighting
+   // Set the light manager.  This should do nothing 
+   // if its already set or if its not compatible.   
+   //setLightManager( $pref::lightManager );   
+   
+   $pref::PostFX::EnableSSAO = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(12));
+   $pref::PostFX::EnableDOF = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(13));
+   $pref::PostFX::EnableVignette = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(14));
+   $pref::PostFX::EnableLightRays = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(15));
+   
+   PostFXManager.settingsEffectSetEnabled("SSAO", $pref::PostFX::EnableSSAO);
+   PostFXManager.settingsEffectSetEnabled("DOF", $pref::PostFX::EnableDOF);
+   PostFXManager.settingsEffectSetEnabled("LightRays", $pref::PostFX::EnableLightRays);
+   PostFXManager.settingsEffectSetEnabled("Vignette", $pref::PostFX::EnableVignette);
+   
+   $pref::Video::disableParallaxMapping = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(10));
+   
+   //water reflections
+   $pref::Water::disableTrueReflections = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(11));
+   
+   // Check the anisotropic filtering.   
+   %level = OptionsMenuSettingsList.getCurrentOption(8);
+   if ( %level != $pref::Video::defaultAnisotropy )
+   {
+      if ( %testNeedApply )
+         return true;
+                                 
+      $pref::Video::defaultAnisotropy = %level;
+   }
+   
+   updateDisplaySettings();
+   
+   echo("Exporting client prefs");
+   %prefPath = getPrefpath();
+   export("$pref::*", %prefPath @ "/clientPrefs.cs", false);
+}   
+
+function updateDisplaySettings()
+{
+   //Update the display settings now
+   $pref::Video::Resolution = getWords( Canvas.getMode( GraphicsMenuResolution.getSelected() ), $WORD::RES_X, $WORD::RES_Y );
+   %newBpp        = 32; // ... its not 1997 anymore.
+	$pref::Video::FullScreen = GraphicsMenuFullScreen.isStateOn() ? "true" : "false";
+	$pref::Video::RefreshRate    = GraphicsMenuRefreshRate.getSelected();
+	$pref::Video::disableVerticalSync = !GraphicsMenuVSync.isStateOn();	
+	$pref::Video::AA = GraphicsMenuAA.getSelected();
+	
+   if ( %newFullScreen $= "false" )
+	{
+      // If we're in windowed mode switch the fullscreen check
+      // if the resolution is bigger than the desktop.
+      %deskRes    = getDesktopResolution();      
+      %deskResX   = getWord(%deskRes, $WORD::RES_X);
+      %deskResY   = getWord(%deskRes, $WORD::RES_Y);
+	   if (  getWord( %newRes, $WORD::RES_X ) > %deskResX || 
+	         getWord( %newRes, $WORD::RES_Y ) > %deskResY )
+      {
+         $pref::Video::FullScreen = "true";
+         GraphicsMenuFullScreen.setStateOn( true );
+      }
+	}
+
+   // Build the final mode string.
+	%newMode = $pref::Video::Resolution SPC $pref::Video::FullScreen SPC %newBpp SPC $pref::Video::RefreshRate SPC $pref::Video::AA;
+	
+   // Change the video mode.   
+   if (  %newMode !$= $pref::Video::mode || 
+         %newVsync != $pref::Video::disableVerticalSync )
+   {
+      if ( %testNeedApply )
+         return true;
+
+      $pref::Video::mode = %newMode;
+      $pref::Video::disableVerticalSync = %newVsync;      
+      configureCanvas();
+   }
 }
 
 function OptionsMenu::populateAudioSettingsList(%this)
@@ -274,8 +357,56 @@ function OptionsMenu::populateAudioSettingsList(%this)
    %this.pageTabIndex = 2;
    OptionsMenuSettingsList.clearRows();
    
+   OptionName.setText("");
+   OptionDescription.setText("");
+   
+   %buffer = sfxGetAvailableDevices();
+   %count = getRecordCount( %buffer );  
+   %audioDriverList = "";
+    
+   for(%i = 0; %i < %count; %i++)
+   {
+      %record = getRecord(%buffer, %i);
+      %provider = getField(%record, 0);
+      
+      if(%i == 0)
+         %audioDriverList = %provider;
+      else 
+         %audioDriverList = %audioDriverList @ "\t" @ %provider;
+   }
+   
    %yesNoList = "Yes\tNo";
-   OptionsMenuSettingsList.addOptionRow("Audio Device", %yesNoList, false, "", -1, -15);
+   OptionsMenuSettingsList.addOptionRow("Audio Driver", %audioDriverList, false, "", -1, -15, true, "", $pref::SFX::provider);
+   OptionsMenuSettingsList.addOptionRow("Audio Device", %yesNoList, false, "", -1, -15, true, "");
+   
+   OptionsMenuSettingsList.addSliderRow("Master Volume", $pref::SFX::masterVolume, 0.1, "0 1", "", -1, -30);
+   OptionsMenuSettingsList.addSliderRow("GUI Volume", $pref::SFX::channelVolume[ $GuiAudioType], 0.1, "0 1", "", -1, -30);
+   OptionsMenuSettingsList.addSliderRow("Effects Volume", $pref::SFX::channelVolume[ $SimAudioType ], 0.1, "0 1", "", -1, -30);
+   OptionsMenuSettingsList.addSliderRow("Music Volume", $pref::SFX::channelVolume[ $MusicAudioType ], 0.1, "0 1", "", -1, -30);
+   
+   OptionsMenuSettingsList.refresh();
+}
+
+function OptionsMenu::applyAudioSettings(%this)
+{
+   sfxSetMasterVolume( $pref::SFX::masterVolume );
+   
+   sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] );
+   sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] );
+   sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] );
+   
+   if ( !sfxCreateDevice(  $pref::SFX::provider, 
+                           $pref::SFX::device, 
+                           $pref::SFX::useHardware,
+                           -1 ) )                              
+      error( "Unable to create SFX device: " @ $pref::SFX::provider 
+                                             SPC $pref::SFX::device 
+                                             SPC $pref::SFX::useHardware );        
+
+   if( !isObject( $AudioTestHandle ) )
+   {
+      sfxPlay(menuButtonPressed);  
+   }
 }
 
 function OptionsMenu::populateKeyboardMouseSettingsList(%this)
@@ -283,13 +414,23 @@ function OptionsMenu::populateKeyboardMouseSettingsList(%this)
    %this.pageTabIndex = 3;
    OptionsMenuSettingsList.clearRows();
    
-   OptionsMenuSettingsList.addOptionRow("Forward", "W", false, "", -1, -15);
+   OptionName.setText("");
+   OptionDescription.setText("");
+   
+   OptionsMenuSettingsList.addKeybindRow("Forward", getButtonBitmap("Keyboard", "W"), "doKeyRemap", -1, -15, true, "Forward butaaaahn");
+   
+   OptionsMenuSettingsList.refresh();
 }
 
 function OptionsMenu::populateGamepadSettingsList(%this)
 {
    %this.pageTabIndex = 4;
    OptionsMenuSettingsList.clearRows();
+   
+   OptionName.setText("");
+   OptionDescription.setText("");
+   
+   OptionsMenuSettingsList.refresh();
 }
 
 function OptionsMenuList::activateRow(%this)
@@ -297,78 +438,6 @@ function OptionsMenuList::activateRow(%this)
    OptionsMenuSettingsList.setFirstResponder();
 }
 
-function OptionsMenuList::backOut(%this)
-{
-   OptionsMenuList.setFirstResponder();
-}
-
-function OptionsMenuOKButton::onClick(%this)
-{
-    //save the settings and then back out
-    eval(OptionsMenu.currentMenu@"::apply();");
-    OptionsMenu.backOut();
-}
-
-//
-//
-function OptionsMenuSettingsList::backOut(%this)
-{
-   OptionsMenuList.setFirstResponder();
-}
-//
-//
-
-function OptionsMenuCancelButton::onClick(%this)
-{
-    //we don't save, so just back out of the menu 
-    OptionsMenu.backOut();
-}
-
-function OptionsMenuDefaultsButton::onClick(%this)
-{
-    //we don't save, so go straight to backing out of the menu    
-    eval(OptionsMenu.currentMenu@"::applyDefaults();");
-    OptionsMenu.backOut();
-}
-
-function ControlsSettingsMenuButton::onClick(%this)
-{
-    OptionsMain.hidden = true;
-    ControlsMenu.hidden = false;
-    
-    KeyboardControlPanel.hidden = false;
-    MouseControlPanel.hidden = true;
-    
-    ControlsMenu.reload();
-}
-
-function GraphicsSettingsMenuButton::onClick(%this)
-{
-    OptionsMain.hidden = true;
-    GraphicsMenu.hidden = false;
-}
-
-function CameraSettingsMenuButton::onClick(%this)
-{
-    OptionsMain.hidden = true;
-    CameraMenu.hidden = false;
-    
-    CameraMenu.loadSettings();
-}
-
-function AudioSettingsMenuButton::onClick(%this)
-{
-    OptionsMain.hidden = true;
-    AudioMenu.hidden = false;
-    AudioMenu.loadSettings();
-}
-
-function ScreenBrSettingsMenuButton::onClick(%this)
-{
-    OptionsMain.hidden = true;
-    ScreenBrightnessMenu.hidden = false;
-}
-
 function OptionsMenu::backOut(%this)
 {
    //save the settings and then back out
@@ -391,217 +460,26 @@ function OptionsMenu::backOut(%this)
    }
 }
 
-function OptionsMenu::addSettingOption(%this, %arrayTarget, %optionName, %defaultValue, %settingsGroup, %targetVar)
-{
-    %option = TAMLRead("data/ui/guis/graphicsMenuSettingsCtrl.taml");
-    
-    if(!isMethod(%settingsGroup, "get") || !isMethod(%settingsGroup, "set"))
-    {
-      error("OptionsMenu::addSettingsOption - unrecognized settings group of: " @ %settingsGroup @ ". Did not have proper getter/setter");
-      return "";
-    }
-    
-    %option-->nameText.text = %optionName;
-    %option-->SettingText.text = eval(%settingsGroup@"::"@"get();");
-    %option.qualitySettingGroup = %settingsGroup;
-    %option.targetVar = %targetVar;
-
-    %arrayTarget.add(%option);
-
-    return %option;
-}
-
-function OptionsMenu::addSliderOption(%this, %arrayTarget, %optionName, %variable, %range, %ticks, %value, %class)
-{
-    %option = TAMLRead("data/ui/guis/graphicsMenuSettingsSlider.taml");
-    
-    %option-->nameText.text = %optionName;
-
-    %arrayTarget.add(%option);
-    
-    if(%range !$= "")
-    {
-       %option-->slider.range = %range;
-    }
-    
-    if(%ticks !$= "")
-    {
-       %option-->slider.ticks = %ticks;
-    }
-    
-    if(%variable !$= "")
-    {
-       %option-->slider.variable = %variable;
-    }
-    
-    if(%value !$= "")
-    {
-       %option-->slider.setValue(%value);
-    }
-    
-    if(%class !$= "")
-    {
-       %option-->slider.className = %class;
-    }
-    else
-        %option-->slider.className = OptionsMenuSlider;
-        
-    %option-->slider.snap = true;
-    
-    %option-->slider.onValueSet();
-
-    return %option;
-}
-
-function OptionsMenuSlider::onMouseDragged(%this)
-{
-   %this.onValueSet();
-}
-
-function OptionsMenuSlider::onValueSet(%this)
-{
-   %this.getParent().getParent()-->valueText.setText(mRound(%this.value * 10));  
-}
-
-function FOVOptionSlider::onMouseDragged(%this)
-{
-   %this.onValueSet();
-}
-
-function FOVOptionSlider::onValueSet(%this)
-{
-   %this.getParent().getParent()-->valueText.setText(mRound(%this.value));
-}
-
-//
-function OptionsMenuForwardSetting::onClick(%this)
+function convertOptionToBool(%val)
 {
-   //we need to advance through the value list, unless it's the end, in which case we do nothing  
-   echo("Move forward in the list!");
-   
-   %settingCtrl = %this.getParent();
-   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
-   %settingsListCount = getTokenCount(%settingsList, ",");
-   %currentSetting = %settingCtrl-->SettingText.text;
-   
-   //We consider 'custom' to be the defacto end of the list. The only way back is to go lower
-   if(%currentSetting $= "Custom")
-      return;
-      
-   %currentSettingIdx = OptionsMenu.getCurrentIndexFromSetting(%settingCtrl);
-   
-   if(%currentSettingIdx != %settingsListCount-1)
-   {
-      %currentSettingIdx++;
-      
-      //advance by one
-      %newSetting = getToken(%settingsList, ",", %currentSettingIdx);
-      eval(%settingCtrl.qualitySettingGroup@"::set(\""@%newSetting@"\");");
-      %settingCtrl-->SettingText.setText( %newSetting );
-      
-      if(%currentSettingIdx == %settingsListCount)
-      {
-         //if we hit the end of the list, disable the forward button  
-      }
-   }
-}
-
-function OptionsMenuBackSetting::onClick(%this)
-{
-   //we need to advance through the value list, unless it's the end, in which case we do nothing  
-   echo("Move back in the list!");
-   
-   %settingCtrl = %this.getParent();
-   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
-   %settingsListCount = getTokenCount(%settingsList, ",");
-   %currentSetting = %settingCtrl-->SettingText.text;
-   
-   %currentSettingIdx = OptionsMenu.getCurrentIndexFromSetting(%settingCtrl);
-   
-   if(%currentSettingIdx != 0)
-   {
-      %currentSettingIdx--;
-      
-      //advance by one
-      %newSetting = getToken(%settingsList, ",", %currentSettingIdx);
-      eval(%settingCtrl.qualitySettingGroup@"::set(\""@%newSetting@"\");");
-      %settingCtrl-->SettingText.setText( %newSetting );
-      
-      if(%currentSettingIdx == %settingsListCount)
-      {
-         //if we hit the end of the list, disable the forward button  
-      }
-   }
-}
-
-function OptionsMenu::getCurrentIndexFromSetting(%this, %settingCtrl)
-{
-   %settingsList = eval(%settingCtrl.qualitySettingGroup@"::getList();");
-   %settingsListCount = getTokenCount(%settingsList, ",");
-   %currentSetting = %settingCtrl-->SettingText.text;
-   
-   for ( %i=0; %i < %settingsListCount; %i++ )
-   {
-      %level = getToken(%settingsList, ",", %i);
-      
-      //find our current level
-      if(%currentSetting $= %level)
-      {
-         return %i;
-      }
-   }
-   
-   return -1;
-}
-
-// =============================================================================
-// CAMERA MENU
-// =============================================================================
-function CameraMenu::onWake(%this)
-{
-    
-}
-
-function CameraMenu::apply(%this)
-{
-   setFOV($pref::Player::defaultFov);  
-}
-
-function CameraMenu::loadSettings(%this)
-{
-   CameraMenuOptionsArray.clear();
-   
-   %option = OptionsMenu.addSettingOption(CameraMenuOptionsArray);
-   %option-->nameText.setText("Invert Vertical");
-   %option.qualitySettingGroup = InvertVerticalMouse;
-   %option.init();
-   
-   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::VertMouseSensitivity", $pref::Input::VertMouseSensitivity);
-   %option-->nameText.setText("Vertical Sensitivity");
-   
-   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::HorzMouseSensitivity", $pref::Input::HorzMouseSensitivity);
-   %option-->nameText.setText("Horizontal Sensitivity");
-   
-   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomVertMouseSensitivity", $pref::Input::ZoomVertMouseSensitivity);
-   %option-->nameText.setText("Zoom Vertical Sensitivity");
-
-   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomHorzMouseSensitivity", $pref::Input::ZoomHorzMouseSensitivity);
-   %option-->nameText.setText("Zoom Horizontal Sensitivity");
-   
-   %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "65 90", 25, "$pref::Player::defaultFov", $pref::Player::defaultFov, FOVOptionSlider);
-   %option-->nameText.setText("Field of View");
-   
-   CameraMenuOptionsArray.refresh();
+   if(%val $= "yes" || %val $= "on")
+      return 1;
+   else 
+      return 0;
 }
 
-function CameraMenuOKButton::onClick(%this)
+function convertBoolToYesNo(%val)
 {
-   //save the settings and then back out
-    CameraMenu.apply();
-    OptionsMenu.backOut();
+   if(%val == 1)
+      return "Yes";
+   else 
+      return "No";
 }
 
-function CameraMenuDefaultsButton::onClick(%this)
+function convertBoolToOnOff(%val)
 {
-   
+   if(%val == 1)
+      return "On";
+   else 
+      return "Off";
 }

+ 0 - 307
Templates/BaseGame/game/data/ui/guis/optionsMenu.gui

@@ -17,313 +17,6 @@
       tile = "0";
       useVariable = "0";
 
-   new GuiControl() {
-      position = "89 75";
-      extent = "846 618";
-      minExtent = "8 2";
-      horizSizing = "center";
-      vertSizing = "center";
-      profile = "GuiDefaultProfile";
-      visible = "0";
-      active = "1";
-      tooltipProfile = "GuiToolTipProfile";
-      hovertime = "1000";
-      isContainer = "1";
-      hidden = "1";
-      canSave = "1";
-      canSaveDynamicFields = "0";
-
-      new GuiBitmapCtrl() {
-         bitmap = "data/ui/images/hudfill.png";
-         color = "255 255 255 255";
-         wrap = "0";
-         position = "0 0";
-         extent = "846 618";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "height";
-         profile = "GuiDefaultProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "0";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-      };
-      new GuiControl() {
-         position = "0 0";
-         extent = "846 20";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "bottom";
-         profile = "GuiDefaultProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "1";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-
-         new GuiBitmapCtrl() {
-            bitmap = "data/ui/images/hudfill.png";
-            color = "255 255 255 255";
-            wrap = "0";
-            position = "0 0";
-            extent = "846 20";
-            minExtent = "8 2";
-            horizSizing = "width";
-            vertSizing = "height";
-            profile = "GuiDefaultProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiTextCtrl() {
-            text = "Options";
-            maxLength = "1024";
-            margin = "0 0 0 0";
-            padding = "0 0 0 0";
-            anchorTop = "1";
-            anchorBottom = "0";
-            anchorLeft = "1";
-            anchorRight = "0";
-            position = "0 0";
-            extent = "846 20";
-            minExtent = "8 2";
-            horizSizing = "width";
-            vertSizing = "bottom";
-            profile = "GuiMenuButtonProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-      };
-      new GuiScrollCtrl() {
-         willFirstRespond = "1";
-         hScrollBar = "alwaysOff";
-         vScrollBar = "dynamic";
-         lockHorizScroll = "0";
-         lockVertScroll = "0";
-         constantThumbHeight = "0";
-         childMargin = "0 0";
-         mouseWheelScrollSpeed = "-1";
-         margin = "0 0 0 0";
-         padding = "0 0 0 0";
-         anchorTop = "1";
-         anchorBottom = "0";
-         anchorLeft = "1";
-         anchorRight = "0";
-         position = "0 25";
-         extent = "846 522";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "height";
-         profile = "GuiMenuScrollProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "1";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-
-         new GuiStackControl(OptionsSettingStack) {
-            stackingType = "Vertical";
-            horizStacking = "Left to Right";
-            vertStacking = "Top to Bottom";
-            padding = "0";
-            dynamicSize = "1";
-            dynamicNonStackExtent = "0";
-            dynamicPos = "0";
-            changeChildSizeToFit = "1";
-            changeChildPosition = "1";
-            position = "1 1";
-            extent = "846 140";
-            minExtent = "16 16";
-            horizSizing = "width";
-            vertSizing = "bottom";
-            profile = "GuiDefaultProfile";
-            visible = "1";
-            active = "1";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "1";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-
-            new GuiButtonCtrl() {
-               text = "Keyboard and Mouse";
-               groupNum = "-1";
-               buttonType = "PushButton";
-               useMouseEvents = "0";
-               position = "0 0";
-               extent = "846 35";
-               minExtent = "8 2";
-               horizSizing = "right";
-               vertSizing = "bottom";
-               profile = "GuiMenuButtonProfile";
-               visible = "1";
-               active = "1";
-               command = "ControlsMenu::loadSettings();";
-               tooltipProfile = "GuiToolTipProfile";
-               hovertime = "1000";
-               isContainer = "0";
-               canSave = "1";
-               canSaveDynamicFields = "0";
-            };
-            new GuiButtonCtrl() {
-               text = "Display";
-               groupNum = "-1";
-               buttonType = "PushButton";
-               useMouseEvents = "0";
-               position = "0 35";
-               extent = "846 35";
-               minExtent = "8 2";
-               horizSizing = "right";
-               vertSizing = "bottom";
-               profile = "GuiMenuButtonProfile";
-               visible = "1";
-               active = "1";
-               command = "DisplayMenu::loadSettings();";
-               tooltipProfile = "GuiToolTipProfile";
-               hovertime = "1000";
-               isContainer = "0";
-               canSave = "1";
-               canSaveDynamicFields = "0";
-            };
-            new GuiButtonCtrl() {
-               text = "Graphics";
-               groupNum = "-1";
-               buttonType = "PushButton";
-               useMouseEvents = "0";
-               position = "0 70";
-               extent = "846 35";
-               minExtent = "8 2";
-               horizSizing = "right";
-               vertSizing = "bottom";
-               profile = "GuiMenuButtonProfile";
-               visible = "1";
-               active = "1";
-               command = "GraphicsMenu::loadSettings();";
-               tooltipProfile = "GuiToolTipProfile";
-               hovertime = "1000";
-               isContainer = "0";
-               canSave = "1";
-               canSaveDynamicFields = "0";
-            };
-            new GuiButtonCtrl() {
-               text = "Audio";
-               groupNum = "-1";
-               buttonType = "PushButton";
-               useMouseEvents = "0";
-               position = "0 105";
-               extent = "846 35";
-               minExtent = "8 2";
-               horizSizing = "right";
-               vertSizing = "bottom";
-               profile = "GuiMenuButtonProfile";
-               visible = "1";
-               active = "1";
-               command = "AudioMenu::loadSettings();";
-               tooltipProfile = "GuiToolTipProfile";
-               hovertime = "1000";
-               isContainer = "0";
-               canSave = "1";
-               canSaveDynamicFields = "0";
-            };
-         };
-      };
-      new GuiMLTextCtrl() {
-         lineSpacing = "2";
-         allowColorChars = "0";
-         maxChars = "-1";
-         text = "This is a test message to act as a tooltip for any selected options menus for more information on the given option.";
-         useURLMouseCursor = "0";
-         position = "0 547";
-         extent = "847 14";
-         minExtent = "8 2";
-         horizSizing = "width";
-         vertSizing = "top";
-         profile = "GuiMLWhiteTextProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "0";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-      };
-      new GuiButtonCtrl() {
-         text = "OK";
-         groupNum = "-1";
-         buttonType = "PushButton";
-         useMouseEvents = "0";
-         position = "0 581";
-         extent = "282 37";
-         minExtent = "8 2";
-         horizSizing = "right";
-         vertSizing = "top";
-         profile = "GuiMenuButtonProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "0";
-         class = "OptionsMenuOKButton";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-      };
-      new GuiButtonCtrl() {
-         text = "Defaults";
-         groupNum = "-1";
-         buttonType = "PushButton";
-         useMouseEvents = "0";
-         position = "282 581";
-         extent = "282 37";
-         minExtent = "8 2";
-         horizSizing = "relative";
-         vertSizing = "top";
-         profile = "GuiMenuButtonProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "0";
-         class = "OptionsMenuDefaultsButton";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-      };
-      new GuiButtonCtrl() {
-         text = "Cancel";
-         groupNum = "-1";
-         buttonType = "PushButton";
-         useMouseEvents = "0";
-         position = "564 581";
-         extent = "282 37";
-         minExtent = "8 2";
-         horizSizing = "left";
-         vertSizing = "height";
-         profile = "GuiMenuButtonProfile";
-         visible = "1";
-         active = "1";
-         tooltipProfile = "GuiToolTipProfile";
-         hovertime = "1000";
-         isContainer = "0";
-         class = "OptionsMenuCancelButton";
-         canSave = "1";
-         canSaveDynamicFields = "0";
-      };
-   };
    new GuiControl() {
       position = "48 56";
       extent = "928 655";

+ 40 - 11
Templates/BaseGame/game/data/ui/guis/pauseMenu.cs

@@ -1,30 +1,59 @@
+function PauseMenuList::onAdd(%this)
+{
+   %this.addRow("Options", "openPauseMenuOptions", -1, -30);
+   %this.addRow("Exit to Menu", "pauseMenuExitToMenu", -1, -30);
+   %this.addRow("Exit to Desktop", "pauseMenuExitToDesktop", -1, -30);  
+}
+
 function PauseMenu::onWake(%this)
 {
    $timescale = 0;
 }
 
+
 function PauseMenu::onSleep(%this)
 {
    $timescale = 1;
 }
 
-function PauseMenu::openOptionsMenu(%this)
+function PauseMenu::onReturnTo(%this)
 {
-   Canvas.pushDialog(OptionsMenu);
-   OptionsMenu.returnGui = %this; 
-   PauseOptionsMain.hidden = true; 
+   PauseMenuList.hidden = false;
+   PauseButtonHolder.refresh();
 }
 
-function PauseMenu::openControlsMenu(%this)
+function openPauseMenuOptions()
 {
    Canvas.pushDialog(OptionsMenu);
-   OptionsMenu.returnGui = %this; 
-   PauseOptionsMain.hidden = true; 
-   OptionsMain.hidden = true;
-   ControlsMenu.hidden = false;
+   OptionsMenu.returnGui = PauseMenu; 
+   PauseMenuList.hidden = true;
 }
 
-function PauseMenu::onReturnTo(%this)
+function pauseMenuExitToMenu()
+{
+   PauseMenuList.hidden = true;
+   MessageBoxOKCancel("Exit?", "Do you wish to exit to the Main Menu?", "escapeFromGame();", "PauseMenu.onReturnTo();");
+}
+
+function pauseMenuExitToDesktop()
+{
+   PauseMenuList.hidden = true;
+   MessageBoxOKCancel("Exit?", "Do you wish to exit to the desktop?", "quit();", "PauseMenu.onReturnTo();");
+}
+
+function PauseButtonHolder::onWake(%this)
+{
+   %this.refresh();
+}
+
+function PauseButtonHolder::refresh(%this)
 {
-   PauseOptionsMain.hidden = false;
+   PauseButtonHolder.add(GamepadButtonsGui);
+   
+   GamepadButtonsGui.clearButtons();
+   
+   GamepadButtonsGui.setButton(2, "A", "", "", "", true);
+   GamepadButtonsGui.setButton(3, "B", "Esc", "Back", "Canvas.popDialog();");
+   
+   GamepadButtonsGui.refreshButtons();
 }

+ 28 - 90
Templates/BaseGame/game/data/ui/guis/pauseMenu.gui

@@ -49,105 +49,43 @@
       isContainer = "1";
       canSave = "1";
       canSaveDynamicFields = "0";
-
-      new GuiControl(PauseOptionsMain) {
-         position = "1 1";
+      
+      new GuiGameListMenuCtrl(PauseMenuList) {
+         class = "UIMenuButtonList";
+         debugRender = "0";
+         callbackOnA = "OptionsMenuSettingsList.activateRow();";
+         callbackOnB = "OptionsMenuSettingsList.backOut();";
+         callbackOnInputs = "1";
+         position = "0 0";
          extent = "700 320";
          minExtent = "8 2";
-         horizSizing = "right";
-         vertSizing = "center";
-         profile = "GuiDefaultProfile";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "DefaultListMenuProfile";
          visible = "1";
          active = "1";
          tooltipProfile = "GuiToolTipProfile";
          hovertime = "1000";
-         isContainer = "1";
+         isContainer = "0";
          canSave = "1";
          canSaveDynamicFields = "0";
-
-         new GuiButtonCtrl(PauseMenuExitButton) {
-            text = "Exit Game";
-            groupNum = "-1";
-            buttonType = "PushButton";
-            useMouseEvents = "1";
-            position = "0 0";
-            extent = "700 35";
-            minExtent = "8 8";
-            horizSizing = "relative";
-            vertSizing = "bottom";
-            profile = "GuiMenuButtonProfile";
-            visible = "1";
-            active = "1";
-            command = "escapeFromGame();";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiButtonCtrl(PauseMenuOptionsButton) {
-            text = "Options";
-            groupNum = "-1";
-            buttonType = "PushButton";
-            useMouseEvents = "1";
-            position = "0 35";
-            extent = "700 35";
-            minExtent = "8 8";
-            horizSizing = "relative";
-            vertSizing = "bottom";
-            profile = "GuiMenuButtonProfile";
-            visible = "1";
-            active = "1";
-            command = "PauseMenu.openOptionsMenu();";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiButtonCtrl(PauseMenuControlsButton) {
-            text = "Controls";
-            groupNum = "-1";
-            buttonType = "PushButton";
-            useMouseEvents = "1";
-            position = "0 70";
-            extent = "700 35";
-            minExtent = "8 8";
-            horizSizing = "relative";
-            vertSizing = "bottom";
-            profile = "GuiMenuButtonProfile";
-            visible = "1";
-            active = "1";
-            command = "PauseMenu.openControlsMenu();";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
-         new GuiButtonCtrl(PauseMenuCancelButton) {
-            text = "Cancel";
-            groupNum = "-1";
-            buttonType = "PushButton";
-            useMouseEvents = "1";
-            position = "466 285";
-            extent = "233 35";
-            minExtent = "8 8";
-            horizSizing = "relative";
-            vertSizing = "bottom";
-            profile = "GuiMenuButtonProfile";
-            visible = "1";
-            active = "1";
-            command = "Canvas.popDialog();";
-            accelerator = "escape";
-            tooltipProfile = "GuiToolTipProfile";
-            hovertime = "1000";
-            isContainer = "0";
-            class = "OptionsMenuDefaultsButton";
-            canSave = "1";
-            canSaveDynamicFields = "0";
-         };
       };
    };
+   
+   new GuiControl(PauseButtonHolder) {
+      position = "189 652";
+      extent = "646 130";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "top";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
 };
 //--- OBJECT WRITE END ---

BIN
Templates/BaseGame/game/data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_Blank.png


+ 1 - 1
Templates/BaseGame/game/data/ui/scripts/displayMenu.cs

@@ -38,7 +38,7 @@ function DisplayMenu::apply(%this)
    }
       
    //Update the display settings now
-   if (getWord( $pref::Video::Resolution, 2) == "")
+   if (getWord( $pref::Video::Resolution, 2) $= "")
    {
       $pref::Video::Resolution = getWord( $pref::Video::Resolution, 0 ) SPC getWord( $pref::Video::Resolution, 1 );
    }

+ 401 - 0
Templates/BaseGame/game/data/ui/scripts/keybindEdit.cs

@@ -0,0 +1,401 @@
+// =============================================================================
+// KEYBINDS MENU
+// =============================================================================
+$RemapCount = 0;
+$RemapName[$RemapCount] = "Forward";
+$RemapCmd[$RemapCount] = "moveforward";
+$RemapGroup[$RemapCount] = "Movement";
+$RemapCount++;
+$RemapName[$RemapCount] = "Backward";
+$RemapCmd[$RemapCount] = "movebackward";
+$RemapGroup[$RemapCount] = "Movement";
+$RemapCount++;
+$RemapName[$RemapCount] = "Strafe Left";
+$RemapCmd[$RemapCount] = "moveleft";
+$RemapGroup[$RemapCount] = "Movement";
+$RemapCount++;
+$RemapName[$RemapCount] = "Strafe Right";
+$RemapCmd[$RemapCount] = "moveright";
+$RemapGroup[$RemapCount] = "Movement";
+$RemapCount++;
+$RemapName[$RemapCount] = "Jump";
+$RemapCmd[$RemapCount] = "jump";
+$RemapGroup[$RemapCount] = "Movement";
+$RemapCount++;
+
+$RemapName[$RemapCount] = "Fire Weapon";
+$RemapCmd[$RemapCount] = "mouseFire";
+$RemapGroup[$RemapCount] = "Combat";
+$RemapCount++;
+$RemapName[$RemapCount] = "Adjust Zoom";
+$RemapCmd[$RemapCount] = "setZoomFov";
+$RemapGroup[$RemapCount] = "Combat";
+$RemapCount++;
+$RemapName[$RemapCount] = "Toggle Zoom";
+$RemapCmd[$RemapCount] = "toggleZoom";
+$RemapGroup[$RemapCount] = "Combat";
+$RemapCount++;
+
+$RemapName[$RemapCount] = "Free Look";
+$RemapCmd[$RemapCount] = "toggleFreeLook";
+$RemapGroup[$RemapCount] = "Miscellaneous";
+$RemapCount++;
+$RemapName[$RemapCount] = "Switch 1st/3rd";
+$RemapCmd[$RemapCount] = "toggleFirstPerson";
+$RemapGroup[$RemapCount] = "Miscellaneous";
+$RemapCount++;
+$RemapName[$RemapCount] = "Toggle Camera";
+$RemapCmd[$RemapCount] = "toggleCamera";
+$RemapGroup[$RemapCount] = "Miscellaneous";
+$RemapCount++;
+
+function ControlSetList::onSelect( %this, %id, %text )
+{
+   ControlsMenuOptionsArray.clear();
+   
+   if(%text $= "Movement")
+      loadGroupKeybinds("Movement");
+   else if(%text $= "Combat")
+      loadGroupKeybinds("Combat");
+   else if(%text $= "Miscellaneous")
+      loadGroupKeybinds("Miscellaneous");
+
+    //ControlsMenuOptionsArray.refresh();
+}
+
+function ControlsMenuOKButton::onClick(%this)
+{
+    // write out the control config into the keybinds.cs file
+    %prefPath = getPrefpath();
+    moveMap.save( %prefPath @ "/keybinds.cs" );
+   
+    OptionsMenu.backOut();
+}
+
+function ControlsMenuDefaultsButton::onClick(%this)
+{
+   //For this to work with module-style, we have to figure that somewhere, we'll set where our default keybind script is at.
+   //This can be hardcoded in your actual project.
+   exec($KeybindPath);
+   ControlsMenu.reload();
+}
+
+function loadGroupKeybinds(%keybindGroup)
+{
+   %optionIndex = 0;
+   for(%i=0; %i < $RemapCount; %i++)
+   {
+      //find and add all the keybinds for the particular group we're looking at
+      if($RemapGroup[%i] $= %keybindGroup)
+      {
+         %temp = getKeybindString(%i);
+         
+         %option = addKeybindOption();
+         %option-->nameText.setText($RemapName[%i]);
+         %option-->rebindButton.setText(%temp);
+         %option-->rebindButton.keybindIndex = %i;
+         %option-->rebindButton.optionIndex = %optionIndex;
+         %optionIndex++;
+      }
+   }
+}
+
+function addKeybindOption()
+{
+    %tamlReader = new Taml();
+   
+    %controlOption = %tamlReader.read("data/ui/guis/controlsMenuSetting.taml");
+    %controlOption.extent.x = OptionsSettingStack.extent.x;
+
+    OptionsSettingStack.add(%controlOption);
+
+    return %graphicsOption;
+}
+
+function getKeybindString(%index )
+{
+   %name       = $RemapName[%index];
+   %cmd        = $RemapCmd[%index];
+
+   %temp = moveMap.getBinding( %cmd );
+   if ( %temp $= "" )
+      return %name TAB "";
+
+   %mapString = "";
+
+   %count = getFieldCount( %temp );
+   for ( %i = 0; %i < %count; %i += 2 )
+   {
+      %device = getField( %temp, %i + 0 );
+      %object = getField( %temp, %i + 1 );
+      
+      %displayName = getMapDisplayName( %device, %object );
+      
+      if(%displayName !$= "")
+      {
+         %tmpMapString = getMapDisplayName( %device, %object );
+         
+         if(%mapString $= "")
+         {
+            %mapString = %tmpMapString;
+         }
+         else
+         {
+            if ( %tmpMapString !$= "")
+            {
+               %mapString = %mapString @ ", " @ %tmpMapString;
+            }
+         }
+      }
+   }
+
+   return %mapString; 
+}
+
+function ControlsMenu::redoMapping( %device, %action, %cmd, %oldIndex, %newIndex )
+{
+	//%actionMap.bind( %device, %action, $RemapCmd[%newIndex] );
+	moveMap.bind( %device, %action, %cmd );
+	
+   %remapList = %this-->OptRemapList;
+	%remapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) );
+	%remapList.setRowById( %newIndex, buildFullMapString( %newIndex ) );
+}
+
+function getMapDisplayName( %device, %action )
+{
+	if ( %device $= "keyboard" )
+		return( %action );		
+	else if ( strstr( %device, "mouse" ) != -1 )
+	{
+		// Substitute "mouse" for "button" in the action string:
+		%pos = strstr( %action, "button" );
+		if ( %pos != -1 )
+		{
+			%mods = getSubStr( %action, 0, %pos );
+			%object = getSubStr( %action, %pos, 1000 );
+			%instance = getSubStr( %object, strlen( "button" ), 1000 );
+			return( %mods @ "mouse" @ ( %instance + 1 ) );
+		}
+		else
+			error( "Mouse input object other than button passed to getDisplayMapName!" );
+	}
+	else if ( strstr( %device, "joystick" ) != -1 )
+	{
+		// Substitute "joystick" for "button" in the action string:
+		%pos = strstr( %action, "button" );
+		if ( %pos != -1 )
+		{
+			%mods = getSubStr( %action, 0, %pos );
+			%object = getSubStr( %action, %pos, 1000 );
+			%instance = getSubStr( %object, strlen( "button" ), 1000 );
+			return( %mods @ "joystick" @ ( %instance + 1 ) );
+		}
+		else
+	   { 
+	      %pos = strstr( %action, "pov" );
+         if ( %pos != -1 )
+         {
+            %wordCount = getWordCount( %action );
+            %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
+            %object = getWord( %action, %wordCount - 1 );
+            switch$ ( %object )
+            {
+               case "upov":   %object = "POV1 up";
+               case "dpov":   %object = "POV1 down";
+               case "lpov":   %object = "POV1 left";
+               case "rpov":   %object = "POV1 right";
+               case "upov2":  %object = "POV2 up";
+               case "dpov2":  %object = "POV2 down";
+               case "lpov2":  %object = "POV2 left";
+               case "rpov2":  %object = "POV2 right";
+               default:       %object = "";
+            }
+            return( %mods @ %object );
+         }
+         else
+            error( "Unsupported Joystick input object passed to getDisplayMapName!" );
+      }
+	}
+		
+	return( "" );		
+}
+
+function ControlsMenu::buildFullMapString( %this, %index )
+{
+   %name       = $RemapName[%index];
+   %cmd        = $RemapCmd[%index];
+
+   %temp = moveMap.getBinding( %cmd );
+   if ( %temp $= "" )
+      return %name TAB "";
+
+   %mapString = "";
+
+   %count = getFieldCount( %temp );
+   for ( %i = 0; %i < %count; %i += 2 )
+   {
+      if ( %mapString !$= "" )
+         %mapString = %mapString @ ", ";
+
+      %device = getField( %temp, %i + 0 );
+      %object = getField( %temp, %i + 1 );
+      %mapString = %mapString @ %this.getMapDisplayName( %device, %object );
+   }
+
+   return %name TAB %mapString; 
+}
+
+function ControlsMenu::fillRemapList( %this )
+{
+   %remapList = %this-->OptRemapList;
+   
+	%remapList.clear();
+   for ( %i = 0; %i < $RemapCount; %i++ )
+      %remapList.addRow( %i, %this.buildFullMapString( %i ) );
+}
+
+function doKeyRemap( %rowIndex )
+{
+   %name = $RemapName[%rowIndex];
+
+	RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." );
+	OptRemapInputCtrl.index = %rowIndex;
+	Canvas.pushDialog( RemapDlg );
+}
+
+function ControlsMenuRebindButton::onClick(%this)
+{
+   %name = $RemapName[%this.keybindIndex];
+   RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." );
+   
+   OptRemapInputCtrl.index = %this.keybindIndex;
+   OptRemapInputCtrl.optionIndex = %this.optionIndex;
+   Canvas.pushDialog( RemapDlg );
+}
+
+function OptRemapInputCtrl::onInputEvent( %this, %device, %action )
+{
+   //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" );
+   Canvas.popDialog( RemapDlg );
+
+   // Test for the reserved keystrokes:
+   if ( %device $= "keyboard" )
+   {
+      // Cancel...
+      if ( %action $= "escape" )
+      {
+         // Do nothing...
+         return;
+      }
+   }
+
+   %cmd  = $RemapCmd[%this.index];
+   %name = $RemapName[%this.index];
+
+   // Grab the friendly display name for this action
+   // which we'll use when prompting the user below.
+   %mapName = ControlsMenu.getMapDisplayName( %device, %action );
+   
+   // Get the current command this action is mapped to.
+   %prevMap = moveMap.getCommand( %device, %action );
+
+   // If nothing was mapped to the previous command 
+   // mapping then it's easy... just bind it.
+   if ( %prevMap $= "" )
+   {
+      ControlsMenu.unbindExtraActions( %cmd, 1 );
+      moveMap.bind( %device, %action, %cmd );
+      
+      //ControlsMenu.reload();
+      %newCommands = getField(ControlsMenu.buildFullMapString( %this.index ), 1);
+      ControlsMenuOptionsArray.getObject(%this.optionIndex)-->rebindButton.setText(%newCommands);
+      return;
+   }
+
+   // If the previous command is the same as the 
+   // current then they hit the same input as what
+   // was already assigned.
+   if ( %prevMap $= %cmd )
+   {
+      ControlsMenu.unbindExtraActions( %cmd, 0 );
+      moveMap.bind( %device, %action, %cmd );
+
+      //ControlsMenu.reload();
+      %newCommands = getField(ControlsMenu.buildFullMapString( %this.index ), 1);
+      ControlsMenuOptionsArray.getObject(%this.optionIndex)-->rebindButton.setText(%newCommands);
+      return;   
+   }
+
+   // Look for the index of the previous mapping.
+   %prevMapIndex = ControlsMenu.findRemapCmdIndex( %prevMap );
+   
+   // If we get a negative index then the previous 
+   // mapping was to an item that isn't included in
+   // the mapping list... so we cannot unmap it.
+   if ( %prevMapIndex == -1 )
+   {
+      MessageBoxOK( "Remap Failed", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" );
+      return;
+   }
+
+   // Setup the forced remapping callback command.
+   %callback = "redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @
+                              %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");";
+   
+   // Warn that we're about to remove the old mapping and
+   // replace it with another.
+   %prevCmdName = $RemapName[%prevMapIndex];
+   Canvas.pushDialog( RemapConfirmDlg );
+   
+   RemapConfirmationText.setText("\"" @ %mapName @ "\" is already bound to \""
+      @ %prevCmdName @ "\"! Do you wish to replace this mapping?");
+   RemapConfirmationYesButton.command = "ControlsMenu.redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @
+                              %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ "); Canvas.popDialog();";
+   RemapConfirmationNoButton.command = "Canvas.popDialog();";
+   
+   /*MessageBoxYesNo( "Warning",
+      "\"" @ %mapName @ "\" is already bound to \""
+      @ %prevCmdName @ "\"!\nDo you wish to replace this mapping?",
+       %callback, "" );*/
+}
+
+function ControlsMenu::findRemapCmdIndex( %this, %command )
+{
+	for ( %i = 0; %i < $RemapCount; %i++ )
+	{
+		if ( %command $= $RemapCmd[%i] )
+			return( %i );			
+	}
+	return( -1 );	
+}
+
+/// This unbinds actions beyond %count associated to the
+/// particular moveMap %commmand.
+function ControlsMenu::unbindExtraActions( %this, %command, %count )
+{
+   %temp = moveMap.getBinding( %command );
+   if ( %temp $= "" )
+      return;
+
+   %count = getFieldCount( %temp ) - ( %count * 2 );
+   for ( %i = 0; %i < %count; %i += 2 )
+   {
+      %device = getField( %temp, %i + 0 );
+      %action = getField( %temp, %i + 1 );
+      
+      moveMap.unbind( %device, %action );
+   }
+}
+
+function ControlsMenu::redoMapping( %this, %device, %action, %cmd, %oldIndex, %newIndex )
+{
+	//%actionMap.bind( %device, %action, $RemapCmd[%newIndex] );
+	moveMap.bind( %device, %action, %cmd );
+	
+   %remapList = %this-->OptRemapList;
+	%remapList.setRowById( %oldIndex, %this.buildFullMapString( %oldIndex ) );
+	%remapList.setRowById( %newIndex, %this.buildFullMapString( %newIndex ) );
+	
+	%this.changeSettingsPage();
+}

+ 0 - 0
Templates/BaseGame/game/data/ui/scripts/optionsList.cs


+ 65 - 0
Templates/BaseGame/game/data/ui/scripts/utility.cs

@@ -0,0 +1,65 @@
+function getButtonBitmap(%device, %button)
+{
+   %path = "";
+   if(%device $= "PS4")
+   { 
+      %path = "data/ui/images/inputs/PS4/PS4_";
+      
+      if(%button $= "A")
+         %path = %path @ "Cross";
+      else if(%button $= "B")
+         %path = %path @ "Circle";
+      else if(%button $= "X")
+         %path = %path @ "Square";
+      else if(%button $= "Y")
+         %path = %path @ "Triangle";
+      else if(%button $= "LB")
+         %path = %path @ "L1";
+      else if(%button $= "LT")
+         %path = %path @ "L2";
+      else if(%button $= "RB")
+         %path = %path @ "R1";
+      else if(%button $= "RT")
+         %path = %path @ "R2";
+      else      
+         continue;
+   }
+   else if(%device $= "Switch")
+   {
+      %path = "data/ui/images/inputs/Switch/Switch_";
+      
+      if(%button $= "A")
+         %path = %path @ "B";
+      else if(%button $= "B")
+         %path = %path @ "A";
+      else if(%button $= "X")
+         %path = %path @ "Y";
+      else if(%button $= "Y")
+         %path = %path @ "X";
+      else if(%button $= "LB")
+         %path = %path @ "LB";
+      else if(%button $= "LT")
+         %path = %path @ "LT";
+      else if(%button $= "RB")
+         %path = %path @ "RB";
+      else if(%button $= "RT")
+         %path = %path @ "RT";
+      else      
+         continue;
+   }
+   else if(%device $= "Keyboard" || %device $= "Mouse")
+   {
+      %pathBase = "data/ui/images/Inputs/Keyboard & Mouse/Keyboard_Black_";
+      %path = %pathBase @ %button @ ".png";
+      if(!isFile(%path))
+         %path = %pathBase @ "Blank";
+   }
+   else if(%device !$= "")
+   {
+      %path = "data/ui/images/inputs/Xbox/Xbox_";
+      
+      %path = %path @ %button;
+   }
+   
+   return %path;
+}