Explorar el Código

Hide: replace jstree with fancy tree in model view

lviguier hace 2 meses
padre
commit
6cb7679f7e
Se han modificado 6 ficheros con 120 adiciones y 165 borrados
  1. 9 0
      bin/style.css
  2. 12 0
      bin/style.less
  3. 1 5
      hide/comp/FancyTree.hx
  4. 0 146
      hide/comp/SceneTree.hx
  5. 5 4
      hide/view/FileBrowser.hx
  6. 93 10
      hide/view/Model.hx

+ 9 - 0
bin/style.css

@@ -5180,6 +5180,15 @@ fancy-tree fancy-scroll fancy-tree-item.feedback-drop-in::after {
   z-index: 10;
   pointer-events: none;
 }
+fancy-tree.overlay {
+  background-color: transparent;
+}
+fancy-tree.overlay fancy-scroll fancy-tree-item {
+  background: transparent;
+}
+fancy-tree.overlay fancy-scroll fancy-tree-item:hover {
+  color: #e2e2e2;
+}
 fancy-gallery {
   display: flex;
   flex-direction: column;

+ 12 - 0
bin/style.less

@@ -6209,6 +6209,18 @@ fancy-tree {
 
 		}
 	}
+
+	&.overlay {
+		background-color: transparent;
+		fancy-scroll {
+			fancy-tree-item {
+				&:hover {
+					color: #e2e2e2;
+				}
+				background: transparent;
+			}
+		}
+ 	}
 }
 
 fancy-gallery {

+ 1 - 5
hide/comp/FancyTree.hx

@@ -846,11 +846,7 @@ class FancyTree<TreeItem> extends hide.comp.Component {
 	}
 
 	function doubleClickHander(data: TreeItemData<TreeItem>, event: js.html.MouseEvent) : Void {
-		if (hasChildren(data.item)) {
-			toggleDataOpen(data);
-		} else {
-			onDoubleClick(data.item);
-		}
+		onDoubleClick(data.item);
 	}
 
 	function dataClickHandler(data: TreeItemData<TreeItem>, event: js.html.MouseEvent) : Void {

+ 0 - 146
hide/comp/SceneTree.hx

@@ -1,146 +0,0 @@
-package hide.comp;
-
-class SceneTree extends IconTree<String> {
-
-	var showRoot : Bool;
-	public var obj : h3d.scene.Object;
-
-	public function new(obj, root, showRoot : Bool) {
-		super(root);
-		this.showRoot = showRoot;
-		this.obj = obj;
-		init();
-	}
-
-	override function onClick(id:String, evt: Dynamic) {
-		onSelectionChanged(getSelectedObjects());
-	}
-
-	override function get( id : String ) {
-		var root = showRoot ? obj.parent : obj;
-		var path = id == null ? "" : id+"/";
-		if( id != null ) {
-			var parts = [for(p in id.split("/")) { id : p, index : Std.parseInt(p) }];
-			for( p in parts ) {
-				if( StringTools.startsWith(p.id,"joint:") ) {
-					root = root.getObjectByName(parts.pop().id.substr(6)); // last joint only
-					break;
-				} else {
-					root = root.getChildAt(p.index);
-				}
-			}
-		}
-		var elements : Array<IconTree.IconTreeItem<String>> = [
-			for( i in 0...root.numChildren ) {
-				var c = root.getChildAt(i);
-				{
-					value :path+i,
-					text : getObjectName(c),
-					icon : "ico ico-" + getIcon(c),
-					children : c.isMesh() || c.numChildren > 0,
-					state : { opened : c.numChildren > 0 && c.numChildren < 10 }
-				}
-			}
-		];
-		if( root.isMesh() ) {
-			var materials = root.toMesh().getMeshMaterials();
-			for( i in 0...materials.length ) {
-				var m = materials[i];
-				elements.push({
-					value :path+"mat:"+i,
-					text : m.name == null ? "Material@"+i : m.name,
-					icon : "ico ico-photo",
-				});
-			}
-			var sk = Std.downcast(root,h3d.scene.Skin);
-			if( sk != null ) {
-				for( j in sk.getSkinData().rootJoints )
-					elements.push({
-						value: path+"joint:"+j.name,
-						text : j.name,
-						icon : "ico ico-gg",
-						children : j.subs.length > 0,
-					});
-			}
-		}
-		var joint = Std.downcast(root,h3d.scene.Skin.Joint);
-		if( joint != null ) {
-			var j = joint.skin.getSkinData().allJoints[joint.index];
-			for( j in j.subs )
-				elements.push({
-					value: path+"joint:"+j.name,
-					text : j.name,
-					icon : "ico ico-gg",
-					children : j.subs.length > 0,
-				});
-		}
-		return elements;
-	}
-
-	override function applyStyle(id: String, el: Element) {
-		var v : Dynamic = resolvePath(id);
-
-		var obj = Std.downcast(v, h3d.scene.Object);
-		if( obj == null || Std.isOfType(obj,h3d.scene.Skin.Joint) ) return;
-
-		if (el.find(".ico-eye").length == 0) {
-			var visibilityToggle = new Element('<i class="ico ico-eye visibility-large-toggle"/>').appendTo(el.find(".jstree-anchor").first());
-			visibilityToggle.click(function (e) {
-				obj.visible = !obj.visible;
-				el.toggleClass("hidden", !obj.visible);
-			});
-		}
-		el.toggleClass("hidden", !obj.visible);
-	}
-
-
-	public function getObjectName( o : h3d.scene.Object ) {
-		if( o.name != null )
-			return o.name;
-		if( o.parent == null )
-			return o.toString();
-		return o.toString() + "@" + @:privateAccess o.parent.children.indexOf(o);
-	}
-
-
-	function resolvePath(id:String) : Dynamic {
-		var path = id.split("/");
-		var root = showRoot ? obj.parent : obj;
-		while( path.length > 0 ) {
-			var idx = Std.parseInt(path[0]);
-			if( idx == null ) break;
-			path.shift();
-			root = root.getChildAt(idx);
-		}
-		if( path.length == 0 )
-			return root;
-		var prop = path[0];
-		switch( prop.split(":").shift() ) {
-		case "mat":
-			return root.toMesh().getMaterials()[Std.parseInt(prop.substr(4))];
-		case "joint":
-			return root.getObjectByName(path.pop().substr(6));
-		}
-		return null;
-	}
-
-	function getIcon( c : h3d.scene.Object ) {
-		if( c.isMesh() ) {
-			if( Std.isOfType(c, h3d.scene.Skin) )
-				return "male";
-			if( Std.isOfType(c, h3d.parts.GpuParticles) || Std.isOfType(c, h3d.parts.Particles) )
-				return "snowflake-o";
-			return "cube";
-		}
-		if( Std.isOfType(c, h3d.scene.Light) )
-			return "sun-o";
-		return "circle-o";
-	}
-
-	function getSelectedObjects() {
-		return [for (s in getSelection()) resolvePath(s)];
-	}
-
-
-	public dynamic function onSelectionChanged(elts : Array<Dynamic>) {}
-}

+ 5 - 4
hide/view/FileBrowser.hx

@@ -96,7 +96,7 @@ class FileBrowser extends hide.ui.View<FileBrowserState> {
 					var newState : FileBrowserState = haxe.Json.parse(haxe.Json.stringify(state));
 					newState.savedLayout = Vertical;
 					close();
-					ide.open("hide.view.FileBrowser", newState, Left);
+					ide.open("hide.view.FileBrowser", newState, hide.ui.View.DisplayPosition.Left);
 				}
 			},
 			{
@@ -106,7 +106,7 @@ class FileBrowser extends hide.ui.View<FileBrowserState> {
 					var newState : FileBrowserState = haxe.Json.parse(haxe.Json.stringify(state));
 					newState.savedLayout = Horizontal;
 					close();
-					ide.open("hide.view.FileBrowser", newState, Bottom);
+					ide.open("hide.view.FileBrowser", newState, hide.ui.View.DisplayPosition.Bottom);
 				}
 			},
 			]
@@ -487,9 +487,10 @@ class FileBrowser extends hide.ui.View<FileBrowserState> {
 		fancyTree.openItem(root, true);
 
 		fancyTree.onDoubleClick = (item: FileEntry) -> {
-			if (item.kind == File) {
+			if (item.kind == File)
 				ide.openFile(item.getPath());
-			}
+			else
+				fancyTree.openItem(item);
 		}
 
 		var right = browserLayout.find(".right");

+ 93 - 10
hide/view/Model.hx

@@ -7,7 +7,7 @@ class Model extends FileView {
 	var tools : hide.comp.Toolbar;
 	var obj : h3d.scene.Object;
 	var sceneEditor : hide.comp.SceneEditor;
-	var tree : hide.comp.SceneTree;
+	var tree : hide.comp.FancyTree<Dynamic>;
 	var tabs : hide.comp.Tabs;
 	var overlay : Element;
 	var eventList : Element;
@@ -91,7 +91,7 @@ class Model extends FileView {
 		sceneEditor.onRefresh = onRefresh;
 		sceneEditor.onUpdate = onUpdate;
 		sceneEditor.onSelectionChanged = function(elts : Array<hrt.prefab.Prefab>, ?mode : hide.comp.SceneEditor.SelectMode = Default) {
-			if (tree != null) tree.setSelection([]);
+			if (tree != null) tree.clearSelection();
 			refreshSelectionHighlight(null);
 		}
 		sceneEditor.view.keys = new hide.ui.Keys(null); // Remove SceneEditor Shortcuts
@@ -248,6 +248,7 @@ class Model extends FileView {
 			return true;
 		}
 
+		refreshSelectionHighlight(null);
 		selectedElements = elts;
 
 		var properties = sceneEditor.properties;
@@ -1301,21 +1302,103 @@ class Model extends FileView {
 		hidePropsRec(obj);
 
 		if( tree != null ) tree.remove();
-		tree = new hide.comp.SceneTree(obj, overlay, obj.name != null);
-		tree.onSelectionChanged = onTreeSelectionChanged;
-		tree.saveDisplayKey = this.saveDisplayKey;
+		tree = new hide.comp.FancyTree<Dynamic>(overlay);
+		tree.element.addClass("overlay");
+		tree.getChildren = (item: Dynamic) -> {
+			if (item == null)
+				return [obj];
+
+			var skin = Std.downcast(item, h3d.scene.Skin);
+			var obj = Std.downcast(item, h3d.scene.Object);
+			var join = Std.downcast(item, h3d.scene.Skin.Joint);
+			var children : Array<Dynamic> = [];
+
+			if (obj != null && @:privateAccess obj.children != null) {
+				for (c in children)
+					if (!Std.isOfType(c, h3d.scene.Graphics))
+						children.push(c);
+			}
+
+			if (skin != null) {
+				var joints = skin.getSkinData().rootJoints;
+				for (j in joints)
+					children.push(skin.getObjectByName(j.name));
+			}
+
+			if (obj != null) {
+				var mats = item.getMaterials(null, false);
+				children = children.concat(mats);
+			}
+
+			if (join != null) {
+				var sObj : h3d.scene.Object = join;
+				while (!Std.isOfType(sObj, h3d.scene.Skin))
+					sObj = sObj.parent;
+				var skin : h3d.scene.Skin = cast sObj;
+				for (j in @:privateAccess skin.getSkinData().allJoints[join.index].subs)
+					children.push(skin.getObjectByName(j.name));
+			}
+
+			return children;
+		};
+		tree.getName = (item: Dynamic) -> {
+			var obj = Std.downcast(item, h3d.scene.Object);
+			if (obj != null) return obj.name;
+
+			var mat = Std.downcast(item, h3d.mat.Material);
+			if (mat != null) return mat.name;
 
-		function ctxMenu(tree, e) {
-			e.preventDefault();
-			var current = tree.getCurrentOver();
+			var join = Std.downcast(item, h3d.scene.Skin.Joint);
+			if (join != null) return join.name;
+
+			return "";
+		};
+		tree.getUniqueName = (item: Dynamic) -> {
+			var o = Std.downcast(item, h3d.scene.Object);
+			if (o == null) return item.name;
+			var path = o.name;
+			var parent = o.parent;
+			while (parent != null) {
+				path = '${parent.name}/${path}';
+				parent = parent.parent;
+			}
+			return path;
+		};
+		tree.getIcon = (item: Dynamic) -> {
+			var skin = Std.downcast(item, h3d.anim.Skin);
+			if (skin != null) return '<div class="ico ico-male"></div>';
+
+			var mat = Std.downcast(item, h3d.mat.Material);
+			if (mat != null) return '<div class="ico ico-photo"></div>';
+
+			var join = Std.downcast(item, h3d.scene.Skin.Joint);
+			if (join != null) return '<div class="ico ico-male"></div>';
+
+			var obj = Std.downcast(item, h3d.scene.Object);
+			if (obj != null) return '<div class="ico ico-gg"></div>';
+
+			return null;
+		};
+		tree.onSelectionChanged = (enterKey : Bool) -> {
+			var selection = tree.getSelectedItems();
+			onTreeSelectionChanged(selection);
+		};
+		tree.onDoubleClick = (item: Dynamic) -> {
+			var obj = Std.downcast(item, h3d.scene.Object);
+			sceneEditor.focusObjects([obj]);
+		};
+		function ctxMenu(item : Dynamic, event : js.html.MouseEvent) {
+			event.preventDefault();
 			var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [
 				{ label : "Merge selected", enabled : false /*canMergeElements(selectedElements)*/, click: () -> mergeModels(cast selectedElements) },
 				{ label : "Merge all meshes", enabled : true, click: () -> mergeModels(cast [for (m in obj.findAll(o -> Std.downcast(o, h3d.scene.Mesh))) m]) },
 			];
 
-			hide.comp.ContextMenu.createFromEvent(cast e, menuItems);
+			hide.comp.ContextMenu.createFromEvent(cast event, menuItems);
 		};
-		tree.element.parent().contextmenu(ctxMenu.bind(tree));
+		tree.onContextMenu = ctxMenu;
+		tree.rebuildTree();
+		tree.openItem(obj, true);
 
 		tools.clear();
 		var anims = scene.listAnims(getPath());