Expanded functionality of the guiPopupCtrlEx to support search filtering

This commit is contained in:
Areloch 2023-12-25 17:00:51 -06:00
parent 4c58a3601f
commit 4f399eb87f
2 changed files with 105 additions and 28 deletions

View file

@ -157,7 +157,7 @@ bool GuiPopupTextListCtrlEx::hasCategories()
{ {
for( S32 i = 0; i < mList.size(); i++) for( S32 i = 0; i < mList.size(); i++)
{ {
if( mList[i].id == -1) if( mList[i].id < 0)
return true; 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 (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; return;
} }
@ -266,7 +266,7 @@ void GuiPopupTextListCtrlEx::onRenderCell(Point2I offset, Point2I cell, bool sel
} }
// Render 'Group' background // 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 ); RectI cellR( offset.x, offset.y, size.x, size.y );
GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL ); GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL );
@ -298,7 +298,7 @@ void GuiPopupTextListCtrlEx::onRenderCell(Point2I offset, Point2I cell, bool sel
} else } 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'. 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 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'. 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; mTl = NULL;
mSc = NULL; mSc = NULL;
mReplaceText = false; mReplaceText = false;
mTextSearchItems = false;
mSearchEdit = nullptr;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -361,6 +363,8 @@ void GuiPopUpMenuCtrlEx::initPersistFields(void)
addField("hotTrackCallback", TypeBool, Offset(mHotTrackItems, GuiPopUpMenuCtrlEx), addField("hotTrackCallback", TypeBool, Offset(mHotTrackItems, GuiPopUpMenuCtrlEx),
"Whether to provide a 'onHotTrackItem' callback when a list item is hovered over"); "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(); Parent::initPersistFields();
} }
@ -395,7 +399,7 @@ DefineEngineMethod( GuiPopUpMenuCtrlEx, addCategory, void, (const char* text),,
"@param text Name of the new category\n\n") "@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),, 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); 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 // Added
bool GuiPopUpMenuCtrlEx::onWake() bool GuiPopUpMenuCtrlEx::onWake()
@ -690,6 +702,14 @@ bool GuiPopUpMenuCtrlEx::onWake()
return true; return true;
} }
void GuiPopUpMenuCtrlEx::onRemove()
{
mBackground = nullptr;
mSearchEdit = nullptr;
mTl = nullptr;
mSc = nullptr;
mBackground = nullptr;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool GuiPopUpMenuCtrlEx::onAdd() bool GuiPopUpMenuCtrlEx::onAdd()
{ {
@ -697,6 +717,9 @@ bool GuiPopUpMenuCtrlEx::onAdd()
return false; return false;
mSelIndex = -1; mSelIndex = -1;
mReplaceText = true; mReplaceText = true;
addChildren();
return true; return true;
} }
@ -921,7 +944,7 @@ void GuiPopUpMenuCtrlEx::addScheme( U32 id, ColorI fontColor, ColorI fontColorHL
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
S32 GuiPopUpMenuCtrlEx::getSelected() S32 GuiPopUpMenuCtrlEx::getSelected()
{ {
if (mSelIndex == -1) if (mSelIndex < 0)
return 0; return 0;
return mEntries[mSelIndex].id; return mEntries[mSelIndex].id;
} }
@ -982,7 +1005,7 @@ void GuiPopUpMenuCtrlEx::setSelected(S32 id, bool bNotifyScript )
if ( isMethod( "onCancel" ) && bNotifyScript ) if ( isMethod( "onCancel" ) && bNotifyScript )
Con::executef( this, "onCancel" ); Con::executef( this, "onCancel" );
if ( id == -1 ) if ( id < 0 )
return; return;
// Execute the popup console command: // Execute the popup console command:
@ -1306,8 +1329,16 @@ void GuiPopUpMenuCtrlEx::closePopUp()
if ( mSelIndex != -1 ) if ( mSelIndex != -1 )
{ {
if ( mReplaceText ) if ( mReplaceText )
setText( mEntries[mSelIndex].buf ); setText(mTl->mList[mSelIndex].text);
setIntVariable( mEntries[mSelIndex].id );
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: // Release the mouse:
@ -1357,10 +1388,12 @@ void GuiPopUpMenuCtrlEx::closePopUp()
root->popDialogControl(mBackground); root->popDialogControl(mBackground);
// Kill the popup: // Kill the popup:
mBackground->removeObject( mSc ); //mBackground->removeObject( mSc );
mTl->deleteObject(); //mTl->deleteObject();
mSc->deleteObject(); //mSc->deleteObject();
mBackground->deleteObject(); //mBackground->deleteObject();
//mSearchEdit->deleteObject();
// Set this as the first responder: // Set this as the first responder:
setFirstResponder(); setFirstResponder();
@ -1392,8 +1425,6 @@ void GuiPopUpMenuCtrlEx::onAction()
GuiControl *canCtrl = getParent(); GuiControl *canCtrl = getParent();
addChildren();
GuiCanvas *root = getRoot(); GuiCanvas *root = getRoot();
Point2I windowExt = root->getExtent(); Point2I windowExt = root->getExtent();
@ -1424,9 +1455,21 @@ void GuiPopUpMenuCtrlEx::onAction()
//mTl->setCellSize(Point2I(width, mFont->getHeight()+3)); //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->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 ) for (U32 j = 0; j < mEntries.size(); ++j)
mTl->addEntry( mEntries[j].id, mEntries[j].buf ); {
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 ) if ( mSelIndex >= 0 )
mTl->setSelectedCell( Point2I( 0, mSelIndex ) ); mTl->setSelectedCell( Point2I( 0, mSelIndex ) );
@ -1507,13 +1550,6 @@ void GuiPopUpMenuCtrlEx::onAction()
newBounds.extent.set( width, maxYdis ); newBounds.extent.set( width, maxYdis );
mSc->setBounds( newBounds ); // Not sure why the '-1' above. 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). 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 ); root->pushDialogControl( mBackground, 99 );
@ -1536,6 +1572,22 @@ void GuiPopUpMenuCtrlEx::onAction()
mTl->setFirstResponder(); mTl->setFirstResponder();
mInAction = true; 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 ); mBackground = new GuiPopUpBackgroundCtrlEx( this, mTl );
AssertFatal( mBackground, "Failed to create the GuiBackgroundCtrlEx for the PopUpMenu" ); 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; fontColor = mProfile->mFontColorHL;
else else
// Default color scheme... // Default color scheme...

View file

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