Преглед на файлове

GuiGameListMenuCtrl Update
Methods to simplify managing localized option lists.
Adds a text key to each option in an option row.
Adds methods for getting the current selections index or key value.
Adds methods for setting the current selection by index or key value.
This change is backward compatible. If the new methods are not called, the control behavior is unaffected.

OTHGMars преди 4 години
родител
ревизия
666065ce6c
променени са 2 файла, в които са добавени 189 реда и са изтрити 9 реда
  1. 137 7
      Engine/source/gui/controls/guiGameListMenuCtrl.cpp
  2. 52 2
      Engine/source/gui/controls/guiGameListMenuCtrl.h

+ 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();