Przeglądaj źródła

added PCustom, float right click adjustement, allow customization of inspector

ncannasse 10 lat temu
rodzic
commit
19f8027e8e

+ 48 - 2
hxd/net/PropInspector.hx

@@ -70,6 +70,10 @@ class PropInspector extends cdb.jq.Client {
 		send(SetCSS(value));
 	}
 
+	public function setName( value : String ) {
+		send(SetName(value));
+	}
+
 	override function sendBytes( msg : haxe.io.Bytes ) {
 		if( !flushWait ) {
 			flushWait = true;
@@ -169,7 +173,9 @@ class PropInspector extends cdb.jq.Client {
 			if( path.charCodeAt(0) != '/'.code && path.charCodeAt(1) != ':'.code )
 				path = hxd.File.applicationPath() + path;
 			hxd.File.load(path, function(data) set( hxd.res.Any.fromBytes(path, data).toTexture() ));
-		case PGroup(_), PPopup(_):
+		case PCustom(_, _, set) if( set != null ):
+			set(v);
+		case PGroup(_), PPopup(_), PCustom(_):
 			throw "Cannot set property " + p.getName();
 		}
 	}
@@ -229,7 +235,7 @@ class PropInspector extends cdb.jq.Client {
 
 	function getPropName( p : Property ) {
 		return switch( propFollow(p) ) {
-		case PGroup(name, _), PBool(name, _), PInt(name, _), PFloat(name, _), PFloats(name, _), PString(name, _), PColor(name, _), PTexture(name, _), PEnum(name,_,_,_): name;
+		case PGroup(name, _), PBool(name, _), PInt(name, _), PFloat(name, _), PFloats(name, _), PString(name, _), PColor(name, _), PTexture(name, _), PEnum(name,_,_,_), PCustom(name,_): name;
 		case PPopup(_): null;
 		}
 	}
@@ -350,6 +356,25 @@ class PropInspector extends cdb.jq.Client {
 					}
 				}
 			));
+			j.mousedown(function(e) {
+				if( e.which == 3 ) {
+					var old = get();
+					var cur : Float = old;
+					j.addClass("active");
+					j.special("startDrag", [], function(v: { done:Bool, dx:Float, dy:Float } ) {
+						var delta = ( Math.max(Math.abs(old == 0 ? 1 : old),1e-3) / 200 ) * v.dx;
+						cur += delta;
+						cur = hxd.Math.fmt(cur);
+						var icur = Math.round(cur);
+						set(icur);
+						jprop.text("" + icur);
+						if( v.done ) {
+							j.removeClass("active");
+							addHistory(path, old, icur);
+						}
+					});
+				}
+			});
 		case PFloat(_, get, set):
 			jprop.text("" + get());
 			j.dblclick(function(_) editValue(jprop,function() return "" + get(),
@@ -361,6 +386,24 @@ class PropInspector extends cdb.jq.Client {
 					}
 				}
 			));
+			j.mousedown(function(e) {
+				if( e.which == 3 ) {
+					var old = get();
+					var cur = old;
+					j.addClass("active");
+					j.special("startDrag", [], function(v: { done:Bool, dx:Float, dy:Float } ) {
+						var delta = ( Math.max(Math.abs(old == 0 ? 1 : old),1e-3) / 100 ) * v.dx;
+						cur += delta;
+						cur = hxd.Math.fmt(cur);
+						set(cur);
+						jprop.text("" + cur);
+						if( v.done ) {
+							j.removeClass("active");
+							addHistory(path, old, cur);
+						}
+					});
+				}
+			});
 		case PFloats(_, get, set):
 			var values = get();
 			jprop.html("<table><tr></tr></table>");
@@ -484,6 +527,9 @@ class PropInspector extends cdb.jq.Client {
 				if( e.which == 3 )
 					j.special("popupMenu", menu, function(i) click(j,i));
 			});
+		case PCustom(_, content, _):
+			var c = content();
+			if( c != null ) c.appendTo(jprop);
 		}
 		return j;
 	}

+ 1 - 0
hxd/net/Property.hx

@@ -11,4 +11,5 @@ enum Property {
 	PTexture( name : String, get : Void -> h3d.mat.Texture, set : h3d.mat.Texture -> Void );
 	PFloats( name : String, get : Void -> Array<Float>, set : Array<Float> -> Void );
 	PPopup( p : Property, menu : Array<String>, click : cdb.jq.JQuery -> Int -> Void );
+	PCustom( name : String, content : Void -> cdb.jq.JQuery, ?set : Dynamic -> Void );
 }

+ 114 - 44
hxd/net/SceneInspector.hx

@@ -34,6 +34,47 @@ private class SceneObject {
 	}
 }
 
+class Element {
+	public var name : String;
+	public var icon : String;
+	public var props : Void -> Array<Property>;
+	public function new() {
+	}
+}
+
+class Tool {
+	public var name(default,set) : String;
+	public var icon(default,set) : String;
+	public var click : Void -> Void;
+	public var j : JQuery;
+	public var jicon : JQuery;
+	public var active(get, set) : Bool;
+	public function new() {
+	}
+	public function reset( i : SceneInspector ) {
+		j = i.J("<li>");
+		jicon = i.J("<i>").appendTo(j);
+		j.click(function(_) click());
+		this.name = name;
+		this.icon = icon;
+	}
+	function get_active() {
+		return j.hasClass("active");
+	}
+	function set_active(v) {
+		j.toggleClass("active", v);
+		return v;
+	}
+	function set_name(v) {
+		if( jicon != null ) jicon.attr("alt", v);
+		return name = v;
+	}
+	function set_icon(v) {
+		if( jicon != null ) jicon.attr("class", "fa fa-"+v);
+		return icon = v;
+	}
+}
+
 class SceneInspector {
 
 	static var CSS = hxd.res.Embed.getFileContent("hxd/net/inspect.css");
@@ -48,13 +89,15 @@ class SceneInspector {
 	var scenePosition = 0;
 	var oldLoop : Void -> Void;
 	var state : Map<String,{ original : Dynamic, current : Dynamic }>;
-	var rootElements : Map<String, Void -> Array<Property>>;
+	var rootElements : Array<Element>;
+	var tools : Array<Tool> ;
+	var activeTool : JQuery;
 
-	public function new( ?host, ?port ) {
-		rootElements = new Map();
+	public function new( scene, ?host, ?port ) {
 		event = new DrawEvent(this);
 		savedFile = "sceneProps.js";
 		state = new Map();
+		tools = [];
 		oldLog = haxe.Log.trace;
 		haxe.Log.trace = onTrace;
 		inspect = new PropInspector(host, port);
@@ -62,12 +105,47 @@ class SceneInspector {
 		inspect.onRefresh = refresh;
 		inspect.onChange = onChange;
 		inspect.handleKey = onKey;
+		this.scene = scene;
+		rootElements = new Array();
+		addElement("Renderer", "object-group", getRendererProps);
+		addTool("Load...", "download", load);
+		addTool("Save...", "save", save);
+		addTool("Undo", "undo", inspect.undo);
+		addTool("Repeat", "repeat", inspect.redo);
+		var pause : Tool = null;
+		pause = addTool("Pause", "pause", function() {
+			if( oldLoop != null ) {
+				hxd.System.setLoop(oldLoop);
+				oldLoop = null;
+			} else {
+				oldLoop = hxd.System.getCurrentLoop();
+				hxd.System.setLoop(pauseLoop);
+			}
+			pause.active = oldLoop != null;
+		});
 	}
 
-	inline function J( ?elt : cdb.jq.Dom, ?query : String ) {
+	public inline function J( ?elt : cdb.jq.Dom, ?query : String ) {
 		return inspect.J(elt,query);
 	}
 
+	public function getActiveTool() {
+		return activeTool;
+	}
+
+	public function createPanel( title ) {
+		return inspect.createPanel(title);
+	}
+
+	public function addTool( name : String, icon : String, click : Void -> Void ) {
+		var t = new Tool();
+		t.name = name;
+		t.icon = icon;
+		t.click = click;
+		tools.push(t);
+		return t;
+	}
+
 	function onKey( e : cdb.jq.Event ) {
 		switch( e.keyCode ) {
 		case 'S'.code if( e.ctrlKey ):
@@ -110,11 +188,6 @@ class SceneInspector {
 		var j = J(inspect.getRoot());
 		j.html('
 			<ul id="toolbar" class="toolbar">
-				<li id="state-load"><i class="fa fa-download" alt="Load..."></i></li>
-				<li id="state-save"><i class="fa fa-save" alt="Save..."></i></li>
-				<li id="history-undo"><i class="fa fa-undo" alt="Undo"></i></li>
-				<li id="history-redo"><i class="fa fa-repeat" alt="Repeat"></i></li>
-				<li id="scene-pause"><i class="fa fa-pause" alt="Pause Game"></i></li>
 			</ul>
 			<div id="scene" class="panel" caption="Scene">
 				<ul id="scontent" class="elt">
@@ -125,28 +198,15 @@ class SceneInspector {
 			<div id="log" class="panel" caption="Log">
 			</div>
 		');
+		var tbar = j.find("#toolbar");
+		for( t in tools ) {
+			t.reset(this);
+			t.j.appendTo(tbar);
+		}
+		inspect.setName("Scene");
 		inspect.setCSS(CSS);
-
 		var scene = J("#scene");
 		scene.dock(j.get(), Left, 0.2);
-
-		var pause = j.find("#scene-pause");
-		pause.click(function(_) {
-			if( oldLoop != null ) {
-				hxd.System.setLoop(oldLoop);
-				oldLoop = null;
-			} else {
-				oldLoop = hxd.System.getCurrentLoop();
-				hxd.System.setLoop(pauseLoop);
-			}
-
-			pause.toggleClass("active", oldLoop != null);
-		});
-		j.find("#history-undo").click(function(_) inspect.undo());
-		j.find("#history-redo").click(function(_) inspect.redo());
-		j.find("#state-save").click(function(_) save());
-		j.find("#state-load").click(function(_) load());
-
 		J("#log").dock(j.get(), Down, 0.3);
 		J("#props").dock(scene.get(), Down, 0.5);
 	}
@@ -156,7 +216,6 @@ class SceneInspector {
 			savedFile = b.fileName;
 			b.load(function(bytes) {
 				var o : Dynamic = haxe.Json.parse(bytes.toString());
-				state = new Map();
 				function browseRec( path : Array<String>, v : Dynamic ) {
 					switch( Type.typeof(v) ) {
 					case TNull, TInt, TFloat, TBool, TClass(_):
@@ -201,28 +260,39 @@ class SceneInspector {
 		hxd.File.saveAs(haxe.io.Bytes.ofString(js), { defaultPath : savedFile, saveFileName : function(name) savedFile = name } );
 	}
 
-	function addElement( name : String, icon : String, getProps : Void -> Array<Property> ) {
-		var lj = J("<li>");
-		lj.html('<i class="fa fa-$icon"></i><div class="content">$name</div>');
-		lj.appendTo(J("#scontent"));
-		lj.find(".content").click(function(_) {
-			J("#scene").find(".selected").removeClass("selected");
-			lj.addClass("selected");
-			fillProps(name, getProps());
-		});
-		rootElements.set(name, getProps);
+	public function addElement( name : String, icon : String, getProps : Void -> Array<Property> ) {
+		var e = new Element();
+		e.name = name.split(".").join(" ");
+		e.icon = icon;
+		e.props = getProps;
+		rootElements.push(e);
+		showElement(e);
 	}
 
 	public function sync() {
 		if( scene == null || !inspect.connected ) return;
 		scenePosition = 0;
 		if( sceneObjects.length == 0 ) {
-			addElement("Renderer", "object-group", getRendererProps);
 			sceneObjects.push(null);
+			for( e in rootElements )
+				showElement(e);
 		}
 		syncRec(scene, null);
 	}
 
+	function showElement( e : Element ) {
+		if( scene == null || !inspect.connected || sceneObjects.length == 0 ) return;
+		var lj = J("<li>");
+		lj.html('<i class="fa fa-${e.icon}"></i><div class="content">${e.name}</div>');
+		lj.appendTo(J("#scontent"));
+		var fullPath = e.name;
+		lj.find(".content").click(function(_) {
+			J("#scene").find(".selected").removeClass("selected");
+			lj.addClass("selected");
+			fillProps(fullPath, e.props());
+		});
+	}
+
 	function resolveProps( path : Array<String> ) {
 		switch( path.shift() ) {
 		case "Scene":
@@ -263,10 +333,10 @@ class SceneInspector {
 			}
 			return getObjectProps(o);
 		case p:
-			var get = rootElements.get(p);
-			if( get == null )
-				throw "Unknown root prop " + p;
-			return get();
+			for( r in rootElements )
+				if( r.name == p )
+					return r.props();
+			throw "Unknown root prop " + p;
 		}
 	}
 

+ 3 - 0
hxd/net/inspect.css

@@ -117,6 +117,9 @@
 	border : 1px solid #888;
 	width : 100%;
 }
+.jqpage table.props tr.active td, .dialog-floating table.props tr.active td {
+	font-weight : bold;
+}
 .jqpage table.props tr.ptexture img, .dialog-floating table.props tr.ptexture img {
 	max-width : 128px;
 	max-height : 128px;

+ 4 - 0
hxd/net/inspect.hss

@@ -124,6 +124,10 @@
 			}
 		}
 
+		tr.active td {
+			font-weight : bold;
+		}
+
 		tr.ptexture img {
 			max-width : 128px;
 			max-height : 128px;

+ 36 - 1
samples/skin/Main.hx

@@ -25,8 +25,43 @@ class Main extends hxd.App {
 		s3d.lightSystem.ambientLight.set(0.4, 0.4, 0.4);
 
 		var shadow = cast(s3d.renderer.getPass("shadow"), h3d.pass.ShadowMap);
-		shadow.lightDirection = dir.direction;
 		shadow.power = 50;
+		dir.enableSpecular = true;
+
+		#if castle
+		// this is an example for connecting to scene inspector
+		// and enable extra properties
+		// this requires to compile with -lib castle and run CDB
+		var i = new hxd.net.SceneInspector(s3d);
+
+		var delta = s3d.camera.pos.sub(s3d.camera.target);
+		delta.z = 0;
+		var angle = Math.atan2(delta.y, delta.x);
+		var dist = delta.length();
+
+		// add node to scene graph
+		i.addElement("Rotation", "repeat", function() {
+			return [
+				PFloat("v", function() return angle, function(v) {
+					angle = v;
+					s3d.camera.pos.x = Math.cos(angle) * dist;
+					s3d.camera.pos.y = Math.sin(angle) * dist;
+				}),
+				PCustom("", function() {
+					var j = i.J("<button>");
+					j.text("Click Me!");
+					j.click(function(_) {
+						var j = i.createPanel("New Panel");
+						j.text("Nothing to see there.");
+					});
+					return j;
+				})
+			];
+		});
+		i.addTool("Exit", "bomb", function() {
+			hxd.System.exit();
+		});
+		#end
 	}
 
 	function loadTexture( name : String ) {