diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
index f93e31957..8596ab83b 100644
--- a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
+++ b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
@@ -196,7 +196,6 @@ namespace FlaxEditor.GUI.ContextMenu
desc.HasSizingFrame = false;
OnWindowCreating(ref desc);
_window = Platform.CreateWindow(ref desc);
- _window.GotFocus += OnWindowGotFocus;
_window.LostFocus += OnWindowLostFocus;
// Attach to the window
@@ -326,48 +325,6 @@ namespace FlaxEditor.GUI.ContextMenu
// Nothing to do
}
- ///
- /// Returns true if context menu is in foreground (eg. context window or any child window has user focus or user opened additional popup within this context).
- ///
- protected virtual bool IsForeground
- {
- get
- {
- // Any external popup is focused
- foreach (var externalPopup in ExternalPopups)
- {
- if (externalPopup && externalPopup.IsForegroundWindow)
- return true;
- }
-
- // Any context menu window is focused
- var anyForeground = false;
- var c = this;
- while (!anyForeground && c != null)
- {
- if (c._window != null && c._window.IsForegroundWindow)
- anyForeground = true;
- c = c._childCM;
- }
-
- return anyForeground;
- }
- }
-
- private void OnWindowGotFocus()
- {
- var child = _childCM;
- if (child != null && _window && _window.IsForegroundWindow)
- {
- // Hide child if user clicked over parent (do it next frame to process other events before - eg. child windows focus loss)
- FlaxEngine.Scripting.InvokeOnUpdate(() =>
- {
- if (child == _childCM)
- HideChild();
- });
- }
- }
-
private void OnWindowLostFocus()
{
// Skip for parent menus (child should handle lost of focus)
@@ -377,13 +334,33 @@ namespace FlaxEditor.GUI.ContextMenu
// Check if user stopped using that popup menu
if (_parentCM != null)
{
- // Focus parent if user clicked over the parent popup
- var mouse = _parentCM.PointFromScreen(FlaxEngine.Input.MouseScreenPosition);
- if (_parentCM.ContainsPoint(ref mouse))
+ if (IsMouseOver)
+ return;
+
+ // Check if mouse is over any of the parents
+ ContextMenuBase focusCM = null;
+ var cm = _parentCM;
+ while (cm != null)
{
- _parentCM._window.Focus();
+ if (cm.IsMouseOver)
+ focusCM = cm;
+ cm = cm._parentCM;
+ }
+
+ if (focusCM != null)
+ {
+ // Focus on the clicked parent and hide any open sub-menus
+ focusCM.HideChild();
+ focusCM._window?.Focus();
+ }
+ else
+ {
+ // User clicked outside the context menus, hide the whole context menu tree
+ TopmostCM.Hide();
}
}
+ else if (!IsMouseOver)
+ Hide();
}
///
@@ -405,18 +382,6 @@ namespace FlaxEditor.GUI.ContextMenu
}
}
- ///
- public override void Update(float deltaTime)
- {
- base.Update(deltaTime);
-
- // Let root context menu to check if none of the popup windows
- if (_parentCM == null && !IsForeground)
- {
- Hide();
- }
- }
-
///
public override void Draw()
{
diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs
index 54aeedb9a..f2c8e2d6a 100644
--- a/Source/Editor/GUI/Tree/TreeNode.cs
+++ b/Source/Editor/GUI/Tree/TreeNode.cs
@@ -700,6 +700,8 @@ namespace FlaxEditor.GUI.Tree
///
public override bool OnMouseDown(Float2 location, MouseButton button)
{
+ UpdateMouseOverFlags(location);
+
// Check if mouse hits bar and node isn't a root
if (_mouseOverHeader)
{
@@ -728,6 +730,8 @@ namespace FlaxEditor.GUI.Tree
///
public override bool OnMouseUp(Float2 location, MouseButton button)
{
+ UpdateMouseOverFlags(location);
+
// Clear flag for left button
if (button == MouseButton.Left)
{
@@ -815,21 +819,7 @@ namespace FlaxEditor.GUI.Tree
///
public override void OnMouseMove(Float2 location)
{
- // Cache flags
- _mouseOverArrow = HasAnyVisibleChild && ArrowRect.Contains(location);
- _mouseOverHeader = new Rectangle(0, 0, Width, _headerHeight - 1).Contains(location);
- if (_mouseOverHeader)
- {
- // Allow non-scrollable controls to stay on top of the header and override the mouse behaviour
- for (int i = 0; i < Children.Count; i++)
- {
- if (!Children[i].IsScrollable && IntersectsChildContent(Children[i], location, out _))
- {
- _mouseOverHeader = false;
- break;
- }
- }
- }
+ UpdateMouseOverFlags(location);
// Check if start drag and drop
if (_isMouseDown && Float2.Distance(_mouseDownPos, location) > 10.0f)
@@ -852,6 +842,25 @@ namespace FlaxEditor.GUI.Tree
}
}
+ private void UpdateMouseOverFlags(Vector2 location)
+ {
+ // Cache flags
+ _mouseOverArrow = HasAnyVisibleChild && ArrowRect.Contains(location);
+ _mouseOverHeader = new Rectangle(0, 0, Width, _headerHeight - 1).Contains(location);
+ if (_mouseOverHeader)
+ {
+ // Allow non-scrollable controls to stay on top of the header and override the mouse behaviour
+ for (int i = 0; i < Children.Count; i++)
+ {
+ if (!Children[i].IsScrollable && IntersectsChildContent(Children[i], location, out _))
+ {
+ _mouseOverHeader = false;
+ break;
+ }
+ }
+ }
+ }
+
///
public override void OnMouseLeave()
{
diff --git a/Source/Engine/UI/GUI/Tooltip.cs b/Source/Engine/UI/GUI/Tooltip.cs
index 9180d6d58..5089e0211 100644
--- a/Source/Engine/UI/GUI/Tooltip.cs
+++ b/Source/Engine/UI/GUI/Tooltip.cs
@@ -179,6 +179,8 @@ namespace FlaxEngine.GUI
/// The target.
public void OnMouseLeaveControl(Control target)
{
+ if (Visible)
+ Hide();
_lastTarget = null;
}