Ver código fonte

Add favorites list in L3D. Fix various layout clusterfucks in L3D due to 100% heights not working well with flex

trethaller 6 anos atrás
pai
commit
d272f9399d
5 arquivos alterados com 120 adições e 19 exclusões
  1. 15 2
      bin/style.css
  2. 19 2
      bin/style.less
  3. 2 0
      hide/comp/IconTree.hx
  4. 74 12
      hide/comp/SceneEditor.hx
  5. 10 3
      hide/view/l3d/Level3D.hx

+ 15 - 2
bin/style.css

@@ -225,7 +225,6 @@ input[type=checkbox]:checked:after {
   border: 1px solid #444;
   width: 300px;
   overflow-y: auto;
-  flex: 0 0 300px;
 }
 .hide-scenetree .jstree {
   width: 300px;
@@ -1077,6 +1076,10 @@ body.hide-subview .lm_controls {
 .jstree .hidden a {
   color: #555;
 }
+.jstree a.favorite {
+  color: white;
+  font-weight: bold;
+}
 .jstree .disabled a {
   color: #533 !important;
   display: inline;
@@ -1102,10 +1105,20 @@ body.hide-subview .lm_controls {
 .jstree-node {
   padding-right: 10px!important;
 }
+.hide-scene-outliner .favorites {
+  overflow-y: auto;
+  background: #111;
+}
+.hide-scene-outliner .favorites label {
+  font-weight: bold;
+}
+.hide-scene-outliner .favorites-tree {
+  padding: 4px;
+}
 .visibility-toggle,
 .visibility-large-toggle {
   position: absolute;
-  right: 0px;
+  right: 4px;
   padding: 4px;
 }
 .visibility-toggle:hover,

+ 19 - 2
bin/style.less

@@ -239,7 +239,6 @@ input[type=checkbox] {
 	border : 1px solid #444;
 	width: 300px;
 	overflow-y: auto;
-	flex: 0 0 300px;
 
 	.jstree {
 		width: 300px;
@@ -1187,6 +1186,11 @@ body.hide-subview {
 		}
 	}
 
+	a.favorite {
+		color: white;
+		font-weight: bold;
+	}
+
 	.disabled {
 		a {
 			color: #533 !important;
@@ -1222,9 +1226,22 @@ body.hide-subview {
 	padding-right: 10px!important;
 }
 
+.hide-scene-outliner {
+	.favorites {
+		overflow-y: auto;
+		label {
+			font-weight: bold;
+		}
+		background: #111;
+	}
+	.favorites-tree {
+		padding: 4px;
+	}
+}
+
 .visibility-toggle, .visibility-large-toggle {
 	position: absolute;
-	right: 0px;
+	right: 4px;
 	padding: 4px;
 
 	&:hover {

+ 2 - 0
hide/comp/IconTree.hx

@@ -98,6 +98,8 @@ class IconTree<T:{}> extends Component {
 				check_callback : function(operation, node, node_parent, value, extra) {
 					if( operation == "edit" && allowRename )
 						return true;
+					if(!map.exists(node.id))  // Can happen on drag from foreign tree
+						return false;
 					if( operation == "rename_node" ) {
 						if( node.text == value ) return true; // no change
 						return onRename(map.get(node.id).value, value);

+ 74 - 12
hide/comp/SceneEditor.hx

@@ -82,6 +82,7 @@ enum RefreshMode {
 class SceneEditor {
 
 	public var tree : hide.comp.IconTree<PrefabElement>;
+	public var favTree : hide.comp.IconTree<PrefabElement>;
 	public var scene : hide.comp.Scene;
 	public var properties : hide.comp.PropsEditor;
 	public var context(default,null) : hxd.prefab.Context;
@@ -99,6 +100,7 @@ class SceneEditor {
 	var ide : hide.Ide;
 	public var event(default, null) : hxd.WaitEvent;
 	var hideList : Map<PrefabElement, Bool> = new Map();
+	var favorites : Array<PrefabElement> = [];
 
 	var undo(get, null):hide.ui.UndoHistory;
 	function get_undo() { return view.undo; }
@@ -121,6 +123,10 @@ class SceneEditor {
 		tree.async = false;
 		tree.autoOpenNodes = false;
 
+		favTree = new hide.comp.IconTree();
+		favTree.async = false;
+		favTree.autoOpenNodes = false;
+
 		var sceneEl = new Element('<div class="heaps-scene"></div>');
 		scene = new hide.comp.Scene(view.config, null, sceneEl);
 		scene.editor = this;
@@ -175,13 +181,23 @@ class SceneEditor {
 			}
 		});
 
-		var list = @:privateAccess view.getDisplayState("hideList");
-		if(list != null) {
-			var m = [for(i in (list:Array<Dynamic>)) i => true];
+		// Load display state
+		{
 			var all = sceneData.flatten(hxd.prefab.Prefab);
-			for(p in all) {
-				if(m.exists(p.getAbsPath()))
-					hideList.set(p, true);
+			var list = @:privateAccess view.getDisplayState("hideList");
+			if(list != null) {
+				var m = [for(i in (list:Array<Dynamic>)) i => true];
+				for(p in all) {
+					if(m.exists(p.getAbsPath()))
+						hideList.set(p, true);
+				}
+			}
+			var favList = @:privateAccess view.getDisplayState("favorites");
+			if(favList != null) {
+				for(p in all) {
+					if(favList.indexOf(p.getAbsPath()) >= 0)
+						favorites.push(p);
+				}
 			}
 		}
 	}
@@ -255,22 +271,39 @@ class SceneEditor {
 
 		// BUILD scene tree
 
-		function makeItem(o:PrefabElement) : hide.comp.IconTree.IconTreeItem<PrefabElement> {
+		function makeItem(o:PrefabElement, ?state) : hide.comp.IconTree.IconTreeItem<PrefabElement> {
 			var p = o.getHideProps();
 			var r : hide.comp.IconTree.IconTreeItem<PrefabElement> = {
 				value : o,
 				text : o.name,
 				icon : "fa fa-"+p.icon,
-				children : o.children.length > 0
+				children : o.children.length > 0,
+				state: state
 			};
 			return r;
 		}
+		favTree.get = function (o:PrefabElement) {
+			if(o == null) {
+				return [for(f in favorites) makeItem(f, {
+					disabled: true
+				})];
+			}
+			return [];
+		}
+		favTree.allowRename = false;
+		favTree.init();
+		favTree.onAllowMove = function(_, _) {
+			return false;
+		};
+		favTree.onClick = function(e) {
+			selectObjects([e], true);
+		}
 		tree.get = function(o:PrefabElement) {
 			var objs = o == null ? sceneData.children : Lambda.array(o);
 			var out = [for( o in objs ) makeItem(o)];
 			return out;
 		};
-		tree.element.parent().contextmenu(function(e) {
+		function ctxMenu(tree, e) {
 			e.preventDefault();
 			var current = tree.getCurrentOver();
 			if(current != null && (curEdit == null || curEdit.elements.indexOf(current) < 0)) {
@@ -282,6 +315,7 @@ class SceneEditor {
 				{ label : "New...", menu : newItems },
 			];
 			var actionItems : Array<hide.comp.ContextMenu.ContextMenuItem> = [
+				{ label : "Favorite", checked : current != null && isFavorite(current), click : function() setFavorite(current, !isFavorite(current)) },
 				{ label : "Rename", enabled : current != null, click : function() tree.editNode(current) },
 				{ label : "Delete", enabled : current != null, click : function() deleteElements(curEdit.rootElements) },
 				{ label : "Duplicate", enabled : current != null, click : duplicate.bind(false) },
@@ -307,7 +341,9 @@ class SceneEditor {
 
 			menuItems.push({ isSeparator : true, label : "" });
 			new hide.comp.ContextMenu(menuItems.concat(actionItems));
-		});
+		};
+		tree.element.parent().contextmenu(ctxMenu.bind(tree));
+		favTree.element.parent().contextmenu(ctxMenu.bind(favTree));
 		tree.allowRename = true;
 		tree.init();
 		tree.onClick = function(e) {
@@ -353,6 +389,7 @@ class SceneEditor {
 
 	public function refresh( ?mode: RefreshMode, ?callb: Void->Void) {
 		if(mode == null || mode == Full) refreshScene();
+		refreshFavs();
 		refreshTree(callb);
 	}
 
@@ -368,6 +405,10 @@ class SceneEditor {
 		});
 	}
 
+	function refreshFavs() {
+		favTree.refresh();
+	}
+
 	function refreshProps() {
 		selectObjects(curEdit.elements, false);
 	}
@@ -746,6 +787,7 @@ class SceneEditor {
 	public function applyTreeStyle(p: PrefabElement, el: Element) {
 		var obj3d  = p.to(Object3D);
 		el.toggleClass("disabled", !p.enabled);
+		el.find("a").first().toggleClass("favorite", isFavorite(p));
 
 		if(obj3d != null) {
 			el.toggleClass("hidden", isHidden(obj3d));
@@ -1172,9 +1214,29 @@ class SceneEditor {
 		return hideList.exists(e);
 	}
 
-	function saveHideState() {
+	function saveDisplayState() {
 		var state = [for (h in hideList.keys()) h.getAbsPath()];
 		@:privateAccess view.saveDisplayState("hideList", state);
+		var state = [for(f in favorites) f.getAbsPath()];
+		@:privateAccess view.saveDisplayState("favorites", state);
+	}
+
+	public function isFavorite(e: PrefabElement) {
+		return favorites.indexOf(e) >= 0;
+	}
+
+	public function setFavorite(e: PrefabElement, fav: Bool) {
+		if(fav && !isFavorite(e))
+			favorites.push(e);
+		else if(!fav && isFavorite(e))
+			favorites.remove(e);
+
+		var el = tree.getElement(e);
+		if(el != null)
+			applyTreeStyle(e, el);
+
+		refreshFavs();
+		saveDisplayState();
 	}
 
 	public function setVisible(elements : Array<PrefabElement>, visible: Bool) {
@@ -1194,7 +1256,7 @@ class SceneEditor {
 				applySceneStyle(o);
 			}
 		}
-		saveHideState();
+		saveDisplayState();
 	}
 
 	function isolate(elts : Array<PrefabElement>) {

+ 10 - 3
hide/view/l3d/Level3D.hx

@@ -318,14 +318,19 @@ class Level3D extends FileView {
 
 		element.html('
 			<div class="flex vertical">
-				<div class="toolbar">
+				<div style="flex: 0 0 30px;">
 					<span class="tools-buttons"></span>
 					<span class="layer-buttons"></span>
 				</div>
-				<div class="flex-elt">
+				<div style="display: flex; flex-direction: row; flex: 1;">
 					<div class="heaps-scene">
 					</div>
-					<div class="hide-scenetree">
+					<div class="hide-scene-outliner">
+						<div class="favorites" style="height:20%;">
+							<label>Favorites</label>
+							<div class="favorites-tree"></div>
+						</div>
+						<div class="hide-scenetree" style="height:80%;"></div>
 					</div>
 					<div class="tabs">
 						<div class="tab expand" name="Scene" icon="sitemap">
@@ -347,9 +352,11 @@ class Level3D extends FileView {
 		sceneEditor = new Level3DSceneEditor(this, data);
 		sceneEditor.addSearchBox(element.find(".hide-scenetree").first());
 		element.find(".hide-scenetree").first().append(sceneEditor.tree.element);
+		element.find(".favorites-tree").first().append(sceneEditor.favTree.element);
 		element.find(".hide-scroll").first().append(sceneEditor.properties.element);
 		element.find(".heaps-scene").first().append(sceneEditor.scene.element);
 		sceneEditor.tree.element.addClass("small");
+		sceneEditor.favTree.element.addClass("small");
 
 		// Level edit
 		{