Have popup sub menus working well

This commit is contained in:
Lars Brubaker 2018-09-11 10:57:53 -07:00
parent 9b4ee04b77
commit 06cfe5a227
14 changed files with 107 additions and 71 deletions

View file

@ -159,5 +159,10 @@ namespace MatterHackers.MatterControl
unregisterEvents?.Invoke(this, null);
base.OnClosed(e);
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -398,6 +398,11 @@ namespace MatterHackers.MatterControl.CustomWidgets
AddChild(topToBottom);
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -149,5 +149,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
scene.SelectionChanged -= Scene_SelectionChanged;
base.OnClosed(e);
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -146,5 +146,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
this.BeforePopup?.Invoke(this, null);
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -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)

View file

@ -183,5 +183,10 @@ namespace MatterHackers.MatterControl.CustomWidgets
base.OnDrawBackground(graphics2D);
}
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -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

View file

@ -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);

View file

@ -81,5 +81,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
this.AddChild(dropDownList);
}
public bool KeepMenuOpen()
{
return false;
}
}
}

View file

@ -212,6 +212,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
: base(FlowDirection.TopToBottom)
{
}
public bool KeepMenuOpen()
{
return false;
}
}
}
}

View file

@ -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