Browse Source

Support dragging prefabs/mesh/shgraphs onto the sceneTree now

Clément Espeute 11 months ago
parent
commit
6847cfacd0
3 changed files with 66 additions and 41 deletions
  1. 16 0
      hide/comp/IconTree.hx
  2. 48 39
      hide/comp/SceneEditor.hx
  3. 2 2
      hide/view/FXEditor.hx

+ 16 - 0
hide/comp/IconTree.hx

@@ -276,6 +276,22 @@ class IconTree<T:{}> extends Component {
 		return i == null ? null : getValue(i);
 		return i == null ? null : getValue(i);
 	}
 	}
 
 
+	public function getCurrentHover() : Null<T> {
+		var elem = element.get(0).querySelectorAll(".jstree-anchor");
+		var id = null;
+		for (e in elem) {
+			if (untyped e.matches(":hover")) {
+				id = untyped e.id;
+				break;
+			}
+		}
+		if( id == null )
+			return null;
+		var trueId = StringTools.replace(id, "_anchor", "");
+		var i = map.get(trueId);
+		return i == null ? null : getValue(i);
+	}
+
 	public function setSelection( objects : Array<T> ) {
 	public function setSelection( objects : Array<T> ) {
 		(element:Dynamic).jstree('deselect_all');
 		(element:Dynamic).jstree('deselect_all');
 		var ids = [for( o in objects ) { var v = getRev(o); if( v != null ) v.id; }];
 		var ids = [for( o in objects ) { var v = getRev(o); if( v != null ) v.id; }];

+ 48 - 39
hide/comp/SceneEditor.hx

@@ -3435,56 +3435,67 @@ class SceneEditor {
 		return true;
 		return true;
 	}
 	}
 
 
-	function createDroppedElement(path: String, parent: PrefabElement) : Array<hrt.prefab.Prefab> {
+	function createDroppedElement(path: String, defaultParent: PrefabElement) : hrt.prefab.Prefab {
 		var prefab : hrt.prefab.Prefab = null;
 		var prefab : hrt.prefab.Prefab = null;
 		var relative = ide.makeRelative(path);
 		var relative = ide.makeRelative(path);
 
 
 		var ptype = hrt.prefab.Prefab.getPrefabType(path);
 		var ptype = hrt.prefab.Prefab.getPrefabType(path);
+		var hover = tree.getCurrentHover();
+		var parent = hover ?? defaultParent;
+		var index = 0;
+		if (parent == defaultParent) {
+			index = defaultParent.children.length;
+		}
 		if (ptype == "shgraph") {
 		if (ptype == "shgraph") {
-			var parents : Map<hrt.prefab.Prefab, Bool> = [];
-			for (parent in selectedPrefabs) {
-				var p = parent;
-				while (p != null && Std.downcast(p, Object3D) == null && Std.downcast(p, Object2D) == null) {
-					p = p.parent;
-				}
-				parents.set(p, true);
-			}
-
-			var prefabs : Array<hrt.prefab.Prefab> = [];
-			if (parents.iterator().hasNext() == false) {
-				ide.quickMessage("Please select (valid) prefabs that should recieve the shadergraph before dragging the shadergraph into the scene");
+			var p = parent;
+			while (p != null && Std.downcast(p, Object3D) == null && Std.downcast(p, Object2D) == null && Std.downcast(p, hrt.prefab.Material) == null) {
+				index = (p.parent?.children.indexOf(p) ?? 0 ) + 1;
+				p = p.parent;
 			}
 			}
-			for (parent => _ in parents) {
-				var shgraph = new hrt.prefab.DynamicShader(parent, null);
-				shgraph.source = relative;
-				shgraph.name = new haxe.io.Path(relative).file;
-				prefabs.push(shgraph);
+			parent = p;
+			if (parent == null) {
+				ide.quickError("Please drop the shadergraph on a valid parent in the scene tree");
+				return null;
 			}
 			}
-			return prefabs;
+
+			var shgraph = new hrt.prefab.DynamicShader(null, null);
+			shgraph.source = relative;
+			shgraph.name = new haxe.io.Path(relative).file;
+			prefab = shgraph;
 		}
 		}
 		else if(ptype != null) {
 		else if(ptype != null) {
-			var ref = new hrt.prefab.Reference(parent, null);
+			var ref = new hrt.prefab.Reference(null, null);
 			ref.source = relative;
 			ref.source = relative;
-			if (ref.hasCycle()) {
-				parent.children.remove(ref);
-				hide.Ide.inst.quickError('Reference to $relative is creating a cycle. The reference creation was aborted.');
-				return null;
-			}
 
 
 			prefab = ref;
 			prefab = ref;
 			prefab.name = new haxe.io.Path(relative).file;
 			prefab.name = new haxe.io.Path(relative).file;
 		}
 		}
 		else if(haxe.io.Path.extension(path).toLowerCase() == "json") {
 		else if(haxe.io.Path.extension(path).toLowerCase() == "json") {
-			prefab = new hrt.prefab.l3d.Particles3D(parent, null);
+			prefab = new hrt.prefab.l3d.Particles3D(null, null);
 			prefab.source = relative;
 			prefab.source = relative;
 			prefab.name = new haxe.io.Path(relative).file;
 			prefab.name = new haxe.io.Path(relative).file;
 		}
 		}
 		else {
 		else {
-			var model = new hrt.prefab.Model(parent, null);
+			var model = new hrt.prefab.Model(null, null);
 			model.source = relative;
 			model.source = relative;
 			prefab = model;
 			prefab = model;
 		}
 		}
-		return [prefab];
+
+		if (prefab == null)
+			return null;
+
+		prefab.parent = parent;
+		parent.children.remove(prefab);
+		parent.children.insert(index, prefab);
+
+		var ref = Std.downcast(prefab, Reference);
+		if (ref != null && (ref.hasCycle() || ref.source == @:privateAccess view.state.path) ) {
+			parent.children.remove(ref);
+			hide.Ide.inst.quickError('Reference to $relative is creating a cycle. The reference creation was aborted.');
+			return null;
+		}
+
+		return prefab;
 	}
 	}
 
 
 	function dropElements(paths: Array<String>, parent: PrefabElement) {
 	function dropElements(paths: Array<String>, parent: PrefabElement) {
@@ -3502,18 +3513,16 @@ class SceneEditor {
 
 
 		var elts: Array<PrefabElement> = [];
 		var elts: Array<PrefabElement> = [];
 		for(path in paths) {
 		for(path in paths) {
-			var prefabs = createDroppedElement(path, parent);
-			for (prefab in prefabs) {
-				if (prefab == null) {
-					continue;
-				}
-				var obj3d= Std.downcast(prefab, Object3D);
-				if (obj3d != null) {
-					obj3d.setTransform(localMat);
-				}
-				autoName(prefab);
-				elts.push(prefab);
+			var prefab = createDroppedElement(path, parent);
+			if (prefab == null) {
+				return;
+			}
+			var obj3d= Std.downcast(prefab, Object3D);
+			if (obj3d != null) {
+				obj3d.setTransform(localMat);
 			}
 			}
+			autoName(prefab);
+			elts.push(prefab);
 		}
 		}
 
 
 		beginRebuild();
 		beginRebuild();

+ 2 - 2
hide/view/FXEditor.hx

@@ -103,14 +103,14 @@ private class FXSceneEditor extends hide.comp.SceneEditor {
 		}
 		}
 	}
 	}
 
 
-	override function createDroppedElement(path:String, parent:PrefabElement): Array<hrt.prefab.Prefab> {
+	override function createDroppedElement(path:String, parent:PrefabElement): hrt.prefab.Prefab {
 		var type = hrt.prefab.Prefab.getPrefabType(path);
 		var type = hrt.prefab.Prefab.getPrefabType(path);
 		if(type == "fx") {
 		if(type == "fx") {
 			var relative = ide.makeRelative(path);
 			var relative = ide.makeRelative(path);
 			var ref = new hrt.prefab.fx.SubFX(parent, null);
 			var ref = new hrt.prefab.fx.SubFX(parent, null);
 			ref.source = relative;
 			ref.source = relative;
 			ref.name = new haxe.io.Path(relative).file;
 			ref.name = new haxe.io.Path(relative).file;
-			return [ref];
+			return ref;
 		}
 		}
 		return super.createDroppedElement(path, parent);
 		return super.createDroppedElement(path, parent);
 	}
 	}