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

more inspector works (color, texture, groups)

ncannasse пре 10 година
родитељ
комит
ee4e5f85ae
3 измењених фајлова са 297 додато и 79 уклоњено
  1. 218 57
      hxd/net/CdbInspector.hx
  2. 41 12
      hxd/net/inspect.css
  3. 38 10
      hxd/net/inspect.hss

+ 218 - 57
hxd/net/CdbInspector.hx

@@ -1,8 +1,15 @@
 package hxd.net;
+import cdb.jq.JQuery;
 
 enum Property {
 	PBool( name : String, get : Void -> Bool, set : Bool -> Void );
+	PInt( name : String, get : Void -> Int, set : Int -> Void );
+	PFloat( name : String, get : Void -> Float, set : Float -> Void );
+	PString( name : String, get : Void -> String, set : String -> Void );
 	PEnum( name : String, e : Enum<Dynamic>, get : Void -> Dynamic, set : Dynamic -> Void );
+	PColor( name : String, hasAlpha : Bool, get : Void -> h3d.Vector, set : h3d.Vector -> Void );
+	PGroup( name : String, props : Array<Property> );
+	PTexture( name : String, get : Void -> h3d.mat.Texture, set : h3d.mat.Texture -> Void );
 }
 
 private class CdbEvent implements h3d.IDrawable {
@@ -132,7 +139,7 @@ class CdbInspector extends cdb.jq.Client {
 		var scene = J("#scene");
 		scene.dock(root, Left, 0.2);
 		J("#log").dock(root, Down, 0.3);
-		J("#material").dock(scene.get(), Down, 0.3);
+		J("#material").dock(scene.get(), Down, 0.5);
 	}
 
 	public function sync() {
@@ -149,6 +156,8 @@ class CdbInspector extends cdb.jq.Client {
 			so.j = J("<li>");
 			so.j.html('<div class="content">${o.toString()}</div>');
 			so.j.find(".content").click(function(_) {
+				J("#scene").find(".selected").removeClass("selected");
+				so.j.addClass("selected");
 				selectObject(o);
 			});
 			so.j.appendTo( p != null ? p.jchild : J("#scontent") );
@@ -174,83 +183,235 @@ class CdbInspector extends cdb.jq.Client {
 	function makeProps( props : Array<Property> ) {
 		var t = J("<table>");
 		t.addClass("props");
-		for( p in props ) {
-			var j = J("<tr>");
-			j.addClass("prop");
-			j.addClass(p.getName().toLowerCase());
-			j.appendTo(t);
-
-			var jname = J("<th>");
-			var jprop = J("<td>");
-			jname.appendTo(j);
-			jprop.appendTo(j);
-
-			switch( p ) {
-			case PBool(name, get, set):
-				jname.text(name);
+		for( p in props )
+			addProp(t, p, 0);
+		return t;
+	}
+
+	function addProp( t : JQuery, p : Property, gid : Int ) {
+		var j = J("<tr>");
+		j.addClass("prop");
+		j.addClass("g_" + gid);
+		j.addClass(p.getName().toLowerCase());
+		if( gid > 0 ) j.style("display", "none");
+		j.appendTo(t);
+
+		var jname = J("<th>");
+		var jprop = J("<td>");
+		jname.appendTo(j);
+		jprop.appendTo(j);
+
+		switch( p ) {
+		case PGroup(name, props):
+
+			jname.attr("colspan", "2");
+			jname.html('<i class="icon-arrow-right"/> ' + StringTools.htmlEscape(name));
+			var gid = t.get().childs.length;
+			j.click(function(_) {
+				var i = jname.find("i");
+				var show = i.hasClass("icon-arrow-right");
+				i.attr("class", show ? "icon-arrow-down" : "icon-arrow-right");
+				t.find(".g_" + gid).style("display", show?"":"none");
+			});
+			jprop.remove();
+			for( p in props )
+				addProp(t, p, gid);
+
+		case PBool(name, get, set):
+			jname.text(name);
+			jprop.text(get() ? "Yes" : "No");
+			j.dblclick(function(_) {
+				set(!get());
 				jprop.text(get() ? "Yes" : "No");
-				j.dblclick(function(_) {
-					set(!get());
-					jprop.text(get() ? "Yes" : "No");
+			});
+		case PEnum(name, tenum, get, set):
+			jname.text(name);
+			jprop.text(get());
+			j.dblclick(function(_) {
+
+				var input = J("<select>");
+				var cur = (get() : EnumValue).getIndex();
+				var all : Array<EnumValue> = tenum.createAll();
+				for( p in all ) {
+					var name = p.getName();
+					var idx = p.getIndex();
+					J("<option>").attr("value", "" + p.getIndex()).attr(idx == cur ? "selected" : "_sel", "selected").text(name).appendTo(input);
+				}
+				jprop.text("");
+				input.appendTo(jprop);
+				input.focus();
+				input.blur(function(_) {
+					input.remove();
+					jprop.text(get());
 				});
-			case PEnum(name, tenum, get, set):
-				jname.text(name);
-				jprop.text(get());
-				j.dblclick(function(_) {
-
-					var input = J("<select>");
-					var cur = (get() : EnumValue).getIndex();
-					var all : Array<EnumValue> = tenum.createAll();
-					for( p in all ) {
-						var name = p.getName();
-						var idx = p.getIndex();
-						J("<option>").attr("value", "" + p.getIndex()).attr(idx == cur ? "selected" : "_sel", "selected").text(name).appendTo(input);
+				input.change(function(_) {
+					var v = Std.parseInt(input.getValue());
+					if( v != null )
+						set(all[v]);
+					input.remove();
+					jprop.text(get());
+				});
+			});
+		case PInt(name, get, set):
+			jname.text(name);
+			jprop.text("" + get());
+			j.dblclick(function(_) editValue(jprop, function() return "" + get(), function(s) { var i = Std.parseInt(s); if( i != null ) set(i); } ));
+		case PFloat(name, get, set):
+			jname.text(name);
+			jprop.text("" + get());
+			j.dblclick(function(_) editValue(jprop, function() return "" + get(), function(s) { var i = Std.parseFloat(s); if( !Math.isNaN(i) ) set(i); } ));
+		case PString(name, get, set):
+			jname.text(name);
+			jprop.text("" + get());
+			j.dblclick(function(_) editValue(jprop, get, set));
+		case PColor(name, alpha, get, set):
+			jname.text(name);
+			function init() {
+				var v = get().toColor() & 0xFFFFFF;
+				jprop.html('<div class="color" style="background:#${StringTools.hex(v,6)}"></div>');
+			}
+			jprop.dblclick(function(_) {
+				jprop.special("colorPick", [get().toColor(),alpha], function(c) {
+					set(h3d.Vector.fromColor(c.color));
+					if( c.done ) init();
+				});
+			});
+			init();
+		case PTexture(name, get, set):
+			jname.text(name);
+			var path = null;
+			var isLoaded = false;
+			function init() {
+				var t = get();
+				var res = null;
+				try {
+					if( t != null && t.name != null )
+						res = hxd.res.Loader.currentInstance.load(t.name).toImage();
+				} catch( e : Dynamic ) {
+				}
+				if( res != null ) {
+					// resolve path
+					var lfs = Std.instance(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
+					if( lfs != null )
+						path = lfs.baseDir + res.entry.path;
+					else {
+						var resPath = haxe.macro.Compiler.getDefine("resPath");
+						if( resPath == null ) resPath = "res";
+						path = hxd.File.applicationPath() + resPath + "/" + res.entry.path;
 					}
-					jprop.text("");
-					input.appendTo(jprop);
-					input.trigger("focus");
-					input.blur(function(_) {
-						input.remove();
-						jprop.text(get());
-					});
-					input.change(function(_) {
-						var v = Std.parseInt(input.getValue());
-						if( v != null )
-							set(all[v]);
-						input.remove();
-						jprop.text(get());
+				} else if( t.name != null && (t.name.charCodeAt(0) == '/'.code || t.name.charCodeAt(1) == ':'.code) )
+					path = t.name;
+
+				if( path == null )
+					jprop.text(""+t);
+				else
+					jprop.html('<img src="file://$path"/>');
+			}
+			init();
+			jprop.dblclick(function(_) {
+				jprop.special("fileSelect", [path, "png,jpg,jpeg,gif"], function(path) {
+
+					if( path == null ) return;
+
+					hxd.File.load(path, function(data) {
+						if( isLoaded ) get().dispose();
+						isLoaded = true;
+						set( hxd.res.Any.fromBytes(path, data).toTexture() );
+						init();
 					});
+
 				});
+			});
+		}
+	}
+
+	function editValue( j : JQuery, get : Void -> String, set : String -> Void ) {
+		var input = J("<input>");
+		input.attr("value", get());
+		j.text("");
+		input.appendTo(j);
+		input.focus();
+		input.blur(function(_) {
+			input.remove();
+			set(input.getValue());
+			j.text(get());
+		});
+		input.keydown(function(e) {
+			if( e.keyCode == 13 )
+				input.blur();
+		});
+	}
+
+	function makeShaderProps( s : hxsl.Shader ) {
+		var props = [];
+		var data = @:privateAccess s.shader;
+		for( v in data.data.vars ) {
+			switch( v.kind ) {
+			case Param:
+				var name = v.name+"__";
+				function set(val:Dynamic) {
+					Reflect.setField(s, name, val);
+					if( hxsl.Ast.Tools.isConst(v) )
+						@:privateAccess s.constModified = true;
+				}
+				switch( v.type ) {
+				case TBool:
+					props.push(PBool(v.name, function() return Reflect.field(s,name), set ));
+				case TInt:
+					props.push(PInt(v.name, function() return Reflect.field(s,name), set ));
+				case TFloat:
+					props.push(PFloat(v.name, function() return Reflect.field(s, name), set));
+				case TVec(size = (3 | 4), VFloat) if( v.name.toLowerCase().indexOf("color") >= 0 ):
+					props.push(PColor(v.name, size == 4, function() return Reflect.field(s, name), set));
+				case TSampler2D, TSamplerCube:
+					props.push(PTexture(v.name, function() return Reflect.field(s, name), set));
+				default:
+					props.push(PString(v.name, function() return ""+Reflect.field(s,name), function(val) { } ));
+				}
+			default:
 			}
 		}
-		return t;
+
+		var name = data.data.name;
+		if( StringTools.startsWith(name, "h3d.shader.") )
+			name = name.substr(11);
+
+		return PGroup("shader "+name, props);
 	}
 
 	function selectObject( o : h3d.scene.Object ) {
+
 		if( !o.isMesh() )
 			return;
+
 		var mat = o.toMesh().material;
 		var j = J("#material");
 		j.text("");
 		j.attr("caption", "Material - " + (mat.name == null ? "@" + o.toString() : mat.name));
-		for( pass in mat.getPasses() ) {
-			var pgrp = J("<div>");
-			pgrp.appendTo(j);
 
-			var p = J("<div>");
-			p.addClass("pass");
-			p.text(pass.name);
-			p.appendTo(pgrp);
+		var props = [];
+
+		for( pass in mat.getPasses() ) {
 
-			var t = makeProps([
+			var pl = [
+				PBool("Lights", function() return pass.enableLights, function(v) pass.enableLights = v),
+				PEnum("Cull", h3d.mat.Data.Face, function() return pass.culling, function(v) pass.culling = v),
+				PEnum("BlendSrc", h3d.mat.Data.Blend, function() return pass.blendSrc, function(v) pass.blendSrc = pass.blendAlphaSrc = v),
+				PEnum("BlendDst", h3d.mat.Data.Blend, function() return pass.blendDst, function(v) pass.blendDst = pass.blendAlphaDst = v),
 				PBool("DepthWrite", function() return pass.depthWrite, function(b) pass.depthWrite = b),
-				PEnum("DepthTest", h3d.mat.Data.Compare, function() return pass.depthTest, function(v) pass.depthTest = v),
-			]);
+				PEnum("DepthTest", h3d.mat.Data.Compare, function() return pass.depthTest, function(v) pass.depthTest = v)
+			];
 
-			t.appendTo(pgrp);
-			t.style("display", "none");
-			p.click(function(_) t.toggle());
+			var shaders = [for( s in pass.getShaders() ) s];
+			shaders.reverse();
+			for( s in shaders )
+				pl.push(makeShaderProps(s));
+
+			props.push(PGroup("pass "+pass.name,pl));
 		}
+
+		var t = makeProps(props);
+		t.appendTo(j);
 	}
 
 }

+ 41 - 12
hxd/net/inspect.css

@@ -1,41 +1,70 @@
-.jqpage div, .jqpage a, .jqpage li, .jqpage td, .jqpage th {
+.jqpage div, .jqpage a, .jqpage li, .jqpage td, .jqpage th, .dialog-floating div, .dialog-floating a, .dialog-floating li, .dialog-floating td, .dialog-floating th {
 	user-select : none;
 	-moz-user-select : none;
 	-webkit-user-select : none;
 }
-.jqpage .panel {
+.jqpage .panel, .dialog-floating .panel {
 	overflow : auto;
 }
-.jqpage #log {
+.jqpage #log, .dialog-floating #log {
 	font-family : Courier;
 }
-.jqpage #log .line {
+.jqpage #log .line, .dialog-floating #log .line {
 	padding : 1px 3px;
 }
-.jqpage #log .line:nth-child(even) {
+.jqpage #log .line:nth-child(even), .dialog-floating #log .line:nth-child(even) {
 	background-color : #eee;
 }
-.jqpage #scene ul.elt {
+.jqpage #scene ul.elt, .dialog-floating #scene ul.elt {
 	background-color : transparent;
 }
-.jqpage #scene ul.elt li {
+.jqpage #scene ul.elt li, .dialog-floating #scene ul.elt li {
 	cursor : pointer;
 }
-.jqpage #scene ul.elt li .content:hover {
+.jqpage #scene ul.elt li .content:hover, .dialog-floating #scene ul.elt li .content:hover {
 	background-color : #eee;
 }
-.jqpage #scene ul.elt ul {
+.jqpage #scene ul.elt ul, .dialog-floating #scene ul.elt ul {
 	padding-left : 20px;
 }
-.jqpage #material .pass {
+.jqpage #scene ul.elt li.selected, .dialog-floating #scene ul.elt li.selected {
+	background-color : #eee;
+}
+.jqpage table.props tr.pgroup, .dialog-floating table.props tr.pgroup {
+	cursor : pointer;
+}
+.jqpage table.props tr.pgroup th, .dialog-floating table.props tr.pgroup th {
+	text-align : left;
 	background-color : #555;
 	color : #bbb;
 	font-weight : bold;
 	padding : 2px 4px;
 	cursor : pointer;
 }
-.jqpage table.props td select {
+.jqpage table.props td, .dialog-floating table.props td {
+	height : 24px;
+}
+.jqpage table.props td input, .jqpage table.props td select, .dialog-floating table.props td input, .dialog-floating table.props td select {
 	padding-left : 0px;
-	height : 20px;
+	height : 18px;
+	border : 1px solid #888;
 	width : 100%;
 }
+.jqpage table.props tr.ptexture img, .dialog-floating table.props tr.ptexture img {
+	max-width : 128px;
+	max-height : 128px;
+}
+.jqpage table.props tr.pcolor td .modal, .dialog-floating table.props tr.pcolor td .modal {
+	opacity : 0;
+	filter : alpha(opacity=0);
+	zoom : 1;
+}
+.jqpage table.props tr.pcolor td .color, .dialog-floating table.props tr.pcolor td .color {
+	display : inline-block;
+	zoom : 1;
+	*display : inline;
+	width : 20px;
+	height : 20px;
+	border : 2px solid white;
+	outline : 1px solid black;
+}

+ 38 - 10
hxd/net/inspect.hss

@@ -1,4 +1,4 @@
-.jqpage {
+.jqpage, .dialog-floating {
 
 	div, a, li, td, th {
 		user-select : none;
@@ -30,27 +30,55 @@
 			ul {
 				padding-left : 20px;
 			}
+			li.selected {
+				background-color : #eee;
+			}
 		}
 	}
 
 	#material {
-		.pass {
-			background-color : #555;
-			color : #bbb;
-			font-weight : bold;
-			padding : 2px 4px;
-			cursor : pointer;
-		}
 	}
 
 	table.props {
+		tr.pgroup {
+			cursor : pointer;
+			th {
+				text-align : left;
+				background-color : #555;
+				color : #bbb;
+				font-weight : bold;
+				padding : 2px 4px;
+				cursor : pointer;
+			}
+		}
 		td {
-			select {
+			height : 24px;
+			input, select {
 				padding-left : 0px;
-				height : 20px;
+				height : 18px;
+				border : 1px solid #888;
 				width : 100%;
 			}
 		}
+
+		tr.ptexture img {
+			max-width : 128px;
+			max-height : 128px;
+		}
+
+		tr.pcolor td {
+			.modal {
+				opacity : 0.;
+			}
+			.color {
+				display : inline-block;
+				width : 20px;
+				height : 20px;
+				border : 2px solid white;
+				outline : 1px solid black;
+			}
+		}
+
 	}
 
 }