diff --git a/Source/Editor/GUI/Tree/Tree.cs b/Source/Editor/GUI/Tree/Tree.cs index facc2c36d..5405a6f24 100644 --- a/Source/Editor/GUI/Tree/Tree.cs +++ b/Source/Editor/GUI/Tree/Tree.cs @@ -41,6 +41,7 @@ namespace FlaxEditor.GUI.Tree private Margin _margin; private bool _autoSize = true; private bool _deferLayoutUpdate = false; + private TreeNode _lastSelectedNode; /// /// The TreeNode that is being dragged over. This could have a value when not dragging. @@ -67,7 +68,7 @@ namespace FlaxEditor.GUI.Tree /// Gets the first selected node or null. /// public TreeNode SelectedNode => Selection.Count > 0 ? Selection[0] : null; - + /// /// Allow nodes to Draw the root tree line. /// @@ -392,20 +393,27 @@ namespace FlaxEditor.GUI.Tree { if (_deferLayoutUpdate) FlushPendingPerformLayout(); + var window = Root; + bool shiftDown = window.GetKey(KeyboardKeys.Shift); + bool keyUpArrow = window.GetKey(KeyboardKeys.ArrowUp); + bool keyDownArrow = window.GetKey(KeyboardKeys.ArrowDown); - var node = SelectedNode; + // Use last selection for last selected node if sift is down + if (shiftDown) + _lastSelectedNode ??= Selection[^1]; + + var node = _lastSelectedNode ?? SelectedNode; + + if (Selection.Count == 0) + _lastSelectedNode = null; // Check if has focus and if any node is focused and it isn't a root if (ContainsFocus && node != null && node.AutoFocus) { - var window = Root; if (window.GetKeyDown(KeyboardKeys.ArrowUp) || window.GetKeyDown(KeyboardKeys.ArrowDown)) _keyUpdateTime = KeyUpdateTimeout; if (_keyUpdateTime >= KeyUpdateTimeout && window is WindowRootControl windowRoot && windowRoot.Window.IsFocused) { - bool keyUpArrow = window.GetKey(KeyboardKeys.ArrowUp); - bool keyDownArrow = window.GetKey(KeyboardKeys.ArrowDown); - // Check if arrow flags are different if (keyDownArrow != keyUpArrow) { @@ -415,24 +423,38 @@ namespace FlaxEditor.GUI.Tree Assert.AreNotEqual(-1, myIndex); // Up - TreeNode toSelect = null; + List toSelect = new List(); + if (shiftDown && _supportMultiSelect) + { + toSelect.AddRange(Selection); + } if (keyUpArrow) { if (myIndex == 0) { // Select parent - toSelect = parentNode; + if (toSelect.Contains(parentNode)) + toSelect.Remove(node); + else + toSelect.Add(parentNode); + _lastSelectedNode = parentNode; } else { // Select previous parent child - toSelect = nodeParent.GetChild(myIndex - 1) as TreeNode; + var select = nodeParent.GetChild(myIndex - 1) as TreeNode; // Select last child if is valid and expanded and has any children - if (toSelect != null && toSelect.IsExpanded && toSelect.HasAnyVisibleChild) + if (select != null && select.IsExpanded && select.HasAnyVisibleChild) { - toSelect = toSelect.GetChild(toSelect.ChildrenCount - 1) as TreeNode; + select = select.GetChild(select.ChildrenCount - 1) as TreeNode; } + + if (toSelect.Contains(select)) + toSelect.Remove(node); + else + toSelect.Add(select); + _lastSelectedNode = select; } } // Down @@ -441,32 +463,48 @@ namespace FlaxEditor.GUI.Tree if (node.IsExpanded && node.HasAnyVisibleChild) { // Select the first child - toSelect = node.GetChild(0) as TreeNode; + var select = node.GetChild(0) as TreeNode; + if (toSelect.Contains(select)) + toSelect.Remove(node); + else + toSelect.Add(select); + _lastSelectedNode = select; } else if (myIndex == nodeParent.ChildrenCount - 1) { // Select next node after parent - while (parentNode != null && toSelect == null) + TreeNode select = null; + while (parentNode != null && select == null) { int parentIndex = parentNode.IndexInParent; if (parentIndex != -1 && parentIndex < parentNode.Parent.ChildrenCount - 1) { - toSelect = parentNode.Parent.GetChild(parentIndex + 1) as TreeNode; + select = parentNode.Parent.GetChild(parentIndex + 1) as TreeNode; } parentNode = parentNode.Parent as TreeNode; } + if (toSelect.Contains(select)) + toSelect.Remove(node); + else + toSelect.Add(select); + _lastSelectedNode = select; } else { // Select next parent child - toSelect = nodeParent.GetChild(myIndex + 1) as TreeNode; + var select = nodeParent.GetChild(myIndex + 1) as TreeNode; + if (toSelect.Contains(select)) + toSelect.Remove(node); + else + toSelect.Add(select); + _lastSelectedNode = select; } } - if (toSelect != null && toSelect.AutoFocus) + if (toSelect.Count > 0) { // Select Select(toSelect); - toSelect.Focus(); + _lastSelectedNode?.Focus(); } // Reset time