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-10-16 16:32:25 -07:00
using System.Collections.Generic ;
using System.Linq ;
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-10-16 16:32:25 -07:00
using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling ;
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-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 ( ) ;
2017-10-16 16:32:25 -07:00
private List < Button > activePrintButtons = new List < Button > ( ) ;
private List < Button > allPrintButtons = new List < Button > ( ) ;
private Button cancelConnectButton ;
private Button resetConnectionButton ;
private Button resumeResumeButton ;
private Button startPrintButton ;
private Button pausePrintButton ;
private Button cancelPrintButton ;
private Button finishSetupButton ;
2017-10-15 15:50:48 -07:00
private OverflowMenu overflowMenu ;
2017-06-09 08:16:46 -07:00
2017-07-14 13:55:02 -07:00
private CancellationTokenSource gcodeLoadCancellationTokenSource ;
2017-10-16 17:09:00 -07:00
private PrinterTabPage printerTabPage ;
2017-10-16 16:32:25 -07:00
2017-09-25 22:11:02 -07:00
public PrinterActionsBar ( PrinterConfig printer , PrinterTabPage printerTabPage , ThemeConfig theme )
2017-05-23 19:03:30 -07:00
{
2017-09-15 12:08:00 -07:00
this . printer = printer ;
2017-10-16 17:09:00 -07:00
this . printerTabPage = printerTabPage ;
2017-08-07 15:47:27 -07:00
this . HAnchor = HAnchor . Stretch ;
this . VAnchor = VAnchor . Fit ;
2017-05-23 19:03:30 -07:00
2017-09-30 10:26:00 -07:00
this . AddChild ( new PrinterConnectButton ( printer , theme ) ) ;
2017-10-16 16:32:25 -07:00
BuildChildElements ( theme ) ;
2017-09-25 22:11:02 -07:00
this . AddChild ( new SlicePopupMenu ( printer , theme , printerTabPage ) ) ;
2017-06-29 19:42:20 -07:00
2017-10-16 16:32:25 -07:00
// Add Handlers
printer . Connection . CommunicationStateChanged . RegisterEvent ( ( s , e ) = >
{
UiThread . RunOnIdle ( SetButtonStates ) ;
} , ref unregisterEvents ) ;
ProfileManager . ProfilesListChanged . RegisterEvent ( ( s , e ) = >
{
UiThread . RunOnIdle ( SetButtonStates ) ;
} , ref unregisterEvents ) ;
printer . Settings . PrintLevelingEnabledChanged . RegisterEvent ( ( s , e ) = >
{
SetButtonStates ( ) ;
} , ref unregisterEvents ) ;
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-25 22:11:02 -07:00
printer . Connection . PrintingStateChanged . RegisterEvent ( ( s , e ) = >
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-25 22:11:02 -07:00
this . AddChild ( new TemperatureWidgetHotend ( printer , extruderIndex , 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-10-15 15:50:48 -07:00
overflowMenu = new OverflowMenu ( IconColor . Theme )
2017-06-09 08:16:46 -07:00
{
AlignToRightEdge = true ,
2017-07-11 16:12:57 -07:00
Name = "Printer Overflow Menu" ,
2017-09-25 22:11:02 -07:00
Margin = theme . ButtonSpacing
2017-06-09 08:16:46 -07:00
} ;
2017-10-15 15:50:48 -07:00
overflowMenu . 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-10-15 15:50:48 -07:00
overflowMenu . DynamicPopupContent = GeneratePrinterOverflowMenu ;
2017-09-01 21:23:08 -07:00
} ;
2017-05-25 17:58:20 -07:00
2017-10-15 15:50:48 -07:00
this . AddChild ( overflowMenu ) ;
2017-06-09 08:16:46 -07:00
}
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-10-17 12:35:24 -07:00
WizardWindow . Show (
new InputBoxPage (
"Rename Printer" . Localize ( ) ,
"Name" . Localize ( ) ,
printer . Settings . GetValue ( SettingsKey . printer_name ) ,
"Enter New Name Here" . Localize ( ) ,
"Rename" . Localize ( ) ,
( newName ) = >
{
if ( ! string . IsNullOrEmpty ( newName ) )
{
printer . Settings . SetValue ( SettingsKey . printer_name , newName ) ;
}
} ) ) ;
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-10-15 15:50:48 -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-10-18 19:54:06 -07:00
StyledMessageBox . ShowMessageBox ( noEepromMappingMessage , noEepromMappingTitle , StyledMessageBox . MessageType . OK ) ;
2017-06-09 08:16:46 -07:00
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
}
2017-10-16 16:32:25 -07:00
#region From PrinterActionRow
protected void BuildChildElements ( ThemeConfig theme )
{
var defaultMargin = theme . ButtonSpacing ;
startPrintButton = theme . ButtonFactory . Generate ( "Print" . Localize ( ) . ToUpper ( ) ) ;
startPrintButton . Name = "Start Print Button" ;
startPrintButton . ToolTipText = "Begin printing the selected item." . Localize ( ) ;
startPrintButton . Margin = defaultMargin ;
startPrintButton . Click + = ( s , e ) = >
{
2017-10-16 17:09:00 -07:00
UiThread . RunOnIdle ( async ( ) = >
2017-10-16 16:32:25 -07:00
{
2017-10-16 17:28:18 -07:00
await ApplicationController . Instance . PrintPart (
2017-10-16 17:09:00 -07:00
printer . Bed . printItem ,
2017-10-16 17:28:18 -07:00
printer ,
2017-10-16 17:09:00 -07:00
printerTabPage . view3DWidget ,
null ) ;
2017-10-16 16:32:25 -07:00
} ) ;
} ;
this . AddChild ( startPrintButton ) ;
allPrintButtons . Add ( startPrintButton ) ;
finishSetupButton = theme . ButtonFactory . Generate ( "Finish Setup..." . Localize ( ) ) ;
finishSetupButton . Name = "Finish Setup Button" ;
finishSetupButton . ToolTipText = "Run setup configuration for printer." . Localize ( ) ;
finishSetupButton . Margin = defaultMargin ;
finishSetupButton . Click + = ( s , e ) = >
{
2017-10-16 17:28:18 -07:00
UiThread . RunOnIdle ( async ( ) = >
2017-10-16 16:32:25 -07:00
{
2017-10-16 17:28:18 -07:00
await ApplicationController . Instance . PrintPart (
printer . Bed . printItem ,
printer ,
printerTabPage . view3DWidget ,
null ) ;
2017-10-16 16:32:25 -07:00
} ) ;
} ;
this . AddChild ( finishSetupButton ) ;
allPrintButtons . Add ( finishSetupButton ) ;
resetConnectionButton = theme . ButtonFactory . Generate ( "Reset" . Localize ( ) . ToUpper ( ) , AggContext . StaticData . LoadIcon ( "e_stop.png" , 14 , 14 , IconColor . Theme ) ) ;
resetConnectionButton . ToolTipText = "Reboots the firmware on the controller" . Localize ( ) ;
resetConnectionButton . Margin = defaultMargin ;
resetConnectionButton . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( printer . Connection . RebootBoard ) ;
} ;
this . AddChild ( resetConnectionButton ) ;
allPrintButtons . Add ( resetConnectionButton ) ;
pausePrintButton = theme . ButtonFactory . Generate ( "Pause" . Localize ( ) . ToUpper ( ) ) ;
pausePrintButton . ToolTipText = "Pause the current print" . Localize ( ) ;
pausePrintButton . Margin = defaultMargin ;
pausePrintButton . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( printer . Connection . RequestPause ) ;
pausePrintButton . Enabled = false ;
} ;
this . AddChild ( pausePrintButton ) ;
allPrintButtons . Add ( pausePrintButton ) ;
cancelConnectButton = theme . ButtonFactory . Generate ( "Cancel Connect" . Localize ( ) . ToUpper ( ) ) ;
cancelConnectButton . ToolTipText = "Stop trying to connect to the printer." . Localize ( ) ;
cancelConnectButton . Margin = defaultMargin ;
cancelConnectButton . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
ApplicationController . Instance . ConditionalCancelPrint ( ) ;
UiThread . RunOnIdle ( SetButtonStates ) ;
} ) ;
this . AddChild ( cancelConnectButton ) ;
allPrintButtons . Add ( cancelConnectButton ) ;
cancelPrintButton = theme . ButtonFactory . Generate ( "Cancel" . Localize ( ) . ToUpper ( ) ) ;
cancelPrintButton . ToolTipText = "Stop the current print" . Localize ( ) ;
cancelPrintButton . Name = "Cancel Print Button" ;
cancelPrintButton . Margin = defaultMargin ;
cancelPrintButton . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
ApplicationController . Instance . ConditionalCancelPrint ( ) ;
SetButtonStates ( ) ;
} ) ;
this . AddChild ( cancelPrintButton ) ;
allPrintButtons . Add ( cancelPrintButton ) ;
resumeResumeButton = theme . ButtonFactory . Generate ( "Resume" . Localize ( ) . ToUpper ( ) ) ;
resumeResumeButton . ToolTipText = "Resume the current print" . Localize ( ) ;
resumeResumeButton . Margin = defaultMargin ;
resumeResumeButton . Name = "Resume Button" ;
resumeResumeButton . Click + = ( s , e ) = >
{
if ( printer . Connection . PrinterIsPaused )
{
printer . Connection . Resume ( ) ;
}
pausePrintButton . Enabled = true ;
} ;
this . AddChild ( resumeResumeButton ) ;
allPrintButtons . Add ( resumeResumeButton ) ;
SetButtonStates ( ) ;
}
protected void DisableActiveButtons ( )
{
foreach ( Button button in this . activePrintButtons )
{
button . Enabled = false ;
}
}
protected void EnableActiveButtons ( )
{
foreach ( Button button in this . activePrintButtons )
{
button . Enabled = true ;
}
}
//Set the states of the buttons based on the status of PrinterCommunication
protected void SetButtonStates ( )
{
this . activePrintButtons . Clear ( ) ;
if ( ! printer . Connection . PrinterIsConnected
& & printer . Connection . CommunicationState ! = CommunicationStates . AttemptingToConnect )
{
if ( ! ProfileManager . Instance . ActiveProfiles . Any ( ) )
{
// TODO: Possibly upsell add printer - ideally don't show printer tab, only show Plus tab
//this.activePrintButtons.Add(addPrinterButton);
}
ShowActiveButtons ( ) ;
EnableActiveButtons ( ) ;
}
else
{
switch ( printer . Connection . CommunicationState )
{
case CommunicationStates . AttemptingToConnect :
this . activePrintButtons . Add ( cancelConnectButton ) ;
EnableActiveButtons ( ) ;
break ;
case CommunicationStates . Connected :
PrintLevelingData levelingData = printer . Settings . Helpers . GetPrintLevelingData ( ) ;
if ( levelingData ! = null & & printer . Settings . GetValue < bool > ( SettingsKey . print_leveling_required_to_print )
& & ! levelingData . HasBeenRunAndEnabled ( ) )
{
this . activePrintButtons . Add ( finishSetupButton ) ;
}
else
{
this . activePrintButtons . Add ( startPrintButton ) ;
}
EnableActiveButtons ( ) ;
break ;
case CommunicationStates . PreparingToPrint :
this . activePrintButtons . Add ( cancelPrintButton ) ;
EnableActiveButtons ( ) ;
break ;
case CommunicationStates . PrintingFromSd :
case CommunicationStates . Printing :
if ( ! printer . Connection . PrintWasCanceled )
{
this . activePrintButtons . Add ( pausePrintButton ) ;
this . activePrintButtons . Add ( cancelPrintButton ) ;
}
else if ( UserSettings . Instance . IsTouchScreen )
{
this . activePrintButtons . Add ( resetConnectionButton ) ;
}
EnableActiveButtons ( ) ;
break ;
case CommunicationStates . Paused :
this . activePrintButtons . Add ( resumeResumeButton ) ;
this . activePrintButtons . Add ( cancelPrintButton ) ;
EnableActiveButtons ( ) ;
break ;
case CommunicationStates . FinishedPrint :
this . activePrintButtons . Add ( startPrintButton ) ;
EnableActiveButtons ( ) ;
break ;
default :
DisableActiveButtons ( ) ;
break ;
}
}
if ( printer . Connection . PrinterIsConnected
& & printer . Settings . GetValue < bool > ( SettingsKey . show_reset_connection ) )
{
this . activePrintButtons . Add ( resetConnectionButton ) ;
ShowActiveButtons ( ) ;
EnableActiveButtons ( ) ;
}
ShowActiveButtons ( ) ;
}
protected void ShowActiveButtons ( )
{
foreach ( Button button in this . allPrintButtons )
{
if ( activePrintButtons . IndexOf ( button ) > = 0 )
{
button . Visible = true ;
}
else
{
button . Visible = false ;
}
}
}
#endregion
2017-05-23 19:03:30 -07:00
}
}