From fdadfa5eeadfaf3fd48cad639c30fce451ba1cc5 Mon Sep 17 00:00:00 2001 From: Areloch Date: Tue, 30 Apr 2024 18:44:17 -0500 Subject: [PATCH] Adds handling for complex fields such as Point2, Point3 and Point4's to be able to apply value changes to only one axis across a multi-object set without affecting other axis' --- .../source/gui/editor/guiInspectorTypes.cpp | 72 ++++++---- Engine/source/gui/editor/guiInspectorTypes.h | 6 +- Engine/source/gui/editor/inspector/field.cpp | 129 ++++++++++++++++++ Engine/source/gui/editor/inspector/field.h | 2 + 4 files changed, 179 insertions(+), 30 deletions(-) diff --git a/Engine/source/gui/editor/guiInspectorTypes.cpp b/Engine/source/gui/editor/guiInspectorTypes.cpp index b8fb74148..f18166be1 100644 --- a/Engine/source/gui/editor/guiInspectorTypes.cpp +++ b/Engine/source/gui/editor/guiInspectorTypes.cpp @@ -1765,12 +1765,12 @@ void GuiInspectorTypeSFXSourceName::consoleInit() void GuiInspectorType2DValue::constructEditControlChildren(GuiControl* retCtrl, S32 width) { - mCtrlX = new GuiTextEditSliderCtrl(); + mCtrlX = new GuiTextEditCtrl(); _registerEditControl(mCtrlX, "x"); mLabelX = new GuiControl(); _registerEditControl(mLabelX, "lx"); - mCtrlY = new GuiTextEditSliderCtrl(); + mCtrlY = new GuiTextEditCtrl(); _registerEditControl(mCtrlY, "y"); mLabelY = new GuiControl(); _registerEditControl(mLabelY, "ly"); @@ -1824,14 +1824,17 @@ void GuiInspectorType2DValue::constructEditControlChildren(GuiControl* retCtrl, mCtrlX->setPosition(Point2I(labelWidth, 0)); mCtrlY->setPosition(Point2I(labelWidth, 0)); - char szBuffer[512]; - dSprintf(szBuffer, 512, "%d.apply(%d.getText() SPC %d.getText());", getId(), mCtrlX->getId(), mCtrlY->getId()); + char szXCBuffer[512]; + dSprintf(szXCBuffer, 512, "%d.applyWord(0, %d.getText());", getId(), mCtrlX->getId()); - mCtrlX->setField("AltCommand", szBuffer); - mCtrlY->setField("AltCommand", szBuffer); + char szYCBuffer[512]; + dSprintf(szYCBuffer, 512, "%d.applyWord(1, %d.getText());", getId(), mCtrlY->getId()); - mCtrlX->setField("Validate", szBuffer); - mCtrlY->setField("Validate", szBuffer); + mCtrlX->setField("AltCommand", szXCBuffer); + mCtrlY->setField("AltCommand", szYCBuffer); + + mCtrlX->setField("Validate", szXCBuffer); + mCtrlY->setField("Validate", szYCBuffer); mContainerX = new GuiControl(); mContainerX->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile"); @@ -1933,7 +1936,7 @@ void GuiInspectorType3DValue::constructEditControlChildren(GuiControl* retCtrl, { Parent::constructEditControlChildren(retCtrl, width); - mCtrlZ = new GuiTextEditSliderCtrl(); + mCtrlZ = new GuiTextEditCtrl(); _registerEditControl(mCtrlZ, "z"); mLabelZ = new GuiControl(); _registerEditControl(mLabelZ, "lz"); @@ -1953,16 +1956,22 @@ void GuiInspectorType3DValue::constructEditControlChildren(GuiControl* retCtrl, mCtrlZ->setPosition(Point2I(labelWidth, 0)); - char szBuffer[512]; - dSprintf(szBuffer, 512, "%d.apply(%d.getText() SPC %d.getText() SPC %d.getText());", getId(), mCtrlX->getId(), mCtrlY->getId(), mCtrlZ->getId()); + char szXCBuffer[512]; + dSprintf(szXCBuffer, 512, "%d.applyWord(0, %d.getText());", getId(), mCtrlX->getId()); - mCtrlX->setField("AltCommand", szBuffer); - mCtrlY->setField("AltCommand", szBuffer); - mCtrlZ->setField("AltCommand", szBuffer); + char szYCBuffer[512]; + dSprintf(szYCBuffer, 512, "%d.applyWord(1, %d.getText());", getId(), mCtrlY->getId()); - mCtrlX->setField("Validate", szBuffer); - mCtrlY->setField("Validate", szBuffer); - mCtrlZ->setField("Validate", szBuffer); + char szZCBuffer[512]; + dSprintf(szZCBuffer, 512, "%d.applyWord(2, %d.getText());", getId(), mCtrlZ->getId()); + + mCtrlX->setField("AltCommand", szXCBuffer); + mCtrlY->setField("AltCommand", szYCBuffer); + mCtrlZ->setField("AltCommand", szZCBuffer); + + mCtrlX->setField("Validate", szXCBuffer); + mCtrlY->setField("Validate", szYCBuffer); + mCtrlZ->setField("Validate", szZCBuffer); mContainerZ = new GuiControl(); mContainerZ->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile"); @@ -2057,18 +2066,27 @@ void GuiInspectorType4DValue::constructEditControlChildren(GuiControl* retCtrl, mCtrlW->setPosition(Point2I(labelWidth, 0)); - char szBuffer[512]; - dSprintf(szBuffer, 512, "%d.apply(%d.getText() SPC %d.getText() SPC %d.getText() SPC %d.getText());", getId(), mCtrlX->getId(), mCtrlY->getId(), mCtrlZ->getId(), mCtrlW->getId()); + char szXCBuffer[512]; + dSprintf(szXCBuffer, 512, "%d.applyWord(0, %d.getText());", getId(), mCtrlX->getId()); - mCtrlX->setField("AltCommand", szBuffer); - mCtrlY->setField("AltCommand", szBuffer); - mCtrlZ->setField("AltCommand", szBuffer); - mCtrlW->setField("AltCommand", szBuffer); + char szYCBuffer[512]; + dSprintf(szYCBuffer, 512, "%d.applyWord(1, %d.getText());", getId(), mCtrlY->getId()); - mCtrlX->setField("Validate", szBuffer); - mCtrlY->setField("Validate", szBuffer); - mCtrlZ->setField("Validate", szBuffer); - mCtrlW->setField("Validate", szBuffer); + char szZCBuffer[512]; + dSprintf(szZCBuffer, 512, "%d.applyWord(2, %d.getText());", getId(), mCtrlZ->getId()); + + char szWCBuffer[512]; + dSprintf(szZCBuffer, 512, "%d.applyWord(3, %d.getText());", getId(), mCtrlW->getId()); + + mCtrlX->setField("AltCommand", szXCBuffer); + mCtrlY->setField("AltCommand", szYCBuffer); + mCtrlZ->setField("AltCommand", szZCBuffer); + mCtrlW->setField("AltCommand", szWCBuffer); + + mCtrlX->setField("Validate", szXCBuffer); + mCtrlY->setField("Validate", szYCBuffer); + mCtrlZ->setField("Validate", szZCBuffer); + mCtrlW->setField("Validate", szWCBuffer); GuiControl* mContainerW = new GuiControl(); mContainerW->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile"); diff --git a/Engine/source/gui/editor/guiInspectorTypes.h b/Engine/source/gui/editor/guiInspectorTypes.h index 12ce20c68..a123936e9 100644 --- a/Engine/source/gui/editor/guiInspectorTypes.h +++ b/Engine/source/gui/editor/guiInspectorTypes.h @@ -604,10 +604,10 @@ class GuiInspectorType2DValue : public GuiInspectorField private: typedef GuiInspectorField Parent; protected: - GuiTextEditSliderCtrl* mCtrlX; + GuiTextEditCtrl* mCtrlX; GuiControl* mLabelX; GuiControl* mContainerX; - GuiTextEditSliderCtrl* mCtrlY; + GuiTextEditCtrl* mCtrlY; GuiControl* mLabelY; GuiControl* mContainerY; GuiTextCtrl* mScriptValue; @@ -634,7 +634,7 @@ class GuiInspectorType3DValue : public GuiInspectorType2DValue private: typedef GuiInspectorType2DValue Parent; protected: - GuiTextEditSliderCtrl* mCtrlZ; + GuiTextEditCtrl* mCtrlZ; GuiControl* mLabelZ; GuiControl* mContainerZ; diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index 35f85f405..17350f325 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -264,6 +264,129 @@ void GuiInspectorField::onRightMouseUp( const GuiEvent &event ) } //----------------------------------------------------------------------------- +void GuiInspectorField::setWordData(const S32& wordIndex, const char* data, bool callbacks) +{ + if (mSpecialEditField) + { + if (mTargetObject != nullptr && mVariableName != StringTable->EmptyString()) + { + const char* fieldData = mTargetObject->getDataField(mVariableName, NULL); + + StringBuilder newFieldData; + const U32 wordCount = StringUnit::getUnitCount(fieldData, " \t\n"); + for (U32 i = 0; i < wordCount; i++) + { + if (i != 0) + newFieldData.append(" "); + + if (i == wordIndex) + newFieldData.append(data); + else + { + newFieldData.append(StringUnit::getUnit(fieldData, i, " \t\n")); + } + } + + mTargetObject->setDataField(mVariableName, NULL, newFieldData.end()); + + if (mCallbackName != StringTable->EmptyString()) + Con::executef(mInspector, mCallbackName, mVariableName, newFieldData.end(), mTargetObject); + } + else if (mVariableName != StringTable->EmptyString()) + { + const char* fieldData = Con::getVariable(mVariableName, ""); + + StringBuilder newFieldData; + const U32 wordCount = StringUnit::getUnitCount(fieldData, " \t\n"); + for (U32 i = 0; i < wordCount; i++) + { + if (i != 0) + newFieldData.append(" "); + + if (i == wordIndex) + newFieldData.append(data); + else + { + newFieldData.append(StringUnit::getUnit(fieldData, i, " \t\n")); + } + } + + Con::setVariable(mVariableName, newFieldData.end()); + + if (mCallbackName != StringTable->EmptyString()) + Con::executef(mInspector, mCallbackName, mVariableName, newFieldData.end()); + } + } + + if (mField == NULL) + return; + + if (verifyData(data)) + { + String strData = data; + const U32 numTargets = mInspector->getNumInspectObjects(); + + if (callbacks && numTargets > 1) + Con::executef(mInspector, "onBeginCompoundEdit"); + + for (U32 i = 0; i < numTargets; ++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); + } + + const char* fieldData = target->getDataField(mField->pFieldname, mFieldArrayIndex); + + StringBuilder newFieldData; + const U32 wordCount = StringUnit::getUnitCount(fieldData, " \t\n"); + for (U32 i = 0; i < wordCount; i++) + { + if (i != 0) + newFieldData.append(" "); + + if (i == wordIndex) + newFieldData.append(data); + else + { + newFieldData.append(StringUnit::getUnit(fieldData, i, " \t\n")); + } + } + + target->inspectPreApply(); + + // Fire callback single-object undo. + + if (callbacks && !mField->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + Con::executef(mInspector, "onInspectorFieldModified", + target->getIdString(), + mField->pFieldname, + mFieldArrayIndex ? mFieldArrayIndex : "(null)", + fieldData, + newFieldData.end()); + + target->setDataField(mField->pFieldname, mFieldArrayIndex, newFieldData.end()); + + // Give the target a chance to validate. + target->inspectPostApply(); + } + + if (callbacks && numTargets > 1) + Con::executef(mInspector, "onEndCompoundEdit"); + } + + // Force our edit to update + updateValue(); +} void GuiInspectorField::setData( const char* data, bool callbacks ) { @@ -762,6 +885,12 @@ DefineEngineMethod( GuiInspectorField, apply, void, ( const char * newValue, boo object->setData( newValue, callbacks ); } +//----------------------------------------------------------------------------- +DefineEngineMethod(GuiInspectorField, applyWord, void, (S32 wordIndex, const char* newValue, bool callbacks), (true), "( string newValue, bool callbacks=true ) - Set the field's value. Suppress callbacks for undo if callbacks=false.") +{ + object->setWordData(wordIndex, newValue, callbacks); +} + //----------------------------------------------------------------------------- DefineEngineMethod( GuiInspectorField, applyWithoutUndo, void, (const char * data), , "() - Set field value without recording undo (same as 'apply( value, false )')." ) diff --git a/Engine/source/gui/editor/inspector/field.h b/Engine/source/gui/editor/inspector/field.h index e04e9231b..a5057254d 100644 --- a/Engine/source/gui/editor/inspector/field.h +++ b/Engine/source/gui/editor/inspector/field.h @@ -167,6 +167,8 @@ class GuiInspectorField : public GuiControl /// to perform their own verification. virtual bool verifyData( StringTableEntry data ) { return true; } + void setWordData(const S32& wordIndex, const char* data, bool callbacks); + /// Set value of the field we are inspecting virtual void setData( const char* data, bool callbacks = true );