Have popup sub menus working well
This commit is contained in:
parent
9b4ee04b77
commit
06cfe5a227
14 changed files with 107 additions and 71 deletions
|
|
@ -159,5 +159,10 @@ namespace MatterHackers.MatterControl
|
|||
unregisterEvents?.Invoke(this, null);
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,24 +168,25 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
var menuTheme = ApplicationController.Instance.MenuTheme;
|
||||
|
||||
PopupMenu modifyMenu = popupMenu.CreateSubMenu("Modify".Localize(), ApplicationController.Instance.MenuTheme);
|
||||
|
||||
foreach (var nodeOperation in ApplicationController.Instance.Graph.Operations)
|
||||
popupMenu.CreateSubMenu("Modify".Localize(), ApplicationController.Instance.MenuTheme, (modifyMenu) =>
|
||||
{
|
||||
foreach (var type in nodeOperation.MappedTypes)
|
||||
foreach (var nodeOperation in ApplicationController.Instance.Graph.Operations)
|
||||
{
|
||||
if (type.IsAssignableFrom(selectedItemType)
|
||||
&& (nodeOperation.IsVisible?.Invoke(selectedItem) != false)
|
||||
&& nodeOperation.IsEnabled?.Invoke(selectedItem) != false)
|
||||
foreach (var type in nodeOperation.MappedTypes)
|
||||
{
|
||||
var subMenuItem = modifyMenu.CreateMenuItem(nodeOperation.Title, nodeOperation.IconCollector?.Invoke(menuTheme));
|
||||
subMenuItem.Click += (s2, e2) =>
|
||||
if (type.IsAssignableFrom(selectedItemType)
|
||||
&& (nodeOperation.IsVisible?.Invoke(selectedItem) != false)
|
||||
&& nodeOperation.IsEnabled?.Invoke(selectedItem) != false)
|
||||
{
|
||||
nodeOperation.Operation(selectedItem, scene).ConfigureAwait(false);
|
||||
};
|
||||
var subMenuItem = modifyMenu.CreateMenuItem(nodeOperation.Title, nodeOperation.IconCollector?.Invoke(menuTheme));
|
||||
subMenuItem.Click += (s2, e2) =>
|
||||
{
|
||||
nodeOperation.Operation(selectedItem, scene).ConfigureAwait(false);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return popupMenu;
|
||||
|
|
|
|||
|
|
@ -342,6 +342,11 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
this.AddSettingsRow(aboutMatterControl);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void AddMenuItem(string title, Action callback)
|
||||
{
|
||||
var newItem = new SettingsItem(title, theme);
|
||||
|
|
|
|||
|
|
@ -398,6 +398,11 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
AddChild(topToBottom);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,5 +149,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
scene.SelectionChanged -= Scene_SelectionChanged;
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,5 +146,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
this.BeforePopup?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,6 +108,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Image = icon
|
||||
};
|
||||
|
||||
menuItem.Click += (s, e) =>
|
||||
{
|
||||
Unfocus();
|
||||
};
|
||||
|
||||
this.AddChild(menuItem);
|
||||
|
||||
return menuItem;
|
||||
|
|
@ -115,10 +120,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
public class SubMenuItemButton : MenuItem, IIgnoredPopupChild
|
||||
{
|
||||
public PopupMenu PopupMenu { get; set; }
|
||||
public SubMenuItemButton(GuiWidget content, ThemeConfig theme, PopupMenu menu) : base(content, theme)
|
||||
public PopupMenu SubMenu { get; set; }
|
||||
|
||||
public SubMenuItemButton(GuiWidget content, ThemeConfig theme) : base(content, theme)
|
||||
{
|
||||
PopupMenu = menu;
|
||||
}
|
||||
|
||||
public override void OnDraw(Graphics2D graphics2D)
|
||||
|
|
@ -136,48 +141,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
graphics2D.Render(arrow, this.Enabled ? Color.Black : Color.Gray);
|
||||
}
|
||||
}
|
||||
|
||||
private SubMenuItemButton CreateSubMenuButton(string name, PopupMenu popupMenu, ImageBuffer icon = null, string shortCut = null)
|
||||
{
|
||||
GuiWidget content;
|
||||
|
||||
var textWidget = new TextWidget(name, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor)
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
Padding = MenuPadding,
|
||||
};
|
||||
|
||||
if (shortCut != null)
|
||||
{
|
||||
content = new GuiWidget()
|
||||
if (SubMenu != null)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
};
|
||||
return SubMenu.ContainsFocus;
|
||||
}
|
||||
|
||||
content.AddChild(new TextWidget(shortCut, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor)
|
||||
{
|
||||
HAnchor = HAnchor.Right
|
||||
});
|
||||
|
||||
content.AddChild(textWidget);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
content = textWidget;
|
||||
}
|
||||
|
||||
content.Selectable = false;
|
||||
|
||||
var menuItem = new SubMenuItemButton(content, theme, popupMenu)
|
||||
{
|
||||
Name = name + " Menu Item",
|
||||
Image = icon
|
||||
};
|
||||
|
||||
this.AddChild(menuItem);
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
public class CheckboxMenuItem : MenuItem, IIgnoredPopupChild, ICheckbox
|
||||
|
|
@ -198,6 +171,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
base.OnLoad(args);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Checked
|
||||
{
|
||||
get => _checked;
|
||||
|
|
@ -267,6 +245,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
base.OnLoad(args);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IList<GuiWidget> SiblingRadioButtonList { get; set; }
|
||||
|
||||
public bool Checked
|
||||
|
|
@ -295,15 +278,32 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
public event EventHandler CheckedStateChanged;
|
||||
}
|
||||
|
||||
public PopupMenu CreateSubMenu(string menuTitle, ThemeConfig menuTheme)
|
||||
public void CreateSubMenu(string menuTitle, ThemeConfig menuTheme, Action<PopupMenu> populateSubMenu)
|
||||
{
|
||||
var subMenu = new PopupMenu(menuTheme);
|
||||
var subMenuItemButton = this.CreateSubMenuButton(menuTitle, subMenu);
|
||||
GuiWidget content = new TextWidget(menuTitle, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor)
|
||||
{
|
||||
Padding = MenuPadding,
|
||||
};
|
||||
|
||||
content.Selectable = false;
|
||||
|
||||
var subMenuItemButton = new SubMenuItemButton(content, theme)
|
||||
{
|
||||
Name = menuTitle + " Menu Item",
|
||||
//Image = icon
|
||||
};
|
||||
|
||||
this.AddChild(subMenuItemButton);
|
||||
|
||||
subMenuItemButton.Click += (s, e) =>
|
||||
{
|
||||
var subMenu = new PopupMenu(menuTheme);
|
||||
subMenuItemButton.SubMenu = subMenu;
|
||||
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
populateSubMenu(subMenu);
|
||||
|
||||
var systemWindow = this.Parents<SystemWindow>().FirstOrDefault();
|
||||
systemWindow.ShowPopup(
|
||||
new MatePoint(subMenuItemButton)
|
||||
|
|
@ -322,10 +322,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
subMenu.Closed += (s1, e1) =>
|
||||
{
|
||||
subMenu.ClearRemovedFlag();
|
||||
subMenuItemButton.SubMenu = null;
|
||||
if(!this.ContainsFocus)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
public MenuItem CreateBoolMenuItem(string name, Func<bool> getter, Action<bool> setter, bool useRadioStyle = false, IList<GuiWidget> siblingRadioButtonList = null)
|
||||
|
|
|
|||
|
|
@ -183,5 +183,10 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
base.OnDrawBackground(graphics2D);
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,9 +88,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
var hookedParents = new HashSet<GuiWidget>();
|
||||
|
||||
var ignoredWidgets = popup.Widget.Children.Where(c => c is IIgnoredPopupChild).ToList();
|
||||
|
||||
bool checkIfNeedScrollBar = true;
|
||||
List<IIgnoredPopupChild> ignoredWidgets = popup.Widget.Children.OfType<IIgnoredPopupChild>().ToList();
|
||||
|
||||
void widgetRelativeTo_PositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
|
@ -158,16 +156,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
|
||||
void FocusChanged(object sender, EventArgs e)
|
||||
void FocusChanged(object s, EventArgs e)
|
||||
{
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
var send = sender;
|
||||
// Fired any time focus changes. Traditionally we closed the menu if the we weren't focused.
|
||||
// Fired any time focus changes. Traditionally we closed the menu if we weren't focused.
|
||||
// To accommodate children (or external widgets) having focus we also query for and consider special cases
|
||||
bool specialChildHasFocus = ignoredWidgets.Any(w => w.ContainsFocus || w.Focused)
|
||||
|| popup.Widget.DescendantsAndSelf<DropDownList>().Any(w => w.IsOpen)
|
||||
|| popup.Widget.DescendantsAndSelf<PopupMenu.SubMenuItemButton>().Any(w => w.PopupMenu.ContainsFocus);
|
||||
bool specialChildHasFocus = ignoredWidgets.Any(w => w.ContainsFocus || w.Focused || w.KeepMenuOpen())
|
||||
|| popup.Widget.DescendantsAndSelf<DropDownList>().Any(w => w.IsOpen);
|
||||
|
||||
// If the focused changed and we've lost focus and no special cases permit, close the menu
|
||||
if (!popup.Widget.ContainsFocus
|
||||
|
|
|
|||
|
|
@ -116,8 +116,6 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
column.Invalidate();
|
||||
imageObject.Invalidate(new InvalidateArgs(imageObject, InvalidateType.Image));
|
||||
|
||||
popupMenu.Unfocus();
|
||||
};
|
||||
|
||||
pasteMenu.Enabled = Clipboard.Instance.ContainsImage;
|
||||
|
|
@ -126,7 +124,6 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
copyMenu.Click += (s2, e2) =>
|
||||
{
|
||||
Clipboard.Instance.SetImage(thumbnailWidget.Image);
|
||||
popupMenu.Unfocus();
|
||||
};
|
||||
|
||||
var popupBounds = new RectangleDouble(e.X + 1, e.Y + 1, e.X + 1, e.Y + 1);
|
||||
|
|
|
|||
|
|
@ -81,5 +81,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
this.AddChild(dropDownList);
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,6 +212,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
}
|
||||
|
||||
public bool KeepMenuOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1320,7 +1320,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Action = () =>
|
||||
{
|
||||
Scene.Paste();
|
||||
popupMenu.Unfocus();
|
||||
},
|
||||
IsEnabled = () => Clipboard.Instance.ContainsImage || Clipboard.Instance.GetText() == "!--IObjectSelection--!"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b59a1957eb2fbdbffe3b21306f124cd48e438d75
|
||||
Subproject commit 6b893b449e604a6294a2abd7ca7bda43400e3adb
|
||||
Loading…
Add table
Add a link
Reference in a new issue