Browse Source

Merge pull request #596 from OTHGMars/menuControl

GuiGameListMenuCtrl Update
Jeff Hutchinson 3 years ago
parent
commit
9c243bc5e2

+ 137 - 7
Engine/source/gui/controls/guiGameListMenuCtrl.cpp

@@ -237,7 +237,7 @@ void GuiGameListMenuCtrl::onRenderListOption(Row* row, Point2I currentOffset)
 
       // calculate text to be at the center between the arrows
       GFont* font = profile->mFont;
-      StringTableEntry text = row->mOptions[row->mSelectedOption];
+      StringTableEntry text = row->mOptions[row->mSelectedOption].mDisplayText;
       S32 textWidth = font->getStrWidth(text);
       S32 columnWidth = profile->mHitAreaLowerRight.x * xScale - profile->mRightPad - columnSplit;
       S32 columnCenter = columnSplit + (columnWidth >> 1);
@@ -489,15 +489,18 @@ void GuiGameListMenuCtrl::addRow(const char* label, const char* optionsList, boo
 {
    static StringTableEntry DELIM = StringTable->insert("\t", true);
    Row* row = new Row();
-   Vector<StringTableEntry> options(__FILE__, __LINE__);
+   Vector<OptionEntry> options(__FILE__, __LINE__);
 
    S32 defaultOption = 0;
 
    S32 count = StringUnit::getUnitCount(optionsList, DELIM);
    for (S32 i = 0; i < count; ++i)
    {
+      OptionEntry e;
       const char* option = StringUnit::getUnit(optionsList, i, DELIM);
-      options.push_back(StringTable->insert(option, true));
+      e.mDisplayText = StringTable->insert(option, true);
+      e.mKeyString = e.mDisplayText;
+      options.push_back(e);
 
       if (String::compare(option, defaultValue) == 0)
          defaultOption = options.size() - 1;
@@ -1075,12 +1078,38 @@ StringTableEntry GuiGameListMenuCtrl::getCurrentOption(S32 rowIndex) const
       Row* row = (Row*)mRows[rowIndex];
       if (row->mSelectedOption != NO_OPTION)
       {
-         return row->mOptions[row->mSelectedOption];
+         return row->mOptions[row->mSelectedOption].mDisplayText;
       }
    }
    return StringTable->insert("", false);
 }
 
+StringTableEntry GuiGameListMenuCtrl::getCurrentOptionKey(S32 rowIndex) const
+{
+   if (isValidRowIndex(rowIndex))
+   {
+      Row* row = (Row*)mRows[rowIndex];
+      if (row->mSelectedOption != NO_OPTION)
+      {
+         return row->mOptions[row->mSelectedOption].mKeyString;
+      }
+   }
+   return StringTable->insert("", false);
+}
+
+S32 GuiGameListMenuCtrl::getCurrentOptionIndex(S32 rowIndex) const
+{
+   if (isValidRowIndex(rowIndex))
+   {
+      Row* row = (Row*)mRows[rowIndex];
+      if (row->mSelectedOption != NO_OPTION)
+      {
+         return row->mSelectedOption;
+      }
+   }
+   return S32(-1);
+}
+
 bool GuiGameListMenuCtrl::selectOption(S32 rowIndex, const char* theOption)
 {
    if (!isValidRowIndex(rowIndex))
@@ -1090,9 +1119,9 @@ bool GuiGameListMenuCtrl::selectOption(S32 rowIndex, const char* theOption)
 
    Row* row = (Row*)mRows[rowIndex];
 
-   for (Vector<StringTableEntry>::iterator anOption = row->mOptions.begin(); anOption < row->mOptions.end(); ++anOption)
+   for (Vector<OptionEntry>::iterator anOption = row->mOptions.begin(); anOption < row->mOptions.end(); ++anOption)
    {
-      if (String::compare(*anOption, theOption) == 0)
+      if (String::compare((*anOption).mDisplayText, theOption) == 0)
       {
          S32 newIndex = anOption - row->mOptions.begin();
          row->mSelectedOption = newIndex;
@@ -1103,6 +1132,45 @@ bool GuiGameListMenuCtrl::selectOption(S32 rowIndex, const char* theOption)
    return false;
 }
 
+bool GuiGameListMenuCtrl::selectOptionByKey(S32 rowIndex, const char* optionKey)
+{
+   if (!isValidRowIndex(rowIndex))
+   {
+      return false;
+   }
+
+   Row* row = (Row*)mRows[rowIndex];
+
+   for (Vector<OptionEntry>::iterator anOption = row->mOptions.begin(); anOption < row->mOptions.end(); ++anOption)
+   {
+      if (String::compare((*anOption).mKeyString, optionKey) == 0)
+      {
+         S32 newIndex = anOption - row->mOptions.begin();
+         row->mSelectedOption = newIndex;
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool GuiGameListMenuCtrl::selectOptionByIndex(S32 rowIndex, S32 optionIndex)
+{
+   if (!isValidRowIndex(rowIndex) || (optionIndex < 0))
+   {
+      return false;
+   }
+
+   Row* row = (Row*)mRows[rowIndex];
+   if (optionIndex < row->mOptions.size())
+   {
+      row->mSelectedOption = optionIndex;
+      return true;
+   }
+
+   return false;
+}
+
 void GuiGameListMenuCtrl::setOptions(S32 rowIndex, const char* optionsList)
 {
    static StringTableEntry DELIM = StringTable->insert("\t", true);
@@ -1119,7 +1187,10 @@ void GuiGameListMenuCtrl::setOptions(S32 rowIndex, const char* optionsList)
    for (S32 i = 0; i < count; ++i)
    {
       const char* option = StringUnit::getUnit(optionsList, i, DELIM);
-      row->mOptions[i] = StringTable->insert(option, true);
+      OptionEntry e;
+      e.mDisplayText = StringTable->insert(option, true);
+      e.mKeyString = e.mDisplayText;
+      row->mOptions[i] = e;
    }
 
    if (row->mSelectedOption >= row->mOptions.size())
@@ -1128,6 +1199,21 @@ void GuiGameListMenuCtrl::setOptions(S32 rowIndex, const char* optionsList)
    }
 }
 
+void GuiGameListMenuCtrl::addOption(S32 rowIndex, const char* displayText, const char* keyText)
+{
+   if (!isValidRowIndex(rowIndex))
+   {
+      return;
+   }
+
+   OptionEntry e;
+   e.mDisplayText = StringTable->insert(displayText, true);
+   e.mKeyString = (keyText[0] == '\0') ? e.mDisplayText : StringTable->insert(keyText, true);
+
+   Row* row = (Row*)mRows[rowIndex];
+   row->mOptions.push_back(e);
+}
+
 void GuiGameListMenuCtrl::clickOption(Row* row, S32 xPos)
 {
    GuiGameListMenuProfile* profile = (GuiGameListMenuProfile*)mProfile;
@@ -1566,6 +1652,22 @@ DefineEngineMethod(GuiGameListMenuCtrl, getCurrentOption, const char*, (S32 row)
    return object->getCurrentOption(row);
 }
 
+DefineEngineMethod(GuiGameListMenuCtrl, getCurrentOptionKey, const char*, (S32 row), ,
+   "Gets the key string for the currently selected option of the given row.\n\n"
+   "@param row Index of the row to get the option from.\n"
+   "@return The key (or id) that was assigned to the selected option on the given row. If there is no selected option then the empty string is returned.")
+{
+   return object->getCurrentOptionKey(row);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, getCurrentOptionIndex, S32, (S32 row), ,
+   "Gets the index into the option list for the currently selected option of the given row.\n\n"
+   "@param row Index of the row to get the option from.\n"
+   "@return The index of the selected option on the given row. If there is no selected option then -1 is returned.")
+{
+   return object->getCurrentOptionIndex(row);
+}
+
 DefineEngineMethod(GuiGameListMenuCtrl, selectOption, bool, (S32 row, const char* option), ,
    "Set the row's current option to the one specified\n\n"
    "@param row Index of the row to set an option on.\n"
@@ -1575,6 +1677,24 @@ DefineEngineMethod(GuiGameListMenuCtrl, selectOption, bool, (S32 row, const char
    return object->selectOption(row, option);
 }
 
+DefineEngineMethod(GuiGameListMenuCtrl, selectOptionByKey, bool, (S32 row, const char* optionKey), ,
+   "Set the row's current option to the one with the specified key.\n\n"
+   "@param row Index of the row to set an option on.\n"
+   "@param optionKey The key string that was assigned to the option to be made active.\n"
+   "@return True if the row contained the key and the option and was set, false otherwise.")
+{
+   return object->selectOptionByKey(row, optionKey);
+}
+
+DefineEngineMethod(GuiGameListMenuCtrl, selectOptionByIndex, bool, (S32 row, S32 optionIndex), ,
+   "Set the row's current option to the one at the specified index.\n\n"
+   "@param row Index of the row to set an option on.\n"
+   "@param optionIndex The index of the option to be made active.\n"
+   "@return True if the index was valid and the option and was set, false otherwise.")
+{
+   return object->selectOptionByIndex(row, optionIndex);
+}
+
 DefineEngineMethod(GuiGameListMenuCtrl, setOptions, void, (S32 row, const char* optionsList), ,
    "Sets the list of options on the given row.\n\n"
    "@param row Index of the row to set options on."
@@ -1583,6 +1703,16 @@ DefineEngineMethod(GuiGameListMenuCtrl, setOptions, void, (S32 row, const char*
    object->setOptions(row, optionsList);
 }
 
+DefineEngineMethod(GuiGameListMenuCtrl, addOption, void, (S32 row, const char* displayText, const char* keyText), (""),
+   "Adds an option to the list of options on the given row.\n\n"
+   "@param row Index of the row to add the option on.\n"
+   "@param displayText The text to display for this option.\n"
+   "@param keyText [Optional] The id string to associate with this value. "
+   "If unset, the id will be the same as the display text.\n")
+{
+   object->addOption(row, displayText, keyText);
+}
+
 DefineEngineMethod(GuiGameListMenuCtrl, getValue, F32, (S32 row), ,
    "Sets the list of options on the given row.\n\n"
    "@param row Index of the row to set options on."

+ 52 - 2
Engine/source/gui/controls/guiGameListMenuCtrl.h

@@ -37,6 +37,18 @@ public:
    typedef GuiGameListMenuProfile Profile;
 
 protected:
+
+   /// \struct OptionEntry
+   /// Display text and ID key for each entry in an option row.
+   struct OptionEntry
+   {
+      StringTableEntry mDisplayText;   ///< The text that is displayed for the option
+      StringTableEntry mKeyString;     ///< Key value that is associated with this option
+      OptionEntry() : mDisplayText(StringTable->EmptyString()), mKeyString(StringTable->EmptyString()) {}
+      virtual ~OptionEntry() {}
+   };
+
+
    /// \struct Row
    /// Internal data representation of a single row in the control.
    struct Row
@@ -60,7 +72,7 @@ protected:
       Mode mMode;
 
       //List options
-      Vector<StringTableEntry>   mOptions;         ///< Collection of options available to display
+      Vector<OptionEntry>        mOptions;         ///< Collection of options available to display
       S32                        mSelectedOption;  ///< Index into mOptions pointing at the selected option
       bool                       mWrapOptions;     ///< Determines if options should "wrap around" at the ends
 
@@ -174,13 +186,43 @@ public:
    /// string is returned.
    StringTableEntry getCurrentOption(S32 rowIndex) const;
 
+   /// Gets the key string for the currently selected option of the given row
+   ///
+   /// \param rowIndex Index of the row to get the option from.
+   /// \return The key (or id) that was assigned to the selected option on the
+   ///  given row. If there is no selected option then the empty string is returned.
+   StringTableEntry getCurrentOptionKey(S32 rowIndex) const;
+
+   /// Gets the index into the option list for the currently selected option of the given row.
+   ///
+   /// \param rowIndex Index of the row to get the option from.
+   /// \return The index of the selected option on the given row. If there is no
+   /// selected option then -1 is returned.
+   S32 getCurrentOptionIndex(S32 rowIndex) const;
+
    /// Attempts to set the given row to the specified selected option. The option
    /// will only be set if the option exists in the control.
    ///
    /// \param rowIndex Index of the row to set an option on.
    /// \param option The option to be made active.
    /// \return True if the row contained the option and was set, false otherwise.
-   bool selectOption(S32 rowIndex, StringTableEntry option);
+   bool selectOption(S32 rowIndex, const char* option);
+
+   /// Attempts to set the given row to the option with the specified key. The
+   /// option will only be set if the key exists in the control.
+   ///
+   /// \param rowIndex Index of the row to set an option on.
+   /// \param optionKey The key string that was assigned to the option to be made active.
+   /// \return True if the row contained the key and the option and was set, false otherwise.
+   bool selectOptionByKey(S32 rowIndex, const char* optionKey);
+
+   /// Attempts to set the given row to the option at the specified index. The option
+   /// will only be set if the index is valid.
+   ///
+   /// \param rowIndex Index of the row to set an option on.
+   /// \param optionIndex The index of the option to be made active.
+   /// \return True if the index was valid and the option and was set, false otherwise.
+   bool selectOptionByIndex(S32 rowIndex, S32 optionIndex);
 
    /// Sets the list of options on the given row.
    ///
@@ -188,6 +230,14 @@ public:
    /// \param optionsList A tab separated list of options for the control.
    void setOptions(S32 rowIndex, const char* optionsList);
 
+   /// Adds an option to the list of options on the given row.
+   ///
+   /// \param rowIndex Index of the row to set options on.
+   /// \param displayText The text to display for this option.
+   /// \param keyText The id string to associate with this value. If NULL the
+   ///  id will be the same as the display text.
+   void addOption(S32 rowIndex, const char* displayText, const char* keyText);
+
    /// Activates the current row. The script callback of  the current row will
    /// be called (if it has one).
    virtual void activateRow();