Sfoglia il codice sorgente

UAdded Undo/Redo support for select, transform, create and delete actions in entity editor, fixed torus bounding box

Ivan Safrin 12 anni fa
parent
commit
568218f268

+ 3 - 3
Core/Contents/Source/PolyScenePrimitive.cpp

@@ -108,9 +108,9 @@ void ScenePrimitive::recreatePrimitive() {
 		break;				
 		case TYPE_TORUS:
 			mesh->createTorus(v1,v2,v3,v4);
-			bBox.x = v1*2;
-			bBox.y = v2;
-			bBox.z = v1*2;						
+			bBox.x = (v1*2) + (v2*2);
+			bBox.y = v2 * 2;
+			bBox.z = (v1*2) + (v2*2);
 		break;						
 		case TYPE_CIRCLE:
 			mesh->createCircle(v1, v2, v3);

File diff suppressed because it is too large
+ 3 - 3
IDE/Assets/ide_icons.ai


+ 1 - 1
IDE/Contents/Include/PolycodeEditor.h

@@ -56,7 +56,7 @@ class PolycodeEditorAction  {
 };
 
 
-class PolycodeEditor : public UIElement, public ClipboardProvider { 
+class PolycodeEditor : public UIElement, public ClipboardProvider {
 public:
 	PolycodeEditor(bool _isReadOnly);
 	virtual ~PolycodeEditor();

+ 52 - 4
IDE/Contents/Include/PolycodeEntityEditor.h

@@ -43,6 +43,46 @@ public:
     std::vector<Entity*> entities;
 };
 
+class PolycodeSceneEditorActionDataEntry {
+public:
+    PolycodeSceneEditorActionDataEntry(){
+        entity = NULL;
+        parentEntity = NULL;
+    }
+    
+    PolycodeSceneEditorActionDataEntry(Vector3 vec3, Number number);
+    PolycodeSceneEditorActionDataEntry(Quaternion quat);
+    PolycodeSceneEditorActionDataEntry(Vector3 vec3);
+    PolycodeSceneEditorActionDataEntry(Number number);
+    PolycodeSceneEditorActionDataEntry(Entity *entity);
+    Vector3 vec3;
+    Quaternion quat;
+    Number number;
+    Entity *entity;
+    Entity *parentEntity;
+};
+
+
+class PolycodeSceneEditorActionData : public PolycodeEditorActionData {
+    public:
+        PolycodeSceneEditorActionData() {
+            reverse = true;
+            deleteEntitiesInDestructor = false;
+        }
+    
+        ~PolycodeSceneEditorActionData() {
+            if(deleteEntitiesInDestructor) {
+                for(int i=0; i < entries.size(); i++) {
+                    delete entries[i].entity;
+                }
+            }
+        }
+    
+        std::vector<PolycodeSceneEditorActionDataEntry> entries;
+        bool deleteEntitiesInDestructor;
+        bool reverse;
+};
+
 class LightDisplay : public Entity {
 public:
     LightDisplay(SceneLight *light);
@@ -97,13 +137,13 @@ class SceneMeshSettings {
 
 class EntityEditorMainView : public UIElement {
 		public:
-			EntityEditorMainView();
+			EntityEditorMainView(PolycodeEditor *editor);
 			~EntityEditorMainView();
 			
             void createIcon(Entity *entity, String iconFile);
             void setEditorProps(Entity *entity);
     
-            void selectEntity(Entity *targetEntity, bool addToSelection = false);
+            void selectEntity(Entity *targetEntity, bool addToSelection = false, bool doAction = true);
     
 			void handleEvent(Event *event);
 			void Resize(Number width, Number height);
@@ -122,11 +162,15 @@ class EntityEditorMainView : public UIElement {
             void Paste(EntityEditorClipboardData *data);
     
             void disableLighting(bool disable);
-            void selectNone();
+            void selectNone(bool doAction);
     
             void onGainFocus();
             void onLoseFocus();
-            void deleteSelected();
+            void deleteSelected(bool doAction);
+    
+            void doAction(String actionName, PolycodeEditorActionData *data);
+    
+            void didPlaceEntity(Entity *entity);
     
             Entity *getObjectRoot();
             void setObjectRoot(SceneEntityInstance *entity);
@@ -141,11 +185,14 @@ class EntityEditorMainView : public UIElement {
 		protected:
     
             CoreInput *input;
+            PolycodeSceneEditorActionData *beforeData;
 			
             bool lightsDisabled;
             int editorMode;
 			Entity *topBar;
 			UIRect *headerBg;
+    
+            PolycodeEditor *editor;
 				
             unsigned int multiselectIndex;
 			std::vector<Entity*> selectedEntities;
@@ -214,6 +261,7 @@ class PolycodeEntityEditor : public PolycodeEditor {
         void saveShaderOptionsToEntry(ObjectEntry *entry, Material *material, ShaderBinding *binding);
     
         void saveEntityToObjectEntry(Entity *entity, ObjectEntry *entry);
+        void doAction(String actionName, PolycodeEditorActionData *data);
     
         String Copy(void **data);
         void Paste(void *data, String clipboardType);

+ 16 - 0
IDE/Contents/Include/TransformGizmo.h

@@ -28,6 +28,17 @@
 
 using namespace Polycode;
 
+class TrasnformGizmoEvent : public Event {
+    public:
+        TrasnformGizmoEvent(int mode);
+    
+        static const int EVENT_TRANSLATE = 0;
+        static const int EVENT_SCALE = 1;
+        static const int EVENT_ROTATE = 2;
+    
+        int mode;
+};
+
 class TransformGizmo : public Entity {
 	public:
 		TransformGizmo(Scene *targetScene, Camera *targetCamera);
@@ -74,6 +85,9 @@ class TransformGizmo : public Entity {
         bool enableGizmo;
     
 	private:
+    
+        void dispatchEndEvent();
+    
         int transformMode;
         int gizmoMode;
         int orientation;
@@ -85,6 +99,8 @@ class TransformGizmo : public Entity {
 		Scene *targetScene;
 		Camera *targetCamera;
     
+        bool firstMove;
+    
 	
 		CoreInput *coreInput;
 		int mode;

+ 11 - 7
IDE/Contents/Source/PolycodeEditor.cpp

@@ -54,7 +54,7 @@ PolycodeEditor::PolycodeEditor(bool _isReadOnly) : UIElement(), ClipboardProvide
 	
 	editorHolder = NULL;
 	
-	currentUndoPosition = 0;
+	currentUndoPosition = -1;
 	
 	Core *core = CoreServices::getInstance()->getCore();
 	
@@ -108,8 +108,8 @@ void PolycodeEditor::handleEvent(Event *event) {
 				if(editorActions.size() > 0) {
 				doAction(editorActions[currentUndoPosition].actionName, editorActions[currentUndoPosition].beforeData);
 				currentUndoPosition--;
-				if(currentUndoPosition < 0) {
-					currentUndoPosition = 0;
+				if(currentUndoPosition < -1) {
+					currentUndoPosition = -1;
 				}
 				}				
 			}
@@ -132,18 +132,22 @@ void PolycodeEditor::handleEvent(Event *event) {
 
 void PolycodeEditor::didAction(String actionName, PolycodeEditorActionData *beforeData, PolycodeEditorActionData *afterData, bool setFileChanged) {
 
-//	printf("DID ACTION: %s\n", actionName.c_str());
+//	printf("DID ACTION (pos: %d): %s\n", currentUndoPosition, actionName.c_str());
 	
 	if(setFileChanged) {
 		setHasChanges(true);
 	}
 	
 	// if the undo position is not at the end, remove the states after it
-	if(currentUndoPosition < editorActions.size()-1 && editorActions.size() > 0) {
+	if(currentUndoPosition < (int)(editorActions.size())-1 && editorActions.size() > 0) {
 		for(int i=currentUndoPosition+1; i < editorActions.size(); i++) {
 			editorActions[i].deleteData();		
 		}
-		editorActions.erase(editorActions.begin()+currentUndoPosition+1, editorActions.end());
+        if(currentUndoPosition > -1) {
+            editorActions.erase(editorActions.begin()+currentUndoPosition+1, editorActions.end());
+        } else {
+            editorActions.clear();
+        }
 	}
 
 	PolycodeEditorAction newAction;
@@ -157,7 +161,7 @@ void PolycodeEditor::didAction(String actionName, PolycodeEditorActionData *befo
 		editorActions.erase(editorActions.begin());
 	}
 	
-	currentUndoPosition = editorActions.size()-1;	
+	currentUndoPosition = editorActions.size()-1;
 }
 
 void PolycodeEditor::Resize(int x, int y) {

+ 243 - 30
IDE/Contents/Source/PolycodeEntityEditor.cpp

@@ -29,6 +29,26 @@ extern UIGlobalMenu *globalMenu;
 extern PolycodeFrame *globalFrame;
 extern Scene *globalScene;
 
+PolycodeSceneEditorActionDataEntry::PolycodeSceneEditorActionDataEntry(Vector3 vec3, Number number) {
+    this->vec3 = vec3;
+    this->number = number;
+}
+PolycodeSceneEditorActionDataEntry::PolycodeSceneEditorActionDataEntry(Vector3 vec3) {
+    this->vec3 = vec3;
+}
+
+PolycodeSceneEditorActionDataEntry::PolycodeSceneEditorActionDataEntry(Quaternion quat) {
+    this->quat = quat;
+}
+
+PolycodeSceneEditorActionDataEntry::PolycodeSceneEditorActionDataEntry(Number number) {
+    this->number = number;
+}
+
+PolycodeSceneEditorActionDataEntry::PolycodeSceneEditorActionDataEntry(Entity *entity) {
+    this->entity = entity;
+}
+
 LightDisplay::LightDisplay(SceneLight *light) : Entity() {
     editorOnly = true;
     this->light = light;
@@ -207,11 +227,14 @@ void CameraPreviewWindow::setCamera(Scene *scene, Camera *camera) {
     }
 }
 
-EntityEditorMainView::EntityEditorMainView() {
+EntityEditorMainView::EntityEditorMainView(PolycodeEditor *editor) {
 	processInputEvents = true;
     multiselectIndex = 0;
     objectRootInstance = NULL;
     lightsDisabled = false;
+    beforeData = NULL;
+    
+    this->editor = editor;
 
 	mainScene = new Scene(Scene::SCENE_3D, true);
 	renderTexture = new SceneRenderTexture(mainScene, mainScene->getDefaultCamera(), 512, 512);
@@ -279,6 +302,8 @@ EntityEditorMainView::EntityEditorMainView() {
     
 	transformGizmo = new TransformGizmo(mainScene, mainScene->getDefaultCamera());
     transformGizmo->enableGizmo = false;
+    transformGizmo->addEventListener(this, Event::CHANGE_EVENT);
+    transformGizmo->addEventListener(this, Event::SELECT_EVENT);
     
 	mainScene->addChild(transformGizmo);		
 	trackballCamera = new TrackballCamera(mainScene->getDefaultCamera(), renderTextureShape);
@@ -327,6 +352,61 @@ std::vector<Entity*> EntityEditorMainView::getSelectedEntities() {
     return selectedEntities;
 }
 
+void EntityEditorMainView::doAction(String actionName, PolycodeEditorActionData *data) {
+    PolycodeSceneEditorActionData *sceneData = (PolycodeSceneEditorActionData*)data;
+	if(actionName == "move") {
+		for(int i=0; i < selectedEntities.size(); i++) {
+            if(i < sceneData->entries.size()) {
+			selectedEntities[i]->setPosition(sceneData->entries[i].vec3);
+            }
+		}
+	} else if(actionName == "scale") {
+		for(int i=0; i < selectedEntities.size(); i++) {
+            if(i < sceneData->entries.size()) {
+                selectedEntities[i]->setScale(sceneData->entries[i].vec3);
+            }
+		}
+    } else if(actionName == "rotate") {
+		for(int i=0; i < selectedEntities.size(); i++) {
+            if(i < sceneData->entries.size()) {
+                selectedEntities[i]->setRotationByQuaternion(sceneData->entries[i].quat);
+            }
+		}
+    } else if(actionName == "select") {
+        selectNone(false);
+        if(sceneData) {
+            for(int i=0; i < sceneData->entries.size(); i++) {
+                    selectEntity(sceneData->entries[i].entity, true, false);
+            }
+        }
+    } else if(actionName == "delete") {
+        if(sceneData->reverse) {
+            selectNone(false);
+            for(int i=0; i < sceneData->entries.size(); i++) {
+                sceneData->entries[i].parentEntity->addChild(sceneData->entries[i].entity);
+                setEditorPropsRecursive(sceneData->entries[i].entity);
+                selectEntity(sceneData->entries[i].entity, true, false);
+            }
+		} else {
+            deleteSelected(false);
+		}
+    } else if(actionName == "create_entity") {
+        if(sceneData->reverse) {
+			deleteSelected(false);
+            selectNone(false);
+            for(int i=0; i < sceneData->entries.size(); i++) {
+                selectEntity(sceneData->entries[i].entity, true, false);
+            }
+            
+		} else {
+            selectNone(false);
+            sceneData->entries[0].parentEntity->addChild(sceneData->entries[0].entity);
+            setEditorPropsRecursive(sceneData->entries[0].entity);
+            selectEntity(sceneData->entries[0].entity, true, false);
+		}
+    }
+}
+
 void EntityEditorMainView::setEditorMode(int newMode) {
     editorMode = newMode;
     if(editorMode == EDITOR_MODE_3D) {
@@ -359,7 +439,7 @@ Entity *EntityEditorMainView::getSelectedEntity() {
 
 void EntityEditorMainView::Paste(EntityEditorClipboardData *data) {
     
-    selectNone();
+    selectNone(false);
     
     for(int i=0; i < data->entities.size(); i++) {
         Entity *entity = data->entities[i]->Clone(true, true);
@@ -524,7 +604,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         sceneObjectRoot->addChild(newPrimitive);
         setEditorProps(newPrimitive);
         newPrimitive->setPosition(cursorPosition);
-        selectEntity(newPrimitive);
+        didPlaceEntity(newPrimitive);
+        selectEntity(newPrimitive, false, false);
         return;
     }
 
@@ -533,7 +614,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         sceneObjectRoot->addChild(newEntity);
         setEditorProps(newEntity);
         newEntity->setPosition(cursorPosition);
-        selectEntity(newEntity);
+        didPlaceEntity(newEntity);
+        selectEntity(newEntity, false, false);
         return;
     }
 
@@ -542,16 +624,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         sceneObjectRoot->addChild(newSound);
         setEditorProps(newSound);
         newSound->setPosition(cursorPosition);
-        selectEntity(newSound);
-        return;
-    }
-
-    if(command == "add_sound") {
-        SceneSound *newSound = new SceneSound("default.wav", 1.0, 2.0);
-        sceneObjectRoot->addChild(newSound);
-        setEditorProps(newSound);
-        newSound->setPosition(cursorPosition);
-        selectEntity(newSound);
+        didPlaceEntity(newSound);
+        selectEntity(newSound, false, false);
         return;
     }
 
@@ -560,7 +634,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         sceneObjectRoot->addChild(newCamera);
         setEditorProps(newCamera);
         newCamera->setPosition(cursorPosition);
-        selectEntity(newCamera);
+        didPlaceEntity(newCamera);
+        selectEntity(newCamera, false, false);
         return;
     }
     
@@ -591,7 +666,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         sceneObjectRoot->addChild(newLabel);
         setEditorProps(newLabel);
         newLabel->setPosition(cursorPosition);
-        selectEntity(newLabel);
+        didPlaceEntity(newLabel);
+        selectEntity(newLabel, false, false);
         return;
     }
     
@@ -602,7 +678,8 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         newLight->enabled = !lightsDisabled;        
         setEditorProps(newLight);
         newLight->setPosition(cursorPosition);
-        selectEntity(newLight);
+        didPlaceEntity(newLight);
+        selectEntity(newLight, false, false);
         return;
     }
     
@@ -650,14 +727,46 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         newEmitter->colorCurveA.addControlPoint2dWithHandles(-0.1, 0.5, 0.0, 0.5, 0.1, 0.5);
         newEmitter->colorCurveA.addControlPoint2dWithHandles(0.9, 0.5, 1.0, 0.5, 1.1, 0.5);
         
-        selectEntity(newEmitter);
+        selectEntity(newEmitter, false, false);
+        didPlaceEntity(newEmitter);        
         return;
         
     }
 }
 
-void EntityEditorMainView::deleteSelected() {
+void EntityEditorMainView::didPlaceEntity(Entity *entity) {
+    PolycodeSceneEditorActionData *beforeData = new PolycodeSceneEditorActionData();
+    PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+    data->reverse = false;
+    
+    for(int i=0; i < selectedEntities.size(); i++) {
+        beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]));
+    }
+    
+    PolycodeSceneEditorActionDataEntry entry(entity);
+    entry.parentEntity = sceneObjectRoot;
+    data->entries.push_back(entry);
+    
+    editor->didAction("create_entity", beforeData, data);
+}
+
+void EntityEditorMainView::deleteSelected(bool doAction) {
 
+    
+    if(doAction) {
+        PolycodeSceneEditorActionData *oldData = new PolycodeSceneEditorActionData();
+        PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+        data->reverse = false;
+        oldData->deleteEntitiesInDestructor = true;
+        
+        for(int i=0; i < selectedEntities.size(); i++) {
+            PolycodeSceneEditorActionDataEntry entry(selectedEntities[i]);
+            entry.parentEntity = selectedEntities[i]->getParentEntity();
+            oldData->entries.push_back(entry);
+        }
+
+        editor->didAction("delete", oldData, data);
+    }
     for(int i=0; i < selectedEntities.size(); i++) {
         selectedEntities[i]->getParentEntity()->removeChild(selectedEntities[i]);
     }
@@ -673,7 +782,7 @@ void EntityEditorMainView::deleteSelected() {
             }
         }
         selectedEntities[i]->removeAllHandlers();
-        delete selectedEntities[i];
+      //  delete selectedEntities[i];
     }
     
     selectedEntities.clear();
@@ -690,7 +799,76 @@ void EntityEditorMainView::onLoseFocus() {
 }
 
 void EntityEditorMainView::handleEvent(Event *event) {
-	if(event->getEventCode() == Event::RESOURCE_RELOAD_EVENT) {
+    
+    if(event->getDispatcher() == transformGizmo) {
+        if(event->getEventCode() == Event::CHANGE_EVENT) {
+            TrasnformGizmoEvent *trasnformEvent = (TrasnformGizmoEvent*) event;
+            switch(trasnformEvent->mode) {
+                case TransformGizmo::TRANSFORM_MOVE:
+                case TransformGizmo::TRANSFORM_MOVE_VIEW:
+                {
+                    PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        data->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getPosition()));
+                    }
+                    editor->didAction("move", beforeData, data);
+                }
+                break;
+                case TransformGizmo::TRANSFORM_SCALE:
+                case TransformGizmo::TRANSFORM_SCALE_VIEW:
+                {
+                    PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        data->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getScale()));
+                    }
+                    editor->didAction("scale", beforeData, data);
+                }
+                break;
+                case TransformGizmo::TRANSFORM_ROTATE:
+                case TransformGizmo::TRANSFORM_ROTATE_VIEW:
+                {
+                    PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        data->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getRotationQuat()));
+                    }
+                    editor->didAction("rotate", beforeData, data);
+                }
+                break;
+            }
+        } else if(event->getEventCode() == Event::SELECT_EVENT) {
+            TrasnformGizmoEvent *trasnformEvent = (TrasnformGizmoEvent*) event;
+            switch(trasnformEvent->mode) {
+                case TransformGizmo::TRANSFORM_MOVE:
+                case TransformGizmo::TRANSFORM_MOVE_VIEW:
+                {
+                    beforeData = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getPosition()));
+                    }
+                }
+                break;
+                case TransformGizmo::TRANSFORM_SCALE:
+                case TransformGizmo::TRANSFORM_SCALE_VIEW:
+                {
+                    beforeData = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getScale()));
+                    }
+                }
+                break;
+                case TransformGizmo::TRANSFORM_ROTATE:
+                case TransformGizmo::TRANSFORM_ROTATE_VIEW:
+                {
+                    beforeData = new PolycodeSceneEditorActionData();
+                    for(int i=0; i < selectedEntities.size(); i++) {
+                        beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]->getRotationQuat()));
+                    }
+                }
+                break;
+            }
+        }
+        
+	} else if(event->getEventCode() == Event::RESOURCE_RELOAD_EVENT) {
         SceneEntityInstanceResourceEntry *entry = dynamic_cast<SceneEntityInstanceResourceEntry*>(event->getDispatcher());
         if(entry) {
                 setEditorProps(entry->getInstance());
@@ -709,7 +887,8 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 sceneObjectRoot->addChild(newMesh);
                 setEditorProps(newMesh);
                 newMesh->setPosition(cursorPosition);
-                selectEntity(newMesh);
+                didPlaceEntity(newMesh);
+                selectEntity(newMesh, false, false);
             } else if(assetSelectType == "image") {
                 SceneImage *newImage = new SceneImage(globalFrame->assetBrowser->getSelectedAssetPath());
                 newImage->setMaterialByName("Unlit");
@@ -719,7 +898,8 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 sceneObjectRoot->addChild(newImage);
                 setEditorProps(newImage);
                 newImage->setPosition(cursorPosition);
-                selectEntity(newImage);
+                didPlaceEntity(newImage);
+                selectEntity(newImage, false, false);
             } else if(assetSelectType == "sprite") {
                 SceneSprite *newSprite = new SceneSprite(globalFrame->assetBrowser->getSelectedAssetPath());
                 
@@ -734,13 +914,16 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 sceneObjectRoot->addChild(newSprite);
                 setEditorProps(newSprite);
                 newSprite->setPosition(cursorPosition);
-                selectEntity(newSprite);
+                didPlaceEntity(newSprite);
+                selectEntity(newSprite, false, false);
             } else if(assetSelectType == "entity") {
                 SceneEntityInstance *newEntity = new SceneEntityInstance(mainScene, globalFrame->assetBrowser->getSelectedAssetPath());
                 sceneObjectRoot->addChild(newEntity);
                 setEditorProps(newEntity);
                 newEntity->setPosition(cursorPosition);
-                selectEntity(newEntity);            }
+                didPlaceEntity(newEntity);
+                selectEntity(newEntity, false, false);
+            }
             
             globalFrame->assetBrowser->removeAllHandlersForListener(this);
             globalFrame->hideModal();
@@ -776,12 +959,12 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 case KEY_BACKSPACE:
                 case KEY_DELETE:
                     if(hasFocus) {
-                        deleteSelected();
+                        deleteSelected(true);
                     }
                 break;
                 case KEY_ESCAPE:
                 {
-                    selectNone();
+                    selectNone(true);
                 }
                 break;
             }
@@ -827,7 +1010,18 @@ void EntityEditorMainView::handleEvent(Event *event) {
     }
 }
 
-void EntityEditorMainView::selectNone() {
+void EntityEditorMainView::selectNone(bool doAction) {
+    
+    if(doAction) {
+        
+        beforeData = new PolycodeSceneEditorActionData();
+        for(int i=0; i < selectedEntities.size(); i++) {
+            beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]));
+        }
+        
+        editor->didAction("select", beforeData, NULL, false);
+    }
+    
     for(int i=0; i < selectedEntities.size(); i++) {
         doEntityDeselect(selectedEntities[i]);
     }
@@ -899,7 +1093,14 @@ void EntityEditorMainView::doEntitySelect(Entity *targetEntity) {
 }
 
 
-void EntityEditorMainView::selectEntity(Entity *targetEntity, bool addToSelection) {
+void EntityEditorMainView::selectEntity(Entity *targetEntity, bool addToSelection, bool doAction) {
+
+    if(doAction) {
+        beforeData = new PolycodeSceneEditorActionData();
+        for(int i=0; i < selectedEntities.size(); i++) {
+            beforeData->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]));
+        }
+    }
     
     if(targetEntity->getUserData()) {
         SceneEntityInstance *instance = (SceneEntityInstance*)targetEntity->getUserData();
@@ -928,6 +1129,14 @@ void EntityEditorMainView::selectEntity(Entity *targetEntity, bool addToSelectio
         doEntitySelect(targetEntity);
     }
     
+    if(doAction) {
+        PolycodeSceneEditorActionData *data = new PolycodeSceneEditorActionData();
+        for(int i=0; i < selectedEntities.size(); i++) {
+            data->entries.push_back(PolycodeSceneEditorActionDataEntry(selectedEntities[i]));
+        }
+        editor->didAction("select", beforeData, data);
+    }
+    
     transformGizmo->setTransformSelection(selectedEntities);
     dispatchEvent(new Event(), Event::CHANGE_EVENT);
     
@@ -1036,7 +1245,7 @@ PolycodeEntityEditor::PolycodeEntityEditor() : PolycodeEditor(true){
 	mainSizer = new UIHSizer(300, 300, 300, false);
 	addChild(mainSizer);
     
-	mainView = new EntityEditorMainView();
+	mainView = new EntityEditorMainView(this);
     mainView->addEventListener(this, Event::CHANGE_EVENT);
 	mainSizer->addLeftChild(mainView);
     
@@ -1071,6 +1280,10 @@ void PolycodeEntityEditor::handleEvent(Event *event) {
     PolycodeEditor::handleEvent(event);
 }
 
+void PolycodeEntityEditor::doAction(String actionName, PolycodeEditorActionData *data) {
+    mainView->doAction(actionName, data);
+}
+
 PolycodeEntityEditor::~PolycodeEntityEditor() {
 }
 

+ 35 - 1
IDE/Contents/Source/TransformGizmo.cpp

@@ -24,6 +24,12 @@
 
 extern UIGlobalMenu *globalMenu;
 
+TrasnformGizmoEvent::TrasnformGizmoEvent(int mode) : Event() {
+    this->mode =  mode;
+    this->eventCode = eventCode;
+    eventType = "TrasnformGizmoEvent";
+}
+
 TransformGizmoMenu::TransformGizmoMenu(TransformGizmo *gizmo) : UIElement() {
 	processInputEvents = true;
     
@@ -92,7 +98,8 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
     orientation = ORIENTATION_GLOBAL;
     centerMode = CENTER_MODE_MEDIAN;
     enableGizmo = true;
-	
+    firstMove = true;
+    
 	this->targetScene = targetScene;
 	this->targetCamera = targetCamera;
 	
@@ -474,6 +481,11 @@ void TransformGizmo::setTransformSelection(std::vector<Entity*> selectedEntities
 
 void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector3 &scale, Number rotate) {
     
+    if(firstMove) {
+        firstMove = false;
+        dispatchEvent(new TrasnformGizmoEvent(mode), Event::SELECT_EVENT);
+    }
+    
     Vector3 globalCenter = getConcatenatedMatrix().getPosition();
     
 	for(int i=0; i < selectedEntities.size(); i++) {
@@ -716,9 +728,11 @@ void TransformGizmo::handleEvent(Event *event) {
                 case KEY_ESCAPE:
                 {
                     if(mode == TRANSFORM_SCALE_VIEW || mode == TRANSFORM_ROTATE_VIEW || mode == TRANSFORM_MOVE_VIEW) {
+                        dispatchEndEvent();
                         mode = previousMode;
                     }                    
                     transforming = false;
+                    firstMove = true;
                 }
                 break;
             }
@@ -794,10 +808,13 @@ void TransformGizmo::handleEvent(Event *event) {
                 break;
                 case InputEvent::EVENT_MOUSEUP:
                 {
+                    dispatchEndEvent();
+                    
                     if(mode == TRANSFORM_SCALE_VIEW || mode == TRANSFORM_ROTATE_VIEW || mode == TRANSFORM_MOVE_VIEW) {
                         mode = previousMode;
                     }
                     transforming = false;
+                    firstMove = true;
                 }
                 break;
             }
@@ -805,6 +822,23 @@ void TransformGizmo::handleEvent(Event *event) {
 	}
 }
 
+void TransformGizmo::dispatchEndEvent() {
+    switch(mode) {
+        case TRANSFORM_MOVE:
+        case TRANSFORM_MOVE_VIEW:
+            dispatchEvent(new TrasnformGizmoEvent(mode), Event::CHANGE_EVENT);
+            break;
+        case TRANSFORM_SCALE:
+        case TRANSFORM_SCALE_VIEW:
+            dispatchEvent(new TrasnformGizmoEvent(mode), Event::CHANGE_EVENT);
+            break;
+        case TRANSFORM_ROTATE:
+        case TRANSFORM_ROTATE_VIEW:
+            dispatchEvent(new TrasnformGizmoEvent(mode), Event::CHANGE_EVENT);
+            break;
+    }
+}
+
 TransformGizmo::~TransformGizmo() {
 
 }

Some files were not shown because too many files changed in this diff