2017-07-06 12:22:56 -07:00
/ *
2018-05-22 22:06:20 -07:00
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
2017-07-06 12:22:56 -07:00
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 .
* /
2017-07-07 16:50:47 -07:00
using System ;
2017-07-10 12:32:41 -07:00
using System.Linq ;
2017-07-06 12:22:56 -07:00
using MatterHackers.Agg ;
2017-10-30 15:54:16 -07:00
using MatterHackers.Agg.Platform ;
2017-07-06 12:22:56 -07:00
using MatterHackers.Agg.UI ;
2021-05-21 15:23:25 -07:00
using MatterHackers.ImageProcessing ;
2017-07-06 12:22:56 -07:00
using MatterHackers.Localizations ;
2019-01-18 09:49:38 -08:00
using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling ;
2017-07-06 12:22:56 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
2017-10-30 15:54:16 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2020-08-01 15:59:20 -07:00
using MatterHackers.MatterControl.PrinterControls ;
2017-07-06 12:22:56 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
using MatterHackers.VectorMath ;
2019-01-18 09:49:38 -08:00
using static MatterHackers . MatterControl . StyledMessageBox ;
2017-07-06 12:22:56 -07:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2022-02-02 17:31:44 -08:00
public class PrinterTabPage : DesignTabPage
2017-07-06 12:22:56 -07:00
{
2019-05-12 21:00:37 -07:00
private GCode2DWidget gcode2DWidget ;
2017-09-15 16:49:21 -07:00
2017-08-16 22:45:46 -07:00
private View3DConfig gcodeOptions ;
2019-02-22 09:22:13 -08:00
2019-05-12 21:00:37 -07:00
private readonly DoubleSolidSlider layerRenderRatioSlider ;
2019-02-22 09:22:13 -08:00
2018-03-14 15:51:43 -07:00
private GCodePanel gcodePanel ;
2019-05-12 21:00:37 -07:00
private VerticalResizeContainer gcodeContainer ;
public PrinterActionsBar PrinterActionsBar { get ; set ; }
2018-01-03 15:24:55 -08:00
private DockingTabControl sideBar ;
private SliceSettingsWidget sliceSettingsWidget ;
2017-09-15 16:49:21 -07:00
2018-12-12 17:12:06 -08:00
public PrinterTabPage ( PartWorkspace workspace , ThemeConfig theme , string tabTitle )
: base ( workspace , theme , tabTitle )
2017-07-06 12:22:56 -07:00
{
2018-05-22 22:06:20 -07:00
gcodeOptions = sceneContext . RendererOptions ;
2018-04-12 08:42:10 -07:00
2020-09-12 13:09:17 -07:00
view3DWidget . Object3DControlLayer . EditorMode = Object3DControlsLayer . EditorType . Printer ;
2017-08-17 10:52:47 -07:00
2021-09-13 21:47:46 -07:00
viewToolBarControls . TransformStateChanged + = ( s , e ) = >
2017-07-10 12:23:02 -07:00
{
switch ( e . TransformMode )
{
2021-05-22 22:24:12 -07:00
case ViewControls3DButtons . Scale :
2017-07-10 12:23:02 -07:00
if ( gcode2DWidget ! = null )
{
2021-05-22 22:24:12 -07:00
gcode2DWidget . TransformState = GCode2DWidget . ETransformState . Scale ;
2017-07-10 12:23:02 -07:00
}
break ;
2021-05-22 22:24:12 -07:00
default :
2017-07-10 12:23:02 -07:00
if ( gcode2DWidget ! = null )
{
2021-05-22 22:24:12 -07:00
gcode2DWidget . TransformState = GCode2DWidget . ETransformState . Move ;
2017-07-10 12:23:02 -07:00
}
break ;
}
} ;
2021-09-13 21:47:46 -07:00
viewToolBarControls . ResetView + = ( sender , e ) = >
2017-07-06 12:22:56 -07:00
{
2017-07-13 15:35:05 -07:00
if ( gcode2DWidget ? . Visible = = true )
2017-07-10 12:23:02 -07:00
{
gcode2DWidget . CenterPartInView ( ) ;
}
2017-07-06 12:22:56 -07:00
} ;
2017-11-27 17:36:36 -08:00
2018-10-21 11:29:59 -07:00
var opaqueTrackColor = theme . ResolveColor ( theme . BedBackgroundColor , theme . SlightShade ) ;
2020-12-30 10:35:47 -08:00
LayerScrollbar = new SliceLayerSelector ( Printer , theme )
2017-07-07 16:50:47 -07:00
{
2017-09-13 15:55:12 -07:00
VAnchor = VAnchor . Stretch ,
2018-03-29 13:27:39 -07:00
HAnchor = HAnchor . Right | HAnchor . Fit ,
2018-02-21 18:43:56 -08:00
Margin = new BorderDouble ( 0 , 4 , 4 , 4 ) ,
2017-11-29 16:40:46 -08:00
Maximum = sceneContext . LoadedGCode ? . LayerCount ? ? 1
2017-07-06 14:41:32 -07:00
} ;
2018-10-21 11:29:59 -07:00
LayerScrollbar . SolidSlider . View . TrackColor = opaqueTrackColor ;
2020-09-11 19:59:14 -07:00
view3DWidget . Object3DControlLayer . AddChild ( LayerScrollbar ) ;
2018-01-03 15:24:55 -08:00
2019-05-12 21:00:37 -07:00
layerRenderRatioSlider = new DoubleSolidSlider ( default ( Vector2 ) , SliceLayerSelector . SliderWidth , theme ) ;
2017-07-06 14:41:32 -07:00
layerRenderRatioSlider . FirstValue = 0 ;
layerRenderRatioSlider . FirstValueChanged + = ( s , e ) = >
{
2017-09-15 16:49:21 -07:00
sceneContext . RenderInfo . FeatureToStartOnRatio0To1 = layerRenderRatioSlider . FirstValue ;
sceneContext . RenderInfo . FeatureToEndOnRatio0To1 = layerRenderRatioSlider . SecondValue ;
2017-07-06 14:41:32 -07:00
this . Invalidate ( ) ;
} ;
layerRenderRatioSlider . SecondValue = 1 ;
layerRenderRatioSlider . SecondValueChanged + = ( s , e ) = >
{
2020-12-30 10:35:47 -08:00
if ( Printer ? . Bed ? . RenderInfo ! = null )
2017-09-01 17:41:43 -07:00
{
2017-09-15 16:49:21 -07:00
sceneContext . RenderInfo . FeatureToStartOnRatio0To1 = layerRenderRatioSlider . FirstValue ;
sceneContext . RenderInfo . FeatureToEndOnRatio0To1 = layerRenderRatioSlider . SecondValue ;
2017-09-01 17:41:43 -07:00
}
2017-07-06 14:41:32 -07:00
this . Invalidate ( ) ;
} ;
2020-09-11 19:59:14 -07:00
view3DWidget . Object3DControlLayer . AddChild ( layerRenderRatioSlider ) ;
2018-10-21 11:29:59 -07:00
theme . ApplySliderStyle ( layerRenderRatioSlider ) ;
layerRenderRatioSlider . View . TrackColor = opaqueTrackColor ;
2017-07-06 14:41:32 -07:00
2017-10-21 20:22:14 -07:00
AddSettingsTabBar ( leftToRight , view3DWidget ) ;
2017-07-07 12:52:00 -07:00
2020-09-11 19:59:14 -07:00
view3DWidget . Object3DControlLayer . BoundsChanged + = ( s , e ) = >
2017-08-16 22:45:46 -07:00
{
SetSliderSizes ( ) ;
} ;
2020-12-30 10:35:47 -08:00
PrinterActionsBar = new PrinterActionsBar ( Printer , this , theme ) ;
2019-05-12 21:00:37 -07:00
theme . ApplyBottomBorder ( PrinterActionsBar ) ;
PrinterActionsBar . modelViewButton . Enabled = sceneContext . EditableScene ;
2017-10-19 09:04:36 -07:00
// Must come after we have an instance of View3DWidget an its undo buffer
2019-05-12 21:00:37 -07:00
topToBottom . AddChild ( PrinterActionsBar , 0 ) ;
2017-10-19 09:04:36 -07:00
2020-09-11 19:59:14 -07:00
var trackball = view3DWidget . Object3DControlLayer . Children < TrackballTumbleWidget > ( ) . FirstOrDefault ( ) ;
2017-10-30 08:53:53 -07:00
2020-09-11 19:59:14 -07:00
tumbleCubeControl = view3DWidget . Object3DControlLayer . Children < TumbleCubeControl > ( ) . FirstOrDefault ( ) ;
2018-03-09 08:04:33 -08:00
2020-09-11 19:59:14 -07:00
var position = view3DWidget . Object3DControlLayer . Children . IndexOf ( trackball ) ;
2017-10-30 08:53:53 -07:00
2020-12-30 10:35:47 -08:00
gcodePanel = new GCodePanel ( this , Printer , sceneContext , theme )
2017-10-30 08:53:53 -07:00
{
2017-10-30 09:00:14 -07:00
Name = "GCode3DWidget" ,
2017-10-30 08:53:53 -07:00
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
2020-09-14 07:36:32 -07:00
BackgroundColor = theme . InteractionLayerOverlayColor ,
2017-10-30 08:53:53 -07:00
} ;
2018-02-16 18:49:36 -08:00
2018-10-14 17:50:54 -07:00
var modelViewSidePanel = view3DWidget . Descendants < VerticalResizeContainer > ( ) . FirstOrDefault ( ) ;
2018-04-18 09:36:53 -07:00
2018-10-14 17:50:54 -07:00
gcodeContainer = new VerticalResizeContainer ( theme , GrabBarSide . Left )
2018-02-16 18:49:36 -08:00
{
2020-06-07 23:09:01 -07:00
Width = UserSettings . Instance . SelectedObjectPanelWidth ,
2018-02-16 18:49:36 -08:00
VAnchor = VAnchor . Stretch ,
2018-02-17 10:42:58 -08:00
HAnchor = HAnchor . Absolute ,
2018-10-25 14:43:21 -07:00
SplitterBarColor = theme . SplitterBackground ,
2018-02-16 18:49:36 -08:00
SplitterWidth = theme . SplitterWidth ,
Visible = false ,
} ;
2018-05-30 16:42:17 -07:00
2018-03-14 15:49:00 -07:00
gcodeContainer . AddChild ( gcodePanel ) ;
2018-05-30 16:42:17 -07:00
gcodeContainer . Resized + = ( s , e ) = >
{
2020-12-30 10:35:47 -08:00
if ( Printer ! = null )
2018-05-30 16:42:17 -07:00
{
2020-06-07 23:09:01 -07:00
UserSettings . Instance . SelectedObjectPanelWidth = gcodeContainer . Width ;
2018-05-30 16:42:17 -07:00
}
} ;
2018-02-16 18:49:36 -08:00
2018-04-18 09:36:53 -07:00
modelViewSidePanel . BoundsChanged + = ( s , e ) = >
{
gcodeContainer . Width = modelViewSidePanel . Width ;
} ;
gcodeContainer . BoundsChanged + = ( s , e ) = >
{
modelViewSidePanel . Width = gcodeContainer . Width ;
} ;
2018-12-29 16:37:17 -08:00
var splitContainer = view3DWidget . FindDescendant ( "SplitContainer" ) ;
2018-02-17 10:42:58 -08:00
splitContainer . AddChild ( gcodeContainer ) ;
2017-10-30 08:53:53 -07:00
2017-11-29 14:41:55 -08:00
// Create and append new widget
2020-12-30 10:35:47 -08:00
gcode2DWidget = new GCode2DWidget ( Printer , theme )
2017-11-29 14:41:55 -08:00
{
2020-12-30 10:35:47 -08:00
Visible = Printer . ViewState . ViewMode = = PartViewMode . Layers2D
2017-11-29 14:41:55 -08:00
} ;
2021-04-19 10:52:04 -07:00
var trackballIndex = 0 ;
foreach ( var child in view3DWidget . Object3DControlLayer . Children )
{
if ( child is TrackballTumbleWidgetExtended )
{
break ;
}
trackballIndex + + ;
}
view3DWidget . Object3DControlLayer . AddChild ( gcode2DWidget , trackballIndex + 1 ) ;
2017-11-29 14:41:55 -08:00
2017-08-16 22:45:46 -07:00
SetSliderSizes ( ) ;
2017-07-06 12:22:56 -07:00
2020-12-30 10:35:47 -08:00
this . SetViewMode ( Printer . ViewState . ViewMode ) ;
2018-01-03 15:24:55 -08:00
2018-09-24 12:21:58 -07:00
this . LayerScrollbar . Margin = LayerScrollbar . Margin . Clone ( top : tumbleCubeControl . Height + tumbleCubeControl . Margin . Height + 4 ) ;
2019-03-03 16:57:50 -08:00
// On load, switch to gcode view if previously editing gcode file. Listeners would normally do this but workspace loads before this UI widget
2019-05-12 21:00:37 -07:00
if ( this ? . PrinterActionsBar ? . modelViewButton is GuiWidget button )
2019-03-03 16:57:50 -08:00
{
button . Enabled = sceneContext . EditableScene ;
if ( sceneContext . ContentType = = "gcode"
2019-05-12 21:00:37 -07:00
& & this ? . PrinterActionsBar ? . layers3DButton is GuiWidget gcodeButton )
2019-03-03 16:57:50 -08:00
{
gcodeButton . InvokeClick ( ) ;
}
}
2018-11-27 12:55:30 -08:00
// Register listeners
2020-12-30 10:35:47 -08:00
Printer . ViewState . VisibilityChanged + = ProcessOptionalTabs ;
Printer . ViewState . ViewModeChanged + = ViewState_ViewModeChanged ;
2019-01-18 09:49:38 -08:00
2020-12-30 10:35:47 -08:00
Printer . Bed . RendererOptions . PropertyChanged + = RendererOptions_PropertyChanged ;
2019-01-18 09:49:38 -08:00
// register for communication messages
2020-12-30 10:35:47 -08:00
Printer . Connection . CommunicationStateChanged + = Connection_CommunicationStateChanged ;
Printer . Connection . PauseOnLayer + = Connection_PauseOnLayer ;
Printer . Connection . FilamentRunout + = Connection_FilamentRunout ;
2019-01-18 09:49:38 -08:00
2018-11-27 12:55:30 -08:00
ApplicationController . Instance . ApplicationError + = ApplicationController_ApplicationError ;
2018-11-30 12:35:56 -08:00
ApplicationController . Instance . ApplicationEvent + = ApplicationController_ApplicationEvent ;
2018-11-27 12:55:30 -08:00
sceneContext . LoadedGCodeChanged + = BedPlate_LoadedGCodeChanged ;
}
2019-02-22 09:22:13 -08:00
public SliceLayerSelector LayerScrollbar { get ; private set ; }
public DoubleSolidSlider LayerFeaturesScrollbar = > layerRenderRatioSlider ;
2019-02-22 06:42:14 -08:00
public int LayerFeaturesIndex
{
get
{
var renderInfo = sceneContext . RenderInfo ;
int layerIndex = renderInfo . EndLayerIndex - 1 ;
int featuresOnLayer = sceneContext . GCodeRenderer . GetNumFeatures ( layerIndex ) ;
int featureIndex = ( int ) ( featuresOnLayer * renderInfo . FeatureToEndOnRatio0To1 + . 5 ) ;
return Math . Max ( 0 , Math . Min ( featureIndex , featuresOnLayer ) ) ;
}
set
{
var renderInfo = sceneContext . RenderInfo ;
int layerIndex = renderInfo . EndLayerIndex - 1 ;
int featuresOnLayer = sceneContext . GCodeRenderer . GetNumFeatures ( layerIndex ) ;
var factor = ( double ) value / featuresOnLayer ;
layerRenderRatioSlider . SecondValue = renderInfo . FeatureToEndOnRatio0To1 = Math . Max ( 0 , Math . Min ( factor , 1 ) ) ;
}
}
2019-05-12 21:00:37 -07:00
private readonly string pauseCaption = "Printer Paused" . Localize ( ) ;
2019-01-18 09:49:38 -08:00
private void ResumePrint ( bool clickedOk )
{
// They clicked either Resume or Ok
2020-12-30 10:35:47 -08:00
if ( clickedOk & & Printer . Connection . Paused )
2019-01-18 09:49:38 -08:00
{
2020-12-30 10:35:47 -08:00
Printer . Connection . Resume ( ) ;
2019-01-18 09:49:38 -08:00
}
}
protected GuiWidget CreateTextField ( string text )
{
return new WrappedTextWidget ( text )
{
Margin = new BorderDouble ( left : 10 , top : 10 ) ,
TextColor = theme . TextColor ,
} ;
}
private void Connection_FilamentRunout ( object sender , PrintPauseEventArgs e )
{
if ( e is PrintPauseEventArgs printePauseEventArgs )
{
2019-04-26 15:53:02 -07:00
if ( printePauseEventArgs . FilamentRunout )
2019-01-18 09:49:38 -08:00
{
2019-01-18 12:13:31 -08:00
UiThread . RunOnIdle ( ( ) = >
2019-01-18 09:49:38 -08:00
{
2019-01-18 12:13:31 -08:00
var unloadFilamentButton = new TextButton ( "Unload Filament" . Localize ( ) , theme )
{
Name = "unload Filament" ,
BackgroundColor = theme . MinimalShade ,
VAnchor = Agg . UI . VAnchor . Absolute ,
HAnchor = Agg . UI . HAnchor . Fit | Agg . UI . HAnchor . Left ,
Margin = new BorderDouble ( 10 , 10 , 0 , 15 )
} ;
2019-06-28 22:22:58 -07:00
unloadFilamentButton . Click + = ( s , e2 ) = >
2019-01-18 09:49:38 -08:00
{
2019-02-16 13:55:27 -08:00
unloadFilamentButton . Parents < SystemWindow > ( ) . First ( ) . Close ( ) ;
2020-12-30 10:35:47 -08:00
DialogWindow . Show ( new UnloadFilamentWizard ( Printer , extruderIndex : 0 ) ) ;
2019-06-28 22:22:58 -07:00
} ;
2019-01-18 12:13:31 -08:00
theme . ApplyPrimaryActionStyle ( unloadFilamentButton ) ;
string filamentPauseMessage = "Your 3D print has been paused.\n\nOut of filament, or jam, detected. Please load more filament or clear the jam." . Localize ( ) ;
var messageBox = new MessageBoxPage ( ResumePrint ,
2019-04-26 15:53:02 -07:00
filamentPauseMessage . FormatWith ( printePauseEventArgs . LayerNumber ) ,
2019-01-18 12:13:31 -08:00
pauseCaption ,
StyledMessageBox . MessageType . YES_NO_WITHOUT_HIGHLIGHT ,
null ,
500 ,
400 ,
"Resume" . Localize ( ) ,
"OK" . Localize ( ) ,
2019-05-12 21:00:37 -07:00
ApplicationController . Instance . Theme ,
false ) ;
2019-01-18 12:13:31 -08:00
messageBox . AddPageAction ( unloadFilamentButton ) ;
DialogWindow . Show ( messageBox ) ;
} ) ;
2019-01-18 09:49:38 -08:00
}
}
}
private void Connection_PauseOnLayer ( object sender , EventArgs e )
{
if ( e is PrintPauseEventArgs printePauseEventArgs )
{
2019-04-30 15:57:54 -07:00
string layerPauseMessage = "Your 3D print has been auto-paused.\n\nLayer {0} reached." . Localize ( ) ;
2019-01-18 09:49:38 -08:00
UiThread . RunOnIdle ( ( ) = > StyledMessageBox . ShowMessageBox ( ResumePrint ,
2019-04-26 15:53:02 -07:00
layerPauseMessage . FormatWith ( printePauseEventArgs . LayerNumber ) ,
2019-01-18 09:49:38 -08:00
pauseCaption ,
StyledMessageBox . MessageType . YES_NO ,
"Resume" . Localize ( ) ,
"OK" . Localize ( ) ) ) ;
}
}
2018-11-30 12:35:56 -08:00
private void ApplicationController_ApplicationEvent ( object sender , string e )
{
2020-12-30 10:35:47 -08:00
Printer . Connection . TerminalLog . WriteLine ( e ) ;
2018-11-30 12:35:56 -08:00
}
2018-11-27 12:55:30 -08:00
private void ApplicationController_ApplicationError ( object sender , string e )
{
2020-12-30 10:35:47 -08:00
Printer . Connection . TerminalLog . WriteLine ( e ) ;
2018-01-03 15:24:55 -08:00
}
2018-04-07 23:46:01 -07:00
private void RendererOptions_PropertyChanged ( object sender , System . ComponentModel . PropertyChangedEventArgs e )
{
2020-12-30 10:35:47 -08:00
if ( e . PropertyName = = nameof ( Printer . Bed . RendererOptions . SyncToPrint ) )
2018-04-07 23:46:01 -07:00
{
this . SetSliderVisibility ( ) ;
}
}
2018-04-02 12:59:18 -07:00
private void ViewState_ViewModeChanged ( object sender , ViewModeChangedEventArgs e )
{
this . SetViewMode ( e . ViewMode ) ;
}
2018-09-07 14:49:26 -07:00
private void ProcessOptionalTabs ( object sender , EventArgs e )
2018-01-03 15:24:55 -08:00
{
2018-09-07 14:49:26 -07:00
this . ProcessOptionalTabs ( ) ;
2017-11-29 15:22:18 -08:00
}
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
private void SetViewMode ( PartViewMode viewMode )
2017-08-16 22:45:46 -07:00
{
2018-03-14 15:49:00 -07:00
if ( gcodePanel = = null | | gcode2DWidget = = null )
2017-07-06 12:22:56 -07:00
{
2017-11-29 15:22:18 -08:00
// Wait for controls to initialize
return ;
}
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
switch ( viewMode )
{
case PartViewMode . Layers2D :
2018-04-18 14:38:09 -07:00
UserSettings . Instance . set ( UserSettingsKey . LayerViewDefault , "2D Layer" ) ;
2017-11-29 15:22:18 -08:00
gcode2DWidget . Visible = true ;
break ;
case PartViewMode . Layers3D :
2018-04-18 14:38:09 -07:00
UserSettings . Instance . set ( UserSettingsKey . LayerViewDefault , "3D Layer" ) ;
2017-11-29 15:22:18 -08:00
break ;
case PartViewMode . Model :
break ;
}
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
gcode2DWidget . Visible = viewMode = = PartViewMode . Layers2D ;
2017-07-06 12:22:56 -07:00
2020-12-30 10:35:47 -08:00
view3DWidget . Object3DControlLayer . DrawOpenGLContent = Printer ? . ViewState . ViewMode ! = PartViewMode . Layers2D ;
2019-02-06 09:31:07 -08:00
sceneContext . ViewState . ModelView = viewMode = = PartViewMode . Model ;
2018-03-09 08:04:33 -08:00
gcodeContainer . Visible = viewMode ! = PartViewMode . Model ;
tumbleCubeControl . Visible = ! gcode2DWidget . Visible ;
2018-02-16 18:49:36 -08:00
2018-03-09 08:04:33 -08:00
if ( viewMode = = PartViewMode . Layers3D )
2017-11-29 15:22:18 -08:00
{
2020-12-30 10:35:47 -08:00
Printer . Bed . Scene . ClearSelection ( ) ;
2017-08-16 22:45:46 -07:00
}
2017-11-29 15:22:18 -08:00
2018-02-16 15:50:33 -08:00
this . SetSliderVisibility ( ) ;
2017-11-29 15:22:18 -08:00
2020-12-30 10:35:47 -08:00
view3DWidget . modelViewSidePanel . Visible = Printer ? . ViewState . ViewMode = = PartViewMode . Model ;
2017-07-06 12:22:56 -07:00
}
2017-07-06 14:41:32 -07:00
private void BedPlate_LoadedGCodeChanged ( object sender , EventArgs e )
{
2018-02-16 15:50:33 -08:00
this . SetSliderVisibility ( ) ;
2017-10-17 12:55:58 -07:00
2018-02-16 15:50:33 -08:00
if ( sceneContext . LoadedGCode = = null )
2017-10-17 12:55:58 -07:00
{
return ;
}
2018-04-23 18:48:17 -07:00
LayerScrollbar . Maximum = sceneContext . LoadedGCode . LayerCount ;
2017-07-06 14:41:32 -07:00
}
2018-02-16 15:50:33 -08:00
private void SetSliderVisibility ( )
2017-07-06 12:22:56 -07:00
{
2020-12-30 10:35:47 -08:00
bool printerIsRunningPrint = Printer . Connection . Paused | | Printer . Connection . Printing ;
2017-07-06 12:22:56 -07:00
2017-08-16 22:45:46 -07:00
if ( gcodeOptions . SyncToPrint & & printerIsRunningPrint )
2017-07-06 12:22:56 -07:00
{
2017-08-16 22:45:46 -07:00
SetAnimationPosition ( ) ;
layerRenderRatioSlider . Visible = false ;
2018-04-23 18:48:17 -07:00
LayerScrollbar . Visible = false ;
2017-07-06 12:22:56 -07:00
}
else
{
2017-08-16 22:45:46 -07:00
if ( layerRenderRatioSlider ! = null )
{
layerRenderRatioSlider . FirstValue = 0 ;
layerRenderRatioSlider . SecondValue = 1 ;
}
2017-07-06 12:22:56 -07:00
2020-12-30 10:35:47 -08:00
bool hasLayers = Printer . Bed . LoadedGCode ? . LayerCount > 0 ;
2018-02-16 15:50:33 -08:00
2018-05-09 08:41:29 -07:00
layerRenderRatioSlider . Visible = hasLayers & & ! sceneContext . ViewState . ModelView ;
LayerScrollbar . Visible = hasLayers & & ! sceneContext . ViewState . ModelView ;
2017-08-16 22:45:46 -07:00
}
2017-07-06 12:22:56 -07:00
}
2017-08-16 22:45:46 -07:00
private void SetSliderSizes ( )
2017-07-06 14:41:32 -07:00
{
2018-04-23 18:48:17 -07:00
if ( LayerScrollbar = = null | | view3DWidget = = null )
2017-07-06 14:41:32 -07:00
{
2017-08-16 22:45:46 -07:00
return ;
}
2017-07-06 14:41:32 -07:00
2018-02-21 18:43:56 -08:00
layerRenderRatioSlider . OriginRelativeParent = new Vector2 ( 4 , 13 ) ;
2020-09-11 19:59:14 -07:00
layerRenderRatioSlider . TotalWidthInPixels = view3DWidget . Object3DControlLayer . Width - 32 ;
2017-07-06 12:22:56 -07:00
}
2017-10-21 20:22:14 -07:00
2018-04-04 15:58:57 -07:00
private double lastPosition = 0 ;
2018-03-09 08:04:33 -08:00
private TumbleCubeControl tumbleCubeControl ;
2018-02-16 15:50:33 -08:00
private bool SetAnimationPosition ( )
2017-07-07 06:18:58 -07:00
{
2020-12-30 10:35:47 -08:00
LayerScrollbar . Value = Printer . Connection . CurrentlyPrintingLayer ;
2018-02-16 15:50:33 -08:00
2020-12-30 10:35:47 -08:00
double currentPosition = Printer . Connection . RatioIntoCurrentLayerInstructions ;
2018-02-16 14:20:15 -08:00
layerRenderRatioSlider . FirstValue = 0 ;
2018-02-16 15:50:33 -08:00
2018-04-04 15:58:57 -07:00
if ( lastPosition ! = currentPosition )
2018-02-16 15:50:33 -08:00
{
layerRenderRatioSlider . SecondValue = currentPosition ;
2018-04-04 15:58:57 -07:00
lastPosition = currentPosition ;
2018-02-16 15:50:33 -08:00
return true ;
}
return false ;
2017-07-10 12:32:41 -07:00
}
2018-01-21 21:07:14 -08:00
internal void ShowGCodeOverflowMenu ( PopupMenu popupMenu )
2017-07-06 14:41:32 -07:00
{
}
2017-08-16 22:45:46 -07:00
public override void OnDraw ( Graphics2D graphics2D )
2017-07-06 14:41:32 -07:00
{
2020-12-30 10:35:47 -08:00
bool printerIsRunningPrint = Printer . Connection . Paused | | Printer . Connection . Printing ;
2017-08-16 22:45:46 -07:00
if ( gcodeOptions . SyncToPrint
& & printerIsRunningPrint
2020-12-30 10:35:47 -08:00
& & Printer . ViewState . ViewMode ! = PartViewMode . Model )
2017-07-06 14:41:32 -07:00
{
2018-02-16 15:50:33 -08:00
if ( this . SetAnimationPosition ( ) )
{
this . Invalidate ( ) ;
}
2017-08-16 22:45:46 -07:00
}
base . OnDraw ( graphics2D ) ;
}
2018-01-21 21:07:14 -08:00
protected override void GetViewControls3DOverflowMenu ( PopupMenu popupMenu )
2017-08-16 22:45:46 -07:00
{
2020-12-30 10:35:47 -08:00
if ( Printer ? . ViewState . ViewMode ! = PartViewMode . Model )
2017-08-16 22:45:46 -07:00
{
2018-03-16 17:44:44 -07:00
view3DWidget . ShowBedViewOptions ( popupMenu ) ;
2018-01-21 21:07:14 -08:00
this . ShowGCodeOverflowMenu ( popupMenu ) ;
2017-07-06 14:41:32 -07:00
}
else
{
2018-01-21 21:07:14 -08:00
view3DWidget . ShowOverflowMenu ( popupMenu ) ;
2017-08-16 22:45:46 -07:00
}
}
2017-07-06 14:41:32 -07:00
2018-08-23 16:44:11 -07:00
public override void OnClosed ( EventArgs e )
2017-07-06 14:41:32 -07:00
{
2018-11-16 08:44:56 -08:00
// Unregister listeners
2017-09-15 16:49:21 -07:00
sceneContext . LoadedGCodeChanged - = BedPlate_LoadedGCodeChanged ;
2020-12-30 10:35:47 -08:00
Printer . Connection . CommunicationStateChanged - = Connection_CommunicationStateChanged ;
2019-01-18 09:49:38 -08:00
2020-12-30 10:35:47 -08:00
Printer . Connection . PauseOnLayer - = Connection_PauseOnLayer ;
Printer . Connection . FilamentRunout - = Connection_FilamentRunout ;
2019-01-18 09:49:38 -08:00
2020-12-30 10:35:47 -08:00
Printer . ViewState . VisibilityChanged - = ProcessOptionalTabs ;
Printer . ViewState . ViewModeChanged - = ViewState_ViewModeChanged ;
Printer . Bed . RendererOptions . PropertyChanged - = RendererOptions_PropertyChanged ;
2018-11-27 12:55:30 -08:00
ApplicationController . Instance . ApplicationError - = ApplicationController_ApplicationError ;
2018-11-30 12:35:56 -08:00
ApplicationController . Instance . ApplicationEvent - = ApplicationController_ApplicationEvent ;
2017-07-06 14:41:32 -07:00
2017-08-16 22:45:46 -07:00
base . OnClosed ( e ) ;
2017-07-06 14:41:32 -07:00
}
2017-08-16 22:45:46 -07:00
private void AddSettingsTabBar ( GuiWidget parent , GuiWidget widgetTodockTo )
{
2020-12-30 10:35:47 -08:00
sideBar = new DockingTabControl ( widgetTodockTo , DockSide . Right , Printer , theme )
2017-08-16 22:45:46 -07:00
{
2017-12-27 13:45:47 -08:00
Name = "DockingTabControl" ,
2020-12-30 10:35:47 -08:00
ControlIsPinned = Printer . ViewState . SliceSettingsTabPinned ,
2018-10-14 17:50:54 -07:00
MinDockingWidth = 400 * ( int ) GuiWidget . DeviceScale
2017-08-16 22:45:46 -07:00
} ;
sideBar . PinStatusChanged + = ( s , e ) = >
{
2020-12-30 10:35:47 -08:00
Printer . ViewState . SliceSettingsTabPinned = sideBar . ControlIsPinned ;
2017-08-16 22:45:46 -07:00
} ;
parent . AddChild ( sideBar ) ;
2017-10-19 10:50:40 -07:00
sideBar . AddPage (
2018-09-07 14:49:26 -07:00
"Slice Settings" ,
2017-10-21 20:22:14 -07:00
"Slice Settings" . Localize ( ) ,
2018-01-03 15:24:55 -08:00
sliceSettingsWidget = new SliceSettingsWidget (
2020-12-30 10:35:47 -08:00
Printer ,
2017-10-19 10:50:40 -07:00
new SettingsContext (
2020-12-30 10:35:47 -08:00
Printer ,
2017-10-21 20:22:14 -07:00
null ,
2017-10-31 14:37:28 -07:00
NamedSettingsLayers . All ) ,
theme ) ) ;
2017-08-16 22:45:46 -07:00
2018-09-07 14:49:26 -07:00
this . ProcessOptionalTabs ( ) ;
}
private void ProcessOptionalTabs ( )
{
sideBar . RemovePage ( "Controls" , false ) ;
sideBar . RemovePage ( "Terminal" , false ) ;
sideBar . RemovePage ( "Printer" , false ) ;
2017-08-16 22:45:46 -07:00
2021-02-12 10:06:11 -08:00
var printerType = Printer . Settings . Slicer . PrinterType ;
if ( Printer . ViewState . ControlsVisible
& & printerType = = PrinterType . FFF )
2017-08-24 17:09:10 -07:00
{
2020-12-30 10:35:47 -08:00
sideBar . AddPage ( "Controls" , "Controls" . Localize ( ) , new ManualPrinterControls ( Printer , theme ) , false ) ;
2018-09-07 14:49:26 -07:00
}
2018-01-03 15:24:55 -08:00
2021-02-12 10:06:11 -08:00
if ( Printer . ViewState . TerminalVisible
& & printerType = = PrinterType . FFF )
2018-09-07 14:49:26 -07:00
{
2018-10-15 18:25:53 -07:00
sideBar . AddPage ( "Terminal" ,
"Terminal" . Localize ( ) ,
2020-12-30 10:35:47 -08:00
new TerminalWidget ( Printer , theme )
2018-09-07 14:49:26 -07:00
{
VAnchor = VAnchor . Stretch ,
HAnchor = HAnchor . Stretch
2018-10-15 18:25:53 -07:00
} ,
2018-09-07 14:49:26 -07:00
false ) ;
}
2018-01-03 15:24:55 -08:00
2020-12-30 10:35:47 -08:00
if ( Printer . ViewState . ConfigurePrinterVisible )
2018-01-03 15:24:55 -08:00
{
sideBar . AddPage (
2018-10-15 18:25:53 -07:00
"Printer" ,
2018-01-03 15:24:55 -08:00
"Printer" . Localize ( ) ,
2020-12-30 10:35:47 -08:00
new ConfigurePrinterWidget ( sliceSettingsWidget . SettingsContext , Printer , theme )
2018-01-03 15:24:55 -08:00
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
2018-09-07 14:49:26 -07:00
} ,
false ) ;
2018-01-03 15:24:55 -08:00
}
2018-09-07 14:49:26 -07:00
sideBar . Rebuild ( ) ;
2017-07-06 14:41:32 -07:00
}
2017-10-30 15:54:16 -07:00
2018-11-16 08:44:56 -08:00
private void Connection_CommunicationStateChanged ( object s , EventArgs e )
{
this . SetSliderVisibility ( ) ;
}
2018-04-12 08:42:10 -07:00
public static GuiWidget PrintProgressWidget ( PrinterConfig printer , ThemeConfig theme )
2017-10-30 15:54:16 -07:00
{
2017-12-11 22:22:56 -08:00
var bodyRow = new GuiWidget ( )
2017-10-30 15:54:16 -07:00
{
2018-09-21 13:29:39 -07:00
HAnchor = HAnchor . Stretch ,
2017-12-11 22:22:56 -08:00
VAnchor = VAnchor . Top | VAnchor . Fit ,
2019-04-12 15:03:03 -07:00
// BackgroundColor = new Color(theme.Colors.PrimaryBackgroundColor, 128),
2017-12-11 22:22:56 -08:00
MinimumSize = new Vector2 ( 275 , 140 ) ,
2017-10-30 15:54:16 -07:00
} ;
// Progress section
var expandingContainer = new HorizontalSpacer ( )
{
VAnchor = VAnchor . Fit | VAnchor . Center
} ;
bodyRow . AddChild ( expandingContainer ) ;
2020-08-01 15:59:20 -07:00
var topToBottom = new FlowLayoutWidget ( FlowDirection . TopToBottom )
2017-10-30 15:54:16 -07:00
{
VAnchor = VAnchor . Center | VAnchor . Fit ,
2018-09-21 13:29:39 -07:00
HAnchor = HAnchor . Stretch ,
2017-10-30 15:54:16 -07:00
} ;
2020-08-01 15:59:20 -07:00
expandingContainer . AddChild ( topToBottom ) ;
var progressRow = new GuiWidget ( )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit
} ;
topToBottom . AddChild ( progressRow ) ;
2017-10-30 15:54:16 -07:00
2018-10-15 18:25:53 -07:00
var progressDial = new ProgressDial ( theme )
2017-10-30 15:54:16 -07:00
{
HAnchor = HAnchor . Center ,
2020-08-01 15:59:20 -07:00
VAnchor = VAnchor . Center ,
2017-10-30 15:54:16 -07:00
Height = 200 * DeviceScale ,
2020-05-16 08:34:06 -07:00
Width = 200 * DeviceScale ,
Name = "Print Progress Dial"
2017-10-30 15:54:16 -07:00
} ;
2020-08-01 15:59:20 -07:00
progressRow . AddChild ( progressDial ) ;
// create a set of controls to do baby stepping on the first layer
var babySteppingControls = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
HAnchor = HAnchor . Right ,
VAnchor = VAnchor . Center | VAnchor . Fit ,
} ;
babySteppingControls . Width = 80 * GuiWidget . DeviceScale ;
progressRow . AddChild ( babySteppingControls ) ;
// add in the move up button
var babyStepAmount = . 02 ;
2021-05-21 15:23:25 -07:00
var upButton = babySteppingControls . AddChild ( new IconButton ( StaticData . Instance . LoadIcon ( "Up Arrow.png" , 32 , 32 ) . SetToColor ( theme . TextColor ) , theme )
2020-08-01 15:59:20 -07:00
{
HAnchor = HAnchor . Center ,
VAnchor = VAnchor . Absolute ,
Margin = 0 ,
2021-11-25 22:28:21 -08:00
BackgroundRadius = theme . ButtonRadius * GuiWidget . DeviceScale ,
2021-12-09 17:49:04 -08:00
ToolTipText = "Raise extruder" . Localize ( ) + "\n\n" + "First layer only" . Localize ( ) . Stars ( ) ,
2020-08-01 15:59:20 -07:00
} ) ;
upButton . Click + = ( s , e ) = >
{
2020-08-11 11:06:56 -07:00
printer . Settings . ForTools < double > ( SettingsKey . baby_step_z_offset , ( key , value , i ) = >
2020-08-09 12:37:37 -07:00
{
2020-08-11 11:06:56 -07:00
if ( printer . Connection . ActiveExtruderIndex = = i )
{
var currentZ = value + babyStepAmount ;
printer . Settings . SetValue ( key , currentZ . ToString ( "0.##" ) ) ;
}
} ) ;
2020-08-01 15:59:20 -07:00
} ;
// add in the current position display
2020-08-09 12:37:37 -07:00
var zTuning = babySteppingControls . AddChild ( new ZTuningWidget ( printer , theme , false )
2020-08-01 15:59:20 -07:00
{
HAnchor = HAnchor . Center | HAnchor . Fit ,
VAnchor = VAnchor . Fit ,
Margin = new BorderDouble ( 0 , 3 , 0 , 0 ) ,
Padding = 0 ,
} ) ;
2017-10-30 15:54:16 -07:00
2020-08-01 15:59:20 -07:00
babySteppingControls . AddChild ( new TextWidget ( "Z Offset" . Localize ( ) , pointSize : 8 )
{
TextColor = theme . TextColor ,
Margin = new BorderDouble ( 0 , 0 , 0 , 3 ) ,
AutoExpandBoundsToText = true ,
HAnchor = HAnchor . Center ,
} ) ;
// add in the move down button
2021-05-21 15:23:25 -07:00
var downButton = babySteppingControls . AddChild ( new IconButton ( StaticData . Instance . LoadIcon ( "Down Arrow.png" , 32 , 32 ) . SetToColor ( theme . TextColor ) , theme )
2020-08-01 15:59:20 -07:00
{
HAnchor = HAnchor . Center ,
VAnchor = VAnchor . Absolute ,
Margin = 0 ,
2021-11-25 22:28:21 -08:00
BackgroundRadius = new RadiusCorners ( theme . ButtonRadius * GuiWidget . DeviceScale , theme . ButtonRadius * GuiWidget . DeviceScale , 0 , 0 ) ,
2021-12-09 17:49:04 -08:00
ToolTipText = "Lower extruder" . Localize ( ) + "\n\n" + "First layer only" . Localize ( ) . Stars ( ) ,
2020-08-01 15:59:20 -07:00
} ) ;
downButton . Click + = ( s , e ) = >
{
2020-08-11 11:06:56 -07:00
printer . Settings . ForTools < double > ( SettingsKey . baby_step_z_offset , ( key , value , i ) = >
2020-08-09 12:37:37 -07:00
{
2020-08-11 11:06:56 -07:00
if ( printer . Connection . ActiveExtruderIndex = = i )
{
var currentZ = value - babyStepAmount ;
printer . Settings . SetValue ( key , currentZ . ToString ( "0.##" ) ) ;
}
} ) ;
2020-08-01 15:59:20 -07:00
} ;
// build the bottom row to hold re-slice
2018-09-21 13:29:39 -07:00
var bottomRow = new GuiWidget ( )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit
} ;
2020-08-01 15:59:20 -07:00
topToBottom . AddChild ( bottomRow ) ;
2018-09-21 13:29:39 -07:00
2019-03-15 22:53:37 -07:00
var resliceMessageRow = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
Visible = false
} ;
2020-08-01 15:59:20 -07:00
topToBottom . AddChild ( resliceMessageRow ) ;
2019-03-15 22:53:37 -07:00
2017-10-30 15:54:16 -07:00
var timeContainer = new FlowLayoutWidget ( )
{
HAnchor = HAnchor . Center | HAnchor . Fit ,
Margin = 3
} ;
2018-09-21 13:29:39 -07:00
bottomRow . AddChild ( timeContainer ) ;
// we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded
2020-05-16 09:31:54 -07:00
if ( IntPtr . Size = = 8 | | ApplicationController . Instance . Allow32BitReSlice )
2018-09-21 13:29:39 -07:00
{
var resliceButton = new TextButton ( "Re-Slice" , theme )
{
2021-02-25 18:13:49 -08:00
VAnchor = VAnchor . Center ,
HAnchor = HAnchor . Right ,
2021-02-26 10:54:33 -08:00
Margin = new BorderDouble ( 0 , 0 , 7 , 0 ) ,
2020-08-01 15:59:20 -07:00
Name = "Re-Slice Button" ,
2021-12-09 17:49:04 -08:00
ToolTipText = "Apply changes to this print" . Localize ( ) + "\n\n" + "Plating and settings changes can be applied" . Localize ( ) . Stars ( )
2018-09-21 13:29:39 -07:00
} ;
2021-02-25 18:13:49 -08:00
theme . MakeRoundedButton ( resliceButton ) ;
2018-09-21 13:29:39 -07:00
bool activelySlicing = false ;
resliceButton . Click + = ( s , e ) = >
{
resliceButton . Enabled = false ;
UiThread . RunOnIdle ( async ( ) = >
{
2019-01-03 16:58:05 -08:00
bool doSlicing = ! activelySlicing & & printer . Bed . EditContext . SourceItem ! = null ;
if ( doSlicing )
{
2019-01-04 18:25:33 -08:00
var errors = printer . ValidateSettings ( ) ;
2019-05-12 21:00:37 -07:00
if ( errors . Any ( err = > err . ErrorLevel = = ValidationErrorLevel . Error ) )
2019-01-03 16:58:05 -08:00
{
doSlicing = false ;
2019-01-04 18:05:10 -08:00
ApplicationController . Instance . ShowValidationErrors ( "Slicing Error" . Localize ( ) , errors ) ;
2019-01-03 16:58:05 -08:00
}
}
2019-01-04 17:09:42 -08:00
2019-05-12 21:00:37 -07:00
if ( doSlicing )
2018-09-21 13:29:39 -07:00
{
activelySlicing = true ;
if ( bottomRow . Name = = null )
{
2020-07-29 14:29:59 -07:00
bottomRow . Name = await printer . Bed . EditContext . GCodeFilePath ( printer ) ;
2018-09-21 13:29:39 -07:00
}
2018-11-08 08:13:08 -08:00
2018-12-05 13:48:25 -08:00
await ApplicationController . Instance . Tasks . Execute ( "Saving" . Localize ( ) , printer , printer . Bed . SaveChanges ) ;
2018-11-08 08:13:08 -08:00
// start up a new slice on a background thread
2018-09-21 13:29:39 -07:00
await ApplicationController . Instance . SliceItemLoadOutput (
printer ,
printer . Bed . Scene ,
2020-07-29 14:29:59 -07:00
await printer . Bed . EditContext . GCodeFilePath ( printer ) ) ;
2018-11-08 08:13:08 -08:00
2018-09-21 13:29:39 -07:00
// Switch to the 3D layer view if on Model view
if ( printer . ViewState . ViewMode = = PartViewMode . Model )
{
printer . ViewState . ViewMode = PartViewMode . Layers3D ;
}
2018-11-08 08:13:08 -08:00
2019-03-15 22:53:37 -07:00
resliceMessageRow . Visible = true ;
resliceMessageRow . VAnchor = VAnchor . Absolute ;
resliceMessageRow . VAnchor = VAnchor . Fit ;
2018-09-21 13:29:39 -07:00
}
else
{
resliceButton . Enabled = true ;
}
} ) ;
} ;
bottomRow . AddChild ( resliceButton ) ;
2019-03-15 22:53:37 -07:00
// setup the message row
{
// when it is done queue it to the change to gcode stream
2022-01-27 11:01:49 -08:00
var switchMessage = "Switch to new G-Code on next layer?" . Localize ( ) ;
2019-03-15 22:53:37 -07:00
resliceMessageRow . AddChild ( new WrappedTextWidget ( switchMessage , theme . DefaultFontSize , textColor : theme . TextColor )
{
Margin = new BorderDouble ( 7 , 3 )
} ) ;
var switchButtonRow = new FlowLayoutWidget ( FlowDirection . RightToLeft )
{
HAnchor = HAnchor . Stretch
} ;
resliceMessageRow . AddChild ( switchButtonRow ) ;
var switchButton = new TextButton ( "Switch" , theme )
{
VAnchor = VAnchor . Center ,
Margin = new BorderDouble ( 5 ) ,
Name = "Switch Button"
} ;
2021-02-25 18:13:49 -08:00
theme . MakeRoundedButton ( switchButton ) ;
2019-03-15 22:53:37 -07:00
switchButtonRow . AddChild ( switchButton ) ;
2020-07-29 14:29:59 -07:00
switchButton . Click + = async ( s , e ) = >
2019-03-15 22:53:37 -07:00
{
if ( printer . Connection ! = null
& & ( printer . Connection . Printing | | printer . Connection . Paused ) )
{
2020-07-29 14:29:59 -07:00
printer . Connection . SwitchToGCode ( await printer . Bed . EditContext . GCodeFilePath ( printer ) ) ;
bottomRow . Name = await printer . Bed . EditContext . GCodeFilePath ( printer ) ;
2019-03-15 22:53:37 -07:00
}
activelySlicing = false ;
resliceButton . Enabled = true ;
resliceMessageRow . Visible = false ;
} ;
var cancelButton = new TextButton ( "Cancel" , theme )
{
VAnchor = VAnchor . Center ,
2021-02-26 11:38:24 -08:00
Margin = new BorderDouble ( 0 , 5 ) ,
2019-03-15 22:53:37 -07:00
Name = "Cancel Re-Slice Button"
} ;
2021-02-25 18:13:49 -08:00
theme . MakeRoundedButton ( cancelButton ) ;
2019-03-15 22:53:37 -07:00
switchButtonRow . AddChild ( cancelButton ) ;
cancelButton . Click + = async ( s , e ) = >
{
await ApplicationController . Instance . SliceItemLoadOutput (
printer ,
printer . Bed . Scene ,
bottomRow . Name ) ;
activelySlicing = false ;
resliceButton . Enabled = true ;
resliceMessageRow . Visible = false ;
} ;
}
2018-09-21 13:29:39 -07:00
}
2017-10-30 15:54:16 -07:00
2021-05-21 15:23:25 -07:00
timeContainer . AddChild ( new ImageWidget ( StaticData . Instance . LoadIcon ( "fa-clock_24.png" , 24 , 24 ) . SetToColor ( theme . TextColor ) )
2017-10-30 15:54:16 -07:00
{
2018-01-18 15:26:49 -08:00
VAnchor = VAnchor . Center
} ) ;
2017-10-30 15:54:16 -07:00
2019-05-12 21:00:37 -07:00
var timeStack = new FlowLayoutWidget ( FlowDirection . TopToBottom )
2017-10-30 15:54:16 -07:00
{
Margin = new BorderDouble ( 10 , 0 , 0 , 0 ) ,
2019-05-12 21:00:37 -07:00
Padding = new BorderDouble ( 5 , 0 , 0 , 0 ) ,
VAnchor = VAnchor . Center | VAnchor . Fit
} ;
timeContainer . AddChild ( timeStack ) ;
var timePrinted = new TextWidget ( "" , pointSize : 16 , textColor : theme . TextColor )
{
AutoExpandBoundsToText = true ,
HAnchor = HAnchor . Center ,
2017-10-30 15:54:16 -07:00
} ;
2019-05-12 21:00:37 -07:00
timeStack . AddChild ( timePrinted ) ;
2017-10-30 15:54:16 -07:00
2019-05-12 21:00:37 -07:00
var timeToEnd = new TextWidget ( "" , pointSize : 9 , textColor : theme . TextColor )
{
AutoExpandBoundsToText = true ,
HAnchor = HAnchor . Center ,
} ;
timeStack . AddChild ( timeToEnd ) ;
var runningInterval = UiThread . SetInterval ( ( ) = >
2020-08-01 15:59:20 -07:00
{
int totalSecondsPrinted = printer . Connection . SecondsPrinted ;
int hoursPrinted = totalSecondsPrinted / ( 60 * 60 ) ;
int minutesPrinted = totalSecondsPrinted / 60 - hoursPrinted * 60 ;
var secondsPrinted = totalSecondsPrinted % 60 ;
2018-02-16 15:50:33 -08:00
2020-08-01 15:59:20 -07:00
// TODO: Consider if the consistency of a common time format would look and feel better than changing formats based on elapsed duration
timePrinted . Text = GetFormatedTime ( hoursPrinted , minutesPrinted , secondsPrinted ) ;
2017-10-30 15:54:16 -07:00
2020-08-01 15:59:20 -07:00
int totalSecondsToEnd = printer . Connection . SecondsToEnd ;
2019-05-12 21:00:37 -07:00
2020-08-01 15:59:20 -07:00
int hoursToEnd = totalSecondsToEnd / ( 60 * 60 ) ;
int minutesToEnd = totalSecondsToEnd / 60 - hoursToEnd * 60 ;
var secondsToEnd = totalSecondsToEnd % 60 ;
2019-05-12 21:00:37 -07:00
2020-08-01 15:59:20 -07:00
timeToEnd . Text = GetFormatedTime ( hoursToEnd , minutesToEnd , secondsToEnd ) ;
2019-05-12 21:00:37 -07:00
2020-08-01 15:59:20 -07:00
progressDial . LayerIndex = printer . Connection . CurrentlyPrintingLayer ;
if ( progressDial . LayerIndex > 0 )
{
babySteppingControls . Visible = false ;
}
2017-10-30 15:54:16 -07:00
2020-08-01 15:59:20 -07:00
progressDial . LayerCompletedRatio = printer . Connection . RatioIntoCurrentLayerSeconds ;
progressDial . CompletedRatio = printer . Connection . PercentComplete / 100 ;
2017-10-30 15:54:16 -07:00
2020-08-01 15:59:20 -07:00
switch ( printer . Connection . CommunicationState )
{
case CommunicationStates . PreparingToPrint :
case CommunicationStates . Printing :
case CommunicationStates . Paused :
bodyRow . Visible = true ;
break ;
default :
bodyRow . Visible = false ;
break ;
}
} , 1 ) ;
2019-05-12 21:00:37 -07:00
2018-11-13 16:52:23 -08:00
bodyRow . Closed + = ( s , e ) = > UiThread . ClearInterval ( runningInterval ) ;
2017-10-30 15:54:16 -07:00
bodyRow . Visible = false ;
return bodyRow ;
}
2019-05-12 21:00:37 -07:00
private static string GetFormatedTime ( int hoursPrinted , int minutesPrinted , int secondsPrinted )
{
if ( hoursPrinted = = 0 & & minutesPrinted = = 0 & & secondsPrinted = = 0 )
{
return "" ;
}
return ( hoursPrinted < = 0 ) ? $"{minutesPrinted}:{secondsPrinted:00}" : $"{hoursPrinted}:{minutesPrinted:00}:{secondsPrinted:00}" ;
}
2017-08-16 22:45:46 -07:00
}
2017-07-06 12:22:56 -07:00
}