2017-07-06 12:22:56 -07:00
/ *
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 .
* /
2017-07-07 16:50:47 -07:00
using System ;
2017-10-30 15:54:16 -07:00
using System.IO ;
2017-07-10 12:32:41 -07:00
using System.Linq ;
2018-01-05 12:44:57 -08:00
using MatterControl.Printing ;
2017-07-06 12:22:56 -07:00
using MatterHackers.Agg ;
2017-10-30 15:54:16 -07:00
using MatterHackers.Agg.ImageProcessing ;
2017-10-30 08:53:53 -07:00
using MatterHackers.Agg.OpenGlGui ;
2017-10-30 15:54:16 -07:00
using MatterHackers.Agg.Platform ;
2017-07-06 12:22:56 -07:00
using MatterHackers.Agg.UI ;
using MatterHackers.Localizations ;
using MatterHackers.MatterControl.CustomWidgets ;
2017-10-30 15:54:16 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2017-07-06 12:22:56 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
using MatterHackers.MeshVisualizer ;
using MatterHackers.VectorMath ;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2017-11-07 14:55:45 -08:00
public class PrinterTabPage : PartTabPage
2017-07-06 12:22:56 -07:00
{
2017-07-10 12:23:02 -07:00
internal GCode2DWidget gcode2DWidget ;
2017-09-15 16:49:21 -07:00
2017-08-16 22:45:46 -07:00
private View3DConfig gcodeOptions ;
2017-07-06 14:41:32 -07:00
private DoubleSolidSlider layerRenderRatioSlider ;
2017-07-10 12:32:41 -07:00
private SystemWindow parentSystemWindow ;
2017-10-21 20:22:14 -07:00
private SliceLayerSelector layerScrollbar ;
2017-11-11 17:28:03 -08:00
internal PrinterConfig printer ;
2017-10-30 08:53:53 -07:00
internal GCode3DWidget gcode3DWidget ;
2017-11-29 13:45:01 -08:00
internal PrinterActionsBar printerActionsBar ;
2018-01-03 15:24:55 -08:00
private DockingTabControl sideBar ;
private SliceSettingsWidget sliceSettingsWidget ;
2017-09-15 16:49:21 -07:00
2017-09-15 18:45:21 -07:00
public PrinterTabPage ( PrinterConfig printer , ThemeConfig theme , string tabTitle )
2017-09-17 01:11:18 -07:00
: base ( printer , printer . Bed , theme , tabTitle )
2017-07-06 12:22:56 -07:00
{
2017-09-15 16:49:21 -07:00
this . printer = printer ;
2017-10-06 12:23:32 -07:00
view3DWidget . meshViewerWidget . EditorMode = MeshViewerWidget . EditorType . Printer ;
2017-08-17 10:52:47 -07:00
2017-09-15 16:49:21 -07:00
gcodeOptions = sceneContext . RendererOptions ;
2017-07-06 14:41:32 -07:00
2017-07-10 12:23:02 -07:00
viewControls3D . TransformStateChanged + = ( s , e ) = >
{
switch ( e . TransformMode )
{
case ViewControls3DButtons . Translate :
if ( gcode2DWidget ! = null )
{
gcode2DWidget . TransformState = GCode2DWidget . ETransformState . Move ;
}
break ;
case ViewControls3DButtons . Scale :
if ( gcode2DWidget ! = null )
{
gcode2DWidget . TransformState = GCode2DWidget . ETransformState . Scale ;
}
break ;
}
} ;
2017-07-06 12:22:56 -07:00
viewControls3D . ResetView + = ( sender , e ) = >
{
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
printer . ViewState . ViewModeChanged + = ( s , e ) = >
2017-07-06 12:22:56 -07:00
{
2017-11-29 15:22:18 -08:00
this . SetViewMode ( e . ViewMode ) ;
2017-07-06 12:22:56 -07:00
} ;
2017-10-21 20:22:14 -07:00
layerScrollbar = new SliceLayerSelector ( printer , sceneContext )
2017-07-07 16:50:47 -07:00
{
2017-09-13 15:55:12 -07:00
VAnchor = VAnchor . Stretch ,
2017-10-21 20:22:14 -07:00
HAnchor = HAnchor . Right | HAnchor . Absolute ,
Width = 60 ,
Margin = new BorderDouble ( 0 , 80 , 8 , 42 ) ,
2017-11-29 16:40:46 -08:00
Maximum = sceneContext . LoadedGCode ? . LayerCount ? ? 1
2017-07-06 14:41:32 -07:00
} ;
2017-10-21 20:22:14 -07:00
view3DContainer . AddChild ( layerScrollbar ) ;
2018-01-03 15:24:55 -08:00
2017-10-21 20:22:14 -07:00
layerRenderRatioSlider = new DoubleSolidSlider ( new Vector2 ( ) , SliceLayerSelector . SliderWidth ) ;
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 ) = >
{
2017-09-01 17:41:43 -07:00
if ( printer ? . Bed ? . RenderInfo ! = null )
{
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 ( ) ;
} ;
view3DContainer . AddChild ( layerRenderRatioSlider ) ;
2017-11-29 16:40:46 -08:00
sceneContext . LoadedGCodeChanged + = BedPlate_LoadedGCodeChanged ;
2017-10-21 20:22:14 -07:00
AddSettingsTabBar ( leftToRight , view3DWidget ) ;
2017-07-07 12:52:00 -07:00
2017-10-06 12:23:32 -07:00
view3DWidget . BoundsChanged + = ( s , e ) = >
2017-08-16 22:45:46 -07:00
{
SetSliderSizes ( ) ;
} ;
2017-12-28 12:51:47 -08:00
printerActionsBar = new PrinterActionsBar ( printer , this , theme ) ;
2017-12-26 09:11:23 -08:00
printerActionsBar . OverflowMenu . BackgroundColor = theme . ResolveColor ( theme . TabBodyBackground , theme . TabBodyBackground ) ;
2017-10-19 09:04:36 -07:00
// Must come after we have an instance of View3DWidget an its undo buffer
topToBottom . AddChild ( printerActionsBar , 0 ) ;
2017-11-09 15:48:05 -08:00
topToBottom . AddChild ( new HorizontalLine ( 20 ) , 1 ) ;
2017-10-30 08:53:53 -07:00
var trackball = view3DWidget . InteractionLayer . Children < TrackballTumbleWidget > ( ) . FirstOrDefault ( ) ;
var position = view3DWidget . InteractionLayer . Children . IndexOf ( trackball ) ;
// The slice layers view
gcode3DWidget = new GCode3DWidget ( printer , sceneContext , theme )
{
2017-10-30 09:00:14 -07:00
Name = "GCode3DWidget" ,
2017-10-30 08:53:53 -07:00
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
Visible = false
} ;
view3DWidget . InteractionLayer . AddChild ( gcode3DWidget , position ) ;
2017-11-29 14:41:55 -08:00
var viewerVolume = sceneContext . ViewerVolume ;
2017-12-11 14:15:50 -08:00
view3DContainer . AddChild ( new RunningTasksWidget ( theme )
{
MinimumSize = new Vector2 ( 100 , 0 ) ,
Margin = new BorderDouble ( left : 10 , bottom : 90 ) ,
VAnchor = VAnchor . Bottom | VAnchor . Fit ,
HAnchor = HAnchor . Left | HAnchor . Fit ,
} ) ;
2017-11-29 14:41:55 -08:00
// Create and append new widget
gcode2DWidget = new GCode2DWidget ( new Vector2 ( viewerVolume . X , viewerVolume . Y ) , sceneContext . BedCenter )
{
Visible = ( printer . ViewState . ViewMode = = PartViewMode . Layers2D )
} ;
view3DWidget . InteractionLayer . AddChild ( gcode2DWidget ) ;
2017-08-16 22:45:46 -07:00
SetSliderSizes ( ) ;
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
this . SetViewMode ( printer . ViewState . ViewMode ) ;
2018-01-03 15:24:55 -08:00
printer . ViewState . ConfigurePrinterChanged + = ConfigurePrinter_Changed ;
}
private void ConfigurePrinter_Changed ( object sender , EventArgs e )
{
this . ProcessOptionalTab ( ) ;
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
{
2017-11-29 15:22:18 -08:00
if ( gcode3DWidget = = 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 :
UserSettings . Instance . set ( "LayerViewDefault" , "2D Layer" ) ;
// HACK: Getting the Layer2D view to show content only works if CenterPartInView is called after the control is visible and after some cycles have passed
gcode2DWidget . Visible = true ;
UiThread . RunOnIdle ( gcode2DWidget . CenterPartInView ) ;
break ;
case PartViewMode . Layers3D :
UserSettings . Instance . set ( "LayerViewDefault" , "3D Layer" ) ;
break ;
case PartViewMode . Model :
break ;
}
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
bool showSliceLayers = viewMode = = PartViewMode . Layers3D ;
2017-07-06 14:41:32 -07:00
2017-11-29 15:22:18 -08:00
gcode3DWidget . Visible = viewMode = = PartViewMode . Layers3D ;
gcode2DWidget . Visible = viewMode = = PartViewMode . Layers2D ;
2017-07-06 12:22:56 -07:00
2017-11-29 16:40:46 -08:00
view3DWidget . meshViewerWidget . ModelView = viewMode = = PartViewMode . Model ;
2017-07-06 12:22:56 -07:00
2017-11-29 15:22:18 -08:00
if ( showSliceLayers )
{
printer . Bed . Scene . ClearSelection ( ) ;
2017-08-16 22:45:46 -07:00
}
2017-11-29 15:22:18 -08:00
2017-11-29 16:40:46 -08:00
var slidersVisible = viewMode ! = PartViewMode . Model & & printer . Bed . LoadedGCode ? . LayerCount > 0 ;
2017-11-29 15:22:18 -08:00
layerScrollbar . Visible = slidersVisible ;
layerRenderRatioSlider . Visible = slidersVisible ;
2017-11-29 16:40:46 -08:00
view3DWidget . selectedObjectContainer . Visible = view3DWidget . meshViewerWidget . ModelView
& & sceneContext . Scene . HasSelection
& & printer ? . ViewState . ViewMode ! = PartViewMode . Layers2D ;
2017-07-06 12:22:56 -07:00
}
2017-07-06 14:41:32 -07:00
private void BedPlate_LoadedGCodeChanged ( object sender , EventArgs e )
{
2017-10-17 12:55:58 -07:00
bool gcodeLoaded = sceneContext . LoadedGCode ! = null ;
2017-10-21 20:22:14 -07:00
layerScrollbar . Visible = gcodeLoaded ;
2017-10-17 12:55:58 -07:00
layerRenderRatioSlider . Visible = gcodeLoaded ;
if ( ! gcodeLoaded )
{
return ;
}
2017-10-21 20:22:14 -07:00
layerScrollbar . Maximum = sceneContext . LoadedGCode . LayerCount ;
2017-07-06 14:41:32 -07:00
}
2017-08-16 22:45:46 -07:00
private void SetSyncToPrintVisibility ( )
2017-07-06 12:22:56 -07:00
{
2017-09-16 01:36:19 -07:00
bool printerIsRunningPrint = printer . Connection . PrinterIsPaused | | printer . Connection . PrinterIsPrinting ;
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 ;
2017-10-21 20:22:14 -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
2017-08-16 22:45:46 -07:00
layerRenderRatioSlider . Visible = true ;
2017-10-21 20:22:14 -07:00
layerScrollbar . Visible = true ;
2017-08-16 22:45:46 -07:00
}
2017-07-06 12:22:56 -07:00
}
2017-09-17 01:11:18 -07:00
// TODO: Moved from View3DWidget as printer specialized logic can't be in the generic base. Consider moving to model
private bool PartsAreInPrintVolume ( )
{
AxisAlignedBoundingBox allBounds = AxisAlignedBoundingBox . Empty ;
foreach ( var aabb in printer . Bed . Scene . Children . Select ( item = > item . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ) )
{
allBounds + = aabb ;
}
2017-10-31 12:51:16 -07:00
bool onBed = allBounds . minXYZ . Z > - . 001 & & allBounds . minXYZ . Z < . 001 ; // really close to the bed
RectangleDouble bedRect = new RectangleDouble ( 0 , 0 , printer . Settings . GetValue < Vector2 > ( SettingsKey . bed_size ) . X , printer . Settings . GetValue < Vector2 > ( SettingsKey . bed_size ) . Y ) ;
2017-09-17 01:11:18 -07:00
bedRect . Offset ( printer . Settings . GetValue < Vector2 > ( SettingsKey . print_center ) - printer . Settings . GetValue < Vector2 > ( SettingsKey . bed_size ) / 2 ) ;
bool inBounds = bedRect . Contains ( new Vector2 ( allBounds . minXYZ ) ) & & bedRect . Contains ( new Vector2 ( allBounds . maxXYZ ) ) ;
return onBed & & inBounds ;
}
2017-08-16 22:45:46 -07:00
private void SetSliderSizes ( )
2017-07-06 14:41:32 -07:00
{
2017-10-21 20:22:14 -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
2017-10-21 20:22:14 -07:00
2017-08-16 22:45:46 -07:00
layerRenderRatioSlider . OriginRelativeParent = new Vector2 ( 11 , 65 ) ;
2017-10-06 12:23:32 -07:00
layerRenderRatioSlider . TotalWidthInPixels = view3DWidget . Width - 45 ;
2017-07-06 12:22:56 -07:00
}
2017-10-21 20:22:14 -07:00
2017-08-16 22:45:46 -07:00
private void SetAnimationPosition ( )
2017-07-07 06:18:58 -07:00
{
2017-09-16 01:36:19 -07:00
int currentLayer = printer . Connection . CurrentlyPrintingLayer ;
2017-08-16 22:45:46 -07:00
if ( currentLayer < = 0 )
2017-07-07 06:18:58 -07:00
{
2017-10-21 20:22:14 -07:00
layerScrollbar . Value = 0 ;
2017-08-16 22:45:46 -07:00
layerRenderRatioSlider . SecondValue = 0 ;
layerRenderRatioSlider . FirstValue = 0 ;
2017-07-10 12:32:41 -07:00
}
2017-08-16 22:45:46 -07:00
else
2017-07-10 12:32:41 -07:00
{
2017-10-21 20:22:14 -07:00
layerScrollbar . Value = currentLayer - 1 ;
2017-09-16 01:36:19 -07:00
layerRenderRatioSlider . SecondValue = printer . Connection . RatioIntoCurrentLayer ;
2017-08-16 22:45:46 -07:00
layerRenderRatioSlider . FirstValue = 0 ;
2017-07-10 12:32:41 -07:00
}
}
2017-07-06 14:41:32 -07:00
internal GuiWidget ShowGCodeOverflowMenu ( )
{
2017-11-20 13:09:52 -08:00
var popupMenu = new PopupMenu ( theme ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Show Print Bed" . Localize ( ) ,
( ) = > gcodeOptions . RenderBed ,
( value ) = >
{
gcodeOptions . RenderBed = value ;
view3DWidget . meshViewerWidget . RenderBed = value ;
} ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Moves" . Localize ( ) ,
( ) = > gcodeOptions . RenderMoves ,
( value ) = > gcodeOptions . RenderMoves = value ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Retractions" . Localize ( ) ,
( ) = > gcodeOptions . RenderRetractions ,
( value ) = > gcodeOptions . RenderRetractions = value ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Speeds" . Localize ( ) ,
( ) = > gcodeOptions . RenderSpeeds ,
( value ) = > gcodeOptions . RenderSpeeds = value ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateHorizontalLine ( ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Extrusion" . Localize ( ) ,
( ) = > gcodeOptions . SimulateExtrusion ,
( value ) = > gcodeOptions . SimulateExtrusion = value ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Transparent" . Localize ( ) ,
( ) = > gcodeOptions . TransparentExtrusion ,
( value ) = > gcodeOptions . TransparentExtrusion = value ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
popupMenu . CreateHorizontalLine ( ) ;
2017-07-06 14:41:32 -07:00
2017-09-15 12:08:00 -07:00
if ( printer . Settings . GetValue < int > ( SettingsKey . extruder_count ) > 1 )
2017-07-06 14:41:32 -07:00
{
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Hide Offsets" . Localize ( ) ,
( ) = > gcodeOptions . HideExtruderOffsets ,
( value ) = > gcodeOptions . HideExtruderOffsets = value ) ;
2017-07-06 14:41:32 -07:00
}
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Sync To Print" . Localize ( ) ,
( ) = > gcodeOptions . SyncToPrint ,
2017-12-09 15:11:38 -08:00
( value ) = >
{
gcodeOptions . SyncToPrint = value ;
if ( ! gcodeOptions . SyncToPrint )
{
// If we are turning off sync to print, set the slider to full.
layerRenderRatioSlider . SecondValue = 1 ;
}
} ) ;
2017-07-06 14:41:32 -07:00
2017-11-20 13:09:52 -08:00
return 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
{
2017-09-16 01:36:19 -07:00
bool printerIsRunningPrint = printer . Connection . PrinterIsPaused | | printer . Connection . PrinterIsPrinting ;
2017-08-16 22:45:46 -07:00
if ( gcodeOptions . SyncToPrint
& & printerIsRunningPrint
2017-12-23 07:03:04 -08:00
& & ( gcode3DWidget . Visible | | gcode2DWidget . Visible ) )
2017-07-06 14:41:32 -07:00
{
SetAnimationPosition ( ) ;
2017-08-16 22:45:46 -07:00
this . Invalidate ( ) ;
}
base . OnDraw ( graphics2D ) ;
}
protected override GuiWidget GetViewControls3DOverflowMenu ( )
{
2017-12-22 10:01:19 -08:00
if ( gcode3DWidget . Visible
| | gcode2DWidget . Visible )
2017-08-16 22:45:46 -07:00
{
return this . ShowGCodeOverflowMenu ( ) ;
2017-07-06 14:41:32 -07:00
}
else
{
2017-10-06 12:23:32 -07:00
return view3DWidget . ShowOverflowMenu ( ) ;
2017-08-16 22:45:46 -07:00
}
}
2017-07-06 14:41:32 -07:00
2017-08-16 22:45:46 -07:00
public override void OnLoad ( EventArgs args )
{
// Find and hook the parent system window KeyDown event
if ( this . Parents < SystemWindow > ( ) . FirstOrDefault ( ) is SystemWindow systemWindow )
{
systemWindow . KeyDown + = Parent_KeyDown ;
parentSystemWindow = systemWindow ;
2017-07-06 14:41:32 -07:00
}
2017-08-16 22:45:46 -07:00
base . OnLoad ( args ) ;
2017-07-06 14:41:32 -07:00
}
2017-08-16 22:45:46 -07:00
public override void OnClosed ( ClosedEventArgs e )
2017-07-06 14:41:32 -07:00
{
2017-08-16 22:45:46 -07:00
// Find and unhook the parent system window KeyDown event
if ( parentSystemWindow ! = null )
2017-07-06 14:41:32 -07:00
{
2017-08-16 22:45:46 -07:00
parentSystemWindow . KeyDown - = Parent_KeyDown ;
2017-07-06 14:41:32 -07:00
}
2017-09-15 16:49:21 -07:00
sceneContext . LoadedGCodeChanged - = BedPlate_LoadedGCodeChanged ;
2018-01-03 15:24:55 -08:00
printer . ViewState . ConfigurePrinterChanged - = ConfigurePrinter_Changed ;
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 Parent_KeyDown ( object sender , KeyEventArgs keyEvent )
2017-07-06 14:41:32 -07:00
{
2017-12-02 22:14:51 -08:00
if ( ! keyEvent . Handled
& & ( gcode3DWidget . Visible
| | gcode2DWidget . Visible ) )
2017-07-06 14:41:32 -07:00
{
2017-08-16 22:45:46 -07:00
switch ( keyEvent . KeyCode )
{
case Keys . Up :
2017-10-21 20:22:14 -07:00
layerScrollbar . Value + = 1 ;
2017-08-16 22:45:46 -07:00
break ;
case Keys . Down :
2017-10-21 20:22:14 -07:00
layerScrollbar . Value - = 1 ;
2017-08-16 22:45:46 -07:00
break ;
}
}
}
private void AddSettingsTabBar ( GuiWidget parent , GuiWidget widgetTodockTo )
{
2018-01-03 15:24:55 -08:00
sideBar = new DockingTabControl ( widgetTodockTo , DockSide . Right , ApplicationController . Instance . ActivePrinter )
2017-08-16 22:45:46 -07:00
{
2017-12-27 13:45:47 -08:00
Name = "DockingTabControl" ,
2017-09-17 14:01:58 -07:00
ControlIsPinned = ApplicationController . Instance . ActivePrinter . ViewState . SliceSettingsTabPinned
2017-08-16 22:45:46 -07:00
} ;
sideBar . PinStatusChanged + = ( s , e ) = >
{
2017-09-17 14:01:58 -07:00
ApplicationController . Instance . ActivePrinter . 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 (
2017-10-21 20:22:14 -07:00
"Slice Settings" . Localize ( ) ,
2018-01-03 15:24:55 -08:00
sliceSettingsWidget = new SliceSettingsWidget (
2017-10-21 20:22:14 -07:00
printer ,
2017-10-19 10:50:40 -07:00
new SettingsContext (
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
2017-09-15 12:08:00 -07:00
sideBar . AddPage ( "Controls" . Localize ( ) , new ManualPrinterControls ( printer ) ) ;
2017-08-16 22:45:46 -07:00
2017-09-17 13:30:05 -07:00
sideBar . AddPage ( "Terminal" . Localize ( ) , new TerminalWidget ( printer )
2017-08-24 17:09:10 -07:00
{
VAnchor = VAnchor . Stretch ,
HAnchor = HAnchor . Stretch
} ) ;
2018-01-03 15:24:55 -08:00
this . ProcessOptionalTab ( ) ;
}
private void ProcessOptionalTab ( )
{
if ( ApplicationController . Instance . ActivePrinter . ViewState . ConfigurePrinterVisible )
{
sideBar . AddPage (
"Printer" . Localize ( ) ,
new ConfigurePrinterWidget ( sliceSettingsWidget , theme )
{
BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ,
Padding = new BorderDouble ( top : 10 ) ,
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
} ) ;
}
else
{
sideBar . RemovePage ( "Printer" ) ;
}
2017-07-06 14:41:32 -07:00
}
2017-10-30 15:54:16 -07:00
2017-12-11 22:22:56 -08:00
public static GuiWidget PrintProgressWidget ( PrinterConfig printer )
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
{
2017-12-11 22:22:56 -08:00
HAnchor = HAnchor . Fit | HAnchor . Center ,
VAnchor = VAnchor . Top | VAnchor . Fit ,
//BackgroundColor = new Color(ActiveTheme.Instance.PrimaryBackgroundColor, 128),
MinimumSize = new Vector2 ( 275 , 140 ) ,
2017-10-30 15:54:16 -07:00
Selectable = false
} ;
// Progress section
var expandingContainer = new HorizontalSpacer ( )
{
VAnchor = VAnchor . Fit | VAnchor . Center
} ;
bodyRow . AddChild ( expandingContainer ) ;
var progressContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
Margin = new BorderDouble ( 50 , 0 ) ,
VAnchor = VAnchor . Center | VAnchor . Fit ,
HAnchor = HAnchor . Center | HAnchor . Fit ,
} ;
expandingContainer . AddChild ( progressContainer ) ;
var progressDial = new ProgressDial ( )
{
HAnchor = HAnchor . Center ,
Height = 200 * DeviceScale ,
Width = 200 * DeviceScale
} ;
progressContainer . AddChild ( progressDial ) ;
var timeContainer = new FlowLayoutWidget ( )
{
HAnchor = HAnchor . Center | HAnchor . Fit ,
Margin = 3
} ;
progressContainer . AddChild ( timeContainer ) ;
var timeImage = AggContext . StaticData . LoadImage ( Path . Combine ( "Images" , "Screensaver" , "time.png" ) ) ;
if ( ! ActiveTheme . Instance . IsDarkTheme )
{
timeImage . InvertLightness ( ) ;
}
timeContainer . AddChild ( new ImageWidget ( timeImage ) ) ;
var timeWidget = new TextWidget ( "" , pointSize : 22 , textColor : ActiveTheme . Instance . PrimaryTextColor )
{
AutoExpandBoundsToText = true ,
Margin = new BorderDouble ( 10 , 0 , 0 , 0 ) ,
VAnchor = VAnchor . Center ,
} ;
timeContainer . AddChild ( timeWidget ) ;
Action updatePrintProgress = null ;
updatePrintProgress = ( ) = >
{
int secondsPrinted = printer . Connection . SecondsPrinted ;
int hoursPrinted = ( int ) ( secondsPrinted / ( 60 * 60 ) ) ;
int minutesPrinted = ( secondsPrinted / 60 - hoursPrinted * 60 ) ;
secondsPrinted = secondsPrinted % 60 ;
// TODO: Consider if the consistency of a common time format would look and feel better than changing formats based on elapsed duration
timeWidget . Text = ( hoursPrinted < = 0 ) ? $"{minutesPrinted}:{secondsPrinted:00}" : $"{hoursPrinted}:{minutesPrinted:00}:{secondsPrinted:00}" ;
progressDial . LayerCount = printer . Connection . CurrentlyPrintingLayer ;
progressDial . LayerCompletedRatio = printer . Connection . RatioIntoCurrentLayer ;
progressDial . CompletedRatio = printer . Connection . PercentComplete / 100 ;
2017-12-11 22:22:56 -08:00
if ( ! bodyRow . HasBeenClosed )
2017-10-30 15:54:16 -07:00
{
switch ( printer . Connection . CommunicationState )
{
case CommunicationStates . PreparingToPrint :
case CommunicationStates . Printing :
case CommunicationStates . Paused :
bodyRow . Visible = true ;
break ;
default :
bodyRow . Visible = false ;
break ;
}
UiThread . RunOnIdle ( updatePrintProgress , 1 ) ;
}
} ;
UiThread . RunOnIdle ( updatePrintProgress , 1 ) ;
bodyRow . Visible = false ;
return bodyRow ;
}
2017-08-16 22:45:46 -07:00
}
2017-07-06 12:22:56 -07:00
}