2
0
Эх сурвалжийг харах

Merge pull request #1192 from Areloch/EditorPopupEXFieldExpansion

Usability improvements for editor fields utilizing popup menus
Brian Roberts 1 жил өмнө
parent
commit
600a6b8ebc

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

+ 135 - 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,158 @@ 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;
+
+               String dbCategory = String(datablock->mCategory).isEmpty() ? String("no category") : String::ToLower(datablock->mCategory);
+
+               if (datablock && (!mDesiredClass || datablock->getClassRep()->isClass(mDesiredClass)) && (dbCategory == categoryName))
+               {
+                  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 = "";
 }
 
 //---------------------------------------------------------------------------------------------