From ca2d378b8c8a037598ceb576c571d6e36c8ff077 Mon Sep 17 00:00:00 2001 From: jlewin Date: Wed, 19 Jun 2019 14:16:49 -0700 Subject: [PATCH] Add dedicated type for OperationGroup buttons --- .../ApplicationView/Themes/ThemeConfig.cs | 40 +++++++----- .../PartPreviewWindow/OperationGroupButton.cs | 45 ++++++++++++++ .../PartPreviewWindow/OperationIconButton.cs | 54 ++++++++++++++++ .../PartPreviewWindow/ViewControls3D.cs | 62 ++++++++++--------- 4 files changed, 156 insertions(+), 45 deletions(-) create mode 100644 MatterControlLib/PartPreviewWindow/OperationGroupButton.cs create mode 100644 MatterControlLib/PartPreviewWindow/OperationIconButton.cs diff --git a/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs b/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs index 043897e33..eac6e5fac 100644 --- a/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs +++ b/MatterControlLib/ApplicationView/Themes/ThemeConfig.cs @@ -410,7 +410,7 @@ namespace MatterHackers.MatterControl return popupMenu; } - public PopupMenuButton CreateSplitButton(SplitButtonParams buttonParams) + public PopupMenuButton CreateSplitButton(SplitButtonParams buttonParams, OperationGroup operationGroup = null) { PopupMenuButton menuButton = null; @@ -428,23 +428,33 @@ namespace MatterHackers.MatterControl // Remove right Padding for drop style innerButton.Padding = innerButton.Padding.Clone(right: 0); - menuButton = new PopupMenuButton(innerButton, this) - { - DynamicPopupContent = () => - { - var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme); - buttonParams.ExtendPopupMenu?.Invoke(popupMenu); - return popupMenu; - }, - Name = buttonParams.ButtonName + " Menu SplitButton", - BackgroundColor = this.ToolbarButtonBackground, - HoverColor = this.ToolbarButtonHover, - MouseDownColor = this.ToolbarButtonDown, - DrawArrow = true, - Margin = this.ButtonSpacing, + if (operationGroup == null) + { + menuButton = new PopupMenuButton(innerButton, this); + } + else + + { + menuButton = new OperationGroupButton(operationGroup, innerButton, this); + } + + menuButton.DynamicPopupContent = () => + { + var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme); + buttonParams.ExtendPopupMenu?.Invoke(popupMenu); + + return popupMenu; }; + menuButton.Name = buttonParams.ButtonName + " Menu SplitButton"; + menuButton.BackgroundColor = this.ToolbarButtonBackground; + menuButton.HoverColor = this.ToolbarButtonHover; + menuButton.MouseDownColor = this.ToolbarButtonDown; + menuButton.DrawArrow = true; + menuButton.Margin = this.ButtonSpacing; + menuButton.DistinctPopupButton = true; + innerButton.Selectable = true; return menuButton; } diff --git a/MatterControlLib/PartPreviewWindow/OperationGroupButton.cs b/MatterControlLib/PartPreviewWindow/OperationGroupButton.cs new file mode 100644 index 000000000..2cf9c3c02 --- /dev/null +++ b/MatterControlLib/PartPreviewWindow/OperationGroupButton.cs @@ -0,0 +1,45 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using MatterHackers.Agg; +using MatterHackers.Agg.UI; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public class OperationGroupButton : PopupMenuButton + { + private OperationGroup operationGroup; + + public OperationGroupButton(OperationGroup operationGroup, GuiWidget innerButton, ThemeConfig theme) + : base(innerButton, theme) + { + this.operationGroup = operationGroup; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/PartPreviewWindow/OperationIconButton.cs b/MatterControlLib/PartPreviewWindow/OperationIconButton.cs new file mode 100644 index 000000000..66d7538b5 --- /dev/null +++ b/MatterControlLib/PartPreviewWindow/OperationIconButton.cs @@ -0,0 +1,54 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.CustomWidgets; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public class OperationIconButton : IconButton + { + private SceneSelectionOperation sceneOperation; + private ISceneContext sceneContext; + + public OperationIconButton(SceneSelectionOperation sceneOperation, ISceneContext sceneContext, ThemeConfig theme) + : base(sceneOperation.Icon(theme.InvertIcons), theme) + { + this.sceneOperation = sceneOperation; + this.sceneContext = sceneContext; + } + + protected override void OnClick(MouseEventArgs mouseEvent) + { + sceneOperation.Action?.Invoke(sceneContext); + + base.OnClick(mouseEvent); + } + } +} \ No newline at end of file diff --git a/MatterControlLib/PartPreviewWindow/ViewControls3D.cs b/MatterControlLib/PartPreviewWindow/ViewControls3D.cs index 113dee630..708de83a8 100644 --- a/MatterControlLib/PartPreviewWindow/ViewControls3D.cs +++ b/MatterControlLib/PartPreviewWindow/ViewControls3D.cs @@ -308,45 +308,47 @@ namespace MatterHackers.MatterControl.PartPreviewWindow PopupMenuButton groupButton = null; - groupButton = theme.CreateSplitButton(new SplitButtonParams() - { - Icon = defaultOperation.Icon(theme.InvertIcons), - DefaultAction = (menuButton) => + groupButton = theme.CreateSplitButton( + new SplitButtonParams() { - defaultOperation.Action.Invoke(sceneContext); - }, - DefaultActionTooltip = defaultOperation.HelpText ?? defaultOperation.Title, - ButtonName = defaultOperation.Title, - ExtendPopupMenu = (PopupMenu popupMenu) => - { - foreach (var operation in operationGroup.Operations) + Icon = defaultOperation.Icon(theme.InvertIcons), + DefaultAction = (menuButton) => { - var operationMenu = popupMenu.CreateMenuItem(operation.Title, operation.Icon?.Invoke(theme.InvertIcons)); - - operationMenu.ToolTipText = operation.HelpText; - operationMenu.Enabled = operation.IsEnabled(sceneContext); - operationMenu.Click += (s, e) => UiThread.RunOnIdle(() => + defaultOperation.Action.Invoke(sceneContext); + }, + DefaultActionTooltip = defaultOperation.HelpText ?? defaultOperation.Title, + ButtonName = defaultOperation.Title, + ExtendPopupMenu = (PopupMenu popupMenu) => + { + foreach (var operation in operationGroup.Operations) { - if (operationGroup.StickySelection - && defaultOperation != operation) + var operationMenu = popupMenu.CreateMenuItem(operation.Title, operation.Icon?.Invoke(theme.InvertIcons)); + + operationMenu.ToolTipText = operation.HelpText; + operationMenu.Enabled = operation.IsEnabled(sceneContext); + operationMenu.Click += (s, e) => UiThread.RunOnIdle(() => { - // Update button - var iconButton = groupButton.Children.OfType().First(); - iconButton.SetIcon(operation.Icon(theme.InvertIcons)); - iconButton.ToolTipText = operation.HelpText ?? operation.Title; + if (operationGroup.StickySelection + && defaultOperation != operation) + { + // Update button + var iconButton = groupButton.Children.OfType().First(); + iconButton.SetIcon(operation.Icon(theme.InvertIcons)); + iconButton.ToolTipText = operation.HelpText ?? operation.Title; - UserSettings.Instance.set(operationGroup.GroupRecordId, operationGroup.Operations.IndexOf(operation).ToString()); + UserSettings.Instance.set(operationGroup.GroupRecordId, operationGroup.Operations.IndexOf(operation).ToString()); - defaultOperation = operation; + defaultOperation = operation; - iconButton.Invalidate(); - } + iconButton.Invalidate(); + } - operation.Action?.Invoke(sceneContext); - }); + operation.Action?.Invoke(sceneContext); + }); + } } - } - }); + }, + operationGroup); button = groupButton; }