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
This commit is contained in:
AzaezelX 2025-03-09 11:51:54 -05:00
parent ab73099dd9
commit fa760fa746
14 changed files with 476 additions and 15 deletions

View file

@ -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.")

View file

@ -174,7 +174,9 @@ public:
StringTableEntry getSearchText() { return mSearchText; }
void setSearchText(StringTableEntry searchText);
Vector<GuiInspectorGroup*> getGroups() { return mGroups; };
DECLARE_CALLBACK(void, onPreInspectObject, (SimObject* object) );
DECLARE_CALLBACK(void, onPostInspectObject, (SimObject* object) );
protected:
typedef Vector< SimObjectPtr< SimObject > > TargetVector;

View file

@ -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<FRangeValidator*>(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<GuiTextEditSliderCtrl*>(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<IRangeValidator*>(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<IRangeValidatorScaled*>(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<GuiTextEditSliderCtrl*>(mEdit);
if (ctrl != NULL)
ctrl->setText(newValue);
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeS32Mask
//-----------------------------------------------------------------------------

View file

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

View file

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

View file

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

View file

@ -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<AbstractClassRep::Field*>(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.")

View file

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