Mesen-X/GUI.NET/MonoToolStripHelper.cs

77 lines
2.4 KiB
C#
Raw Permalink Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace Mesen.GUI
{
//Everything in here is a workaround for issues with dropdown menus in the latest version of Mono (5.18)
//Bug report:
//https://github.com/mono/mono/issues/12644
static class MonoToolStripHelper
{
private static HashSet<ToolStripDropDown> _openedDropdowns = new HashSet<ToolStripDropDown>();
public static void DropdownOpening(object sender, EventArgs e)
{
ToolStripDropDownItem ddItem = (ToolStripDropDownItem)sender;
if(!ddItem.GetCurrentParent().Visible) {
ddItem.DropDown.Close();
return;
}
HashSet<object> parents = new HashSet<object>();
parents.Add(ddItem.GetCurrentParent());
ToolStripItem parent = ddItem.OwnerItem;
if(parent != null) {
parents.Add(parent);
parents.Add(parent.GetCurrentParent());
while((parent = parent.OwnerItem) != null) {
parents.Add(parent);
parents.Add(parent.GetCurrentParent());
}
}
foreach(ToolStripDropDown openedDropdown in _openedDropdowns.ToList()) {
//Close all non-parent dropdowns when opening a new dropdown
if(!parents.Contains(openedDropdown.OwnerItem) && !parents.Contains(openedDropdown)) {
openedDropdown.Close();
}
}
_openedDropdowns.Add(ddItem.DropDown);
}
public static void DropdownClosed(object sender, EventArgs e)
{
ToolStripDropDownItem ddItem = (ToolStripDropDownItem)sender;
ToolStripDropDown parent = ddItem.GetCurrentParent() as ToolStripDropDown;
if(parent != null) {
Point pos = parent.PointToClient(Cursor.Position);
if(pos.X < 0 || pos.Y < 0 || pos.X > parent.Width || pos.Y > parent.Height) {
//When closing a dropdown, if the mouse isn't inside its parent, close all the parent, too.
parent.Close();
}
}
_openedDropdowns.Remove(ddItem.DropDown);
}
public static void ContextMenuOpening(object sender, EventArgs e)
{
//Close all existing dropdowns with no exception when a context menu opens
foreach(ToolStripDropDown openedDropdown in _openedDropdowns.ToList()) {
openedDropdown.Close();
}
_openedDropdowns = new HashSet<ToolStripDropDown>();
_openedDropdowns.Add((ContextMenuStrip)sender);
}
public static void ContextMenuClosed(object sender, EventArgs e)
{
_openedDropdowns.Remove((ContextMenuStrip)sender);
}
}
}