2017-05-23 19:03:30 -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 .
* /
using System ;
2017-08-12 00:23:26 -07:00
using System.Collections.Generic ;
2017-07-14 13:55:02 -07:00
using System.Threading ;
2017-05-23 19:03:30 -07:00
using MatterHackers.Agg ;
2017-08-20 02:34:39 -07:00
using MatterHackers.Agg.Platform ;
2017-05-23 19:03:30 -07:00
using MatterHackers.Agg.UI ;
using MatterHackers.Localizations ;
using MatterHackers.MatterControl.ActionBar ;
2017-05-24 14:19:02 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
2017-05-23 19:03:30 -07:00
using MatterHackers.MatterControl.EeProm ;
using MatterHackers.MatterControl.PrinterCommunication ;
2017-06-29 18:46:59 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2017-06-29 19:42:20 -07:00
using MatterHackers.MeshVisualizer ;
2017-08-14 05:49:22 -07:00
using MatterHackers.VectorMath ;
2017-05-23 19:03:30 -07:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2017-06-09 08:16:46 -07:00
public class PrinterActionsBar : FlowLayoutWidget
2017-05-23 19:03:30 -07:00
{
2017-09-15 12:08:00 -07:00
private PrinterConfig printer ;
2017-08-30 10:37:44 -07:00
private EventHandler unregisterEvents ;
2017-06-09 08:16:46 -07:00
private static EePromMarlinWindow openEePromMarlinWidget = null ;
private static EePromRepetierWindow openEePromRepetierWidget = null ;
private string noEepromMappingMessage = "Oops! There is no eeprom mapping for your printer's firmware." . Localize ( ) + "\n\n" + "You may need to wait a minute for your printer to finish initializing." . Localize ( ) ;
private string noEepromMappingTitle = "Warning - No EEProm Mapping" . Localize ( ) ;
private OverflowDropdown overflowDropdown ;
2017-06-29 19:42:20 -07:00
private SliceProgressReporter sliceProgressReporter ;
2017-07-14 13:55:02 -07:00
private CancellationTokenSource gcodeLoadCancellationTokenSource ;
2017-06-29 19:42:20 -07:00
public class SliceProgressReporter : IProgress < string >
{
2017-08-09 11:48:57 -07:00
private InteractionLayer interactionLayer ;
2017-06-29 19:42:20 -07:00
2017-08-09 11:48:57 -07:00
public SliceProgressReporter ( InteractionLayer interactionLayer )
2017-06-29 19:42:20 -07:00
{
2017-08-09 11:48:57 -07:00
this . interactionLayer = interactionLayer ;
2017-06-29 19:42:20 -07:00
}
public void StartReporting ( )
{
2017-08-09 11:48:57 -07:00
interactionLayer . BeginProgressReporting ( "Slicing Part" ) ;
2017-06-29 19:42:20 -07:00
}
public void EndReporting ( )
{
2017-08-09 11:48:57 -07:00
interactionLayer . EndProgressReporting ( ) ;
2017-06-29 19:42:20 -07:00
}
public void Report ( string value )
{
2017-08-09 11:48:57 -07:00
interactionLayer . partProcessingInfo . centeredInfoDescription . Text = value ;
2017-06-29 19:42:20 -07:00
}
}
2017-09-15 12:08:00 -07:00
public PrinterActionsBar ( PrinterConfig printer , View3DWidget modelViewer , PrinterTabPage printerTabPage )
2017-05-23 19:03:30 -07:00
{
2017-09-15 12:08:00 -07:00
this . printer = printer ;
2017-08-14 08:57:24 -07:00
UndoBuffer undoBuffer = modelViewer . Scene . UndoBuffer ;
2017-05-23 19:03:30 -07:00
2017-08-07 07:23:45 -07:00
var defaultMargin = ApplicationController . Instance . Theme . ButtonSpacing ;
var buttonFactory = ApplicationController . Instance . Theme . ButtonFactory ;
2017-07-11 16:12:57 -07:00
2017-08-09 11:48:57 -07:00
sliceProgressReporter = new SliceProgressReporter ( modelViewer . InteractionLayer ) ;
2017-06-29 19:42:20 -07:00
2017-08-07 15:47:27 -07:00
this . HAnchor = HAnchor . Stretch ;
this . VAnchor = VAnchor . Fit ;
2017-09-15 12:08:00 -07:00
this . AddChild ( new PrinterConnectButton ( printer , buttonFactory , 0 ) ) ;
2017-05-23 19:03:30 -07:00
2017-09-15 12:08:00 -07:00
this . AddChild ( new PrintActionRow ( printer , buttonFactory , this , defaultMargin ) ) ;
2017-05-24 19:11:51 -07:00
2017-08-06 20:59:42 -07:00
var sliceButton = buttonFactory . Generate ( "Slice" . Localize ( ) . ToUpper ( ) ) ;
2017-06-29 19:42:20 -07:00
sliceButton . ToolTipText = "Slice Parts" . Localize ( ) ;
sliceButton . Name = "Generate Gcode Button" ;
2017-07-11 16:12:57 -07:00
sliceButton . Margin = defaultMargin ;
2017-06-29 19:42:20 -07:00
sliceButton . Click + = async ( s , e ) = >
{
2017-09-15 12:08:00 -07:00
if ( printer . Settings . PrinterSelected )
2017-06-29 19:42:20 -07:00
{
var printItem = ApplicationController . Instance . ActivePrintItem ;
2017-09-15 12:08:00 -07:00
if ( printer . Settings . IsValid ( ) & & printItem ! = null )
2017-06-29 19:42:20 -07:00
{
sliceButton . Enabled = false ;
try
{
sliceProgressReporter . StartReporting ( ) ;
// Save any pending changes before starting the print
await ApplicationController . Instance . ActiveView3DWidget . PersistPlateIfNeeded ( ) ;
2017-08-04 21:32:48 -07:00
2017-06-29 19:42:20 -07:00
await SlicingQueue . SliceFileAsync ( printItem , sliceProgressReporter ) ;
2017-07-14 13:55:02 -07:00
gcodeLoadCancellationTokenSource = new CancellationTokenSource ( ) ;
2017-08-16 05:55:23 -07:00
ApplicationController . Instance . Printer . Bed . LoadGCode ( printItem . GetGCodePathAndFileName ( ) , gcodeLoadCancellationTokenSource . Token , printerTabPage . modelViewer . gcodeViewer . LoadProgress_Changed ) ;
2017-06-29 19:42:20 -07:00
sliceProgressReporter . EndReporting ( ) ;
2017-07-07 06:18:58 -07:00
printerTabPage . ViewMode = PartViewMode . Layers3D ;
2017-06-29 19:42:20 -07:00
// HACK: directly fire method which previously ran on SlicingDone event on PrintItemWrapper
2017-07-10 14:00:27 -07:00
UiThread . RunOnIdle ( printerTabPage . modelViewer . gcodeViewer . CreateAndAddChildren ) ;
2017-06-29 19:42:20 -07:00
}
catch ( Exception ex )
{
Console . WriteLine ( "Error slicing file: " + ex . Message ) ;
}
sliceButton . Enabled = true ;
} ;
}
else
{
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox ( null , "Oops! Please select a printer in order to continue slicing." , "Select Printer" , StyledMessageBox . MessageType . OK ) ;
} ) ;
}
} ;
this . AddChild ( sliceButton ) ;
2017-08-30 10:37:44 -07:00
// put in the detail message
var printerConnectionDetail = new TextWidget ( "" )
{
Margin = new BorderDouble ( 5 , 0 ) ,
TextColor = ActiveTheme . Instance . PrimaryTextColor ,
AutoExpandBoundsToText = true ,
PointSize = 8
} ;
2017-09-15 12:08:00 -07:00
printer . Connection . PrintingStateChanged . RegisterEvent ( ( e , s ) = >
2017-08-30 10:37:44 -07:00
{
2017-09-15 12:08:00 -07:00
printerConnectionDetail . Text = printer . Connection . PrinterConnectionStatus ;
2017-08-30 10:37:44 -07:00
} , ref unregisterEvents ) ;
this . AddChild ( printerConnectionDetail ) ;
2017-08-04 21:32:48 -07:00
this . AddChild ( new HorizontalSpacer ( ) ) ;
2017-09-15 12:08:00 -07:00
bool shareTemp = printer . Settings . GetValue < bool > ( SettingsKey . extruders_share_temperature ) ;
int extruderCount = shareTemp ? 1 : printer . Settings . GetValue < int > ( SettingsKey . extruder_count ) ;
2017-09-06 18:16:45 -07:00
for ( int extruderIndex = 0 ; extruderIndex < extruderCount ; extruderIndex + + )
2017-06-29 18:46:59 -07:00
{
2017-09-15 12:08:00 -07:00
this . AddChild ( new TemperatureWidgetHotend ( printer , extruderIndex , ApplicationController . Instance . Theme . MenuButtonFactory )
2017-09-06 18:16:45 -07:00
{
Margin = new BorderDouble ( right : 10 )
} ) ;
}
2017-06-29 18:46:59 -07:00
2017-09-15 12:08:00 -07:00
if ( printer . Settings . GetValue < bool > ( SettingsKey . has_heated_bed ) )
2017-06-29 18:46:59 -07:00
{
2017-09-15 12:08:00 -07:00
this . AddChild ( new TemperatureWidgetBed ( printer ) ) ;
2017-06-29 18:46:59 -07:00
}
2017-06-09 08:16:46 -07:00
overflowDropdown = new OverflowDropdown ( allowLightnessInvert : true )
{
AlignToRightEdge = true ,
2017-07-11 16:12:57 -07:00
Name = "Printer Overflow Menu" ,
Margin = defaultMargin
2017-06-09 08:16:46 -07:00
} ;
overflowDropdown . DynamicPopupContent = GeneratePrinterOverflowMenu ;
2017-06-02 13:17:30 -07:00
2017-06-09 08:16:46 -07:00
// Deregister on close
this . Closed + = ( s , e ) = >
{
2017-06-02 13:17:30 -07:00
overflowDropdown . DynamicPopupContent = GeneratePrinterOverflowMenu ;
2017-09-01 21:23:08 -07:00
} ;
2017-05-25 17:58:20 -07:00
2017-06-09 08:16:46 -07:00
this . AddChild ( overflowDropdown ) ;
}
2017-05-24 14:19:02 -07:00
2017-08-14 11:06:23 -07:00
public override void AddChild ( GuiWidget childToAdd , int indexInChildrenList = - 1 )
{
childToAdd . VAnchor | = VAnchor . Center ;
base . AddChild ( childToAdd , indexInChildrenList ) ;
}
2017-07-14 13:55:02 -07:00
public override void OnClosed ( ClosedEventArgs e )
{
2017-08-30 10:37:44 -07:00
unregisterEvents ? . Invoke ( this , null ) ;
2017-07-14 13:55:02 -07:00
gcodeLoadCancellationTokenSource ? . Cancel ( ) ;
base . OnClosed ( e ) ;
}
2017-06-09 08:16:46 -07:00
private GuiWidget GeneratePrinterOverflowMenu ( )
{
2017-07-28 08:19:22 -07:00
var menuActions = new NamedAction [ ]
2017-06-09 08:16:46 -07:00
{
2017-07-28 08:57:33 -07:00
new NamedAction ( )
{
2017-08-20 02:34:39 -07:00
Icon = AggContext . StaticData . LoadIcon ( "memory_16x16.png" , 16 , 16 ) ,
2017-07-28 08:57:33 -07:00
Title = "Configure EEProm" . Localize ( ) ,
Action = configureEePromButton_Click
} ,
2017-07-28 08:19:22 -07:00
new NamedAction ( )
2017-07-27 14:25:21 -07:00
{
2017-07-28 08:19:22 -07:00
Title = "Rename Printer" . Localize ( ) ,
Action = ( ) = >
2017-07-27 14:25:21 -07:00
{
2017-08-23 15:13:52 -07:00
var renameItemPage = new RenameItemPage (
2017-07-28 08:19:22 -07:00
"Rename Printer" . Localize ( ) + ":" ,
2017-09-15 12:08:00 -07:00
printer . Settings . GetValue ( SettingsKey . printer_name ) ,
2017-07-28 08:19:22 -07:00
( newName ) = >
{
if ( ! string . IsNullOrEmpty ( newName ) )
{
2017-09-15 12:08:00 -07:00
printer . Settings . SetValue ( SettingsKey . printer_name , newName ) ;
2017-07-28 08:19:22 -07:00
}
} ) ;
2017-08-23 15:13:52 -07:00
2017-08-23 15:51:29 -07:00
WizardWindow . Show ( renameItemPage ) ;
2017-07-27 14:25:21 -07:00
}
2017-07-28 08:19:22 -07:00
} ,
new NamedAction ( ) { Title = "----" } ,
new NamedAction ( )
2017-07-27 14:25:21 -07:00
{
2017-07-28 08:19:22 -07:00
Title = "Delete Printer" . Localize ( ) ,
Action = ( ) = >
2017-07-27 14:25:21 -07:00
{
2017-07-28 08:19:22 -07:00
StyledMessageBox . ShowMessageBox (
( doDelete ) = >
{
if ( doDelete )
{
2017-09-15 12:08:00 -07:00
printer . Settings . Helpers . SetMarkedForDelete ( true ) ;
2017-07-28 08:19:22 -07:00
}
} ,
"Are you sure you want to delete your currently selected printer?" . Localize ( ) ,
"Delete Printer?" . Localize ( ) ,
StyledMessageBox . MessageType . YES_NO ,
"Delete Printer" . Localize ( ) ) ;
2017-07-27 14:25:21 -07:00
}
2017-07-28 08:19:22 -07:00
}
2017-07-27 14:25:21 -07:00
} ;
2017-08-12 00:23:26 -07:00
return ApplicationController . Instance . Theme . CreatePopupMenu ( menuActions ) ;
2017-06-09 08:16:46 -07:00
}
2017-05-23 19:03:30 -07:00
2017-07-28 08:57:33 -07:00
private void configureEePromButton_Click ( )
2017-06-09 08:16:46 -07:00
{
UiThread . RunOnIdle ( ( ) = >
2017-05-23 19:03:30 -07:00
{
#if false // This is to force the creation of the repetier window for testing when we don't have repetier firmware.
new MatterHackers . MatterControl . EeProm . EePromRepetierWidget ( ) ;
#else
2017-09-15 12:08:00 -07:00
switch ( printer . Connection . FirmwareType )
2017-06-09 08:16:46 -07:00
{
2017-06-13 17:32:38 -07:00
case FirmwareTypes . Repetier :
2017-06-09 08:16:46 -07:00
if ( openEePromRepetierWidget ! = null )
{
openEePromRepetierWidget . BringToFront ( ) ;
}
else
{
2017-09-15 12:08:00 -07:00
openEePromRepetierWidget = new EePromRepetierWindow ( printer . Connection ) ;
2017-06-09 08:16:46 -07:00
openEePromRepetierWidget . Closed + = ( RepetierWidget , RepetierEvent ) = >
2017-05-23 19:03:30 -07:00
{
2017-06-09 08:16:46 -07:00
openEePromRepetierWidget = null ;
} ;
}
break ;
2017-06-13 17:32:38 -07:00
case FirmwareTypes . Marlin :
2017-06-09 08:16:46 -07:00
if ( openEePromMarlinWidget ! = null )
{
openEePromMarlinWidget . BringToFront ( ) ;
}
else
{
2017-09-15 12:08:00 -07:00
openEePromMarlinWidget = new EePromMarlinWindow ( printer . Connection ) ;
2017-06-09 08:16:46 -07:00
openEePromMarlinWidget . Closed + = ( marlinWidget , marlinEvent ) = >
2017-05-23 19:03:30 -07:00
{
2017-06-09 08:16:46 -07:00
openEePromMarlinWidget = null ;
} ;
}
break ;
default :
2017-09-15 12:08:00 -07:00
printer . Connection . SendLineToPrinterNow ( "M115" ) ;
2017-06-09 08:16:46 -07:00
StyledMessageBox . ShowMessageBox ( null , noEepromMappingMessage , noEepromMappingTitle , StyledMessageBox . MessageType . OK ) ;
break ;
}
2017-05-23 19:03:30 -07:00
#endif
2017-09-01 21:23:08 -07:00
} ) ;
2017-05-23 19:03:30 -07:00
}
}
}