/// <summary> /// Hide popup menu and all child menus. /// </summary> public virtual void Hide() { if (!Visible) { return; } // Lock update IsLayoutLocked = true; // Close child HideChild(); // Unlink from window Parent = null; // Close window if (_window != null) { var win = _window; _window = null; win.Close(); } // Unlink from parent if (_parentCM != null) { _parentCM._childCM = null; _parentCM = null; } // Hide Visible = false; OnHide(); }
/// <summary> /// Hides child popup menu if any opened. /// </summary> public void HideChild() { if (_childCM != null) { _childCM.Hide(); _childCM = null; } }
/// <summary> /// Shows new child context menu. /// </summary> /// <param name="child">The child menu.</param> /// <param name="location">The child menu initial location.</param> /// <param name="isSubMenu">True if context menu is a normal sub-menu, otherwise it is a custom menu popup linked as child.</param> public void ShowChild(ContextMenuBase child, Vector2 location, bool isSubMenu = true) { // Hide current child HideChild(); // Set child _childCM = child; _childCM._parentCM = this; _childCM._isSubMenu = isSubMenu; // Show child _childCM.Show(this, location); }
/// <summary> /// Show context menu over given control. /// </summary> /// <param name="parent">Parent control to attach to it.</param> /// <param name="location">Popup menu origin location in parent control coordinates.</param> public virtual void Show(Control parent, Vector2 location) { Assert.IsNotNull(parent); // Ensure to be closed Hide(); // Peek parent control window var parentWin = parent.RootWindow; if (parentWin == null) { return; } // Check if show menu inside the other menu - then link as a child to prevent closing the calling menu window on lost focus if (_parentCM == null && parentWin.ChildrenCount == 1 && parentWin.Children[0] is ContextMenuBase parentCM) { parentCM.ShowChild(this, parentCM.ScreenToClient(parent.ClientToScreen(location)), false); return; } // Unlock and perform controls update UnlockChildrenRecursive(); PerformLayout(); // Calculate popup direction and initial location (fit on a single monitor) var dpiScale = Platform.DpiScale; Vector2 dpiSize = Size * dpiScale; Vector2 locationWS = parent.PointToWindow(location); Vector2 locationSS = parentWin.ClientToScreen(locationWS * dpiScale); Location = Vector2.Zero; Rectangle monitorBounds = Platform.GetMonitorBounds(locationSS); Vector2 rightBottomLocationSS = locationSS + dpiSize; bool isUp = false, isLeft = false; if (monitorBounds.Bottom < rightBottomLocationSS.Y) { // Direction: up isUp = true; locationSS.Y -= dpiSize.Y; } if (monitorBounds.Right < rightBottomLocationSS.X) { // Direction: left isLeft = true; locationSS.X -= dpiSize.X; } // Update direction flag if (isUp) { _direction = isLeft ? ContextMenuDirection.LeftUp : ContextMenuDirection.RightUp; } else { _direction = isLeft ? ContextMenuDirection.LeftDown : ContextMenuDirection.RightDown; } // Create window var desc = CreateWindowSettings.Default; desc.Position = locationSS; desc.StartPosition = WindowStartPosition.Manual; desc.Size = dpiSize; desc.Fullscreen = false; desc.HasBorder = false; desc.SupportsTransparency = false; desc.ShowInTaskbar = false; desc.ActivateWhenFirstShown = true; desc.AllowInput = true; desc.AllowMinimize = false; desc.AllowMaximize = false; desc.AllowDragAndDrop = false; desc.IsTopmost = true; desc.IsRegularWindow = false; desc.HasSizingFrame = false; _window = Platform.CreateWindow(ref desc); _window.LostFocus += OnWindowLostFocus; // Attach to the window _parentCM = parent as ContextMenuBase; Parent = _window.GUI; // Show Visible = true; if (_window == null) { return; } _window.Show(); PerformLayout(); Focus(); OnShow(); }