Merge pull request #1269 from Areloch/MultiObjectEditMadness

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'
This commit is contained in:
Brian Roberts 2024-05-01 23:21:15 -05:00 committed by GitHub
commit 67b052a192
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 281 additions and 39 deletions

View file

@ -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");
@ -1797,15 +1797,9 @@ void GuiInspectorType2DValue::constructEditControlChildren(GuiControl* retCtrl,
mCtrlX->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile");
mCtrlX->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mCtrlX->setDataField(StringTable->insert("format"), NULL, "%g");
mCtrlX->setDataField(StringTable->insert("range"), NULL, "-1e+32 1e+32");
mCtrlX->setDataField(StringTable->insert("increment"), NULL, "0.0001");
mCtrlY->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile");
mCtrlY->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mCtrlY->setDataField(StringTable->insert("format"), NULL, "%g");
mCtrlY->setDataField(StringTable->insert("range"), NULL, "-1e+32 1e+32");
mCtrlY->setDataField(StringTable->insert("increment"), NULL, "0.0001");
mLabelX->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiXDimensionText");
mLabelY->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiYDimensionText");
@ -1824,14 +1818,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,16 +1930,13 @@ void GuiInspectorType3DValue::constructEditControlChildren(GuiControl* retCtrl,
{
Parent::constructEditControlChildren(retCtrl, width);
mCtrlZ = new GuiTextEditSliderCtrl();
mCtrlZ = new GuiTextEditCtrl();
_registerEditControl(mCtrlZ, "z");
mLabelZ = new GuiControl();
_registerEditControl(mLabelZ, "lz");
mCtrlZ->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile");
mCtrlZ->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mCtrlZ->setDataField(StringTable->insert("format"), NULL, "%g");
mCtrlZ->setDataField(StringTable->insert("range"), NULL, "-1e+32 1e+32");
mCtrlZ->setDataField(StringTable->insert("increment"), NULL, "0.0001");
mLabelZ->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiZDimensionText");
@ -1953,16 +1947,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 +2057,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");

View file

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

View file

@ -264,6 +264,231 @@ 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);
const char* wordData = StringUnit::getUnit(fieldData, wordIndex, " \t\n");
S32 type = mField->type;
if (type == TypeS8 || type == TypeS32 || type == TypeF32 || type == TypeS32Vector
|| type == TypeF32Vector
|| type == TypeColorI
|| type == TypeColorF
|| type == TypePoint2I
|| type == TypePoint2F
|| type == TypePoint3F
|| type == TypePoint4F
|| type == TypeRectI
|| type == TypeRectF
|| type == TypeMatrixPosition
|| type == TypeMatrixRotation
|| type == TypeBox3F
|| type == TypeRectUV
|| type == TypeRotationF)
{
if (dAtof(wordData) != dAtof(data))
return;
}
else if(dStrEqual(wordData, data))
return;
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, "");
const char* wordData = StringUnit::getUnit(fieldData, wordIndex, " \t\n");
S32 type = mField->type;
if (type == TypeS8 || type == TypeS32 || type == TypeF32 || type == TypeS32Vector
|| type == TypeF32Vector
|| type == TypeColorI
|| type == TypeColorF
|| type == TypePoint2I
|| type == TypePoint2F
|| type == TypePoint3F
|| type == TypePoint4F
|| type == TypeRectI
|| type == TypeRectF
|| type == TypeMatrixPosition
|| type == TypeMatrixRotation
|| type == TypeBox3F
|| type == TypeRectUV
|| type == TypeRotationF)
{
if (dAtof(wordData) != dAtof(data))
return;
}
else if (dStrEqual(wordData, data))
return;
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();
bool changed = false;
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);
const char* wordData = StringUnit::getUnit(fieldData, wordIndex, " \t\n");
S32 type = mField->type;
if (type == TypeS8 || type == TypeS32 || type == TypeF32 || type == TypeS32Vector
|| type == TypeF32Vector
|| type == TypeColorI
|| type == TypeColorF
|| type == TypePoint2I
|| type == TypePoint2F
|| type == TypePoint3F
|| type == TypePoint4F
|| type == TypeRectI
|| type == TypeRectF
|| type == TypeMatrixPosition
|| type == TypeMatrixRotation
|| type == TypeBox3F
|| type == TypeRectUV
|| type == TypeRotationF)
{
if (dAtof(wordData) != dAtof(data))
{
changed = true;
break;
}
}
else if (!dStrEqual(wordData, data))
{
changed = true;
break;
}
}
if(!changed)
return;
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 +987,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 )')." )

View file

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