diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs index 8103e0128..2edff5c92 100644 --- a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs +++ b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. +using System.Collections.Generic; using FlaxEngine; using FlaxEngine.Assertions; using FlaxEngine.GUI; @@ -88,6 +89,11 @@ namespace FlaxEditor.GUI.ContextMenu /// public bool IsSubMenu => _isSubMenu; + /// + /// External dialog popups opened within the context window (eg. color picker) that should preserve context menu visibility (prevent from closing context menu). + /// + public List ExternalPopups = new List(); + /// /// Initializes a new instance of the class. /// @@ -311,6 +317,34 @@ 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 OnWindowLostFocus() { // Skip for parent menus (child should handle lost of focus) @@ -354,20 +388,9 @@ namespace FlaxEditor.GUI.ContextMenu base.Update(deltaTime); // Let root context menu to check if none of the popup windows - if (_parentCM == null) + if (_parentCM == null && !IsForeground) { - var anyForeground = false; - var c = this; - while (!anyForeground && c != null) - { - if (c._window != null && c._window.IsForegroundWindow) - anyForeground = true; - c = c._childCM; - } - if (!anyForeground) - { - Hide(); - } + Hide(); } } diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index acd030be1..7c71c5628 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -398,9 +398,9 @@ namespace FlaxEditor.Modules var dialog = new ColorPickerDialog(initialValue, colorChanged, pickerClosed, useDynamicEditing); dialog.Show(targetControl); - // Place dialog nearby the target control if (targetControl != null) { + // Place dialog nearby the target control var targetControlDesktopCenter = targetControl.PointToScreen(targetControl.Size * 0.5f); var desktopSize = Platform.GetMonitorBounds(targetControlDesktopCenter); var pos = targetControlDesktopCenter + new Float2(10.0f, -dialog.Height * 0.5f); @@ -411,6 +411,18 @@ namespace FlaxEditor.Modules var desktopBounds = Platform.VirtualDesktopBounds; pos = Float2.Clamp(pos, desktopBounds.UpperLeft, desktopBounds.BottomRight - dialog.Size); dialog.RootWindow.Window.Position = pos; + + // Register for context menu (prevent auto-closing context menu when selecting color) + var c = targetControl; + while (c != null) + { + if (c is ContextMenuBase cm) + { + cm.ExternalPopups.Add(dialog.RootWindow?.Window); + break; + } + c = c.Parent; + } } return dialog;