Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

View file

@ -0,0 +1,129 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/editor/inspector/customField.h"
#include "gui/editor/guiInspector.h"
//-----------------------------------------------------------------------------
// GuiInspectorCustomField - Child class of GuiInspectorField
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT( GuiInspectorCustomField );
ConsoleDocClass( GuiInspectorCustomField,
"@brief A control that allows to edit the custom properties (text) of one or more SimObjects.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiInspectorCustomField::GuiInspectorCustomField( GuiInspector *inspector,
GuiInspectorGroup* parent,
SimFieldDictionary::Entry* field )
{
mInspector = inspector;
mParent = parent;
setBounds(0,0,100,20);
}
GuiInspectorCustomField::GuiInspectorCustomField()
{
mInspector = NULL;
mParent = NULL;
}
void GuiInspectorCustomField::setData( const char* data, bool callbacks )
{
mCustomValue = data;
// Force our edit to update
updateValue();
}
const char* GuiInspectorCustomField::getData( U32 inspectObjectIndex )
{
return mCustomValue;
}
void GuiInspectorCustomField::updateValue()
{
setValue( mCustomValue );
}
void GuiInspectorCustomField::setDoc( const char* doc )
{
mDoc = StringTable->insert( doc, true );
}
void GuiInspectorCustomField::setToolTip( StringTableEntry data )
{
static StringTableEntry sTooltipProfile = StringTable->insert( "tooltipProfile" );
static StringTableEntry sHoverTime = StringTable->insert( "hovertime" );
static StringTableEntry sTooltip = StringTable->insert( "tooltip" );
mEdit->setDataField( sTooltipProfile, NULL, "GuiToolTipProfile" );
mEdit->setDataField( sHoverTime, NULL, "1000" );
mEdit->setDataField( sTooltip, NULL, data );
}
bool GuiInspectorCustomField::onAdd()
{
if( !Parent::onAdd() )
return false;
return true;
}
void GuiInspectorCustomField::setInspectorField( AbstractClassRep::Field *field,
StringTableEntry caption,
const char*arrayIndex )
{
// Override the base just to be sure it doesn't get called.
// We don't use an AbstractClassRep::Field...
// mField = field;
// mCaption = StringTable->EmptyString();
// mRenameCtrl->setText( getFieldName() );
}
GuiControl* GuiInspectorCustomField::constructEditControl()
{
GuiControl* retCtrl = new GuiTextCtrl();
static StringTableEntry sProfile = StringTable->insert( "profile" );
retCtrl->setDataField( sProfile, NULL, "GuiInspectorTextEditProfile" );
// Register the object
retCtrl->registerObject();
return retCtrl;
}
void GuiInspectorCustomField::setValue( const char* newValue )
{
GuiTextCtrl *ctrl = dynamic_cast<GuiTextCtrl*>( mEdit );
if( ctrl != NULL )
ctrl->setText( newValue );
}
void GuiInspectorCustomField::_executeSelectedCallback()
{
Con::executef( mInspector, "onFieldSelected", mCaption, ConsoleBaseType::getType(TypeCaseString)->getTypeName(), mDoc );
}

View file

@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_CUSTOMFIELD_H_
#define _GUI_INSPECTOR_CUSTOMFIELD_H_
#include "console/simFieldDictionary.h"
#include "gui/editor/inspector/field.h"
class GuiInspectorCustomField : public GuiInspectorField
{
typedef GuiInspectorField Parent;
public:
GuiInspectorCustomField( GuiInspector *inspector, GuiInspectorGroup* parent, SimFieldDictionary::Entry* field );
GuiInspectorCustomField();
~GuiInspectorCustomField() {};
DECLARE_CONOBJECT( GuiInspectorCustomField );
virtual void setData( const char* data, bool callbacks = true );
virtual const char* getData( U32 inspectObjectIndex = 0 );
virtual void updateValue();
virtual StringTableEntry getFieldName() { return StringTable->EmptyString(); }
virtual void setDoc( const char* doc );
virtual void setToolTip( StringTableEntry data );
virtual bool onAdd();
virtual void setInspectorField( AbstractClassRep::Field *field,
StringTableEntry caption = NULL,
const char *arrayIndex = NULL );
virtual GuiControl* constructEditControl();
virtual void setValue( const char* newValue );
protected:
virtual void _executeSelectedCallback();
protected:
String mCustomValue;
StringTableEntry mDoc;
};
#endif // _GUI_INSPECTOR_DYNAMICFIELD_H_

View file

@ -0,0 +1,165 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "console/simBase.h"
#include "console/simDatablock.h"
#include "gui/editor/guiInspector.h"
#include "gui/editor/inspector/datablockField.h"
#include "gui/editor/inspector/group.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "gui/editor/inspector/datablockField.h"
#include "sfx/sfxTypes.h"
#include "sfx/sfxDescription.h"
#include "sfx/sfxEnvironment.h"
#include "sfx/sfxAmbience.h"
#include "sfx/sfxTrack.h"
//-----------------------------------------------------------------------------
// GuiInspectorDatablockField
// Field construction for datablock types
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorDatablockField);
ConsoleDocClass( GuiInspectorDatablockField,
"@brief Custom field type for datablock enumeration.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiInspectorDatablockField::GuiInspectorDatablockField( StringTableEntry className )
{
setClassName( className );
}
void GuiInspectorDatablockField::setClassName( StringTableEntry className )
{
if( !className || !className[ 0 ] )
mDesiredClass = NULL;
else
{
mDesiredClass = AbstractClassRep::findClassRep( className );
if( !mDesiredClass )
Con::errorf( "GuiInspectorDatablockField::setClassName - no class '%s' found!", className );
}
}
void GuiInspectorDatablockField::_populateMenu( GuiPopUpMenuCtrl* menu )
{
menu->addScheme( 1, ColorI( 80, 0, 0, 255 ), ColorI( 80, 0, 0, 255 ), ColorI( 80, 0, 0, 255 ) ); // For client-only coloring.
menu->addEntry( "", 0 ); // For unsetting.
SimSet* set = _getDatablockSet();
U32 id = 1;
for( SimSet::iterator iter = set->begin(); iter != set->end(); ++ iter )
{
SimDataBlock* datablock = dynamic_cast< SimDataBlock* >( *iter );
// Skip non-datablocks if we somehow encounter them.
if( !datablock )
continue;
// Ok, now we have to figure inheritance info.
if( datablock && ( !mDesiredClass || datablock->getClassRep()->isClass( mDesiredClass ) ) )
menu->addEntry( datablock->getName(), id ++, datablock->isClientOnly() ? 1 : 0 );
}
menu->sort();
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeSFXDescriptionName
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorTypeSFXDescriptionName);
ConsoleDocClass( GuiInspectorTypeSFXDescriptionName,
"@brief Inspector field type for SFXDescriptionName\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeSFXDescriptionName::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType( TypeSFXDescriptionName )->setInspectorFieldType( "GuiInspectorTypeSFXDescriptionName" );
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeSFXTrackName
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorTypeSFXTrackName);
ConsoleDocClass( GuiInspectorTypeSFXTrackName,
"@brief Inspector field type for SFXTrackName\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeSFXTrackName::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType( TypeSFXTrackName )->setInspectorFieldType( "GuiInspectorTypeSFXTrackName" );
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeSFXEnvironmentName
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorTypeSFXEnvironmentName);
ConsoleDocClass( GuiInspectorTypeSFXEnvironmentName,
"@brief Inspector field type for SFXEnvironment\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeSFXEnvironmentName::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType( TypeSFXEnvironmentName )->setInspectorFieldType( "GuiInspectorTypeSFXEnvironmentName" );
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeSFXAmbienceName
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorTypeSFXAmbienceName);
ConsoleDocClass( GuiInspectorTypeSFXAmbienceName,
"@brief Inspector field type for SFXAmbience\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeSFXAmbienceName::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType( TypeSFXAmbienceName )->setInspectorFieldType( "GuiInspectorTypeSFXAmbienceName" );
}

View file

@ -0,0 +1,134 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_DATABLOCKFIELD_H_
#define _GUI_INSPECTOR_DATABLOCKFIELD_H_
#include "gui/editor/guiInspectorTypes.h"
//-----------------------------------------------------------------------------
// GuiInspectorDatablockField - custom field type for datablock enumeration
//-----------------------------------------------------------------------------
class GuiInspectorDatablockField : public GuiInspectorTypeMenuBase
{
public:
typedef GuiInspectorTypeMenuBase Parent;
protected:
AbstractClassRep *mDesiredClass;
virtual SimSet* _getDatablockSet() const { return Sim::getDataBlockGroup(); }
virtual void _populateMenu( GuiPopUpMenuCtrl* menu );
public:
DECLARE_CONOBJECT(GuiInspectorDatablockField);
GuiInspectorDatablockField( StringTableEntry className );
GuiInspectorDatablockField() { mDesiredClass = NULL; };
void setClassName( StringTableEntry className );
};
//-----------------------------------------------------------------------------
// TypeSFXDescriptionName GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorTypeSFXDescriptionName : public GuiInspectorDatablockField
{
public:
typedef GuiInspectorDatablockField Parent;
protected:
virtual SimSet* _getDatablockSet() const { return Sim::getSFXDescriptionSet(); }
public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXDescriptionName);
static void consoleInit();
};
//-----------------------------------------------------------------------------
// TypeSFXTrackName GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorTypeSFXTrackName : public GuiInspectorDatablockField
{
public:
typedef GuiInspectorDatablockField Parent;
protected:
virtual SimSet* _getDatablockSet() const { return Sim::getSFXTrackSet(); }
public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXTrackName);
static void consoleInit();
};
//-----------------------------------------------------------------------------
// TypeSFXEnvironmentName GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorTypeSFXEnvironmentName : public GuiInspectorDatablockField
{
public:
typedef GuiInspectorDatablockField Parent;
protected:
virtual SimSet* _getDatablockSet() const { return Sim::getSFXEnvironmentSet(); }
public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXEnvironmentName);
static void consoleInit();
};
//-----------------------------------------------------------------------------
// TypeSFXAmbienceName GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorTypeSFXAmbienceName : public GuiInspectorDatablockField
{
public:
typedef GuiInspectorDatablockField Parent;
protected:
virtual SimSet* _getDatablockSet() const { return Sim::getSFXAmbienceSet(); }
public:
DECLARE_CONOBJECT(GuiInspectorTypeSFXAmbienceName);
static void consoleInit();
};
#endif

View file

@ -0,0 +1,321 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/editor/inspector/dynamicField.h"
#include "gui/editor/inspector/dynamicGroup.h"
#include "gui/editor/guiInspector.h"
#include "gui/buttons/guiIconButtonCtrl.h"
//-----------------------------------------------------------------------------
// GuiInspectorDynamicField - Child class of GuiInspectorField
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT( GuiInspectorDynamicField );
ConsoleDocClass( GuiInspectorDynamicField,
"@brief Custom field type for dynamic variable modification on SimObjects.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiInspectorDynamicField::GuiInspectorDynamicField( GuiInspector *inspector,
GuiInspectorGroup* parent,
SimFieldDictionary::Entry* field )
: mRenameCtrl( NULL ),
mDeleteButton( NULL )
{
mInspector = inspector;
mParent = parent;
mDynField = field;
setBounds(0,0,100,20);
}
void GuiInspectorDynamicField::setData( const char* data, bool callbacks )
{
if ( mDynField == NULL )
return;
const U32 numTargets = mInspector->getNumInspectObjects();
if( callbacks && numTargets > 1 )
Con::executef( mInspector, "beginCompoundUndo" );
// 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 )
Con::executef( mInspector, "onFieldRemoved", target->getIdString(), mDynField->slotName );
else
Con::executef( mInspector, "onInspectorFieldModified", target->getIdString(), mDynField->slotName, oldData, data );
}
target->setDataField( mDynField->slotName, NULL, data );
// give the target a chance to validate
target->inspectPostApply();
}
}
if( callbacks && numTargets > 1 )
Con::executef( mInspector, "endCompoundUndo" );
// Force our edit to update
updateValue();
}
const char* GuiInspectorDynamicField::getData( U32 inspectObjectIndex )
{
if( mDynField == NULL )
return "";
return mInspector->getInspectObject( inspectObjectIndex )->getDataField( mDynField->slotName, NULL );
}
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 )
Con::executef( mInspector, "onBeginCompoundEdit" );
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->isMethod( "onFieldRenameAlreadyDefined" ) )
Con::executef( mInspector, "onFieldRenameAlreadyDefined", 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.
Con::executef( mInspector, "onFieldRenamed", 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 )
Con::executef( mInspector, "onEndCompoundEdit" );
// 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);
}
}
bool GuiInspectorDynamicField::onAdd()
{
if( !Parent::onAdd() )
return false;
//pushObjectToBack(mEdit);
// Create our renaming field
mRenameCtrl = new GuiTextEditCtrl();
mRenameCtrl->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorDynamicFieldProfile" );
char szName[512];
dSprintf( szName, 512, "IE_%s_%d_%s_Rename", mRenameCtrl->getClassName(), mInspector->getInspectObject()->getId(), getFieldName() );
mRenameCtrl->registerObject( szName );
// Our command will evaluate to :
//
// if( (editCtrl).getText() !$= "" )
// (field).renameField((editCtrl).getText());
//
char szBuffer[1024];
dSprintf( szBuffer, sizeof( szBuffer ), "if( %d.getText() !$= \"\" ) %d.renameField(%d.getText());", mRenameCtrl->getId(), getId(), mRenameCtrl->getId() );
mRenameCtrl->setText( getFieldName() );
mRenameCtrl->setField("Validate", szBuffer );
addObject( mRenameCtrl );
// Resize the name control to fit in our caption rect
mRenameCtrl->resize( mCaptionRect.point, mCaptionRect.extent );
// Resize the value control to leave space for the delete button
mEdit->resize( mValueRect.point, mValueRect.extent);
// Clear out any caption set from Parent::onAdd
// since we are rendering the fieldname with our 'rename' control.
mCaption = StringTable->insert( "" );
// Create delete button control
mDeleteButton = new GuiBitmapButtonCtrl();
SimObject* profilePtr = Sim::findObject("InspectorDynamicFieldButton");
if( profilePtr != NULL )
mDeleteButton->setControlProfile( dynamic_cast<GuiControlProfile*>(profilePtr) );
dSprintf( szBuffer, sizeof( szBuffer ),
"%d.apply(\"\");%d.schedule(1,\"inspectGroup\");",
getId(),
mParent->getId() );
// FIXME Hardcoded image
mDeleteButton->setField( "Bitmap", "tools/gui/images/iconDelete" );
mDeleteButton->setField( "Text", "X" );
mDeleteButton->setField( "Command", szBuffer );
mDeleteButton->setSizing( horizResizeLeft, vertResizeCenter );
mDeleteButton->resize(Point2I(getWidth() - 20,2), Point2I(16, 16));
mDeleteButton->registerObject();
addObject(mDeleteButton);
return true;
}
bool GuiInspectorDynamicField::updateRects()
{
Point2I fieldExtent = getExtent();
S32 dividerPos, dividerMargin;
mInspector->getDivider( dividerPos, dividerMargin );
S32 editWidth = dividerPos - dividerMargin;
mEditCtrlRect.set( fieldExtent.x - dividerPos + dividerMargin, 1, editWidth, fieldExtent.y - 1 );
mCaptionRect.set( 0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y );
mValueRect.set( mEditCtrlRect.point, mEditCtrlRect.extent - Point2I( 20, 0 ) );
mDeleteRect.set( fieldExtent.x - 20, 2, 16, fieldExtent.y - 4 );
// This is probably being called during Parent::onAdd
// so our special controls haven't been created yet but are just about to
// so we just need to calculate the extents.
if ( mRenameCtrl == NULL )
return false;
bool sized0 = mRenameCtrl->resize( mCaptionRect.point, mCaptionRect.extent );
bool sized1 = mEdit->resize( mValueRect.point, mValueRect.extent );
bool sized2 = mDeleteButton->resize(Point2I(getWidth() - 20,2), Point2I(16, 16));
return ( sized0 || sized1 || sized2 );
}
void GuiInspectorDynamicField::setInspectorField( AbstractClassRep::Field *field,
StringTableEntry caption,
const char*arrayIndex )
{
// Override the base just to be sure it doesn't get called.
// We don't use an AbstractClassRep::Field...
// mField = field;
// mCaption = StringTable->EmptyString();
// mRenameCtrl->setText( getFieldName() );
}
void GuiInspectorDynamicField::_executeSelectedCallback()
{
ConsoleBaseType* type = mDynField->type;
if ( type )
Con::executef( mInspector, "onFieldSelected", mDynField->slotName, type->getTypeName() );
else
Con::executef( mInspector, "onFieldSelected", mDynField->slotName, "TypeDynamicField" );
}
ConsoleMethod( GuiInspectorDynamicField, renameField, void, 3,3, "field.renameField(newDynamicFieldName);" )
{
object->renameField( argv[ 2 ] );
}

View file

@ -0,0 +1,72 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_DYNAMICFIELD_H_
#define _GUI_INSPECTOR_DYNAMICFIELD_H_
#include "console/simFieldDictionary.h"
#include "gui/editor/inspector/field.h"
class GuiInspectorDynamicField : public GuiInspectorField
{
typedef GuiInspectorField Parent;
public:
GuiInspectorDynamicField( GuiInspector *inspector, GuiInspectorGroup* parent, SimFieldDictionary::Entry* field );
GuiInspectorDynamicField() {};
~GuiInspectorDynamicField() {};
DECLARE_CONOBJECT( GuiInspectorDynamicField );
virtual void setData( const char* data, bool callbacks = true );
virtual const char* getData( U32 inspectObjectIndex = 0 );
virtual StringTableEntry getFieldName() { return ( mDynField != NULL ) ? mDynField->slotName : StringTable->insert( "" ); }
virtual StringTableEntry getRawFieldName() { return getFieldName(); }
virtual bool onAdd();
void renameField( const char* newFieldName );
GuiControl* constructRenameControl();
virtual bool updateRects();
virtual void setInspectorField( AbstractClassRep::Field *field,
StringTableEntry caption = NULL,
const char *arrayIndex = NULL );
protected:
virtual void _executeSelectedCallback();
protected:
/// Dynamic field dictionary entry for first target object only.
SimFieldDictionary::Entry* mDynField;
SimObjectPtr<GuiTextEditCtrl> mRenameCtrl;
GuiBitmapButtonCtrl* mDeleteButton;
RectI mDeleteRect;
RectI mValueRect;
};
#endif // _GUI_INSPECTOR_DYNAMICFIELD_H_

View file

@ -0,0 +1,258 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/buttons/guiIconButtonCtrl.h"
#include "gui/editor/guiInspector.h"
#include "gui/editor/inspector/dynamicGroup.h"
#include "gui/editor/inspector/dynamicField.h"
IMPLEMENT_CONOBJECT(GuiInspectorDynamicGroup);
ConsoleDocClass( GuiInspectorDynamicGroup,
"@brief Used to inspect an object's FieldDictionary (dynamic fields) instead "
"of regular persistent fields.\n\n"
"Editor use only.\n\n"
"@internal"
);
//-----------------------------------------------------------------------------
// GuiInspectorDynamicGroup - add custom controls
//-----------------------------------------------------------------------------
bool GuiInspectorDynamicGroup::createContent()
{
if(!Parent::createContent())
return false;
// encapsulate the button in a dummy control.
GuiControl* shell = new GuiControl();
shell->setDataField( StringTable->insert("profile"), NULL, "GuiTransparentProfile" );
if( !shell->registerObject() )
{
delete shell;
return false;
}
// add a button that lets us add new dynamic fields.
GuiBitmapButtonCtrl* addFieldBtn = new GuiBitmapButtonCtrl();
{
SimObject* profilePtr = Sim::findObject("InspectorDynamicFieldButton");
if( profilePtr != NULL )
addFieldBtn->setControlProfile( dynamic_cast<GuiControlProfile*>(profilePtr) );
// FIXME Hardcoded image
addFieldBtn->setBitmap("tools/gui/images/iconAdd.png");
char commandBuf[64];
dSprintf(commandBuf, 64, "%d.addDynamicField();", this->getId());
addFieldBtn->setField("command", commandBuf);
addFieldBtn->setSizing(horizResizeLeft,vertResizeCenter);
//addFieldBtn->setField("buttonMargin", "2 2");
addFieldBtn->resize(Point2I(getWidth() - 20,2), Point2I(16, 16));
addFieldBtn->registerObject("zAddButton");
}
shell->resize(Point2I(0,0), Point2I(getWidth(), 28));
shell->addObject(addFieldBtn);
// save off the shell control, so we can push it to the bottom of the stack in inspectGroup()
mAddCtrl = shell;
mStack->addObject(shell);
return true;
}
struct FieldEntry
{
SimFieldDictionary::Entry* mEntry;
U32 mNumTargets;
};
static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b)
{
FieldEntry& fa = *((FieldEntry *)a);
FieldEntry& fb = *((FieldEntry *)b);
return dStrnatcmp(fa.mEntry->slotName, fb.mEntry->slotName);
}
//-----------------------------------------------------------------------------
// 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 GuiInspectorDynamicGroup::updateAllFields()
{
// We overload this to just reinspect the group.
inspectGroup();
}
ConsoleMethod(GuiInspectorDynamicGroup, inspectGroup, bool, 2, 2, "Refreshes the dynamic fields in the inspector.")
{
return object->inspectGroup();
}
void GuiInspectorDynamicGroup::clearFields()
{
// save mAddCtrl
Sim::getGuiGroup()->addObject(mAddCtrl);
// delete everything else
mStack->clear();
// clear the mChildren list.
mChildren.clear();
// and restore.
mStack->addObject(mAddCtrl);
}
SimFieldDictionary::Entry* GuiInspectorDynamicGroup::findDynamicFieldInDictionary( StringTableEntry fieldName )
{
SimFieldDictionary * fieldDictionary = mParent->getInspectObject()->getFieldDictionary();
for(SimFieldDictionaryIterator ditr(fieldDictionary); *ditr; ++ditr)
{
SimFieldDictionary::Entry * entry = (*ditr);
if( entry->slotName == fieldName )
return entry;
}
return NULL;
}
void GuiInspectorDynamicGroup::addDynamicField()
{
// We can't add a field without a target
if( !mStack )
{
Con::warnf("GuiInspectorDynamicGroup::addDynamicField - no target SimObject to add a dynamic field to.");
return;
}
// find a field name that is not in use.
// But we wont try more than 100 times to find an available field.
U32 uid = 1;
char buf[64] = "dynamicField";
SimFieldDictionary::Entry* entry = findDynamicFieldInDictionary(buf);
while(entry != NULL && uid < 100)
{
dSprintf(buf, sizeof(buf), "dynamicField%03d", uid++);
entry = findDynamicFieldInDictionary(buf);
}
const U32 numTargets = mParent->getNumInspectObjects();
if( numTargets > 1 )
Con::executef( mParent, "onBeginCompoundEdit" );
for( U32 i = 0; i < numTargets; ++ i )
{
SimObject* target = mParent->getInspectObject( i );
Con::evaluatef( "%d.dynamicField = \"defaultValue\";", target->getId(), buf );
// Notify script.
Con::executef( mParent, "onFieldAdded", target->getIdString(), buf );
}
if( numTargets > 1 )
Con::executef( mParent, "onEndCompoundEdit" );
// now we simply re-inspect the object, to see the new field.
inspectGroup();
instantExpand();
}
ConsoleMethod( GuiInspectorDynamicGroup, addDynamicField, void, 2, 2, "obj.addDynamicField();" )
{
object->addDynamicField();
}
ConsoleMethod( GuiInspectorDynamicGroup, removeDynamicField, void, 3, 3, "" )
{
}

View file

@ -0,0 +1,65 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_DYNAMICGROUP_H_
#define _GUI_INSPECTOR_DYNAMICGROUP_H_
#include "gui/editor/inspector/group.h"
#include "console/simFieldDictionary.h"
class GuiInspectorDynamicGroup : public GuiInspectorGroup
{
private:
typedef GuiInspectorGroup Parent;
GuiControl* mAddCtrl;
public:
DECLARE_CONOBJECT(GuiInspectorDynamicGroup);
GuiInspectorDynamicGroup() { /*mNeedScroll=false;*/ };
GuiInspectorDynamicGroup( StringTableEntry groupName, SimObjectPtr<GuiInspector> parent )
: GuiInspectorGroup( groupName, parent) { /*mNeedScroll=false;*/};
//-----------------------------------------------------------------------------
// inspectGroup is overridden in GuiInspectorDynamicGroup to inspect an
// objects FieldDictionary (dynamic fields) instead of regular persistent
// fields.
bool inspectGroup();
virtual void updateAllFields();
// For scriptable dynamic field additions
void addDynamicField();
// Clear our fields (delete them)
void clearFields();
// Find an already existent field by name in the dictionary
virtual SimFieldDictionary::Entry* findDynamicFieldInDictionary( StringTableEntry fieldName );
protected:
// create our inner controls when we add
virtual bool createContent();
};
#endif // _GUI_INSPECTOR_DYNAMICGROUP_H_

View file

@ -0,0 +1,666 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/editor/inspector/field.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "gui/editor/guiInspector.h"
#include "core/util/safeDelete.h"
#include "gfx/gfxDrawUtil.h"
#include "math/mathTypes.h"
#include "core/strings/stringUnit.h"
IMPLEMENT_CONOBJECT(GuiInspectorField);
ConsoleDocClass( GuiInspectorField,
"@brief The GuiInspectorField control is a representation of a single abstract "
"field for a given ConsoleObject derived object.\n\n"
"Editor use only.\n\n"
"@internal"
);
//-----------------------------------------------------------------------------
GuiInspectorField::GuiInspectorField( GuiInspector* inspector,
GuiInspectorGroup* parent,
AbstractClassRep::Field* field )
: mInspector( inspector ),
mParent( parent ),
mField( field ),
mFieldArrayIndex( NULL ),
mEdit( NULL )
{
if( field != NULL )
mCaption = field->pFieldname;
else
mCaption = StringTable->EmptyString();
setCanSave( false );
setBounds(0,0,100,18);
if( field )
_setFieldDocs( field->pFieldDocs );
}
//-----------------------------------------------------------------------------
GuiInspectorField::GuiInspectorField()
: mInspector( NULL ),
mParent( NULL ),
mEdit( NULL ),
mField( NULL ),
mFieldArrayIndex( NULL ),
mCaption( StringTable->EmptyString() ),
mHighlighted( false )
{
setCanSave( false );
}
//-----------------------------------------------------------------------------
GuiInspectorField::~GuiInspectorField()
{
}
//-----------------------------------------------------------------------------
void GuiInspectorField::init( GuiInspector *inspector, GuiInspectorGroup *group )
{
mInspector = inspector;
mParent = group;
}
//-----------------------------------------------------------------------------
bool GuiInspectorField::onAdd()
{
setInspectorProfile();
if ( !Parent::onAdd() )
return false;
if ( !mInspector )
return false;
mEdit = constructEditControl();
if ( mEdit == NULL )
return false;
setBounds(0,0,100,18);
// Add our edit as a child
addObject( mEdit );
// Calculate Caption and EditCtrl Rects
updateRects();
// Force our editField to set it's value
updateValue();
return true;
}
//-----------------------------------------------------------------------------
bool GuiInspectorField::resize( const Point2I &newPosition, const Point2I &newExtent )
{
if ( !Parent::resize( newPosition, newExtent ) )
return false;
return updateRects();
}
//-----------------------------------------------------------------------------
void GuiInspectorField::onRender( Point2I offset, const RectI &updateRect )
{
RectI ctrlRect(offset, getExtent());
// Render fillcolor...
if ( mProfile->mOpaque )
GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColor);
// Render caption...
if ( mCaption && mCaption[0] )
{
// Backup current ClipRect
RectI clipBackup = GFX->getClipRect();
RectI clipRect = updateRect;
// The rect within this control in which our caption must fit.
RectI rect( offset + mCaptionRect.point + mProfile->mTextOffset, mCaptionRect.extent + Point2I(1,1) - Point2I(5,0) );
// Now clipRect is the amount of our caption rect that is actually visible.
bool hit = clipRect.intersect( rect );
if ( hit )
{
GFX->setClipRect( clipRect );
GFXDrawUtil *drawer = GFX->getDrawUtil();
// Backup modulation color
ColorI currColor;
drawer->getBitmapModulation( &currColor );
// Draw caption background...
if( !isActive() )
GFX->getDrawUtil()->drawRectFill( clipRect, mProfile->mFillColorNA );
else if ( mHighlighted )
GFX->getDrawUtil()->drawRectFill( clipRect, mProfile->mFillColorHL );
// Draw caption text...
drawer->setBitmapModulation( !isActive() ? mProfile->mFontColorNA : mHighlighted ? mProfile->mFontColorHL : mProfile->mFontColor );
// Clip text with '...' if too long to fit
String clippedText( mCaption );
clipText( clippedText, clipRect.extent.x );
renderJustifiedText( offset + mProfile->mTextOffset, getExtent(), clippedText );
// Restore modulation color
drawer->setBitmapModulation( currColor );
// Restore previous ClipRect
GFX->setClipRect( clipBackup );
}
}
// Render Children...
renderChildControls(offset, updateRect);
// Render border...
if ( mProfile->mBorder )
renderBorder(ctrlRect, mProfile);
// Render divider...
Point2I worldPnt = mEditCtrlRect.point + offset;
GFX->getDrawUtil()->drawLine( worldPnt.x - 5,
worldPnt.y,
worldPnt.x - 5,
worldPnt.y + getHeight(),
!isActive() ? mProfile->mBorderColorNA : mHighlighted ? mProfile->mBorderColorHL : mProfile->mBorderColor );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::setFirstResponder( GuiControl *firstResponder )
{
Parent::setFirstResponder( firstResponder );
if ( firstResponder == this || firstResponder == mEdit )
{
mInspector->setHighlightField( this );
}
}
//-----------------------------------------------------------------------------
void GuiInspectorField::onMouseDown( const GuiEvent &event )
{
if ( mCaptionRect.pointInRect( globalToLocalCoord( event.mousePoint ) ) )
{
if ( mEdit )
//mEdit->onMouseDown( event );
mInspector->setHighlightField( this );
}
else
Parent::onMouseDown( event );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::onRightMouseUp( const GuiEvent &event )
{
if ( mCaptionRect.pointInRect( globalToLocalCoord( event.mousePoint ) ) )
Con::executef( mInspector, "onFieldRightClick", getIdString() );
else
Parent::onMouseDown( event );
}
//-----------------------------------------------------------------------------
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 )
Con::executef( mInspector, "onBeginCompoundEdit" );
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 )
Con::executef( mInspector, "onInspectorFieldModified",
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 )
Con::executef( mInspector, "onEndCompoundEdit" );
}
// Force our edit to update
updateValue();
}
//-----------------------------------------------------------------------------
const char* GuiInspectorField::getData( U32 inspectObjectIndex )
{
if( mField == NULL )
return "";
return mInspector->getInspectObject( inspectObjectIndex )->getDataField( mField->pFieldname, mFieldArrayIndex );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::resetData()
{
if( !mField )
return;
SimObject* inspectObject = getInspector()->getInspectObject();
SimObject* tempObject = static_cast< SimObject* >( inspectObject->getClassRep()->create() );
setData( tempObject->getDataField( mField->pFieldname, mFieldArrayIndex ) );
delete tempObject;
}
//-----------------------------------------------------------------------------
void GuiInspectorField::setInspectorField( AbstractClassRep::Field *field, StringTableEntry caption, const char*arrayIndex )
{
mField = field;
if ( arrayIndex != NULL )
mFieldArrayIndex = StringTable->insert( arrayIndex );
if ( !caption || !caption[0] )
mCaption = getFieldName();
else
mCaption = caption;
_setFieldDocs( mField->pFieldDocs );
}
//-----------------------------------------------------------------------------
StringTableEntry GuiInspectorField::getRawFieldName()
{
if( !mField )
return StringTable->EmptyString();
return mField->pFieldname;
}
//-----------------------------------------------------------------------------
StringTableEntry GuiInspectorField::getFieldName()
{
// Sanity
if ( mField == NULL )
return StringTable->EmptyString();
// Array element?
if( mFieldArrayIndex != NULL )
{
S32 frameTempSize = dStrlen( mField->pFieldname ) + 32;
FrameTemp<char> valCopy( frameTempSize );
dSprintf( (char *)valCopy, frameTempSize, "%s[%s]", mField->pFieldname, mFieldArrayIndex );
// Return formatted element
return StringTable->insert( valCopy );
}
// Plain field name.
return mField->pFieldname;
}
//-----------------------------------------------------------------------------
StringTableEntry GuiInspectorField::getFieldType()
{
if( !mField )
return StringTable->EmptyString();
return ConsoleBaseType::getType( mField->type )->getTypeName();
}
//-----------------------------------------------------------------------------
GuiControl* GuiInspectorField::constructEditControl()
{
GuiControl* retCtrl = new GuiTextEditCtrl();
static StringTableEntry sProfile = StringTable->insert( "profile" );
retCtrl->setDataField( sProfile, NULL, "GuiInspectorTextEditProfile" );
_registerEditControl( retCtrl );
char szBuffer[512];
dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(), retCtrl->getId() );
// Suffices to hook on to "validate" as regardless of whether we lose
// focus through the user pressing enter or clicking away on another
// keyboard control, we will see a validate call.
retCtrl->setField("validate", szBuffer );
return retCtrl;
}
//-----------------------------------------------------------------------------
void GuiInspectorField::setInspectorProfile()
{
GuiControlProfile *profile = NULL;
if( mInspector->getNumInspectObjects() > 1 )
{
if( !hasSameValueInAllObjects() )
Sim::findObject( "GuiInspectorMultiFieldDifferentProfile", profile );
else
Sim::findObject( "GuiInspectorMultiFieldProfile", profile );
}
if( !profile )
Sim::findObject( "GuiInspectorFieldProfile", profile );
if( profile )
setControlProfile( profile );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::setValue( StringTableEntry newValue )
{
GuiTextEditCtrl *ctrl = dynamic_cast<GuiTextEditCtrl*>( mEdit );
if( ctrl != NULL )
ctrl->setText( newValue );
}
//-----------------------------------------------------------------------------
bool GuiInspectorField::updateRects()
{
S32 dividerPos, dividerMargin;
mInspector->getDivider( dividerPos, dividerMargin );
Point2I fieldExtent = getExtent();
Point2I fieldPos = getPosition();
S32 editWidth = dividerPos - dividerMargin;
mEditCtrlRect.set( fieldExtent.x - dividerPos + dividerMargin, 1, editWidth, fieldExtent.y - 1 );
mCaptionRect.set( 0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y );
if ( !mEdit )
return false;
return mEdit->resize( mEditCtrlRect.point, mEditCtrlRect.extent );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::updateValue()
{
if( mInspector->getNumInspectObjects() > 1 )
{
setInspectorProfile();
if( !hasSameValueInAllObjects() )
setValue( StringTable->EmptyString() );
else
setValue( getData() );
}
else
setValue( getData() );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::setHLEnabled( bool enabled )
{
mHighlighted = enabled;
if ( mHighlighted )
{
if ( mEdit && !mEdit->isFirstResponder() )
{
mEdit->setFirstResponder();
GuiTextEditCtrl *edit = dynamic_cast<GuiTextEditCtrl*>( mEdit );
if ( edit )
{
mouseUnlock();
edit->mouseLock();
edit->setCursorPos(0);
}
}
_executeSelectedCallback();
}
}
//-----------------------------------------------------------------------------
bool GuiInspectorField::hasSameValueInAllObjects()
{
char value1[ 2048 ];
// Get field value from first object.
const char* data1 = getData( 0 );
if( data1 )
{
dStrncpy( value1, data1, sizeof( value1 ) );
value1[ sizeof( value1 ) - 1 ] = 0;
}
else
value1[ 0 ] = 0;
// Check if all other objects have the same value.
const U32 numObjects = mInspector->getNumInspectObjects();
for( U32 i = 1; i < numObjects; ++ i )
{
const char* value2 = getData( i );
if( !value2 )
value2 = "";
if( dStrcmp( value1, value2 ) != 0 )
return false;
}
return true;
}
//-----------------------------------------------------------------------------
void GuiInspectorField::_executeSelectedCallback()
{
if( mField )
Con::executef( mInspector, "onFieldSelected", mField->pFieldname, ConsoleBaseType::getType(mField->type)->getTypeName(), mFieldDocs.c_str() );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::_registerEditControl( GuiControl *ctrl )
{
char szName[512];
dSprintf( szName, 512, "IE_%s_%d_%s_Field", ctrl->getClassName(), mInspector->getInspectObject()->getId(), mCaption);
// Register the object
ctrl->registerObject( szName );
}
//-----------------------------------------------------------------------------
void GuiInspectorField::_setFieldDocs( StringTableEntry docs )
{
mFieldDocs = String();
if( docs && docs[ 0 ] )
{
// Only accept first line of docs for brevity.
const char* newline = dStrchr( docs, '\n' );
if( newline )
mFieldDocs = String( docs, newline - docs );
else
mFieldDocs = docs;
}
}
//=============================================================================
// Console Methods.
//=============================================================================
// MARK: ---- Console Methods ----
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, getInspector, S32, 2, 2, "() - Return the GuiInspector to which this field belongs." )
{
return object->getInspector()->getId();
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, getInspectedFieldName, const char*, 2, 2, "() - Return the name of the field edited by this inspector field." )
{
return object->getFieldName();
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, getInspectedFieldType, const char*, 2, 2, "() - Return the type of the field edited by this inspector field." )
{
return object->getFieldType();
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, apply, void, 3, 4, "( string newValue, bool callbacks=true ) - Set the field's value. Suppress callbacks for undo if callbacks=false." )
{
bool callbacks = true;
if( argc > 3 )
callbacks = dAtob( argv[ 3 ] );
object->setData( argv[ 2 ], callbacks );
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, applyWithoutUndo, void, 3, 3, "() - Set field value without recording undo (same as 'apply( value, false )')." )
{
object->setData( argv[ 2 ], false );
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, getData, const char*, 2, 2, "() - Return the value currently displayed on the field." )
{
return object->getData();
}
//-----------------------------------------------------------------------------
ConsoleMethod( GuiInspectorField, reset, void, 2, 2, "() - Reset to default value." )
{
object->resetData();
}

View file

@ -0,0 +1,194 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_FIELD_H_
#define _GUI_INSPECTOR_FIELD_H_
#include "gui/core/guiCanvas.h"
#include "gui/shiny/guiTickCtrl.h"
#include "gui/controls/guiTextEditCtrl.h"
#include "gui/buttons/guiBitmapButtonCtrl.h"
#include "gui/controls/guiPopUpCtrl.h"
#include "gui/containers/guiRolloutCtrl.h"
class GuiInspectorGroup;
class GuiInspector;
/// The GuiInspectorField control is a representation of a single abstract
/// field for a given ConsoleObject derived object. It handles creation
/// getting and setting of it's fields data and editing control.
///
/// Creation of custom edit controls is done through this class and is
/// dependent upon the dynamic console type, which may be defined to be
/// custom for different types.
///
/// @note GuiInspectorField controls must have a GuiInspectorGroup as their
/// parent.
class GuiInspectorField : public GuiControl
{
public:
typedef GuiControl Parent;
friend class GuiInspectorGroup;
protected:
/// The text to display as the field name.
StringTableEntry mCaption;
/// The group to which this field belongs.
GuiInspectorGroup* mParent;
/// The GuiInspector that the group is in to which this field belongs.
GuiInspector* mInspector;
///
AbstractClassRep::Field* mField;
///
StringTableEntry mFieldArrayIndex;
///
String mFieldDocs;
///
GuiControl* mEdit;
///
RectI mCaptionRect;
///
RectI mEditCtrlRect;
///
bool mHighlighted;
virtual void _registerEditControl( GuiControl *ctrl );
virtual void _executeSelectedCallback();
void _setFieldDocs( StringTableEntry docs );
public:
explicit GuiInspectorField();
///
GuiInspectorField( GuiInspector *inspector, GuiInspectorGroup* parent, AbstractClassRep::Field* field );
virtual ~GuiInspectorField();
///
virtual void init( GuiInspector *inspector, GuiInspectorGroup *group );
///
virtual void setInspectorField( AbstractClassRep::Field *field,
StringTableEntry caption = NULL,
const char *arrayIndex = NULL );
///
virtual GuiControl* constructEditControl();
/// Chooses and sets the GuiControlProfile.
virtual void setInspectorProfile();
/// Sets this control's caption text, usually set within setInspectorField,
/// this is exposed in case someone wants to override the normal caption.
virtual void setCaption( StringTableEntry caption ) { mCaption = caption; }
/// Returns pointer to this InspectorField's edit ctrl.
virtual GuiControl* getEditCtrl() { return mEdit; }
/// Sets the value of this GuiInspectorField (not the actual field)
/// This means the EditCtrl unless overridden.
virtual void setValue( const char* newValue );
/// Get the currently value of this control (not the actual field)
virtual const char* getValue() { return NULL; }
/// Update this controls value to reflect that of the inspected field.
virtual void updateValue();
/// Return the name of the field being edited.
virtual StringTableEntry getFieldName();
/// Return the name of the console type that this field uses.
virtual StringTableEntry getFieldType();
/// Return the name without the array index that may potentially be present.
virtual StringTableEntry getRawFieldName();
///
StringTableEntry getArrayIndex() const { return mFieldArrayIndex; }
/// Called from within setData to allow child classes
/// to perform their own verification.
virtual bool verifyData( StringTableEntry data ) { return true; }
/// Set value of the field we are inspecting
virtual void setData( const char* data, bool callbacks = true );
/// Reset the field value to its default value based on default-constructed objects.
///
/// @note If multiple objects are inspected, this will take the default value from
/// the first object and set all fields to this value.
virtual void resetData();
/// Get value of the field we are inspecting.
///
/// @note The string returned by this method may be a transient string allocated
/// internally by the console. For any non-transient needs, this string has
/// to be copied to locally owned memory.
/// @note This method always returns the value of the field in the first
/// inspected object.
virtual const char* getData( U32 inspectObjectIndex = 0 );
/// Update the inspected field to match the value of this control.
virtual void updateData() {};
///
virtual bool updateRects();
///
virtual void setHLEnabled( bool enabled );
/// Return true if all inspected objects have the same value for this
/// field.
bool hasSameValueInAllObjects();
/// Return the inspector object that this field belongs to.
GuiInspector* getInspector() const { return mInspector; }
// GuiControl.
virtual bool onAdd();
virtual bool resize(const Point2I &newPosition, const Point2I &newExtent);
virtual void onRender(Point2I offset, const RectI &updateRect);
virtual void setFirstResponder( GuiControl *firstResponder );
virtual void onMouseDown( const GuiEvent &event );
virtual void onRightMouseUp( const GuiEvent &event );
DECLARE_CONOBJECT( GuiInspectorField );
DECLARE_CATEGORY( "Gui Editor" );
};
#endif // _GUI_INSPECTOR_FIELD_H_

View file

@ -0,0 +1,567 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/editor/guiInspector.h"
#include "gui/editor/inspector/group.h"
#include "gui/editor/inspector/dynamicField.h"
#include "gui/editor/inspector/datablockField.h"
#include "gui/buttons/guiIconButtonCtrl.h"
IMPLEMENT_CONOBJECT(GuiInspectorGroup);
ConsoleDocClass( GuiInspectorGroup,
"@brief The GuiInspectorGroup control is a helper control that the inspector "
"makes use of which houses a collapsible pane type control for separating "
"inspected objects fields into groups.\n\n"
"Editor use only.\n\n"
"@internal"
);
//#define DEBUG_SPEW
//-----------------------------------------------------------------------------
GuiInspectorGroup::GuiInspectorGroup()
: mParent( NULL ),
mStack(NULL)
{
setBounds(0,0,200,20);
mChildren.clear();
setCanSave( false );
// Make sure we receive our ticks.
setProcessTicks();
mMargin.set(0,0,5,0);
}
//-----------------------------------------------------------------------------
GuiInspectorGroup::GuiInspectorGroup( const String& groupName,
SimObjectPtr<GuiInspector> parent )
: mParent( parent ),
mStack(NULL)
{
setBounds(0,0,200,20);
mCaption = groupName;
setCanSave( false );
mChildren.clear();
mMargin.set(0,0,4,0);
}
//-----------------------------------------------------------------------------
GuiInspectorGroup::~GuiInspectorGroup()
{
}
//-----------------------------------------------------------------------------
bool GuiInspectorGroup::onAdd()
{
setDataField( StringTable->insert("profile"), NULL, "GuiInspectorGroupProfile" );
if( !Parent::onAdd() )
return false;
// Create our inner controls. Allow subclasses to provide other content.
if(!createContent())
return false;
inspectGroup();
return true;
}
//-----------------------------------------------------------------------------
bool GuiInspectorGroup::createContent()
{
// Create our field stack control
mStack = new GuiStackControl();
// Prefer GuiTransperantProfile for the stack.
mStack->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorStackProfile" );
if( !mStack->registerObject() )
{
SAFE_DELETE( mStack );
return false;
}
addObject( mStack );
mStack->setField( "padding", "0" );
return true;
}
//-----------------------------------------------------------------------------
void GuiInspectorGroup::animateToContents()
{
calculateHeights();
if(size() > 0)
animateTo( mExpanded.extent.y );
else
animateTo( mHeader.extent.y );
}
//-----------------------------------------------------------------------------
GuiInspectorField* GuiInspectorGroup::constructField( S32 fieldType )
{
// See if we can construct a field of this type
ConsoleBaseType *cbt = ConsoleBaseType::getType(fieldType);
if( !cbt )
return NULL;
// Alright, is it a datablock?
if(cbt->isDatablock())
{
// Default to GameBaseData
StringTableEntry typeClassName = cbt->getTypeClassName();
if( mParent->getNumInspectObjects() == 1 && !dStricmp(typeClassName, "GameBaseData") )
{
// Try and setup the classname based on the object type
char className[256];
dSprintf(className,256,"%sData", mParent->getInspectObject( 0 )->getClassName());
// Walk the ACR list and find a matching class if any.
AbstractClassRep *walk = AbstractClassRep::getClassList();
while(walk)
{
if(!dStricmp(walk->getClassName(), className))
break;
walk = walk->getNextClass();
}
// We found a valid class
if (walk)
typeClassName = walk->getClassName();
}
GuiInspectorDatablockField *dbFieldClass = new GuiInspectorDatablockField( typeClassName );
if( dbFieldClass != NULL )
{
// return our new datablock field with correct datablock type enumeration info
return dbFieldClass;
}
}
// Nope, not a datablock. So maybe it has a valid inspector field override we can use?
if(!cbt->getInspectorFieldType())
// Nothing, so bail.
return NULL;
// Otherwise try to make it!
ConsoleObject *co = create(cbt->getInspectorFieldType());
GuiInspectorField *gif = dynamic_cast<GuiInspectorField*>(co);
if(!gif)
{
// Wasn't appropriate type, bail.
delete co;
return NULL;
}
return gif;
}
//-----------------------------------------------------------------------------
GuiInspectorField *GuiInspectorGroup::findField( const char *fieldName )
{
// If we don't have any field children we can't very well find one then can we?
if( mChildren.empty() )
return NULL;
Vector<GuiInspectorField*>::iterator i = mChildren.begin();
for( ; i != mChildren.end(); i++ )
{
if( (*i)->getFieldName() != NULL && dStricmp( (*i)->getFieldName(), fieldName ) == 0 )
return (*i);
}
return NULL;
}
//-----------------------------------------------------------------------------
void GuiInspectorGroup::clearFields()
{
// Deallocates all field related controls.
mStack->clear();
// Then just cleanup our vectors which also point to children
// that we keep for our own convenience.
mArrayCtrls.clear();
mChildren.clear();
}
//-----------------------------------------------------------------------------
bool GuiInspectorGroup::inspectGroup()
{
// We can't inspect a group without a target!
if( !mParent->getNumInspectObjects() )
return false;
// to prevent crazy resizing, we'll just freeze our stack for a sec..
mStack->freeze(true);
bool bNoGroup = false;
// Un-grouped fields are all sorted into the 'general' group
if ( dStricmp( mCaption, "General" ) == 0 )
bNoGroup = true;
// Just delete all fields and recreate them (like the dynamicGroup)
// because that makes creating controls for array fields a lot easier
clearFields();
bool bNewItems = false;
bool bMakingArray = false;
GuiStackControl *pArrayStack = NULL;
GuiRolloutCtrl *pArrayRollout = NULL;
bool bGrabItems = false;
AbstractClassRep* commonAncestorClass = findCommonAncestorClass();
AbstractClassRep::FieldList& fieldList = commonAncestorClass->mFieldList;
for( AbstractClassRep::FieldList::iterator itr = fieldList.begin();
itr != fieldList.end(); ++ itr )
{
AbstractClassRep::Field* field = &( *itr );
if( field->type == AbstractClassRep::StartGroupFieldType )
{
// If we're dealing with general fields, always set grabItems to true (to skip them)
if( bNoGroup == true )
bGrabItems = true;
else if( dStricmp( field->pGroupname, mCaption ) == 0 )
bGrabItems = true;
continue;
}
else if ( field->type == AbstractClassRep::EndGroupFieldType )
{
// If we're dealing with general fields, always set grabItems to false (to grab them)
if( bNoGroup == true )
bGrabItems = false;
else if( dStricmp( field->pGroupname, mCaption ) == 0 )
bGrabItems = false;
continue;
}
// Skip field if it has the HideInInspectors flag set.
if( field->flag.test( AbstractClassRep::FIELD_HideInInspectors ) )
continue;
if( ( bGrabItems == true || ( bNoGroup == true && bGrabItems == false ) ) && itr->type != AbstractClassRep::DeprecatedFieldType )
{
if( bNoGroup == true && bGrabItems == true )
continue;
if ( field->type == AbstractClassRep::StartArrayFieldType )
{
#ifdef DEBUG_SPEW
Platform::outputDebugString( "[GuiInspectorGroup] Beginning array '%s'",
field->pFieldname );
#endif
// Starting an array...
// Create a rollout for the Array, give it the array's name.
GuiRolloutCtrl *arrayRollout = new GuiRolloutCtrl();
GuiControlProfile *arrayRolloutProfile = dynamic_cast<GuiControlProfile*>( Sim::findObject( "GuiInspectorRolloutProfile0" ) );
arrayRollout->setControlProfile(arrayRolloutProfile);
//arrayRollout->mCaption = StringTable->insert( String::ToString( "%s (%i)", field->pGroupname, field->elementCount ) );
arrayRollout->setCaption( field->pGroupname );
//arrayRollout->setMargin( 14, 0, 0, 0 );
arrayRollout->registerObject();
GuiStackControl *arrayStack = new GuiStackControl();
arrayStack->registerObject();
arrayStack->freeze(true);
arrayRollout->addObject(arrayStack);
// Allocate a rollout for each element-count in the array
// Give it the element count name.
for ( U32 i = 0; i < field->elementCount; i++ )
{
GuiRolloutCtrl *elementRollout = new GuiRolloutCtrl();
GuiControlProfile *elementRolloutProfile = dynamic_cast<GuiControlProfile*>( Sim::findObject( "GuiInspectorRolloutProfile0" ) );
char buf[256];
dSprintf( buf, 256, " [%i]", i );
elementRollout->setControlProfile(elementRolloutProfile);
elementRollout->setCaption(buf);
//elementRollout->setMargin( 14, 0, 0, 0 );
elementRollout->registerObject();
GuiStackControl *elementStack = new GuiStackControl();
elementStack->registerObject();
elementRollout->addObject(elementStack);
elementRollout->instantCollapse();
arrayStack->addObject( elementRollout );
}
pArrayRollout = arrayRollout;
pArrayStack = arrayStack;
arrayStack->freeze(false);
pArrayRollout->instantCollapse();
mStack->addObject(arrayRollout);
bMakingArray = true;
continue;
}
else if ( field->type == AbstractClassRep::EndArrayFieldType )
{
#ifdef DEBUG_SPEW
Platform::outputDebugString( "[GuiInspectorGroup] Ending array '%s'",
field->pFieldname );
#endif
bMakingArray = false;
continue;
}
if ( bMakingArray )
{
// Add a GuiInspectorField for this field,
// for every element in the array...
for ( U32 i = 0; i < pArrayStack->size(); i++ )
{
FrameTemp<char> intToStr( 64 );
dSprintf( intToStr, 64, "%d", i );
// The array stack should have a rollout for each element
// as children...
GuiRolloutCtrl *pRollout = dynamic_cast<GuiRolloutCtrl*>(pArrayStack->at(i));
// And the each of those rollouts should have a stack for
// fields...
GuiStackControl *pStack = dynamic_cast<GuiStackControl*>(pRollout->at(0));
// And we add a new GuiInspectorField to each of those stacks...
GuiInspectorField *fieldGui = constructField( field->type );
if ( fieldGui == NULL )
fieldGui = new GuiInspectorField();
fieldGui->init( mParent, this );
StringTableEntry caption = field->pFieldname;
fieldGui->setInspectorField( field, caption, intToStr );
if( fieldGui->registerObject() )
{
#ifdef DEBUG_SPEW
Platform::outputDebugString( "[GuiInspectorGroup] Adding array element '%s[%i]'",
field->pFieldname, i );
#endif
mChildren.push_back( fieldGui );
pStack->addObject( fieldGui );
}
else
delete fieldGui;
}
continue;
}
// This is weird, but it should work for now. - JDD
// We are going to check to see if this item is an array
// if so, we're going to construct a field for each array element
if( field->elementCount > 1 )
{
// Make a rollout control for this array
//
GuiRolloutCtrl *rollout = new GuiRolloutCtrl();
rollout->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorRolloutProfile0" );
rollout->setCaption(String::ToString( "%s (%i)", field->pFieldname, field->elementCount));
rollout->setMargin( 14, 0, 0, 0 );
rollout->registerObject();
mArrayCtrls.push_back(rollout);
// Put a stack control within the rollout
//
GuiStackControl *stack = new GuiStackControl();
stack->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorStackProfile" );
stack->registerObject();
stack->freeze(true);
rollout->addObject(stack);
mStack->addObject(rollout);
// Create each field and add it to the stack.
//
for (S32 nI = 0; nI < field->elementCount; nI++)
{
FrameTemp<char> intToStr( 64 );
dSprintf( intToStr, 64, "%d", nI );
// Construct proper ValueName[nI] format which is "ValueName0" for index 0, etc.
String fieldName = String::ToString( "%s%d", field->pFieldname, nI );
// If the field already exists, just update it
GuiInspectorField *fieldGui = findField( fieldName );
if( fieldGui != NULL )
{
fieldGui->updateValue();
continue;
}
bNewItems = true;
fieldGui = constructField( field->type );
if ( fieldGui == NULL )
fieldGui = new GuiInspectorField();
fieldGui->init( mParent, this );
StringTableEntry caption = StringTable->insert( String::ToString(" [%i]",nI) );
fieldGui->setInspectorField( field, caption, intToStr );
if ( fieldGui->registerObject() )
{
mChildren.push_back( fieldGui );
stack->addObject( fieldGui );
}
else
delete fieldGui;
}
stack->freeze(false);
stack->updatePanes();
rollout->instantCollapse();
}
else
{
// If the field already exists, just update it
GuiInspectorField *fieldGui = findField( field->pFieldname );
if ( fieldGui != NULL )
{
fieldGui->updateValue();
continue;
}
bNewItems = true;
fieldGui = constructField( field->type );
if ( fieldGui == NULL )
fieldGui = new GuiInspectorField();
fieldGui->init( mParent, this );
fieldGui->setInspectorField( field );
if( fieldGui->registerObject() )
{
#ifdef DEBUG_SPEW
Platform::outputDebugString( "[GuiInspectorGroup] Adding field '%s'",
field->pFieldname );
#endif
mChildren.push_back( fieldGui );
mStack->addObject( fieldGui );
}
else
{
SAFE_DELETE( fieldGui );
}
}
}
}
mStack->freeze(false);
mStack->updatePanes();
// If we've no new items, there's no need to resize anything!
if( bNewItems == false && !mChildren.empty() )
return true;
sizeToContents();
setUpdate();
return true;
}
//-----------------------------------------------------------------------------
bool GuiInspectorGroup::updateFieldValue( StringTableEntry fieldName, StringTableEntry arrayIdx )
{
// Check if we contain a field of this name,
// if so update its value and return true.
Vector<GuiInspectorField*>::iterator iter = mChildren.begin();
if( arrayIdx == StringTable->EmptyString() )
arrayIdx = NULL;
for( ; iter != mChildren.end(); iter++ )
{
GuiInspectorField *field = (*iter);
if ( field->mField &&
field->mField->pFieldname == fieldName &&
field->mFieldArrayIndex == arrayIdx )
{
field->updateValue();
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
void GuiInspectorGroup::updateAllFields()
{
Vector<GuiInspectorField*>::iterator iter = mChildren.begin();
for( ; iter != mChildren.end(); iter++ )
(*iter)->updateValue();
}
//-----------------------------------------------------------------------------
AbstractClassRep* GuiInspectorGroup::findCommonAncestorClass()
{
AbstractClassRep* classRep = getInspector()->getInspectObject( 0 )->getClassRep();
const U32 numInspectObjects = getInspector()->getNumInspectObjects();
for( U32 i = 1; i < numInspectObjects; ++ i )
{
SimObject* object = getInspector()->getInspectObject( i );
while( !object->getClassRep()->isClass( classRep ) )
{
classRep = classRep->getParentClass();
AssertFatal( classRep, "GuiInspectorGroup::findcommonAncestorClass - Walked above ConsoleObject!" );
}
}
return classRep;
}

View file

@ -0,0 +1,87 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_GROUP_H_
#define _GUI_INSPECTOR_GROUP_H_
#include "gui/core/guiCanvas.h"
#include "gui/controls/guiTextEditCtrl.h"
#include "gui/buttons/guiBitmapButtonCtrl.h"
#include "gui/containers/guiRolloutCtrl.h"
// Forward refs
class GuiInspector;
class GuiInspectorField;
/// The GuiInspectorGroup control is a helper control that the inspector
/// makes use of which houses a collapsible pane type control for separating
/// inspected objects fields into groups. The content of the inspector is
/// made up of zero or more GuiInspectorGroup controls inside of a GuiStackControl
///
class GuiInspectorGroup : public GuiRolloutCtrl
{
private:
typedef GuiRolloutCtrl Parent;
public:
// Members
SimObjectPtr<GuiInspector> mParent;
Vector<GuiInspectorField*> mChildren;
GuiStackControl* mStack;
Vector<GuiRolloutCtrl*> mArrayCtrls;
// Constructor/Destructor/Conobject Declaration
GuiInspectorGroup();
GuiInspectorGroup( const String& groupName, SimObjectPtr<GuiInspector> parent );
virtual ~GuiInspectorGroup();
DECLARE_CONOBJECT(GuiInspectorGroup);
DECLARE_CATEGORY( "Gui Editor" );
virtual GuiInspectorField* constructField( S32 fieldType );
virtual GuiInspectorField* findField( const char *fieldName );
// Publicly Accessible Information about this group
const String& getGroupName() const { return mCaption; };
SimObjectPtr<GuiInspector> getInspector() { return mParent; };
bool onAdd();
virtual bool inspectGroup();
virtual void animateToContents();
void clearFields();
virtual bool updateFieldValue( StringTableEntry fieldName, const char *arrayIdx );
virtual void updateAllFields();
U32 getNumFields() const { return mChildren.size(); }
protected:
// overridable method that creates our inner controls.
virtual bool createContent();
/// Determine the class that is a common ancestor to all inspected objects.
AbstractClassRep* findCommonAncestorClass();
};
#endif // _GUI_INSPECTOR_GROUP_H_

View file

@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/editor/inspector/variableField.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "gui/editor/guiInspector.h"
#include "core/util/safeDelete.h"
#include "gfx/gfxDrawUtil.h"
//-----------------------------------------------------------------------------
// GuiInspectorVariableField
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorVariableField);
ConsoleDocClass( GuiInspectorVariableField,
"@brief Inspector support for variables in a GuiVariableInspector.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiInspectorVariableField::GuiInspectorVariableField()
{
}
GuiInspectorVariableField::~GuiInspectorVariableField()
{
}
bool GuiInspectorVariableField::onAdd()
{
setInspectorProfile();
// Hack: skip our immediate parent
if ( !Parent::Parent::onAdd() )
return false;
{
GuiTextEditCtrl *edit = new GuiTextEditCtrl();
edit->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorTextEditProfile" );
edit->registerObject();
char szBuffer[512];
dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(), edit->getId() );
edit->setField("AltCommand", szBuffer );
edit->setField("Validate", szBuffer );
mEdit = edit;
}
setBounds(0,0,100,18);
// Add our edit as a child
addObject( mEdit );
// Calculate Caption and EditCtrl Rects
updateRects();
// Force our editField to set it's value
updateValue();
return true;
}
void GuiInspectorVariableField::setData( const char* data, bool callbacks )
{
if ( !mCaption || mCaption[0] == 0 )
return;
Con::setVariable( mCaption, data );
// Force our edit to update
updateValue();
}
const char* GuiInspectorVariableField::getData( U32 inspectObjectIndex )
{
if ( !mCaption || mCaption[0] == 0 )
return "";
return Con::getVariable( mCaption );
}
void GuiInspectorVariableField::setValue( const char* newValue )
{
GuiTextEditCtrl *ctrl = dynamic_cast<GuiTextEditCtrl*>( mEdit );
if( ctrl != NULL )
ctrl->setText( newValue );
}
void GuiInspectorVariableField::updateValue()
{
if ( !mCaption || mCaption[0] == 0 )
return;
setValue( getData() );
}

View file

@ -0,0 +1,62 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_VARIABLEFIELD_H_
#define _GUI_INSPECTOR_VARIABLEFIELD_H_
#ifndef _GUI_INSPECTOR_FIELD_H_
#include "gui/editor/inspector/field.h"
#endif
class GuiInspectorGroup;
class GuiInspector;
class GuiInspectorVariableField : public GuiInspectorField
{
friend class GuiInspectorField;
public:
typedef GuiInspectorField Parent;
GuiInspectorVariableField();
virtual ~GuiInspectorVariableField();
DECLARE_CONOBJECT( GuiInspectorVariableField );
DECLARE_CATEGORY( "Gui Editor" );
virtual bool onAdd();
virtual void setValue( const char* newValue );
virtual const char* getValue() { return NULL; }
virtual void updateValue();
virtual void setData( const char* data, bool callbacks = true );
virtual const char* getData( U32 inspectObjectIndex = 0 );
virtual void updateData() {};
protected:
};
#endif // _GUI_INSPECTOR_VARIABLEFIELD_H_

View file

@ -0,0 +1,109 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/editor/inspector/variableGroup.h"
#include "gui/editor/inspector/variableField.h"
#include "gui/editor/guiInspector.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "console/consoleInternal.h"
extern ExprEvalState gEvalState;
//-----------------------------------------------------------------------------
// GuiInspectorVariableGroup
//-----------------------------------------------------------------------------
//
//
IMPLEMENT_CONOBJECT(GuiInspectorVariableGroup);
ConsoleDocClass( GuiInspectorVariableGroup,
"@brief Inspector support for variable groups in a GuiVariableInspector.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiInspectorVariableGroup::GuiInspectorVariableGroup()
{
}
GuiInspectorVariableGroup::~GuiInspectorVariableGroup()
{
}
GuiInspectorField* GuiInspectorVariableGroup::constructField( S32 fieldType )
{
return NULL;
}
bool GuiInspectorVariableGroup::inspectGroup()
{
// to prevent crazy resizing, we'll just freeze our stack for a sec..
mStack->freeze(true);
clearFields();
Vector<String> names;
gEvalState.globalVars.exportVariables( mSearchString, &names, NULL );
bool bNewItems = false;
for ( U32 i = 0; i < names.size(); i++ )
{
const String &varName = names[i];
// If the field already exists, just update it
GuiInspectorVariableField *field = dynamic_cast<GuiInspectorVariableField*>( findField( varName ) );
if ( field != NULL )
{
field->updateValue();
continue;
}
bNewItems = true;
field = new GuiInspectorVariableField();
field->init( mParent, this );
field->setInspectorField( NULL, StringTable->insert( varName ) );
if ( field->registerObject() )
{
mChildren.push_back( field );
mStack->addObject( field );
}
else
delete field;
}
mStack->freeze(false);
mStack->updatePanes();
// If we've no new items, there's no need to resize anything!
if( bNewItems == false && !mChildren.empty() )
return true;
sizeToContents();
setUpdate();
return true;
}

View file

@ -0,0 +1,55 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_INSPECTOR_VARIABLEGROUP_H_
#define _GUI_INSPECTOR_VARIABLEGROUP_H_
#ifndef _GUI_INSPECTOR_GROUP_H_
#include "gui/editor/inspector/group.h"
#endif
// Forward refs
class GuiInspector;
class GuiInspectorField;
class GuiInspectorVariableGroup : public GuiInspectorGroup
{
public:
typedef GuiInspectorGroup Parent;
String mSearchString;
GuiInspectorVariableGroup();
virtual ~GuiInspectorVariableGroup();
DECLARE_CONOBJECT(GuiInspectorVariableGroup);
DECLARE_CATEGORY( "Gui Editor" );
virtual GuiInspectorField* constructField( S32 fieldType );
virtual bool inspectGroup();
protected:
};
#endif // _GUI_INSPECTOR_VARIABLEGROUP_H_

View file

@ -0,0 +1,67 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/editor/inspector/variableInspector.h"
#include "gui/editor/inspector/variableGroup.h"
GuiVariableInspector::GuiVariableInspector()
{
}
GuiVariableInspector::~GuiVariableInspector()
{
}
IMPLEMENT_CONOBJECT(GuiVariableInspector);
ConsoleDocClass( GuiVariableInspector,
"@brief GUI dedicated to variable viewing/manipulation\n\n"
"Mostly used in console system, internal use only.\n\n"
"@internal"
);
void GuiVariableInspector::loadVars( String searchStr )
{
clearGroups();
GuiInspectorVariableGroup *group = new GuiInspectorVariableGroup();
group->setHeaderHidden( true );
group->setCanCollapse( false );
group->mParent = this;
group->setCaption( "Global Variables" );
group->mSearchString = searchStr;
if( group != NULL )
{
group->registerObject();
mGroups.push_back( group );
addObject( group );
}
//group->inspectGroup();
}
ConsoleMethod( GuiVariableInspector, loadVars, void, 3, 3, "loadVars( searchString )" )
{
object->loadVars( argv[2] );
}

View file

@ -0,0 +1,52 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUI_VARIABLEINSPECTOR_H_
#define _GUI_VARIABLEINSPECTOR_H_
#ifndef _GUI_INSPECTOR_H_
#include "gui/editor/guiInspector.h"
#endif
class GuiVariableInspector : public GuiInspector
{
typedef GuiInspector Parent;
public:
GuiVariableInspector();
virtual ~GuiVariableInspector();
DECLARE_CONOBJECT( GuiVariableInspector );
DECLARE_CATEGORY( "Gui Editor" );
virtual void inspectObject( SimObject *object ) {}
virtual void loadVars( String searchString );
protected:
};
#endif // _GUI_VARIABLEINSPECTOR_H_