Explorar o código

[animgraph] Parameter reordering and deletion

Clément Espeute hai 8 meses
pai
achega
d0efc18557
Modificáronse 3 ficheiros con 150 adicións e 4 borrados
  1. 22 0
      bin/style.css
  2. 25 0
      bin/style.less
  3. 103 4
      hide/view/animgraph/AnimGraphEditor.hx

+ 22 - 0
bin/style.css

@@ -4156,7 +4156,9 @@ hide-popover hide-content {
 }
 }
 button-2 {
 button-2 {
   min-height: 16px;
   min-height: 16px;
+  min-width: 24px;
   display: flex;
   display: flex;
+  justify-content: stretch;
   border: var(--basic-border);
   border: var(--basic-border);
   border-radius: var(--basic-border-radius);
   border-radius: var(--basic-border-radius);
   box-sizing: border-box;
   box-sizing: border-box;
@@ -4273,6 +4275,7 @@ graph-editor-root properties-container graph-parameters > ul graph-parameter {
   justify-items: stretch;
   justify-items: stretch;
   border: var(--basic-border);
   border: var(--basic-border);
   border-radius: var(--basic-border-radius);
   border-radius: var(--basic-border-radius);
+  position: relative;
 }
 }
 graph-editor-root properties-container graph-parameters > ul graph-parameter header {
 graph-editor-root properties-container graph-parameters > ul graph-parameter header {
   display: flex;
   display: flex;
@@ -4332,6 +4335,25 @@ graph-editor-root properties-container graph-parameters > ul graph-parameter .ic
   transition: transform 0.25s;
   transition: transform 0.25s;
   transform: rotate(0deg);
   transform: rotate(0deg);
 }
 }
+graph-editor-root properties-container graph-parameters > ul graph-parameter.hovertop:before,
+graph-editor-root properties-container graph-parameters > ul graph-parameter.hoverbot:after {
+  display: block;
+  position: absolute;
+  z-index: 100;
+  margin: 0 auto;
+  width: 100%;
+  content: "";
+}
+graph-editor-root properties-container graph-parameters > ul graph-parameter:before {
+  border-top: 10px solid rgba(114, 180, 255, 0.75);
+  top: 0px;
+  pointer-events: none;
+}
+graph-editor-root properties-container graph-parameters > ul graph-parameter:after {
+  border-bottom: 10px solid rgba(114, 180, 255, 0.75);
+  bottom: 0px;
+  pointer-events: none;
+}
 /** Blendspace2dEditor **/
 /** Blendspace2dEditor **/
 blend-space-2d-root {
 blend-space-2d-root {
   width: 100%;
   width: 100%;

+ 25 - 0
bin/style.less

@@ -4916,7 +4916,9 @@ hide-popover {
 
 
 button-2 {
 button-2 {
 	min-height: 16px;
 	min-height: 16px;
+	min-width: 24px;
 	display: flex;
 	display: flex;
+	justify-content: stretch;
 	border: var(--basic-border);
 	border: var(--basic-border);
 	border-radius: var(--basic-border-radius);
 	border-radius: var(--basic-border-radius);
 	box-sizing: border-box;
 	box-sizing: border-box;
@@ -5060,6 +5062,7 @@ graph-editor-root {
 
 
 					border: var(--basic-border);
 					border: var(--basic-border);
 					border-radius: var(--basic-border-radius);
 					border-radius: var(--basic-border-radius);
+					position: relative;
 
 
 					header {
 					header {
 						display: flex;
 						display: flex;
@@ -5131,6 +5134,28 @@ graph-editor-root {
 						transition: transform 0.25s;
 						transition: transform 0.25s;
 						transform: rotate(0deg);
 						transform: rotate(0deg);
 					}
 					}
+
+
+					&.hovertop:before, &.hoverbot:after {
+						display: block;
+						position: absolute;
+						z-index: 100;
+						margin: 0 auto;
+						width: 100%;
+						content: "";
+					}
+
+					&:before {
+						border-top: 10px solid rgba(114, 180, 255, 0.75);
+						top: 0px;
+						pointer-events: none;
+					}
+
+					&:after {
+						border-bottom: 10px solid rgba(114, 180, 255, 0.75);
+						bottom: 0px;
+						pointer-events: none;
+					}
 				}
 				}
 			}
 			}
 		}
 		}

+ 103 - 4
hide/view/animgraph/AnimGraphEditor.hx

@@ -58,7 +58,8 @@ class AnimGraphEditor extends GenericGraphEditor {
     }
     }
 
 
     public function refreshPreview() {
     public function refreshPreview() {
-        setPreview(previewNode);
+        if (previewNode != null)
+            setPreview(previewNode);
     }
     }
 
 
     public function setPreview(newOutput: hrt.animgraph.nodes.AnimNode) {
     public function setPreview(newOutput: hrt.animgraph.nodes.AnimNode) {
@@ -94,9 +95,10 @@ class AnimGraphEditor extends GenericGraphEditor {
         for (paramIndex => param in animGraph.parameters) {
         for (paramIndex => param in animGraph.parameters) {
             var paramElement = new Element('<graph-parameter>
             var paramElement = new Element('<graph-parameter>
                 <header>
                 <header>
+                    <div class="reorder ico ico-reorder" draggable="true"></div>
                     <div class="ico ico-chevron-down toggle-open"></div>
                     <div class="ico ico-chevron-down toggle-open"></div>
                     <input type="text" value="${param.name}" class="fill"></input>
                     <input type="text" value="${param.name}" class="fill"></input>
-                    <div class="reorder ico ico-reorder" draggable="true"></div>
+                    <button-2 class="menu"><div class="ico ico-ellipsis-v"/></button-2>
                 </header>
                 </header>
             </graph-parameter>').appendTo(parametersList);
             </graph-parameter>').appendTo(parametersList);
 
 
@@ -125,6 +127,10 @@ class AnimGraphEditor extends GenericGraphEditor {
                 undo.change(Custom(exec));
                 undo.change(Custom(exec));
             });
             });
 
 
+            name.on("contextmenu", (e) -> {
+                e.stopPropagation();
+            });
+
             var toggleOpen = paramElement.find(".toggle-open");
             var toggleOpen = paramElement.find(".toggle-open");
             toggleOpen.on("click", (e) -> {
             toggleOpen.on("click", (e) -> {
                 open = !open;
                 open = !open;
@@ -137,8 +143,47 @@ class AnimGraphEditor extends GenericGraphEditor {
                 e.dataTransfer.setDragImage(paramElement.get(0), Std.int(paramElement.width()), 0);
                 e.dataTransfer.setDragImage(paramElement.get(0), Std.int(paramElement.width()), 0);
 
 
                 e.dataTransfer.setData("index", '${paramIndex}');
                 e.dataTransfer.setData("index", '${paramIndex}');
+                e.dataTransfer.dropEffect = "move";
+                trace("Dragstart", e.dataTransfer.getData("index"));
             }
             }
 
 
+            inline function isAfter(e) {
+                return e.clientY > (paramElement.offset().top + paramElement.outerHeight() / 2.0);
+            }
+
+            paramElement.get(0).addEventListener("dragover", function(e : js.html.DragEvent) {
+                if (!e.dataTransfer.types.contains("index"))
+                    return;
+                var after = isAfter(e);
+                paramElement.toggleClass("hovertop", !after);
+                paramElement.toggleClass("hoverbot", after);
+                e.preventDefault();
+            });
+
+            paramElement.get(0).addEventListener("dragleave", function(e : js.html.DragEvent) {
+                if (!e.dataTransfer.types.contains("index"))
+                    return;
+                paramElement.toggleClass("hovertop", false);
+                paramElement.toggleClass("hoverbot", false);
+            });
+
+            paramElement.get(0).addEventListener("dragenter", function(e : js.html.DragEvent) {
+                if (!e.dataTransfer.types.contains("index"))
+                    return;
+                e.preventDefault();
+            });
+
+            paramElement.get(0).addEventListener("drop", function(e : js.html.DragEvent) {
+                var toMoveIndex = Std.parseInt(e.dataTransfer.getData("index"));
+                paramElement.toggleClass("hovertop", false);
+                paramElement.toggleClass("hoverbot", false);
+                if (paramIndex == null)
+                    return;
+                var after = isAfter(e);
+                execMoveParameterTo(toMoveIndex, paramIndex, after);
+            });
+
+
             var content = new Element("<content></content>").appendTo(paramElement);
             var content = new Element("<content></content>").appendTo(paramElement);
             var props = new Element("<ul>").appendTo(content);
             var props = new Element("<ul>").appendTo(content);
             if (previewAnimation != null) {
             if (previewAnimation != null) {
@@ -157,14 +202,68 @@ class AnimGraphEditor extends GenericGraphEditor {
                 var range = new hide.comp.Range(null,def);
                 var range = new hide.comp.Range(null,def);
                 range.setOnChangeUndo(undo, () -> param.defaultValue, (v:Float) -> param.defaultValue = v);
                 range.setOnChangeUndo(undo, () -> param.defaultValue, (v:Float) -> param.defaultValue = v);
             }
             }
+
+            paramElement.find("header").get(0).addEventListener("contextmenu", function (e : js.html.MouseEvent) {
+                e.preventDefault();
+                hide.comp.ContextMenu.createFromEvent(e, [
+                    {label: "Delete", click: () -> execRemoveParam(paramIndex)}
+                ]);
+            });
+
+            var menu = paramElement.find(".menu");
+            menu.on("click", (e) -> {
+                e.preventDefault();
+                hide.comp.ContextMenu.createDropdown(menu.get(0), [
+                    {label: "Delete", click: () -> execRemoveParam(paramIndex)}
+                ]);
+            });
+        }
+    }
+
+    function execRemoveParam(index: Int) {
+        var save = @:privateAccess animGraph.parameters[index].copyToDynamic({});
+        function exec(isUndo : Bool) {
+            if (!isUndo) {
+                animGraph.parameters.splice(index, 1);
+            } else {
+                var param = new hrt.animgraph.AnimGraph.Parameter();
+                @:privateAccess param.copyFromDynamic(save);
+                animGraph.parameters.insert(index, param);
+            }
+            refreshPamamList();
         }
         }
+        exec(false);
+        undo.change(Custom(exec));
     }
     }
 
 
+    function execMoveParameterTo(oldIndex: Int, newIndex: Int, after: Bool) {
+        if (!after) newIndex -= 1;
+		if (oldIndex == newIndex)
+			return;
+        if (newIndex < oldIndex) {
+            newIndex += 1;
+        }
+
+		function exec(isUndo: Bool) {
+            if (!isUndo) {
+                var param = animGraph.parameters.splice(oldIndex, 1)[0];
+                animGraph.parameters.insert(newIndex, param);
+            } else {
+                var param = animGraph.parameters.splice(newIndex, 1)[0];
+                animGraph.parameters.insert(oldIndex, param);
+            }
+            refreshPamamList();
+		}
+		exec(false);
+		undo.change(Custom(exec));
+	}
+
     override function getDefaultContent() : haxe.io.Bytes {
     override function getDefaultContent() : haxe.io.Bytes {
         @:privateAccess return haxe.io.Bytes.ofString(ide.toJSON(new hrt.animgraph.AnimGraph(null, null).serialize()));
         @:privateAccess return haxe.io.Bytes.ofString(ide.toJSON(new hrt.animgraph.AnimGraph(null, null).serialize()));
     }
     }
 
 
     override function save() {
     override function save() {
+        js.Browser.document.activeElement.blur();
         var content = ide.toJSON(animGraph.save());
         var content = ide.toJSON(animGraph.save());
         currentSign = ide.makeSignature(content);
         currentSign = ide.makeSignature(content);
 		sys.io.File.saveContent(getPath(), content);
 		sys.io.File.saveContent(getPath(), content);
@@ -290,14 +389,14 @@ class AnimGraphEditor extends GenericGraphEditor {
         var inputNode = animGraph.getNodeByEditorId(edge.nodeToId);
         var inputNode = animGraph.getNodeByEditorId(edge.nodeToId);
         inputNode.inputEdges[edge.inputToId] = {target: animGraph.getNodeByEditorId(edge.nodeFromId), outputIndex: edge.outputFromId};
         inputNode.inputEdges[edge.inputToId] = {target: animGraph.getNodeByEditorId(edge.nodeFromId), outputIndex: edge.outputFromId};
 
 
-        setPreview(previewNode);
+        refreshPreview();
     }
     }
 
 
     override function removeEdge(nodeToId: Int, inputToId : Int) : Void {
     override function removeEdge(nodeToId: Int, inputToId : Int) : Void {
         var inputNode = animGraph.getNodeByEditorId(nodeToId);
         var inputNode = animGraph.getNodeByEditorId(nodeToId);
         inputNode.inputEdges[inputToId] = null;
         inputNode.inputEdges[inputToId] = null;
 
 
-        setPreview(previewNode);
+        refreshPreview();
     }
     }
 
 
     override function onScenePreviewUpdate(dt:Float) {
     override function onScenePreviewUpdate(dt:Float) {