Преглед изворни кода

Hooked up IDE property controls to the Undo/Redo system and implemented Undo/Redo in the screen editor for most actions. ColorPicker and HSlide no longer send out change events on drag, only on release, multiple fixes in the IDE

Ivan Safrin пре 12 година
родитељ
комит
d857b25e22

+ 127 - 12
IDE/Contents/Include/PolycodeProps.h

@@ -26,18 +26,26 @@
 #include "PolycodeUI.h"
 #include "PolycodeUI.h"
 #include "Polycode.h"
 #include "Polycode.h"
 #include "OSBasics.h"
 #include "OSBasics.h"
+#include "PolycodeEditor.h"
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
 
 
+class PolycodeEditorPropActionData;
+
 class PropProp : public UIElement {
 class PropProp : public UIElement {
 	public:
 	public:
 		PropProp(String caption, String type);
 		PropProp(String caption, String type);
 		~PropProp();
 		~PropProp();
-	
+
+		virtual void setPropData(PolycodeEditorPropActionData* data) {}
+		
 		String propType;
 		String propType;
 		ScreenLabel *label;
 		ScreenLabel *label;
-		ScreenEntity *propContents;
+		ScreenEntity *propContents;				
+		
+		bool suppressChangeEvent;		
+		bool settingFromData;
 };
 };
 
 
 class Vector2Prop : public PropProp {
 class Vector2Prop : public PropProp {
@@ -47,9 +55,14 @@ class Vector2Prop : public PropProp {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void set(Vector2 position);
 		void set(Vector2 position);
 		Vector2 get();
 		Vector2 get();
+		
+		void setPropData(PolycodeEditorPropActionData* data);
 				
 				
 		UITextInput *positionX;
 		UITextInput *positionX;
-		UITextInput *positionY;						
+		UITextInput *positionY;	
+		
+		Vector2 lastData;
+		Vector2 currentData;		
 };
 };
 
 
 class SliderProp : public PropProp {
 class SliderProp : public PropProp {
@@ -59,9 +72,14 @@ class SliderProp : public PropProp {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void set(Number number);
 		void set(Number number);
 		Number get();
 		Number get();
+		
+		void setPropData(PolycodeEditorPropActionData* data);		
 				
 				
 		UIHSlider *slider;
 		UIHSlider *slider;
 		ScreenLabel *valueLabel;
 		ScreenLabel *valueLabel;
+		
+		Number lastValue;
+		Number currentValue;
 };
 };
 
 
 
 
@@ -72,8 +90,13 @@ class NumberProp : public PropProp {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void set(Number number);
 		void set(Number number);
 		Number get();
 		Number get();
+		
+		void setPropData(PolycodeEditorPropActionData* data);
 				
 				
 		UITextInput *numberEntry;
 		UITextInput *numberEntry;
+		
+		Number lastValue;
+		Number currentValue;
 };
 };
 
 
 
 
@@ -98,8 +121,13 @@ class StringProp : public PropProp {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void set(String str);
 		void set(String str);
 		String get();
 		String get();
+
+		void setPropData(PolycodeEditorPropActionData* data);
 				
 				
 		UITextInput *stringEntry;
 		UITextInput *stringEntry;
+		
+		String lastValue;
+		String currentValue;
 };
 };
 
 
 class ColorProp : public PropProp {
 class ColorProp : public PropProp {
@@ -108,8 +136,13 @@ class ColorProp : public PropProp {
 		~ColorProp();		
 		~ColorProp();		
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		
 		
+		virtual void setPropData(PolycodeEditorPropActionData* data);
+		
 		void set(Color color);
 		void set(Color color);
 		Color get();
 		Color get();
+		
+		Color currentColor;
+		Color lastColor;
 				
 				
 		UIColorBox *colorEntry;
 		UIColorBox *colorEntry;
 };
 };
@@ -120,10 +153,15 @@ class ComboProp : public PropProp {
 		~ComboProp();		
 		~ComboProp();		
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		
 		
+		void setPropData(PolycodeEditorPropActionData* data);
+			
 		void set(unsigned int index);
 		void set(unsigned int index);
 		unsigned int get();
 		unsigned int get();
 				
 				
 		UIComboBox *comboEntry;
 		UIComboBox *comboEntry;
+		
+		int lastValue;
+		int currentValue;
 };
 };
 
 
 class BoolProp : public PropProp {
 class BoolProp : public PropProp {
@@ -132,10 +170,15 @@ class BoolProp : public PropProp {
 		~BoolProp();		
 		~BoolProp();		
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		
 		
+		void setPropData(PolycodeEditorPropActionData* data);
+		
 		void set(bool val);
 		void set(bool val);
 		bool get();
 		bool get();
 				
 				
 		UICheckBox *checkEntry;
 		UICheckBox *checkEntry;
+		
+		bool lastData;
+		bool currentData;
 };
 };
 
 
 class SoundProp : public PropProp {
 class SoundProp : public PropProp {
@@ -147,10 +190,15 @@ class SoundProp : public PropProp {
 		void set(String soundPath);
 		void set(String soundPath);
 		String get();
 		String get();
 		
 		
+		void setPropData(PolycodeEditorPropActionData* data);
+		
 		Sound *previewSound;
 		Sound *previewSound;
 		ScreenLabel *soundFile;		
 		ScreenLabel *soundFile;		
 		UIButton *changeButton;
 		UIButton *changeButton;
-		UIButton *playButton;		
+		UIButton *playButton;	
+		
+		String lastData;
+		String currentData;
 };
 };
 
 
 class BezierRGBACurveProp : public PropProp {
 class BezierRGBACurveProp : public PropProp {
@@ -187,23 +235,33 @@ class TextureProp : public PropProp {
 		
 		
 		void set(Texture *texture);
 		void set(Texture *texture);
 		Texture* get();
 		Texture* get();
+		
+		void setPropData(PolycodeEditorPropActionData* data);
 				
 				
 		ScreenShape *previewShape;
 		ScreenShape *previewShape;
 		UIButton *changeButton;
 		UIButton *changeButton;
 		ScreenLabel *textureLabel;
 		ScreenLabel *textureLabel;
+		
+		String lastData;
+		String currentData;
 };
 };
 
 
 class ScreenSpriteProp : public PropProp {
 class ScreenSpriteProp : public PropProp {
 	public:
 	public:
 		ScreenSpriteProp(String caption);
 		ScreenSpriteProp(String caption);
 		~ScreenSpriteProp();
 		~ScreenSpriteProp();
-		void handleEvent(Event *event);			
+		void handleEvent(Event *event);
+		
+		void setPropData(PolycodeEditorPropActionData* data);
 		
 		
 		void set(String fileName);
 		void set(String fileName);
 		String get();		
 		String get();		
 				
 				
 		ScreenSprite *previewSprite;
 		ScreenSprite *previewSprite;
 		UIButton *changeButton;
 		UIButton *changeButton;
+		
+		String lastData;
+		String currentData;
 };
 };
 
 
 
 
@@ -213,20 +271,27 @@ class ScreenEntityInstanceProp : public PropProp {
 		~ScreenEntityInstanceProp();
 		~ScreenEntityInstanceProp();
 		void handleEvent(Event *event);			
 		void handleEvent(Event *event);			
 		
 		
+		void setPropData(PolycodeEditorPropActionData* data);
+		
 		void set(String fileName);
 		void set(String fileName);
 		String get();		
 		String get();		
 				
 				
 		ScreenEntityInstance *previewInstance;
 		ScreenEntityInstance *previewInstance;
 		UIButton *changeButton;
 		UIButton *changeButton;
+		
+		String lastData;
+		String currentData;
+		
 };
 };
 
 
-
 class PropSheet : public UIElement {
 class PropSheet : public UIElement {
 	public:
 	public:
 		PropSheet(String caption, String type);
 		PropSheet(String caption, String type);
 		~PropSheet();		
 		~PropSheet();		
 		void Resize(Number width, Number height);
 		void Resize(Number width, Number height);
 		
 		
+		virtual void applyPropActionData(PolycodeEditorPropActionData *data);
+		
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		
 		
 		void setCollapsed(bool val);
 		void setCollapsed(bool val);
@@ -292,8 +357,8 @@ class ShaderTexturesSheet : public PropSheet {
 class EntitySheet : public PropSheet {
 class EntitySheet : public PropSheet {
 	public:
 	public:
 		EntitySheet();
 		EntitySheet();
-		~EntitySheet();
-		
+		~EntitySheet();	
+	
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void Update();
 		void Update();
 				
 				
@@ -312,7 +377,9 @@ class EntityPropSheet : public PropSheet {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void Update();
 		void Update();
 		void refreshProps();
 		void refreshProps();
-				
+
+		void applyPropActionData(PolycodeEditorPropActionData *data);
+
 		UIButton *addButton;
 		UIButton *addButton;
 		
 		
 		Entity *entity;
 		Entity *entity;
@@ -320,7 +387,7 @@ class EntityPropSheet : public PropSheet {
 		
 		
 		int lastNumProps;
 		int lastNumProps;
 		
 		
-		int removeIndex;
+		int removeIndex;		
 		
 		
 };
 };
 
 
@@ -357,7 +424,8 @@ class ScreenLabelSheet : public PropSheet {
 		void handleEvent(Event *event);
 		void handleEvent(Event *event);
 		void Update();
 		void Update();
 				
 				
-		ScreenLabel *label;	
+		ScreenLabel *label;
+		ScreenLabel *lastLabel;	
 		
 		
 		int lastSize;
 		int lastSize;
 		String lastFont;
 		String lastFont;
@@ -544,4 +612,51 @@ class PropList : public UIElement {
 		std::vector<PropSheet*> props;	
 		std::vector<PropSheet*> props;	
 		ScreenShape *bg;
 		ScreenShape *bg;
 		ScreenShape *bg2;				
 		ScreenShape *bg2;				
-};
+};
+
+class PolycodeEditorPropActionData : public PolycodeEditorActionData {
+	public:
+		PolycodeEditorPropActionData(){}
+		virtual ~PolycodeEditorPropActionData(){}
+		
+		bool boolVal;
+		String stringVal;
+		int intVal;
+		Number numVal;
+		Color colorVal;
+		Vector3 vector3Val;
+		Vector2 vector2Val;
+		
+		Entity entity;
+		
+		PropSheet *sheet;
+		PropProp *prop;
+};
+
+
+PolycodeEditorPropActionData *PropDataBool(bool val);
+PolycodeEditorPropActionData *PropDataInt(int val);
+PolycodeEditorPropActionData *PropDataNumber(Number val);
+PolycodeEditorPropActionData *PropDataString(String val);
+PolycodeEditorPropActionData *PropDataColor(Color val);
+PolycodeEditorPropActionData *PropDataVector3(Vector3 val);
+PolycodeEditorPropActionData *PropDataVector2(Vector2 val);
+PolycodeEditorPropActionData *PropDataEntity(Entity *entity);
+
+class PropEvent : public Event {
+	public:
+		PropEvent(PropProp *prop, PropSheet *sheet, PolycodeEditorPropActionData *beforeData, PolycodeEditorPropActionData *afterData);
+		virtual ~PropEvent();
+		
+		void setSheet(PropSheet *sheet);
+		
+		PropProp *prop;
+		PropSheet *sheet;
+		
+		PolycodeEditorPropActionData *beforeData;
+		PolycodeEditorPropActionData *afterData;
+				
+		static const int EVENTBASE_PROPEVENT = 0xC00;
+		static const int EVENT_PROP_CHANGE = EVENTBASE_PROPEVENT+0;
+
+};

+ 2 - 0
IDE/Contents/Source/PolycodeEditor.cpp

@@ -118,6 +118,8 @@ void PolycodeEditor::handleEvent(Event *event) {
 }
 }
 
 
 void PolycodeEditor::didAction(String actionName, PolycodeEditorActionData *beforeData, PolycodeEditorActionData *afterData, bool setFileChanged) {
 void PolycodeEditor::didAction(String actionName, PolycodeEditorActionData *beforeData, PolycodeEditorActionData *afterData, bool setFileChanged) {
+
+//	printf("DID ACTION: %s\n", actionName.c_str());
 	
 	
 	if(setFileChanged) {
 	if(setFileChanged) {
 		setHasChanges(true);
 		setHasChanges(true);

+ 324 - 87
IDE/Contents/Source/PolycodeProps.cpp

@@ -27,6 +27,91 @@ extern UIColorPicker *globalColorPicker;
 extern PolycodeFrame *globalFrame;
 extern PolycodeFrame *globalFrame;
 extern UIGlobalMenu *globalMenu;
 extern UIGlobalMenu *globalMenu;
 
 
+PolycodeEditorPropActionData *PropDataBool(bool val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->boolVal = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataInt(int val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->intVal = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataNumber(Number val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->numVal = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataString(String val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->stringVal = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataColor(Color val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->colorVal = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataVector3(Vector3 val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->vector3Val = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataVector2(Vector2 val) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->vector2Val = val;
+	return data;
+}
+
+PolycodeEditorPropActionData *PropDataEntity(Entity *entity) {
+	PolycodeEditorPropActionData *data = new PolycodeEditorPropActionData();
+	data->entity = *entity;
+	data->entity.ownsChildren = false;
+	for(int i=0; i < data->entity.getNumChildren(); i++) {
+		data->entity.removeChild(data->entity.getChildAtIndex(i));
+	}
+	return data;
+}
+
+PropEvent::PropEvent(PropProp *prop, PropSheet *sheet, PolycodeEditorPropActionData *beforeData, PolycodeEditorPropActionData *afterData) : Event() {
+	this->prop = prop;
+	this->sheet = sheet;
+	this->beforeData = beforeData;
+	this->afterData = afterData;	
+	this->eventType = "PropEvent";
+	
+	if(this->beforeData) {
+		this->beforeData->sheet = sheet;
+		this->beforeData->prop = prop;
+	}
+
+	if(this->afterData) {
+		this->afterData->sheet = sheet;
+		this->afterData->prop = prop;
+	}
+		
+}
+
+void PropEvent::setSheet(PropSheet *sheet) {
+	if(this->beforeData) {
+		this->beforeData->sheet = sheet;
+	}
+
+	if(this->afterData) {
+		this->afterData->sheet = sheet;
+	}
+}
+
+PropEvent::~PropEvent() {
+
+}
+
 PropList::PropList(String caption) : UIElement() {
 PropList::PropList(String caption) : UIElement() {
 
 
 	setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 	setPositionMode(ScreenEntity::POSITION_TOPLEFT);
@@ -106,7 +191,9 @@ void PropList::Resize(Number width, Number height) {
 void PropList::handleEvent(Event *event) {
 void PropList::handleEvent(Event *event) {
 	if(event->getEventType() == "" && event->getEventCode() == Event::COMPLETE_EVENT) {
 	if(event->getEventType() == "" && event->getEventCode() == Event::COMPLETE_EVENT) {
 		Resize(width, height);
 		Resize(width, height);
-	}	
+	} else if(event->getEventCode() == Event::CHANGE_EVENT) {
+	
+	}
 }
 }
 
 
 void PropList::addPropSheet(PropSheet *sheet) {
 void PropList::addPropSheet(PropSheet *sheet) {
@@ -114,6 +201,7 @@ void PropList::addPropSheet(PropSheet *sheet) {
 	props.push_back(sheet);
 	props.push_back(sheet);
 	Resize(width, height);
 	Resize(width, height);
 	sheet->addEventListener(this, Event::COMPLETE_EVENT);
 	sheet->addEventListener(this, Event::COMPLETE_EVENT);
+	sheet->addEventListener(this, Event::CHANGE_EVENT);	
 }
 }
 
 
 PropSheet::PropSheet(String caption, String type) : UIElement() {
 PropSheet::PropSheet(String caption, String type) : UIElement() {
@@ -177,8 +265,13 @@ void PropSheet::handleEvent(Event *event) {
 		if(event->getDispatcher() == expandButton) {
 		if(event->getDispatcher() == expandButton) {
 			setCollapsed(false);
 			setCollapsed(false);
 		}
 		}
-
 	}
 	}
+	
+	if(event->getEventCode() == PropEvent::EVENT_PROP_CHANGE ) {
+		PropEvent *propEvent = (PropEvent*) event;
+		PropEvent *newEvent = new PropEvent(propEvent->prop, this, propEvent->beforeData, propEvent->afterData);		
+		dispatchEvent(newEvent, PropEvent::EVENT_PROP_CHANGE);
+	}	
 }
 }
 
 
 PropSheet::~PropSheet() {
 PropSheet::~PropSheet() {
@@ -203,11 +296,19 @@ void PropSheet::addProp(PropProp *prop) {
 	contents->addChild(prop);
 	contents->addChild(prop);
 	props.push_back(prop);
 	props.push_back(prop);
 	prop->addEventListener(this, Event::CHANGE_EVENT);
 	prop->addEventListener(this, Event::CHANGE_EVENT);
+	prop->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);	
 	Resize(width, height);
 	Resize(width, height);
 }
 }
 
 
+
+void PropSheet::applyPropActionData(PolycodeEditorPropActionData *data) {
+	data->prop->setPropData(data);
+}
+
+
 PropProp::PropProp(String caption, String type) : UIElement() {
 PropProp::PropProp(String caption, String type) : UIElement() {
 
 
+	suppressChangeEvent = false;
 	propType = type;
 	propType = type;
 	label = new ScreenLabel(caption, 12);
 	label = new ScreenLabel(caption, 12);
 	label->color.a = 0.4;
 	label->color.a = 0.4;
@@ -237,6 +338,9 @@ Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 	label->color.a = 0.4;
 	label->color.a = 0.4;
 	propContents->addChild(label);
 	propContents->addChild(label);
 	label->setPosition(60, 6);	
 	label->setPosition(60, 6);	
+	
+	positionX = NULL;
+	positionY = NULL;
 
 
 	positionX = new UITextInput(false, 50, 12);
 	positionX = new UITextInput(false, 50, 12);
 	positionX->addEventListener(this, UIEvent::CHANGE_EVENT);
 	positionX->addEventListener(this, UIEvent::CHANGE_EVENT);
@@ -258,15 +362,31 @@ Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 
 
 void Vector2Prop::handleEvent(Event *event) {
 void Vector2Prop::handleEvent(Event *event) {
 	if(event->getDispatcher() == positionX || event->getDispatcher() == positionY) {
 	if(event->getDispatcher() == positionX || event->getDispatcher() == positionY) {
-		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		
+			if(positionX && positionY) {
+				lastData = currentData;
+				currentData = Vector2(atof(positionX->getText().c_str()), atof(positionY->getText().c_str()));
+			}
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataVector2(lastData), PropDataVector2(currentData)), PropEvent::EVENT_PROP_CHANGE);
+
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
+void Vector2Prop::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->vector2Val);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
 void Vector2Prop::set(Vector2 position) {
 void Vector2Prop::set(Vector2 position) {
+	suppressChangeEvent = true;
 	positionX->setText(String::NumberToString(position.x));
 	positionX->setText(String::NumberToString(position.x));
 	positionY->setText(String::NumberToString(position.y));
 	positionY->setText(String::NumberToString(position.y));
+	suppressChangeEvent = false;	
 }
 }
 
 
 Vector2 Vector2Prop::get() {
 Vector2 Vector2Prop::get() {
@@ -300,7 +420,12 @@ CustomProp::CustomProp(String key, String value) : PropProp("", "Custom") {
 }
 }
 
 
 CustomProp::~CustomProp() {
 CustomProp::~CustomProp() {
-
+	keyEntry->removeAllHandlersForListener(this);
+	valueEntry->removeAllHandlersForListener(this);
+	removeButton->removeAllHandlersForListener(this);
+	delete removeButton;
+	delete keyEntry;
+	delete valueEntry;
 }
 }
 
 
 void CustomProp::handleEvent(Event *event) {
 void CustomProp::handleEvent(Event *event) {
@@ -343,17 +468,29 @@ StringProp::StringProp(String caption) : PropProp(caption, "String") {
 void StringProp::handleEvent(Event *event) {
 void StringProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == stringEntry) {
 	if(event->getDispatcher() == stringEntry) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			lastValue = currentValue;
+			currentValue = stringEntry->getText();
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataString(lastValue), PropDataString(currentValue)), PropEvent::EVENT_PROP_CHANGE);
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
+void StringProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->stringVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void StringProp::set(String str) {
 void StringProp::set(String str) {
-	stringEntry->setText(str);
+	suppressChangeEvent = true;
+	stringEntry->setText(str, false);
+	suppressChangeEvent = false;	
 }
 }
 
 
 String StringProp::get() {
 String StringProp::get() {
-	return stringEntry->getText();
+	return currentValue;
 }
 }
 	
 	
 		
 		
@@ -362,7 +499,7 @@ StringProp::~StringProp() {
 }
 }
 
 
 SliderProp::SliderProp(String caption, Number min, Number max) : PropProp(caption, "Slider") {
 SliderProp::SliderProp(String caption, Number min, Number max) : PropProp(caption, "Slider") {
-
+	
 	slider = new UIHSlider(min, max, 100);
 	slider = new UIHSlider(min, max, 100);
 	slider->addEventListener(this, UIEvent::CHANGE_EVENT);
 	slider->addEventListener(this, UIEvent::CHANGE_EVENT);
 	slider->setPosition(5, 8);
 	slider->setPosition(5, 8);
@@ -380,19 +517,35 @@ SliderProp::SliderProp(String caption, Number min, Number max) : PropProp(captio
 void SliderProp::handleEvent(Event *event) {
 void SliderProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == slider) {
 	if(event->getDispatcher() == slider) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			lastValue = currentValue;
+			currentValue = slider->getSliderValue();		
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataNumber(lastValue), PropDataNumber(currentValue)), PropEvent::EVENT_PROP_CHANGE);
+			}
 			valueLabel->setText(String::NumberToString(slider->getSliderValue()));
 			valueLabel->setText(String::NumberToString(slider->getSliderValue()));
 		}
 		}
 	}
 	}
 }
 }
 
 
+void SliderProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->numVal);
+	lastValue = currentValue;
+	currentValue = slider->getSliderValue();			
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void SliderProp::set(Number number) {
 void SliderProp::set(Number number) {
+	suppressChangeEvent = true;
 	slider->setSliderValue(number);
 	slider->setSliderValue(number);
+	lastValue = currentValue;
+	currentValue = slider->getSliderValue();	
 	valueLabel->setText(String::NumberToString(slider->getSliderValue()));	
 	valueLabel->setText(String::NumberToString(slider->getSliderValue()));	
+	suppressChangeEvent = false;	
 }
 }
 
 
 Number SliderProp::get() {
 Number SliderProp::get() {
-	return slider->getSliderValue();
+	return currentValue;
 }
 }
 	
 	
 		
 		
@@ -413,20 +566,33 @@ NumberProp::NumberProp(String caption) : PropProp(caption, "Number") {
 
 
 }
 }
 
 
+void NumberProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->numVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void NumberProp::handleEvent(Event *event) {
 void NumberProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == numberEntry) {
 	if(event->getDispatcher() == numberEntry) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			lastValue = currentValue;
+			currentValue = atof(numberEntry->getText().c_str());
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataNumber(lastValue), PropDataNumber(currentValue)), PropEvent::EVENT_PROP_CHANGE);
+				
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
 void NumberProp::set(Number number) {
 void NumberProp::set(Number number) {
-	numberEntry->setText(String::NumberToString(number));
+	suppressChangeEvent = true;
+	numberEntry->setText(String::NumberToString(number), false);
+	suppressChangeEvent = false;	
 }
 }
 
 
 Number NumberProp::get() {
 Number NumberProp::get() {
-	return atof(numberEntry->getText().c_str());
+	return currentValue;
 }
 }
 	
 	
 		
 		
@@ -446,18 +612,34 @@ ColorProp::ColorProp(String caption) : PropProp(caption, "Color") {
 
 
 void ColorProp::handleEvent(Event *event) {
 void ColorProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == colorEntry) {
 	if(event->getDispatcher() == colorEntry) {
-		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+			lastColor = currentColor;
+			currentColor = colorEntry->getSelectedColor();
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataColor(lastColor), PropDataColor(currentColor)), PropEvent::EVENT_PROP_CHANGE);
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
+
+void ColorProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->colorVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
+
 void ColorProp::set(Color color) {
 void ColorProp::set(Color color) {
+	suppressChangeEvent = true;
 	colorEntry->setBoxColor(color);
 	colorEntry->setBoxColor(color);
+	lastColor = currentColor;
+	currentColor = colorEntry->getSelectedColor();	
+	suppressChangeEvent = false;	
 }
 }
 
 
 Color ColorProp::get() {
 Color ColorProp::get() {
-	return colorEntry->getSelectedColor();
+	return currentColor;
 }
 }
 	
 	
 		
 		
@@ -466,7 +648,6 @@ ColorProp::~ColorProp() {
 }
 }
 
 
 ComboProp::ComboProp(String caption) : PropProp(caption, "Combo") {
 ComboProp::ComboProp(String caption) : PropProp(caption, "Combo") {
-
 	comboEntry = new UIComboBox(globalMenu, 150);
 	comboEntry = new UIComboBox(globalMenu, 150);
 	comboEntry->addEventListener(this, UIEvent::CHANGE_EVENT);
 	comboEntry->addEventListener(this, UIEvent::CHANGE_EVENT);
 	propContents->addChild(comboEntry);
 	propContents->addChild(comboEntry);
@@ -475,20 +656,32 @@ ComboProp::ComboProp(String caption) : PropProp(caption, "Combo") {
 
 
 }
 }
 
 
+void ComboProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->intVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void ComboProp::handleEvent(Event *event) {
 void ComboProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == comboEntry) {
 	if(event->getDispatcher() == comboEntry) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			lastValue = currentValue;
+			currentValue = comboEntry->getSelectedIndex();
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				dispatchEvent(new PropEvent(this, NULL, PropDataInt(lastValue), PropDataInt(currentValue)), PropEvent::EVENT_PROP_CHANGE);
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
 void ComboProp::set(unsigned int index) {
 void ComboProp::set(unsigned int index) {
+	suppressChangeEvent = true;
 	comboEntry->setSelectedIndex(index);
 	comboEntry->setSelectedIndex(index);
+	suppressChangeEvent = false;	
 }
 }
 
 
 unsigned int ComboProp::get() {
 unsigned int ComboProp::get() {
-	return comboEntry->getSelectedIndex();
+	return currentValue;
 }
 }
 	
 	
 		
 		
@@ -506,20 +699,30 @@ BoolProp::BoolProp(String caption) : PropProp(caption, "Bool") {
 
 
 }
 }
 
 
+void BoolProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->boolVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void BoolProp::handleEvent(Event *event) {
 void BoolProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == checkEntry) {
 	if(event->getDispatcher() == checkEntry) {
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
 		if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CHANGE_EVENT) {		
+			lastData = currentData;
+			currentData = checkEntry->isChecked();
 			dispatchEvent(new Event(), Event::CHANGE_EVENT);
 			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			dispatchEvent(new PropEvent(this, NULL, PropDataBool(lastData), PropDataBool(currentData)), PropEvent::EVENT_PROP_CHANGE);
 		}
 		}
 	}
 	}
 }
 }
 
 
 void BoolProp::set(bool val) {
 void BoolProp::set(bool val) {
 	checkEntry->setChecked(val);
 	checkEntry->setChecked(val);
+	lastData = currentData;
+	currentData = checkEntry->isChecked();	
 }
 }
 
 
 bool BoolProp::get() {
 bool BoolProp::get() {
-	return checkEntry->isChecked();
+	return currentData;
 }
 }
 	
 	
 		
 		
@@ -564,7 +767,8 @@ void SoundProp::handleEvent(Event *event) {
 		set(newSoundPath);
 		set(newSoundPath);
 		
 		
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		dispatchEvent(new PropEvent(this, NULL, PropDataString(lastData), PropDataString(currentData)), PropEvent::EVENT_PROP_CHANGE);
 		globalFrame->hideModal();
 		globalFrame->hideModal();
 		
 		
 	}
 	}
@@ -586,10 +790,19 @@ void SoundProp::handleEvent(Event *event) {
 
 
 }
 }
 
 
+void SoundProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->stringVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void SoundProp::set(String soundPath) {
 void SoundProp::set(String soundPath) {
 	if(previewSound) {
 	if(previewSound) {
 		delete previewSound;
 		delete previewSound;
 	}	
 	}	
+	
+	lastData = currentData;
+	currentData = soundPath;
+	
 	previewSound = new Sound(soundPath);	
 	previewSound = new Sound(soundPath);	
 	soundFile->setText(soundPath);
 	soundFile->setText(soundPath);
 }
 }
@@ -685,20 +898,19 @@ TextureProp::~TextureProp() {
 
 
 }
 }
 
 
+void TextureProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(data->stringVal));
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
 
 
 void TextureProp::handleEvent(Event *event) {
 void TextureProp::handleEvent(Event *event) {
 
 
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
-		String texturePath = globalFrame->assetBrowser->getSelectedAssetPath();
-				
-		previewShape->loadTexture(texturePath);
-		
-		OSFileEntry entry = OSFileEntry(texturePath, OSFileEntry::TYPE_FILE);		
-		textureLabel->setText(entry.name);		
-		
+		String texturePath = globalFrame->assetBrowser->getSelectedAssetPath();				
+		set(CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(texturePath));		
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-		
+		dispatchEvent(new PropEvent(this, NULL, PropDataString(lastData), PropDataString(currentData)), PropEvent::EVENT_PROP_CHANGE);
 		globalFrame->hideModal();
 		globalFrame->hideModal();
 		
 		
 	}
 	}
@@ -715,6 +927,9 @@ void TextureProp::handleEvent(Event *event) {
 void TextureProp::set(Texture *texture) {
 void TextureProp::set(Texture *texture) {
 	previewShape->setTexture(texture);
 	previewShape->setTexture(texture);
 	
 	
+	lastData = currentData;
+	currentData = texture->getResourcePath();
+	
 	OSFileEntry entry = OSFileEntry(texture->getResourcePath(), OSFileEntry::TYPE_FILE);		
 	OSFileEntry entry = OSFileEntry(texture->getResourcePath(), OSFileEntry::TYPE_FILE);		
 	textureLabel->setText(entry.name);		
 	textureLabel->setText(entry.name);		
 	
 	
@@ -723,6 +938,7 @@ void TextureProp::set(Texture *texture) {
 Texture* TextureProp::get() {
 Texture* TextureProp::get() {
 	return previewShape->getTexture();
 	return previewShape->getTexture();
 }
 }
+
 ScreenSpriteProp::ScreenSpriteProp(String caption) : PropProp(caption, "ScreenSprite"){
 ScreenSpriteProp::ScreenSpriteProp(String caption) : PropProp(caption, "ScreenSprite"){
 
 
 		previewSprite = new ScreenSprite("default/default.sprite");
 		previewSprite = new ScreenSprite("default/default.sprite");
@@ -743,26 +959,16 @@ ScreenSpriteProp::~ScreenSpriteProp() {
 
 
 }
 }
 
 
-
 void ScreenSpriteProp::handleEvent(Event *event) {
 void ScreenSpriteProp::handleEvent(Event *event) {
 
 
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 		String filePath = globalFrame->assetBrowser->getSelectedAssetPath();
 		String filePath = globalFrame->assetBrowser->getSelectedAssetPath();
 		
 		
-		if(previewSprite) {
-			propContents->removeChild(previewSprite);
-			delete previewSprite;
-		}
-		
-		previewSprite = new ScreenSprite(filePath);
-		previewSprite->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
-		previewSprite->setPosition(2, 1);
-		previewSprite->setShapeSize(48,48);		
-		propContents->addChild(previewSprite);	
+		set(filePath);
 		
 		
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-		
+		dispatchEvent(new PropEvent(this, NULL, PropDataString(lastData), PropDataString(currentData)), PropEvent::EVENT_PROP_CHANGE);
 		globalFrame->hideModal();
 		globalFrame->hideModal();
 	}
 	}
 
 
@@ -775,6 +981,11 @@ void ScreenSpriteProp::handleEvent(Event *event) {
 	}
 	}
 }
 }
 
 
+void ScreenSpriteProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->stringVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);	
+}
+
 void ScreenSpriteProp::set(String fileName) {
 void ScreenSpriteProp::set(String fileName) {
 
 
 	if(fileName != previewSprite->getFileName()) {
 	if(fileName != previewSprite->getFileName()) {
@@ -783,6 +994,9 @@ void ScreenSpriteProp::set(String fileName) {
 			propContents->removeChild(previewSprite);
 			propContents->removeChild(previewSprite);
 			delete previewSprite;
 			delete previewSprite;
 		}
 		}
+		lastData = currentData;
+		currentData = fileName;
+		
 		previewSprite = new ScreenSprite(fileName);
 		previewSprite = new ScreenSprite(fileName);
 		previewSprite->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 		previewSprite->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 		previewSprite->setPosition(2, 1);
 		previewSprite->setPosition(2, 1);
@@ -818,21 +1032,11 @@ void ScreenEntityInstanceProp::handleEvent(Event *event) {
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
 		String filePath = globalFrame->assetBrowser->getSelectedAssetPath();
 		String filePath = globalFrame->assetBrowser->getSelectedAssetPath();
 		
 		
-		propContents->removeChild(previewInstance);
-		delete previewInstance;
-		previewInstance = new ScreenEntityInstance(filePath);
-		previewInstance->getResourceEntry()->reloadOnFileModify = true;
-		CoreServices::getInstance()->getResourceManager()->addResource(previewInstance->getResourceEntry());
-		previewInstance->setPosition(24, 24);
-		
-		Number radius = previewInstance->getCompoundBBoxRadius();
-		previewInstance->setScale(48.0/(radius*2.0), 48.0/(radius*2.0));
-		
-		propContents->addChild(previewInstance);
+		set(filePath);
 		
 		
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		globalFrame->assetBrowser->removeAllHandlersForListener(this);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-		
+		dispatchEvent(new PropEvent(this, NULL, PropDataString(lastData), PropDataString(currentData)), PropEvent::EVENT_PROP_CHANGE);
 		globalFrame->hideModal();
 		globalFrame->hideModal();
 	}
 	}
 
 
@@ -845,6 +1049,11 @@ void ScreenEntityInstanceProp::handleEvent(Event *event) {
 	}
 	}
 }
 }
 
 
+void ScreenEntityInstanceProp::setPropData(PolycodeEditorPropActionData* data) {
+	set(data->stringVal);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
 void ScreenEntityInstanceProp::set(String fileName) {
 void ScreenEntityInstanceProp::set(String fileName) {
 
 
 	if(fileName != previewInstance->getFileName()) {
 	if(fileName != previewInstance->getFileName()) {
@@ -854,6 +1063,9 @@ void ScreenEntityInstanceProp::set(String fileName) {
 		previewInstance->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 		previewInstance->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 		previewInstance->setPosition(2, 1);
 		previewInstance->setPosition(2, 1);
 		
 		
+		lastData = currentData;
+		currentData = fileName;
+		
 		Number radius = previewInstance->getCompoundBBoxRadius();
 		Number radius = previewInstance->getCompoundBBoxRadius();
 		if(radius > 48) {
 		if(radius > 48) {
 			previewInstance->setScale(48.0/(radius*2.0), 48.0/(radius*2.0));		
 			previewInstance->setScale(48.0/(radius*2.0), 48.0/(radius*2.0));		
@@ -902,7 +1114,6 @@ void ShapeSheet::handleEvent(Event *event) {
 	if(!shape)
 	if(!shape)
 		return;
 		return;
 
 
-
 	if(event->getDispatcher() == strokeProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 	if(event->getDispatcher() == strokeProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 		lastStrokeVal = strokeProp->get();
 		lastStrokeVal = strokeProp->get();
 		shape->strokeEnabled = lastStrokeVal;
 		shape->strokeEnabled = lastStrokeVal;
@@ -912,7 +1123,7 @@ void ShapeSheet::handleEvent(Event *event) {
 	if(event->getDispatcher() == shapeSize  && event->getEventCode() == Event::CHANGE_EVENT) {
 	if(event->getDispatcher() == shapeSize  && event->getEventCode() == Event::CHANGE_EVENT) {
 		lastShapeSize = shapeSize->get();
 		lastShapeSize = shapeSize->get();
 		shape->setShapeSize(lastShapeSize.x, lastShapeSize.y);
 		shape->setShapeSize(lastShapeSize.x, lastShapeSize.y);
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);	
 	}
 	}
 
 
 	if(event->getDispatcher() == typeProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 	if(event->getDispatcher() == typeProp  && event->getEventCode() == Event::CHANGE_EVENT) {
@@ -930,7 +1141,7 @@ void ShapeSheet::handleEvent(Event *event) {
 	if(event->getDispatcher() == strokeSize  && event->getEventCode() == Event::CHANGE_EVENT) {
 	if(event->getDispatcher() == strokeSize  && event->getEventCode() == Event::CHANGE_EVENT) {
 		lastStrokeSize = strokeSize->get();
 		lastStrokeSize = strokeSize->get();
 		shape->strokeWidth = lastStrokeSize;
 		shape->strokeWidth = lastStrokeSize;
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);	
 	}
 	}
 	
 	
 	PropSheet::handleEvent(event);
 	PropSheet::handleEvent(event);
@@ -948,10 +1159,12 @@ void ShapeSheet::Update() {
 		
 		
 		if(lastShapeType != shape->getShapeType()-1) {
 		if(lastShapeType != shape->getShapeType()-1) {
 			typeProp->set(shape->getShapeType()-1);			
 			typeProp->set(shape->getShapeType()-1);			
+			lastShapeType = shape->getShapeType()-1;			
 		}
 		}
 		
 		
 		if(lastStrokeVal != shape->strokeEnabled) {
 		if(lastStrokeVal != shape->strokeEnabled) {
 			strokeProp->set(shape->strokeEnabled);
 			strokeProp->set(shape->strokeEnabled);
+			lastStrokeVal = shape->strokeEnabled;
 		}
 		}
 		
 		
 		if(lastStrokeColor != shape->strokeColor) {
 		if(lastStrokeColor != shape->strokeColor) {
@@ -983,13 +1196,31 @@ EntityPropSheet::EntityPropSheet() : PropSheet("CUSTOM PROPERTIES", "entityProps
 	removeIndex = -1;
 	removeIndex = -1;
 }
 }
 
 
+void EntityPropSheet::applyPropActionData(PolycodeEditorPropActionData *data) {
+	if(!entity)
+		return;
+		
+	entity->entityProps.clear();
+	for(int i=0; i < data->entity.entityProps.size(); i++) {
+			entity->entityProps.push_back(data->entity.entityProps[i]);
+	}
+	
+	refreshProps();
+}
+
+
 void EntityPropSheet::handleEvent(Event *event) {
 void EntityPropSheet::handleEvent(Event *event) {
 	if(!entity)
 	if(!entity)
 		return;
 		return;
 		
 		
 	if(event->getDispatcher() == addButton && event->getEventType() == "UIEvent") {
 	if(event->getDispatcher() == addButton && event->getEventType() == "UIEvent") {
+		PolycodeEditorPropActionData *beforeData = PropDataEntity(entity);	
 		entity->entityProps.push_back(EntityProp());
 		entity->entityProps.push_back(EntityProp());
 		refreshProps();
 		refreshProps();
+		PolycodeEditorPropActionData *afterData = PropDataEntity(entity);			
+		PropEvent *propEvent = new PropEvent(NULL, this, beforeData, afterData);
+		dispatchEvent(propEvent, PropEvent::EVENT_PROP_CHANGE);					
+		
 	}
 	}
 	
 	
 	for(int i=0; i < props.size(); i++) {
 	for(int i=0; i < props.size(); i++) {
@@ -999,15 +1230,19 @@ void EntityPropSheet::handleEvent(Event *event) {
 					removeIndex = i;
 					removeIndex = i;
 				break;
 				break;
 				case Event::CHANGE_EVENT:
 				case Event::CHANGE_EVENT:
+					PolycodeEditorPropActionData *beforeData = PropDataEntity(entity);
 					if(i < entity->entityProps.size()) {
 					if(i < entity->entityProps.size()) {
 						entity->entityProps[i].propName = ((CustomProp*)props[i])->getKey();
 						entity->entityProps[i].propName = ((CustomProp*)props[i])->getKey();
 						entity->entityProps[i].propValue = ((CustomProp*)props[i])->getValue();			
 						entity->entityProps[i].propValue = ((CustomProp*)props[i])->getValue();			
 					}
 					}
+					PolycodeEditorPropActionData *afterData = PropDataEntity(entity);			
+					PropEvent *propEvent = new PropEvent(NULL, this, beforeData, afterData);
+					dispatchEvent(propEvent, PropEvent::EVENT_PROP_CHANGE);					
 				break;				
 				break;				
 			}
 			}
 		}
 		}
 	}
 	}
-
+	PropSheet::handleEvent(event);
 }
 }
 
 
 void EntityPropSheet::refreshProps() {
 void EntityPropSheet::refreshProps() {
@@ -1046,11 +1281,17 @@ void EntityPropSheet::Update() {
 	if(entity) {
 	if(entity) {
 	
 	
 		if(removeIndex != -1) {
 		if(removeIndex != -1) {
+		
+			PolycodeEditorPropActionData *beforeData = PropDataEntity(entity);
+				
 			if(removeIndex < entity->entityProps.size()) {
 			if(removeIndex < entity->entityProps.size()) {
 				entity->entityProps.erase(entity->entityProps.begin() + removeIndex);
 				entity->entityProps.erase(entity->entityProps.begin() + removeIndex);
 			}
 			}
 			removeIndex = -1;
 			removeIndex = -1;
 			refreshProps();
 			refreshProps();
+			PolycodeEditorPropActionData *afterData = PropDataEntity(entity);			
+			PropEvent *propEvent = new PropEvent(NULL, this, beforeData, afterData);
+			dispatchEvent(propEvent, PropEvent::EVENT_PROP_CHANGE);
 		}
 		}
 	
 	
 		enabled = true;		
 		enabled = true;		
@@ -1308,7 +1549,7 @@ EntitySheet::EntitySheet() : PropSheet("ENTITY", "entity"){
 EntitySheet::~EntitySheet() {
 EntitySheet::~EntitySheet() {
 
 
 }
 }
-		
+
 void EntitySheet::handleEvent(Event *event) {
 void EntitySheet::handleEvent(Event *event) {
 
 
 	if(!entity)
 	if(!entity)
@@ -1316,31 +1557,26 @@ void EntitySheet::handleEvent(Event *event) {
 
 
 	if(event->getDispatcher() == blendingProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 	if(event->getDispatcher() == blendingProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 		entity->blendingMode = blendingProp->get();
 		entity->blendingMode = blendingProp->get();
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-	}
-
-
-	if(event->getDispatcher() == colorProp  && event->getEventCode() == Event::CHANGE_EVENT) {
+	} else if(event->getDispatcher() == colorProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 		entity->color = colorProp->get();
 		entity->color = colorProp->get();
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-	}
-
-		
-	if(event->getDispatcher() == idProp  && event->getEventCode() == Event::CHANGE_EVENT) {
+	}else if(event->getDispatcher() == idProp  && event->getEventCode() == Event::CHANGE_EVENT) {
 		entity->id = idProp->get();
 		entity->id = idProp->get();
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
-	}
-
-	if(event->getDispatcher() == tagProp  && event->getEventCode() == Event::CHANGE_EVENT) {
+	} else if(event->getDispatcher() == tagProp  && event->getEventCode() == Event::CHANGE_EVENT) {
+		
+		String tagString = "";
+		for(int i=0; i < entity->getNumTags(); i++) {
+			if(i != 0) {
+				tagString += ",";
+			}
+			tagString += entity->getTagAtIndex(i);
+		}
 		
 		
 		entity->clearTags();
 		entity->clearTags();
 		String cleaned =  tagProp->get().replace(" ", "");
 		String cleaned =  tagProp->get().replace(" ", "");
 		std::vector<String> tags = cleaned.split(",");
 		std::vector<String> tags = cleaned.split(",");
 		for(int i=0; i < tags.size(); i++) {
 		for(int i=0; i < tags.size(); i++) {
 			entity->addTag(tags[i]);
 			entity->addTag(tags[i]);
-		}
-		
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		}		
 	}
 	}
 	
 	
 	PropSheet::handleEvent(event);	
 	PropSheet::handleEvent(event);	
@@ -1972,7 +2208,7 @@ void ScreenLabelSheet::refreshFonts() {
 ScreenLabelSheet::~ScreenLabelSheet() {
 ScreenLabelSheet::~ScreenLabelSheet() {
 
 
 }
 }
-		
+
 void ScreenLabelSheet::handleEvent(Event *event) {
 void ScreenLabelSheet::handleEvent(Event *event) {
 	if(!label)
 	if(!label)
 		return;
 		return;
@@ -1988,7 +2224,7 @@ void ScreenLabelSheet::handleEvent(Event *event) {
 		label->getLabel()->setFont(font);
 		label->getLabel()->setFont(font);
 		label->setText(caption->get());		
 		label->setText(caption->get());		
 		lastFont = fontName;
 		lastFont = fontName;
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 	}
 	}
 
 
 
 
@@ -2001,7 +2237,7 @@ void ScreenLabelSheet::handleEvent(Event *event) {
 					
 					
 		label->getLabel()->setSize(newSize);
 		label->getLabel()->setSize(newSize);
 		label->setText(caption->get());		
 		label->setText(caption->get());		
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 	}
 	}
 
 
 
 
@@ -2012,33 +2248,34 @@ void ScreenLabelSheet::handleEvent(Event *event) {
 			label->getLabel()->setAntialiasMode(Label::ANTIALIAS_NONE);		
 			label->getLabel()->setAntialiasMode(Label::ANTIALIAS_NONE);		
 		}		
 		}		
 		label->setText(caption->get());
 		label->setText(caption->get());
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
 	}
 	}
-
 	
 	
 	PropSheet::handleEvent(event);
 	PropSheet::handleEvent(event);
 }
 }
 
 
 void ScreenLabelSheet::Update() {
 void ScreenLabelSheet::Update() {
 	if(label) {
 	if(label) {
-		enabled = true;	
+		enabled = true;		
+		if(label != lastLabel) {
+			lastLabel = label;
+	
 		caption->set(label->getText());		
 		caption->set(label->getText());		
 		enableAA->set(label->getLabel()->getAntialiasMode() == Label::ANTIALIAS_FULL);
 		enableAA->set(label->getLabel()->getAntialiasMode() == Label::ANTIALIAS_FULL);
-		if(label->getLabel()->getSize() != lastSize) {
-			size->set(label->getLabel()->getSize());
-			lastSize = label->getLabel()->getSize();
-		}
+		size->set(label->getLabel()->getSize());
 		
 		
 		for(int i=0; i < font->comboEntry->getNumItems(); i++) {
 		for(int i=0; i < font->comboEntry->getNumItems(); i++) {
 			String comboFont = font->comboEntry->getItemAtIndex(i)->label;
 			String comboFont = font->comboEntry->getItemAtIndex(i)->label;
 			
 			
 			if(comboFont == label->getLabel()->getFont()->getFontName()) {
 			if(comboFont == label->getLabel()->getFont()->getFontName()) {
 				if(comboFont != lastFont) {
 				if(comboFont != lastFont) {
-					font->comboEntry->setSelectedIndex(i);
+					font->set(i);
 					lastFont = comboFont;
 					lastFont = comboFont;
 				}
 				}
 			}
 			}
 		}
 		}
+
+		}
 	} else {
 	} else {
 		enabled = false;
 		enabled = false;
 	}
 	}

+ 116 - 17
IDE/Contents/Source/PolycodeScreenEditor.cpp

@@ -738,45 +738,56 @@ PolycodeScreenEditorMain::PolycodeScreenEditorMain(PolycodeEditor *editor) {
 	
 	
 	particleSheet = new ScreenParticleSheet();
 	particleSheet = new ScreenParticleSheet();
 	particleSheet->addEventListener(this, Event::CHANGE_EVENT);	
 	particleSheet->addEventListener(this, Event::CHANGE_EVENT);	
+	particleSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);		
 	entityProps->addPropSheet(particleSheet);
 	entityProps->addPropSheet(particleSheet);
 
 
 	spriteSheet = new ScreenSpriteSheet();
 	spriteSheet = new ScreenSpriteSheet();
-	spriteSheet->addEventListener(this, Event::CHANGE_EVENT);	
+	spriteSheet->addEventListener(this, Event::CHANGE_EVENT);
+	spriteSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);	
 	entityProps->addPropSheet(spriteSheet);
 	entityProps->addPropSheet(spriteSheet);
 	
 	
 	instanceSheet = new ScreenEntityInstanceSheet();
 	instanceSheet = new ScreenEntityInstanceSheet();
 	instanceSheet->addEventListener(this, Event::CHANGE_EVENT);	
 	instanceSheet->addEventListener(this, Event::CHANGE_EVENT);	
+	instanceSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
 	entityProps->addPropSheet(instanceSheet);
 	entityProps->addPropSheet(instanceSheet);
 
 
 	labelSheet = new ScreenLabelSheet();
 	labelSheet = new ScreenLabelSheet();
 	labelSheet->addEventListener(this, Event::CHANGE_EVENT);	
 	labelSheet->addEventListener(this, Event::CHANGE_EVENT);	
+	labelSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);	
 	entityProps->addPropSheet(labelSheet);
 	entityProps->addPropSheet(labelSheet);
 
 
 	soundSheet = new SoundSheet();
 	soundSheet = new SoundSheet();
 	entityProps->addPropSheet(soundSheet);
 	entityProps->addPropSheet(soundSheet);
 	soundSheet->addEventListener(this, Event::CHANGE_EVENT);
 	soundSheet->addEventListener(this, Event::CHANGE_EVENT);
-
+	soundSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+	
 	imageSheet = new ScreenImageSheet();
 	imageSheet = new ScreenImageSheet();
 	entityProps->addPropSheet(imageSheet);
 	entityProps->addPropSheet(imageSheet);
 	imageSheet->addEventListener(this, Event::CHANGE_EVENT);	
 	imageSheet->addEventListener(this, Event::CHANGE_EVENT);	
-
+	imageSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+	
 	shapeSheet = new ShapeSheet();
 	shapeSheet = new ShapeSheet();
 	shapeSheet->addEventListener(this, Event::CHANGE_EVENT);
 	shapeSheet->addEventListener(this, Event::CHANGE_EVENT);
+	shapeSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
 	entityProps->addPropSheet(shapeSheet);
 	entityProps->addPropSheet(shapeSheet);
 
 
 	transform2dSheet = new Transform2DSheet();
 	transform2dSheet = new Transform2DSheet();
 	transform2dSheet->addEventListener(this, Event::CHANGE_EVENT);
 	transform2dSheet->addEventListener(this, Event::CHANGE_EVENT);
+	transform2dSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);	
 	entityProps->addPropSheet(transform2dSheet);
 	entityProps->addPropSheet(transform2dSheet);
 	
 	
 	screenEntitySheet = new ScreenEntitySheet();
 	screenEntitySheet = new ScreenEntitySheet();
 	entityProps->addPropSheet(screenEntitySheet);
 	entityProps->addPropSheet(screenEntitySheet);
 	screenEntitySheet->addEventListener(this, Event::CHANGE_EVENT);	
 	screenEntitySheet->addEventListener(this, Event::CHANGE_EVENT);	
-			
+	screenEntitySheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+				
 	entitySheet = new EntitySheet();
 	entitySheet = new EntitySheet();
 	entityProps->addPropSheet(entitySheet);
 	entityProps->addPropSheet(entitySheet);
+	entitySheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
 	
 	
 	entityPropSheet = new EntityPropSheet();
 	entityPropSheet = new EntityPropSheet();
 	entityPropSheet->addEventListener(this, Event::CHANGE_EVENT);	
 	entityPropSheet->addEventListener(this, Event::CHANGE_EVENT);	
+	entityPropSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
 	entityProps->addPropSheet(entityPropSheet);	
 	entityProps->addPropSheet(entityPropSheet);	
 	
 	
 	entityProps->updateProps();		
 	entityProps->updateProps();		
@@ -835,15 +846,18 @@ void PolycodeScreenEditorMain::doAction(String actionName, PolycodeEditorActionD
 		for(int i=0; i < selectedEntities.size(); i++) {
 		for(int i=0; i < selectedEntities.size(); i++) {
 			selectedEntities[i]->position = screenData->entries[i].vec3;
 			selectedEntities[i]->position = screenData->entries[i].vec3;
 		}
 		}
+		syncTransformToSelected();
 	} else if(actionName == "scale") {
 	} else if(actionName == "scale") {
 		for(int i=0; i < selectedEntities.size(); i++) {
 		for(int i=0; i < selectedEntities.size(); i++) {
 			selectedEntities[i]->scale = screenData->entries[i].vec3;
 			selectedEntities[i]->scale = screenData->entries[i].vec3;
 		}	
 		}	
+		syncTransformToSelected();		
 	} else if(actionName == "rotate") {
 	} else if(actionName == "rotate") {
 		for(int i=0; i < selectedEntities.size(); i++) {
 		for(int i=0; i < selectedEntities.size(); i++) {
 			selectedEntities[i]->position = screenData->entries[i].vec3;		
 			selectedEntities[i]->position = screenData->entries[i].vec3;		
 			selectedEntities[i]->setRotation(screenData->entries[i].number);
 			selectedEntities[i]->setRotation(screenData->entries[i].number);
-		}		
+		}
+		syncTransformToSelected();			
 	} else if(actionName == "select") {
 	} else if(actionName == "select") {
 			selectEntity(NULL, false);	
 			selectEntity(NULL, false);	
 			if(data) {
 			if(data) {
@@ -854,6 +868,7 @@ void PolycodeScreenEditorMain::doAction(String actionName, PolycodeEditorActionD
 				}					
 				}					
 				multiSelect = oldMultiSelect;				
 				multiSelect = oldMultiSelect;				
 			}
 			}
+		syncTransformToSelected();			
 	} else if(actionName == "set_current_layer") {
 	} else if(actionName == "set_current_layer") {
 		if(screenData->entry.entity) {
 		if(screenData->entry.entity) {
 			setCurrentLayer(screenData->entry.entity, false);
 			setCurrentLayer(screenData->entry.entity, false);
@@ -886,10 +901,24 @@ void PolycodeScreenEditorMain::doAction(String actionName, PolycodeEditorActionD
 				selectEntity(screenData->entries[i].entity, false);
 				selectEntity(screenData->entries[i].entity, false);
 			}
 			}
 			multiSelect = oldMultiSelect;			
 			multiSelect = oldMultiSelect;			
-			if(treeView) {
-				treeView->Refresh();		
-			}			
 		}
 		}
+		if(treeView) {
+			treeView->Refresh();		
+		}					
+	} else if(actionName == "create_entity") {	
+		if(screenData->reverse) {
+			deleteEntity(screenData->entry.entity);
+		} else {
+			screenData->entry.parentEntity->addChild(screenData->entry.entity);			
+		}
+		
+		if(treeView) {
+			treeView->Refresh();		
+		}			
+					
+	} else if(actionName == "prop_change") {
+		PolycodeEditorPropActionData *propData = (PolycodeEditorPropActionData*) data;
+		propData->sheet->applyPropActionData(propData);
 	}
 	}
 }
 }
 
 
@@ -1388,7 +1417,14 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 				
 				
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}				
+				}
+				
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingLabel);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingLabel);
+				editor->didAction("create_entity", beforeData, data);
 		}
 		}
 		break;		
 		break;		
 		case MODE_IMAGE:
 		case MODE_IMAGE:
@@ -1407,7 +1443,15 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 					
 					
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}											
+				}	
+				
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingImage);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingImage);
+				editor->didAction("create_entity", beforeData, data);
+											
 		}
 		}
 		break;		
 		break;		
 		case MODE_SHAPE:
 		case MODE_SHAPE:
@@ -1426,7 +1470,15 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 
 
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}											
+				}
+				
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingShape);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingShape);				
+				editor->didAction("create_entity", beforeData, data);
+															
 		}
 		}
 		break;
 		break;
 		case MODE_PARTICLES:
 		case MODE_PARTICLES:
@@ -1481,7 +1533,15 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 				
 				
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}											
+				}
+				
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingEmitter);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingEmitter);				
+				editor->didAction("create_entity", beforeData, data);
+																										
 		}
 		}
 		break;			
 		break;			
 		case MODE_SPRITE:
 		case MODE_SPRITE:
@@ -1505,7 +1565,15 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 
 
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}											
+				}
+				
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingSprite);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingSprite);				
+				editor->didAction("create_entity", beforeData, data);
+																										
 		}
 		}
 		break;		
 		break;		
 		case MODE_LINK:
 		case MODE_LINK:
@@ -1524,7 +1592,15 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 
 
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}											
+				}
+
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingInstance);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingInstance);				
+				editor->didAction("create_entity", beforeData, data);
+															
 		}
 		}
 		break;		
 		break;		
 		case MODE_ENTITY:
 		case MODE_ENTITY:
@@ -1546,7 +1622,16 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 
 
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}								
+				}
+
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingEntity);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingEntity);				
+				editor->didAction("create_entity", beforeData, data);
+				
+								
 		}
 		}
 		break;
 		break;
 		case MODE_SOUND:
 		case MODE_SOUND:
@@ -1571,7 +1656,16 @@ void PolycodeScreenEditorMain::handleMouseDown(Vector2 position) {
 			
 			
 				if(treeView) {
 				if(treeView) {
 					treeView->Refresh();		
 					treeView->Refresh();		
-				}								
+				}
+
+				PolycodeScreenEditorActionData *beforeData = new PolycodeScreenEditorActionData();
+				PolycodeScreenEditorActionData *data = new PolycodeScreenEditorActionData();
+				data->reverse = false;
+				data->entry = PolycodeScreenEditorActionDataEntry(placingSound);
+				beforeData->entry = PolycodeScreenEditorActionDataEntry(placingSound);				
+				editor->didAction("create_entity", beforeData, data);
+				
+																				
 		}
 		}
 		break;		
 		break;		
 	}
 	}
@@ -1938,6 +2032,11 @@ void PolycodeScreenEditorMain::handleEvent(Event *event) {
 			entityProps->scrollContainer->setScrollValue(0.0, 1.0);
 			entityProps->scrollContainer->setScrollValue(0.0, 1.0);
 	}
 	}
 	
 	
+	if(event->getEventCode() == PropEvent::EVENT_PROP_CHANGE) {
+		PropEvent *propEvent  = (PropEvent*) event;
+		editor->didAction("prop_change", propEvent->beforeData, propEvent->afterData);
+	}
+	
 	if((event->getDispatcher() == transform2dSheet || event->getDispatcher() == labelSheet || event->getDispatcher() == imageSheet || event->getDispatcher() == shapeSheet || event->getDispatcher() == screenEntitySheet) && event->getEventType() == "") {
 	if((event->getDispatcher() == transform2dSheet || event->getDispatcher() == labelSheet || event->getDispatcher() == imageSheet || event->getDispatcher() == shapeSheet || event->getDispatcher() == screenEntitySheet) && event->getEventType() == "") {
 		syncTransformToSelected();
 		syncTransformToSelected();
 		treeView->Refresh();		
 		treeView->Refresh();		
@@ -2314,7 +2413,7 @@ void PolycodeScreenEditorMain::setMode(int newMode) {
 	parentingLine->visible = false;
 	parentingLine->visible = false;
 	parenting = false;
 	parenting = false;
 	
 	
-	selectEntity(NULL);
+	selectEntity(NULL, false);
 	
 	
 	switch(mode) {
 	switch(mode) {
 		case MODE_SHAPE:
 		case MODE_SHAPE:

+ 2 - 0
Modules/Contents/UI/Include/PolyUIColorBox.h

@@ -47,6 +47,8 @@ namespace Polycode {
 			void handleEvent(Event *event);
 			void handleEvent(Event *event);
 			void setSaturationAndValue(Number S, Number V);
 			void setSaturationAndValue(Number S, Number V);
 			
 			
+			void updateColorFromMainSelector();
+			void updateColorFromHueSelector();
 			void rebuildFromTextInputs();
 			void rebuildFromTextInputs();
 			
 			
 			void cancelColorListeners();
 			void cancelColorListeners();

+ 2 - 0
Modules/Contents/UI/Include/PolyUIHSlider.h

@@ -47,6 +47,8 @@ namespace Polycode {
 		
 		
 			Number gripPos;
 			Number gripPos;
 			
 			
+			bool dragging;
+			
 			Number labelXPos;
 			Number labelXPos;
 			Number labelYPos;
 			Number labelYPos;
 			UIBox *bgRect;
 			UIBox *bgRect;

+ 4 - 3
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -1,4 +1,4 @@
-/*
+ /*
  Copyright (C) 2012 by Ivan Safrin
  Copyright (C) 2012 by Ivan Safrin
  
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -117,8 +117,9 @@ namespace Polycode {
 			 * into the text field
 			 * into the text field
 			 *
 			 *
 			 * @param text The new text contents.
 			 * @param text The new text contents.
+			 * @param sendChangeEvent If true (default), will send out an Event::CHANGE_EVENT 
 			 */
 			 */
-			void setText(String text);
+			void setText(String text, bool sendChangeEvent = true);
 
 
 			/**
 			/**
 			 * Returns the text contents of this element.
 			 * Returns the text contents of this element.
@@ -138,7 +139,7 @@ namespace Polycode {
 			 */
 			 */
 			int insertLine(bool after = true);
 			int insertLine(bool after = true);
 
 
-			void changedText();
+			void changedText(bool sendChangeEvent = true);
 			void applySyntaxFormatting();
 			void applySyntaxFormatting();
 			
 			
 			void onKeyDown(PolyKEY key, wchar_t charCode);
 			void onKeyDown(PolyKEY key, wchar_t charCode);

+ 9 - 12
Modules/Contents/UI/Source/PolyUIColorBox.cpp

@@ -301,15 +301,13 @@ void UIColorPicker::handleEvent(Event *event) {
 				InputEvent *inputEvent = (InputEvent*) event;
 				InputEvent *inputEvent = (InputEvent*) event;
 				hueSelector->setPositionY(inputEvent->getMousePosition().y+hueFrame->position.y);
 				hueSelector->setPositionY(inputEvent->getMousePosition().y+hueFrame->position.y);
 				hueSelector->startDrag(inputEvent->mousePosition.x-hueSelector->getPosition().x,inputEvent->mousePosition.y-hueSelector->getPosition().y+hueFrame->position.y);		
 				hueSelector->startDrag(inputEvent->mousePosition.x-hueSelector->getPosition().x,inputEvent->mousePosition.y-hueSelector->getPosition().y+hueFrame->position.y);		
-				Number newHue = 360.0 - (((inputEvent->getMousePosition().y-hueFrame->getPosition().y)/((hueFrame->getPosition().y+hueFrame->getHeight())-hueFrame->getPosition().y)) * 360.0f);
-				setHue(newHue);
-						
 			}
 			}
 			break;
 			break;
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 			{
 			{
 				hueSelector->stopDrag();
 				hueSelector->stopDrag();
+				updateColorFromHueSelector();	
 			}
 			}
 			break;	
 			break;	
 		}
 		}
@@ -324,17 +322,13 @@ void UIColorPicker::handleEvent(Event *event) {
 				InputEvent *inputEvent = (InputEvent*) event;
 				InputEvent *inputEvent = (InputEvent*) event;
 				mainSelector->setPosition(inputEvent->getMousePosition().x+mainColorRect->position.x, inputEvent->getMousePosition().y+mainColorRect->position.y);
 				mainSelector->setPosition(inputEvent->getMousePosition().x+mainColorRect->position.x, inputEvent->getMousePosition().y+mainColorRect->position.y);
 				mainSelector->startDrag(inputEvent->mousePosition.x-mainSelector->getPosition().x+mainColorRect->position.x,inputEvent->mousePosition.y-mainSelector->getPosition().y+mainColorRect->position.y);
 				mainSelector->startDrag(inputEvent->mousePosition.x-mainSelector->getPosition().x+mainColorRect->position.x,inputEvent->mousePosition.y-mainSelector->getPosition().y+mainColorRect->position.y);
-				
-				Number newV = 1.0 - inputEvent->getMousePosition().y / mainColorRect->getHeight();
-				Number newS = inputEvent->getMousePosition().x / mainColorRect->getWidth();
-
-				setSaturationAndValue(newS, newV);
 			}
 			}
 			break;
 			break;
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 			{
 			{
 				mainSelector->stopDrag();			
 				mainSelector->stopDrag();			
+				updateColorFromMainSelector();
 			}
 			}
 			break;	
 			break;	
 		}
 		}
@@ -370,8 +364,7 @@ UIColorPicker::~UIColorPicker() {
 		delete junkLabels[c];
 		delete junkLabels[c];
 }
 }
 
 
-void UIColorPicker::Update() {
-
+void UIColorPicker::updateColorFromMainSelector() {
 	if(mainSelector->getPosition2D() != lastMainSelectorPosition) {
 	if(mainSelector->getPosition2D() != lastMainSelectorPosition) {
 		lastMainSelectorPosition = mainSelector->getPosition2D();
 		lastMainSelectorPosition = mainSelector->getPosition2D();
 		
 		
@@ -384,7 +377,9 @@ void UIColorPicker::Update() {
 					
 					
 		setSaturationAndValue(newS, newV);	
 		setSaturationAndValue(newS, newV);	
 	}
 	}
-	
+}
+
+void UIColorPicker::updateColorFromHueSelector() {
 	if(hueSelector->getPosition().y != lastHueSelectorPosition) {
 	if(hueSelector->getPosition().y != lastHueSelectorPosition) {
 		lastHueSelectorPosition = hueSelector->getPosition().y;
 		lastHueSelectorPosition = hueSelector->getPosition().y;
 		
 		
@@ -399,8 +394,10 @@ void UIColorPicker::Update() {
 					
 					
 		Number newHue = 360.0 - (((newPosY-hueFrame->getPosition().y)/((hueFrame->getPosition().y+hueFrame->getHeight())-hueFrame->getPosition().y)) * 360.0f);
 		Number newHue = 360.0 - (((newPosY-hueFrame->getPosition().y)/((hueFrame->getPosition().y+hueFrame->getHeight())-hueFrame->getPosition().y)) * 360.0f);
 		setHue(newHue);
 		setHue(newHue);
-	}	
+	}
+}
 
 
+void UIColorPicker::Update() {	
 	UIWindow::Update();
 	UIWindow::Update();
 }
 }
 
 

+ 11 - 1
Modules/Contents/UI/Source/PolyUIHSlider.cpp

@@ -75,6 +75,7 @@ UIHSlider::UIHSlider(Number start, Number end, Number width) : UIElement() {
 	gripRect->setDragLimits(Rectangle(0,floor(bgHeight/2.0),width,0));
 	gripRect->setDragLimits(Rectangle(0,floor(bgHeight/2.0),width,0));
 	
 	
 	gripPos = 0;
 	gripPos = 0;
+	dragging = false;
 }
 }
 
 
 UIHSlider::~UIHSlider() {
 UIHSlider::~UIHSlider() {
@@ -107,10 +108,15 @@ void UIHSlider::handleEvent(Event *event) {
 				gripPos = gripRect->getPosition().x;				
 				gripPos = gripRect->getPosition().x;				
 				sliderValue = startValue+((endValue - startValue) * (gripPos/sliderWidth));				
 				sliderValue = startValue+((endValue - startValue) * (gripPos/sliderWidth));				
 				gripRect->startDrag(inputEvent->mousePosition.x-gripRect->getPosition().x,inputEvent->mousePosition.y-gripRect->getPosition().y);
 				gripRect->startDrag(inputEvent->mousePosition.x-gripRect->getPosition().x,inputEvent->mousePosition.y-gripRect->getPosition().y);
+				dragging = true;
 			break;
 			break;
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:
 				gripRect->stopDrag();
 				gripRect->stopDrag();
+				if(dragging) {
+					dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);
+				}
+				dragging = false;				
 			break;
 			break;
 		}	
 		}	
 	}
 	}
@@ -120,10 +126,15 @@ void UIHSlider::handleEvent(Event *event) {
 		switch(event->getEventCode()) {
 		switch(event->getEventCode()) {
 			case InputEvent::EVENT_MOUSEDOWN:
 			case InputEvent::EVENT_MOUSEDOWN:
 				gripRect->startDrag(inputEvent->mousePosition.x-gripRect->getPosition().x,inputEvent->mousePosition.y-gripRect->getPosition().y);
 				gripRect->startDrag(inputEvent->mousePosition.x-gripRect->getPosition().x,inputEvent->mousePosition.y-gripRect->getPosition().y);
+				dragging = true;				
 			break;
 			break;
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:		
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:		
 				gripRect->stopDrag();
 				gripRect->stopDrag();
+				if(dragging) {
+					dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);
+				}
+				dragging = false;				
 			break;
 			break;
 		}	
 		}	
 	}
 	}
@@ -134,6 +145,5 @@ void UIHSlider::Update() {
 	if(gripRect->getPosition().x != gripPos) {
 	if(gripRect->getPosition().x != gripPos) {
 		gripPos = gripRect->getPosition().x;
 		gripPos = gripRect->getPosition().x;
 		sliderValue = startValue+((endValue - startValue) * (gripPos/sliderWidth));
 		sliderValue = startValue+((endValue - startValue) * (gripPos/sliderWidth));
-		dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);
 	}
 	}
 }
 }

+ 6 - 4
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -467,11 +467,13 @@ void UITextInput::applySyntaxFormatting() {
 	readjustBuffer();	
 	readjustBuffer();	
 }
 }
 
 
-void UITextInput::changedText() {
+void UITextInput::changedText(bool sendChangeEvent) {
 	if(settingText)
 	if(settingText)
 		return;
 		return;
 	applySyntaxFormatting();
 	applySyntaxFormatting();
-	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
+	if(sendChangeEvent) {
+		dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);	
+	}
 }
 }
 
 
 void UITextInput::setSyntaxHighlighter(UITextInputSyntaxHighlighter *syntaxHighliter) {
 void UITextInput::setSyntaxHighlighter(UITextInputSyntaxHighlighter *syntaxHighliter) {
@@ -601,7 +603,7 @@ void UITextInput::restructLines() {
 	
 	
 }
 }
 
 
-void UITextInput::setText(String text) {
+void UITextInput::setText(String text, bool sendChangeEvent) {
 	if(!multiLine) {
 	if(!multiLine) {
 		lines[lineOffset] = text;
 		lines[lineOffset] = text;
 		caretPosition = text.length();
 		caretPosition = text.length();
@@ -613,7 +615,7 @@ void UITextInput::setText(String text) {
 		clearSelection();
 		clearSelection();
 	}
 	}
 //	needFullRedraw = true;		
 //	needFullRedraw = true;		
-	changedText();
+	changedText(sendChangeEvent);
 }
 }
 
 
 void UITextInput::onLoseFocus() {
 void UITextInput::onLoseFocus() {