2014-04-16 15:11:01 -07:00
/ *
2017-01-23 12:38:34 -08:00
Copyright ( c ) 2017 , Kevin Pope , John Lewin
2014-04-16 15:11:01 -07:00
All rights reserved .
Redistribution and use in source and binary forms , with or without
2015-04-08 15:20:10 -07:00
modification , are permitted provided that the following conditions are met :
2014-04-16 15:11:01 -07:00
1. Redistributions of source code must retain the above copyright notice , this
2015-04-08 15:20:10 -07:00
list of conditions and the following disclaimer .
2014-04-16 15:11:01 -07:00
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
2015-04-08 15:20:10 -07:00
and / or other materials provided with the distribution .
2014-04-16 15:11:01 -07:00
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
2015-04-08 15:20:10 -07:00
of the authors and should not be interpreted as representing official policies ,
2014-04-16 15:11:01 -07:00
either expressed or implied , of the FreeBSD Project .
* /
2017-06-30 18:00:02 -07:00
using System ;
2018-01-18 15:28:09 -08:00
using System.IO ;
2017-06-27 18:41:34 -07:00
using System.Linq ;
using MatterHackers.Agg ;
2018-01-18 15:28:09 -08:00
using MatterHackers.Agg.Platform ;
2017-06-27 18:41:34 -07:00
using MatterHackers.Agg.UI ;
2014-04-16 15:11:01 -07:00
using MatterHackers.Localizations ;
2017-06-27 18:41:34 -07:00
using MatterHackers.MatterControl.ConfigurationPage ;
2017-06-30 18:00:02 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
2014-06-11 14:52:58 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2015-04-08 15:20:10 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2014-04-16 15:11:01 -07:00
namespace MatterHackers.MatterControl.ActionBar
{
2017-09-08 10:23:28 -07:00
internal class ControlContentExtruder : FlowLayoutWidget
2015-04-08 15:20:10 -07:00
{
2017-09-08 10:23:28 -07:00
private int moveAmount = 1 ;
2017-09-15 12:08:00 -07:00
private PrinterConfig printer ;
2017-09-08 10:23:28 -07:00
2017-09-15 12:08:00 -07:00
internal ControlContentExtruder ( PrinterConfig printer , int extruderIndex , TextImageButtonFactory buttonFactory )
2017-09-08 10:23:28 -07:00
: base ( FlowDirection . TopToBottom )
{
HAnchor = HAnchor . Stretch ;
2017-09-15 12:08:00 -07:00
this . printer = printer ;
2017-09-08 10:23:28 -07:00
2018-01-18 15:28:09 -08:00
// add in load and unload buttons
2017-09-08 10:23:28 -07:00
var macroButtons = GetExtruderMacros ( extruderIndex , buttonFactory ) ;
2018-01-18 15:28:09 -08:00
this . AddChild ( new SettingsItem ( "Filament" . Localize ( ) , macroButtons , enforceGutter : false ) ) ;
2017-09-08 10:23:28 -07:00
// Add the Extrude buttons
var moveButtonFactory = ApplicationController . Instance . Theme . MicroButtonMenu ;
var buttonContainer = new FlowLayoutWidget ( )
{
HAnchor = HAnchor . Fit ,
VAnchor = VAnchor . Fit
} ;
var retractButton = buttonFactory . Generate ( "Retract" . Localize ( ) ) ;
retractButton . ToolTipText = "Retract filament" . Localize ( ) ;
retractButton . Margin = new BorderDouble ( 8 , 0 ) ;
retractButton . Click + = ( s , e ) = >
{
2017-09-15 12:08:00 -07:00
printer . Connection . MoveExtruderRelative ( moveAmount * - 1 , printer . Settings . EFeedRate ( extruderIndex ) , extruderIndex ) ;
2017-09-08 10:23:28 -07:00
} ;
buttonContainer . AddChild ( retractButton ) ;
var extrudeButton = buttonFactory . Generate ( "Extrude" . Localize ( ) ) ;
extrudeButton . Name = "Extrude Button" ;
extrudeButton . ToolTipText = "Extrude filament" . Localize ( ) ;
extrudeButton . Margin = 0 ;
extrudeButton . Click + = ( s , e ) = >
{
2017-09-15 12:08:00 -07:00
printer . Connection . MoveExtruderRelative ( moveAmount , printer . Settings . EFeedRate ( extruderIndex ) , extruderIndex ) ;
2017-09-08 10:23:28 -07:00
} ;
buttonContainer . AddChild ( extrudeButton ) ;
this . AddChild ( new SettingsItem (
2017-09-08 11:46:53 -07:00
macroButtons = = null ? "Filament" . Localize ( ) : "" , // Don't put the name if we put in a macro button (it hase the name)
2017-09-08 10:23:28 -07:00
buttonContainer ,
enforceGutter : false ) ) ;
var moveButtonsContainer = new FlowLayoutWidget ( )
{
VAnchor = VAnchor . Fit ,
HAnchor = HAnchor . Fit ,
Margin = new BorderDouble ( 0 , 3 )
} ;
RadioButton oneButton = moveButtonFactory . GenerateRadioButton ( "1" ) ;
oneButton . VAnchor = VAnchor . Center ;
oneButton . CheckedStateChanged + = ( s , e ) = >
{
if ( oneButton . Checked )
{
moveAmount = 1 ;
}
} ;
moveButtonsContainer . AddChild ( oneButton ) ;
RadioButton tenButton = moveButtonFactory . GenerateRadioButton ( "10" ) ;
tenButton . VAnchor = VAnchor . Center ;
tenButton . CheckedStateChanged + = ( s , e ) = >
{
if ( tenButton . Checked )
{
moveAmount = 10 ;
}
} ;
moveButtonsContainer . AddChild ( tenButton ) ;
RadioButton oneHundredButton = moveButtonFactory . GenerateRadioButton ( "100" ) ;
oneHundredButton . VAnchor = VAnchor . Center ;
oneHundredButton . CheckedStateChanged + = ( s , e ) = >
{
if ( oneHundredButton . Checked )
{
moveAmount = 100 ;
}
} ;
moveButtonsContainer . AddChild ( oneHundredButton ) ;
tenButton . Checked = true ;
2017-10-15 00:22:47 -07:00
moveButtonsContainer . AddChild ( new TextWidget ( "mm" , textColor : buttonFactory . Options . NormalTextColor , pointSize : 8 )
2017-09-08 10:23:28 -07:00
{
VAnchor = VAnchor . Center ,
Margin = new BorderDouble ( 3 , 0 )
} ) ;
this . AddChild ( new SettingsItem ( "Distance" . Localize ( ) , moveButtonsContainer , enforceGutter : false ) ) ;
}
private GuiWidget GetExtruderMacros ( int extruderIndex , TextImageButtonFactory buttonFactory )
{
2018-01-18 15:28:09 -08:00
var row = new FlowLayoutWidget ( ) ;
GCodeMacro loadFilament = new GCodeMacro ( ) ;
loadFilament . GCode = AggContext . StaticData . ReadAllText ( Path . Combine ( "SliceSettings" , "load_filament.txt" ) ) ;
Button loadButton = buttonFactory . Generate ( "Load" . Localize ( ) ) ;
loadButton . Margin = new BorderDouble ( 0 , 8 , 8 , 4 ) ;
loadButton . Click + = ( s , e ) = > loadFilament . Run ( printer . Connection ) ;
row . AddChild ( loadButton ) ;
GCodeMacro unloadFilament = new GCodeMacro ( ) ;
unloadFilament . GCode = AggContext . StaticData . ReadAllText ( Path . Combine ( "SliceSettings" , "unload_filament.txt" ) ) ;
Button unloadButton = buttonFactory . Generate ( "Unload" . Localize ( ) ) ;
unloadButton . Click + = ( s , e ) = > unloadFilament . Run ( printer . Connection ) ;
row . AddChild ( unloadButton ) ;
return row ;
2017-09-08 10:23:28 -07:00
}
2017-09-06 18:16:45 -07:00
}
internal class TemperatureWidgetHotend : TemperatureWidgetBase
{
2017-09-11 10:54:46 -07:00
private TextImageButtonFactory buttonFactory ;
2017-09-08 10:23:28 -07:00
private int hotendIndex = - 1 ;
2016-05-03 08:49:16 -07:00
private string sliceSettingsNote = "Note: Slice Settings are applied before the print actually starts. Changes while printing will not effect the active print." . Localize ( ) ;
private string waitingForExtruderToHeatMessage = "The extruder is currently heating and its target temperature cannot be changed until it reaches {0}°C.\n\nYou can set the starting extruder temperature in 'Slice Settings' -> 'Filament'.\n\n{1}" . Localize ( ) ;
2015-04-08 15:20:10 -07:00
2017-09-15 12:08:00 -07:00
public TemperatureWidgetHotend ( PrinterConfig printer , int hotendIndex , TextImageButtonFactory buttonFactory )
: base ( printer , "150.3°" )
2015-04-08 15:20:10 -07:00
{
2017-09-07 16:24:11 -07:00
this . Name = $"Hotend {hotendIndex}" ;
2017-09-08 10:23:28 -07:00
this . hotendIndex = hotendIndex ;
2017-06-27 18:41:34 -07:00
this . buttonFactory = buttonFactory ;
this . DisplayCurrentTemperature ( ) ;
this . ToolTipText = "Current extruder temperature" . Localize ( ) ;
2015-08-12 13:16:39 -07:00
2017-09-15 12:08:00 -07:00
printer . Connection . HotendTemperatureRead . RegisterEvent ( ( s , e ) = > DisplayCurrentTemperature ( ) , ref unregisterEvents ) ;
2015-04-08 15:20:10 -07:00
}
2018-01-10 14:41:14 -08:00
protected override int ActualTemperature = > ( int ) printer . Connection . GetActualHotendTemperature ( this . hotendIndex ) ;
protected override int TargetTemperature = > ( int ) printer . Connection . GetTargetHotendTemperature ( this . hotendIndex ) ;
2015-04-08 15:20:10 -07:00
2018-01-10 12:55:41 -08:00
string TemperatureKey
{
get
{
2018-01-10 14:41:14 -08:00
return "temperature" + ( ( this . hotendIndex > 0 & & this . hotendIndex < 4 ) ? hotendIndex . ToString ( ) : "" ) ;
2018-01-10 12:55:41 -08:00
}
}
2017-06-27 18:41:34 -07:00
protected override GuiWidget GetPopupContent ( )
2017-01-23 12:38:34 -08:00
{
2017-06-27 18:41:34 -07:00
var widget = new IgnoredPopupWidget ( )
{
2017-09-20 11:12:13 -07:00
Width = 350 ,
2017-08-07 15:47:27 -07:00
HAnchor = HAnchor . Absolute ,
VAnchor = VAnchor . Fit ,
2017-10-31 11:43:25 -07:00
BackgroundColor = Color . White ,
2017-06-30 18:00:02 -07:00
Padding = new BorderDouble ( 12 , 5 , 12 , 0 )
2017-06-27 18:41:34 -07:00
} ;
var container = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
2017-08-07 15:47:27 -07:00
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
2017-10-31 11:43:25 -07:00
BackgroundColor = Color . White
2017-06-27 18:41:34 -07:00
} ;
2017-09-06 18:16:45 -07:00
widget . AddChild ( container ) ;
2017-06-27 18:41:34 -07:00
2017-09-07 16:24:11 -07:00
GuiWidget hotendRow ;
container . AddChild ( hotendRow = new SettingsItem (
2017-09-08 10:23:28 -07:00
string . Format ( "{0} {1}" , "Hotend" . Localize ( ) , hotendIndex + 1 ) ,
2017-06-27 18:41:34 -07:00
new SettingsItem . ToggleSwitchConfig ( )
{
Checked = false ,
ToggleAction = ( itemChecked ) = >
{
if ( itemChecked )
{
// Set to goal temp
2018-01-08 18:21:30 -08:00
SetTargetTemperature ( printer . Settings . Helpers . ExtruderTemperature ( hotendIndex ) ) ;
2017-06-27 18:41:34 -07:00
}
else
{
// Turn off extruder
2017-09-15 12:08:00 -07:00
printer . Connection . SetTargetHotendTemperature ( hotendIndex , 0 ) ;
2017-06-27 18:41:34 -07:00
}
}
2017-09-06 18:16:45 -07:00
} ,
2017-06-27 18:41:34 -07:00
enforceGutter : false ) ) ;
2018-01-12 12:21:29 -08:00
heatToggle = hotendRow . Descendants < CheckBox > ( ) . FirstOrDefault ( ) ;
2017-09-07 16:24:11 -07:00
heatToggle . Name = "Toggle Heater" ;
2018-01-08 18:21:30 -08:00
int tabIndex = 0 ;
var settingsContext = new SettingsContext ( printer , null , NamedSettingsLayers . All ) ;
2018-01-09 15:26:06 -08:00
// TODO: make this be for the correct extruder
2018-01-13 18:54:40 -08:00
var settingsData = SettingsOrganizer . Instance . GetSettingsData ( TemperatureKey ) ;
2018-01-14 10:13:42 -08:00
var row = SliceSettingsTabView . CreateItemRow ( settingsData , settingsContext , printer , Color . Black , ApplicationController . Instance . Theme , ref tabIndex ) ;
2018-01-08 18:21:30 -08:00
2018-01-09 15:26:06 -08:00
container . AddChild ( row ) ;
2017-09-06 18:16:45 -07:00
// add in the temp graph
Action fillGraph = null ;
var graph = new DataViewGraph ( )
{
2017-09-08 11:46:53 -07:00
DynamiclyScaleRange = false ,
MinValue = 0 ,
ShowGoal = true ,
GoalColor = ActiveTheme . Instance . PrimaryAccentColor ,
2018-01-08 18:21:30 -08:00
GoalValue = printer . Settings . Helpers . ExtruderTemperature ( hotendIndex ) ,
2017-09-08 11:46:53 -07:00
MaxValue = 280 , // could come from some profile value in the future
2017-09-06 18:16:45 -07:00
Width = widget . Width - 20 ,
2017-09-08 11:46:53 -07:00
Height = 35 , // this works better if it is a common multiple of the Width
} ;
2017-09-06 18:16:45 -07:00
fillGraph = ( ) = >
{
graph . AddData ( this . ActualTemperature ) ;
2017-09-08 10:23:28 -07:00
if ( ! this . HasBeenClosed )
2017-09-06 18:16:45 -07:00
{
UiThread . RunOnIdle ( fillGraph , 1 ) ;
}
} ;
2018-01-12 12:21:29 -08:00
var valueField = row . Descendants < MHNumberEdit > ( ) . FirstOrDefault ( ) ;
2018-01-09 15:26:06 -08:00
valueField . Name = "Temperature Input" ;
2018-01-13 13:03:14 -08:00
var settingsRow = row . DescendantsAndSelf < SliceSettingsRow > ( ) . FirstOrDefault ( ) ;
2018-01-08 18:21:30 -08:00
ActiveSliceSettings . SettingChanged . RegisterEvent ( ( s , e ) = >
{
if ( e is StringEventArgs stringEvent )
{
2018-01-10 12:55:41 -08:00
if ( stringEvent . Data = = TemperatureKey )
2018-01-08 18:21:30 -08:00
{
2018-01-10 12:55:41 -08:00
var temp = printer . Settings . Helpers . ExtruderTemperature ( hotendIndex ) ;
valueField . Value = temp ;
graph . GoalValue = temp ;
settingsRow . UpdateStyle ( ) ;
if ( heatToggle . Checked )
{
SetTargetTemperature ( temp ) ;
}
2018-01-08 18:21:30 -08:00
}
} ;
} , ref unregisterEvents ) ;
2017-09-06 18:16:45 -07:00
UiThread . RunOnIdle ( fillGraph ) ;
container . AddChild ( graph ) ;
2018-01-10 12:55:41 -08:00
if ( hotendIndex = = 0 )
2017-06-27 18:41:34 -07:00
{
2018-01-10 12:55:41 -08:00
// put in the material selector
var presetsSelector = new PresetSelectorWidget ( printer , "Material" . Localize ( ) , Color . Transparent , NamedSettingsLayers . Material , true )
{
Margin = 0 ,
BackgroundColor = Color . Transparent ,
HAnchor = HAnchor . Absolute ,
Width = 150
} ;
2017-06-27 18:41:34 -07:00
2018-01-10 12:55:41 -08:00
presetsSelector . DropDownList . Name = "Hotend Preset Selector" ;
2017-09-21 09:12:33 -07:00
2018-01-10 12:55:41 -08:00
this . Width = 150 ;
2017-06-27 18:41:34 -07:00
2018-01-10 12:55:41 -08:00
// HACK: remove undesired item
var label = presetsSelector . Children < TextWidget > ( ) . FirstOrDefault ( ) ;
label . Close ( ) ;
2017-06-27 18:41:34 -07:00
2018-01-10 12:55:41 -08:00
var pulldownContainer = presetsSelector . FindNamedChildRecursive ( "Preset Pulldown Container" ) ;
if ( pulldownContainer ! = null )
{
pulldownContainer . Padding = 0 ;
}
2017-06-27 18:41:34 -07:00
2018-01-10 12:55:41 -08:00
var dropList = presetsSelector . FindNamedChildRecursive ( "Material" ) as DropDownList ;
if ( dropList ! = null )
{
dropList . TextColor = Color . Black ;
}
container . AddChild ( new SettingsItem ( "Material" . Localize ( ) , presetsSelector , enforceGutter : false ) ) ;
2017-06-27 18:41:34 -07:00
}
2018-01-10 12:55:41 -08:00
else // put in a temperature selector for the correct material
{
2017-06-27 18:41:34 -07:00
2018-01-10 12:55:41 -08:00
}
2017-06-27 18:41:34 -07:00
2017-09-08 10:23:28 -07:00
// put in the actual extruder controls
2017-09-15 12:08:00 -07:00
bool shareTemp = printer . Settings . GetValue < bool > ( SettingsKey . extruders_share_temperature ) ;
int extruderCount = printer . Settings . GetValue < int > ( SettingsKey . extruder_count ) ;
2017-09-08 11:46:53 -07:00
if ( shareTemp & & extruderCount > 1 )
2017-06-27 18:41:34 -07:00
{
2017-09-08 10:23:28 -07:00
for ( int extruderIndex = 0 ; extruderIndex < extruderCount ; extruderIndex + + )
2017-06-27 18:41:34 -07:00
{
2017-09-08 10:23:28 -07:00
container . AddChild ( new HorizontalLine ( )
{
Margin = new BorderDouble ( 0 , 5 , 0 , 0 )
} ) ;
2017-06-27 18:41:34 -07:00
2017-09-08 10:23:28 -07:00
container . AddChild ( new TextWidget ( "Extruder" . Localize ( ) + " " + ( extruderIndex + 1 ) . ToString ( ) )
{
AutoExpandBoundsToText = true ,
2017-10-31 11:43:25 -07:00
TextColor = Color . Black ,
2017-09-11 10:54:46 -07:00
HAnchor = HAnchor . Left ,
2017-09-08 10:23:28 -07:00
} ) ;
2017-09-15 12:08:00 -07:00
container . AddChild ( new ControlContentExtruder ( printer , extruderIndex , buttonFactory ) ) ;
2017-06-27 18:41:34 -07:00
}
2017-09-08 10:23:28 -07:00
}
else
2017-06-27 18:41:34 -07:00
{
2017-09-15 12:08:00 -07:00
container . AddChild ( new ControlContentExtruder ( printer , hotendIndex , buttonFactory ) ) ;
2017-09-08 10:23:28 -07:00
}
2017-06-27 18:41:34 -07:00
2017-09-06 18:16:45 -07:00
return widget ;
}
2017-06-30 18:00:02 -07:00
2017-09-20 13:15:25 -07:00
public override void OnDraw ( Graphics2D graphics2D )
{
if ( heatToggle ! = null )
{
heatToggle . Checked = printer . Connection . GetTargetHotendTemperature ( hotendIndex ) ! = 0 ;
}
base . OnDraw ( graphics2D ) ;
}
2017-09-11 10:54:46 -07:00
protected override void SetTargetTemperature ( double targetTemp )
2017-07-31 17:57:10 -07:00
{
2017-09-11 10:54:46 -07:00
double goalTemp = ( int ) ( targetTemp + . 5 ) ;
2017-09-15 12:08:00 -07:00
if ( printer . Connection . PrinterIsPrinting
& & printer . Connection . DetailedPrintingState = = DetailedPrintingState . HeatingExtruder
& & goalTemp ! = printer . Connection . GetTargetHotendTemperature ( hotendIndex ) )
2017-07-31 17:57:10 -07:00
{
2017-09-15 12:08:00 -07:00
string message = string . Format ( waitingForExtruderToHeatMessage , printer . Connection . GetTargetHotendTemperature ( hotendIndex ) , sliceSettingsNote ) ;
2017-10-18 19:54:06 -07:00
StyledMessageBox . ShowMessageBox ( message , "Waiting For Extruder To Heat" . Localize ( ) ) ;
2017-09-11 10:54:46 -07:00
}
else
{
2017-09-15 12:08:00 -07:00
printer . Connection . SetTargetHotendTemperature ( hotendIndex , ( int ) ( targetTemp + . 5 ) ) ;
2017-07-31 17:57:10 -07:00
}
}
2015-04-08 15:20:10 -07:00
}
}