diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs index 25c063372..1236e22b5 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs @@ -2,9 +2,12 @@ using System; using System.Collections.Generic; +using FlaxEditor.Content; using FlaxEditor.GUI.ContextMenu; +using FlaxEditor.GUI.Drag; using FlaxEditor.GUI.Tree; using FlaxEditor.SceneGraph; +using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.GUI; @@ -56,6 +59,129 @@ namespace FlaxEditor.Windows.Assets } } + private class SceneTreePanel : Panel + { + private PrefabWindow _window; + private DragAssets _dragAssets; + private DragActorType _dragActorType; + private DragHandlers _dragHandlers; + + public SceneTreePanel(PrefabWindow window) + : base(ScrollBars.Vertical) + { + _window = window; + Offsets = Margin.Zero; + AnchorPreset = AnchorPresets.StretchAll; + } + + private bool ValidateDragAsset(AssetItem assetItem) + { + return assetItem.OnEditorDrag(this); + } + + private static bool ValidateDragActorType(ScriptType actorType) + { + return true; + } + + /// + public override DragDropEffect OnDragEnter(ref Vector2 location, DragData data) + { + var result = base.OnDragEnter(ref location, data); + if (result == DragDropEffect.None) + { + if (_dragHandlers == null) + _dragHandlers = new DragHandlers(); + if (_dragAssets == null) + { + _dragAssets = new DragAssets(ValidateDragAsset); + _dragHandlers.Add(_dragAssets); + } + if (_dragAssets.OnDragEnter(data)) + return _dragAssets.Effect; + if (_dragActorType == null) + { + _dragActorType = new DragActorType(ValidateDragActorType); + _dragHandlers.Add(_dragActorType); + } + if (_dragActorType.OnDragEnter(data)) + return _dragActorType.Effect; + } + return result; + } + + /// + public override DragDropEffect OnDragMove(ref Vector2 location, DragData data) + { + var result = base.OnDragMove(ref location, data); + if (result == DragDropEffect.None) + { + result = _dragHandlers.Effect; + } + return result; + } + + /// + public override void OnDragLeave() + { + base.OnDragLeave(); + + _dragHandlers?.OnDragLeave(); + } + + /// + public override DragDropEffect OnDragDrop(ref Vector2 location, DragData data) + { + var result = base.OnDragDrop(ref location, data); + if (result == DragDropEffect.None) + { + // Drag assets + if (_dragAssets != null && _dragAssets.HasValidDrag) + { + for (int i = 0; i < _dragAssets.Objects.Count; i++) + { + var item = _dragAssets.Objects[i]; + var actor = item.OnEditorDrop(this); + actor.Name = item.ShortName; + _window.Spawn(actor); + } + result = DragDropEffect.Move; + } + // Drag actor type + else if (_dragActorType != null && _dragActorType.HasValidDrag) + { + for (int i = 0; i < _dragActorType.Objects.Count; i++) + { + var item = _dragActorType.Objects[i]; + var actor = item.CreateInstance() as Actor; + if (actor == null) + { + Editor.LogWarning("Failed to spawn actor of type " + item.TypeName); + continue; + } + actor.Name = item.Name; + _window.Spawn(actor); + } + result = DragDropEffect.Move; + } + + _dragHandlers.OnDragDrop(null); + } + return result; + } + + public override void OnDestroy() + { + _window = null; + _dragAssets = null; + _dragActorType = null; + _dragHandlers?.Clear(); + _dragHandlers = null; + + base.OnDestroy(); + } + } + /// /// Occurs when prefab hierarchy panel wants to show the context menu. Allows to add custom options. Applies to all prefab windows. /// diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index 9c484d9d4..474f73372 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -94,13 +94,17 @@ namespace FlaxEditor.Windows.Assets _undo.ActionDone += OnUndoEvent; // Split Panel 1 - _split1 = new SplitPanel(Orientation.Horizontal, ScrollBars.Both, ScrollBars.None) + _split1 = new SplitPanel(Orientation.Horizontal, ScrollBars.None, ScrollBars.None) { AnchorPreset = AnchorPresets.StretchAll, Offsets = new Margin(0, 0, _toolstrip.Bottom, 0), SplitterValue = 0.2f, Parent = this }; + var sceneTreePanel = new SceneTreePanel(this) + { + Parent = _split1.Panel1, + }; // Split Panel 2 _split2 = new SplitPanel(Orientation.Horizontal, ScrollBars.None, ScrollBars.Vertical) @@ -117,7 +121,7 @@ namespace FlaxEditor.Windows.Assets AnchorPreset = AnchorPresets.HorizontalStretchTop, IsScrollable = true, Offsets = new Margin(0, 0, 0, 18 + 6), - Parent = _split1.Panel1, + Parent = sceneTreePanel, }; _searchBox = new TextBox { @@ -138,7 +142,7 @@ namespace FlaxEditor.Windows.Assets _tree.AddChild(Graph.Root.TreeNode); _tree.SelectedChanged += OnTreeSelectedChanged; _tree.RightClick += OnTreeRightClick; - _tree.Parent = _split1.Panel1; + _tree.Parent = sceneTreePanel; // Prefab viewport _viewport = new PrefabWindowViewport(this) @@ -447,7 +451,7 @@ namespace FlaxEditor.Windows.Assets { _split1.SplitterValue = 0.2f; _split2.SplitterValue = 0.6f; - LiveReload = true; + LiveReload = false; } ///