Updates the field types used in the editor to utilize the GuiPopUpMenuCtrlEx to make them support categories and be able to search filter them

Updates the dataBlock field type to properly present categorized listings
Expands the datablock Field to have an edit and add buttons on the field to make the workflow simpler
Adds utility functions to GuiPopUpMenuCtrlEx to control indentation, categories and searchability
Expands datablock editor functionality to be able to create a datablock of a type to pre-set the inheritFrom param of the process early(used for the add new button on DB fields to carry-through the current DB to the creation process of a derivative)
This commit is contained in:
Areloch 2024-02-03 16:10:28 -06:00
parent efffabae06
commit d952722811
7 changed files with 205 additions and 35 deletions

View file

@ -855,7 +855,7 @@ void GuiPopUpMenuCtrlEx::sortID()
}
//------------------------------------------------------------------------------
void GuiPopUpMenuCtrlEx::addEntry(const char *buf, S32 id, U32 scheme)
void GuiPopUpMenuCtrlEx::addEntry(const char *buf, S32 id, U32 scheme, const bool& intented)
{
if( !buf )
{
@ -882,6 +882,7 @@ void GuiPopUpMenuCtrlEx::addEntry(const char *buf, S32 id, U32 scheme)
dStrcpy( e.buf, buf, 256 );
e.id = id;
e.scheme = scheme;
e.indented = intented;
// see if there is a shortcut key
char * cp = dStrchr( e.buf, '~' );
@ -1326,8 +1327,8 @@ void GuiPopUpMenuCtrlEx::closePopUp()
mSelIndex = ( mRevNum >= mSelIndex && mSelIndex != -1 ) ? mRevNum - mSelIndex : mSelIndex;
if ( mSelIndex != -1 )
{
if ( mReplaceText )
setText(mTl->mList[mSelIndex].text);
if (mReplaceText)
setText(mEntries[mSelIndex].buf);
for(U32 i=0; i < mEntries.size(); i++)
{
@ -1465,7 +1466,12 @@ void GuiPopUpMenuCtrlEx::onAction()
}
else
{
mTl->addEntry(mEntries[j].id, mEntries[j].buf);
String entryText = mEntries[j].buf;
if(mEntries[j].indented)
entryText = String(" ") + entryText;
mTl->addEntry(mEntries[j].id, entryText.c_str());
}
}

View file

@ -86,8 +86,9 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
S32 id;
U16 ascii;
U16 scheme;
bool usesColorBox; // Added
ColorI colorbox; // Added
bool usesColorBox; // Added
ColorI colorbox; // Added
bool indented; // Added
};
struct Scheme
@ -156,7 +157,11 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
void setBitmap(const char *name); // Added
void sort();
void sortID(); // Added
void addEntry(const char *buf, S32 id = -1, U32 scheme = 0);
void addEntry(const char *buf, S32 id = -1, U32 scheme = 0, const bool& indented = false);
void addCategory(const char *buf)
{
addEntry(buf, -2, 0);
}
void addScheme(U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL);
void onRender(Point2I offset, const RectI &updateRect);
void onAction();
@ -184,6 +189,7 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl
S32 getNumEntries() { return( mEntries.size() ); }
void replaceText(S32);
void setCanSearch(const bool& canSearch) { mTextSearchItems = canSearch; }
void setSearchText(String searchTxt) { mSearchText = String::ToLower(searchTxt); onAction(); }
DECLARE_CONOBJECT(GuiPopUpMenuCtrlEx);

View file

@ -56,9 +56,9 @@ ConsoleDocClass( GuiInspectorTypeMenuBase,
GuiControl* GuiInspectorTypeMenuBase::constructEditControl()
{
GuiControl* retCtrl = new GuiPopUpMenuCtrl();
GuiControl* retCtrl = new GuiPopUpMenuCtrlEx();
GuiPopUpMenuCtrl *menu = dynamic_cast<GuiPopUpMenuCtrl*>(retCtrl);
GuiPopUpMenuCtrlEx *menu = dynamic_cast<GuiPopUpMenuCtrlEx*>(retCtrl);
// Let's make it look pretty.
retCtrl->setDataField( StringTable->insert("profile"), NULL, "ToolsGuiPopupMenuProfile" );
@ -89,7 +89,7 @@ void GuiInspectorTypeMenuBase::setValue( StringTableEntry newValue )
ctrl->setText( newValue );
}
void GuiInspectorTypeMenuBase::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeMenuBase::_populateMenu( GuiPopUpMenuCtrlEx *menu )
{
// do nothing, child classes override this.
}
@ -105,7 +105,7 @@ ConsoleDocClass( GuiInspectorTypeEnum,
"@internal"
);
void GuiInspectorTypeEnum::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeEnum::_populateMenu( GuiPopUpMenuCtrlEx *menu )
{
const EngineEnumTable* table = mField->table;
if( !table )
@ -148,7 +148,7 @@ ConsoleDocClass( GuiInspectorTypeCubemapName,
"@internal"
);
void GuiInspectorTypeCubemapName::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeCubemapName::_populateMenu(GuiPopUpMenuCtrlEx *menu )
{
PROFILE_SCOPE( GuiInspectorTypeCubemapName_populateMenu );
@ -356,7 +356,7 @@ ConsoleDocClass( GuiInspectorTypeGuiProfile,
"@internal"
);
void GuiInspectorTypeGuiProfile::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeGuiProfile::_populateMenu(GuiPopUpMenuCtrlEx *menu )
{
// Check whether we should show profiles from the editor category.
@ -399,7 +399,7 @@ ConsoleDocClass(GuiInspectorTypeActionMap,
"@internal"
);
void GuiInspectorTypeActionMap::_populateMenu(GuiPopUpMenuCtrl* menu)
void GuiInspectorTypeActionMap::_populateMenu(GuiPopUpMenuCtrlEx* menu)
{
// Add the action maps to the menu.
//First add a blank entry so you can clear the action map
@ -1671,7 +1671,7 @@ ConsoleDocClass( GuiInspectorTypeSFXParameterName,
"@internal"
);
void GuiInspectorTypeSFXParameterName::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeSFXParameterName::_populateMenu(GuiPopUpMenuCtrlEx *menu )
{
SimSet* set = Sim::getSFXParameterGroup();
for( SimSet::iterator iter = set->begin(); iter != set->end(); ++ iter )
@ -1703,7 +1703,7 @@ ConsoleDocClass( GuiInspectorTypeSFXStateName,
"@internal"
);
void GuiInspectorTypeSFXStateName::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeSFXStateName::_populateMenu(GuiPopUpMenuCtrlEx *menu )
{
menu->addEntry( "", 0 );
@ -1737,7 +1737,7 @@ ConsoleDocClass( GuiInspectorTypeSFXSourceName,
"@internal"
);
void GuiInspectorTypeSFXSourceName::_populateMenu( GuiPopUpMenuCtrl *menu )
void GuiInspectorTypeSFXSourceName::_populateMenu(GuiPopUpMenuCtrlEx *menu )
{
menu->addEntry( "", 0 );

View file

@ -45,6 +45,7 @@
#ifndef _GUITEXTEDITSLIDERCTRL_H_
#include "gui/controls/guiTextEditSliderCtrl.h"
#endif
#include "gui/controls/guiPopUpCtrlEx.h"
class GuiPopUpMenuCtrl;
@ -63,7 +64,7 @@ public:
//-----------------------------------------------------------------------------
virtual GuiControl* constructEditControl();
virtual void setValue( StringTableEntry newValue );
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu( GuiPopUpMenuCtrlEx *menu );
};
//-----------------------------------------------------------------------------
@ -77,7 +78,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeEnum);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
//-----------------------------------------------------------------------------
@ -91,7 +92,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeCubemapName);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
//--------------------------------------------------------------------------------
@ -129,7 +130,7 @@ public:
GuiInspectorTypeRegularMaterialName() {}
DECLARE_CONOBJECT(GuiInspectorTypeRegularMaterialName);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
//--------------------------------------------------------------------------------
@ -183,7 +184,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeGuiProfile);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
//-----------------------------------------------------------------------------
@ -197,7 +198,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeActionMap);
static void consoleInit();
virtual void _populateMenu(GuiPopUpMenuCtrl* menu);
virtual void _populateMenu(GuiPopUpMenuCtrlEx * menu);
};
//-----------------------------------------------------------------------------
@ -561,7 +562,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXParameterName);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
@ -576,7 +577,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXStateName);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
@ -591,7 +592,7 @@ public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXSourceName);
static void consoleInit();
virtual void _populateMenu( GuiPopUpMenuCtrl *menu );
virtual void _populateMenu(GuiPopUpMenuCtrlEx *menu );
};
//-----------------------------------------------------------------------------

View file

@ -32,6 +32,7 @@
#include "sfx/sfxEnvironment.h"
#include "sfx/sfxAmbience.h"
#include "sfx/sfxTrack.h"
#include "T3D/gameBase/gameBase.h"
//-----------------------------------------------------------------------------
@ -64,30 +65,157 @@ void GuiInspectorDatablockField::setClassName( StringTableEntry className )
}
}
void GuiInspectorDatablockField::_populateMenu( GuiPopUpMenuCtrl* menu )
void GuiInspectorDatablockField::_populateMenu( GuiPopUpMenuCtrlEx* menu )
{
menu->setCanSearch(true);
menu->addScheme( 1, ColorI( 80, 0, 0, 255 ), ColorI( 80, 0, 0, 255 ), ColorI( 80, 0, 0, 255 ) ); // For client-only coloring.
menu->addEntry( "", 0 ); // For unsetting.
SimSet* set = _getDatablockSet();
U32 id = 1;
for( SimSet::iterator iter = set->begin(); iter != set->end(); ++ iter )
//We can do some special filtering here if it's derived from GameBase a la categories
if(mDesiredClass->isSubclassOf(AbstractClassRep::findClassRep("GameBaseData")))
{
SimDataBlock* datablock = dynamic_cast< SimDataBlock* >( *iter );
//First, do categories
Vector<String> categories;
for (SimSet::iterator iter = set->begin(); iter != set->end(); ++iter)
{
SimDataBlock* datablock = dynamic_cast<SimDataBlock*>(*iter);
// Skip non-datablocks if we somehow encounter them.
if (!datablock)
continue;
if (datablock && (!mDesiredClass || datablock->getClassRep()->isClass(mDesiredClass)))
{
GameBaseData *data = dynamic_cast<GameBaseData*>(datablock);
if(data)
{
String category = data->mCategory;
if(category.isNotEmpty() && (categories.empty() || categories.find_next(category) == -1))
categories.push_back(category);
}
}
}
if (categories.size() > 0)
{
categories.push_back("No Category");
//Now that we have our categories, lets populate our list
for (Vector<String>::iterator catIter = categories.begin(); catIter != categories.end(); ++catIter)
{
String categoryName = String::ToLower(catIter->c_str());
if (categoryName != String::EmptyString)
{
menu->addCategory(catIter->c_str());
id++;
}
for (SimSet::iterator iter = set->begin(); iter != set->end(); ++iter)
{
GameBaseData* datablock = dynamic_cast<GameBaseData*>(*iter);
// Skip non-datablocks if we somehow encounter them.
if (!datablock)
continue;
if (datablock && (!mDesiredClass || datablock->getClassRep()->isClass(mDesiredClass)) &&
(String::ToLower(datablock->mCategory) == categoryName || (datablock->mCategory == String::EmptyString && categoryName == String("No Category"))))
{
menu->addEntry(datablock->getName(), id++, datablock->isClientOnly() ? 1 : 0, true);
}
}
}
return;
}
}
for (SimSet::iterator iter = set->begin(); iter != set->end(); ++iter)
{
SimDataBlock* datablock = dynamic_cast<SimDataBlock*>(*iter);
// Skip non-datablocks if we somehow encounter them.
if( !datablock )
if (!datablock)
continue;
// Ok, now we have to figure inheritance info.
if( datablock && ( !mDesiredClass || datablock->getClassRep()->isClass( mDesiredClass ) ) )
menu->addEntry( datablock->getName(), id ++, datablock->isClientOnly() ? 1 : 0 );
if (datablock && (!mDesiredClass || datablock->getClassRep()->isClass(mDesiredClass)))
menu->addEntry(datablock->getName(), id++, datablock->isClientOnly() ? 1 : 0);
}
menu->sort();
}
GuiControl* GuiInspectorDatablockField::constructEditControl()
{
// Create base filename edit controls
GuiControl* retCtrl = Parent::constructEditControl();
if (retCtrl == NULL)
return retCtrl;
char szBuffer[512];
// Create "Open in Editor" button
mEditButton = new GuiButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "DatablockEditorPlugin.openDatablock(%d.getText());", retCtrl->getId());
mEditButton->setField("Command", szBuffer);
mEditButton->setText("...");
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiInspectorButtonProfile");
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Edit this datablock");
mEditButton->registerObject();
addObject(mEditButton);
//Add add button
mAddButton = new GuiBitmapButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "DatablockEditorPlugin.createNewDatablockOfType(%s, %d.getText());", mDesiredClass->getClassName(), retCtrl->getId());
mAddButton->setField("Command", szBuffer);
char addBtnBitmapName[512] = "ToolsModule:iconAdd_Image";
mAddButton->setBitmap(StringTable->insert(addBtnBitmapName));
mAddButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mAddButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mAddButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mAddButton->setDataField(StringTable->insert("tooltip"), NULL, "Create new datablock");
mAddButton->registerObject();
addObject(mAddButton);
return retCtrl;
}
bool GuiInspectorDatablockField::updateRects()
{
S32 dividerPos, dividerMargin;
mInspector->getDivider(dividerPos, dividerMargin);
Point2I fieldExtent = getExtent();
Point2I fieldPos = getPosition();
mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mEditButton != NULL)
{
mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mEditButton->resize(mBrowseRect.point, mBrowseRect.extent);
}
if (mAddButton != NULL)
{
RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
resized |= mAddButton->resize(shapeEdRect.point, shapeEdRect.extent);
}
return resized;
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeSFXDescriptionName

View file

@ -23,6 +23,7 @@
#ifndef _GUI_INSPECTOR_DATABLOCKFIELD_H_
#define _GUI_INSPECTOR_DATABLOCKFIELD_H_
#include "gui/controls/guiPopUpCtrlEx.h"
#include "gui/editor/guiInspectorTypes.h"
@ -38,9 +39,14 @@ class GuiInspectorDatablockField : public GuiInspectorTypeMenuBase
protected:
AbstractClassRep *mDesiredClass;
SimObjectPtr<GuiBitmapButtonCtrl> mAddButton;
SimObjectPtr<GuiButtonCtrl> mEditButton;
RectI mBrowseRect;
virtual SimSet* _getDatablockSet() const { return Sim::getDataBlockSet(); }
virtual void _populateMenu( GuiPopUpMenuCtrl* menu );
virtual void _populateMenu( GuiPopUpMenuCtrlEx* menu );
virtual GuiControl* constructEditControl();
virtual bool updateRects();
public:

View file

@ -629,10 +629,21 @@ function DatablockEditorPlugin::deleteDatablock( %this )
}
//---------------------------------------------------------------------------------------------
function DatablockEditorPlugin::createNewDatablockOfType(%this, %class, %inheritFrom)
{
$DATABLOCK_EDITOR_NEWDB_CLASS = %class;
$DATABLOCK_EDITOR_NEWDB_INHERITFROM = %inheritFrom;
%this.pickDatablockPath();
}
function DatablockEditorPlugin::createDatablock(%this)
{
%class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem());
if($DATABLOCK_EDITOR_NEWDB_CLASS $= "")
%class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem());
else
%class = $DATABLOCK_EDITOR_NEWDB_CLASS;
if( %class !$= "" )
{
// Need to prompt for a name.
@ -659,6 +670,12 @@ function DatablockEditorPlugin::createDatablock(%this)
%list.add( %datablock.getName(), %i + 1 );
}
if($DATABLOCK_EDITOR_NEWDB_INHERITFROM !$= "")
{
%inheritFromListId = %list.findText($DATABLOCK_EDITOR_NEWDB_INHERITFROM);
%list.setSelected(%inheritFromListId);
}
// Set up state of client-side checkbox.
%clientSideCheckBox = DatablockEditorCreatePrompt-->ClientSideCheckBox;
@ -717,7 +734,11 @@ function DatablockEditorPlugin::createPromptNameCheck(%this, %path)
function DatablockEditorPlugin::createDatablockFinish( %this, %name, %copySource )
{
%class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem());
if($DATABLOCK_EDITOR_NEWDB_CLASS $= "")
%class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem());
else
%class = $DATABLOCK_EDITOR_NEWDB_CLASS;
if( %class !$= "" )
{
%action = %this.createUndo( ActionCreateDatablock, "Create New Datablock" );
@ -742,6 +763,8 @@ function DatablockEditorPlugin::createDatablockFinish( %this, %name, %copySource
%action.redo();
}
$DATABLOCK_EDITOR_NEWDB_CLASS = "";
}
//---------------------------------------------------------------------------------------------