Adds logic and handling for Inspected SimObjects to be able to inject new InspectorGroups and InspectorFields when being inspected for editing.

Allows for expanded editing capabilities of existing classes without needing to add static fields to classes
This commit is contained in:
Areloch 2023-03-04 19:04:44 -06:00
parent 7fa2e72d5f
commit 3991019912
6 changed files with 154 additions and 2 deletions

View file

@ -25,7 +25,10 @@
#include "gui/editor/inspector/dynamicField.h"
#include "gui/editor/inspector/datablockField.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "T3D/assets/MaterialAsset.h"
#include "T3D/assets/ShapeAsset.h"
#include "T3D/assets/ImageAsset.h"
#include "T3D/assets/SoundAsset.h"
IMPLEMENT_CONOBJECT(GuiInspectorGroup);
@ -564,3 +567,97 @@ AbstractClassRep* GuiInspectorGroup::findCommonAncestorClass()
return classRep;
}
void GuiInspectorGroup::addInspectorField(StringTableEntry name, StringTableEntry typeName, const char* description, const char* callbackName)
{
S32 fieldType = -1;
if (typeName == StringTable->insert("int"))
fieldType = TypeS32;
else if (typeName == StringTable->insert("float"))
fieldType = TypeF32;
else if (typeName == StringTable->insert("vector"))
fieldType = TypePoint3F;
else if (typeName == StringTable->insert("vector2"))
fieldType = TypePoint2F;
else if (typeName == StringTable->insert("material"))
fieldType = TypeMaterialAssetId;
else if (typeName == StringTable->insert("image"))
fieldType = TypeImageAssetId;
else if (typeName == StringTable->insert("shape"))
fieldType = TypeShapeAssetId;
else if (typeName == StringTable->insert("sound"))
fieldType = TypeSoundAssetId;
else if (typeName == StringTable->insert("bool"))
fieldType = TypeBool;
else if (typeName == StringTable->insert("object"))
fieldType = TypeSimObjectPtr;
else if (typeName == StringTable->insert("string"))
fieldType = TypeString;
else if (typeName == StringTable->insert("colorI"))
fieldType = TypeColorI;
else if (typeName == StringTable->insert("colorF"))
fieldType = TypeColorF;
else if (typeName == StringTable->insert("ease"))
fieldType = TypeEaseF;
else if (typeName == StringTable->insert("command"))
fieldType = TypeCommand;
else if (typeName == StringTable->insert("filename"))
fieldType = TypeStringFilename;
else
fieldType = -1;
GuiInspectorField* fieldGui = constructField(fieldType);
if (fieldGui == nullptr)
{
//call down into script and see if there's special handling for that type of field
//this allows us to have completely special-case field types implemented entirely in script
if (isMethod("onConstructField"))
{
//ensure our stack variable is bound if we need it
Con::evaluatef("%d.stack = %d;", this->getId(), mStack->getId());
Con::executef(this, "onConstructField", name, name, typeName, description, StringTable->EmptyString(), StringTable->EmptyString(), callbackName);
}
}
else
{
fieldGui->init(mParent, this);
fieldGui->setSpecialEditField(true);
fieldGui->setTargetObject(mParent->getInspectObject(0));
StringTableEntry fieldName = StringTable->insert(name);
fieldGui->setSpecialEditVariableName(fieldName);
fieldGui->setSpecialEditCallbackName(callbackName);
fieldGui->setInspectorField(NULL, fieldName);
fieldGui->setDocs(description);
if (fieldGui->registerObject())
{
fieldGui->setValue(mParent->getInspectObject(0)->getDataField(fieldName, NULL));
mStack->addObject(fieldGui);
}
else
{
SAFE_DELETE(fieldGui);
}
}
}
DefineEngineMethod(GuiInspectorGroup, addField, void, (const char* fieldName, const char* fieldTypeName, const char* description, const char* callbackName),
("", "", "", ""),
"Adds a new Inspector field to this group.\n"
"@param fieldName The name of the field to add. The field will associate to a variable of the same name on the inspected object for editing purposes."
"@param fieldTypeName The name of the type of field it is. If it's an understood existing type, it will create it as normal. If it's an unknown type, it will attempt to call into script to create it."
"@param description (Optional) Description of the field."
"@param callbackName (Optional) Sets a special callback function to be called when this field is edited.")
{
if (dStrEqual(fieldName, "") || dStrEqual(fieldTypeName, ""))
return;
object->addInspectorField(StringTable->insert(fieldName), StringTable->insert(fieldTypeName), description, callbackName);
}

View file

@ -76,6 +76,8 @@ public:
U32 getNumFields() const { return mChildren.size(); }
void addInspectorField(StringTableEntry name, StringTableEntry typeName, const char* description, const char* callbackName);
protected:
// overridable method that creates our inner controls.
virtual bool createContent();