using System.Reflection; using Avalonia.Controls; using Avalonia.Threading; using Shouldly; using Xunit; using AtomUIContextMenu = AtomUI.Desktop.Controls.ContextMenu; using AtomUIMenuItem = AtomUI.Desktop.Controls.MenuItem; using AtomUIPopup = AtomUI.Desktop.Controls.Popup; using AtomUIWindow = AtomUI.Desktop.Controls.Window; namespace AtomUI.Desktop.Controls.Tests.Menu; public class ContextMenuPinnedOpenTests { static ContextMenuPinnedOpenTests() { AvaloniaTestApp.EnsureInitialized(); } [Fact] public void Popup_Pin_Opens_ContextMenu_And_Physical_Popup() { var contextMenu = new AtomUIContextMenu { IsMotionEnabled = false }; contextMenu.Items.Add(new AtomUIMenuItem { Header = "Open" }); var host = new Border { Width = 120, Height = 40, ContextMenu = contextMenu }; var window = ShowInWindow(host); try { contextMenu.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); var popup = GetPopup(contextMenu); contextMenu.IsOpen.ShouldBeTrue(); popup.IsPopupPinnedOpen.ShouldBeTrue(); popup.IsOpen.ShouldBeTrue(); } finally { window.Close(); Dispatcher.UIThread.RunJobs(); } } [Fact] public void Popup_Pin_Rejects_ContextMenu_Close_Before_Submenu_Cleanup() { var parentItem = new AtomUIMenuItem { Header = "Parent" }; parentItem.Items.Add(new AtomUIMenuItem { Header = "Child" }); var contextMenu = new AtomUIContextMenu { IsMotionEnabled = false }; contextMenu.Items.Add(parentItem); var host = new Border { Width = 120, Height = 40, ContextMenu = contextMenu }; var window = ShowInWindow(host); try { contextMenu.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); parentItem.IsSubMenuOpen = true; Dispatcher.UIThread.RunJobs(); parentItem.IsSubMenuOpen.ShouldBeTrue(); contextMenu.Close(); Dispatcher.UIThread.RunJobs(); contextMenu.IsOpen.ShouldBeTrue(); parentItem.IsSubMenuOpen.ShouldBeTrue(); GetPopup(contextMenu).IsOpen.ShouldBeTrue(); } finally { window.Close(); Dispatcher.UIThread.RunJobs(); } } [Fact] public void Popup_Pin_Rejects_Window_Deactivation_Close() { var contextMenu = new AtomUIContextMenu { IsMotionEnabled = false }; contextMenu.Items.Add(new AtomUIMenuItem { Header = "Open" }); var host = new Border { Width = 120, Height = 40, ContextMenu = contextMenu }; var window = ShowInWindow(host); try { contextMenu.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); contextMenu.IsOpen.ShouldBeTrue(); RaiseWindowDeactivated(window); Dispatcher.UIThread.RunJobs(); contextMenu.IsOpen.ShouldBeTrue(); GetPopup(contextMenu).IsOpen.ShouldBeTrue(); } finally { window.Close(); Dispatcher.UIThread.RunJobs(); } } [Fact] public void Popup_Unpin_Leaves_ContextMenu_Open_And_Restores_Normal_Close() { var contextMenu = new AtomUIContextMenu { IsMotionEnabled = false }; contextMenu.Items.Add(new AtomUIMenuItem { Header = "Open" }); var host = new Border { Width = 120, Height = 40, ContextMenu = contextMenu }; var window = ShowInWindow(host); try { contextMenu.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); var popup = GetPopup(contextMenu); contextMenu.IsPopupPinnedOpen = false; Dispatcher.UIThread.RunJobs(); contextMenu.IsOpen.ShouldBeTrue(); popup.IsPopupPinnedOpen.ShouldBeFalse(); popup.IsOpen.ShouldBeTrue(); contextMenu.Close(); Dispatcher.UIThread.RunJobs(); contextMenu.IsOpen.ShouldBeFalse(); popup.IsOpen.ShouldBeFalse(); } finally { window.Close(); Dispatcher.UIThread.RunJobs(); } } [Fact] public void Replacing_A_Pinned_ContextMenu_Closes_The_Old_Owner_Session() { var oldContextMenu = new AtomUIContextMenu { IsMotionEnabled = false }; oldContextMenu.Items.Add(new AtomUIMenuItem { Header = "Old" }); var replacement = new AtomUIContextMenu { IsMotionEnabled = false }; replacement.Items.Add(new AtomUIMenuItem { Header = "New" }); var host = new Border { Width = 120, Height = 40, ContextMenu = oldContextMenu }; var window = ShowInWindow(host); try { oldContextMenu.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); var oldPopup = GetPopup(oldContextMenu); oldPopup.IsOpen.ShouldBeTrue(); host.ContextMenu = replacement; Dispatcher.UIThread.RunJobs(); oldContextMenu.IsOpen.ShouldBeFalse(); oldPopup.IsOpen.ShouldBeFalse(); replacement.IsPopupPinnedOpen = true; Dispatcher.UIThread.RunJobs(); replacement.IsOpen.ShouldBeTrue(); GetPopup(replacement).IsOpen.ShouldBeTrue(); } finally { window.Close(); Dispatcher.UIThread.RunJobs(); } } private static AtomUIPopup GetPopup(AtomUIContextMenu contextMenu) { var field = typeof(AtomUIContextMenu).GetField("_popup", BindingFlags.Instance | BindingFlags.NonPublic); field.ShouldNotBeNull(); return field.GetValue(contextMenu).ShouldBeOfType(); } private static AtomUIWindow ShowInWindow(Control content) { var window = new AtomUIWindow { Width = 320, Height = 200, Content = content }; window.Show(); Dispatcher.UIThread.RunJobs(); return window; } private static void RaiseWindowDeactivated(AtomUIWindow window) { var method = typeof(WindowBase).GetMethod( "HandleDeactivated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.ShouldNotBeNull(); method.Invoke(window, null); } }