123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- //-----------------------------------------------------------------------------
- // 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/worldEditor/undoActions.h"
- #include "gui/editor/inspector/field.h"
- #include "gui/editor/guiInspector.h"
- #include "console/consoleTypes.h"
- #include "console/engineAPI.h"
- IMPLEMENT_CONOBJECT( MECreateUndoAction );
- ConsoleDocClass( MECreateUndoAction,
- "@brief Material Editor create undo instance\n\n"
- "Not intended for game development, for editors or internal use only.\n\n "
- "@internal");
- MECreateUndoAction::MECreateUndoAction( const UTF8* actionName )
- : UndoAction( actionName )
- {
- }
- MECreateUndoAction::~MECreateUndoAction()
- {
- }
- void MECreateUndoAction::initPersistFields()
- {
- Parent::initPersistFields();
- }
- void MECreateUndoAction::addObject( SimObject *object )
- {
- AssertFatal( object, "MECreateUndoAction::addObject() - Got null object!" );
- mObjects.increment();
- mObjects.last().id = object->getId();
- }
- DefineEngineMethod( MECreateUndoAction, addObject, void, ( SimObject* obj),,
- "Add the object being created to an undo action.\n"
- "@param obj Object being created you want to create the undo for.")
- {
- if (obj)
- object->addObject( obj );
- }
- void MECreateUndoAction::undo()
- {
- for ( S32 i= mObjects.size()-1; i >= 0; i-- )
- {
- ObjectState &state = mObjects[i];
- SimObject *object = Sim::findObject( state.id );
- if ( !object )
- continue;
- // Save the state.
- if ( !state.memento.hasState() )
- state.memento.save( object );
- // Store the group.
- SimGroup *group = object->getGroup();
- if ( group )
- state.groupId = group->getId();
- // We got what we need... delete it.
- object->deleteObject();
- }
-
- Con::executef( this, "onUndone" );
- }
- void MECreateUndoAction::redo()
- {
- for ( S32 i=0; i < mObjects.size(); i++ )
- {
- const ObjectState &state = mObjects[i];
- // Create the object.
- SimObject::setForcedId(state.id); // Restore the object's Id
- SimObject *object = state.memento.restore();
- if ( !object )
- continue;
- // Now restore its group.
- SimGroup *group;
- if ( Sim::findObject( state.groupId, group ) )
- group->addObject( object );
- }
-
- Con::executef( this, "onRedone" );
- }
- IMPLEMENT_CONOBJECT( MEDeleteUndoAction );
- ConsoleDocClass( MEDeleteUndoAction,
- "@brief Material Editor delete undo instance\n\n"
- "Not intended for game development, for editors or internal use only.\n\n "
- "@internal");
- MEDeleteUndoAction::MEDeleteUndoAction( const UTF8 *actionName )
- : UndoAction( actionName )
- {
- }
- MEDeleteUndoAction::~MEDeleteUndoAction()
- {
- }
- void MEDeleteUndoAction::initPersistFields()
- {
- Parent::initPersistFields();
- }
- void MEDeleteUndoAction::deleteObject( SimObject *object )
- {
- AssertFatal( object, "MEDeleteUndoAction::deleteObject() - Got null object!" );
- AssertFatal( object->isProperlyAdded(),
- "MEDeleteUndoAction::deleteObject() - Object should be registered!" );
- mObjects.increment();
- ObjectState& state = mObjects.last();
- // Capture the object id.
- state.id = object->getId();
- // Save the state.
- state.memento.save( object );
- // Store the group.
- SimGroup *group = object->getGroup();
- if ( group )
- state.groupId = group->getId();
- //Do any special handling of delete actions the object may do
- object->handleDeleteAction();
- // Now delete the object.
- object->deleteObject();
- }
- void MEDeleteUndoAction::deleteObject( const Vector<SimObject*> &objectList )
- {
- for ( S32 i = 0; i < objectList.size(); i++ )
- deleteObject( objectList[i] );
- }
- DefineEngineMethod( MEDeleteUndoAction, deleteObject, void, ( SimObject* obj),,
- "Delete the object and add it to the undo action.\n"
- "@param obj Object to delete and add to the undo action.")
- {
- if (obj)
- object->deleteObject( obj );
- }
- void MEDeleteUndoAction::undo()
- {
- for ( S32 i= mObjects.size()-1; i >= 0; i-- )
- {
- const ObjectState &state = mObjects[i];
- // Create the object.
- SimObject::setForcedId(state.id); // Restore the object's Id
- SimObject *object = state.memento.restore();
- if ( !object )
- continue;
- // Now restore its group.
- SimGroup *group;
- if ( Sim::findObject( state.groupId, group ) )
- group->addObject( object );
- }
-
- Con::executef( this, "onUndone" );
- }
- void MEDeleteUndoAction::redo()
- {
- for ( S32 i=0; i < mObjects.size(); i++ )
- {
- const ObjectState& state = mObjects[i];
- SimObject *object = Sim::findObject( state.id );
- if ( object )
- object->deleteObject();
- }
-
- Con::executef( this, "onRedone" );
- }
- IMPLEMENT_CONOBJECT( InspectorFieldUndoAction );
- ConsoleDocClass( InspectorFieldUndoAction,
- "@brief Inspector Field undo action instance\n\n"
- "Not intended for game development, for editors or internal use only.\n\n "
- "@internal");
- InspectorFieldUndoAction::InspectorFieldUndoAction()
- {
- mInspector = NULL;
- mObjId = 0;
- mField = NULL;
- mSlotName = StringTable->EmptyString();
- mArrayIdx = StringTable->EmptyString();
- }
- InspectorFieldUndoAction::InspectorFieldUndoAction( const UTF8 *actionName )
- : UndoAction( actionName )
- {
- mInspector = NULL;
- mObjId = 0;
- mField = NULL;
- mSlotName = StringTable->EmptyString();
- mArrayIdx = StringTable->EmptyString();
- }
- void InspectorFieldUndoAction::initPersistFields()
- {
- addField( "inspectorGui", TYPEID< GuiInspector >(), Offset( mInspector, InspectorFieldUndoAction ) );
- addField( "objectId", TypeS32, Offset( mObjId, InspectorFieldUndoAction ) );
- addField( "fieldName", TypeString, Offset( mSlotName, InspectorFieldUndoAction ) );
- addField( "fieldValue", TypeRealString, Offset( mData, InspectorFieldUndoAction ) );
- addField( "arrayIndex", TypeString, Offset( mArrayIdx, InspectorFieldUndoAction ) );
- Parent::initPersistFields();
- }
- void InspectorFieldUndoAction::undo()
- {
- SimObject *obj = NULL;
- if ( !Sim::findObject( mObjId, obj ) )
- return;
- if ( mArrayIdx && dStricmp( mArrayIdx, "(null)" ) == 0 )
- mArrayIdx = NULL;
- // Grab the current data.
- String data = obj->getDataField( mSlotName, mArrayIdx );
- // Call this to mirror the way field changes are done through the inspector.
- obj->inspectPreApply();
- // Restore the data from the UndoAction
- obj->setDataField( mSlotName, mArrayIdx, mData.c_str() );
- // Call this to mirror the way field changes are done through the inspector.
- obj->inspectPostApply();
- // If the affected object is still being inspected,
- // update the InspectorField to reflect the changed value.
- if ( mInspector && mInspector->getNumInspectObjects() > 0 && mInspector->getInspectObject() == obj )
- mInspector->updateFieldValue( mSlotName, mArrayIdx );
- // Now save the previous data in this UndoAction
- // since an undo action must become a redo action and vice-versa
- mData = data;
- }
|