renames the engine method arg to avoid name confusion.
[Torque-3d.git] / Engine / source / gui / editor / guiInspector.cpp
blob77ab67365b19158b468e1c8a571591bc6d19bae4
1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2012 GarageGames, LLC
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
21 //-----------------------------------------------------------------------------
23 #include "console/engineAPI.h"
24 #include "gui/editor/guiInspector.h"
25 #include "gui/editor/inspector/field.h"
26 #include "gui/editor/inspector/group.h"
27 #include "gui/buttons/guiIconButtonCtrl.h"
28 #include "gui/editor/inspector/dynamicGroup.h"
29 #include "gui/containers/guiScrollCtrl.h"
30 #include "gui/editor/inspector/customField.h"
32 #ifdef TORQUE_EXPERIMENTAL_EC
33 #include "gui/editor/inspector/entityGroup.h"
34 #include "gui/editor/inspector/mountingGroup.h"
35 #include "gui/editor/inspector/componentGroup.h"
36 #endif
38 IMPLEMENT_CONOBJECT(GuiInspector);
40 ConsoleDocClass( GuiInspector,
41 "@brief A control that allows to edit the properties of one or more SimObjects.\n\n"
42 "Editor use only.\n\n"
43 "@internal"
47 //#define DEBUG_SPEW
50 //-----------------------------------------------------------------------------
52 GuiInspector::GuiInspector()
53 : mDividerPos( 0.35f ),
54 mDividerMargin( 5 ),
55 mOverDivider( false ),
56 mMovingDivider( false ),
57 mHLField( NULL ),
58 mShowCustomFields( true )
60 mPadding = 1;
63 //-----------------------------------------------------------------------------
65 GuiInspector::~GuiInspector()
67 clearGroups();
70 //-----------------------------------------------------------------------------
72 void GuiInspector::initPersistFields()
74 addGroup( "Inspector" );
76 addField( "dividerMargin", TypeS32, Offset( mDividerMargin, GuiInspector ) );
78 addField( "groupFilters", TypeRealString, Offset( mGroupFilters, GuiInspector ),
79 "Specify groups that should be shown or not. Specifying 'shown' implicitly does 'not show' all other groups. Example string: +name -otherName" );
81 addField( "showCustomFields", TypeBool, Offset( mShowCustomFields, GuiInspector ),
82 "If false the custom fields Name, Id, and Source Class will not be shown." );
84 endGroup( "Inspector" );
86 Parent::initPersistFields();
89 //-----------------------------------------------------------------------------
91 void GuiInspector::onRemove()
93 clearGroups();
94 Parent::onRemove();
97 //-----------------------------------------------------------------------------
99 void GuiInspector::onDeleteNotify( SimObject *object )
101 Parent::onDeleteNotify( object );
103 if( isInspectingObject( object ) )
104 removeInspectObject( object );
107 //-----------------------------------------------------------------------------
109 void GuiInspector::parentResized(const RectI &oldParentRect, const RectI &newParentRect)
111 GuiControl *parent = getParent();
112 if ( parent && dynamic_cast<GuiScrollCtrl*>(parent) != NULL )
114 GuiScrollCtrl *scroll = dynamic_cast<GuiScrollCtrl*>(parent);
115 setWidth( ( newParentRect.extent.x - ( scroll->scrollBarThickness() + 4 ) ) );
117 else
118 Parent::parentResized(oldParentRect,newParentRect);
121 //-----------------------------------------------------------------------------
123 bool GuiInspector::resize( const Point2I &newPosition, const Point2I &newExtent )
125 //F32 dividerPerc = (F32)getWidth() / (F32)mDividerPos;
127 bool result = Parent::resize( newPosition, newExtent );
129 //mDividerPos = (F32)getWidth() * dividerPerc;
131 updateDivider();
133 return result;
136 //-----------------------------------------------------------------------------
138 GuiControl* GuiInspector::findHitControl( const Point2I &pt, S32 initialLayer )
140 if ( mOverDivider || mMovingDivider )
141 return this;
143 return Parent::findHitControl( pt, initialLayer );
146 //-----------------------------------------------------------------------------
148 void GuiInspector::getCursor( GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent )
150 GuiCanvas *pRoot = getRoot();
151 if( !pRoot )
152 return;
154 S32 desiredCursor = mOverDivider ? PlatformCursorController::curResizeVert : PlatformCursorController::curArrow;
156 // Bail if we're already at the desired cursor
157 if ( pRoot->mCursorChanged == desiredCursor )
158 return;
160 PlatformWindow *pWindow = static_cast<GuiCanvas*>(getRoot())->getPlatformWindow();
161 AssertFatal(pWindow != NULL,"GuiControl without owning platform window! This should not be possible.");
162 PlatformCursorController *pController = pWindow->getCursorController();
163 AssertFatal(pController != NULL,"PlatformWindow without an owned CursorController!");
165 // Now change the cursor shape
166 pController->popCursor();
167 pController->pushCursor(desiredCursor);
168 pRoot->mCursorChanged = desiredCursor;
171 //-----------------------------------------------------------------------------
173 void GuiInspector::onMouseMove(const GuiEvent &event)
175 if ( collideDivider( globalToLocalCoord( event.mousePoint ) ) )
176 mOverDivider = true;
177 else
178 mOverDivider = false;
181 //-----------------------------------------------------------------------------
183 void GuiInspector::onMouseDown(const GuiEvent &event)
185 if ( mOverDivider )
187 mMovingDivider = true;
191 //-----------------------------------------------------------------------------
193 void GuiInspector::onMouseUp(const GuiEvent &event)
195 mMovingDivider = false;
198 //-----------------------------------------------------------------------------
200 void GuiInspector::onMouseDragged(const GuiEvent &event)
202 if ( !mMovingDivider )
203 return;
205 Point2I localPnt = globalToLocalCoord( event.mousePoint );
207 S32 inspectorWidth = getWidth();
209 // Distance from mouse/divider position in local space
210 // to the right edge of the inspector
211 mDividerPos = inspectorWidth - localPnt.x;
212 mDividerPos = mClamp( mDividerPos, 0, inspectorWidth );
214 // Divide that by the inspectorWidth to get a percentage
215 mDividerPos /= inspectorWidth;
217 updateDivider();
220 //-----------------------------------------------------------------------------
222 GuiInspectorGroup* GuiInspector::findExistentGroup( StringTableEntry groupName )
224 // If we have no groups, it couldn't possibly exist
225 if( mGroups.empty() )
226 return NULL;
228 // Attempt to find it in the group list
229 Vector<GuiInspectorGroup*>::iterator i = mGroups.begin();
231 for( ; i != mGroups.end(); i++ )
233 if( dStricmp( (*i)->getGroupName(), groupName ) == 0 )
234 return *i;
237 return NULL;
240 //-----------------------------------------------------------------------------
242 void GuiInspector::updateFieldValue( StringTableEntry fieldName, StringTableEntry arrayIdx )
244 // We don't know which group contains the field of this name,
245 // so ask each group in turn, and break when a group returns true
246 // signifying it contained and updated that field.
248 Vector<GuiInspectorGroup*>::iterator groupIter = mGroups.begin();
250 for( ; groupIter != mGroups.end(); groupIter++ )
252 if ( (*groupIter)->updateFieldValue( fieldName, arrayIdx ) )
253 break;
257 //-----------------------------------------------------------------------------
259 void GuiInspector::clearGroups()
261 #ifdef DEBUG_SPEW
262 Platform::outputDebugString( "[GuiInspector] Clearing %i (%s)", getId(), getName() );
263 #endif
265 // If we have no groups, there's nothing to clear!
266 if( mGroups.empty() )
267 return;
269 mHLField = NULL;
271 if( isMethod( "onClear" ) )
272 Con::executef( this, "onClear" );
274 Vector<GuiInspectorGroup*>::iterator i = mGroups.begin();
276 freeze(true);
278 // Delete Groups
279 for( ; i != mGroups.end(); i++ )
281 if((*i) && (*i)->isProperlyAdded())
282 (*i)->deleteObject();
285 mGroups.clear();
287 freeze(false);
288 updatePanes();
291 //-----------------------------------------------------------------------------
293 bool GuiInspector::isInspectingObject( SimObject* object )
295 const U32 numTargets = mTargets.size();
296 for( U32 i = 0; i < numTargets; ++ i )
297 if( mTargets[ i ] == object )
298 return true;
300 return false;
303 //-----------------------------------------------------------------------------
305 void GuiInspector::inspectObject( SimObject *object )
307 if( mTargets.size() > 1 || !isInspectingObject( object ) )
308 clearInspectObjects();
310 addInspectObject( object );
313 //-----------------------------------------------------------------------------
315 void GuiInspector::clearInspectObjects()
317 const U32 numTargets = mTargets.size();
318 for( U32 i = 0; i < numTargets; ++ i )
319 clearNotify( mTargets[ i ] );
321 clearGroups();
322 mTargets.clear();
325 //-----------------------------------------------------------------------------
327 void GuiInspector::addInspectObject( SimObject* object, bool autoSync )
329 // If we are already inspecting the object, just update the groups.
331 if( isInspectingObject( object ) )
333 #ifdef DEBUG_SPEW
334 Platform::outputDebugString( "[GuiInspector] Refreshing view of %i:%s (%s)",
335 object->getId(), object->getClassName(), object->getName() );
336 #endif
338 Vector<GuiInspectorGroup*>::iterator i = mGroups.begin();
339 for ( ; i != mGroups.end(); i++ )
340 (*i)->updateAllFields();
342 return;
345 #ifdef DEBUG_SPEW
346 Platform::outputDebugString( "[GuiInspector] Adding %i:%s (%s) to inspect set",
347 object->getId(), object->getClassName(), object->getName() );
348 #endif
350 // Give users a chance to customize fields on this object
351 if( object->isMethod("onDefineFieldTypes") )
352 Con::executef( object, "onDefineFieldTypes" );
354 // Set Target
355 mTargets.push_back( object );
356 deleteNotify( object );
358 if( autoSync )
359 refresh();
362 //-----------------------------------------------------------------------------
364 void GuiInspector::removeInspectObject( SimObject* object )
366 const U32 numTargets = mTargets.size();
367 for( U32 i = 0; i < numTargets; ++ i )
368 if( mTargets[ i ] == object )
370 // Delete all inspector data *before* removing the target so that apply calls
371 // triggered by edit controls losing focus will not find the inspect object
372 // gone.
374 clearGroups();
376 #ifdef DEBUG_SPEW
377 Platform::outputDebugString( "[GuiInspector] Removing %i:%s (%s) from inspect set",
378 object->getId(), object->getClassName(), object->getName() );
379 #endif
381 mTargets.erase( i );
382 clearNotify( object );
384 // Refresh the inspector except if the system is going down.
386 if( !Sim::isShuttingDown() )
387 refresh();
389 return;
393 //-----------------------------------------------------------------------------
395 void GuiInspector::setName( StringTableEntry newName )
397 if( mTargets.size() != 1 )
398 return;
400 StringTableEntry name = StringTable->insert(newName);
402 // Only assign a new name if we provide one
403 mTargets[ 0 ]->assignName(name);
406 //-----------------------------------------------------------------------------
408 bool GuiInspector::collideDivider( const Point2I &localPnt )
410 RectI divisorRect( getWidth() - getWidth() * mDividerPos - mDividerMargin, 0, mDividerMargin * 2, getHeight() );
412 if ( divisorRect.pointInRect( localPnt ) )
413 return true;
415 return false;
418 //-----------------------------------------------------------------------------
420 void GuiInspector::updateDivider()
422 for ( U32 i = 0; i < mGroups.size(); i++ )
423 for ( U32 j = 0; j < mGroups[i]->mChildren.size(); j++ )
424 mGroups[i]->mChildren[j]->updateRects();
426 //setUpdate();
429 //-----------------------------------------------------------------------------
431 void GuiInspector::getDivider( S32 &pos, S32 &margin )
433 pos = (F32)getWidth() * mDividerPos;
434 margin = mDividerMargin;
437 //-----------------------------------------------------------------------------
439 void GuiInspector::setHighlightField( GuiInspectorField *field )
441 if ( mHLField == field )
442 return;
444 if ( mHLField.isValid() )
445 mHLField->setHLEnabled( false );
446 mHLField = field;
448 // We could have been passed a null field, meaning, set no field highlighted.
449 if ( mHLField.isNull() )
450 return;
452 mHLField->setHLEnabled( true );
455 //-----------------------------------------------------------------------------
457 bool GuiInspector::isGroupFiltered( const char *groupName ) const
459 // Internal and Ungrouped always filtered, we never show them.
460 if ( dStricmp( groupName, "Internal" ) == 0 ||
461 dStricmp( groupName, "Ungrouped" ) == 0 ||
462 dStricmp( groupName, "AdvCoordManipulation" ) == 0)
463 return true;
465 // Normal case, determine if filtered by looking at the mGroupFilters string.
466 String searchStr;
468 // Is this group explicitly show? Does it immediately follow a + char.
469 searchStr = String::ToString( "+%s", groupName );
470 if ( mGroupFilters.find( searchStr ) != String::NPos )
471 return false;
473 // Were there any other + characters, if so, we are implicitly hidden.
474 if ( mGroupFilters.find( "+" ) != String::NPos )
475 return true;
477 // Is this group explicitly hidden? Does it immediately follow a - char.
478 searchStr = String::ToString( "-%s", groupName );
479 if ( mGroupFilters.find( searchStr ) != String::NPos )
480 return true;
482 return false;
485 //-----------------------------------------------------------------------------
487 bool GuiInspector::isGroupExplicitlyFiltered( const char *groupName ) const
489 String searchStr;
491 searchStr = String::ToString( "-%s", groupName );
493 if ( mGroupFilters.find( searchStr ) != String::NPos )
494 return true;
496 return false;
499 //-----------------------------------------------------------------------------
501 void GuiInspector::setObjectField( const char *fieldName, const char *data )
503 GuiInspectorField *field;
505 for ( S32 i = 0; i < mGroups.size(); i++ )
507 field = mGroups[i]->findField( fieldName );
509 if( field )
511 field->setData( data );
512 return;
517 //-----------------------------------------------------------------------------
519 static SimObject *sgKeyObj = NULL;
521 bool findInspectors( GuiInspector *obj )
523 if ( obj->isAwake() && obj->isInspectingObject( sgKeyObj ) )
524 return true;
526 return false;
529 //-----------------------------------------------------------------------------
531 GuiInspector* GuiInspector::findByObject( SimObject *obj )
533 sgKeyObj = obj;
535 Vector< GuiInspector* > found;
536 Sim::getGuiGroup()->findObjectByCallback( findInspectors, found );
538 if ( found.empty() )
539 return NULL;
541 return found.first();
544 //-----------------------------------------------------------------------------
546 void GuiInspector::refresh()
548 clearGroups();
550 // Remove any inspect object that happened to have
551 // already been killed.
553 for( U32 i = 0; i < mTargets.size(); ++ i )
554 if( !mTargets[ i ] )
556 mTargets.erase( i );
557 -- i;
560 if( !mTargets.size() )
561 return;
563 // Special group for fields which should appear at the top of the
564 // list outside of a rollout control.
566 GuiInspectorGroup *ungroup = NULL;
567 if( mTargets.size() == 1 )
569 ungroup = new GuiInspectorGroup( "Ungrouped", this );
570 ungroup->setHeaderHidden( true );
571 ungroup->setCanCollapse( false );
573 ungroup->registerObject();
574 mGroups.push_back( ungroup );
575 addObject( ungroup );
578 // Put the 'transform' group first
579 GuiInspectorGroup *transform = new GuiInspectorGroup( "Transform", this );
581 transform->registerObject();
582 mGroups.push_back(transform);
583 addObject(transform);
585 // Always create the 'general' group (for fields without a group)
586 GuiInspectorGroup *general = new GuiInspectorGroup( "General", this );
588 general->registerObject();
589 mGroups.push_back(general);
590 addObject(general);
592 #ifdef TORQUE_EXPERIMENTAL_EC
593 //Entity inspector group
594 if (mTargets.first()->getClassRep()->isSubclassOf("Entity"))
596 GuiInspectorEntityGroup *components = new GuiInspectorEntityGroup("Components", this);
597 if (components != NULL)
599 components->registerObject();
600 mGroups.push_back(components);
601 addObject(components);
604 //Mounting group override
605 GuiInspectorGroup *mounting = new GuiInspectorMountingGroup("Mounting", this);
606 if (mounting != NULL)
608 mounting->registerObject();
609 mGroups.push_back(mounting);
610 addObject(mounting);
614 if (mTargets.first()->getClassRep()->isSubclassOf("Component"))
616 //Build the component field groups as the component describes it
617 Component* comp = dynamic_cast<Component*>(mTargets.first().getPointer());
619 if (comp->getComponentFieldCount() > 0)
621 GuiInspectorComponentGroup *compGroup = new GuiInspectorComponentGroup("Component Fields", this);
622 compGroup->registerObject();
623 mGroups.push_back(compGroup);
624 addObject(compGroup);
627 #endif
629 // Create the inspector groups for static fields.
631 for( TargetVector::iterator iter = mTargets.begin(); iter != mTargets.end(); ++ iter )
633 AbstractClassRep::FieldList &fieldList = ( *iter )->getModifiableFieldList();
635 // Iterate through, identifying the groups and create necessary GuiInspectorGroups
636 for( AbstractClassRep::FieldList::iterator itr = fieldList.begin(); itr != fieldList.end(); itr++ )
638 if ( itr->type == AbstractClassRep::StartGroupFieldType )
640 GuiInspectorGroup* group = findExistentGroup( itr->pGroupname );
642 if( !group && !isGroupFiltered( itr->pGroupname ) )
644 GuiInspectorGroup *group = new GuiInspectorGroup( itr->pGroupname, this );
646 group->registerObject();
647 if( !group->getNumFields() )
649 #ifdef DEBUG_SPEW
650 Platform::outputDebugString( "[GuiInspector] Removing empty group '%s'",
651 group->getCaption().c_str() );
652 #endif
654 // The group ended up having no fields. Remove it.
655 group->deleteObject();
657 else
659 mGroups.push_back( group );
660 addObject( group );
667 // Deal with dynamic fields
668 if ( !isGroupFiltered( "Dynamic Fields" ) )
670 GuiInspectorGroup *dynGroup = new GuiInspectorDynamicGroup( "Dynamic Fields", this);
672 dynGroup->registerObject();
673 mGroups.push_back( dynGroup );
674 addObject( dynGroup );
677 if( mShowCustomFields && mTargets.size() == 1 )
679 SimObject* object = mTargets.first();
681 // Add the SimObjectID field to the ungrouped group.
683 GuiInspectorCustomField* field = new GuiInspectorCustomField();
684 field->init( this, ungroup );
686 if( field->registerObject() )
688 ungroup->mChildren.push_back( field );
689 ungroup->mStack->addObject( field );
691 static StringTableEntry sId = StringTable->insert( "id" );
693 field->setCaption( sId );
694 field->setData( object->getIdString() );
695 field->setDoc( "SimObjectId of this object. [Read Only]" );
697 else
698 delete field;
700 // Add the Source Class field to the ungrouped group.
702 field = new GuiInspectorCustomField();
703 field->init( this, ungroup );
705 if( field->registerObject() )
707 ungroup->mChildren.push_back( field );
708 ungroup->mStack->addObject( field );
710 StringTableEntry sSourceClass = StringTable->insert( "Source Class", true );
711 field->setCaption( sSourceClass );
712 field->setData( object->getClassName() );
714 Namespace* ns = object->getClassRep()->getNameSpace();
715 field->setToolTip( Con::getNamespaceList( ns ) );
717 field->setDoc( "Native class of this object. [Read Only]" );
719 else
720 delete field;
724 // If the general group is still empty at this point ( or filtered ), kill it.
725 if ( isGroupFiltered( "General" ) || general->mStack->size() == 0 )
727 for(S32 i=0; i<mGroups.size(); i++)
729 if ( mGroups[i] == general )
731 mGroups.erase(i);
732 general->deleteObject();
733 updatePanes();
735 break;
740 // If transform turns out to be empty or filtered, remove it
741 if( isGroupFiltered( "Transform" ) || transform->mStack->size() == 0 )
743 for(S32 i=0; i<mGroups.size(); i++)
745 if ( mGroups[i] == transform )
747 mGroups.erase(i);
748 transform->deleteObject();
749 updatePanes();
751 break;
756 // If ungrouped is empty or explicitly filtered, remove it.
757 if( ungroup && ( isGroupExplicitlyFiltered( "Ungrouped" ) || ungroup->getNumFields() == 0 ) )
759 for(S32 i=0; i<mGroups.size(); i++)
761 if ( mGroups[i] == ungroup )
763 mGroups.erase(i);
764 ungroup->deleteObject();
765 updatePanes();
767 break;
772 // If the object cannot be renamed, deactivate the name field if we have it.
774 if( ungroup && getNumInspectObjects() == 1 && !getInspectObject()->isNameChangeAllowed() )
776 GuiInspectorField* nameField = ungroup->findField( "name" );
777 if( nameField )
778 nameField->setActive( false );
782 //-----------------------------------------------------------------------------
784 void GuiInspector::sendInspectPreApply()
786 const U32 numObjects = getNumInspectObjects();
787 for( U32 i = 0; i < numObjects; ++ i )
788 getInspectObject( i )->inspectPreApply();
791 //-----------------------------------------------------------------------------
793 void GuiInspector::sendInspectPostApply()
795 const U32 numObjects = getNumInspectObjects();
796 for( U32 i = 0; i < numObjects; ++ i )
797 getInspectObject( i )->inspectPostApply();
800 //=============================================================================
801 // Console Methods.
802 //=============================================================================
803 // MARK: ---- Console Methods ----
805 //-----------------------------------------------------------------------------
806 DefineEngineMethod( GuiInspector, inspect, void, (const char* simObject), (""),
807 "Inspect the given object.\n"
808 "@param simObject Object to inspect.")
810 SimObject * target = Sim::findObject(simObject);
811 if(!target)
813 if(dAtoi(simObject) > 0)
814 Con::warnf("%s::inspect(): invalid object: %s", object->getClassName(), simObject);
816 object->clearInspectObjects();
817 return;
820 object->inspectObject(target);
823 //-----------------------------------------------------------------------------
825 DefineEngineMethod( GuiInspector, addInspect, void, (const char* simObject, bool autoSync), (true),
826 "Add the object to the list of objects being inspected.\n"
827 "@param simObject Object to add to the inspection."
828 "@param autoSync Auto sync the values when they change.")
830 SimObject* obj;
831 if( !Sim::findObject( simObject, obj ) )
833 Con::errorf( "%s::addInspect(): invalid object: %s", object->getClassName(), simObject );
834 return;
837 object->addInspectObject( obj, autoSync );
840 //-----------------------------------------------------------------------------
842 DefineEngineMethod( GuiInspector, removeInspect, void, (const char* simObject), ,
843 "Remove the object from the list of objects being inspected.\n"
844 "@param simObject Object to remove from the inspection.")
846 SimObject* obj;
847 if( !Sim::findObject( simObject, obj ) )
849 Con::errorf( "%s::removeInspect(): invalid object: %s", object->getClassName(), simObject );
850 return;
853 object->removeInspectObject( obj );
856 //-----------------------------------------------------------------------------
858 DefineEngineMethod( GuiInspector, refresh, void, (), ,
859 "Re-inspect the currently selected object.\n")
861 if ( object->getNumInspectObjects() == 0 )
862 return;
864 SimObject *target = object->getInspectObject();
865 if ( target )
866 object->inspectObject( target );
869 //-----------------------------------------------------------------------------
871 DefineEngineMethod( GuiInspector, getInspectObject, const char*, (S32 index), (0),
872 "Returns currently inspected object.\n"
873 "@param index Index of object in inspection list you want to get."
874 "@return object being inspected.")
877 if( index < 0 || index >= object->getNumInspectObjects() )
879 Con::errorf( "GuiInspector::getInspectObject() - index out of range: %i", index );
880 return "";
883 return object->getInspectObject( index )->getIdString();
886 //-----------------------------------------------------------------------------
888 DefineEngineMethod( GuiInspector, getNumInspectObjects, S32, (), ,
889 "Return the number of objects currently being inspected.\n"
890 "@return number of objects currently being inspected.")
892 return object->getNumInspectObjects();
895 //-----------------------------------------------------------------------------
897 DefineEngineMethod( GuiInspector, setName, void, (const char* newObjectName), ,
898 "Rename the object being inspected (first object in inspect list).\n"
899 "@param newObjectName new name for object being inspected.")
901 object->setName(newObjectName);
904 //-----------------------------------------------------------------------------
906 DefineEngineMethod( GuiInspector, apply, void, (), ,
907 "Force application of inspected object's attributes.\n")
909 object->sendInspectPostApply();
912 //-----------------------------------------------------------------------------
914 DefineEngineMethod( GuiInspector, setObjectField, void, (const char* fieldname, const char* data ), ,
915 "Set a named fields value on the inspected object if it exists. This triggers all the usual callbacks that would occur if the field had been changed through the gui..\n"
916 "@param fieldname Field name on object we are inspecting we want to change."
917 "@param data New Value for the given field.")
919 object->setObjectField( fieldname, data );
922 //-----------------------------------------------------------------------------
924 DefineEngineMethod( GuiInspector, findByObject, S32, (SimObject* obj), ,
925 "Returns the id of an awake inspector that is inspecting the passed object if one exists\n"
926 "@param object Object to find away inspector for."
927 "@return id of an awake inspector that is inspecting the passed object if one exists, else NULL or 0.")
929 if ( !obj)
930 return NULL;
932 SimObject *inspector = GuiInspector::findByObject(obj);
934 if ( !inspector )
935 return NULL;
937 return inspector->getId();