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++)
{
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...

View file

@ -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" );