//----------------------------------------------------------------------------- // GuiInspectorDynamicGroup - inspectGroup override //----------------------------------------------------------------------------- bool GuiInspectorDynamicGroup::inspectGroup() { // clear the first responder if it's set mStack->clearFirstResponder(); // Clearing the fields and recreating them will more than likely be more // efficient than looking up existent fields, updating them, and then iterating // over existent fields and making sure they still exist, if not, deleting them. clearFields(); // Create a vector of the fields Vector< FieldEntry > flist; const U32 numTargets = mParent->getNumInspectObjects(); for( U32 i = 0; i < numTargets; ++ i ) { SimObject* target = mParent->getInspectObject( i ); // Then populate with fields SimFieldDictionary * fieldDictionary = target->getFieldDictionary(); for(SimFieldDictionaryIterator ditr(fieldDictionary); *ditr; ++ditr) { if( i == 0 ) { flist.increment(); flist.last().mEntry = *ditr; flist.last().mNumTargets = 1; } else { const U32 numFields = flist.size(); for( U32 n = 0; n < numFields; ++ n ) if( flist[ n ].mEntry->slotName == ( *ditr )->slotName ) { flist[ n ].mNumTargets ++; break; } } } } dQsort( flist.address(), flist.size(), sizeof( FieldEntry ), compareEntries ); for(U32 i = 0; i < flist.size(); i++) { if( flist[ i ].mNumTargets != numTargets ) continue; SimFieldDictionary::Entry* entry = flist[i].mEntry; // Create a dynamic field inspector. Can't reuse typed GuiInspectorFields as // these rely on AbstractClassRep::Fields. GuiInspectorDynamicField *field = new GuiInspectorDynamicField( mParent, this, entry ); // Register the inspector field and add it to our lists if( field->registerObject() ) { mChildren.push_back( field ); mStack->addObject( field ); } else delete field; } mStack->pushObjectToBack(mAddCtrl); setUpdate(); return true; }
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); } }