From 1707f95a520711187a103648e1728384bd55023c Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 16:39:15 -0700 Subject: [PATCH 1/9] Add Garbage Collector helper in debug to aid in memory troubleshooting --- PartPreviewWindow/ViewControls3D.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/PartPreviewWindow/ViewControls3D.cs b/PartPreviewWindow/ViewControls3D.cs index 47b395c4d..8b5c1657d 100644 --- a/PartPreviewWindow/ViewControls3D.cs +++ b/PartPreviewWindow/ViewControls3D.cs @@ -596,6 +596,19 @@ namespace MatterHackers.MatterControl.PartPreviewWindow }); } }, +#if DEBUG + new NamedAction() + { + Title = "GC.Collect".Localize(), + Action = () => + { + UiThread.RunOnIdle(() => + { + GC.Collect(); + }); + } + }, +#endif new NamedAction() { Title = "----" }, new NamedAction() { From c92c95fa641b8a5bd932286ced1d4ee6f62d6dfe Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 16:49:53 -0700 Subject: [PATCH 2/9] Filter out history files less than 500b - Issue MatterHackers/MCCentral#3682 Part History folder does not sync with the home screen parts list. - Issue MatterHackers/MCCentral#3683 Plate History folder shows a lot of broken workspaces instead of syncing with home screen plate list --- Library/Providers/MatterControl/PlatingHistoryContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Providers/MatterControl/PlatingHistoryContainer.cs b/Library/Providers/MatterControl/PlatingHistoryContainer.cs index 456d47f1b..4c6a5e919 100644 --- a/Library/Providers/MatterControl/PlatingHistoryContainer.cs +++ b/Library/Providers/MatterControl/PlatingHistoryContainer.cs @@ -83,7 +83,7 @@ namespace MatterHackers.MatterControl.Library if (Directory.Exists(this.FullPath)) { var recentFiles = new DirectoryInfo(this.FullPath).GetFiles("*.mcx").OrderByDescending(f => f.LastWriteTime); - Items = recentFiles.Take(this.PageSize).Select(f => new FileSystemFileItem(f.FullName)).ToList(); + Items = recentFiles.Where(f => f.Length > 500).Take(this.PageSize).Select(f => new FileSystemFileItem(f.FullName)).ToList(); } } From a2131f248e09f54280d1b40ed4dcb01cb9d3d9b0 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 17:01:20 -0700 Subject: [PATCH 3/9] Safely load file - Issue MatterHackers/MCCentral#3633 Missing file breaks app --- ApplicationView/ApplicationController.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index aa3c8622a..8665b26ae 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -116,7 +116,7 @@ namespace MatterHackers.MatterControl public class ApplicationController { - public List FeatureGuides { get; set; } = JsonConvert.DeserializeObject>(AggContext.StaticData.ReadAllText(Path.Combine("OEMSettings", "HelpGuides.json"))); + public List FeatureGuides { get; set; } private Dictionary> objectEditorsByType; @@ -666,6 +666,20 @@ namespace MatterHackers.MatterControl this.Theme = new ThemeConfig(); this.MenuTheme = new ThemeConfig(); + List helpGuides = null; + + string helpGuidesPath = Path.Combine("OEMSettings", "HelpGuides.json"); + if (AggContext.StaticData.FileExists(helpGuidesPath)) + { + try + { + helpGuides = JsonConvert.DeserializeObject>(AggContext.StaticData.ReadAllText(helpGuidesPath)); + } + catch { } + } + + this.FeatureGuides = helpGuides ?? new List(); + ActiveTheme.ThemeChanged.RegisterEvent((s, e) => { ChangeToTheme(ActiveTheme.Instance); From 077ca1b6e76c70bd43ff446f54deff554ac09e9c Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 17:10:29 -0700 Subject: [PATCH 4/9] Fix incorrect ordering of parameters --- PartPreviewWindow/StartPage/ExplorePanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PartPreviewWindow/StartPage/ExplorePanel.cs b/PartPreviewWindow/StartPage/ExplorePanel.cs index e1dede438..df5dc650d 100644 --- a/PartPreviewWindow/StartPage/ExplorePanel.cs +++ b/PartPreviewWindow/StartPage/ExplorePanel.cs @@ -70,7 +70,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab { FeedData explorerFeed = null; - var json = ApplicationController.LoadCachedFile(staticFile, "MatterHackers"); + var json = ApplicationController.LoadCachedFile("MatterHackers", staticFile); if (json != null) { // Construct directly from cache From f8ae45996f5b2e1a108e47ad3ea3b625b816607f Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 17:34:30 -0700 Subject: [PATCH 5/9] Concise instance construction --- SlicerConfiguration/SliceSettingsWidget.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/SlicerConfiguration/SliceSettingsWidget.cs b/SlicerConfiguration/SliceSettingsWidget.cs index 08d99c51d..3cd069cae 100644 --- a/SlicerConfiguration/SliceSettingsWidget.cs +++ b/SlicerConfiguration/SliceSettingsWidget.cs @@ -530,9 +530,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private UIField CreateToggleFieldForSection(SliceSettingData settingData) { - // Create toggle field for key - UIField uiField = new ToggleboxField(theme); bool useDefaultSavePattern = false; + + string sliceSettingValue = settingsContext.GetValue(settingData.SlicerConfigName); + + // Create toggle field for key + UIField uiField = new ToggleboxField(theme) + { + HelpText = settingData.HelpText, + Name = $"{settingData.PresentationName} Field" + }; + uiField.Initialize(tabIndexForItem++); + uiField.ValueChanged += (s, e) => { if (e.UserInitiated) @@ -559,13 +568,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration allUiFields[settingData.SlicerConfigName] = uiField; } - uiField.HelpText = settingData.HelpText; - - uiField.Name = $"{settingData.PresentationName} Field"; - uiField.Initialize(tabIndexForItem++); - - string sliceSettingValue = settingsContext.GetValue(settingData.SlicerConfigName); - uiField.SetValue(sliceSettingValue, userInitiated: false); uiField.ValueChanged += (s, e) => From 8a923bc0c6226bc2e2b38823b7cea4c02fd2972c Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 17:39:54 -0700 Subject: [PATCH 6/9] Document necessity of second ValueChanged listener - Issue MatterHackers/MCCentral#3643 CreateToggleFieldForSection registers two different ValueChanged listeners --- SlicerConfiguration/SliceSettingsWidget.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SlicerConfiguration/SliceSettingsWidget.cs b/SlicerConfiguration/SliceSettingsWidget.cs index 3cd069cae..7911f1d76 100644 --- a/SlicerConfiguration/SliceSettingsWidget.cs +++ b/SlicerConfiguration/SliceSettingsWidget.cs @@ -570,6 +570,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration uiField.SetValue(sliceSettingValue, userInitiated: false); + // Second ValueChanged listener defined after SetValue to ensure it's unaffected by initial change uiField.ValueChanged += (s, e) => { if (useDefaultSavePattern From 56031dbc77d3608ce5ba8f24efe5c6cc93d7c2a6 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 18:27:02 -0700 Subject: [PATCH 7/9] Extract EditorPanel resize functionality to new type - Issue MatterHackers/MCCentral#3645 Tree view - Needs title and collapse ability --- PartPreviewWindow/ResizableSectionWidget.cs | 83 +++++++++++++++++++++ PartPreviewWindow/SelectedObjectPanel.cs | 49 +++--------- 2 files changed, 94 insertions(+), 38 deletions(-) create mode 100644 PartPreviewWindow/ResizableSectionWidget.cs diff --git a/PartPreviewWindow/ResizableSectionWidget.cs b/PartPreviewWindow/ResizableSectionWidget.cs new file mode 100644 index 000000000..1e8ec0bc1 --- /dev/null +++ b/PartPreviewWindow/ResizableSectionWidget.cs @@ -0,0 +1,83 @@ +/* +Copyright (c) 2018, 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 System; +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl.CustomWidgets; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public class ResizableSectionWidget : SectionWidget + { + public BottomResizeContainer ResizeContainer { get; } + + public event EventHandler Resized; + + public ResizableSectionWidget(string sectionTitle, double initialHeight, GuiWidget sectionContent, ThemeConfig theme, GuiWidget rightAlignedContent = null, int headingPointSize = -1, bool expandingContent = true, bool expanded = true, string serializationKey = null, bool defaultExpansion = false, bool setContentVAnchor = true) + : base(sectionTitle, new GuiWidget(), theme, rightAlignedContent, headingPointSize, expanded, expanded, serializationKey, defaultExpansion, setContentVAnchor) + { + this.VAnchor = VAnchor.Fit; + + this.ResizeContainer = new BottomResizeContainer(theme) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Absolute, + Height = initialHeight + }; + + this.ResizeContainer.Resized += (s, e) => + { + this.Resized?.Invoke(this, null); + }; + + // Add container used to host the current specialized editor for the selection + var scrollableWidget = new ScrollableWidget(true) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Stretch + }; + scrollableWidget.AddChild(sectionContent); + scrollableWidget.ScrollArea.HAnchor = HAnchor.Stretch; + + this.ResizeContainer.AddChild(scrollableWidget); + + // A wrapping container to fix resize quirks - GuiWidget with H:Stretch V:Fit that can be hidden and shown and allow the ResizeContainer can keep it's size + var resizeWrapper = new GuiWidget() + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Fit, + Name = "editorRootContainer" + }; + resizeWrapper.AddChild(this.ResizeContainer); + + this.SetContentWidget(resizeWrapper); + } + } +} \ No newline at end of file diff --git a/PartPreviewWindow/SelectedObjectPanel.cs b/PartPreviewWindow/SelectedObjectPanel.cs index ad2206ee0..26902b12d 100644 --- a/PartPreviewWindow/SelectedObjectPanel.cs +++ b/PartPreviewWindow/SelectedObjectPanel.cs @@ -52,12 +52,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private ThemeConfig theme; private BedConfig sceneContext; private View3DWidget view3DWidget; - private SectionWidget editorSectionWidget; + private ResizableSectionWidget editorSectionWidget; private TextButton editButton; private GuiWidget editorPanel; private InlineTitleEdit inlineTitleEdit; - private BottomResizeContainer editorResizeContainer; public SelectedObjectPanel(View3DWidget view3DWidget, BedConfig sceneContext, ThemeConfig theme) : base(FlowDirection.TopToBottom) @@ -87,25 +86,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.AddChild(scrollable); - editorResizeContainer = new BottomResizeContainer(theme) - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Absolute, - Height = sceneContext.ViewState.SelectedObjectEditorHeight - }; - var toolbar = new Toolbar(theme) { Padding = theme.ToolbarPadding, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit }; - editorResizeContainer.AddChild(toolbar); - - editorResizeContainer.Resized += (s, e) => - { - sceneContext.ViewState.SelectedObjectEditorHeight = editorResizeContainer.Height; - }; var scene = sceneContext.Scene; @@ -185,31 +171,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow scene.SelectionChanged += (s, e) => removeButton.Enabled = scene.SelectedItem?.CanRemove == true; toolbar.AddChild(removeButton); - // Add container used to host the current specialized editor for the selection - var scrollableEditor = new ScrollableWidget(true) - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Stretch - }; - scrollableEditor.AddChild(editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) + editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Padding = new BorderDouble(top: 10) - }); - scrollableEditor.ScrollArea.HAnchor = HAnchor.Stretch; - - editorResizeContainer.AddChild(scrollableEditor); - - // A wrapping container to fix resize quirks - GuiWidget with H:Stretch V:Fit that can be hidden and shown and allow the ResizeContainer can keep it's size - var editorResizeWrapper = new GuiWidget() - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Fit, - Name = "editorRootContainer" }; - editorResizeWrapper.AddChild(editorResizeContainer); - inlineTitleEdit = new InlineTitleEdit("", theme, "Object Name"); inlineTitleEdit.TitleChanged += (s, e) => { @@ -219,10 +186,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } }; - editorSectionWidget = new SectionWidget("Editor", editorResizeWrapper, theme, serializationKey: UserSettingsKey.EditorPanelExpanded, defaultExpansion: true) + editorSectionWidget = new ResizableSectionWidget("Editor", sceneContext.ViewState.SelectedObjectEditorHeight, editorPanel, theme, serializationKey: UserSettingsKey.EditorPanelExpanded, defaultExpansion: true) { VAnchor = VAnchor.Fit, }; + editorSectionWidget.Resized += (s, e) => + { + sceneContext.ViewState.SelectedObjectEditorHeight = editorSectionWidget.ResizeContainer.Height; + }; + + editorSectionWidget.ResizeContainer.AddChild(toolbar, 0); // TODO: Replace hackery with practical solution if (editorSectionWidget.Children.FirstOrDefault() is ExpandCheckboxButton checkbox) @@ -267,10 +240,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow foreach(var sectionWidget in this.ContentPanel.Children()) { // Special case for editorResizeWrapper due to ResizeContainer - if (sectionWidget.ContentPanel == editorResizeWrapper) + if (sectionWidget is ResizableSectionWidget resizableSectionWidget) { // Apply padding to ResizeContainer not wrapper - editorResizeContainer.Padding = new BorderDouble(10, 10, 10, 0); + resizableSectionWidget.ResizeContainer.Padding = new BorderDouble(10, 10, 10, 0); } else { From 626ff1515117941466139c10a34903570f62f893 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 18:39:03 -0700 Subject: [PATCH 8/9] Use new ResizableSectionWidget - Issue MatterHackers/MCCentral#3645 Tree view - Needs title and collapse ability --- PartPreviewWindow/View3D/View3DWidget.cs | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/PartPreviewWindow/View3D/View3DWidget.cs b/PartPreviewWindow/View3D/View3DWidget.cs index 7fbe3c258..ccfb74cc1 100644 --- a/PartPreviewWindow/View3D/View3DWidget.cs +++ b/PartPreviewWindow/View3D/View3DWidget.cs @@ -182,21 +182,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow VAnchor = VAnchor.Fit, }); - treeSection = new BottomResizeContainer(theme) - { - HAnchor = HAnchor.Stretch, - VAnchor = VAnchor.Absolute, - Height = sceneContext.ViewState.SceneTreeHeight - }; - modelViewSidePanel.AddChild(treeSection); - // add the tree view treeView = new TreeView(theme) { - TextColor = theme.Colors.PrimaryTextColor, - PointSize = theme.DefaultFontSize, - HAnchor =HAnchor.Stretch, - VAnchor = VAnchor.Stretch + HAnchor = HAnchor.Left | HAnchor.Fit, + VAnchor = VAnchor.Top | VAnchor.Fit, + Margin = new BorderDouble(left: 30, top: 2) }; treeView.AfterSelect += (s, e) => { @@ -207,7 +198,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } selectedObjectPanel.SetActiveItem((IObject3D)treeView.SelectedNode.Tag); }; - treeSection.AddChild(treeView); + + var treeSection = new ResizableSectionWidget("Design History".Localize(), sceneContext.ViewState.SceneTreeHeight, treeView, theme, expanded: false); + treeSection.Resized += (s, e) => + { + sceneContext.ViewState.SceneTreeHeight = treeSection.ResizeContainer.Height; + }; + modelViewSidePanel.AddChild(treeSection); modelViewSidePanel.AddChild(selectedObjectPanel); splitContainer.AddChild(modelViewSidePanel); @@ -361,8 +358,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow public override void OnClosed(ClosedEventArgs e) { - sceneContext.ViewState.SceneTreeHeight = treeSection.Height; - viewControls3D.TransformStateChanged -= ViewControls3D_TransformStateChanged; Scene.SelectionChanged -= Scene_SelectionChanged; this.InteractionLayer.DrawGlOpaqueContent -= Draw_GlOpaqueContent; @@ -1280,7 +1275,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow protected bool allowAutoRotate = false; public MeshViewerWidget meshViewerWidget; - private BottomResizeContainer treeSection; private bool assigningTreeNode; public InteractiveScene Scene => sceneContext.Scene; From ee2d1cdaf4b6c14ffeabf5af4295fc865c74fb1c Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 22 Jun 2018 18:48:46 -0700 Subject: [PATCH 9/9] Add missing .csproj update --- MatterControl.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/MatterControl.csproj b/MatterControl.csproj index e98bcc6c1..3bfb50245 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -128,6 +128,7 @@ +