// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using FlaxEditor.Gizmo; using FlaxEditor.GUI.Tree; using FlaxEditor.SceneGraph; using FlaxEditor.SceneGraph.GUI; using FlaxEditor.Viewport.Cameras; using FlaxEngine; namespace FlaxEditor.Windows.Assets { public sealed partial class PrefabWindow { /// /// The current selection (readonly). /// public readonly List Selection = new List(); /// /// Occurs when selection gets changed. /// public event Action SelectionChanged; private void OnTreeSelectedChanged(List before, List after) { // Check if lock events if (_isUpdatingSelection) return; if (after.Count > 0) { // Get actors from nodes var actors = new List(after.Count); for (int i = 0; i < after.Count; i++) { if (after[i] is ActorTreeNode node && node.Actor) actors.Add(node.ActorNode); } // Select Select(actors); } else { // Deselect Deselect(); } } /// /// Called when selection gets changed. /// /// The selection before the change. public void OnSelectionChanged(SceneGraphNode[] before) { Undo.AddAction(new SelectionChangeAction(before, Selection.ToArray(), OnSelectionUndo)); OnSelectionChanges(); } private void OnSelectionUndo(SceneGraphNode[] toSelect) { Selection.Clear(); Selection.AddRange(toSelect); OnSelectionChanges(); } private void OnSelectionChanges() { _isUpdatingSelection = true; // Update tree var selection = Selection; if (selection.Count == 0) { _tree.Deselect(); } else { // Find nodes to select var nodes = new List(selection.Count); for (int i = 0; i < selection.Count; i++) { if (selection[i] is ActorNode node) { nodes.Add(node.TreeNode); } } // Select nodes _tree.Select(nodes); // For single node selected scroll view so user can see it if (nodes.Count == 1) { nodes[0].ExpandAllParents(true); ScrollViewTo(nodes[0]); } } // Update properties editor var objects = Selection.ConvertAll(x => x.EditableObject).Distinct(); _propertiesEditor.Select(objects); _isUpdatingSelection = false; // Send event SelectionChanged?.Invoke(); } /// /// Selects the specified nodes collection. /// /// The nodes. public void Select(List nodes) { if (nodes == null || nodes.Count == 0) { Deselect(); return; } if (Utils.ArraysEqual(Selection, nodes)) return; var before = Selection.ToArray(); Selection.Clear(); Selection.AddRange(nodes); OnSelectionChanged(before); } /// /// Selects the specified node. /// /// The node. /// if set to true will use additive mode, otherwise will clear previous selection. public void Select(SceneGraphNode node, bool additive = false) { if (node == null) { Deselect(); return; } // Check if won't change if (!additive && Selection.Count == 1 && Selection[0] == node) return; if (additive && Selection.Contains(node)) return; var before = Selection.ToArray(); if (!additive) Selection.Clear(); Selection.Add(node); OnSelectionChanged(before); } /// /// Deselects the specified node. /// public void Deselect(SceneGraphNode node) { if (!Selection.Contains(node)) return; var before = Selection.ToArray(); Selection.Remove(node); OnSelectionChanged(before); } /// /// Clears the selection. /// public void Deselect() { if (Selection.Count == 0) return; var before = Selection.ToArray(); Selection.Clear(); OnSelectionChanged(before); } } }