From 79081c647428ec707e93dec2f735fe7398ecd16c Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 21 Sep 2017 02:49:36 -0500 Subject: [PATCH] Updates the VariableInspector, VariableGroup and VariableField objects to actually be useful. In addition to the original functionality of being able to have a var name passed in and search for all vars with that in it, it also lets you build out a completely custom Inspector. Unlike the regular Inspector, which requires a specific object or objects, from which the fields are pulled from, this lets you manually create fields, which can tie into any given object and their fields, global vars, and also not only supports the engine types for fields, but also triggers a callback to script if a field type is not found allowing fully custom fields to be handled as needed. --- Engine/source/console/consoleObject.h | 1 + Engine/source/gui/editor/guiInspector.h | 8 +- .../source/gui/editor/guiInspectorTypes.cpp | 58 +++-- Engine/source/gui/editor/inspector/field.cpp | 95 ++++++++- Engine/source/gui/editor/inspector/field.h | 20 ++ .../gui/editor/inspector/variableField.cpp | 21 +- .../gui/editor/inspector/variableField.h | 3 +- .../gui/editor/inspector/variableGroup.cpp | 191 +++++++++++++++-- .../gui/editor/inspector/variableGroup.h | 29 +++ .../editor/inspector/variableInspector.cpp | 199 +++++++++++++++++- .../gui/editor/inspector/variableInspector.h | 18 ++ 11 files changed, 593 insertions(+), 50 deletions(-) diff --git a/Engine/source/console/consoleObject.h b/Engine/source/console/consoleObject.h index adef30e77..b5253ced6 100644 --- a/Engine/source/console/consoleObject.h +++ b/Engine/source/console/consoleObject.h @@ -475,6 +475,7 @@ public: FIELD_HideInInspectors = BIT( 0 ), ///< Do not show the field in inspectors. FIELD_ComponentInspectors = BIT(1), ///< Custom fields used by components. They are likely to be non-standard size/configuration, so ///< They are handled specially + FIELD_CustomInspectors = BIT(2), ///< Display as a button in inspectors. }; struct Field diff --git a/Engine/source/gui/editor/guiInspector.h b/Engine/source/gui/editor/guiInspector.h index 01fa5c1b6..f5b00a796 100644 --- a/Engine/source/gui/editor/guiInspector.h +++ b/Engine/source/gui/editor/guiInspector.h @@ -82,7 +82,13 @@ public: virtual void clearInspectObjects(); /// Get the currently inspected object - SimObject* getInspectObject( U32 index = 0 ) { return mTargets[ index ]; } + SimObject* getInspectObject(U32 index = 0) + { + if (!mTargets.empty()) + return mTargets[index]; + else + return nullptr; + } /// Return the number of objects being inspected by this GuiInspector. U32 getNumInspectObjects() const { return mTargets.size(); } diff --git a/Engine/source/gui/editor/guiInspectorTypes.cpp b/Engine/source/gui/editor/guiInspectorTypes.cpp index 0b107b5fd..f31d4facd 100644 --- a/Engine/source/gui/editor/guiInspectorTypes.cpp +++ b/Engine/source/gui/editor/guiInspectorTypes.cpp @@ -400,7 +400,7 @@ ConsoleDocClass( GuiInspectorTypeCheckBox, GuiControl* GuiInspectorTypeCheckBox::constructEditControl() { - if ( mField->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors) ) + if (mField && mField->flag.test(AbstractClassRep::FIELD_CustomInspectors)) { // This checkbox (bool field) is meant to be treated as a button. GuiControl* retCtrl = new GuiButtonCtrl(); @@ -425,27 +425,55 @@ GuiControl* GuiInspectorTypeCheckBox::constructEditControl() button->setField("Command", szBuffer ); return retCtrl; - } else { - GuiControl* retCtrl = new GuiCheckBoxCtrl(); + } + else if (mField && mField->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + { + // This checkbox (bool field) is meant to be treated as a button. + GuiControl* retCtrl = new GuiButtonCtrl(); - GuiCheckBoxCtrl *check = dynamic_cast(retCtrl); + // If we couldn't construct the control, bail! + if (retCtrl == NULL) + return retCtrl; - // Let's make it look pretty. - retCtrl->setDataField( StringTable->insert("profile"), NULL, "InspectorTypeCheckboxProfile" ); - retCtrl->setField( "text", "" ); + GuiButtonCtrl *button = dynamic_cast(retCtrl); - check->setIndent( 4 ); + // Let's make it look pretty. + retCtrl->setDataField(StringTable->insert("profile"), NULL, "InspectorTypeButtonProfile"); + retCtrl->setField("text", "Click Here"); - retCtrl->setScriptValue( getData() ); + retCtrl->setScriptValue(getData()); - _registerEditControl( retCtrl ); + _registerEditControl(retCtrl); - // Configure it to update our value when the popup is closed - char szBuffer[512]; - dSprintf( szBuffer, 512, "%d.apply(%d.getValue());",getId(),check->getId() ); - check->setField("Command", szBuffer ); + // Configure it to update our value when the popup is closed + char szBuffer[512]; + dSprintf(szBuffer, 512, "%d.apply(%d.getValue());", getId(), button->getId()); + button->setField("Command", szBuffer); - return retCtrl; + return retCtrl; + } + else + { + GuiControl* retCtrl = new GuiCheckBoxCtrl(); + + GuiCheckBoxCtrl *check = dynamic_cast(retCtrl); + + // Let's make it look pretty. + retCtrl->setDataField(StringTable->insert("profile"), NULL, "InspectorTypeCheckboxProfile"); + retCtrl->setField("text", ""); + + check->setIndent(4); + + retCtrl->setScriptValue(getData()); + + _registerEditControl(retCtrl); + + // Configure it to update our value when the popup is closed + char szBuffer[512]; + dSprintf(szBuffer, 512, "%d.apply(%d.getValue());", getId(), check->getId()); + check->setField("Command", szBuffer); + + return retCtrl; } } diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index d47d291d6..f8efaca02 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -49,7 +49,8 @@ GuiInspectorField::GuiInspectorField( GuiInspector* inspector, mInspector( inspector ), mField( field ), mFieldArrayIndex( NULL ), - mEdit( NULL ) + mEdit( NULL ), + mTargetObject(NULL) { if( field != NULL ) mCaption = field->pFieldname; @@ -72,7 +73,11 @@ GuiInspectorField::GuiInspectorField() mEdit( NULL ), mCaption( StringTable->EmptyString() ), mFieldArrayIndex( NULL ), - mHighlighted( false ) + mHighlighted( false ), + mTargetObject(NULL), + mVariableName(StringTable->EmptyString()), + mCallbackName(StringTable->EmptyString()), + mSpecialEditField(false) { setCanSave( false ); } @@ -118,6 +123,7 @@ bool GuiInspectorField::onAdd() // Force our editField to set it's value updateValue(); + Con::evaluatef("%d.edit = %d;", this->getId(), mEdit->getId()); return true; } @@ -244,6 +250,24 @@ void GuiInspectorField::onRightMouseUp( const GuiEvent &event ) void GuiInspectorField::setData( const char* data, bool callbacks ) { + if (mSpecialEditField) + { + if (mTargetObject != nullptr && mVariableName != StringTable->EmptyString()) + { + mTargetObject->setDataField(mVariableName, NULL, data); + + if (mCallbackName != StringTable->EmptyString()) + Con::executef(mInspector, mCallbackName, mVariableName, data, mTargetObject); + } + else if (mVariableName != StringTable->EmptyString()) + { + Con::setVariable(mVariableName, data); + + if (mCallbackName != StringTable->EmptyString()) + Con::executef(mInspector, mCallbackName, mVariableName, data); + } + } + if( mField == NULL ) return; @@ -257,7 +281,19 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) for( U32 i = 0; i < numTargets; ++ i ) { - SimObject* target = mInspector->getInspectObject( i ); + //For now, for simplicity's sake, you can only edit the components in a simple edit + SimObject* target = NULL; + if (numTargets == 1) + { + target = mTargetObject; + + if (!target) + target = mInspector->getInspectObject(i); + } + else + { + target = mInspector->getInspectObject(i); + } String oldValue = target->getDataField( mField->pFieldname, mFieldArrayIndex); @@ -347,10 +383,31 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) const char* GuiInspectorField::getData( U32 inspectObjectIndex ) { - if( mField == NULL ) - return ""; + if (!mSpecialEditField) + { + if (mField == NULL) + return ""; - return mInspector->getInspectObject( inspectObjectIndex )->getDataField( mField->pFieldname, mFieldArrayIndex ); + if (mTargetObject) + return mTargetObject->getDataField(mField->pFieldname, mFieldArrayIndex); + + return mInspector->getInspectObject(inspectObjectIndex)->getDataField(mField->pFieldname, mFieldArrayIndex); + } + else + { + if (mTargetObject != nullptr && mVariableName != StringTable->EmptyString()) + { + return mTargetObject->getDataField(mVariableName, NULL); + } + else if (mVariableName != StringTable->EmptyString()) + { + return Con::getVariable(mVariableName); + } + else + { + return ""; + } + } } //----------------------------------------------------------------------------- @@ -483,6 +540,17 @@ void GuiInspectorField::setValue( StringTableEntry newValue ) //----------------------------------------------------------------------------- +void GuiInspectorField::setEditControl(GuiControl* editCtrl) +{ + if (mEdit) + mEdit->deleteObject(); + + mEdit = editCtrl; + addObject(mEdit); +} + +//----------------------------------------------------------------------------- + bool GuiInspectorField::updateRects() { S32 dividerPos, dividerMargin; @@ -587,7 +655,10 @@ void GuiInspectorField::_executeSelectedCallback() void GuiInspectorField::_registerEditControl( GuiControl *ctrl ) { char szName[512]; - dSprintf( szName, 512, "IE_%s_%d_%s_Field", ctrl->getClassName(), mInspector->getInspectObject()->getId(), mCaption); + if(mInspector->getInspectObject() != nullptr) + dSprintf( szName, 512, "IE_%s_%d_%s_Field", ctrl->getClassName(), mInspector->getInspectObject()->getId(), mCaption); + else + dSprintf(szName, 512, "IE_%s_%s_Field", ctrl->getClassName(), mCaption); // Register the object ctrl->registerObject( szName ); @@ -663,3 +734,13 @@ DefineConsoleMethod( GuiInspectorField, reset, void, (), , "() - Reset to defaul { object->resetData(); } + +DefineConsoleMethod(GuiInspectorField, setCaption, void, (String newCaption),, "() - Reset to default value.") +{ + object->setCaption(StringTable->insert(newCaption.c_str())); +} + +DefineConsoleMethod(GuiInspectorField, setEditControl, void, (GuiControl* editCtrl), (nullAsType()), "() - Reset to default value.") +{ + object->setEditControl(editCtrl); +} diff --git a/Engine/source/gui/editor/inspector/field.h b/Engine/source/gui/editor/inspector/field.h index 2a4f8718b..cb1210b53 100644 --- a/Engine/source/gui/editor/inspector/field.h +++ b/Engine/source/gui/editor/inspector/field.h @@ -84,6 +84,16 @@ class GuiInspectorField : public GuiControl /// bool mHighlighted; + //An override that lets us bypass inspector-dependent logic for setting/getting variables/fields + bool mSpecialEditField; + //An override to make sure this field is associated to an object that isn't expressly + //the one the inspector is inspecting. Such as an entity's component. + SimObject* mTargetObject; + //Special edit field, variable name - the variable or field name targeted + StringTableEntry mVariableName; + //Special edit field, callback name - if defined, we'll do a callback to the function listed here when editing the field + StringTableEntry mCallbackName; + virtual void _registerEditControl( GuiControl *ctrl ); virtual void _executeSelectedCallback(); @@ -116,6 +126,10 @@ class GuiInspectorField : public GuiControl /// this is exposed in case someone wants to override the normal caption. virtual void setCaption( StringTableEntry caption ) { mCaption = caption; } + void setEditControl(GuiControl* editCtrl); + + virtual void setDocs(String docs) { mFieldDocs = docs; } + /// Returns pointer to this InspectorField's edit ctrl. virtual GuiControl* getEditCtrl() { return mEdit; } @@ -187,6 +201,12 @@ class GuiInspectorField : public GuiControl virtual void onMouseDown( const GuiEvent &event ); virtual void onRightMouseUp( const GuiEvent &event ); + void setTargetObject(SimObject* obj) { mTargetObject = obj; } + SimObject* getTargetObject() { return mTargetObject; } + void setSpecialEditField(bool isSpecialEditField) { mSpecialEditField = isSpecialEditField; } + void setSpecialEditVariableName(String varName) { mVariableName = StringTable->insert(varName); } + void setSpecialEditCallbackName(String callName) { mCallbackName = StringTable->insert(callName); } + DECLARE_CONOBJECT( GuiInspectorField ); DECLARE_CATEGORY( "Gui Editor" ); }; diff --git a/Engine/source/gui/editor/inspector/variableField.cpp b/Engine/source/gui/editor/inspector/variableField.cpp index f773722e0..76f640762 100644 --- a/Engine/source/gui/editor/inspector/variableField.cpp +++ b/Engine/source/gui/editor/inspector/variableField.cpp @@ -93,10 +93,25 @@ bool GuiInspectorVariableField::onAdd() void GuiInspectorVariableField::setData( const char* data, bool callbacks ) { - if ( !mCaption || mCaption[0] == 0 ) - return; + if (mOwnerObject == nullptr && mVariableName == StringTable->EmptyString()) + { + if (!mCaption || mCaption[0] == 0) + return; - Con::setVariable( mCaption, data ); + Con::setVariable(mCaption, data); + } + else + { + if (mOwnerObject != nullptr) + { + mOwnerObject->setDataField(mVariableName, NULL, data); + } + else + { + //probably a global var if we have no object attached, so just let it set + Con::setVariable(mVariableName, data); + } + } // Force our edit to update updateValue(); diff --git a/Engine/source/gui/editor/inspector/variableField.h b/Engine/source/gui/editor/inspector/variableField.h index ae720a7c4..39ba2e2b8 100644 --- a/Engine/source/gui/editor/inspector/variableField.h +++ b/Engine/source/gui/editor/inspector/variableField.h @@ -56,7 +56,8 @@ public: virtual void updateData() {}; protected: - + StringTableEntry mVariableName; + SimObject* mOwnerObject; }; #endif // _GUI_INSPECTOR_VARIABLEFIELD_H_ diff --git a/Engine/source/gui/editor/inspector/variableGroup.cpp b/Engine/source/gui/editor/inspector/variableGroup.cpp index 6c1cca7ec..2d03f7483 100644 --- a/Engine/source/gui/editor/inspector/variableGroup.cpp +++ b/Engine/source/gui/editor/inspector/variableGroup.cpp @@ -51,7 +51,7 @@ GuiInspectorVariableGroup::~GuiInspectorVariableGroup() GuiInspectorField* GuiInspectorVariableGroup::constructField( S32 fieldType ) { - return NULL; + return Parent::constructField(fieldType); } bool GuiInspectorVariableGroup::inspectGroup() @@ -59,39 +59,133 @@ bool GuiInspectorVariableGroup::inspectGroup() // to prevent crazy resizing, we'll just freeze our stack for a sec.. mStack->freeze(true); - clearFields(); - - Vector names; - - gEvalState.globalVars.exportVariables( mSearchString, &names, NULL ); - bool bNewItems = false; - for ( U32 i = 0; i < names.size(); i++ ) - { - const String &varName = names[i]; + if (!mSearchString.equal("")) + { + Vector names; - // If the field already exists, just update it - GuiInspectorVariableField *field = dynamic_cast( findField( varName ) ); - if ( field != NULL ) + gEvalState.globalVars.exportVariables(mSearchString, &names, NULL); + + for (U32 i = 0; i < names.size(); i++) { - field->updateValue(); + const String &varName = names[i]; + + // If the field already exists, just update it + GuiInspectorVariableField *field = dynamic_cast(findField(varName)); + if (field != NULL) + { + field->updateValue(); + continue; + } + + bNewItems = true; + + field = new GuiInspectorVariableField(); + field->init(mParent, this); + field->setInspectorField(NULL, StringTable->insert(varName)); + + if (field->registerObject()) + { + mChildren.push_back(field); + mStack->addObject(field); + } + else + delete field; + } + } + + for (U32 i = 0; i < mFields.size(); i++) + { + bNewItems = true; + + GuiInspectorField *fieldGui = findField(mFields[i]->mFieldName); + if (fieldGui != NULL) + { + fieldGui->updateValue(); + continue; + } + + //first and foremost, nab the field type and check if it's a custom field or not. + //If it's not a custom field, proceed below, if it is, hand it off to script to be handled by the component + if (mFields[i]->mFieldType == -1) + { + 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", mFields[i]->mFieldName, + mFields[i]->mFieldLabel, mFields[i]->mFieldTypeName, mFields[i]->mFieldDescription, + mFields[i]->mDefaultValue, mFields[i]->mDataValues, mFields[i]->mOwnerObject); + } continue; } bNewItems = true; - field = new GuiInspectorVariableField(); - field->init( mParent, this ); - field->setInspectorField( NULL, StringTable->insert( varName ) ); + fieldGui = constructField(mFields[i]->mFieldType); + if (fieldGui == NULL) + fieldGui = new GuiInspectorField(); - if ( field->registerObject() ) + fieldGui->init(mParent, this); + + fieldGui->setSpecialEditField(true); + + if (mFields[i]->mOwnerObject) { - mChildren.push_back( field ); - mStack->addObject( field ); + fieldGui->setTargetObject(mFields[i]->mOwnerObject); } else - delete field; + { + //check if we're binding to a global var first, if we have no owner + if (mFields[i]->mFieldName[0] != '$') + { + fieldGui->setTargetObject(mParent); + } + } + + fieldGui->setSpecialEditVariableName(mFields[i]->mFieldName); + fieldGui->setSpecialEditCallbackName(mFields[i]->mSetCallbackName); + + fieldGui->setInspectorField(NULL, mFields[i]->mFieldLabel); + fieldGui->setDocs(mFields[i]->mFieldDescription); + + /*if (mFields[i]->mSetCallbackName != StringTable->EmptyString()) + { + fieldGui->on.notify() + }*/ + + if (fieldGui->registerObject()) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[GuiInspectorVariableGroup] Adding field '%s'", + field->pFieldname); +#endif + + if (mFields[i]->mOwnerObject) + { + String val = mFields[i]->mOwnerObject->getDataField(mFields[i]->mFieldName, NULL); + + if(val.isEmpty()) + fieldGui->setValue(mFields[i]->mDefaultValue); + else + fieldGui->setValue(val); + } + else + { + fieldGui->setValue(mFields[i]->mDefaultValue); + } + + fieldGui->setActive(mFields[i]->mEnabled); + + mChildren.push_back(fieldGui); + mStack->addObject(fieldGui); + } + else + { + SAFE_DELETE(fieldGui); + } } mStack->freeze(false); @@ -107,3 +201,58 @@ bool GuiInspectorVariableGroup::inspectGroup() return true; } + +void GuiInspectorVariableGroup::clearFields() +{ + mFields.clear(); +} + +void GuiInspectorVariableGroup::addField(VariableField* field) +{ + bool found = false; + + for (U32 i = 0; i < mFields.size(); i++) + { + if (mFields[i]->mFieldName == field->mFieldName) + { + found = true; + break; + } + } + + if(!found) + mFields.push_back(field); +} + +void GuiInspectorVariableGroup::addInspectorField(GuiInspectorField* field) +{ + mStack->addObject(field); + mChildren.push_back(field); + mStack->updatePanes(); +} + +GuiInspectorField* GuiInspectorVariableGroup::createInspectorField() +{ + GuiInspectorField* newField = new GuiInspectorField(); + + newField->init(mParent, this); + + newField->setSpecialEditField(true); + + if (newField->registerObject()) + { + return newField; + } + + return NULL; +} + +DefineConsoleMethod(GuiInspectorVariableGroup, createInspectorField, GuiInspectorField*, (),, "createInspectorField()") +{ + return object->createInspectorField(); +} + +DefineConsoleMethod(GuiInspectorVariableGroup, addInspectorField, void, (GuiInspectorField* field), (nullAsType()), "addInspectorField( GuiInspectorFieldObject )") +{ + object->addInspectorField(field); +} \ No newline at end of file diff --git a/Engine/source/gui/editor/inspector/variableGroup.h b/Engine/source/gui/editor/inspector/variableGroup.h index fd0370c99..0711933a0 100644 --- a/Engine/source/gui/editor/inspector/variableGroup.h +++ b/Engine/source/gui/editor/inspector/variableGroup.h @@ -31,6 +31,28 @@ class GuiInspector; class GuiInspectorField; +struct VariableField +{ + StringTableEntry mFieldName; + StringTableEntry mFieldLabel; + StringTableEntry mFieldDescription; + + StringTableEntry mFieldTypeName; + S32 mFieldType; + + SimObject* mOwnerObject; + + StringTableEntry mDefaultValue; + String mDataValues; + + String mGroup; + + StringTableEntry mSetCallbackName; + + bool mHidden; + bool mEnabled; +}; + class GuiInspectorVariableGroup : public GuiInspectorGroup { public: @@ -49,7 +71,14 @@ public: virtual bool inspectGroup(); + void clearFields(); + void addField(VariableField* field); + + void addInspectorField(GuiInspectorField* field); + GuiInspectorField* createInspectorField(); + protected: + Vector mFields; }; #endif // _GUI_INSPECTOR_VARIABLEGROUP_H_ diff --git a/Engine/source/gui/editor/inspector/variableInspector.cpp b/Engine/source/gui/editor/inspector/variableInspector.cpp index aeb78957c..6e673bc34 100644 --- a/Engine/source/gui/editor/inspector/variableInspector.cpp +++ b/Engine/source/gui/editor/inspector/variableInspector.cpp @@ -21,7 +21,6 @@ //----------------------------------------------------------------------------- #include "gui/editor/inspector/variableInspector.h" -#include "gui/editor/inspector/variableGroup.h" #include "console/engineAPI.h" GuiVariableInspector::GuiVariableInspector() @@ -56,7 +55,203 @@ void GuiVariableInspector::loadVars( String searchStr ) mGroups.push_back( group ); addObject( group ); - //group->inspectGroup(); + group->inspectGroup(); +} + +void GuiVariableInspector::update() +{ + clearGroups(); + + for (U32 i = 0; i < mFields.size(); i++) + { + //first, get the var's group name. if the group exists, we'll add to it's list + GuiInspectorVariableGroup *group = nullptr; + + for (U32 g = 0; g < mGroups.size(); g++) + { + if (mGroups[g]->getCaption().equal(mFields[i].mGroup)) + { + group = static_cast(mGroups[g]); + break; + } + } + + if (group == nullptr) + { + group = new GuiInspectorVariableGroup(); + + group->setHeaderHidden(false); + group->setCanCollapse(true); + group->mParent = this; + group->setCaption(mFields[i].mGroup); + + group->registerObject(); + mGroups.push_back(group); + addObject(group); + } + + group->addField(&mFields[i]); + } + + //And now, cue our update for the groups themselves + for (U32 g = 0; g < mGroups.size(); g++) + { + mGroups[g]->inspectGroup(); + } +} + +void GuiVariableInspector::startGroup(const char* name) +{ + if (!mCurrentGroup.isEmpty()) + return; + + mCurrentGroup = name; +} + +void GuiVariableInspector::endGroup() +{ + mCurrentGroup = ""; +} + +void GuiVariableInspector::addField(const char* name, const char* label, const char* typeName, const char* description, + const char* defaultValue, const char* dataValues, SimObject* ownerObj) +{ + VariableField newField; + newField.mFieldName = StringTable->insert(name); + newField.mFieldLabel = StringTable->insert(label); + newField.mFieldTypeName = StringTable->insert(typeName); + newField.mFieldDescription = StringTable->insert(description); + newField.mDefaultValue = StringTable->insert(defaultValue); + newField.mDataValues = String(dataValues); + newField.mGroup = mCurrentGroup; + newField.mSetCallbackName = StringTable->EmptyString(); + newField.mEnabled = true; + + newField.mOwnerObject = ownerObj; + + //establish the field on the ownerObject(if we have one) + //This way, we can let the field hook into the object's field and modify it when changed + if (newField.mOwnerObject != nullptr) + { + if (!newField.mOwnerObject->isField(newField.mFieldName)) + { + newField.mOwnerObject->setDataField(newField.mFieldName, NULL, newField.mDefaultValue); + } + } + + // + //find the field type + S32 fieldTypeMask = -1; + + if (newField.mFieldTypeName == StringTable->insert("int")) + fieldTypeMask = TypeS32; + else if (newField.mFieldTypeName == StringTable->insert("float")) + fieldTypeMask = TypeF32; + else if (newField.mFieldTypeName == StringTable->insert("vector")) + fieldTypeMask = TypePoint3F; + //else if (fieldType == StringTable->insert("material")) + // fieldTypeMask = TypeMaterialName; + else if (newField.mFieldTypeName == StringTable->insert("image")) + fieldTypeMask = TypeImageFilename; + else if (newField.mFieldTypeName == StringTable->insert("shape")) + fieldTypeMask = TypeShapeFilename; + else if (newField.mFieldTypeName == StringTable->insert("bool")) + fieldTypeMask = TypeBool; + else if (newField.mFieldTypeName == StringTable->insert("object")) + fieldTypeMask = TypeSimObjectPtr; + else if (newField.mFieldTypeName == StringTable->insert("string")) + fieldTypeMask = TypeString; + else if (newField.mFieldTypeName == StringTable->insert("colorI")) + fieldTypeMask = TypeColorI; + else if (newField.mFieldTypeName == StringTable->insert("colorF")) + fieldTypeMask = TypeColorF; + else if (newField.mFieldTypeName == StringTable->insert("ease")) + fieldTypeMask = TypeEaseF; + else + fieldTypeMask = -1; + + newField.mFieldType = fieldTypeMask; + // + + mFields.push_back(newField); + + update(); +} + +void GuiVariableInspector::addCallbackField(const char* name, const char* label, const char* typeName, const char* description, + const char* defaultValue, const char* dataValues, const char* callbackName, SimObject* ownerObj) +{ + addField(name, label, typeName, description, defaultValue, dataValues, ownerObj); + + //Add the callback name + mFields.last().mSetCallbackName = StringTable->insert(callbackName); + + update(); +} + +void GuiVariableInspector::clearFields() +{ + mFields.clear(); + update(); +} + +void GuiVariableInspector::setFieldEnabled(const char* name, bool enabled) +{ + String fieldName = name; + for (U32 i = 0; i < mFields.size(); i++) + { + if (fieldName.equal(mFields[i].mFieldName, String::NoCase)) + { + mFields[i].mEnabled = enabled; + update(); + return; + } + } +} + +DefineConsoleMethod(GuiVariableInspector, startGroup, void, (const char* name),, "startGroup( groupName )") +{ + object->startGroup(name); +} + +DefineConsoleMethod(GuiVariableInspector, endGroup, void, (),, "endGroup()") +{ + object->endGroup(); +} + +DefineConsoleMethod(GuiVariableInspector, addField, void, (const char* name, const char* label, const char* typeName, + const char* description, const char* defaultValue, const char* dataValues, SimObject* ownerObj), + ("","","","","", "", nullAsType()), "addField( fieldName/varName, fieldLabel, fieldTypeName, description, defaultValue, defaultValues, ownerObject )") +{ + if (name == "" || typeName == "") + return; + + object->addField(name, label, typeName, description, defaultValue, dataValues, ownerObj); +} + +DefineConsoleMethod(GuiVariableInspector, addCallbackField, void, (const char* name, const char* label, const char* typeName, + const char* description, const char* defaultValue, const char* dataValues, const char* callbackName, SimObject* ownerObj), + ("", "", "", "", "", "", nullAsType()), "addField( fieldName/varName, fieldLabel, fieldTypeName, description, defaultValue, defaultValues, callbackName, ownerObject )") +{ + if (name == "" || typeName == "") + return; + + object->addCallbackField(name, label, typeName, description, defaultValue, dataValues, callbackName, ownerObj); +} + +DefineConsoleMethod(GuiVariableInspector, update, void, (), , "update()") +{ + object->update(); +} + +DefineConsoleMethod(GuiVariableInspector, clearFields, void, (), , "clearFields()") +{ + object->clearFields(); +} + +DefineConsoleMethod(GuiVariableInspector, setFieldEnabled, void, (const char* fieldName, bool isEnabled), (true), "setFieldEnabled( fieldName, isEnabled )") +{ + object->setFieldEnabled(fieldName, isEnabled); } DefineConsoleMethod( GuiVariableInspector, loadVars, void, ( const char * searchString ), , "loadVars( searchString )" ) diff --git a/Engine/source/gui/editor/inspector/variableInspector.h b/Engine/source/gui/editor/inspector/variableInspector.h index c28196429..58cdcda81 100644 --- a/Engine/source/gui/editor/inspector/variableInspector.h +++ b/Engine/source/gui/editor/inspector/variableInspector.h @@ -26,6 +26,9 @@ #ifndef _GUI_INSPECTOR_H_ #include "gui/editor/guiInspector.h" #endif +#ifndef _GUI_INSPECTOR_VARIABLEGROUP_H_ +#include "gui/editor/inspector/variableGroup.h" +#endif class GuiVariableInspector : public GuiInspector @@ -44,8 +47,23 @@ public: virtual void loadVars( String searchString ); + void update(); + + void startGroup(const char* name); + void endGroup(); + + void addField(const char* name, const char* label, const char* typeName, const char* description, + const char* defaultValue, const char* dataValues, SimObject* ownerObj); + void addCallbackField(const char* name, const char* label, const char* typeName, const char* description, + const char* defaultValue, const char* dataValues, const char* callbackName, SimObject* ownerObj); + void setFieldEnabled(const char* name, bool enabled); + void clearFields(); protected: + + Vector mFields; + + String mCurrentGroup; };