diff --git a/MatterControl.csproj b/MatterControl.csproj
index 1025104c0..933784358 100644
--- a/MatterControl.csproj
+++ b/MatterControl.csproj
@@ -208,6 +208,7 @@
+
diff --git a/PartPreviewWindow/GCodeDetails.cs b/PartPreviewWindow/GCodeDetails.cs
index b29493fe6..e03630877 100644
--- a/PartPreviewWindow/GCodeDetails.cs
+++ b/PartPreviewWindow/GCodeDetails.cs
@@ -27,7 +27,6 @@ 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.GCodeVisualizer;
using MatterHackers.MatterControl.SlicerConfiguration;
diff --git a/PartPreviewWindow/GCodeDetailsView.cs b/PartPreviewWindow/GCodeDetailsView.cs
new file mode 100644
index 000000000..dd33b30dc
--- /dev/null
+++ b/PartPreviewWindow/GCodeDetailsView.cs
@@ -0,0 +1,119 @@
+/*
+Copyright (c) 2017, 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.Localizations;
+using MatterHackers.MatterControl.SlicerConfiguration;
+
+namespace MatterHackers.MatterControl.PartPreviewWindow
+{
+ public class GCodeDetailsView : FlowLayoutWidget
+ {
+ private TextWidget massTextWidget;
+ private TextWidget costTextWidget;
+
+ // Cost info is only displayed when available - conditionalCostPanel is invisible when cost <= 0
+ private GuiWidget conditionalCostPanel;
+
+ private EventHandler unregisterEvents;
+
+ public GCodeDetailsView(GCodeDetails gcodeDetails)
+ : base(FlowDirection.TopToBottom)
+ {
+ // put in the print time
+ this.AddChild(new TextWidget("Print Time".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
+ this.AddChild(new TextWidget(gcodeDetails.EstimatedPrintTime, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 14)
+ {
+ Margin = new BorderDouble(0, 9, 0, 3)
+ });
+
+ // show the filament used
+ this.AddChild(new TextWidget("Filament Length".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
+ this.AddChild(new TextWidget(gcodeDetails.FilamentUsed, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
+ {
+ Margin = new BorderDouble(0, 9, 0, 3)
+ });
+
+ this.AddChild(new TextWidget("Filament Volume".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
+ this.AddChild(new TextWidget(gcodeDetails.FilamentVolume, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
+ {
+ Margin = new BorderDouble(0, 9, 0, 3)
+ });
+
+ this.AddChild(new TextWidget("Estimated Mass".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
+
+ this.AddChild(massTextWidget = new TextWidget(gcodeDetails.EstimatedMass, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
+ {
+ Margin = new BorderDouble(0, 9, 0, 3)
+ });
+
+ conditionalCostPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
+ {
+ HAnchor = HAnchor.ParentLeftRight,
+ VAnchor = VAnchor.FitToChildren,
+ Visible = gcodeDetails.TotalCost > 0
+ };
+
+ conditionalCostPanel.AddChild(new TextWidget("Estimated Cost".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
+ conditionalCostPanel.AddChild(costTextWidget = new TextWidget(gcodeDetails.EstimatedCost, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
+ {
+ Margin = new BorderDouble(top: 3)
+ });
+
+ this.AddChild(conditionalCostPanel);
+
+ ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
+ {
+ if (e is StringEventArgs stringEvent)
+ {
+ if (stringEvent.Data == SettingsKey.filament_cost
+ || stringEvent.Data == SettingsKey.filament_diameter
+ || stringEvent.Data == SettingsKey.filament_density)
+ {
+ massTextWidget.Text = gcodeDetails.EstimatedMass;
+ conditionalCostPanel.Visible = gcodeDetails.TotalCost > 0;
+
+ if (gcodeDetails.TotalCost > 0)
+ {
+ costTextWidget.Text = gcodeDetails.EstimatedCost;
+ }
+ }
+ }
+ }, ref unregisterEvents);
+ }
+
+ public override void OnClosed(ClosedEventArgs e)
+ {
+ unregisterEvents?.Invoke(this, null);
+ base.OnClosed(e);
+ }
+ }
+}
diff --git a/PartPreviewWindow/ViewGcodeBasic.cs b/PartPreviewWindow/ViewGcodeBasic.cs
index 79218475c..9c7b783ea 100644
--- a/PartPreviewWindow/ViewGcodeBasic.cs
+++ b/PartPreviewWindow/ViewGcodeBasic.cs
@@ -117,7 +117,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
CreateAndAddChildren();
- ActiveSliceSettings.SettingChanged.RegisterEvent(CheckSettingChanged, ref unregisterEvents);
+ ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
+ {
+ if (e is StringEventArgs stringEvent)
+ {
+ if (stringEvent.Data == "extruder_offset")
+ {
+ printer.BedPlate.GCodeRenderer.Clear3DGCode();
+ }
+ }
+ }, ref unregisterEvents);
// TODO: Why do we clear GCode on AdvancedControlsPanelReloading - assume some slice settings should invalidate. If so, code should be more specific and bound to slice settings changed
ApplicationController.Instance.AdvancedControlsPanelReloading.RegisterEvent((s, e) => printer.BedPlate.GCodeRenderer?.Clear3DGCode(), ref unregisterEvents);
@@ -125,33 +134,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private GCodeFile loadedGCode => printer.BedPlate.LoadedGCode;
- private void CheckSettingChanged(object sender, EventArgs e)
- {
- if (e is StringEventArgs stringEvent)
- {
- if (loadedGCode != null
- && (
- stringEvent.Data == SettingsKey.filament_cost
- || stringEvent.Data == SettingsKey.filament_diameter
- || stringEvent.Data == SettingsKey.filament_density)
- )
- {
- massTextWidget.Text = gcodeDetails.EstimatedMass;
- conditionalCostPanel.Visible = gcodeDetails.TotalCost > 0;
-
- if (gcodeDetails.TotalCost > 0)
- {
- costTextWidget.Text = gcodeDetails.EstimatedCost;
- }
- }
-
- if (stringEvent.Data == "extruder_offset")
- {
- printer.BedPlate.GCodeRenderer.Clear3DGCode();
- }
- }
- }
-
private void CreateAndAddChildren()
{
CloseAllChildren();
@@ -400,73 +382,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
- TextWidget massTextWidget;
- TextWidget costTextWidget;
-
- // Cost info is only displayed when available - conditionalCostPanel is invisible when cost <= 0
- GuiWidget conditionalCostPanel;
-
- GCodeDetails gcodeDetails;
-
- private FlowLayoutWidget CreateModelInfo(GCodeDetails gcodeDetails)
- {
- var modelInfoContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
- {
- Padding = new BorderDouble(5),
- Margin = new BorderDouble(0, 0, 35, 5),
- BackgroundColor = new RGBA_Bytes(0, 0, 0, ViewControlsBase.overlayAlpha),
- HAnchor = HAnchor.ParentRight | HAnchor.AbsolutePosition,
- VAnchor = VAnchor.ParentTop | VAnchor.FitToChildren,
- Width = 150
- };
-
- // put in the print time
- modelInfoContainer.AddChild(new TextWidget("Print Time".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
- modelInfoContainer.AddChild(new TextWidget(gcodeDetails.EstimatedPrintTime, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 14)
- {
- Margin = new BorderDouble(0, 9, 0, 3)
- });
-
- // show the filament used
- modelInfoContainer.AddChild(new TextWidget("Filament Length".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
- modelInfoContainer.AddChild(new TextWidget(gcodeDetails.FilamentUsed, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
- {
- Margin = new BorderDouble(0, 9, 0, 3)
- });
-
- modelInfoContainer.AddChild(new TextWidget("Filament Volume".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
- modelInfoContainer.AddChild(new TextWidget(gcodeDetails.FilamentVolume, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
- {
- Margin = new BorderDouble(0, 9, 0, 3)
- });
-
- modelInfoContainer.AddChild(new TextWidget("Estimated Mass".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
-
- modelInfoContainer.AddChild(massTextWidget = new TextWidget(gcodeDetails.EstimatedMass, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
- {
- Margin = new BorderDouble(0, 9, 0, 3)
- });
-
- conditionalCostPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
- {
- HAnchor = HAnchor.ParentLeftRight,
- VAnchor = VAnchor.FitToChildren,
- Visible = gcodeDetails.TotalCost > 0
- };
-
- conditionalCostPanel.AddChild(new TextWidget("Estimated Cost".Localize() + ":", textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 9));
- conditionalCostPanel.AddChild(costTextWidget = new TextWidget(gcodeDetails.EstimatedCost, pointSize: 14, textColor: ActiveTheme.Instance.PrimaryTextColor)
- {
- Margin = new BorderDouble(0, 9, 0, 3)
- });
-
- modelInfoContainer.AddChild(conditionalCostPanel);
-
- // TODO: Every time you click Generate we wire up a listener - only when we close do they get released. This is a terrible pattern that has a good chance of creating a high leak scenario. Since RootedEventHandlers are normally only cleared when a widget is closed, we should **only** register them in widget constructors
- PrinterConnection.Instance.CommunicationStateChanged.RegisterEvent(HookUpGCodeMessagesWhenDonePrinting, ref unregisterEvents);
-
- return modelInfoContainer;
- }
+ private GCodeDetails gcodeDetails;
internal GuiWidget ShowOverflowMenu()
{
@@ -579,11 +495,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
printItem.SlicingDone -= sliceItem_Done;
generateGCodeButton.Visible = false;
-
- // TODO: Bad pattern - figure out how to revise
- // However if the print finished or is canceled we are going to want to get updates again. So, hook the status event
- PrinterConnection.Instance.CommunicationStateChanged.RegisterEvent(HookUpGCodeMessagesWhenDonePrinting, ref unregisterEvents);
- UiThread.RunOnIdle(SetSyncToPrintVisibility);
}
}
@@ -771,7 +682,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
setLayerWidget.VAnchor = Agg.UI.VAnchor.ParentTop;
layerSelectionButtonsPanel.AddChild(setLayerWidget);
-
+
navigationWidget?.Close();
navigationWidget = new LayerNavigationWidget(gcode2DWidget, ApplicationController.Instance.Theme.GCodeLayerButtons);
navigationWidget.Margin = new BorderDouble(0, 0, 20, 0);
@@ -800,7 +711,21 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
BoundsChanged += new EventHandler(PartPreviewGCode_BoundsChanged);
this.gcodeDetails = new GCodeDetails(this.loadedGCode);
- this.AddChild(CreateModelInfo(gcodeDetails));
+
+ this.AddChild(new GCodeDetailsView(gcodeDetails)
+ {
+ Margin = new BorderDouble(0, 0, 35, 5),
+ Padding = new BorderDouble(10),
+ BackgroundColor = new RGBA_Bytes(0, 0, 0, ViewControlsBase.overlayAlpha),
+ HAnchor = HAnchor.ParentRight | HAnchor.AbsolutePosition,
+ VAnchor = VAnchor.ParentTop | VAnchor.FitToChildren,
+ Width = 150
+ });
+
+ // TODO: Bad pattern - figure out how to revise
+ // However if the print finished or is canceled we are going to want to get updates again. So, hook the status event
+ PrinterConnection.Instance.CommunicationStateChanged.RegisterEvent(HookUpGCodeMessagesWhenDonePrinting, ref unregisterEvents);
+ UiThread.RunOnIdle(SetSyncToPrintVisibility);
// Switch to the most recent view mode, defaulting to Layers3D
SwitchViewModes();