void GuiInspectorDynamicField::setData( const char* data, bool callbacks ) { if ( mDynField == NULL ) return; const U32 numTargets = mInspector->getNumInspectObjects(); if( callbacks && numTargets > 1 ) { mInspector->beginCompoundUndo_callback(); } // Setting an empty string will kill the field. const bool isRemoval = !data[ 0 ]; for( U32 i = 0; i < numTargets; ++ i ) { SimObject* target = mInspector->getInspectObject( i ); // Callback on the inspector when the field is modified // to allow creation of undo/redo actions. const char *oldData = target->getDataField( mDynField->slotName, NULL ); if ( !oldData ) oldData = ""; if ( dStrcmp( oldData, data ) != 0 ) { target->inspectPreApply(); if( callbacks ) { if( isRemoval ) { mInspector->onFieldRemoved_callback( target->getIdString(), mDynField->slotName ); } else { mInspector->onInspectorFieldModified_callback( target->getIdString(), mDynField->slotName,"(null)", oldData, data ); } } target->setDataField( mDynField->slotName, NULL, data ); // give the target a chance to validate target->inspectPostApply(); } } if( callbacks && numTargets > 1 ) { mInspector->endCompoundUndo_callback(); } // Force our edit to update updateValue(); }
void GuiInspectorField::setData( const char* data, bool callbacks ) { if( mField == NULL ) return; if( verifyData( data ) ) { String strData = data; const U32 numTargets = mInspector->getNumInspectObjects(); if( callbacks && numTargets > 1 ) { mInspector->onBeginCompoundEdit_callback(); } for( U32 i = 0; i < numTargets; ++ i ) { SimObject* target = mInspector->getInspectObject( i ); String oldValue = target->getDataField( mField->pFieldname, mFieldArrayIndex); // For numeric fields, allow input expressions. String newValue = strData; S32 type= mField->type; if( type == TypeS8 || type == TypeS32 || type == TypeF32 ) { char buffer[ 2048 ]; expandEscape( buffer, newValue ); newValue = Con::evaluatef( "%%f = \"%s\"; return ( %s );", oldValue.c_str(), buffer ); } else if( 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 ) { //TODO: we should actually take strings into account and not chop things up between quotes U32 numNewUnits = StringUnit::getUnitCount( newValue, " \t\n\r" ); StringBuilder strNew; bool isFirst = true; for( U32 n = 0; n < numNewUnits; ++ n ) { char oldComponentVal[ 1024 ]; StringUnit::getUnit( oldValue, n, " \t\n\r", oldComponentVal, sizeof( oldComponentVal ) ); char newComponentExpr[ 1024 ]; StringUnit::getUnit( newValue, n, " \t\n\r", newComponentExpr, sizeof( newComponentExpr ) ); char buffer[ 2048 ]; expandEscape( buffer, newComponentExpr ); const char* newComponentVal = Con::evaluatef( "%%f = \"%s\"; %%v = \"%s\"; return ( %s );", oldComponentVal, oldValue.c_str(), buffer ); if( !isFirst ) strNew.append( ' ' ); strNew.append( newComponentVal ); isFirst = false; } newValue = strNew.end(); } target->inspectPreApply(); // Fire callback single-object undo. if( callbacks ) { mInspector->onInspectorFieldModified_callback( target->getIdString(), mField->pFieldname, mFieldArrayIndex ? mFieldArrayIndex : "(null)", oldValue.c_str(), newValue.c_str() ); } target->setDataField( mField->pFieldname, mFieldArrayIndex, newValue ); // Give the target a chance to validate. target->inspectPostApply(); } if( callbacks && numTargets > 1 ) { mInspector->onEndCompoundEdit_callback(); } } // Force our edit to update updateValue(); }
void GuiInspectorDynamicField::renameField( const char* newFieldName ) { newFieldName = StringTable->insert( newFieldName ); if ( mDynField == NULL || mParent == NULL || mEdit == NULL ) { Con::warnf("GuiInspectorDynamicField::renameField - No target object or dynamic field data found!" ); return; } if ( !newFieldName ) { Con::warnf("GuiInspectorDynamicField::renameField - Invalid field name specified!" ); return; } // Only proceed if the name has changed if ( dStricmp( newFieldName, getFieldName() ) == 0 ) return; // Grab a pointer to our parent and cast it to GuiInspectorDynamicGroup GuiInspectorDynamicGroup *group = dynamic_cast<GuiInspectorDynamicGroup*>(mParent); if ( group == NULL ) { Con::warnf("GuiInspectorDynamicField::renameField - Unable to locate GuiInspectorDynamicGroup parent!" ); return; } const U32 numTargets = mInspector->getNumInspectObjects(); if( numTargets > 1 ) { mInspector->onBeginCompoundEdit_callback(); } const char* oldFieldName = getFieldName(); SimFieldDictionary::Entry* newEntry = NULL; for( U32 i = 0; i < numTargets; ++ i ) { SimObject* target = mInspector->getInspectObject( i ); // Make sure the new field is not already defined as a static field // on the object. if( target->isField( newFieldName ) ) { // New field is already defined. If we can, let the scripts handle // the error. Otherwise, just emit an error on the console and proceed. if( numTargets == 1 ) { mInspector->onFieldRenameAlreadyDefined_callback( target->getIdString(), oldFieldName, newFieldName ); } else { Con::errorf( "GuiInspectorDynamicField::renameField - field '%s' is already defined on %i:%s (%s)", newFieldName, target->getId(), target->getClassName(), target->getName() ); } // Reset the text entry. if( mRenameCtrl ) mRenameCtrl->setText( oldFieldName ); continue; } char currentValue[1024] = {0}; // Grab our current dynamic field value (we use a temporary buffer as this gets corrupted upon Con::eval) dSprintf( currentValue, sizeof( currentValue ), "%s", target->getDataField( oldFieldName, NULL ) ); // Unset the old field and set the new field. target->setDataField( oldFieldName, NULL, "" ); target->setDataField( newFieldName, NULL, currentValue ); // Notify script. mInspector->onFieldRenamed_callback( target->getIdString(), oldFieldName, newFieldName ); // Look up the new SimFieldDictionary entry. if( !newEntry ) { newEntry = target->getFieldDictionary()->findDynamicField( newFieldName ); if( !newEntry ) { Con::warnf( "GuiInspectorDynamicField::renameField - could not find new field '%s' on object %i:%s (%s)", newFieldName, target->getId(), target->getClassName(), target->getName() ); } mDynField = newEntry; } } if( numTargets > 1 ) { mInspector->onEndCompoundEdit_callback(); } // Lastly we need to reassign our validate field for our value edit control char szBuffer[1024]; dSprintf( szBuffer, sizeof( szBuffer ), "%d.apply(%d.getText());", getId(), mEdit->getId() ); mEdit->setField("validate", szBuffer ); if( mDeleteButton ) { dSprintf(szBuffer, sizeof( szBuffer ), "%d.apply("");%d.inspectGroup();", getId(), newFieldName, group->getId()); mDeleteButton->setField("Command", szBuffer); } }