Browse Source

started adding properties undo

Nicolas Cannasse 8 years ago
parent
commit
944e4e0da8
7 changed files with 138 additions and 33 deletions
  1. 36 10
      hide/comp/Properties.hx
  2. 13 0
      hide/comp/Scene.hx
  3. 45 0
      hide/comp/UndoHistory.hx
  4. 3 0
      hide/ui/View.hx
  5. 8 1
      hide/view/FileView.hx
  6. 8 15
      hide/view/Model.hx
  7. 25 7
      hide/view/Particles3D.hx

+ 36 - 10
hide/comp/Properties.hx

@@ -4,17 +4,16 @@ class Properties extends Component {
 
 
 	public var panel : Element;
 	public var panel : Element;
 	public var content : Element;
 	public var content : Element;
+	public var undo : hide.comp.UndoHistory;
 
 
-	public function new(root) {
+	public function new(root,?undo) {
 		super(root);
 		super(root);
+		this.undo = undo == null ? new hide.comp.UndoHistory() : undo;
 		var e = new Element("<div class='hide-properties'><div class='content'></div><div class='panel'></div></div>").appendTo(root);
 		var e = new Element("<div class='hide-properties'><div class='content'></div><div class='panel'></div></div>").appendTo(root);
 		content = e.find(".content");
 		content = e.find(".content");
 		panel = e.find(".panel");
 		panel = e.find(".panel");
 	}
 	}
 
 
-	public dynamic function beforeChange() {
-	}
-
 	public function add( e : Element, context : Dynamic ) {
 	public function add( e : Element, context : Dynamic ) {
 
 
 		e.appendTo(panel);
 		e.appendTo(panel);
@@ -47,19 +46,32 @@ class Properties extends Component {
 			var fname = f.attr("field");
 			var fname = f.attr("field");
 			var current : Dynamic = Reflect.field(context, fname);
 			var current : Dynamic = Reflect.field(context, fname);
 			var enumValue : Enum<Dynamic> = null;
 			var enumValue : Enum<Dynamic> = null;
+			var tempChange = false;
+			var hadTempChange = false;
 
 
 			switch( f.attr("type") ) {
 			switch( f.attr("type") ) {
 			case "checkbox":
 			case "checkbox":
 				f.prop("checked", current);
 				f.prop("checked", current);
 				f.change(function(_) {
 				f.change(function(_) {
-					beforeChange();
-					Reflect.setProperty(context, fname, f.prop("checked"));
+					undo.change(Field(context, fname, current), function() {
+						current = Reflect.field(context, fname);
+						f.prop("checked", current);
+					});
+					current = f.prop("checked");
+					Reflect.setProperty(context, fname, current);
 				});
 				});
 				continue;
 				continue;
 			case "texture":
 			case "texture":
 				var sel = new hide.comp.TextureSelect(f);
 				var sel = new hide.comp.TextureSelect(f);
 				sel.value = current;
 				sel.value = current;
-				sel.onChange = function() Reflect.setProperty(context, fname, sel.value);
+				sel.onChange = function() {
+					undo.change(Field(context, fname, current), function() {
+						current = Reflect.field(context, fname);
+						sel.value = current;
+					});
+					current = sel.value;
+					Reflect.setProperty(context, fname, current);
+				}
 				continue;
 				continue;
 			default:
 			default:
 			}
 			}
@@ -73,7 +85,7 @@ class Properties extends Component {
 			}
 			}
 
 
 			if( f.is("[type=range]") )
 			if( f.is("[type=range]") )
-				f.on("input", function(_) f.change());
+				f.on("input", function(_) { tempChange = true; f.change(); });
 
 
 			f.val(current);
 			f.val(current);
 			f.keyup(function(e) {
 			f.keyup(function(e) {
@@ -85,6 +97,7 @@ class Properties extends Component {
 					f.blur();
 					f.blur();
 					return;
 					return;
 				}
 				}
+				tempChange = true;
 				f.change();
 				f.change();
 			});
 			});
 			f.change(function(e) {
 			f.change(function(e) {
@@ -99,9 +112,22 @@ class Properties extends Component {
 
 
 				if( f.is("select") ) f.blur();
 				if( f.is("select") ) f.blur();
 
 
-				if( current == newVal ) return;
+				if( current == newVal ) {
+					if( tempChange || !hadTempChange )
+						return;
+					hadTempChange = false;
+				}
 
 
-				beforeChange();
+				if( tempChange ) {
+					tempChange = false;
+					hadTempChange = true;
+				}
+				else {
+					undo.change(Field(context, fname, current), function() {
+						current = Reflect.field(context, fname);
+						f.val(current);
+					});
+				}
 				current = newVal;
 				current = newVal;
 				Reflect.setProperty(context, fname, newVal);
 				Reflect.setProperty(context, fname, newVal);
 
 

+ 13 - 0
hide/comp/Scene.hx

@@ -201,6 +201,19 @@ class Scene extends Component implements h3d.IDrawable {
 		return hxd.res.Any.fromBytes(path,data).toModel().toHmd();
 		return hxd.res.Any.fromBytes(path,data).toModel().toHmd();
 	}
 	}
 
 
+	public function resetCamera( ?obj : h3d.scene.Object ) {
+		if( obj == null ) obj = s3d;
+		var b = obj.getBounds();
+		var dx = Math.max(Math.abs(b.xMax),Math.abs(b.xMin));
+		var dy = Math.max(Math.abs(b.yMax),Math.abs(b.yMin));
+		var dz = Math.max(Math.abs(b.zMax),Math.abs(b.zMin));
+		var dist = Math.max(Math.max(dx * 6, dy * 6), dz * 4);
+		var ang = Math.PI / 4;
+		var zang = Math.PI * 0.4;
+		s3d.camera.pos.set(Math.sin(zang) * Math.cos(ang) * dist, Math.sin(zang) * Math.sin(ang) * dist, Math.cos(zang) * dist);
+		s3d.camera.target.set(0, 0, (b.zMax + b.zMin) * 0.5);
+	}
+
 	public function render( e : h3d.Engine ) {
 	public function render( e : h3d.Engine ) {
 		s3d.render(e);
 		s3d.render(e);
 		s2d.render(e);
 		s2d.render(e);

+ 45 - 0
hide/comp/UndoHistory.hx

@@ -0,0 +1,45 @@
+package hide.comp;
+
+enum HistoryElement {
+	Field( obj : Dynamic, field : String, oldValue : Dynamic );
+}
+
+private typedef Elt = { h : HistoryElement, callb : Void -> Void };
+
+class UndoHistory {
+
+	var undoElts : Array<Elt> = [];
+	var redoElts : Array<Elt> = [];
+
+	public function new() {
+	}
+
+	public function change(h, ?callb) {
+		undoElts.push({ h : h, callb : callb });
+		redoElts = [];
+		trace(undoElts.length);
+	}
+
+	public function undo() {
+		var h = undoElts.pop();
+		return handleElement(h, redoElts);
+	}
+
+	public function redo() {
+		var h = redoElts.pop();
+		return handleElement(h, undoElts);
+	}
+
+	public function handleElement( e : Elt, other : Array<Elt> ) {
+		if( e == null ) return false;
+		switch( e.h ) {
+		case Field(obj, field, value):
+			var curValue = Reflect.field(obj, field);
+			other.push({ h : Field(obj, field, curValue), callb : e.callb });
+			Reflect.setField(obj, field, value);
+		}
+		if( e.callb != null ) e.callb();
+		return true;
+	}
+
+}

+ 3 - 0
hide/ui/View.hx

@@ -56,6 +56,9 @@ class View<T> {
 		untyped cont.parent.__view = this;
 		untyped cont.parent.__view = this;
 	}
 	}
 
 
+	public function registerKey( name : String, callb : Void -> Void ) {
+	}
+
 	public function rebuild() {
 	public function rebuild() {
 		if( container == null ) return;
 		if( container == null ) return;
 		syncTitle();
 		syncTitle();

+ 8 - 1
hide/view/FileView.hx

@@ -39,7 +39,8 @@ class FileView extends hide.ui.View<{ path : String }> {
 
 
 	var extension(get,never) : String;
 	var extension(get,never) : String;
 	var modified(default,set) : Bool;
 	var modified(default,set) : Bool;
-	var props(get,null) : FileProps;
+	var props(get, null) : FileProps;
+	var undo = new hide.comp.UndoHistory();
 
 
 	function get_extension() {
 	function get_extension() {
 		var file = state.path.split("/").pop();
 		var file = state.path.split("/").pop();
@@ -50,6 +51,12 @@ class FileView extends hide.ui.View<{ path : String }> {
 		return null;
 		return null;
 	}
 	}
 
 
+	override function setContainer(cont) {
+		super.setContainer(cont);
+		registerKey("undo", function() undo.undo());
+		registerKey("redo", function() undo.redo());
+	}
+
 	override function onBeforeClose() {
 	override function onBeforeClose() {
 		if( modified && !js.Browser.window.confirm(state.path+" has been modified, quit without saving?") )
 		if( modified && !js.Browser.window.confirm(state.path+" has been modified, quit without saving?") )
 			return false;
 			return false;

+ 8 - 15
hide/view/Model.hx

@@ -67,12 +67,13 @@ class Model extends FileView {
 
 
 	function listAnims() {
 	function listAnims() {
 		var dirs : Array<String> = props.get("hmd.animPaths");
 		var dirs : Array<String> = props.get("hmd.animPaths");
-		if( dirs == null ) {
-			var parts = getPath().split("/");
-			parts.pop();
-			dirs = [parts.join("/")];
-		} else
-			dirs = [for( d in dirs ) ide.resourceDir + d];
+		if( dirs == null ) dirs = [];
+		dirs = [for( d in dirs ) ide.resourceDir + d];
+
+		var parts = getPath().split("/");
+		parts.pop();
+		dirs.unshift(parts.join("/"));
+
 		var anims = [];
 		var anims = [];
 		for( dir in dirs )
 		for( dir in dirs )
 			for( f in sys.FileSystem.readDirectory(dir) )
 			for( f in sys.FileSystem.readDirectory(dir) )
@@ -82,15 +83,7 @@ class Model extends FileView {
 	}
 	}
 
 
 	function resetCamera() {
 	function resetCamera() {
-		var b = obj.getBounds();
-		var dx = Math.max(Math.abs(b.xMax),Math.abs(b.xMin));
-		var dy = Math.max(Math.abs(b.yMax),Math.abs(b.yMin));
-		var dz = Math.max(Math.abs(b.zMax),Math.abs(b.zMin));
-		var dist = Math.max(Math.max(dx * 6, dy * 6), dz * 4);
-		var ang = Math.PI / 4;
-		var zang = Math.PI * 0.4;
-		scene.s3d.camera.pos.set(Math.sin(zang) * Math.cos(ang) * dist, Math.sin(zang) * Math.sin(ang) * dist, Math.cos(zang) * dist);
-		scene.s3d.camera.target.set(0, 0, (b.zMax + b.zMin) * 0.5);
+		scene.resetCamera(obj);
 		control.loadFromCamera();
 		control.loadFromCamera();
 	}
 	}
 
 

+ 25 - 7
hide/view/Particles3D.hx

@@ -29,7 +29,7 @@ class Particles3D extends FileView {
 	}
 	}
 
 
 	override function onDisplay( e : Element ) {
 	override function onDisplay( e : Element ) {
-		properties = new hide.comp.Properties(e);
+		properties = new hide.comp.Properties(e,undo);
 		scene = new hide.comp.Scene(properties.content);
 		scene = new hide.comp.Scene(properties.content);
 		scene.onReady = init;
 		scene.onReady = init;
 	}
 	}
@@ -123,20 +123,38 @@ class Particles3D extends FileView {
 	}
 	}
 
 
 	function init() {
 	function init() {
-		new h3d.scene.CameraController(scene.s3d).loadFromCamera();
 		parts = new GpuParticles(this,scene.s3d);
 		parts = new GpuParticles(this,scene.s3d);
 		parts.load(haxe.Json.parse(sys.io.File.getContent(getPath())));
 		parts.load(haxe.Json.parse(sys.io.File.getContent(getPath())));
 
 
+		var bounds = new h3d.scene.Box(0x808080, parts.bounds, parts);
+		bounds.visible = false;
+
 		for( g in parts.getGroups() )
 		for( g in parts.getGroups() )
 			addGroup(g);
 			addGroup(g);
-		var but = new Element('<input type="button" value="New Group"/>');
-		but.appendTo(properties.panel);
-		but.click(function(_) {
+		var extra = new Element('
+			<div class="section open">
+				<h1>Manage</h1>
+				<div class="content">
+					<div class="inputs">
+						<input type="button" class="new" value="New Group"/>
+						<div>Show Bounds <input type="checkbox" class="bounds"/></div>
+					</div>
+				</div>
+			</div>
+		');
+
+		extra.find(".bounds").change(function(e) bounds.visible = e.getThis().prop("checked"));
+		extra.appendTo(properties.panel);
+
+		extra.find(".new").click(function(_) {
 			var g = parts.addGroup();
 			var g = parts.addGroup();
 			g.name = "Group#" + Lambda.count({ iterator : parts.getGroups });
 			g.name = "Group#" + Lambda.count({ iterator : parts.getGroups });
 			addGroup(g);
 			addGroup(g);
-			but.appendTo(properties.panel);
-		},null);
+			extra.appendTo(properties.panel);
+		}, null);
+
+		//scene.resetCamera(); -- tofix when bounds are done
+		new h3d.scene.CameraController(scene.s3d).loadFromCamera();
 	}
 	}
 
 
 	static var _ = FileTree.registerExtension(Particles3D, ["json.particles3D"], { icon : "snowflake-o", createNew: "Particle 3D" });
 	static var _ = FileTree.registerExtension(Particles3D, ["json.particles3D"], { icon : "snowflake-o", createNew: "Particle 3D" });