diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 0e78ec419..e4c5eebce 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -316,47 +316,36 @@ namespace MatterHackers.MatterControl { Thread.CurrentThread.Name = $"ThumbnailGeneration"; - while(true) + while(!MatterControlApplication.Instance.HasBeenClosed) { - while(queuedThumbCallbacks.Count > 0) + Thread.Sleep(100); + + try { - if (MatterControlApplication.Instance.HasBeenClosed) + if (queuedThumbCallbacks.Count > 0) { - return; - } + Func callback; + lock (thumbsLock) + { + callback = queuedThumbCallbacks.Dequeue(); + } - Func callback; - lock(thumbsLock) - { - callback = queuedThumbCallbacks.Dequeue(); - } - - try - { await callback(); } - catch(ThreadAbortException e) + else { - return; + // Process until queuedThumbCallbacks is empty then wait for new tasks via QueueForGeneration + thumbGenResetEvent.WaitOne(); } - catch (Exception ex) - { - Console.WriteLine("Error generating thumbnail: " + ex.Message); - } - - Thread.Sleep(100); } - - // Process until queuedThumbCallbacks is empty then wait for new tasks via QueueForGeneration - thumbGenResetEvent.WaitOne(); - - // TODO: Call thumbGenResetEvent on application close to gracefully shutdown - - // Abort if closing - if (MatterControlApplication.Instance.HasBeenClosed) + catch (ThreadAbortException e) { return; } + catch (Exception ex) + { + Console.WriteLine("Error generating thumbnail: " + ex.Message); + } } } @@ -502,7 +491,13 @@ namespace MatterHackers.MatterControl }; // Remove consumed ClientToken from running list on shutdown - ApplicationClosed += (s, e) => ApplicationSettings.Instance.ReleaseClientToken(); + ApplicationClosed += (s, e) => + { + ApplicationSettings.Instance.ReleaseClientToken(); + + // Release the waiting ThumbnailGeneration task so it can shutdown gracefully + thumbGenResetEvent?.Set(); + }; PrinterConnectionAndCommunication.Instance.CommunicationStateChanged.RegisterEvent((s, e) => { @@ -519,6 +514,8 @@ namespace MatterHackers.MatterControl }, ref unregisterEvents); this.InitializeLibrary(); + + } public void StartSignIn() diff --git a/ApplicationView/WidescreenPanel.cs b/ApplicationView/WidescreenPanel.cs index e5760e1dd..1fc46da41 100644 --- a/ApplicationView/WidescreenPanel.cs +++ b/ApplicationView/WidescreenPanel.cs @@ -60,6 +60,12 @@ namespace MatterHackers.MatterControl this.AnchorAll(); this.Name = "WidescreenPanel"; + // HACK: Long term we need a better solution which does not rely on ActivePrintItem/PrintItemWrapper + if (PrinterConnectionAndCommunication.Instance.ActivePrintItem == null) + { + ApplicationController.Instance.ClearPlate(); + } + var library3DViewSplitter = new Splitter() { Padding = new BorderDouble(4), diff --git a/CustomWidgets/DockingTabControl.cs b/CustomWidgets/DockingTabControl.cs index f33e33858..eea9602cb 100644 --- a/CustomWidgets/DockingTabControl.cs +++ b/CustomWidgets/DockingTabControl.cs @@ -103,7 +103,7 @@ namespace MatterHackers.MatterControl.CustomWidgets if (ControlIsPinned) { - var content = new DockWindowContent(this, nameWidget.Value, tabTitle, ControlIsPinned); + var content = new DockWindowContent(this, nameWidget.Value, tabTitle); var tabPage = new TabPage(content, tabTitle); @@ -139,7 +139,7 @@ namespace MatterHackers.MatterControl.CustomWidgets AlignToRightEdge = true, Name = $"{tabTitle} Sidebar" }; - settingsButton.PopupContent = new DockWindowContent(this, nameWidget.Value, tabTitle, ControlIsPinned) + settingsButton.PopupContent = new DockWindowContent(this, nameWidget.Value, tabTitle) { BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor }; @@ -151,19 +151,9 @@ namespace MatterHackers.MatterControl.CustomWidgets { tabControl.TabBar.AddChild(new HorizontalSpacer()); - var icon = StaticData.Instance.LoadIcon("Pushpin_16x.png", 16, 16).InvertLightness(); - var imageWidget = new ImageWidget(icon) - { - VAnchor = VAnchor.ParentCenter - }; - imageWidget.Margin = new BorderDouble(right: 25, top: 6); - imageWidget.MinimumSize = new Vector2(16, 16); - imageWidget.Click += (s, e) => - { - ControlIsPinned = !ControlIsPinned; - UiThread.RunOnIdle(() => Rebuild()); - }; - tabControl.TabBar.AddChild(imageWidget); + var pinButton = this.CreatePinButton(); + pinButton.Margin = new BorderDouble(right: 18, bottom: 7); + tabControl.TabBar.AddChild(pinButton); } } @@ -174,7 +164,6 @@ namespace MatterHackers.MatterControl.CustomWidgets Width = 30; VAnchor = VAnchor.ParentBottomTop; HAnchor = HAnchor.FitToChildren; - //BackgroundColor = RGBA_Bytes.Red; topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.FitToChildren, @@ -233,9 +222,27 @@ namespace MatterHackers.MatterControl.CustomWidgets } } + private ImageWidget CreatePinButton() + { + var icon = StaticData.Instance.LoadIcon(this.isPinned ? "Pushpin_16x.png" : "PushpinUnpin_16x.png", 16, 16).InvertLightness(); + var imageWidget = new ImageWidget(icon) + { + Name = "Pin Settings Button", + Margin = new BorderDouble(right: 25, top: 6), + MinimumSize = new Vector2(16, 16) + }; + imageWidget.Click += (s, e) => + { + this.ControlIsPinned = !this.ControlIsPinned; + UiThread.RunOnIdle(() => this.Rebuild()); + }; + + return imageWidget; + } + private class DockWindowContent : GuiWidget, IIgnoredPopupChild { - internal DockWindowContent(DockingTabControl parent, GuiWidget child, string title, bool isDocked) + internal DockWindowContent(DockingTabControl dockingControl, GuiWidget child, string title) { var topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom) { @@ -243,7 +250,7 @@ namespace MatterHackers.MatterControl.CustomWidgets HAnchor = HAnchor.ParentLeftRight }; - if (!isDocked) + if (!dockingControl.ControlIsPinned) { var titleBar = new FlowLayoutWidget() { @@ -256,22 +263,9 @@ namespace MatterHackers.MatterControl.CustomWidgets Margin = new BorderDouble(left: 12) }); + titleBar.AddChild(new HorizontalSpacer()); - titleBar.AddChild(new HorizontalSpacer() { Height = 5, DebugShowBounds = false }); - - var icon = StaticData.Instance.LoadIcon((isDocked) ? "Pushpin_16x.png" : "PushpinUnpin_16x.png", 16, 16).InvertLightness(); - var imageWidget = new ImageWidget(icon) - { - Name = "Pin Settings Button", - Margin = new BorderDouble(right: 25, top: 6), - MinimumSize = new Vector2(16, 16) - }; - imageWidget.Click += (s, e) => - { - parent.ControlIsPinned = !parent.ControlIsPinned; - UiThread.RunOnIdle(() => parent.Rebuild()); - }; - titleBar.AddChild(imageWidget); + titleBar.AddChild(dockingControl.CreatePinButton()); topToBottom.AddChild(titleBar); } diff --git a/PartPreviewWindow/View3D/View3DWidget.cs b/PartPreviewWindow/View3D/View3DWidget.cs index abbcf3d1b..41809c8e9 100644 --- a/PartPreviewWindow/View3D/View3DWidget.cs +++ b/PartPreviewWindow/View3D/View3DWidget.cs @@ -244,6 +244,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.openMode = openMode; allowAutoRotate = (autoRotate == AutoRotate.Enabled); meshViewerWidget = new MeshViewerWidget(viewerVolume, bedCenter, bedShape); + this.printItemWrapper = printItemWrapper; } public override void Initialize() @@ -253,7 +254,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.windowType = windowType; autoRotating = allowAutoRotate; - this.printItemWrapper = printItemWrapper; this.Name = "View3DWidget"; this.BackgroundColor = ApplicationController.Instance.Theme.TabBodyBackground; diff --git a/Tests/MatterControl.AutomationTests/PrintingTests.cs b/Tests/MatterControl.AutomationTests/PrintingTests.cs index 87a6eb81d..17abdf935 100644 --- a/Tests/MatterControl.AutomationTests/PrintingTests.cs +++ b/Tests/MatterControl.AutomationTests/PrintingTests.cs @@ -78,7 +78,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Type("2"); // switch to controls so we can see the heights - testRunner.ClickByName("Controls Tab"); + testRunner.SwitchToControlsTab(); // run the leveling wizard testRunner.ClickByName("Finish Setup Button"); @@ -228,8 +228,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.ClickByName("Layer(s) To Pause: Edit"); testRunner.Type("2;6"); - // switch to controls so we can see the heights - testRunner.ClickByName("Controls Tab"); + testRunner.ClickByName("Pin Settings Button"); // print a part testRunner.AddDefaultFileToBedplate(); @@ -275,7 +274,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.AddDefaultFileToBedplate(); - testRunner.ClickByName("Controls Tab", 1); + testRunner.SwitchToControlsTab(); // Wait for printing to complete var printFinishedResetEvent = new AutoResetEvent(false); @@ -308,8 +307,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Type(targetFeedRate.ToString()); // Force focus away from the feed rate field, causing an persisted update - testRunner.ClickByName("Controls Tab", 1); - testRunner.Delay(); + testRunner.ClickByName("Extrusion Multiplier NumberEdit"); ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate); @@ -368,7 +366,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.AddDefaultFileToBedplate(); - testRunner.ClickByName("Controls Tab", 1); + testRunner.SwitchToControlsTab(); var printFinishedResetEvent = new AutoResetEvent(false); PrinterConnectionAndCommunication.Instance.PrintFinished.RegisterEvent((s, e) => printFinishedResetEvent.Set(), ref unregisterEvents); @@ -400,8 +398,7 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Type(targetFeedRate.ToString()); // Force focus away from the feed rate field, causing an persisted update - testRunner.ClickByName("Controls Tab", 1); - testRunner.Delay(); + testRunner.SwitchToControlsTab(); ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate); diff --git a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs index 16be0d914..ce4ded654 100644 --- a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs +++ b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs @@ -290,12 +290,12 @@ namespace MatterHackers.MatterControl.Tests.Automation Assert.IsFalse(testRunner.WaitForName("Bed Temperature Textbox", 2), "Filament -> Bed Temp should not be visible after Heated Bed unchecked"); // Make sure Bed Temperature Options are not visible in printer controls - testRunner.ClickByName("Controls Tab"); + testRunner.SwitchToControlsTab(); Assert.IsFalse(testRunner.WaitForName("Bed Temperature Controls Widget", 2), "Controls -> Bed Temp should not be visible after Heated Bed unchecked"); return Task.CompletedTask; - }, overrideWidth: 550); + }, overrideWidth: 1300); } [Test] diff --git a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs index 4aa1b5fd6..f4361034e 100644 --- a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs +++ b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs @@ -549,9 +549,7 @@ namespace MatterHackers.MatterControl.Tests.Automation public static void SwitchToAdvancedSliceSettings(this AutomationRunner testRunner) { testRunner.ClickByName("Slice Settings Sidebar"); - testRunner.ClickByName("Pin Settings Button"); - testRunner.Delay(1); // Switch to Slice Settings Tab @@ -566,6 +564,19 @@ namespace MatterHackers.MatterControl.Tests.Automation testRunner.Delay(.5); } + public static void SwitchToControlsTab(this AutomationRunner testRunner) + { + // If the sidebar exists, we need to expand and pin it + if (testRunner.WaitForName("Slice Settings Sidebar", 0.2)) + { + testRunner.ClickByName("Slice Settings Sidebar"); + testRunner.ClickByName("Pin Settings Button"); + testRunner.Delay(1); + } + + testRunner.ClickByName("Controls Tab"); + } + /// /// Adds the given asset names to the local library and validates the result ///