diff --git a/Content/Shaders/Editor/Grid.flax b/Content/Shaders/Editor/Grid.flax index 311867604..09ecd00e6 100644 --- a/Content/Shaders/Editor/Grid.flax +++ b/Content/Shaders/Editor/Grid.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c13729c4ec2ef534271c60fee6fff2e0489bf4445fe91aa8a2bbc3d581715602 -size 4666 +oid sha256:e5671b8b77b460a17d0a3c14174994a05cf1b3d8869d10b350de4a8053419836 +size 4647 diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index c6ead7a76..8c3256eb9 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -670,6 +670,8 @@ namespace FlaxEditor { FlaxEngine.Networking.NetworkManager.Stop(); // Shutdown any multiplayer from playmode PlayModeEnding?.Invoke(); + for (int i = 0; i < _modules.Count; i++) + _modules[i].OnPlayEnding(); } internal void OnPlayEnd() diff --git a/Source/Editor/GUI/AssetPicker.cs b/Source/Editor/GUI/AssetPicker.cs index b3690e754..bf04aa068 100644 --- a/Source/Editor/GUI/AssetPicker.cs +++ b/Source/Editor/GUI/AssetPicker.cs @@ -299,6 +299,7 @@ namespace FlaxEditor.GUI { // Select asset Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem); + Editor.Instance.Windows.ContentWin.ClearItemsSearch(); } } else if (Button1Rect.Contains(location)) @@ -312,6 +313,7 @@ namespace FlaxEditor.GUI { // Select asset Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem); + Editor.Instance.Windows.ContentWin.ClearItemsSearch(); } else if (Button3Rect.Contains(location)) { diff --git a/Source/Editor/GUI/Tree/Tree.cs b/Source/Editor/GUI/Tree/Tree.cs index e36f0ccd5..8df26c211 100644 --- a/Source/Editor/GUI/Tree/Tree.cs +++ b/Source/Editor/GUI/Tree/Tree.cs @@ -73,6 +73,11 @@ namespace FlaxEditor.GUI.Tree /// public bool DrawRootTreeLine = true; + /// + /// Occurs when the deferred layout operation was performed. + /// + public event Action AfterDeferredLayout; + /// /// Gets or sets the margin for the child tree nodes. /// @@ -375,6 +380,7 @@ namespace FlaxEditor.GUI.Tree if (_deferLayoutUpdate) { base.PerformLayout(); + AfterDeferredLayout?.Invoke(); _deferLayoutUpdate = false; } diff --git a/Source/Editor/Modules/EditorModule.cs b/Source/Editor/Modules/EditorModule.cs index 8285088fa..410453302 100644 --- a/Source/Editor/Modules/EditorModule.cs +++ b/Source/Editor/Modules/EditorModule.cs @@ -76,6 +76,13 @@ namespace FlaxEditor.Modules { } + /// + /// Called when Editor will leave the play mode. + /// + public virtual void OnPlayEnding() + { + } + /// /// Called when Editor leaves the play mode. /// diff --git a/Source/Editor/Modules/WindowsModule.cs b/Source/Editor/Modules/WindowsModule.cs index ad680a4af..3e7ce2d9f 100644 --- a/Source/Editor/Modules/WindowsModule.cs +++ b/Source/Editor/Modules/WindowsModule.cs @@ -1226,6 +1226,13 @@ namespace FlaxEditor.Modules Windows[i].OnPlayBegin(); } + /// + public override void OnPlayEnding() + { + for (int i = 0; i < Windows.Count; i++) + Windows[i].OnPlayEnding(); + } + /// public override void OnPlayEnd() { diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 8a42a7a92..5dedd604f 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -912,7 +912,7 @@ namespace FlaxEditor.Surface /// public override bool OnTestTooltipOverControl(ref Float2 location) { - return _headerRect.Contains(ref location) && ShowTooltip; + return _headerRect.Contains(ref location) && ShowTooltip && !Surface.IsConnecting && !Surface.IsBoxSelecting; } /// @@ -1070,7 +1070,7 @@ namespace FlaxEditor.Surface // Header var headerColor = style.BackgroundHighlighted; - if (_headerRect.Contains(ref _mousePosition)) + if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsBoxSelecting) headerColor *= 1.07f; Render2D.FillRectangle(_headerRect, headerColor); Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center); @@ -1078,7 +1078,8 @@ namespace FlaxEditor.Surface // Close button if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit) { - Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey); + bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsBoxSelecting; + Render2D.DrawSprite(style.Cross, _closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey); } // Footer @@ -1123,8 +1124,9 @@ namespace FlaxEditor.Surface if (base.OnMouseUp(location, button)) return true; - // Close - if (button == MouseButton.Left && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(ref location)) + // Close/ delete + bool canDelete = !Surface.IsConnecting && !Surface.WasBoxSelecting && !Surface.WasMovingSelection; + if (button == MouseButton.Left && canDelete && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(ref location)) { Surface.Delete(this); return true; diff --git a/Source/Editor/Surface/VisjectSurface.Draw.cs b/Source/Editor/Surface/VisjectSurface.Draw.cs index 5a63fe4de..01277d0d2 100644 --- a/Source/Editor/Surface/VisjectSurface.Draw.cs +++ b/Source/Editor/Surface/VisjectSurface.Draw.cs @@ -225,7 +225,7 @@ namespace FlaxEditor.Surface _rootControl.DrawComments(); - if (IsSelecting) + if (IsBoxSelecting) { DrawSelection(); } diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs index 09df195eb..63dfa063d 100644 --- a/Source/Editor/Surface/VisjectSurface.Input.cs +++ b/Source/Editor/Surface/VisjectSurface.Input.cs @@ -590,6 +590,9 @@ namespace FlaxEditor.Surface // Cache flags and state if (_leftMouseDown && button == MouseButton.Left) { + WasBoxSelecting = IsBoxSelecting; + WasMovingSelection = _isMovingSelection; + _leftMouseDown = false; EndMouseCapture(); Cursor = CursorType.Default; diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index 1683b6398..1201318d8 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -232,15 +232,25 @@ namespace FlaxEditor.Surface } /// - /// Gets a value indicating whether user is selecting nodes. + /// Gets a value indicating whether user is box selecting nodes. /// - public bool IsSelecting => _leftMouseDown && !_isMovingSelection && _connectionInstigator == null; + public bool IsBoxSelecting => _leftMouseDown && !_isMovingSelection && _connectionInstigator == null; + + /// + /// Gets a value indicating whether user was previously box selecting nodes. + /// + public bool WasBoxSelecting { get; private set; } /// /// Gets a value indicating whether user is moving selected nodes. /// public bool IsMovingSelection => _leftMouseDown && _isMovingSelection && _connectionInstigator == null; + /// + /// Gets a value indicating whether user was previously moving selected nodes. + /// + public bool WasMovingSelection { get; private set; } + /// /// Gets a value indicating whether user is connecting nodes. /// diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Selection.cs b/Source/Editor/Windows/Assets/PrefabWindow.Selection.cs index 03e2a9652..6208aa7a1 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Selection.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Selection.cs @@ -97,10 +97,7 @@ namespace FlaxEditor.Windows.Assets // For single node selected scroll view so user can see it if (nodes.Count == 1) - { - nodes[0].ExpandAllParents(true); - ScrollViewTo(nodes[0]); - } + ScrollToSelectedNode(); } // Update properties editor diff --git a/Source/Editor/Windows/EditorWindow.cs b/Source/Editor/Windows/EditorWindow.cs index f61f5cce6..6d01432ba 100644 --- a/Source/Editor/Windows/EditorWindow.cs +++ b/Source/Editor/Windows/EditorWindow.cs @@ -219,6 +219,13 @@ namespace FlaxEditor.Windows { } + /// + /// Called when Editor will leave the play mode. + /// + public virtual void OnPlayEnding() + { + } + /// /// Called when Editor leaves the play mode. /// diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs index f852b63c4..4ae975cfe 100644 --- a/Source/Editor/Windows/SceneTreeWindow.cs +++ b/Source/Editor/Windows/SceneTreeWindow.cs @@ -33,6 +33,7 @@ namespace FlaxEditor.Windows private DragScriptItems _dragScriptItems; private DragHandlers _dragHandlers; private bool _isDropping = false; + private bool _forceScrollNodeToView = false; /// /// Scene tree panel. @@ -90,6 +91,15 @@ namespace FlaxEditor.Windows _tree.SelectedChanged += Tree_OnSelectedChanged; _tree.RightClick += OnTreeRightClick; _tree.Parent = _sceneTreePanel; + _tree.AfterDeferredLayout += () => + { + if (_forceScrollNodeToView) + { + _forceScrollNodeToView = false; + ScrollToSelectedNode(); + } + }; + headerPanel.Parent = this; // Setup input actions @@ -141,6 +151,16 @@ namespace FlaxEditor.Windows root.TreeNode.UpdateFilter(query); _tree.UnlockChildrenRecursive(); + + // When keep the selected nodes in a view + var nodeSelection = _tree.Selection; + if (nodeSelection.Count != 0) + { + var node = nodeSelection[nodeSelection.Count - 1]; + node.Expand(true); + _forceScrollNodeToView = true; + } + PerformLayout(); PerformLayout(); } diff --git a/Source/Editor/Windows/Search/ContentFinder.cs b/Source/Editor/Windows/Search/ContentFinder.cs index e4227e5c4..9118739b8 100644 --- a/Source/Editor/Windows/Search/ContentFinder.cs +++ b/Source/Editor/Windows/Search/ContentFinder.cs @@ -42,6 +42,7 @@ namespace FlaxEditor.Windows.Search if (value == _selectedItem || (value != null && !_matchedItems.Contains(value))) return; + // Restore the previous selected item to the non-selected color if (_selectedItem != null) { _selectedItem.BackgroundColor = Color.Transparent; @@ -54,6 +55,7 @@ namespace FlaxEditor.Windows.Search _selectedItem.BackgroundColor = Style.Current.BackgroundSelected; if (_matchedItems.Count > VisibleItemCount) { + _selectedItem.Focus(); _resultPanel.ScrollViewTo(_selectedItem, true); } } @@ -180,39 +182,17 @@ namespace FlaxEditor.Windows.Search switch (key) { case KeyboardKeys.ArrowDown: - { - if (_matchedItems.Count == 0) - return true; - int currentPos; - if (_selectedItem != null) - { - currentPos = _matchedItems.IndexOf(_selectedItem) + 1; - if (currentPos >= _matchedItems.Count) - currentPos--; - } - else - { - currentPos = 0; - } - SelectedItem = _matchedItems[currentPos]; - return true; - } case KeyboardKeys.ArrowUp: { if (_matchedItems.Count == 0) return true; - int currentPos; - if (_selectedItem != null) - { - currentPos = _matchedItems.IndexOf(_selectedItem) - 1; - if (currentPos < 0) - currentPos = 0; - } - else - { - currentPos = 0; - } - SelectedItem = _matchedItems[currentPos]; + + var focusedIndex = _matchedItems.IndexOf(_selectedItem); + int delta = key == KeyboardKeys.ArrowDown ? -1 : 1; + int nextIndex = Mathf.Wrap(focusedIndex - delta, 0, _matchedItems.Count - 1); + var nextItem = _matchedItems[nextIndex]; + + SelectedItem = nextItem; return true; } case KeyboardKeys.Return: @@ -234,6 +214,17 @@ namespace FlaxEditor.Windows.Search Hide(); return true; } + case KeyboardKeys.Backspace: + { + // Alow the user to quickly focus the searchbar + if (_searchBox != null && !_searchBox.IsFocused) + { + _searchBox.Focus(); + _searchBox.SelectAll(); + return true; + } + break; + } } return base.OnKeyDown(key); diff --git a/Source/Shaders/Editor/Grid.shader b/Source/Shaders/Editor/Grid.shader index f109ddd1a..45bb1ed90 100644 --- a/Source/Shaders/Editor/Grid.shader +++ b/Source/Shaders/Editor/Grid.shader @@ -3,7 +3,7 @@ // Ben Golus // https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#3e73 -#define USE_FORWARD true; +#define MIN_DERIV 0.00001f #include "./Flax/Common.hlsl" @@ -61,11 +61,6 @@ float remap(float origFrom, float origTo, float targetFrom, float targetTo, floa return lerp(targetFrom, targetTo, rel); } -float ddLength(float a) -{ - return length(float2(ddx(a), ddy(a))); -} - float GetLine(float pos, float scale, float thickness) { float lineWidth = thickness; @@ -73,7 +68,7 @@ float GetLine(float pos, float scale, float thickness) float2 uvDDXY = float2(ddx(coord), ddy(coord)); - float deriv = float(length(uvDDXY.xy)); + float deriv = max(float(length(uvDDXY.xy)), MIN_DERIV); float drawWidth = clamp(lineWidth, deriv, 0.5); float lineAA = deriv * 1.5; float gridUV = abs(coord); @@ -92,7 +87,7 @@ float GetGrid(float3 pos, float scale, float thickness) float4 uvDDXY = float4(ddx(coord), ddy(coord)); - float2 deriv = float2(length(uvDDXY.xz), length(uvDDXY.yw)); + float2 deriv = max(float2(length(uvDDXY.xz), length(uvDDXY.yw)), float2(MIN_DERIV, MIN_DERIV)); float2 drawWidth = clamp(lineWidth, deriv, 0.5); float2 lineAA = deriv * 1.5; float2 gridUV = 1.0 - abs(frac(coord) * 2.0 - 1.0);