Browse Source

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)

Areloch 1 year ago
parent
commit
d952722811

+ 10 - 4
Engine/source/gui/controls/guiPopUpCtrlEx.cpp

@@ -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());
       }
    }
 

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

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

+ 10 - 10
Engine/source/gui/editor/guiInspectorTypes.cpp

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

+ 10 - 9
Engine/source/gui/editor/guiInspectorTypes.h

@@ -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 );
 };
 
 //-----------------------------------------------------------------------------

+ 134 - 6
Engine/source/gui/editor/inspector/datablockField.cpp

@@ -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 

+ 7 - 1
Engine/source/gui/editor/inspector/datablockField.h

@@ -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:
       

+ 25 - 2
Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript

@@ -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 = "";
 }
 
 //---------------------------------------------------------------------------------------------