Преглед изворни кода

Expanded functionality of the guiPopupCtrlEx to support search filtering

Areloch пре 1 година
родитељ
комит
4f399eb87f
2 измењених фајлова са 105 додато и 28 уклоњено
  1. 94 25
      Engine/source/gui/controls/guiPopUpCtrlEx.cpp
  2. 11 3
      Engine/source/gui/controls/guiPopUpCtrlEx.h

+ 94 - 25
Engine/source/gui/controls/guiPopUpCtrlEx.cpp

@@ -157,7 +157,7 @@ bool GuiPopupTextListCtrlEx::hasCategories()
 {
    for( S32 i = 0; i < mList.size(); i++)
    {
-      if( mList[i].id == -1)
+      if( mList[i].id < 0)
          return true;
    }
 
@@ -202,7 +202,7 @@ void GuiPopupTextListCtrlEx::onMouseUp(const GuiEvent &event)
 
    if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
    {
-      if (mList[cell.y].id == -1)
+      if (mList[cell.y].id < 0)
          return;
    }
 
@@ -266,7 +266,7 @@ void GuiPopupTextListCtrlEx::onRenderCell(Point2I offset, Point2I cell, bool sel
    }
 
    // Render 'Group' background
-   if ( mList[cell.y].id == -1)
+   if ( mList[cell.y].id == -2)
    {
       RectI cellR( offset.x, offset.y, size.x, size.y );
       GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL );
@@ -298,7 +298,7 @@ void GuiPopupTextListCtrlEx::onRenderCell(Point2I offset, Point2I cell, bool sel
 
    } else
    {
-      if ((mList[cell.y].id == -1) || (!hasCategories()))
+      if ((mList[cell.y].id == -2) || (!hasCategories()))
          GFX->getDrawUtil()->drawText( mFont, Point2I( textXOffset, offset.y ), mList[cell.y].text ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
       else
          GFX->getDrawUtil()->drawText( mFont, Point2I( textXOffset + 8, offset.y ), mList[cell.y].text ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
@@ -339,6 +339,8 @@ GuiPopUpMenuCtrlEx::GuiPopUpMenuCtrlEx(void)
    mTl = NULL;
    mSc = NULL;
    mReplaceText = false;
+   mTextSearchItems = false;
+   mSearchEdit = nullptr;
 }
 
 //------------------------------------------------------------------------------
@@ -361,6 +363,8 @@ void GuiPopUpMenuCtrlEx::initPersistFields(void)
    addField("hotTrackCallback",         TypeBool,         Offset(mHotTrackItems, GuiPopUpMenuCtrlEx),
       "Whether to provide a 'onHotTrackItem' callback when a list item is hovered over");
 
+   addField("allowTextSearch", TypeBool, Offset(mTextSearchItems, GuiPopUpMenuCtrlEx), "If true, will enable a text edit field so you can search filter the dropdown list");
+
    Parent::initPersistFields();
 }
 
@@ -395,7 +399,7 @@ DefineEngineMethod( GuiPopUpMenuCtrlEx, addCategory, void, (const char* text),,
 
                "@param text Name of the new category\n\n")
 {
-   object->addEntry(text, -1, 0);
+   object->addEntry(text, -2, 0);
 }
 
 DefineEngineMethod( GuiPopUpMenuCtrlEx, addScheme, void, (S32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL),,
@@ -671,6 +675,14 @@ DefineEngineMethod( GuiPopUpMenuCtrlEx, replaceText, void, (S32 boolVal), ,
    object->replaceText(boolVal);
 }
 
+//------------------------------------------------------------------------------
+DefineEngineMethod(GuiPopUpMenuCtrlEx, setSearchText, void, (const char* searchText), (""),
+   "@brief Flag that causes each new text addition to replace the current entry\n\n"
+   "@param True to turn on replacing, false to disable it")
+{
+   object->setSearchText(searchText);
+}
+
 //------------------------------------------------------------------------------
 //  Added
 bool GuiPopUpMenuCtrlEx::onWake()
@@ -690,6 +702,14 @@ bool GuiPopUpMenuCtrlEx::onWake()
    return true;
 }
 
+void GuiPopUpMenuCtrlEx::onRemove()
+{
+   mBackground = nullptr;
+   mSearchEdit = nullptr;
+   mTl = nullptr;
+   mSc = nullptr;
+   mBackground = nullptr;
+}
 //------------------------------------------------------------------------------
 bool GuiPopUpMenuCtrlEx::onAdd()
 {
@@ -697,6 +717,9 @@ bool GuiPopUpMenuCtrlEx::onAdd()
       return false;
    mSelIndex = -1;
    mReplaceText = true;
+
+   addChildren();
+
    return true;
 }
 
@@ -921,7 +944,7 @@ void GuiPopUpMenuCtrlEx::addScheme( U32 id, ColorI fontColor, ColorI fontColorHL
 //------------------------------------------------------------------------------
 S32 GuiPopUpMenuCtrlEx::getSelected()
 {
-   if (mSelIndex == -1)
+   if (mSelIndex < 0)
       return 0;
    return mEntries[mSelIndex].id;
 }
@@ -982,7 +1005,7 @@ void GuiPopUpMenuCtrlEx::setSelected(S32 id, bool bNotifyScript )
    if ( isMethod( "onCancel" ) && bNotifyScript )
       Con::executef( this, "onCancel" );
 
-   if ( id == -1 )
+   if ( id < 0 )
       return;
 
    // Execute the popup console command:
@@ -1306,8 +1329,16 @@ void GuiPopUpMenuCtrlEx::closePopUp()
    if ( mSelIndex != -1 )
    {
       if ( mReplaceText )
-         setText( mEntries[mSelIndex].buf );
-      setIntVariable( mEntries[mSelIndex].id );
+         setText(mTl->mList[mSelIndex].text);
+
+      for(U32 i=0; i < mEntries.size(); i++)
+      {
+        if(dStrcmp(mEntries[i].buf,mTl->mList[mSelIndex].text) == 0)
+        {
+           setIntVariable(mEntries[i].id);
+            break;
+         }
+      }
    }
 
    // Release the mouse:
@@ -1357,10 +1388,12 @@ void GuiPopUpMenuCtrlEx::closePopUp()
       root->popDialogControl(mBackground);
 
    // Kill the popup:
-   mBackground->removeObject( mSc );
-   mTl->deleteObject();
-   mSc->deleteObject();
-   mBackground->deleteObject();
+   //mBackground->removeObject( mSc );
+   //mTl->deleteObject();
+   //mSc->deleteObject();
+   //mBackground->deleteObject();
+
+   //mSearchEdit->deleteObject();
 
    // Set this as the first responder:
    setFirstResponder();
@@ -1392,8 +1425,6 @@ void GuiPopUpMenuCtrlEx::onAction()
 
    GuiControl *canCtrl = getParent();
 
-   addChildren();
-
    GuiCanvas *root = getRoot();
    Point2I windowExt = root->getExtent();
 
@@ -1424,9 +1455,21 @@ void GuiPopUpMenuCtrlEx::onAction()
 
    //mTl->setCellSize(Point2I(width, mFont->getHeight()+3));
    mTl->setCellSize(Point2I(width, mProfile->mFont->getHeight() + textSpace)); //  Modified the above line to use textSpace rather than the '3' as this is what is used below.
+   mTl->clear();
 
-   for ( U32 j = 0; j < mEntries.size(); ++j )
-      mTl->addEntry( mEntries[j].id, mEntries[j].buf );
+   for (U32 j = 0; j < mEntries.size(); ++j)
+   {
+      if(mSearchText != String::EmptyString)
+      {
+         String entryText = String::ToLower(mEntries[j].buf);
+         if (entryText.find(mSearchText) != -1 && mEntries[j].id != -2)
+            mTl->addEntry(mEntries[j].id, mEntries[j].buf);
+      }
+      else
+      {
+         mTl->addEntry(mEntries[j].id, mEntries[j].buf);
+      }
+   }
 
    if ( mSelIndex >= 0 )
       mTl->setSelectedCell( Point2I( 0, mSelIndex ) );
@@ -1507,13 +1550,6 @@ void GuiPopUpMenuCtrlEx::onAction()
    newBounds.extent.set( width, maxYdis );
    mSc->setBounds( newBounds ); //  Not sure why the '-1' above.
 
-   mSc->registerObject();
-   mTl->registerObject();
-   mBackground->registerObject();
-
-   mSc->addObject( mTl );
-   mBackground->addObject( mSc );
-
    mBackgroundCancel = false; //  Setup check if user clicked on the background instead of the text list (ie: didn't want to change their current selection).
 
    root->pushDialogControl( mBackground, 99 );
@@ -1536,6 +1572,22 @@ void GuiPopUpMenuCtrlEx::onAction()
    mTl->setFirstResponder();
 
    mInAction = true;
+
+   if(mTextSearchItems)
+   {
+      mSearchEdit->resize(pointInGC, Point2I(getExtent().x - 20, getExtent().y));
+
+      mSearchEdit->setFirstResponder();
+
+      mSearchEdit->setText(mSearchText.c_str());     
+
+      // 
+      char searchCommandBuffer[512];
+      dSprintf(searchCommandBuffer, sizeof(searchCommandBuffer), "%s.setSearchText(%s.getText());",
+         getIdString(), mSearchEdit->getIdString());
+
+      mSearchEdit->setConsoleCommand(searchCommandBuffer);
+   }
 }
 
 //------------------------------------------------------------------------------
@@ -1566,6 +1618,23 @@ void GuiPopUpMenuCtrlEx::addChildren()
 
    mBackground = new GuiPopUpBackgroundCtrlEx( this, mTl );
    AssertFatal( mBackground, "Failed to create the GuiBackgroundCtrlEx for the PopUpMenu" );
+
+   mSearchEdit = new GuiTextEditCtrl;
+   AssertFatal(mSearchEdit, "Failed to create the GuiTextEditCtrl for the PopUpMenu");
+   GuiControlProfile* searchEditProf;
+   if (Sim::findObject("ToolsGuiTextEditCtrl", searchEditProf))
+   {
+      mSearchEdit->setControlProfile(prof);
+   }
+
+   mSc->registerObject();
+   mTl->registerObject();
+   mBackground->registerObject();
+   mSearchEdit->registerObject();
+
+   mSc->addObject(mTl);
+   mBackground->addObject(mSc);
+   mBackground->addObject(mSearchEdit);
 }
 
 //------------------------------------------------------------------------------
@@ -1621,7 +1690,7 @@ bool GuiPopUpMenuCtrlEx::getFontColor( ColorI &fontColor, S32 id, bool selected,
       }
    }
 
-   if(id == -1)
+   if(id < 0)
       fontColor = mProfile->mFontColorHL;
    else
    // Default color scheme...

+ 11 - 3
Engine/source/gui/controls/guiPopUpCtrlEx.h

@@ -35,6 +35,7 @@
 #ifndef _GUISCROLLCTRL_H_
 #include "gui/containers/guiScrollCtrl.h"
 #endif
+#include "guiTextEditCtrl.h"
 class GuiPopUpMenuCtrlEx;
 class GuiPopupTextListCtrlEx;
 
@@ -118,6 +119,8 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
    bool mRenderScrollInNA; //  Added
    bool mReverseTextList;	//  Added - Should we reverse the text list if we display up?
    bool mHotTrackItems;
+   bool mTextSearchItems;
+   String mSearchText;
 
    enum BitmapModes
    {
@@ -134,6 +137,8 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
 
 	S32 mIdMax;
 
+   GuiTextEditCtrl* mSearchEdit; //  Added
+
    virtual void addChildren();
    virtual void repositionPopup();
 
@@ -143,9 +148,10 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
    GuiPopUpMenuCtrlEx(void);
    ~GuiPopUpMenuCtrlEx();   
    GuiScrollCtrl::Region mScrollDir;
-   bool onWake(); //  Added
-   bool onAdd();
-   void onSleep();
+   virtual bool onWake(); //  Added
+   virtual void onRemove();
+   virtual bool onAdd();
+   virtual void onSleep();
    void setBitmap(const char *name); //  Added
    void sort();
    void sortID(); //  Added
@@ -176,6 +182,8 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
    S32 findText( const char* text );
    S32 getNumEntries()   { return( mEntries.size() ); }
    void replaceText(S32);
+
+   void setSearchText(String searchTxt) { mSearchText = String::ToLower(searchTxt); onAction();  }
    
    DECLARE_CONOBJECT(GuiPopUpMenuCtrlEx);
    DECLARE_CATEGORY( "Gui Lists" );