From 1e61abdfefff2154be63e0ffc2e1b2f36603ff64 Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Wed, 11 Dec 2024 17:11:00 +0100 Subject: [PATCH 1/2] add highlight when actor reference is single clicked --- .../Editors/FlaxObjectRefEditor.cs | 24 ++++++++ Source/Editor/GUI/Tree/TreeNode.cs | 60 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs index fd367d21f..18953e88f 100644 --- a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs @@ -7,6 +7,7 @@ using FlaxEditor.CustomEditors.Elements; using FlaxEditor.GUI; using FlaxEditor.GUI.Drag; using FlaxEditor.SceneGraph; +using FlaxEditor.SceneGraph.GUI; using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.GUI; @@ -300,7 +301,30 @@ namespace FlaxEditor.CustomEditors.Editors // Picker dropdown menu if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location)) + { ShowDropDownMenu(); + return true; + } + + if (button == MouseButton.Left) + { + + _isMouseDown = false; + + if (Value is Actor a && !_hasValidDragOver) + { + ActorTreeNode treeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; + treeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(treeNode, true); + treeNode.StartHighlight(); + return true; + } + + if (Value is Script s && !IsDragOver && !_hasValidDragOver) + { + // TODO: Highlight scripts when Value is a script + } + } return base.OnMouseUp(location, button); } diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs index 9bb9d2038..7059266c4 100644 --- a/Source/Editor/GUI/Tree/TreeNode.cs +++ b/Source/Editor/GUI/Tree/TreeNode.cs @@ -23,10 +23,17 @@ namespace FlaxEditor.GUI.Tree /// public const float DefaultNodeOffsetY = 0; + private const float _targetHighlightScale = 1.25f; + private const float _highlightScaleAnimDuration = 0.85f; + private Tree _tree; private bool _opened, _canChangeOrder; private float _animationProgress, _cachedHeight; + private bool _isHightlighted; + private float _targetHighlightTimeSec; + private float _currentHighlightTimeSec; + private float _highlightScale; private bool _mouseOverArrow, _mouseOverHeader; private float _xOffset, _textWidth; private float _headerHeight = 16.0f; @@ -605,9 +612,44 @@ namespace FlaxEditor.GUI.Tree } } + /// + /// Adds a box around the text to highlight the node. + /// + /// The duration of the highlight in seconds. + public void StartHighlight(float durationSec = 3) + { + _isHightlighted = true; + _targetHighlightTimeSec = durationSec; + _currentHighlightTimeSec = 0; + _highlightScale = 2f; + } + + /// + /// Stops any current highlight. + /// + public void StopHighlight() + { + _isHightlighted = false; + _targetHighlightTimeSec = 0; + _currentHighlightTimeSec = 0; + } + /// public override void Update(float deltaTime) { + // Highlight animations + if (_isHightlighted) + { + _currentHighlightTimeSec += deltaTime; + + // In the first second, animate the highlight to shrink into it's resting position + if (_currentHighlightTimeSec < _highlightScaleAnimDuration) + _highlightScale = Mathf.Lerp(_highlightScale, _targetHighlightScale, _currentHighlightTimeSec); + + if (_currentHighlightTimeSec >= _targetHighlightTimeSec) + _isHightlighted = false; + } + // Drop/down animation if (_animationProgress < 1.0f) { @@ -676,6 +718,18 @@ namespace FlaxEditor.GUI.Tree textRect.Width -= 18.0f; } + float textWidth = TextFont.GetFont().MeasureText(_text).X; + Rectangle trueTextRect = textRect; + trueTextRect.Width = textWidth; + trueTextRect.Scale(_highlightScale); + + if (_isHightlighted) + { + Color highlightBackgroundColor = Editor.Instance.Options.Options.Visual.HighlightColor; + highlightBackgroundColor = highlightBackgroundColor.AlphaMultiplied(0.3f); + Render2D.FillRectangle(trueTextRect, highlightBackgroundColor); + } + // Draw text Color textColor = CacheTextColor(); Render2D.DrawText(TextFont.GetFont(), _text, textRect, textColor, TextAlignment.Near, TextAlignment.Center); @@ -730,6 +784,12 @@ namespace FlaxEditor.GUI.Tree } } + if (_isHightlighted) + { + // Draw highlights + Render2D.DrawRectangle(trueTextRect, Editor.Instance.Options.Options.Visual.HighlightColor, 3); + } + // Base if (_opened) { From 99e836b1fb6a2349c4e4f568d77baa9a9e305af5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Wed, 11 Dec 2024 20:43:52 -0600 Subject: [PATCH 2/2] Fix valid drop not resetting, add debounce timer to highlighting for showing on double click prevention --- .../Editors/FlaxObjectRefEditor.cs | 46 ++++++++++++++++--- Source/Editor/GUI/Tree/TreeNode.cs | 9 +++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs index 18953e88f..908aba278 100644 --- a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs @@ -24,6 +24,7 @@ namespace FlaxEditor.CustomEditors.Editors public class FlaxObjectRefPickerControl : Control { private ScriptType _type; + private ActorTreeNode _linkedTreeNode; private Object _value; private string _valueName; private bool _supportsPickDropDown; @@ -308,22 +309,50 @@ namespace FlaxEditor.CustomEditors.Editors if (button == MouseButton.Left) { - _isMouseDown = false; - + // Highlight actor reference. if (Value is Actor a && !_hasValidDragOver) { - ActorTreeNode treeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; - treeNode.ExpandAllParents(); - Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(treeNode, true); - treeNode.StartHighlight(); + if (_linkedTreeNode != null && _linkedTreeNode.Actor == a) + { + _linkedTreeNode.ExpandAllParents(); + _linkedTreeNode.StartHighlight(); + } + else + { + _linkedTreeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; + _linkedTreeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); + _linkedTreeNode.StartHighlight(); + } return true; } + // Highlight actor with script reference. if (Value is Script s && !IsDragOver && !_hasValidDragOver) { - // TODO: Highlight scripts when Value is a script + var scriptActor = s.Actor; + if (scriptActor != null) + { + if (_linkedTreeNode != null && _linkedTreeNode.Actor == scriptActor) + { + _linkedTreeNode.ExpandAllParents(); + _linkedTreeNode.StartHighlight(); + } + else + { + _linkedTreeNode = Editor.Instance.Scene.GetActorNode(scriptActor).TreeNode; + _linkedTreeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); + _linkedTreeNode.StartHighlight(); + } + return true; + } } + + // Reset valid drag over if still true at this point. + if (_hasValidDragOver) + _hasValidDragOver = false; } return base.OnMouseUp(location, button); @@ -350,6 +379,8 @@ namespace FlaxEditor.CustomEditors.Editors // Check if has object selected if (_value != null) { + if (_linkedTreeNode != null) + _linkedTreeNode.StopHighlight(); // Select object if (_value is Actor actor) Editor.Instance.SceneEditing.Select(actor); @@ -493,6 +524,7 @@ namespace FlaxEditor.CustomEditors.Editors _value = null; _type = ScriptType.Null; _valueName = null; + _linkedTreeNode = null; base.OnDestroy(); } diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs index 7059266c4..90639cebc 100644 --- a/Source/Editor/GUI/Tree/TreeNode.cs +++ b/Source/Editor/GUI/Tree/TreeNode.cs @@ -33,6 +33,8 @@ namespace FlaxEditor.GUI.Tree private bool _isHightlighted; private float _targetHighlightTimeSec; private float _currentHighlightTimeSec; + // Used to prevent showing highlight on double mouse click + private float _debounceHighlightTime; private float _highlightScale; private bool _mouseOverArrow, _mouseOverHeader; private float _xOffset, _textWidth; @@ -621,6 +623,7 @@ namespace FlaxEditor.GUI.Tree _isHightlighted = true; _targetHighlightTimeSec = durationSec; _currentHighlightTimeSec = 0; + _debounceHighlightTime = 0; _highlightScale = 2f; } @@ -632,6 +635,7 @@ namespace FlaxEditor.GUI.Tree _isHightlighted = false; _targetHighlightTimeSec = 0; _currentHighlightTimeSec = 0; + _debounceHighlightTime = 0; } /// @@ -640,6 +644,7 @@ namespace FlaxEditor.GUI.Tree // Highlight animations if (_isHightlighted) { + _debounceHighlightTime += deltaTime; _currentHighlightTimeSec += deltaTime; // In the first second, animate the highlight to shrink into it's resting position @@ -723,7 +728,7 @@ namespace FlaxEditor.GUI.Tree trueTextRect.Width = textWidth; trueTextRect.Scale(_highlightScale); - if (_isHightlighted) + if (_isHightlighted && _debounceHighlightTime > 0.1f) { Color highlightBackgroundColor = Editor.Instance.Options.Options.Visual.HighlightColor; highlightBackgroundColor = highlightBackgroundColor.AlphaMultiplied(0.3f); @@ -784,7 +789,7 @@ namespace FlaxEditor.GUI.Tree } } - if (_isHightlighted) + if (_isHightlighted && _debounceHighlightTime > 0.1f) { // Draw highlights Render2D.DrawRectangle(trueTextRect, Editor.Instance.Options.Options.Visual.HighlightColor, 3);