From fa760fa746790583d9f38b08f617b0a00b3aafec Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 9 Mar 2025 11:51:54 -0500 Subject: [PATCH] add numerous new validators as well as inspector support to treat a significant chunk of the codebase as range-clmped values which can take a guisliderbarctrl with a configurable at the validator level fidelity variable additionally adds a new addfieldV and addprotetedfieldV for further callback validated slider-presented variables *also* adds an on additional callbacks to the inspector itself, like onPreinspectobject, onPostinspectObject, and onPostInspectorfieldModified in addition to *that*, adds a new hidefield command to tag a given specific field not to show in inspector --- Engine/source/console/consoleObject.cpp | 106 ++++++++++++++++ Engine/source/console/consoleObject.h | 38 ++++++ Engine/source/console/consoleTypes.cpp | 42 +++++++ Engine/source/console/consoleTypes.h | 2 + Engine/source/console/typeValidators.cpp | 35 +++++- Engine/source/console/typeValidators.h | 49 +++++++- Engine/source/gui/editor/guiInspector.cpp | 37 +++++- Engine/source/gui/editor/guiInspector.h | 4 +- .../source/gui/editor/guiInspectorTypes.cpp | 113 +++++++++++++++++- Engine/source/gui/editor/guiInspectorTypes.h | 29 +++++ .../gui/editor/inspector/dynamicField.cpp | 1 + Engine/source/gui/editor/inspector/field.cpp | 2 + Engine/source/gui/editor/inspector/group.cpp | 32 ++++- Engine/source/gui/editor/inspector/group.h | 1 + 14 files changed, 476 insertions(+), 15 deletions(-) diff --git a/Engine/source/console/consoleObject.cpp b/Engine/source/console/consoleObject.cpp index 75928b542..71a9ed545 100644 --- a/Engine/source/console/consoleObject.cpp +++ b/Engine/source/console/consoleObject.cpp @@ -624,6 +624,86 @@ void ConsoleObject::addProtectedField(const char* in_pFieldname, sg_tempFieldList.push_back(f); } +void ConsoleObject::addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn, + AbstractClassRep::WriteDataNotify in_writeDataFn, + TypeValidator* v, + const U32 in_elementCount, + const char* in_pFieldDocs, + U32 flags) +{ + AbstractClassRep::Field f; + f.pFieldname = StringTable->insert(in_pFieldname); + + if (in_pFieldDocs) + f.pFieldDocs = in_pFieldDocs; + + f.type = in_fieldType; + f.offset = in_fieldOffset; + f.elementCount = in_elementCount; + f.validator = v; + f.flag = flags; + + f.setDataFn = in_setDataFn; + f.getDataFn = in_getDataFn; + f.writeDataFn = in_writeDataFn; + f.networkMask = 0; + + ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); + AssertFatal(conType, "ConsoleObject::addProtectedField - invalid console type"); + f.table = conType->getEnumTable(); + + sg_tempFieldList.push_back(f); +} + +void ConsoleObject::addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn, + TypeValidator* v, + const U32 in_elementCount, + const char* in_pFieldDocs, + U32 flags) +{ + addProtectedFieldV( + in_pFieldname, + in_fieldType, + in_fieldOffset, + in_setDataFn, + in_getDataFn, + &defaultProtectedWriteFn, + v, + in_elementCount, + in_pFieldDocs, + flags); +} + +void ConsoleObject::addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn, + TypeValidator* v, + const char* in_pFieldDocs, + U32 flags) +{ + addProtectedFieldV( + in_pFieldname, + in_fieldType, + in_fieldOffset, + in_setDataFn, + in_getDataFn, + &defaultProtectedWriteFn, + v, + 1, + in_pFieldDocs, + flags); +} + void ConsoleObject::addFieldV(const char* in_pFieldname, const U32 in_fieldType, const dsize_t in_fieldOffset, @@ -648,6 +728,32 @@ void ConsoleObject::addFieldV(const char* in_pFieldname, sg_tempFieldList.push_back(f); } +void ConsoleObject::addFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + TypeValidator* v, + const U32 in_elementCount, + const char* in_pFieldDocs) +{ + AbstractClassRep::Field f; + f.pFieldname = StringTable->insert(in_pFieldname); + if (in_pFieldDocs) + f.pFieldDocs = in_pFieldDocs; + f.type = in_fieldType; + f.offset = in_fieldOffset; + f.elementCount = 1; + f.table = NULL; + f.setDataFn = &defaultProtectedSetFn; + f.getDataFn = &defaultProtectedGetFn; + f.writeDataFn = &defaultProtectedWriteFn; + f.elementCount = in_elementCount; + f.validator = v; + f.networkMask = 0; + v->fieldIndex = sg_tempFieldList.size(); + + sg_tempFieldList.push_back(f); +} + void ConsoleObject::addDeprecatedField(const char *fieldName) { AbstractClassRep::Field f; diff --git a/Engine/source/console/consoleObject.h b/Engine/source/console/consoleObject.h index 8c6bfdec2..b4daf6613 100644 --- a/Engine/source/console/consoleObject.h +++ b/Engine/source/console/consoleObject.h @@ -945,6 +945,13 @@ public: TypeValidator *v, const char * in_pFieldDocs = NULL); + static void addFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + TypeValidator* v, + const U32 in_elementCount, + const char* in_pFieldDocs = NULL); + /// Register a complex protected field. /// /// @param in_pFieldname Name of the field. @@ -998,6 +1005,37 @@ public: const char* in_pFieldDocs = NULL, U32 flags = 0); + + static void addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn, + AbstractClassRep::WriteDataNotify in_writeDataFn = &defaultProtectedWriteFn, + TypeValidator* v = NULL, + const U32 in_elementCount = 1, + const char* in_pFieldDocs = NULL, + U32 flags = 0); + + static void addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn, + TypeValidator* v = NULL, + const U32 in_elementCount = 1, + const char* in_pFieldDocs = NULL, + U32 flags = 0); + + static void addProtectedFieldV(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::SetDataNotify in_setDataFn, + AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn, + TypeValidator* v = NULL, + const char* in_pFieldDocs = NULL, + U32 flags = 0); + /// Add a deprecated field. /// /// A deprecated field will always be undefined, even if you assign a value to it. This diff --git a/Engine/source/console/consoleTypes.cpp b/Engine/source/console/consoleTypes.cpp index a6a0992c6..766c02dd0 100644 --- a/Engine/source/console/consoleTypes.cpp +++ b/Engine/source/console/consoleTypes.cpp @@ -473,6 +473,48 @@ ConsoleSetType( TypeF32 ) Con::printf("(TypeF32) Cannot set multiple args to a single F32."); } +//----------------------------------------------------------------------------- +// TypeRangedF32 +//----------------------------------------------------------------------------- +ConsoleType(float, TypeRangedF32, F32, "") + +ConsoleGetType(TypeRangedF32) +{ + static const U32 bufSize = 256; + char* returnBuffer = Con::getReturnBuffer(bufSize); + dSprintf(returnBuffer, bufSize, "%g", *((F32*)dptr)); + return returnBuffer; +} +ConsoleSetType(TypeRangedF32) +{ + if (argc == 1) + *((F32*)dptr) = dAtof(argv[0]); + else + Con::printf("(TypeF32) Cannot set multiple args to a single F32."); +} + +//----------------------------------------------------------------------------- +// TypeRangedS32 +//----------------------------------------------------------------------------- +ConsoleType(int, TypeRangedS32, S32, "") + +ConsoleGetType(TypeRangedS32) +{ + static const U32 bufSize = 512; + char* returnBuffer = Con::getReturnBuffer(bufSize); + dSprintf(returnBuffer, bufSize, "%d", *((S32*)dptr)); + return returnBuffer; +} + +ConsoleSetType(TypeRangedS32) +{ + if (argc == 1) + *((S32*)dptr) = dAtoi(argv[0]); + else + Con::printf("(TypeRangedS32) Cannot set multiple args to a single S32."); +} + + //----------------------------------------------------------------------------- // TypeF32Vector //----------------------------------------------------------------------------- diff --git a/Engine/source/console/consoleTypes.h b/Engine/source/console/consoleTypes.h index 047402ce9..ff7281d10 100644 --- a/Engine/source/console/consoleTypes.h +++ b/Engine/source/console/consoleTypes.h @@ -66,9 +66,11 @@ DefineConsoleType( TypeBoolVector, Vector) DefineConsoleType( TypeS8, S8 ) DefineConsoleType( TypeS16, S16) DefineConsoleType( TypeS32, S32 ) +DefineConsoleType(TypeRangedS32, S32) DefineConsoleType( TypeS32Vector, Vector ) DefineConsoleType( TypeF64, F64 ) DefineConsoleType( TypeF32, F32 ) +DefineConsoleType( TypeRangedF32, F32) DefineConsoleType( TypeF32Vector, Vector ) DefineUnmappedConsoleType( TypeString, const char * ) // plain UTF-8 strings are not supported in new interop DefineConsoleType( TypeCaseString, const char * ) diff --git a/Engine/source/console/typeValidators.cpp b/Engine/source/console/typeValidators.cpp index 6b2ea7475..e22d6045e 100644 --- a/Engine/source/console/typeValidators.cpp +++ b/Engine/source/console/typeValidators.cpp @@ -100,9 +100,42 @@ void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr) namespace CommonValidators { - FRangeValidator PositiveFloat(0.0f, F32_MAX); + FRangeValidator F32Range(F32_MIN, F32_MAX, F32_MAX); + FRangeValidator DirFloat(-1.0f, 1.0f); + FRangeValidator NegDefaultF32(-1.0f, F32_MAX, F32_MAX); + FRangeValidator PositiveFloat(0.0f, F32_MAX, F32_MAX); FRangeValidator PositiveNonZeroFloat((F32)POINT_EPSILON, F32_MAX); FRangeValidator NormalizedFloat(0.0f, 1.0f); + + FRangeValidator F32_8BitPercent(0.0f, 1.0f, 1 << 8); + FRangeValidator F32_16BitPercent(0.0f, 1.0f, 1 << 16); + FRangeValidator ValidSlopeAngle(0.0f, 89.9f, 89.9f); + FRangeValidator CornerAngle(0.0f, 90.0f, 90.0f); + + IRangeValidator S32Range(S32_MIN, S32_MAX); + IRangeValidator DirInt(-1,1); + IRangeValidator NegDefaultInt(-1, S32_MAX); + IRangeValidator PositiveInt(0, S32_MAX); + IRangeValidator NaturalNumber(1, S32_MAX); + //see "T3D/gameBase/processList.h" for TickMs = 32 + IRangeValidator MSTickRange(32, S32_MAX); + + IRangeValidator S32_8BitCap(0, 1 << 8); + IRangeValidator S32_16BitCap(0, 1 << 16); Point3NormalizeValidator NormalizedPoint3(1.0f); + + FRangeValidator DegreeRange(-360.0f, 360.0f, 720.0f); + FRangeValidator PosDegreeRange(0.0f, 360.0f, 360.0f); + FRangeValidator DegreeRangeHalf(-180.0f, 180.0f, 360.0f); + FRangeValidator PosDegreeRangeHalf(0.0f, 180.0f, 180.0f); + FRangeValidator DegreeRangeQuarter(-90.0f, 90.0f, 180.0f); + FRangeValidator PosDegreeRangeQuarter(0.0f, 90.0f, 90.0f); + + IRangeValidator S32_DegreeRange(-360, 360); + IRangeValidator S32_PosDegreeRange(0, 360); + IRangeValidator S32_DegreeRangeHalf(-180, 180); + IRangeValidator S32_PosDegreeRangeHalf(0, 180); + IRangeValidator S32_DegreeRangeQuarter(-90, 90); + IRangeValidator S32_PosDegreeRangeQuarter(0, 90); }; diff --git a/Engine/source/console/typeValidators.h b/Engine/source/console/typeValidators.h index ac97cbd44..f9bc57b6c 100644 --- a/Engine/source/console/typeValidators.h +++ b/Engine/source/console/typeValidators.h @@ -46,31 +46,35 @@ class TypeValidator /// Floating point min/max range validator class FRangeValidator : public TypeValidator { - F32 minV, maxV; + F32 minV, maxV, mFidelity; public: - FRangeValidator(F32 minValue, F32 maxValue) + FRangeValidator(F32 minValue, F32 maxValue, F32 fidelity = 0.0f) { minV = minValue; maxV = maxValue; + mFidelity = fidelity; } void validateType(SimObject *object, void *typePtr) override; F32 getMin() { return minV; }; F32 getMax() { return maxV; }; + F32 getFidelity() { return mFidelity; }; }; /// Signed integer min/max range validator class IRangeValidator : public TypeValidator { - S32 minV, maxV; + S32 minV, maxV, mFidelity; public: - IRangeValidator(S32 minValue, S32 maxValue) + IRangeValidator(S32 minValue, S32 maxValue, S32 fidelity = 1) { minV = minValue; maxV = maxValue; + mFidelity = fidelity; } void validateType(SimObject *object, void *typePtr) override; - F32 getMin() { return minV; }; - F32 getMax() { return maxV; }; + S32 getMin() { return minV; }; + S32 getMax() { return maxV; }; + S32 getFidelity() { return mFidelity; }; }; /// Scaled integer field validator @@ -89,6 +93,9 @@ public: factor = scaleFactor; } void validateType(SimObject *object, void *typePtr) override; + S32 getMin() { return minV; }; + S32 getMax() { return maxV; }; + S32 getScaleFactor() { return factor; }; }; /// Vector normalization validator @@ -104,12 +111,42 @@ public: namespace CommonValidators { // Floats + extern FRangeValidator F32Range; + extern FRangeValidator DirFloat; + extern FRangeValidator NegDefaultF32; extern FRangeValidator PositiveFloat; extern FRangeValidator PositiveNonZeroFloat; extern FRangeValidator NormalizedFloat; + extern FRangeValidator F32_8BitPercent; + extern FRangeValidator F32_16BitPercent; + extern FRangeValidator ValidSlopeAngle; + extern FRangeValidator CornerAngle; + extern IRangeValidator S32Range; + extern IRangeValidator DirInt; + extern IRangeValidator NegDefaultInt; + extern IRangeValidator PositiveInt; + extern IRangeValidator NaturalNumber; + extern IRangeValidator MSTickRange; + extern IRangeValidator S32_8BitCap; + extern IRangeValidator S32_16BitCap; // Other Math Types extern Point3NormalizeValidator NormalizedPoint3; + + // orbital mechanics + extern FRangeValidator DegreeRange; + extern FRangeValidator PosDegreeRange; + extern FRangeValidator DegreeRangeHalf; + extern FRangeValidator PosDegreeRangeHalf; + extern FRangeValidator DegreeRangeQuarter; + extern FRangeValidator PosDegreeRangeQuarter; + + extern IRangeValidator S32_DegreeRange; + extern IRangeValidator S32_PosDegreeRange; + extern IRangeValidator S32_DegreeRangeHalf; + extern IRangeValidator S32_PosDegreeRangeHalf; + extern IRangeValidator S32_DegreeRangeQuarter; + extern IRangeValidator S32_PosDegreeRangeQuarter; }; #endif diff --git a/Engine/source/gui/editor/guiInspector.cpp b/Engine/source/gui/editor/guiInspector.cpp index 94bfc8d9c..1b231a5ec 100644 --- a/Engine/source/gui/editor/guiInspector.cpp +++ b/Engine/source/gui/editor/guiInspector.cpp @@ -28,6 +28,7 @@ #include "gui/editor/inspector/dynamicGroup.h" #include "gui/containers/guiScrollCtrl.h" #include "gui/editor/inspector/customField.h" +#include "console/typeValidators.h" IMPLEMENT_CONOBJECT(GuiInspector); @@ -38,6 +39,12 @@ ConsoleDocClass( GuiInspector, ); +IMPLEMENT_CALLBACK(GuiInspector, onPreInspectObject, void, (SimObject* object), (object), + "Called prior to inspecting a new object.\n"); + +IMPLEMENT_CALLBACK(GuiInspector, onPostInspectObject, void, (SimObject* object), (object), + "Called after inspecting a new object.\n"); + //#define DEBUG_SPEW @@ -71,7 +78,7 @@ void GuiInspector::initPersistFields() docsURL; addGroup( "Inspector" ); - addField( "dividerMargin", TypeS32, Offset( mDividerMargin, GuiInspector ) ); + addFieldV( "dividerMargin", TypeRangedS32, Offset( mDividerMargin, GuiInspector ), &CommonValidators::PositiveInt); addField( "groupFilters", TypeRealString, Offset( mGroupFilters, GuiInspector ), "Specify groups that should be shown or not. Specifying 'shown' implicitly does 'not show' all other groups. Example string: +name -otherName" ); @@ -79,7 +86,7 @@ void GuiInspector::initPersistFields() addField( "showCustomFields", TypeBool, Offset( mShowCustomFields, GuiInspector ), "If false the custom fields Name, Id, and Source Class will not be shown." ); - addField("forcedArrayIndex", TypeS32, Offset(mForcedArrayIndex, GuiInspector)); + addFieldV("forcedArrayIndex", TypeRangedS32, Offset(mForcedArrayIndex, GuiInspector), &CommonValidators::NegDefaultInt); addField("searchText", TypeString, Offset(mSearchText, GuiInspector), "A string that, if not blank, is used to filter shown fields"); endGroup( "Inspector" ); @@ -325,11 +332,14 @@ bool GuiInspector::isInspectingObject( SimObject* object ) //----------------------------------------------------------------------------- void GuiInspector::inspectObject( SimObject *object ) -{ +{ + onPreInspectObject_callback((mTargets.size() > 1)? mTargets[0] : NULL); + if( mTargets.size() > 1 || !isInspectingObject( object ) ) clearInspectObjects(); addInspectObject( object ); + onPostInspectObject_callback(object); } //----------------------------------------------------------------------------- @@ -349,7 +359,8 @@ void GuiInspector::clearInspectObjects() void GuiInspector::addInspectObject( SimObject* object, bool autoSync ) { // If we are already inspecting the object, just update the groups. - + + onPreInspectObject_callback((mTargets.size() > 1) ? mTargets[0] : NULL); if( isInspectingObject( object ) ) { #ifdef DEBUG_SPEW @@ -379,6 +390,7 @@ void GuiInspector::addInspectObject( SimObject* object, bool autoSync ) if( autoSync ) refresh(); + onPostInspectObject_callback(object); } //----------------------------------------------------------------------------- @@ -629,7 +641,7 @@ void GuiInspector::refresh() GuiInspectorGroup *newGroup = new GuiInspectorGroup( itr->pGroupname, this ); newGroup->setForcedArrayIndex(mForcedArrayIndex); - newGroup->registerObject(); + newGroup->registerObject(); if( !newGroup->getNumFields() ) { #ifdef DEBUG_SPEW @@ -995,6 +1007,21 @@ DefineEngineMethod(GuiInspector, findExistentGroup, S32, (const char* groupName) return group ? group->getId() : 0; } +DefineEngineMethod(GuiInspector, getInspectedGroupCount, S32, (), , + "How many inspected groups there are.\n" + "@return how many inspected groups there are") +{ + return object->getGroups().size(); +} + +DefineEngineMethod(GuiInspector, getInspectedGroup, GuiInspectorGroup*, (S32 key), , + "Finds an existing GuiInspectorGroup if it exists and returns it's Id.\n" + "@param key nth group out of the list of groups." + "@return id of the GuiInspectorGroup") +{ + return object->getGroups()[key]; +} + DefineEngineMethod(GuiInspector, removeGroup, void, (const char* groupName), , "Finds an existing GuiInspectorGroup if it exists removes it.\n" "@param groupName Name of the new GuiInspectorGroup to find in this Inspector.") diff --git a/Engine/source/gui/editor/guiInspector.h b/Engine/source/gui/editor/guiInspector.h index 3b473829b..5b97a9f1f 100644 --- a/Engine/source/gui/editor/guiInspector.h +++ b/Engine/source/gui/editor/guiInspector.h @@ -174,7 +174,9 @@ public: StringTableEntry getSearchText() { return mSearchText; } void setSearchText(StringTableEntry searchText); - + Vector getGroups() { return mGroups; }; + DECLARE_CALLBACK(void, onPreInspectObject, (SimObject* object) ); + DECLARE_CALLBACK(void, onPostInspectObject, (SimObject* object) ); protected: typedef Vector< SimObjectPtr< SimObject > > TargetVector; diff --git a/Engine/source/gui/editor/guiInspectorTypes.cpp b/Engine/source/gui/editor/guiInspectorTypes.cpp index 6281d71d2..ed2f57af9 100644 --- a/Engine/source/gui/editor/guiInspectorTypes.cpp +++ b/Engine/source/gui/editor/guiInspectorTypes.cpp @@ -41,7 +41,7 @@ #include "math/mEase.h" #include "math/mathTypes.h" #include "sim/actionMap.h" - +#include "console/typeValidators.h" //----------------------------------------------------------------------------- // GuiInspectorTypeMenuBase @@ -1350,6 +1350,117 @@ void GuiInspectorTypeS32::setValue( StringTableEntry newValue ) ctrl->setText( newValue ); } +//----------------------------------------------------------------------------- +// GuiInspectorTypeRangedF32 +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT(GuiInspectorTypeRangedF32); + +ConsoleDocClass(GuiInspectorTypeRangedF32, + "@brief Inspector field type for range-clamped F32\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeRangedF32::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeRangedF32)->setInspectorFieldType("GuiInspectorTypeRangedF32"); +} + +GuiControl* GuiInspectorTypeRangedF32::constructEditControl() +{ + GuiControl* retCtrl = new GuiTextEditSliderCtrl(); + + retCtrl->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile"); + + // Don't forget to register ourselves + _registerEditControl(retCtrl); + + char szBuffer[512]; + dSprintf(szBuffer, 512, "%d.apply(%d.getText());", getId(), retCtrl->getId()); + retCtrl->setField("AltCommand", szBuffer); + FRangeValidator* validator = dynamic_cast(mField->validator); + if (validator) + { + retCtrl->setField("format", "%g"); + retCtrl->setField("range", String::ToString("%g %g", validator->getMin(), validator->getMax())); + if (validator->getFidelity()>0.0f) + retCtrl->setField("increment", String::ToString("%g", (validator->getMax()-validator->getMin())/validator->getFidelity())); + else + retCtrl->setField("increment", String::ToString("%g", POINT_EPSILON)); + } + return retCtrl; +} + +void GuiInspectorTypeRangedF32::setValue(StringTableEntry newValue) +{ + GuiTextEditSliderCtrl* ctrl = dynamic_cast(mEdit); + if (ctrl != NULL) + ctrl->setText(newValue); +} + +//----------------------------------------------------------------------------- +// GuiInspectorTypeRangedS32 +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT(GuiInspectorTypeRangedS32); + +ConsoleDocClass(GuiInspectorTypeRangedS32, + "@brief Inspector field type for range-clamped S32\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeRangedS32::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeRangedS32)->setInspectorFieldType("GuiInspectorTypeRangedS32"); +} + +GuiControl* GuiInspectorTypeRangedS32::constructEditControl() +{ + GuiControl* retCtrl = new GuiTextEditSliderCtrl(); + + retCtrl->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile"); + + // Don't forget to register ourselves + _registerEditControl(retCtrl); + + char szBuffer[512]; + dSprintf(szBuffer, 512, "%d.apply(%d.getText());", getId(), retCtrl->getId()); + retCtrl->setField("AltCommand", szBuffer); + IRangeValidator* validator = dynamic_cast(mField->validator); + + retCtrl->setField("increment", "1"); + retCtrl->setField("format", "%d"); + retCtrl->setField("range", "-2147483648 2147483647"); + + if (validator) + { + retCtrl->setField("range", String::ToString("%d %d", validator->getMin(), validator->getMax())); + if (validator->getFidelity() > 1) + retCtrl->setField("increment", String::ToString("%d", (validator->getMax() - validator->getMin()) / validator->getFidelity())); + } + else + { + IRangeValidatorScaled* scaledValidator = dynamic_cast(mField->validator); + if (scaledValidator) + { + retCtrl->setField("range", String::ToString("%d %d", scaledValidator->getMin(), scaledValidator->getMax())); + if (validator->getFidelity() > 1) + retCtrl->setField("increment", String::ToString("%d", scaledValidator->getScaleFactor())); + } + } + return retCtrl; +} + +void GuiInspectorTypeRangedS32::setValue(StringTableEntry newValue) +{ + GuiTextEditSliderCtrl* ctrl = dynamic_cast(mEdit); + if (ctrl != NULL) + ctrl->setText(newValue); +} //----------------------------------------------------------------------------- // GuiInspectorTypeS32Mask //----------------------------------------------------------------------------- diff --git a/Engine/source/gui/editor/guiInspectorTypes.h b/Engine/source/gui/editor/guiInspectorTypes.h index a123936e9..839d51718 100644 --- a/Engine/source/gui/editor/guiInspectorTypes.h +++ b/Engine/source/gui/editor/guiInspectorTypes.h @@ -473,6 +473,35 @@ public: void setValue( StringTableEntry newValue ) override; }; +//------------------------------------------------------------------------------ +// TypeRangedF32 GuiInspectorField class +//------------------------------------------------------------------------------ +class GuiInspectorTypeRangedF32 : public GuiInspectorField +{ +private: + typedef GuiInspectorField Parent; +public: + DECLARE_CONOBJECT(GuiInspectorTypeRangedF32); + static void consoleInit(); + + GuiControl* constructEditControl() override; + void setValue(StringTableEntry newValue) override; +}; + +//------------------------------------------------------------------------------ +// TypeRangedS32 GuiInspectorField class +//------------------------------------------------------------------------------ +class GuiInspectorTypeRangedS32 : public GuiInspectorField +{ +private: + typedef GuiInspectorField Parent; +public: + DECLARE_CONOBJECT(GuiInspectorTypeRangedS32); + static void consoleInit(); + + GuiControl* constructEditControl() override; + void setValue(StringTableEntry newValue) override; +}; //------------------------------------------------------------------------------ // TypeBitMask32 GuiInspectorField class diff --git a/Engine/source/gui/editor/inspector/dynamicField.cpp b/Engine/source/gui/editor/inspector/dynamicField.cpp index 52ff17457..fbf61314c 100644 --- a/Engine/source/gui/editor/inspector/dynamicField.cpp +++ b/Engine/source/gui/editor/inspector/dynamicField.cpp @@ -86,6 +86,7 @@ void GuiInspectorDynamicField::setData( const char* data, bool callbacks ) // give the target a chance to validate target->inspectPostApply(); + Con::executef(mInspector, "onPostInspectorFieldModified", mInspector->getIdString(), target->getIdString()); } } diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index 9a5caeec0..748eddb88 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -615,6 +615,8 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) // Give the target a chance to validate. target->inspectPostApply(); + if (String::compare(oldValue.c_str(), newValue.c_str()) != 0) + Con::executef(mInspector, "onPostInspectorFieldModified", mInspector->getIdString(), target->getIdString()); } if( callbacks && numTargets > 1 ) diff --git a/Engine/source/gui/editor/inspector/group.cpp b/Engine/source/gui/editor/inspector/group.cpp index 2f517d52d..38070feed 100644 --- a/Engine/source/gui/editor/inspector/group.cpp +++ b/Engine/source/gui/editor/inspector/group.cpp @@ -282,7 +282,7 @@ bool GuiInspectorGroup::inspectGroup() bGrabItems = false; continue; } - + // Skip field if it has the HideInInspectors flag set. if (field->flag.test(AbstractClassRep::FIELD_HideInInspectors)) @@ -761,6 +761,26 @@ void GuiInspectorGroup::removeInspectorField(StringTableEntry name) } } +void GuiInspectorGroup::hideInspectorField(StringTableEntry fieldName, bool setHidden) +{ + SimObject* inspectObj = mParent->getInspectObject(); + if (inspectObj == nullptr) + return; + + AbstractClassRep::Field* field = const_cast(inspectObj->getClassRep()->findField(fieldName)); + + if (field == NULL) + { + Con::errorf("fieldName not found: %s.%s", inspectObj->getName(), fieldName); + return; + } + + if (setHidden) + field->flag.set(AbstractClassRep::FIELD_HideInInspectors); + else + field->flag.clear(AbstractClassRep::FIELD_HideInInspectors); +} + DefineEngineMethod(GuiInspectorGroup, createInspectorField, GuiInspectorField*, (), , "createInspectorField()") { return object->createInspectorField(); @@ -798,6 +818,16 @@ DefineEngineMethod(GuiInspectorGroup, removeField, void, (const char* fieldName) object->removeInspectorField(StringTable->insert(fieldName)); } +DefineEngineMethod(GuiInspectorGroup, hideField, void, (const char* fieldName, bool setHidden), (true), + "Removes a Inspector field to this group of a given name.\n" + "@param fieldName The name of the field to be removed.") +{ + if (dStrEqual(fieldName, "")) + return; + + object->hideInspectorField(StringTable->insert(fieldName), setHidden); +} + DefineEngineMethod(GuiInspectorGroup, setForcedArrayIndex, void, (S32 arrayIndex), (-1), "Sets the ForcedArrayIndex for the group. Used to force presentation of arrayed fields to only show a specific field index." "@param arrayIndex The specific field index for arrayed fields to show. Use -1 or blank arg to go back to normal behavior.") diff --git a/Engine/source/gui/editor/inspector/group.h b/Engine/source/gui/editor/inspector/group.h index 1d9c55dc9..eb49a8b0d 100644 --- a/Engine/source/gui/editor/inspector/group.h +++ b/Engine/source/gui/editor/inspector/group.h @@ -86,6 +86,7 @@ public: void addInspectorField(StringTableEntry name, StringTableEntry typeName, const char* description, const char* callbackName); void addInspectorField(GuiInspectorField* field); void removeInspectorField(StringTableEntry name); + void hideInspectorField(StringTableEntry fieldName, bool setHidden); void setForcedArrayIndex(const S32& arrayIndex = -1) {