From c61afe9fee3b30cd4af394db905b1e4dd03e205d Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Wed, 15 Sep 2021 17:44:24 -0700 Subject: [PATCH] Making tool bar able to hind elements --- .../ApplicationView/SceneOperations.cs | 5 +- .../CustomWidgets/SceneOperation.cs | 20 ++++- .../DesignTools/PublicPropertyEditor.cs | 6 +- .../PublicPropertySliderFunctions.cs | 6 +- .../PartPreviewWindow/PopupMenu.cs | 80 +++++++++++++++++ .../View3D/PrinterBar/OverflowBar.cs | 5 ++ .../PartPreviewWindow/ViewToolBarControls.cs | 87 ++++++++++++++++--- .../PrinterCommunication/PrinterConnection.cs | 30 +++---- .../UIFields/EnumDisplayField.cs | 69 ++++++++------- Submodules/agg-sharp | 2 +- 10 files changed, 241 insertions(+), 69 deletions(-) diff --git a/MatterControlLib/ApplicationView/SceneOperations.cs b/MatterControlLib/ApplicationView/SceneOperations.cs index c52da2691..6e9c967a5 100644 --- a/MatterControlLib/ApplicationView/SceneOperations.cs +++ b/MatterControlLib/ApplicationView/SceneOperations.cs @@ -808,6 +808,7 @@ namespace MatterHackers.MatterControl new OperationGroup("Path") { TitleResolver = () => "Path".Localize(), + Visible = OperationGroup.GetVisible("Path", false), Operations = new List() { LinearExtrudeOperation(), @@ -815,6 +816,7 @@ namespace MatterHackers.MatterControl SmoothPathOperation(), InflatePathOperation(), OutlinePathOperation(), + AddBaseOperation(), } }, new OperationGroup("Merge") @@ -847,12 +849,12 @@ namespace MatterHackers.MatterControl { ReduceOperation(), RepairOperation(), - AddBaseOperation(), } }, new OperationGroup("Printing") { TitleResolver = () => "Printing".Localize(), + Visible = OperationGroup.GetVisible("Path", false), Operations = new List() { ToggleSupportOperation(), @@ -862,6 +864,7 @@ namespace MatterHackers.MatterControl new OperationGroup("Design Apps") { TitleResolver = () => "Design Apps".Localize(), + Visible = OperationGroup.GetVisible("Path", false), Operations = new List() { FitToBoundsOperation(), diff --git a/MatterControlLib/CustomWidgets/SceneOperation.cs b/MatterControlLib/CustomWidgets/SceneOperation.cs index fab8af340..5d0beb1d5 100644 --- a/MatterControlLib/CustomWidgets/SceneOperation.cs +++ b/MatterControlLib/CustomWidgets/SceneOperation.cs @@ -121,16 +121,28 @@ namespace MatterHackers.Agg.UI public EventHandler VisibleChanged; - private bool _visible; + private static string VisibleKey(string opperationGroupName) + { + return $"scene_operation_visible_{opperationGroupName}"; + } + + public static bool GetVisible(string id, bool defaultIfNotSet) + { + return UserSettings.Instance.Fields.GetBool(VisibleKey(id), defaultIfNotSet); + } public bool Visible { - get => _visible; + get + { + return GetVisible(this.Id, true); + } + set { - if (_visible != value) + if (Visible != value) { - _visible = value; + UserSettings.Instance.Fields.SetBool(VisibleKey(Id), value); VisibleChanged?.Invoke(this, null); } } diff --git a/MatterControlLib/DesignTools/PublicPropertyEditor.cs b/MatterControlLib/DesignTools/PublicPropertyEditor.cs index a0caa6e4c..a30744525 100644 --- a/MatterControlLib/DesignTools/PublicPropertyEditor.cs +++ b/MatterControlLib/DesignTools/PublicPropertyEditor.cs @@ -406,7 +406,7 @@ namespace MatterHackers.MatterControl.DesignTools } rowContainer = CreateSettingsRow(property, - PublicPropertySliderFunctions.GetFieldContentWithSlider(property, context, field, undoBuffer, (valueString) => { return double.Parse(valueString); }), + PublicPropertySliderFunctions.GetFieldContentWithSlider(property, context, field, undoBuffer, (valueString) => { return double.Parse(valueString); }, theme), theme); } } @@ -836,7 +836,7 @@ namespace MatterHackers.MatterControl.DesignTools { doubleExpresion.Expression = valueString; return doubleExpresion; - }), + }, theme), theme, rows); @@ -911,7 +911,7 @@ namespace MatterHackers.MatterControl.DesignTools { intExpresion.Expression = valueString; return intExpresion; - }), + }, theme), theme, rows); diff --git a/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs b/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs index 57a750fde..dedeb746c 100644 --- a/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs +++ b/MatterControlLib/DesignTools/PublicPropertySliderFunctions.cs @@ -40,7 +40,7 @@ namespace MatterHackers.MatterControl.DesignTools { public static class PublicPropertySliderFunctions { - public static GuiWidget GetFieldContentWithSlider(EditableProperty property, PPEContext context, UIField field, UndoBuffer undoBuffer, Func valueFromString) + public static GuiWidget GetFieldContentWithSlider(EditableProperty property, PPEContext context, UIField field, UndoBuffer undoBuffer, Func valueFromString, ThemeConfig theme) { var sliderAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault(); if (sliderAttribute != null) @@ -55,6 +55,10 @@ namespace MatterHackers.MatterControl.DesignTools VAnchor = VAnchor.Center, }; + slider.View.TrackColor = theme.TextColor; + slider.View.ThumbColor = theme.PrimaryAccentColor; + slider.View.TrackHeight = 1 * GuiWidget.DeviceScale; + Func getFieldValue = null; double GetSlider0To1FromField() diff --git a/MatterControlLib/PartPreviewWindow/PopupMenu.cs b/MatterControlLib/PartPreviewWindow/PopupMenu.cs index 560e8782e..edcffe0d1 100644 --- a/MatterControlLib/PartPreviewWindow/PopupMenu.cs +++ b/MatterControlLib/PartPreviewWindow/PopupMenu.cs @@ -37,6 +37,7 @@ using MatterHackers.Agg.UI; using MatterHackers.Agg.VertexSource; using MatterHackers.ImageProcessing; using MatterHackers.MatterControl.CustomWidgets; +using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.PartPreviewWindow @@ -410,6 +411,73 @@ namespace MatterHackers.MatterControl.PartPreviewWindow return menuItem; } + /// + /// Create and add a new menu item + /// + /// The text of the item + /// + /// + /// + /// + public MenuItem CreateButtonSelectMenuItem(string text, IEnumerable<(string key, string text)> buttonKvps, string startingValue, Action setter) + { + var textWidget = new TextWidget(text, pointSize: theme.DefaultFontSize, textColor: theme.TextColor) + { + Padding = MenuPadding, + VAnchor = VAnchor.Center, + }; + + return this.CreateButtonSelectMenuItem(textWidget, text, buttonKvps, startingValue, setter); + } + + public MenuItem CreateButtonSelectMenuItem(string text, ImageBuffer icon, IEnumerable<(string key, string text)> buttonKvps, string startingValue, Action setter) + { + var row = new FlowLayoutWidget() + { + Selectable = false + }; + row.AddChild(new IconButton(icon, theme)); + + var textWidget = new TextWidget(text, pointSize: theme.DefaultFontSize, textColor: theme.TextColor) + { + Padding = MenuPadding, + VAnchor = VAnchor.Center + }; + row.AddChild(textWidget); + + return this.CreateButtonSelectMenuItem(row, text, buttonKvps, startingValue, setter); + } + + public MenuItem CreateButtonSelectMenuItem(GuiWidget guiWidget, string name, IEnumerable<(string key, string text)> buttonKvps, string startingValue, Action setter) + { + var row = new FlowLayoutWidget() + { + HAnchor = HAnchor.MaxFitOrStretch, + Name = name + " Menu Item", + }; + + row.AddChild(guiWidget); + row.AddChild(new HorizontalSpacer()); + + foreach(var buttonKvp in buttonKvps) + { + var localKey = buttonKvp.key; + var button = EnumDisplayField.CreateThemedRadioButton(buttonKvp.text, buttonKvp.key, "", startingValue == buttonKvp.key, () => + { + setter?.Invoke(localKey); + }, theme); + row.AddChild(button); + } + + var menuItem = new MenuItemHoldOpen(row, theme) + { + }; + + this.AddChild(menuItem); + + return menuItem; + } + public MenuItem CreateMenuItem(GuiWidget guiWidget, string name, ImageBuffer icon = null) { var menuItem = new MenuItem(guiWidget, theme) @@ -483,6 +551,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } + public bool KeepMenuOpen => false; + public override void OnDraw(Graphics2D graphics2D) { if (this.Image != null) @@ -496,6 +566,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow base.OnDraw(graphics2D); } } + + public class MenuItemHoldOpen : MenuItem, IIgnoredPopupChild + { + public MenuItemHoldOpen(GuiWidget content, ThemeConfig theme) + : base(content, theme) + { + } + + public bool KeepMenuOpen => false; + } } public static class PopupMenuExtensions diff --git a/MatterControlLib/PartPreviewWindow/View3D/PrinterBar/OverflowBar.cs b/MatterControlLib/PartPreviewWindow/View3D/PrinterBar/OverflowBar.cs index 77b5208f1..63211fbb6 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/PrinterBar/OverflowBar.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/PrinterBar/OverflowBar.cs @@ -130,6 +130,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { } + public OverflowMenuButton(string text, ThemeConfig theme) + : base(text, CreateOverflowIcon(theme), theme) + { + } + public OverflowMenuButton(OverflowBar overflowBar, ThemeConfig theme) : this(overflowBar, CreateOverflowIcon(theme), theme) { diff --git a/MatterControlLib/PartPreviewWindow/ViewToolBarControls.cs b/MatterControlLib/PartPreviewWindow/ViewToolBarControls.cs index ed2f1eacb..47129f0ae 100644 --- a/MatterControlLib/PartPreviewWindow/ViewToolBarControls.cs +++ b/MatterControlLib/PartPreviewWindow/ViewToolBarControls.cs @@ -200,24 +200,40 @@ namespace MatterHackers.MatterControl.PartPreviewWindow void UpdateVisability(object s, EventArgs e) { - if (operationGroup.Collapse) + if (operationGroup.Visible) { - actionDropDown.Visible = true; - operationButtonGroup.Visible = false; + if (operationGroup.Collapse) + { + actionDropDown.Visible = true; + operationButtonGroup.Visible = false; + + DoWrappingLayout(); + } + else + { + actionDropDown.Visible = false; + operationButtonGroup.Visible = true; + + DoWrappingLayout(); + } } else { actionDropDown.Visible = false; - operationButtonGroup.Visible = true; + operationButtonGroup.Visible = false; + + DoWrappingLayout(); } } UserSettings.Instance.SettingChanged += UpdateVisability; operationGroup.CollapseChanged += UpdateVisability; + operationGroup.VisibleChanged += UpdateVisability; this.Closed += (s, e) => { - operationGroup.CollapseChanged -= UpdateVisability; UserSettings.Instance.SettingChanged -= UpdateVisability; + operationGroup.CollapseChanged -= UpdateVisability; + operationGroup.VisibleChanged -= UpdateVisability; }; UpdateVisability(operationGroup, null); @@ -270,11 +286,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } // add the options menu - var optionsButton = new OverflowBar.OverflowMenuButton(theme); + this.AddChild(new HorizontalSpacer()); + + var overflowIcon = StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "overflow.png"), 32, 32).SetToColor(theme.TextColor); + var optionsButton = new PopupMenuButton(overflowIcon, theme) + { + AlignToRightEdge = true + }; this.AddChild(optionsButton); - optionsButton.Name = "Printer Overflow Menu"; - optionsButton.ToolTipText = "Printer Options".Localize(); - GeneratePrinterOverflowMenu(optionsButton, theme); + optionsButton.Name = "ToolBar Overflow Menu"; + optionsButton.ToolTipText = "Tool Bar Options".Localize(); + optionsButton.DynamicPopupContent = () => GenerateToolBarOptionsMenu(theme); // Register listeners undoBuffer.Changed += UndoBuffer_Changed; @@ -285,12 +307,53 @@ namespace MatterHackers.MatterControl.PartPreviewWindow UpdateToolbarButtons(null, null); } - private void GeneratePrinterOverflowMenu(PopupMenuButton optionsButton, ThemeConfig theme) + private GuiWidget GenerateToolBarOptionsMenu(ThemeConfig theme) { - optionsButton.DynamicPopupContent = () => + var popupMenu = new PopupMenu(theme) { - return new GuiWidget(50, 100); + Padding = new BorderDouble(0, 7), }; + + var buttonData = new (string, string)[] + { + ("Collapsed".Localize(), "Collapsed"), + ("Expanded".Localize(), "Expanded"), + ("Hidden".Localize(), "Hidden"), + }; + + foreach (var namedAction in SceneOperations.All) + { + if (namedAction is OperationGroup operationGroup) + { + var startingValue = operationGroup.Collapse ? "Collapsed" : "Expanded"; + if(!operationGroup.Visible) + { + startingValue = "Hidden"; + } + + popupMenu.CreateButtonSelectMenuItem(operationGroup.Title, buttonData, startingValue, (value) => + { + switch (value) + { + case "Expanded": + operationGroup.Collapse = false; + operationGroup.Visible = true; + break; + + case "Collapsed": + operationGroup.Collapse = true; + operationGroup.Visible = true; + break; + + case "Hidden": + operationGroup.Visible = false; + break; + } + }); + } + }; + + return popupMenu; } private FlowLayoutWidget CreateOperationButtonGroup(ThemeConfig theme, OperationGroup operationGroup) diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 29c16a171..0ce8cadb2 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -1910,7 +1910,6 @@ Make sure that your printer is turned on. Some printers will appear to be connec resetSerialPort.Close(); - // let the process know we canceled not ended normally. CommunicationState = CommunicationStates.Disconnected; } } @@ -2114,8 +2113,6 @@ Make sure that your printer is turned on. Some printers will appear to be connec public PrintingModes PrintingMode { get; private set; } - private CancellationTokenSource printingCancellation; - public enum PrintingModes { Normal, @@ -2138,8 +2135,6 @@ Make sure that your printer is turned on. Some printers will appear to be connec this.PrintingMode = printingMode; - printingCancellation = new CancellationTokenSource(); - haveReportedError = false; PrintWasCanceled = false; cancelPrintNextWriteLine = false; @@ -2149,6 +2144,7 @@ Make sure that your printer is turned on. Some printers will appear to be connec ClearQueuedGCode(); ActivePrintTask = printTaskToUse; + CanceledPrintTask = null; await Task.Run(() => { @@ -2203,7 +2199,7 @@ Make sure that your printer is turned on. Some printers will appear to be connec ActivePrintTask.CommitAndPushToServer(); - Task.Run(() => this.SyncProgressToDB(printingCancellation.Token)); + Task.Run(() => this.SyncProgressToDB()); PrintStarted?.Invoke(this, null); } @@ -2297,9 +2293,10 @@ Make sure that your printer is turned on. Some printers will appear to be connec { lock (locker) { - // Flag as canceled, wait briefly for listening threads to catch up - printingCancellation.Cancel(); - Thread.Sleep(15); + TerminalLog.WriteLine("Print Canceled"); + + // Flag as canceled + this.cancelPrintNextWriteLine = true; CancelInProgressStreamProcessors(); // get rid of all the gcode we have left to print @@ -2312,7 +2309,6 @@ Make sure that your printer is turned on. Some printers will appear to be connec } // let the process know we canceled not ended normally. - this.cancelPrintNextWriteLine = true; CanceleRequested?.Invoke(this, null); if (markPrintCanceled && ActivePrintTask != null) @@ -2509,13 +2505,17 @@ Make sure that your printer is turned on. Some printers will appear to be connec public GCodeStream TotalGCodeStream => totalGCodeStream; - private void SyncProgressToDB(CancellationToken cancellationToken) + private void SyncProgressToDB() { - // var timer = Stopwatch.StartNew(); + bool WatingForPrintToFinish() + { + var canceled = cancelPrintNextWriteLine || PrintWasCanceled; + var stillPrinting = this.CommunicationState != CommunicationStates.FinishedPrint && this.CommunicationState != CommunicationStates.Connected; - while (!cancellationToken.IsCancellationRequested - && this.CommunicationState != CommunicationStates.FinishedPrint - && this.CommunicationState != CommunicationStates.Connected) + return !canceled && stillPrinting; + } + + while (WatingForPrintToFinish()) { double secondsSinceStartedPrint = timePrinting.Elapsed.TotalSeconds; diff --git a/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs b/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs index 9ee75cc80..cf314b425 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs @@ -236,42 +236,11 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { var localIndex = index; - var radioButton = new RadioTextButton(enumItem.Value, theme) - { - VAnchor = VAnchor.Center | VAnchor.Fit, - DrawUnderline = false, - BackgroundRadius = theme.ButtonRadius + 4, - Margin = new BorderDouble(5, 0, 0, 0), - Padding = new BorderDouble(9, 5), - // BackgroundInset = new BorderDouble(5, 4), - SelectedBackgroundColor = theme.PrimaryAccentColor, - UnselectedBackgroundColor = theme.MinimalShade, - BackgroundColor = theme.MinimalShade, - ToolTipText = descriptions[index] - }; - - radioButton.CheckedStateChanged += (s, e) => - { - var button = s as RadioTextButton; - button.TextColor = button.Checked ? theme.BackgroundColor : theme.TextColor; - }; - - // set it if checked - if (enumItem.Key == this.InitialValue) - { - radioButton.Checked = true; - } + var radioButton = CreateThemedRadioButton(enumItem.Value, enumItem.Key, descriptions[index], this.InitialValue == enumItem.Key, () => this.SetValue(enumItem.Key, true), theme); menuRow.AddChild(radioButton); var localItem = enumItem; - radioButton.CheckedStateChanged += (s, e) => - { - if (radioButton.Checked) - { - this.SetValue(localItem.Key, true); - } - }; index++; } @@ -279,6 +248,42 @@ namespace MatterHackers.MatterControl.SlicerConfiguration this.Content = menuRow; } + public static RadioTextButton CreateThemedRadioButton(string text, string key, string toolTipText, bool startChecked, Action setChecked, ThemeConfig theme) + { + var radioButton = new RadioTextButton(text, theme) + { + VAnchor = VAnchor.Center | VAnchor.Fit, + DrawUnderline = false, + BackgroundRadius = theme.ButtonRadius + 4, + Margin = new BorderDouble(5, 0, 0, 0), + Padding = new BorderDouble(9, 5), + // BackgroundInset = new BorderDouble(5, 4), + SelectedBackgroundColor = theme.PrimaryAccentColor, + UnselectedBackgroundColor = theme.MinimalShade, + BackgroundColor = theme.MinimalShade, + ToolTipText = toolTipText + }; + + radioButton.CheckedStateChanged += (s, e) => + { + var button = s as RadioTextButton; + button.TextColor = button.Checked ? theme.BackgroundColor : theme.TextColor; + }; + + // set it if checked + radioButton.Checked = startChecked; + + radioButton.CheckedStateChanged += (s, e) => + { + if (radioButton.Checked) + { + setChecked?.Invoke(); + } + }; + + return radioButton; + } + private void AddIconRow(IEnumerable<(string Key, string Value)> enumItems, List descriptions) { var iconsRow = new FlowLayoutWidget(); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 7e55f2c52..53d5cec07 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 7e55f2c529b1504924b65ec3a296d1e82876d20d +Subproject commit 53d5cec07af14d5395d750024e3b69f1056faa22