2019-01-16 11:22:17 +00:00
// #include "libslic3r/GCodeSender.hpp"
2019-03-27 11:14:34 +00:00
# include "slic3r/Utils/Serial.hpp"
2018-01-25 12:46:04 +00:00
# include "Tab.hpp"
# include "PresetBundle.hpp"
# include "PresetHints.hpp"
2018-12-04 16:56:49 +00:00
# include "libslic3r/Utils.hpp"
2018-03-16 13:06:23 +00:00
2018-03-15 17:06:26 +00:00
# include "slic3r/Utils/Http.hpp"
2018-07-08 12:32:48 +00:00
# include "slic3r/Utils/PrintHost.hpp"
2018-03-15 17:06:26 +00:00
# include "BonjourDialog.hpp"
2018-02-28 15:04:56 +00:00
# include "WipeTowerDialog.hpp"
2018-04-20 10:58:07 +00:00
# include "ButtonsDescription.hpp"
2018-01-25 12:46:04 +00:00
2017-12-05 14:54:01 +00:00
# include <wx/app.h>
# include <wx/button.h>
2017-12-13 13:45:10 +00:00
# include <wx/scrolwin.h>
2017-12-05 14:54:01 +00:00
# include <wx/sizer.h>
# include <wx/bmpcbox.h>
# include <wx/bmpbuttn.h>
# include <wx/treectrl.h>
# include <wx/imaglist.h>
2017-12-22 10:50:28 +00:00
# include <wx/settings.h>
2018-03-15 17:06:26 +00:00
# include <wx/filedlg.h>
2017-12-05 14:54:01 +00:00
2018-01-18 10:45:25 +00:00
# include <boost/algorithm/string/predicate.hpp>
2018-04-06 11:37:00 +00:00
# include "wxExtensions.hpp"
2018-04-17 08:15:48 +00:00
# include <wx/wupdlock.h>
2018-01-03 09:12:42 +00:00
2018-09-20 23:33:41 +00:00
# include "GUI_App.hpp"
2018-11-29 11:33:04 +00:00
# include "GUI_ObjectList.hpp"
2019-03-22 14:45:51 +00:00
# include "ConfigWizard.hpp"
2018-01-03 09:12:42 +00:00
2017-12-05 14:54:01 +00:00
namespace Slic3r {
namespace GUI {
2018-10-03 14:27:02 +00:00
wxDEFINE_EVENT ( EVT_TAB_VALUE_CHANGED , wxCommandEvent ) ;
wxDEFINE_EVENT ( EVT_TAB_PRESETS_CHANGED , SimpleEvent ) ;
2018-12-04 16:56:49 +00:00
Tab : : Tab ( wxNotebook * parent , const wxString & title , const char * name ) :
m_parent ( parent ) , m_title ( title ) , m_name ( name )
{
Create ( parent , wxID_ANY , wxDefaultPosition , wxDefaultSize , wxBK_LEFT | wxTAB_TRAVERSAL , name ) ;
set_type ( ) ;
m_compatible_printers . type = Preset : : TYPE_PRINTER ;
m_compatible_printers . key_list = " compatible_printers " ;
m_compatible_printers . key_condition = " compatible_printers_condition " ;
m_compatible_printers . dialog_title = _ ( L ( " Compatible printers " ) ) ;
m_compatible_printers . dialog_label = _ ( L ( " Select the printers this profile is compatible with. " ) ) ;
m_compatible_prints . type = Preset : : TYPE_PRINT ;
m_compatible_prints . key_list = " compatible_prints " ;
m_compatible_prints . key_condition = " compatible_prints_condition " ;
m_compatible_prints . dialog_title = _ ( L ( " Compatible print profiles " ) ) ;
m_compatible_prints . dialog_label = _ ( L ( " Select the print profiles this profile is compatible with. " ) ) ;
wxGetApp ( ) . tabs_list . push_back ( this ) ;
2019-02-04 11:07:15 +00:00
m_em_unit = wxGetApp ( ) . em_unit ( ) ;
2019-03-18 11:48:39 +00:00
Bind ( wxEVT_SIZE , ( [ this ] ( wxSizeEvent & evt ) {
for ( auto page : m_pages )
if ( ! page . get ( ) - > IsShown ( ) )
page - > layout_valid = false ;
evt . Skip ( ) ;
} ) ) ;
2018-12-04 16:56:49 +00:00
}
2018-10-03 14:27:02 +00:00
2018-10-09 10:41:05 +00:00
void Tab : : set_type ( )
{
if ( m_name = = " print " ) { m_type = Slic3r : : Preset : : TYPE_PRINT ; }
2018-11-16 16:36:23 +00:00
else if ( m_name = = " sla_print " ) { m_type = Slic3r : : Preset : : TYPE_SLA_PRINT ; }
2018-10-09 10:41:05 +00:00
else if ( m_name = = " filament " ) { m_type = Slic3r : : Preset : : TYPE_FILAMENT ; }
else if ( m_name = = " sla_material " ) { m_type = Slic3r : : Preset : : TYPE_SLA_MATERIAL ; }
else if ( m_name = = " printer " ) { m_type = Slic3r : : Preset : : TYPE_PRINTER ; }
2018-12-04 16:56:49 +00:00
else { m_type = Slic3r : : Preset : : TYPE_INVALID ; assert ( false ) ; }
2018-10-09 10:41:05 +00:00
}
2017-12-05 14:54:01 +00:00
// sub new
2018-10-04 14:43:10 +00:00
void Tab : : create_preset_tab ( )
2017-12-05 14:54:01 +00:00
{
2019-03-13 12:13:18 +00:00
# ifdef __WINDOWS__
2019-03-18 11:48:39 +00:00
SetDoubleBuffered ( true ) ;
2019-03-13 12:13:18 +00:00
# endif //__WINDOWS__
2018-10-04 14:43:10 +00:00
m_preset_bundle = wxGetApp ( ) . preset_bundle ;
2018-01-05 14:11:33 +00:00
2017-12-05 14:54:01 +00:00
// Vertical sizer to hold the choice menu and the rest of the page.
2018-06-28 16:30:22 +00:00
# ifdef __WXOSX__
auto * main_sizer = new wxBoxSizer ( wxVERTICAL ) ;
main_sizer - > SetSizeHints ( this ) ;
this - > SetSizer ( main_sizer ) ;
// Create additional panel to Fit() it from OnActivate()
// It's needed for tooltip showing on OSX
m_tmp_panel = new wxPanel ( this , wxID_ANY , wxDefaultPosition , wxDefaultSize , wxBK_LEFT | wxTAB_TRAVERSAL ) ;
auto panel = m_tmp_panel ;
auto sizer = new wxBoxSizer ( wxVERTICAL ) ;
m_tmp_panel - > SetSizer ( sizer ) ;
m_tmp_panel - > Layout ( ) ;
main_sizer - > Add ( m_tmp_panel , 1 , wxEXPAND | wxALL , 0 ) ;
# else
2018-01-05 14:11:33 +00:00
Tab * panel = this ;
2017-12-05 14:54:01 +00:00
auto * sizer = new wxBoxSizer ( wxVERTICAL ) ;
sizer - > SetSizeHints ( panel ) ;
panel - > SetSizer ( sizer ) ;
2018-06-28 16:30:22 +00:00
# endif //__WXOSX__
2017-12-05 14:54:01 +00:00
// preset chooser
2019-04-16 08:05:45 +00:00
m_presets_choice = new wxBitmapComboBox ( panel , wxID_ANY , " " , wxDefaultPosition , wxSize ( 35 * m_em_unit , - 1 ) , 0 , 0 , wxCB_READONLY ) ;
2018-04-06 11:37:00 +00:00
2018-03-06 08:44:53 +00:00
auto color = wxSystemSettings : : GetColour ( wxSYS_COLOUR_WINDOW ) ;
2017-12-05 14:54:01 +00:00
//buttons
2019-04-13 21:46:52 +00:00
m_scaled_buttons . reserve ( 6 ) ;
m_scaled_buttons . reserve ( 2 ) ;
add_scaled_button ( panel , & m_btn_save_preset , " save " ) ;
add_scaled_button ( panel , & m_btn_delete_preset , " cross " ) ;
2017-12-05 14:54:01 +00:00
2018-01-16 15:28:01 +00:00
m_show_incompatible_presets = false ;
2019-04-13 21:46:52 +00:00
add_scaled_bitmap ( this , m_bmp_show_incompatible_presets , " flag_red " ) ;
add_scaled_bitmap ( this , m_bmp_hide_incompatible_presets , " flag_green " ) ;
2019-04-24 23:45:00 +00:00
2019-04-13 21:46:52 +00:00
add_scaled_button ( panel , & m_btn_hide_incompatible_presets , m_bmp_hide_incompatible_presets . name ( ) ) ;
2017-12-13 13:45:10 +00:00
2018-02-23 08:16:35 +00:00
m_btn_save_preset - > SetToolTip ( _ ( L ( " Save current " ) ) + m_title ) ;
m_btn_delete_preset - > SetToolTip ( _ ( L ( " Delete this preset " ) ) ) ;
2017-12-26 22:04:54 +00:00
m_btn_delete_preset - > Disable ( ) ;
2017-12-13 13:45:10 +00:00
2019-04-13 21:46:52 +00:00
add_scaled_button ( panel , & m_question_btn , " question " ) ;
2018-04-30 12:20:33 +00:00
m_question_btn - > SetToolTip ( _ ( L ( " Hover the cursor over buttons to find more information \n "
" or click this button. " ) ) ) ;
2018-04-19 14:20:30 +00:00
2018-04-23 08:27:42 +00:00
// Determine the theme color of OS (dark or light)
2018-10-01 13:09:31 +00:00
auto luma = wxGetApp ( ) . get_colour_approx_luma ( wxSystemSettings : : GetColour ( wxSYS_COLOUR_WINDOW ) ) ;
2018-04-16 09:03:08 +00:00
// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
2019-04-13 21:46:52 +00:00
add_scaled_bitmap ( this , m_bmp_value_lock , luma > = 128 ? " lock_closed " : " lock_closed_white " ) ;
add_scaled_bitmap ( this , m_bmp_value_unlock , " lock_open " ) ;
2018-04-16 09:03:08 +00:00
m_bmp_non_system = & m_bmp_white_bullet ;
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
2019-04-13 21:46:52 +00:00
add_scaled_bitmap ( this , m_bmp_value_revert , " undo " ) ;
2019-04-24 23:45:00 +00:00
add_scaled_bitmap ( this , m_bmp_white_bullet , luma > = 128 ? " dot " : " dot_white " ) ;
2018-04-19 14:20:30 +00:00
2018-04-20 10:58:07 +00:00
fill_icon_descriptions ( ) ;
2018-04-24 12:11:23 +00:00
set_tooltips_text ( ) ;
2018-04-20 10:58:07 +00:00
2019-04-13 21:46:52 +00:00
add_scaled_button ( panel , & m_undo_btn , m_bmp_white_bullet . name ( ) ) ;
add_scaled_button ( panel , & m_undo_to_sys_btn , m_bmp_white_bullet . name ( ) ) ;
2018-10-31 11:56:08 +00:00
m_undo_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent ) { on_roll_back_value ( ) ; } ) ) ;
m_undo_to_sys_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent ) { on_roll_back_value ( true ) ; } ) ) ;
2018-04-20 10:58:07 +00:00
m_question_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent )
{
2018-04-20 13:02:54 +00:00
auto dlg = new ButtonsDescription ( this , & m_icon_descriptions ) ;
2018-10-31 11:56:08 +00:00
if ( dlg - > ShowModal ( ) = = wxID_OK ) {
2018-04-30 12:20:33 +00:00
// Colors for ui "decoration"
2018-10-31 11:56:08 +00:00
for ( Tab * tab : wxGetApp ( ) . tabs_list ) {
2018-10-01 13:09:31 +00:00
tab - > m_sys_label_clr = wxGetApp ( ) . get_label_clr_sys ( ) ;
tab - > m_modified_label_clr = wxGetApp ( ) . get_label_clr_modified ( ) ;
2018-04-30 12:20:33 +00:00
tab - > update_labels_colour ( ) ;
}
}
2018-04-20 10:58:07 +00:00
} ) ) ;
2018-03-21 21:21:37 +00:00
2018-04-17 08:15:48 +00:00
// Colors for ui "decoration"
2018-10-01 13:09:31 +00:00
m_sys_label_clr = wxGetApp ( ) . get_label_clr_sys ( ) ;
m_modified_label_clr = wxGetApp ( ) . get_label_clr_modified ( ) ;
m_default_text_clr = wxGetApp ( ) . get_label_clr_default ( ) ;
2018-03-21 21:21:37 +00:00
2019-01-10 10:05:58 +00:00
// Sizer with buttons for mode changing
2019-04-24 23:45:00 +00:00
m_mode_sizer = new ModeSizer ( panel ) ;
2019-01-10 10:05:58 +00:00
2019-02-06 14:29:13 +00:00
const float scale_factor = wxGetApp ( ) . em_unit ( ) * 0.1 ; // GetContentScaleFactor();
2017-12-26 22:04:54 +00:00
m_hsizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2019-01-11 11:47:40 +00:00
sizer - > Add ( m_hsizer , 0 , wxEXPAND | wxBOTTOM , 3 ) ;
m_hsizer - > Add ( m_presets_choice , 0 , wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL , 3 ) ;
2019-02-06 14:29:13 +00:00
m_hsizer - > AddSpacer ( int ( 4 * scale_factor ) ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Add ( m_btn_save_preset , 0 , wxALIGN_CENTER_VERTICAL ) ;
2019-02-06 14:29:13 +00:00
m_hsizer - > AddSpacer ( int ( 4 * scale_factor ) ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Add ( m_btn_delete_preset , 0 , wxALIGN_CENTER_VERTICAL ) ;
2019-02-06 14:29:13 +00:00
m_hsizer - > AddSpacer ( int ( 16 * scale_factor ) ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Add ( m_btn_hide_incompatible_presets , 0 , wxALIGN_CENTER_VERTICAL ) ;
2019-02-06 14:29:13 +00:00
m_hsizer - > AddSpacer ( int ( 64 * scale_factor ) ) ;
2018-03-21 21:21:37 +00:00
m_hsizer - > Add ( m_undo_to_sys_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
m_hsizer - > Add ( m_undo_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
2019-02-06 14:29:13 +00:00
m_hsizer - > AddSpacer ( int ( 32 * scale_factor ) ) ;
2018-04-19 14:20:30 +00:00
m_hsizer - > Add ( m_question_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
2019-01-11 11:47:40 +00:00
// m_hsizer->AddStretchSpacer(32);
// StretchSpacer has a strange behavior under OSX, so
// There is used just additional sizer for m_mode_sizer with right alignment
auto mode_sizer = new wxBoxSizer ( wxVERTICAL ) ;
mode_sizer - > Add ( m_mode_sizer , 1 , wxALIGN_RIGHT ) ;
m_hsizer - > Add ( mode_sizer , 1 , wxALIGN_CENTER_VERTICAL | wxRIGHT , wxOSX ? 15 : 5 ) ;
2017-12-05 14:54:01 +00:00
//Horizontal sizer to hold the tree and the selected page.
2017-12-26 22:04:54 +00:00
m_hsizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( m_hsizer , 1 , wxEXPAND , 0 ) ;
2017-12-05 14:54:01 +00:00
//left vertical sizer
2017-12-26 22:04:54 +00:00
m_left_sizer = new wxBoxSizer ( wxVERTICAL ) ;
m_hsizer - > Add ( m_left_sizer , 0 , wxEXPAND | wxLEFT | wxTOP | wxBOTTOM , 3 ) ;
2017-12-05 14:54:01 +00:00
// tree
2019-02-07 13:44:05 +00:00
m_treectrl = new wxTreeCtrl ( panel , wxID_ANY , wxDefaultPosition , wxSize ( 20 * m_em_unit , - 1 ) ,
2018-01-18 10:45:25 +00:00
wxTR_NO_BUTTONS | wxTR_HIDE_ROOT | wxTR_SINGLE | wxTR_NO_LINES | wxBORDER_SUNKEN | wxWANTS_CHARS ) ;
2017-12-26 22:04:54 +00:00
m_left_sizer - > Add ( m_treectrl , 1 , wxEXPAND ) ;
2019-02-06 14:29:13 +00:00
m_icons = new wxImageList ( int ( 16 * scale_factor ) , int ( 16 * scale_factor ) , true , 1 ) ;
2017-12-05 14:54:01 +00:00
// Index of the last icon inserted into $self->{icons}.
2017-12-26 22:04:54 +00:00
m_icon_count = - 1 ;
m_treectrl - > AssignImageList ( m_icons ) ;
m_treectrl - > AddRoot ( " root " ) ;
m_treectrl - > SetIndent ( 0 ) ;
m_disable_tree_sel_changed_event = 0 ;
2017-12-13 13:45:10 +00:00
2018-01-05 14:11:33 +00:00
m_treectrl - > Bind ( wxEVT_TREE_SEL_CHANGED , & Tab : : OnTreeSelChange , this ) ;
m_treectrl - > Bind ( wxEVT_KEY_DOWN , & Tab : : OnKeyDown , this ) ;
2017-12-13 13:45:10 +00:00
2018-10-31 11:56:08 +00:00
m_presets_choice - > Bind ( wxEVT_COMBOBOX , ( [ this ] ( wxCommandEvent e ) {
2018-02-01 11:09:09 +00:00
//! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox,
//! but the OSX version derived from wxOwnerDrawnCombo, instead of:
2019-01-03 13:34:53 +00:00
//! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
2018-02-01 11:09:09 +00:00
//! we doing next:
int selected_item = m_presets_choice - > GetSelection ( ) ;
2018-04-26 10:40:17 +00:00
if ( m_selected_preset_item = = selected_item & & ! m_presets - > current_is_dirty ( ) )
2018-04-19 10:08:59 +00:00
return ;
2018-10-31 11:56:08 +00:00
if ( selected_item > = 0 ) {
2018-02-05 11:49:23 +00:00
std : : string selected_string = m_presets_choice - > GetString ( selected_item ) . ToUTF8 ( ) . data ( ) ;
2019-03-22 16:07:12 +00:00
if ( selected_string . find ( PresetCollection : : separator_head ( ) ) = = 0
2018-05-02 11:20:36 +00:00
/*selected_string == "------- System presets -------" ||
2018-10-31 11:56:08 +00:00
selected_string = = " ------- User presets ------- " */ ) {
2018-04-19 10:08:59 +00:00
m_presets_choice - > SetSelection ( m_selected_preset_item ) ;
2019-03-22 16:07:12 +00:00
if ( wxString : : FromUTF8 ( selected_string . c_str ( ) ) = = PresetCollection : : separator ( L ( " Add a new printer " ) ) )
2019-03-22 14:45:51 +00:00
wxTheApp - > CallAfter ( [ ] ( ) { Slic3r : : GUI : : config_wizard ( Slic3r : : GUI : : ConfigWizard : : RR_USER ) ; } ) ;
2018-04-19 10:08:59 +00:00
return ;
}
m_selected_preset_item = selected_item ;
2018-02-05 10:03:13 +00:00
select_preset ( selected_string ) ;
2018-02-01 11:09:09 +00:00
}
2018-01-16 15:28:01 +00:00
} ) ) ;
2018-10-31 11:56:08 +00:00
m_btn_save_preset - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent e ) { save_preset ( ) ; } ) ) ;
m_btn_delete_preset - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent e ) { delete_preset ( ) ; } ) ) ;
m_btn_hide_incompatible_presets - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent e ) {
2018-01-18 10:45:25 +00:00
toggle_show_hide_incompatible ( ) ;
2018-01-16 15:28:01 +00:00
} ) ) ;
2017-12-13 13:45:10 +00:00
2019-04-13 21:46:52 +00:00
// Fill cache for mode bitmaps
m_mode_bitmap_cache . reserve ( 3 ) ;
2019-04-24 23:45:00 +00:00
m_mode_bitmap_cache . push_back ( ScalableBitmap ( this , " mode_simple_.png " ) ) ;
m_mode_bitmap_cache . push_back ( ScalableBitmap ( this , " mode_middle_.png " ) ) ;
m_mode_bitmap_cache . push_back ( ScalableBitmap ( this , " mode_expert_.png " ) ) ;
2019-04-13 21:46:52 +00:00
2017-12-05 14:54:01 +00:00
// Initialize the DynamicPrintConfig by default keys/values.
2017-12-13 13:45:10 +00:00
build ( ) ;
rebuild_page_tree ( ) ;
2019-03-07 15:36:39 +00:00
m_complited = true ;
2017-12-05 14:54:01 +00:00
}
2019-04-24 23:45:00 +00:00
void Tab : : add_scaled_button ( wxWindow * parent ,
ScalableButton * * btn ,
const std : : string & icon_name ,
2019-04-13 21:46:52 +00:00
const wxString & label /* = wxEmptyString*/ ,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/ )
{
2019-04-24 23:45:00 +00:00
* btn = new ScalableButton ( parent , wxID_ANY , icon_name , label , wxDefaultSize , wxDefaultPosition , style ) ;
2019-04-13 21:46:52 +00:00
m_scaled_buttons . push_back ( * btn ) ;
}
2019-04-24 23:45:00 +00:00
void Tab : : add_scaled_bitmap ( wxWindow * parent ,
ScalableBitmap & bmp ,
const std : : string & icon_name )
2019-04-13 21:46:52 +00:00
{
2019-04-24 23:45:00 +00:00
bmp = ScalableBitmap ( parent , icon_name ) ;
2019-04-13 21:46:52 +00:00
m_scaled_bitmaps . push_back ( & bmp ) ;
}
2018-03-16 11:56:03 +00:00
void Tab : : load_initial_data ( )
{
m_config = & m_presets - > get_edited_preset ( ) . config ;
2018-04-16 09:03:08 +00:00
m_bmp_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_bmp_value_unlock : & m_bmp_white_bullet ;
2018-04-24 12:11:23 +00:00
m_ttg_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_ttg_value_unlock : & m_ttg_white_bullet_ns ;
m_tt_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_tt_value_unlock : & m_ttg_white_bullet_ns ;
2018-03-16 11:56:03 +00:00
}
2018-08-03 12:34:52 +00:00
Slic3r : : GUI : : PageShp Tab : : add_options_page ( const wxString & title , const std : : string & icon , bool is_extruder_pages /*= false*/ )
2017-12-05 14:54:01 +00:00
{
2017-12-13 13:45:10 +00:00
// Index of icon in an icon list $self->{icons}.
auto icon_idx = 0 ;
2017-12-26 22:04:54 +00:00
if ( ! icon . empty ( ) ) {
2018-02-28 14:39:20 +00:00
icon_idx = ( m_icon_index . find ( icon ) = = m_icon_index . end ( ) ) ? - 1 : m_icon_index . at ( icon ) ;
2017-12-13 13:45:10 +00:00
if ( icon_idx = = - 1 ) {
// Add a new icon to the icon list.
2019-04-24 23:45:00 +00:00
m_scaled_icons_list . push_back ( ScalableBitmap ( this , icon ) ) ;
2019-04-13 21:46:52 +00:00
m_icons - > Add ( m_scaled_icons_list . back ( ) . bmp ( ) ) ;
2018-10-23 09:44:46 +00:00
icon_idx = + + m_icon_count ;
2017-12-26 22:04:54 +00:00
m_icon_index [ icon ] = icon_idx ;
2017-12-13 13:45:10 +00:00
}
}
// Initialize the page.
2018-06-28 16:30:22 +00:00
# ifdef __WXOSX__
auto panel = m_tmp_panel ;
# else
auto panel = this ;
# endif
2019-04-13 21:46:52 +00:00
PageShp page ( new Page ( panel , title , icon_idx , m_mode_bitmap_cache ) ) ;
2019-03-18 11:48:39 +00:00
// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
# ifdef __WINDOWS__
// page->SetDoubleBuffered(true);
# endif //__WINDOWS__
2018-12-18 12:22:22 +00:00
page - > SetScrollbars ( 1 , 20 , 1 , 2 ) ;
2017-12-13 13:45:10 +00:00
page - > Hide ( ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Add ( page . get ( ) , 1 , wxEXPAND | wxLEFT , 5 ) ;
2018-08-03 12:34:52 +00:00
2018-08-07 09:58:27 +00:00
if ( ! is_extruder_pages )
2018-01-02 11:50:27 +00:00
m_pages . push_back ( page ) ;
2017-12-14 13:42:47 +00:00
2018-01-12 11:41:13 +00:00
page - > set_config ( m_config ) ;
2017-12-13 13:45:10 +00:00
return page ;
}
2018-06-27 07:07:04 +00:00
void Tab : : OnActivate ( )
{
# ifdef __WXOSX__
wxWindowUpdateLocker noUpdates ( this ) ;
2018-06-28 16:30:22 +00:00
auto size = GetSizer ( ) - > GetSize ( ) ;
m_tmp_panel - > GetSizer ( ) - > SetMinSize ( size . x + m_size_move , size . y ) ;
Fit ( ) ;
m_size_move * = - 1 ;
# endif // __WXOSX__
2018-06-27 07:07:04 +00:00
}
2018-04-30 12:20:33 +00:00
void Tab : : update_labels_colour ( )
{
2019-03-18 11:48:39 +00:00
// Freeze();
2018-04-30 12:20:33 +00:00
//update options "decoration"
for ( const auto opt : m_options_list )
{
const wxColour * color = & m_sys_label_clr ;
// value isn't equal to system value
2018-10-31 11:56:08 +00:00
if ( ( opt . second & osSystemValue ) = = 0 ) {
2018-04-30 12:20:33 +00:00
// value is equal to last saved
if ( ( opt . second & osInitValue ) ! = 0 )
color = & m_default_text_clr ;
// value is modified
else
color = & m_modified_label_clr ;
}
2018-12-04 16:56:49 +00:00
if ( opt . first = = " bed_shape " | | opt . first = = " compatible_prints " | | opt . first = = " compatible_printers " ) {
2018-04-30 12:20:33 +00:00
if ( m_colored_Label ! = nullptr ) {
m_colored_Label - > SetForegroundColour ( * color ) ;
m_colored_Label - > Refresh ( true ) ;
}
continue ;
}
Field * field = get_field ( opt . first ) ;
if ( field = = nullptr ) continue ;
field - > set_label_colour_force ( color ) ;
}
2019-03-18 11:48:39 +00:00
// Thaw();
2018-04-30 12:20:33 +00:00
auto cur_item = m_treectrl - > GetFirstVisibleItem ( ) ;
2018-10-31 11:56:08 +00:00
while ( cur_item ) {
2018-04-30 12:20:33 +00:00
auto title = m_treectrl - > GetItemText ( cur_item ) ;
for ( auto page : m_pages )
{
if ( page - > title ( ) ! = title )
continue ;
const wxColor * clr = ! page - > m_is_nonsys_values ? & m_sys_label_clr :
page - > m_is_modified_values ? & m_modified_label_clr :
& m_default_text_clr ;
m_treectrl - > SetItemTextColour ( cur_item , * clr ) ;
break ;
}
cur_item = m_treectrl - > GetNextVisible ( cur_item ) ;
}
}
2018-03-09 07:34:32 +00:00
// Update UI according to changes
void Tab : : update_changed_ui ( )
{
2018-04-16 11:43:01 +00:00
if ( m_postpone_update_ui )
return ;
2018-03-07 14:05:41 +00:00
2019-03-22 11:11:23 +00:00
const bool deep_compare = ( m_type = = Slic3r : : Preset : : TYPE_PRINTER | | m_type = = Slic3r : : Preset : : TYPE_SLA_MATERIAL ) ;
2018-08-08 15:47:59 +00:00
auto dirty_options = m_presets - > current_dirty_options ( deep_compare ) ;
auto nonsys_options = m_presets - > current_different_from_parent_options ( deep_compare ) ;
2018-12-04 16:56:49 +00:00
if ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) {
2018-03-08 10:58:06 +00:00
TabPrinter * tab = static_cast < TabPrinter * > ( this ) ;
2018-03-19 16:21:37 +00:00
if ( tab - > m_initial_extruders_count ! = tab - > m_extruders_count )
2018-04-18 12:15:13 +00:00
dirty_options . emplace_back ( " extruders_count " ) ;
2018-04-18 11:32:21 +00:00
if ( tab - > m_sys_extruders_count ! = tab - > m_extruders_count )
2018-04-18 12:15:13 +00:00
nonsys_options . emplace_back ( " extruders_count " ) ;
2018-04-18 11:32:21 +00:00
}
2018-03-19 16:21:37 +00:00
2018-04-18 11:32:21 +00:00
for ( auto & it : m_options_list )
it . second = m_opt_status_value ;
2018-03-19 16:21:37 +00:00
2018-04-18 12:15:13 +00:00
for ( auto opt_key : dirty_options ) m_options_list [ opt_key ] & = ~ osInitValue ;
for ( auto opt_key : nonsys_options ) m_options_list [ opt_key ] & = ~ osSystemValue ;
2018-03-16 11:56:03 +00:00
2019-03-18 11:48:39 +00:00
// Freeze();
2018-03-23 16:27:43 +00:00
//update options "decoration"
2018-04-18 12:15:13 +00:00
for ( const auto opt : m_options_list )
2018-03-21 21:21:37 +00:00
{
2018-03-23 16:27:43 +00:00
bool is_nonsys_value = false ;
bool is_modified_value = true ;
2019-04-24 23:45:00 +00:00
const ScalableBitmap * sys_icon = & m_bmp_value_lock ;
const ScalableBitmap * icon = & m_bmp_value_revert ;
2018-04-18 11:32:21 +00:00
2018-04-24 12:11:23 +00:00
const wxColour * color = & m_sys_label_clr ;
const wxString * sys_tt = & m_tt_value_lock ;
const wxString * tt = & m_tt_value_revert ;
// value isn't equal to system value
2018-10-31 11:56:08 +00:00
if ( ( opt . second & osSystemValue ) = = 0 ) {
2018-03-23 16:27:43 +00:00
is_nonsys_value = true ;
2018-04-18 11:32:21 +00:00
sys_icon = m_bmp_non_system ;
2018-04-24 12:11:23 +00:00
sys_tt = m_tt_non_system ;
// value is equal to last saved
2018-04-18 11:32:21 +00:00
if ( ( opt . second & osInitValue ) ! = 0 )
color = & m_default_text_clr ;
2018-04-24 12:11:23 +00:00
// value is modified
2018-03-22 08:37:42 +00:00
else
2018-04-18 11:32:21 +00:00
color = & m_modified_label_clr ;
2018-03-21 21:21:37 +00:00
}
2018-04-18 11:32:21 +00:00
if ( ( opt . second & osInitValue ) ! = 0 )
2018-03-23 16:27:43 +00:00
{
is_modified_value = false ;
2018-04-18 11:32:21 +00:00
icon = & m_bmp_white_bullet ;
2018-04-24 12:11:23 +00:00
tt = & m_tt_white_bullet ;
2018-03-23 16:27:43 +00:00
}
2018-12-04 16:56:49 +00:00
if ( opt . first = = " bed_shape " | | opt . first = = " compatible_prints " | | opt . first = = " compatible_printers " ) {
2018-04-13 16:22:06 +00:00
if ( m_colored_Label ! = nullptr ) {
2018-04-18 11:32:21 +00:00
m_colored_Label - > SetForegroundColour ( * color ) ;
2018-04-13 16:22:06 +00:00
m_colored_Label - > Refresh ( true ) ;
}
continue ;
}
2018-04-18 11:32:21 +00:00
Field * field = get_field ( opt . first ) ;
2018-03-23 16:27:43 +00:00
if ( field = = nullptr ) continue ;
field - > m_is_nonsys_value = is_nonsys_value ;
field - > m_is_modified_value = is_modified_value ;
2018-04-18 11:32:21 +00:00
field - > set_undo_bitmap ( icon ) ;
field - > set_undo_to_sys_bitmap ( sys_icon ) ;
2018-04-24 12:11:23 +00:00
field - > set_undo_tooltip ( tt ) ;
field - > set_undo_to_sys_tooltip ( sys_tt ) ;
2018-04-18 11:32:21 +00:00
field - > set_label_colour ( color ) ;
2018-03-16 11:56:03 +00:00
}
2019-03-18 11:48:39 +00:00
// Thaw();
2018-03-21 21:21:37 +00:00
wxTheApp - > CallAfter ( [ this ] ( ) {
update_changed_tree_ui ( ) ;
} ) ;
}
2018-04-18 11:32:21 +00:00
void Tab : : init_options_list ( )
{
if ( ! m_options_list . empty ( ) )
m_options_list . clear ( ) ;
for ( const auto opt_key : m_config - > keys ( ) )
m_options_list . emplace ( opt_key , m_opt_status_value ) ;
}
2018-03-21 21:21:37 +00:00
template < class T >
2018-08-08 15:47:59 +00:00
void add_correct_opts_to_options_list ( const std : : string & opt_key , std : : map < std : : string , int > & map , Tab * tab , const int & value )
2018-03-21 21:21:37 +00:00
{
T * opt_cur = static_cast < T * > ( tab - > m_config - > option ( opt_key ) ) ;
for ( int i = 0 ; i < opt_cur - > values . size ( ) ; i + + )
2018-04-18 11:32:21 +00:00
map . emplace ( opt_key + " # " + std : : to_string ( i ) , value ) ;
2018-03-21 21:21:37 +00:00
}
2018-04-18 11:32:21 +00:00
void TabPrinter : : init_options_list ( )
2018-03-21 21:21:37 +00:00
{
2018-04-18 11:32:21 +00:00
if ( ! m_options_list . empty ( ) )
m_options_list . clear ( ) ;
2018-03-21 21:21:37 +00:00
for ( const auto opt_key : m_config - > keys ( ) )
2018-03-16 11:56:03 +00:00
{
2018-10-31 11:56:08 +00:00
if ( opt_key = = " bed_shape " ) {
2018-04-18 11:32:21 +00:00
m_options_list . emplace ( opt_key , m_opt_status_value ) ;
2018-03-21 21:21:37 +00:00
continue ;
}
switch ( m_config - > option ( opt_key ) - > type ( ) )
{
2018-04-18 11:32:21 +00:00
case coInts : add_correct_opts_to_options_list < ConfigOptionInts > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coBools : add_correct_opts_to_options_list < ConfigOptionBools > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coFloats : add_correct_opts_to_options_list < ConfigOptionFloats > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coStrings : add_correct_opts_to_options_list < ConfigOptionStrings > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coPercents : add_correct_opts_to_options_list < ConfigOptionPercents > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coPoints : add_correct_opts_to_options_list < ConfigOptionPoints > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
default : m_options_list . emplace ( opt_key , m_opt_status_value ) ; break ;
2018-03-21 21:21:37 +00:00
}
}
2018-04-18 11:32:21 +00:00
m_options_list . emplace ( " extruders_count " , m_opt_status_value ) ;
2018-03-21 21:21:37 +00:00
}
2018-08-08 15:47:59 +00:00
void TabSLAMaterial : : init_options_list ( )
{
if ( ! m_options_list . empty ( ) )
m_options_list . clear ( ) ;
for ( const auto opt_key : m_config - > keys ( ) )
{
2018-12-04 16:56:49 +00:00
if ( opt_key = = " compatible_prints " | | opt_key = = " compatible_printers " ) {
2018-08-08 15:47:59 +00:00
m_options_list . emplace ( opt_key , m_opt_status_value ) ;
continue ;
}
switch ( m_config - > option ( opt_key ) - > type ( ) )
{
case coInts : add_correct_opts_to_options_list < ConfigOptionInts > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coBools : add_correct_opts_to_options_list < ConfigOptionBools > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coFloats : add_correct_opts_to_options_list < ConfigOptionFloats > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coStrings : add_correct_opts_to_options_list < ConfigOptionStrings > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coPercents : add_correct_opts_to_options_list < ConfigOptionPercents > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
case coPoints : add_correct_opts_to_options_list < ConfigOptionPoints > ( opt_key , m_options_list , this , m_opt_status_value ) ; break ;
default : m_options_list . emplace ( opt_key , m_opt_status_value ) ; break ;
}
}
}
2018-04-13 16:22:06 +00:00
void Tab : : get_sys_and_mod_flags ( const std : : string & opt_key , bool & sys_page , bool & modified_page )
{
2018-04-18 11:32:21 +00:00
auto opt = m_options_list . find ( opt_key ) ;
if ( sys_page ) sys_page = ( opt - > second & osSystemValue ) ! = 0 ;
2018-12-04 16:56:49 +00:00
modified_page | = ( opt - > second & osInitValue ) = = 0 ;
2018-04-13 16:22:06 +00:00
}
2018-03-21 21:21:37 +00:00
void Tab : : update_changed_tree_ui ( )
{
2019-02-04 11:57:39 +00:00
if ( m_options_list . empty ( ) )
return ;
2018-03-21 21:21:37 +00:00
auto cur_item = m_treectrl - > GetFirstVisibleItem ( ) ;
2018-10-22 13:18:05 +00:00
if ( ! cur_item | | ! m_treectrl - > IsVisible ( cur_item ) )
2018-10-15 15:18:38 +00:00
return ;
2019-03-22 19:49:17 +00:00
auto selected_item = m_treectrl - > GetSelection ( ) ;
auto selection = selected_item ? m_treectrl - > GetItemText ( selected_item ) : " " ;
2018-10-31 11:56:08 +00:00
while ( cur_item ) {
2018-03-21 21:21:37 +00:00
auto title = m_treectrl - > GetItemText ( cur_item ) ;
for ( auto page : m_pages )
2018-03-16 11:56:03 +00:00
{
2018-10-22 10:07:40 +00:00
if ( page - > title ( ) ! = title )
2018-03-21 21:21:37 +00:00
continue ;
bool sys_page = true ;
bool modified_page = false ;
2018-10-31 11:56:08 +00:00
if ( title = = _ ( " General " ) ) {
2018-03-23 16:27:43 +00:00
std : : initializer_list < const char * > optional_keys { " extruders_count " , " bed_shape " } ;
for ( auto & opt_key : optional_keys ) {
2018-04-13 16:22:06 +00:00
get_sys_and_mod_flags ( opt_key , sys_page , modified_page ) ;
2018-03-23 16:27:43 +00:00
}
2018-03-21 21:21:37 +00:00
}
2018-10-31 11:56:08 +00:00
if ( title = = _ ( " Dependencies " ) ) {
2018-12-04 16:56:49 +00:00
if ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) {
sys_page = m_presets - > get_selected_preset_parent ( ) ! = nullptr ;
2018-07-02 11:51:50 +00:00
modified_page = false ;
2018-12-04 16:56:49 +00:00
} else {
if ( m_type = = Slic3r : : Preset : : TYPE_FILAMENT | | m_type = = Slic3r : : Preset : : TYPE_SLA_MATERIAL )
get_sys_and_mod_flags ( " compatible_prints " , sys_page , modified_page ) ;
get_sys_and_mod_flags ( " compatible_printers " , sys_page , modified_page ) ;
2018-07-02 11:51:50 +00:00
}
2018-04-13 16:22:06 +00:00
}
2018-03-21 21:21:37 +00:00
for ( auto group : page - > m_optgroups )
{
2018-04-13 16:22:06 +00:00
if ( ! sys_page & & modified_page )
break ;
2018-03-21 21:21:37 +00:00
for ( t_opt_map : : iterator it = group - > m_opt_map . begin ( ) ; it ! = group - > m_opt_map . end ( ) ; + + it ) {
const std : : string & opt_key = it - > first ;
2018-04-13 16:22:06 +00:00
get_sys_and_mod_flags ( opt_key , sys_page , modified_page ) ;
2018-03-19 16:21:37 +00:00
}
2018-03-16 11:56:03 +00:00
}
2018-04-18 11:32:21 +00:00
const wxColor * clr = sys_page ? & m_sys_label_clr :
modified_page ? & m_modified_label_clr :
& m_default_text_clr ;
if ( page - > set_item_colour ( clr ) )
m_treectrl - > SetItemTextColour ( cur_item , * clr ) ;
2018-03-22 08:37:42 +00:00
page - > m_is_nonsys_values = ! sys_page ;
page - > m_is_modified_values = modified_page ;
2018-10-31 11:56:08 +00:00
if ( selection = = title ) {
2018-03-22 08:37:42 +00:00
m_is_nonsys_values = page - > m_is_nonsys_values ;
m_is_modified_values = page - > m_is_modified_values ;
}
2018-03-21 21:21:37 +00:00
break ;
2018-03-16 11:56:03 +00:00
}
2018-09-20 23:33:41 +00:00
auto next_item = m_treectrl - > GetNextVisible ( cur_item ) ;
2018-10-08 14:27:38 +00:00
cur_item = next_item ;
2018-03-16 11:56:03 +00:00
}
2018-03-22 08:37:42 +00:00
update_undo_buttons ( ) ;
}
void Tab : : update_undo_buttons ( )
{
2019-04-13 21:46:52 +00:00
m_undo_btn - > SetBitmap_ ( m_is_modified_values ? m_bmp_value_revert : m_bmp_white_bullet ) ;
m_undo_to_sys_btn - > SetBitmap_ ( m_is_nonsys_values ? * m_bmp_non_system : m_bmp_value_lock ) ;
2018-03-22 08:37:42 +00:00
2018-04-24 12:11:23 +00:00
m_undo_btn - > SetToolTip ( m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet ) ;
m_undo_to_sys_btn - > SetToolTip ( m_is_nonsys_values ? * m_ttg_non_system : m_ttg_value_lock ) ;
2018-01-05 14:11:33 +00:00
}
2018-04-18 11:32:21 +00:00
void Tab : : on_roll_back_value ( const bool to_sys /*= true*/ )
2018-03-22 09:56:57 +00:00
{
2018-04-18 11:32:21 +00:00
int os ;
if ( to_sys ) {
if ( ! m_is_nonsys_values ) return ;
os = osSystemValue ;
}
else {
if ( ! m_is_modified_values ) return ;
os = osInitValue ;
}
2018-03-22 09:56:57 +00:00
2018-04-16 11:43:01 +00:00
m_postpone_update_ui = true ;
2018-03-22 09:56:57 +00:00
auto selection = m_treectrl - > GetItemText ( m_treectrl - > GetSelection ( ) ) ;
for ( auto page : m_pages )
if ( page - > title ( ) = = selection ) {
2018-10-31 11:56:08 +00:00
for ( auto group : page - > m_optgroups ) {
if ( group - > title = = _ ( " Capabilities " ) ) {
2018-04-18 11:32:21 +00:00
if ( ( m_options_list [ " extruders_count " ] & os ) = = 0 )
to_sys ? group - > back_to_sys_value ( " extruders_count " ) : group - > back_to_initial_value ( " extruders_count " ) ;
2018-03-22 09:56:57 +00:00
}
2018-10-31 11:56:08 +00:00
if ( group - > title = = _ ( " Size and coordinates " ) ) {
if ( ( m_options_list [ " bed_shape " ] & os ) = = 0 ) {
2018-04-18 11:32:21 +00:00
to_sys ? group - > back_to_sys_value ( " bed_shape " ) : group - > back_to_initial_value ( " bed_shape " ) ;
2018-04-16 11:43:01 +00:00
load_key_value ( " bed_shape " , true /*some value*/ , true ) ;
}
2018-03-22 09:56:57 +00:00
}
2018-12-04 16:56:49 +00:00
if ( group - > title = = _ ( " Profile dependencies " ) ) {
if ( m_type ! = Slic3r : : Preset : : TYPE_PRINTER & & ( m_options_list [ " compatible_printers " ] & os ) = = 0 ) {
2018-04-18 11:32:21 +00:00
to_sys ? group - > back_to_sys_value ( " compatible_printers " ) : group - > back_to_initial_value ( " compatible_printers " ) ;
2018-04-16 11:43:01 +00:00
load_key_value ( " compatible_printers " , true /*some value*/ , true ) ;
2018-04-13 16:22:06 +00:00
2018-04-16 11:43:01 +00:00
bool is_empty = m_config - > option < ConfigOptionStrings > ( " compatible_printers " ) - > values . empty ( ) ;
2018-12-04 16:56:49 +00:00
m_compatible_printers . checkbox - > SetValue ( is_empty ) ;
is_empty ? m_compatible_printers . btn - > Disable ( ) : m_compatible_printers . btn - > Enable ( ) ;
}
if ( ( m_type = = Slic3r : : Preset : : TYPE_PRINT | | m_type = = Slic3r : : Preset : : TYPE_SLA_PRINT ) & & ( m_options_list [ " compatible_prints " ] & os ) = = 0 ) {
to_sys ? group - > back_to_sys_value ( " compatible_prints " ) : group - > back_to_initial_value ( " compatible_prints " ) ;
load_key_value ( " compatible_prints " , true /*some value*/ , true ) ;
bool is_empty = m_config - > option < ConfigOptionStrings > ( " compatible_prints " ) - > values . empty ( ) ;
m_compatible_prints . checkbox - > SetValue ( is_empty ) ;
is_empty ? m_compatible_prints . btn - > Disable ( ) : m_compatible_prints . btn - > Enable ( ) ;
2018-04-16 11:43:01 +00:00
}
2018-04-13 16:22:06 +00:00
}
2018-12-04 16:56:49 +00:00
for ( auto kvp : group - > m_opt_map ) {
const std : : string & opt_key = kvp . first ;
2018-04-18 11:32:21 +00:00
if ( ( m_options_list [ opt_key ] & os ) = = 0 )
to_sys ? group - > back_to_sys_value ( opt_key ) : group - > back_to_initial_value ( opt_key ) ;
2018-03-22 09:56:57 +00:00
}
}
break ;
}
2018-04-16 11:43:01 +00:00
m_postpone_update_ui = false ;
2018-03-23 16:27:43 +00:00
update_changed_ui ( ) ;
2018-03-22 09:56:57 +00:00
}
2018-03-09 07:34:32 +00:00
// Update the combo box label of the selected preset based on its "dirty" state,
// comparing the selected preset config with $self->{config}.
2018-10-31 11:56:08 +00:00
void Tab : : update_dirty ( )
{
2018-03-09 07:34:32 +00:00
m_presets - > update_dirty_ui ( m_presets_choice ) ;
on_presets_changed ( ) ;
update_changed_ui ( ) ;
}
2018-01-16 15:28:01 +00:00
void Tab : : update_tab_ui ( )
{
2019-04-23 14:33:06 +00:00
m_selected_preset_item = m_presets - > update_tab_ui ( m_presets_choice , m_show_incompatible_presets , m_em_unit ) ;
2018-01-16 15:28:01 +00:00
}
2018-01-05 14:11:33 +00:00
// Load a provied DynamicConfig into the tab, modifying the active preset.
// This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view.
2018-04-13 10:35:04 +00:00
void Tab : : load_config ( const DynamicPrintConfig & config )
2018-01-05 14:11:33 +00:00
{
bool modified = 0 ;
2018-01-12 11:41:13 +00:00
for ( auto opt_key : m_config - > diff ( config ) ) {
2018-03-12 15:52:21 +00:00
m_config - > set_key_value ( opt_key , config . option ( opt_key ) - > clone ( ) ) ;
2018-01-05 14:11:33 +00:00
modified = 1 ;
}
if ( modified ) {
2018-01-07 17:41:40 +00:00
update_dirty ( ) ;
2018-01-05 14:11:33 +00:00
//# Initialize UI components with the config values.
2018-01-09 08:41:07 +00:00
reload_config ( ) ;
2018-01-05 14:11:33 +00:00
update ( ) ;
}
}
2018-01-09 08:41:07 +00:00
// Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields.
2018-10-31 15:22:36 +00:00
void Tab : : reload_config ( )
{
2019-03-18 11:48:39 +00:00
// Freeze();
2018-01-09 08:41:07 +00:00
for ( auto page : m_pages )
page - > reload_config ( ) ;
2019-03-18 11:48:39 +00:00
// Thaw();
2018-01-09 08:41:07 +00:00
}
2019-03-20 15:22:01 +00:00
void Tab : : update_mode ( )
{
m_mode = wxGetApp ( ) . get_mode ( ) ;
// update mode for ModeSizer
m_mode_sizer - > SetMode ( m_mode ) ;
update_visibility ( ) ;
}
2018-12-21 08:19:00 +00:00
void Tab : : update_visibility ( )
2018-10-19 11:55:29 +00:00
{
2019-03-20 15:22:01 +00:00
Freeze ( ) ; // There is needed Freeze/Thaw to avoid a flashing after Show/Layout
2018-10-21 21:09:24 +00:00
2018-10-19 11:55:29 +00:00
for ( auto page : m_pages )
2019-03-20 15:22:01 +00:00
page - > update_visibility ( m_mode ) ;
2018-10-21 21:09:24 +00:00
update_page_tree_visibility ( ) ;
2019-01-11 11:47:40 +00:00
Layout ( ) ;
2019-03-21 09:46:40 +00:00
Thaw ( ) ;
2018-10-22 10:07:40 +00:00
2019-03-20 15:22:01 +00:00
update_changed_tree_ui ( ) ;
2018-10-19 11:55:29 +00:00
}
2019-04-24 23:45:00 +00:00
void Tab : : msw_rescale ( )
2019-04-10 07:56:32 +00:00
{
m_em_unit = wxGetApp ( ) . em_unit ( ) ;
2019-04-24 23:45:00 +00:00
m_mode_sizer - > msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
2019-04-16 08:05:45 +00:00
m_presets_choice - > SetSize ( 35 * m_em_unit , - 1 ) ;
2019-04-13 21:46:52 +00:00
m_treectrl - > SetMinSize ( wxSize ( 20 * m_em_unit , - 1 ) ) ;
2019-04-10 07:56:32 +00:00
update_tab_ui ( ) ;
2019-04-13 21:46:52 +00:00
// rescale buttons and cached bitmaps
for ( const auto btn : m_scaled_buttons )
2019-04-24 23:45:00 +00:00
btn - > msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
for ( const auto bmp : m_scaled_bitmaps )
2019-04-24 23:45:00 +00:00
bmp - > msw_rescale ( ) ;
for ( ScalableBitmap & bmp : m_mode_bitmap_cache )
bmp . msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
// rescale icons for tree_ctrl
2019-04-24 23:45:00 +00:00
for ( ScalableBitmap & bmp : m_scaled_icons_list )
bmp . msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
// recreate and set new ImageList for tree_ctrl
m_icons - > RemoveAll ( ) ;
m_icons = new wxImageList ( m_scaled_icons_list . front ( ) . bmp ( ) . GetWidth ( ) , m_scaled_icons_list . front ( ) . bmp ( ) . GetHeight ( ) ) ;
2019-04-24 23:45:00 +00:00
for ( ScalableBitmap & bmp : m_scaled_icons_list )
2019-04-13 21:46:52 +00:00
m_icons - > Add ( bmp . bmp ( ) ) ;
m_treectrl - > AssignImageList ( m_icons ) ;
// rescale options_groups
for ( auto page : m_pages )
2019-04-24 23:45:00 +00:00
page - > msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
Layout ( ) ;
2019-04-10 07:56:32 +00:00
}
2018-04-13 10:35:04 +00:00
Field * Tab : : get_field ( const t_config_option_key & opt_key , int opt_index /* = -1*/ ) const
2018-01-11 09:33:17 +00:00
{
Field * field = nullptr ;
2018-10-31 11:56:08 +00:00
for ( auto page : m_pages ) {
2018-01-12 16:16:59 +00:00
field = page - > get_field ( opt_key , opt_index ) ;
2018-01-11 09:33:17 +00:00
if ( field ! = nullptr )
return field ;
}
return field ;
}
2018-01-16 15:28:01 +00:00
// Set a key/value pair on this page. Return true if the value has been modified.
// Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer
// after a preset is loaded.
2018-10-31 11:56:08 +00:00
bool Tab : : set_value ( const t_config_option_key & opt_key , const boost : : any & value ) {
2018-01-16 15:28:01 +00:00
bool changed = false ;
for ( auto page : m_pages ) {
if ( page - > set_value ( opt_key , value ) )
changed = true ;
}
return changed ;
}
2018-01-12 11:41:13 +00:00
// To be called by custom widgets, load a value into a config,
// update the preset selection boxes (the dirty flags)
2018-04-16 11:43:01 +00:00
// If value is saved before calling this function, put saved_value = true,
// and value can be some random value because in this case it will not been used
void Tab : : load_key_value ( const std : : string & opt_key , const boost : : any & value , bool saved_value /*= false*/ )
2017-12-22 10:50:28 +00:00
{
2018-04-16 11:43:01 +00:00
if ( ! saved_value ) change_opt_value ( * m_config , opt_key , value ) ;
2018-01-12 11:41:13 +00:00
// Mark the print & filament enabled if they are compatible with the currently selected preset.
2018-12-04 16:56:49 +00:00
if ( opt_key = = " compatible_printers " | | opt_key = = " compatible_prints " ) {
2018-04-13 12:49:33 +00:00
// Don't select another profile if this profile happens to become incompatible.
2018-12-04 16:56:49 +00:00
m_preset_bundle - > update_compatible ( false ) ;
}
2018-01-12 11:41:13 +00:00
m_presets - > update_dirty_ui ( m_presets_choice ) ;
on_presets_changed ( ) ;
update ( ) ;
}
2018-04-13 10:35:04 +00:00
void Tab : : on_value_change ( const std : : string & opt_key , const boost : : any & value )
2018-01-21 22:35:00 +00:00
{
2019-03-11 12:59:58 +00:00
if ( wxGetApp ( ) . plater ( ) = = nullptr ) {
return ;
}
2019-03-11 15:00:13 +00:00
const bool is_fff = supports_printer_technology ( ptFFF ) ;
ConfigOptionsGroup * og_freq_chng_params = wxGetApp ( ) . sidebar ( ) . og_freq_chng_params ( is_fff ) ;
if ( opt_key = = " fill_density " | | opt_key = = " pad_enable " )
2018-03-12 15:52:21 +00:00
{
2018-10-05 21:29:15 +00:00
boost : : any val = og_freq_chng_params - > get_config_value ( * m_config , opt_key ) ;
og_freq_chng_params - > set_value ( opt_key , val ) ;
2018-03-12 15:52:21 +00:00
}
2019-03-11 15:00:13 +00:00
if ( is_fff & & ( opt_key = = " support_material " | | opt_key = = " support_material_buildplate_only " ) | |
! is_fff & & ( opt_key = = " supports_enable " | | opt_key = = " support_buildplate_only " ) )
2018-03-12 15:52:21 +00:00
{
2019-03-11 15:00:13 +00:00
const std : : string support = is_fff ? " support_material " : " supports_enable " ;
const std : : string buildplate_only = is_fff ? " support_material_buildplate_only " : " support_buildplate_only " ;
wxString new_selection = ! m_config - > opt_bool ( support ) ? _ ( " None " ) :
m_config - > opt_bool ( buildplate_only ) ? _ ( " Support on build plate only " ) :
_ ( " Everywhere " ) ;
2018-10-05 21:29:15 +00:00
og_freq_chng_params - > set_value ( " support " , new_selection ) ;
2018-03-12 15:52:21 +00:00
}
2019-03-11 15:00:13 +00:00
2018-03-12 15:52:21 +00:00
if ( opt_key = = " brim_width " )
{
bool val = m_config - > opt_float ( " brim_width " ) > 0.0 ? true : false ;
2018-10-05 21:29:15 +00:00
og_freq_chng_params - > set_value ( " brim " , val ) ;
2018-03-12 15:52:21 +00:00
}
2018-04-05 08:44:31 +00:00
if ( opt_key = = " wipe_tower " | | opt_key = = " single_extruder_multi_material " | | opt_key = = " extruders_count " )
update_wiping_button_visibility ( ) ;
2019-02-22 08:38:56 +00:00
if ( opt_key = = " extruders_count " )
wxGetApp ( ) . plater ( ) - > on_extruders_change ( boost : : any_cast < size_t > ( value ) ) ;
2018-01-21 22:35:00 +00:00
update ( ) ;
2018-01-25 12:46:04 +00:00
}
2018-01-21 22:35:00 +00:00
2018-04-05 08:44:31 +00:00
// Show/hide the 'purging volumes' button
void Tab : : update_wiping_button_visibility ( ) {
2018-10-04 14:43:10 +00:00
if ( m_preset_bundle - > printers . get_selected_preset ( ) . printer_technology ( ) = = ptSLA )
2018-08-06 15:01:41 +00:00
return ; // ys_FIXME
2018-04-05 08:44:31 +00:00
bool wipe_tower_enabled = dynamic_cast < ConfigOptionBool * > ( ( m_preset_bundle - > prints . get_edited_preset ( ) . config ) . option ( " wipe_tower " ) ) - > value ;
bool multiple_extruders = dynamic_cast < ConfigOptionFloats * > ( ( m_preset_bundle - > printers . get_edited_preset ( ) . config ) . option ( " nozzle_diameter " ) ) - > values . size ( ) > 1 ;
bool single_extruder_mm = dynamic_cast < ConfigOptionBool * > ( ( m_preset_bundle - > printers . get_edited_preset ( ) . config ) . option ( " single_extruder_multi_material " ) ) - > value ;
2018-10-24 10:57:23 +00:00
auto wiping_dialog_button = wxGetApp ( ) . sidebar ( ) . get_wiping_dialog_button ( ) ;
2018-10-03 13:14:52 +00:00
if ( wiping_dialog_button ) {
wiping_dialog_button - > Show ( wipe_tower_enabled & & multiple_extruders & & single_extruder_mm ) ;
wiping_dialog_button - > GetParent ( ) - > Layout ( ) ;
2018-09-20 23:33:41 +00:00
}
2018-04-05 08:44:31 +00:00
}
2018-01-16 15:28:01 +00:00
// Call a callback to update the selection of presets on the platter:
// To update the content of the selection boxes,
// to update the filament colors of the selection boxes,
// to update the "dirty" flags of the selection boxes,
2019-03-13 12:13:18 +00:00
// to update number of "filament" selection boxes when the number of extruders change.
2018-02-08 09:58:13 +00:00
void Tab : : on_presets_changed ( )
2018-01-21 22:35:00 +00:00
{
2019-03-13 16:38:41 +00:00
if ( wxGetApp ( ) . plater ( ) = = nullptr ) {
return ;
}
2019-03-13 12:13:18 +00:00
// Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets
wxGetApp ( ) . plater ( ) - > sidebar ( ) . update_presets ( m_type ) ;
update_preset_description_line ( ) ;
2018-12-04 16:56:49 +00:00
// Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
for ( auto t : m_dependent_tabs )
{
// If the printer tells us that the print or filament/sla_material preset has been switched or invalidated,
// refresh the print or filament/sla_material tab page.
wxGetApp ( ) . get_tab ( t ) - > load_current_preset ( ) ;
2018-11-16 10:14:56 +00:00
}
2019-02-22 10:59:40 +00:00
// clear m_dependent_tabs after first update from select_preset()
// to avoid needless preset loading from update() function
m_dependent_tabs . clear ( ) ;
2018-04-26 10:40:17 +00:00
}
2018-03-23 08:41:04 +00:00
2018-04-26 10:40:17 +00:00
void Tab : : update_preset_description_line ( )
{
2018-03-23 08:41:04 +00:00
const Preset * parent = m_presets - > get_selected_preset_parent ( ) ;
2018-04-26 10:40:17 +00:00
const Preset & preset = m_presets - > get_edited_preset ( ) ;
wxString description_line = preset . is_default ?
_ ( L ( " It's a default preset. " ) ) : preset . is_system ?
_ ( L ( " It's a system preset. " ) ) :
_ ( L ( " Current preset is inherited from " ) ) + ( parent = = nullptr ?
" default preset. " :
" : \n \t " + parent - > name ) ;
if ( preset . is_default | | preset . is_system )
description_line + = " \n \t " + _ ( L ( " It can't be deleted or modified. " ) ) +
" \n \t " + _ ( L ( " Any modifications should be saved as a new preset inherited from this one. " ) ) +
" \n \t " + _ ( L ( " To do that please specify a new name for the preset. " ) ) ;
if ( parent & & parent - > vendor )
{
description_line + = " \n \n " + _ ( L ( " Additional information: " ) ) + " \n " ;
2018-12-04 16:56:49 +00:00
description_line + = " \t " + _ ( L ( " vendor " ) ) + " : " + ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ? " \n \t \t " : " " ) + parent - > vendor - > name +
2018-04-26 10:40:17 +00:00
" , ver: " + parent - > vendor - > config_version . to_string ( ) ;
2018-12-04 16:56:49 +00:00
if ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) {
2018-10-31 17:05:25 +00:00
const std : : string & printer_model = preset . config . opt_string ( " printer_model " ) ;
if ( ! printer_model . empty ( ) )
2018-04-26 10:40:17 +00:00
description_line + = " \n \n \t " + _ ( L ( " printer model " ) ) + " : \n \t \t " + printer_model ;
2018-10-31 17:05:25 +00:00
switch ( preset . printer_technology ( ) ) {
case ptFFF :
2018-04-26 10:40:17 +00:00
{
2018-10-31 17:05:25 +00:00
//FIXME add prefered_sla_material_profile for SLA
const std : : string & default_print_profile = preset . config . opt_string ( " default_print_profile " ) ;
const std : : vector < std : : string > & default_filament_profiles = preset . config . option < ConfigOptionStrings > ( " default_filament_profile " ) - > values ;
if ( ! default_print_profile . empty ( ) )
description_line + = " \n \n \t " + _ ( L ( " default print profile " ) ) + " : \n \t \t " + default_print_profile ;
if ( ! default_filament_profiles . empty ( ) )
{
description_line + = " \n \n \t " + _ ( L ( " default filament profile " ) ) + " : \n \t \t " ;
for ( auto & profile : default_filament_profiles ) {
if ( & profile ! = & * default_filament_profiles . begin ( ) )
description_line + = " , " ;
description_line + = profile ;
}
2018-04-26 10:40:17 +00:00
}
2018-10-31 17:05:25 +00:00
break ;
}
case ptSLA :
{
//FIXME add prefered_sla_material_profile for SLA
const std : : string & default_sla_material_profile = preset . config . opt_string ( " default_sla_material_profile " ) ;
if ( ! default_sla_material_profile . empty ( ) )
description_line + = " \n \n \t " + _ ( L ( " default SLA material profile " ) ) + " : \n \t \t " + default_sla_material_profile ;
2018-11-16 16:36:23 +00:00
const std : : string & default_sla_print_profile = preset . config . opt_string ( " default_sla_print_profile " ) ;
if ( ! default_sla_print_profile . empty ( ) )
description_line + = " \n \n \t " + _ ( L ( " default SLA print profile " ) ) + " : \n \t \t " + default_sla_print_profile ;
2018-10-31 17:05:25 +00:00
break ;
}
2018-04-26 10:40:17 +00:00
}
}
}
m_parent_preset_description_line - > SetText ( description_line , false ) ;
2018-01-16 15:28:01 +00:00
}
2018-03-13 15:14:36 +00:00
void Tab : : update_frequently_changed_parameters ( )
{
2019-01-15 08:31:53 +00:00
auto og_freq_chng_params = wxGetApp ( ) . sidebar ( ) . og_freq_chng_params ( supports_printer_technology ( ptFFF ) ) ;
2018-10-05 21:29:15 +00:00
if ( ! og_freq_chng_params ) return ;
2019-01-15 08:31:53 +00:00
2019-03-27 15:59:34 +00:00
const bool is_fff = supports_printer_technology ( ptFFF ) ;
2019-01-15 08:31:53 +00:00
2019-03-27 15:59:34 +00:00
const std : : string support = is_fff ? " support_material " : " supports_enable " ;
const std : : string buildplate_only = is_fff ? " support_material_buildplate_only " : " support_buildplate_only " ;
2018-03-13 15:14:36 +00:00
2019-03-27 15:59:34 +00:00
wxString new_selection = ! m_config - > opt_bool ( support ) ? _ ( " None " ) :
m_config - > opt_bool ( buildplate_only ) ? _ ( " Support on build plate only " ) :
_ ( " Everywhere " ) ;
2018-10-05 21:29:15 +00:00
og_freq_chng_params - > set_value ( " support " , new_selection ) ;
2018-03-13 15:14:36 +00:00
2019-03-27 15:59:34 +00:00
const std : : string updated_value_key = is_fff ? " fill_density " : " pad_enable " ;
const boost : : any val = og_freq_chng_params - > get_config_value ( * m_config , updated_value_key ) ;
og_freq_chng_params - > set_value ( updated_value_key , val ) ;
2018-04-04 09:13:28 +00:00
2019-03-27 15:59:34 +00:00
if ( is_fff )
{
og_freq_chng_params - > set_value ( " brim " , bool ( m_config - > opt_float ( " brim_width " ) > 0.0 ) ) ;
update_wiping_button_visibility ( ) ;
}
2018-03-13 15:14:36 +00:00
}
2018-01-05 14:11:33 +00:00
void TabPrint : : build ( )
2017-12-13 13:45:10 +00:00
{
2018-01-05 14:11:33 +00:00
m_presets = & m_preset_bundle - > prints ;
2018-03-16 11:56:03 +00:00
load_initial_data ( ) ;
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " Layers and perimeters " ) ) , " layers " ) ;
2018-02-23 08:16:35 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Layer height " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " layer_height " ) ;
optgroup - > append_single_option_line ( " first_layer_height " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Vertical shells " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " perimeters " ) ;
optgroup - > append_single_option_line ( " spiral_vase " ) ;
2017-12-14 13:42:47 +00:00
2018-01-15 11:13:05 +00:00
Line line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_recommended_thin_wall_thickness_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Horizontal shells " ) ) ) ;
line = { _ ( L ( " Solid layers " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
line . append_option ( optgroup - > get_option ( " top_solid_layers " ) ) ;
line . append_option ( optgroup - > get_option ( " bottom_solid_layers " ) ) ;
2017-12-14 13:42:47 +00:00
optgroup - > append_line ( line ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Quality (slower slicing) " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " extra_perimeters " ) ;
optgroup - > append_single_option_line ( " ensure_vertical_shell_thickness " ) ;
optgroup - > append_single_option_line ( " avoid_crossing_perimeters " ) ;
optgroup - > append_single_option_line ( " thin_walls " ) ;
optgroup - > append_single_option_line ( " overhangs " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Advanced " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " seam_position " ) ;
optgroup - > append_single_option_line ( " external_perimeters_first " ) ;
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Infill " ) ) , " infill " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Infill " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " fill_density " ) ;
optgroup - > append_single_option_line ( " fill_pattern " ) ;
2019-02-22 14:25:35 +00:00
optgroup - > append_single_option_line ( " top_fill_pattern " ) ;
optgroup - > append_single_option_line ( " bottom_fill_pattern " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Reducing printing time " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " infill_every_layers " ) ;
optgroup - > append_single_option_line ( " infill_only_where_needed " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Advanced " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " solid_infill_every_layers " ) ;
optgroup - > append_single_option_line ( " fill_angle " ) ;
optgroup - > append_single_option_line ( " solid_infill_below_area " ) ;
optgroup - > append_single_option_line ( " bridge_angle " ) ;
optgroup - > append_single_option_line ( " only_retract_when_crossing_perimeters " ) ;
optgroup - > append_single_option_line ( " infill_first " ) ;
2017-12-14 13:42:47 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Skirt and brim " ) ) , " skirt+brim " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Skirt " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " skirts " ) ;
optgroup - > append_single_option_line ( " skirt_distance " ) ;
optgroup - > append_single_option_line ( " skirt_height " ) ;
optgroup - > append_single_option_line ( " min_skirt_length " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Brim " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " brim_width " ) ;
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Support material " ) ) , " support " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Support material " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " support_material " ) ;
2018-09-17 13:12:13 +00:00
optgroup - > append_single_option_line ( " support_material_auto " ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " support_material_threshold " ) ;
optgroup - > append_single_option_line ( " support_material_enforce_layers " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Raft " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " raft_layers " ) ;
// # optgroup->append_single_option_line(get_option_("raft_contact_distance");
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Options for support material and raft " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " support_material_contact_distance " ) ;
optgroup - > append_single_option_line ( " support_material_pattern " ) ;
optgroup - > append_single_option_line ( " support_material_with_sheath " ) ;
optgroup - > append_single_option_line ( " support_material_spacing " ) ;
optgroup - > append_single_option_line ( " support_material_angle " ) ;
optgroup - > append_single_option_line ( " support_material_interface_layers " ) ;
optgroup - > append_single_option_line ( " support_material_interface_spacing " ) ;
optgroup - > append_single_option_line ( " support_material_interface_contact_loops " ) ;
optgroup - > append_single_option_line ( " support_material_buildplate_only " ) ;
optgroup - > append_single_option_line ( " support_material_xy_spacing " ) ;
optgroup - > append_single_option_line ( " dont_support_bridges " ) ;
optgroup - > append_single_option_line ( " support_material_synchronize_layers " ) ;
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Speed " ) ) , " time " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Speed for print moves " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " perimeter_speed " ) ;
optgroup - > append_single_option_line ( " small_perimeter_speed " ) ;
optgroup - > append_single_option_line ( " external_perimeter_speed " ) ;
optgroup - > append_single_option_line ( " infill_speed " ) ;
optgroup - > append_single_option_line ( " solid_infill_speed " ) ;
optgroup - > append_single_option_line ( " top_solid_infill_speed " ) ;
optgroup - > append_single_option_line ( " support_material_speed " ) ;
optgroup - > append_single_option_line ( " support_material_interface_speed " ) ;
optgroup - > append_single_option_line ( " bridge_speed " ) ;
optgroup - > append_single_option_line ( " gap_fill_speed " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Speed for non-print moves " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " travel_speed " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Modifiers " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " first_layer_speed " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Acceleration control (advanced) " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " perimeter_acceleration " ) ;
optgroup - > append_single_option_line ( " infill_acceleration " ) ;
optgroup - > append_single_option_line ( " bridge_acceleration " ) ;
optgroup - > append_single_option_line ( " first_layer_acceleration " ) ;
optgroup - > append_single_option_line ( " default_acceleration " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Autospeed (advanced) " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " max_print_speed " ) ;
optgroup - > append_single_option_line ( " max_volumetric_speed " ) ;
2019-01-29 17:07:45 +00:00
# ifdef HAS_PRESSURE_EQUALIZER
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " max_volumetric_extrusion_rate_slope_positive " ) ;
optgroup - > append_single_option_line ( " max_volumetric_extrusion_rate_slope_negative " ) ;
2019-01-29 17:07:45 +00:00
# endif /* HAS_PRESSURE_EQUALIZER */
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Multiple Extruders " ) ) , " funnel " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Extruders " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " perimeter_extruder " ) ;
optgroup - > append_single_option_line ( " infill_extruder " ) ;
optgroup - > append_single_option_line ( " solid_infill_extruder " ) ;
optgroup - > append_single_option_line ( " support_material_extruder " ) ;
optgroup - > append_single_option_line ( " support_material_interface_extruder " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Ooze prevention " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " ooze_prevention " ) ;
optgroup - > append_single_option_line ( " standby_temperature_delta " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Wipe tower " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " wipe_tower " ) ;
optgroup - > append_single_option_line ( " wipe_tower_x " ) ;
optgroup - > append_single_option_line ( " wipe_tower_y " ) ;
optgroup - > append_single_option_line ( " wipe_tower_width " ) ;
2018-02-27 07:56:11 +00:00
optgroup - > append_single_option_line ( " wipe_tower_rotation_angle " ) ;
2018-03-12 14:41:25 +00:00
optgroup - > append_single_option_line ( " wipe_tower_bridging " ) ;
2018-07-27 20:19:46 +00:00
optgroup - > append_single_option_line ( " single_extruder_multi_material_priming " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Advanced " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " interface_shells " ) ;
2017-12-13 13:45:10 +00:00
2019-04-12 10:08:52 +00:00
page = add_options_page ( _ ( L ( " Advanced " ) ) , " wrench " ) ;
2018-03-22 13:12:29 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Extrusion width " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " extrusion_width " ) ;
optgroup - > append_single_option_line ( " first_layer_extrusion_width " ) ;
optgroup - > append_single_option_line ( " perimeter_extrusion_width " ) ;
optgroup - > append_single_option_line ( " external_perimeter_extrusion_width " ) ;
optgroup - > append_single_option_line ( " infill_extrusion_width " ) ;
optgroup - > append_single_option_line ( " solid_infill_extrusion_width " ) ;
optgroup - > append_single_option_line ( " top_infill_extrusion_width " ) ;
optgroup - > append_single_option_line ( " support_material_extrusion_width " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Overlap " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " infill_overlap " ) ;
2017-12-14 13:42:47 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Flow " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " bridge_flow_ratio " ) ;
2017-12-14 13:42:47 +00:00
2019-03-01 16:53:02 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Slicing " ) ) ) ;
optgroup - > append_single_option_line ( " slice_closing_radius " ) ;
optgroup - > append_single_option_line ( " resolution " ) ;
optgroup - > append_single_option_line ( " xy_size_compensation " ) ;
optgroup - > append_single_option_line ( " elefant_foot_compensation " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Other " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " clip_multipart_objects " ) ;
2017-12-13 13:45:10 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Output options " ) ) , " output+page_white " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Sequential printing " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " complete_objects " ) ;
2018-02-23 08:16:35 +00:00
line = { _ ( L ( " Extruder clearance (mm) " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
Option option = optgroup - > get_option ( " extruder_clearance_radius " ) ;
2019-04-13 21:46:52 +00:00
option . opt . width = 6 ;
2017-12-14 13:42:47 +00:00
line . append_option ( option ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " extruder_clearance_height " ) ;
2019-04-13 21:46:52 +00:00
option . opt . width = 6 ;
2017-12-14 13:42:47 +00:00
line . append_option ( option ) ;
optgroup - > append_line ( line ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Output file " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " gcode_comments " ) ;
2019-01-31 14:09:16 +00:00
optgroup - > append_single_option_line ( " gcode_label_objects " ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " output_filename_format " ) ;
2017-12-18 12:58:51 +00:00
option . opt . full_width = true ;
2017-12-14 13:42:47 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Post-processing scripts " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " post_process " ) ;
2017-12-18 12:58:51 +00:00
option . opt . full_width = true ;
2019-04-13 21:46:52 +00:00
option . opt . height = 5 ; //50;
2017-12-14 13:42:47 +00:00
optgroup - > append_single_option_line ( option ) ;
2017-12-13 13:45:10 +00:00
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Notes " ) ) , " note.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Notes " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " notes " ) ;
2017-12-18 12:58:51 +00:00
option . opt . full_width = true ;
2019-04-13 21:46:52 +00:00
option . opt . height = 25 ; //250;
2017-12-14 13:42:47 +00:00
optgroup - > append_single_option_line ( option ) ;
2017-12-13 13:45:10 +00:00
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
2018-12-04 16:56:49 +00:00
line = optgroup - > create_single_option_line ( " compatible_printers " ) ;
line . widget = [ this ] ( wxWindow * parent ) {
return compatible_widget_create ( parent , m_compatible_printers ) ;
2017-12-26 22:04:54 +00:00
} ;
2018-04-13 16:22:06 +00:00
optgroup - > append_line ( line , & m_colored_Label ) ;
2018-01-11 09:33:17 +00:00
option = optgroup - > get_option ( " compatible_printers_condition " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2018-03-22 10:46:15 +00:00
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
2017-12-13 13:45:10 +00:00
}
2018-01-12 11:41:13 +00:00
// Reload current config (aka presets->edited_preset->config) into the UI fields.
2018-10-31 11:56:08 +00:00
void TabPrint : : reload_config ( )
{
2018-12-04 16:56:49 +00:00
this - > compatible_widget_reload ( m_compatible_printers ) ;
2018-01-12 11:41:13 +00:00
Tab : : reload_config ( ) ;
}
2018-01-05 14:11:33 +00:00
void TabPrint : : update ( )
{
2018-10-04 14:43:10 +00:00
if ( m_preset_bundle - > printers . get_selected_preset ( ) . printer_technology ( ) = = ptSLA )
2018-08-06 15:01:41 +00:00
return ; // ys_FIXME
2019-02-22 08:38:56 +00:00
// #ys_FIXME_to_delete
2019-01-14 14:38:54 +00:00
//! Temporary workaround for the correct updates of the SpinCtrl (like "perimeters"):
// KillFocus() for the wxSpinCtrl use CallAfter function. So,
// to except the duplicate call of the update() after dialog->ShowModal(),
// let check if this process is already started.
2019-02-20 15:09:18 +00:00
// if (is_msg_dlg_already_exist) // ! It looks like a fixed problem after start to using of a m_dirty_options
// return; // ! TODO Let delete this part of code after a common aplication testing
2019-01-14 14:38:54 +00:00
2019-02-22 08:38:56 +00:00
m_update_cnt + + ;
2019-03-18 11:48:39 +00:00
// Freeze();
2018-01-05 14:11:33 +00:00
2018-03-16 16:25:11 +00:00
double fill_density = m_config - > option < ConfigOptionPercent > ( " fill_density " ) - > value ;
2018-02-23 08:16:35 +00:00
if ( m_config - > opt_bool ( " spiral_vase " ) & &
2018-01-26 00:44:34 +00:00
! ( m_config - > opt_int ( " perimeters " ) = = 1 & & m_config - > opt_int ( " top_solid_layers " ) = = 0 & &
2018-03-16 16:25:11 +00:00
fill_density = = 0 ) ) {
2018-02-23 08:16:35 +00:00
wxString msg_text = _ ( L ( " The Spiral Vase mode requires: \n "
2018-01-05 14:11:33 +00:00
" - one perimeter \n "
2018-02-23 08:16:35 +00:00
" - no top solid layers \n "
" - 0% fill density \n "
" - no support material \n "
" - no ensure_vertical_shell_thickness \n "
" \n Shall I adjust those settings in order to enable Spiral Vase? " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Spiral Vase " ) ) , wxICON_WARNING | wxYES | wxNO ) ;
2019-02-20 15:09:18 +00:00
// is_msg_dlg_already_exist = true;
2018-01-26 00:44:34 +00:00
DynamicPrintConfig new_conf = * m_config ;
2018-02-23 08:16:35 +00:00
if ( dialog - > ShowModal ( ) = = wxID_YES ) {
2018-01-05 14:11:33 +00:00
new_conf . set_key_value ( " perimeters " , new ConfigOptionInt ( 1 ) ) ;
new_conf . set_key_value ( " top_solid_layers " , new ConfigOptionInt ( 0 ) ) ;
new_conf . set_key_value ( " fill_density " , new ConfigOptionPercent ( 0 ) ) ;
new_conf . set_key_value ( " support_material " , new ConfigOptionBool ( false ) ) ;
2018-02-22 10:34:41 +00:00
new_conf . set_key_value ( " support_material_enforce_layers " , new ConfigOptionInt ( 0 ) ) ;
2018-01-05 14:11:33 +00:00
new_conf . set_key_value ( " ensure_vertical_shell_thickness " , new ConfigOptionBool ( false ) ) ;
2018-03-16 16:25:11 +00:00
fill_density = 0 ;
2018-01-05 14:11:33 +00:00
}
else {
new_conf . set_key_value ( " spiral_vase " , new ConfigOptionBool ( false ) ) ;
}
2018-02-23 08:16:35 +00:00
load_config ( new_conf ) ;
2018-03-16 16:25:11 +00:00
on_value_change ( " fill_density " , fill_density ) ;
2019-02-20 15:09:18 +00:00
// is_msg_dlg_already_exist = false;
2018-01-05 14:11:33 +00:00
}
2018-02-23 08:16:35 +00:00
if ( m_config - > opt_bool ( " wipe_tower " ) & & m_config - > opt_bool ( " support_material " ) & &
2018-01-12 11:41:13 +00:00
m_config - > opt_float ( " support_material_contact_distance " ) > 0. & &
( m_config - > opt_int ( " support_material_extruder " ) ! = 0 | | m_config - > opt_int ( " support_material_interface_extruder " ) ! = 0 ) ) {
2018-02-23 08:16:35 +00:00
wxString msg_text = _ ( L ( " The Wipe Tower currently supports the non-soluble supports only \n "
2018-01-11 09:33:17 +00:00
" if they are printed with the current extruder without triggering a tool change. \n "
" (both support_material_extruder and support_material_interface_extruder need to be set to 0). \n "
2018-02-23 08:16:35 +00:00
" \n Shall I adjust those settings in order to enable the Wipe Tower? " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Wipe Tower " ) ) , wxICON_WARNING | wxYES | wxNO ) ;
2018-01-12 11:41:13 +00:00
DynamicPrintConfig new_conf = * m_config ;
2018-01-11 09:33:17 +00:00
if ( dialog - > ShowModal ( ) = = wxID_YES ) {
new_conf . set_key_value ( " support_material_extruder " , new ConfigOptionInt ( 0 ) ) ;
new_conf . set_key_value ( " support_material_interface_extruder " , new ConfigOptionInt ( 0 ) ) ;
}
2018-02-23 08:16:35 +00:00
else
2018-01-11 09:33:17 +00:00
new_conf . set_key_value ( " wipe_tower " , new ConfigOptionBool ( false ) ) ;
load_config ( new_conf ) ;
}
2018-02-23 08:16:35 +00:00
if ( m_config - > opt_bool ( " wipe_tower " ) & & m_config - > opt_bool ( " support_material " ) & &
2018-01-12 11:41:13 +00:00
m_config - > opt_float ( " support_material_contact_distance " ) = = 0 & &
! m_config - > opt_bool ( " support_material_synchronize_layers " ) ) {
2018-02-23 08:16:35 +00:00
wxString msg_text = _ ( L ( " For the Wipe Tower to work with the soluble supports, the support layers \n "
2018-01-11 09:33:17 +00:00
" need to be synchronized with the object layers. \n "
2018-02-23 08:16:35 +00:00
" \n Shall I synchronize support layers in order to enable the Wipe Tower? " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Wipe Tower " ) ) , wxICON_WARNING | wxYES | wxNO ) ;
2018-01-12 11:41:13 +00:00
DynamicPrintConfig new_conf = * m_config ;
2018-01-11 09:33:17 +00:00
if ( dialog - > ShowModal ( ) = = wxID_YES ) {
new_conf . set_key_value ( " support_material_synchronize_layers " , new ConfigOptionBool ( true ) ) ;
}
else
new_conf . set_key_value ( " wipe_tower " , new ConfigOptionBool ( false ) ) ;
load_config ( new_conf ) ;
}
2018-01-12 11:41:13 +00:00
if ( m_config - > opt_bool ( " support_material " ) ) {
2018-01-11 09:33:17 +00:00
// Ask only once.
if ( ! m_support_material_overhangs_queried ) {
m_support_material_overhangs_queried = true ;
2018-01-12 11:41:13 +00:00
if ( ! m_config - > opt_bool ( " overhangs " ) /* != 1*/ ) {
2018-02-23 08:16:35 +00:00
wxString msg_text = _ ( L ( " Supports work better, if the following feature is enabled: \n "
2018-01-11 09:33:17 +00:00
" - Detect bridging perimeters \n "
2018-02-23 08:16:35 +00:00
" \n Shall I adjust those settings for supports? " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Support Generator " ) ) , wxICON_WARNING | wxYES | wxNO | wxCANCEL ) ;
2018-01-12 11:41:13 +00:00
DynamicPrintConfig new_conf = * m_config ;
2018-01-11 09:33:17 +00:00
auto answer = dialog - > ShowModal ( ) ;
if ( answer = = wxID_YES ) {
// Enable "detect bridging perimeters".
new_conf . set_key_value ( " overhangs " , new ConfigOptionBool ( true ) ) ;
2018-02-23 08:16:35 +00:00
} else if ( answer = = wxID_NO ) {
2018-01-11 09:33:17 +00:00
// Do nothing, leave supports on and "detect bridging perimeters" off.
2018-02-23 08:16:35 +00:00
} else if ( answer = = wxID_CANCEL ) {
2018-01-11 09:33:17 +00:00
// Disable supports.
new_conf . set_key_value ( " support_material " , new ConfigOptionBool ( false ) ) ;
m_support_material_overhangs_queried = false ;
}
load_config ( new_conf ) ;
}
}
}
else {
m_support_material_overhangs_queried = false ;
}
2018-01-12 11:41:13 +00:00
if ( m_config - > option < ConfigOptionPercent > ( " fill_density " ) - > value = = 100 ) {
auto fill_pattern = m_config - > option < ConfigOptionEnum < InfillPattern > > ( " fill_pattern " ) - > value ;
2018-01-11 09:33:17 +00:00
std : : string str_fill_pattern = " " ;
2018-01-12 11:41:13 +00:00
t_config_enum_values map_names = m_config - > option < ConfigOptionEnum < InfillPattern > > ( " fill_pattern " ) - > get_enum_values ( ) ;
2018-02-23 08:16:35 +00:00
for ( auto it : map_names ) {
2018-01-11 09:33:17 +00:00
if ( fill_pattern = = it . second ) {
str_fill_pattern = it . first ;
break ;
}
}
2018-10-31 11:56:08 +00:00
if ( ! str_fill_pattern . empty ( ) ) {
2019-02-22 14:25:35 +00:00
const std : : vector < std : : string > & external_fill_pattern = m_config - > def ( ) - > get ( " top_fill_pattern " ) - > enum_values ;
2018-01-11 09:33:17 +00:00
bool correct_100p_fill = false ;
2018-12-04 16:56:49 +00:00
for ( const std : : string & fill : external_fill_pattern )
2018-01-11 09:33:17 +00:00
{
2018-12-04 16:56:49 +00:00
if ( str_fill_pattern = = fill )
2018-01-11 09:33:17 +00:00
correct_100p_fill = true ;
}
// get fill_pattern name from enum_labels for using this one at dialog_msg
2018-01-12 11:41:13 +00:00
str_fill_pattern = m_config - > def ( ) - > get ( " fill_pattern " ) - > enum_labels [ fill_pattern ] ;
2018-10-31 11:56:08 +00:00
if ( ! correct_100p_fill ) {
2018-02-23 08:16:35 +00:00
wxString msg_text = _ ( L ( " The " ) ) + str_fill_pattern + _ ( L ( " infill pattern is not supposed to work at 100% density. \n "
" \n Shall I switch to rectilinear fill pattern? " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Infill " ) ) , wxICON_WARNING | wxYES | wxNO ) ;
2018-01-12 11:41:13 +00:00
DynamicPrintConfig new_conf = * m_config ;
2018-01-11 09:33:17 +00:00
if ( dialog - > ShowModal ( ) = = wxID_YES ) {
new_conf . set_key_value ( " fill_pattern " , new ConfigOptionEnum < InfillPattern > ( ipRectilinear ) ) ;
2018-03-14 10:45:31 +00:00
fill_density = 100 ;
2018-01-11 09:33:17 +00:00
}
else
2018-03-14 14:10:16 +00:00
fill_density = m_presets - > get_selected_preset ( ) . config . option < ConfigOptionPercent > ( " fill_density " ) - > value ;
2018-03-14 10:45:31 +00:00
new_conf . set_key_value ( " fill_density " , new ConfigOptionPercent ( fill_density ) ) ;
2018-01-11 09:33:17 +00:00
load_config ( new_conf ) ;
2018-03-14 10:45:31 +00:00
on_value_change ( " fill_density " , fill_density ) ;
2018-01-11 09:33:17 +00:00
}
}
}
2018-01-12 11:41:13 +00:00
bool have_perimeters = m_config - > opt_int ( " perimeters " ) > 0 ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " extra_perimeters " , " ensure_vertical_shell_thickness " , " thin_walls " , " overhangs " ,
" seam_position " , " external_perimeters_first " , " external_perimeter_extrusion_width " ,
" perimeter_speed " , " small_perimeter_speed " , " external_perimeter_speed " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_perimeters ) ;
2018-01-12 11:41:13 +00:00
bool have_infill = m_config - > option < ConfigOptionPercent > ( " fill_density " ) - > value > 0 ;
2018-01-11 09:33:17 +00:00
// infill_extruder uses the same logic as in Print::extruders()
2018-04-04 08:18:26 +00:00
for ( auto el : { " fill_pattern " , " infill_every_layers " , " infill_only_where_needed " ,
" solid_infill_every_layers " , " solid_infill_below_area " , " infill_extruder " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_infill ) ;
2018-01-12 11:41:13 +00:00
bool have_solid_infill = m_config - > opt_int ( " top_solid_layers " ) > 0 | | m_config - > opt_int ( " bottom_solid_layers " ) > 0 ;
2018-01-11 09:33:17 +00:00
// solid_infill_extruder uses the same logic as in Print::extruders()
2019-02-22 14:25:35 +00:00
for ( auto el : { " top_fill_pattern " , " bottom_fill_pattern " , " infill_first " , " solid_infill_extruder " ,
2018-04-04 08:18:26 +00:00
" solid_infill_extrusion_width " , " solid_infill_speed " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_solid_infill ) ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " fill_angle " , " bridge_angle " , " infill_extrusion_width " ,
" infill_speed " , " bridge_speed " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_infill | | have_solid_infill ) ;
get_field ( " gap_fill_speed " ) - > toggle ( have_perimeters & & have_infill ) ;
2018-01-12 11:41:13 +00:00
bool have_top_solid_infill = m_config - > opt_int ( " top_solid_layers " ) > 0 ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " top_infill_extrusion_width " , " top_solid_infill_speed " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_top_solid_infill ) ;
2018-01-12 11:41:13 +00:00
bool have_default_acceleration = m_config - > opt_float ( " default_acceleration " ) > 0 ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " perimeter_acceleration " , " infill_acceleration " ,
" bridge_acceleration " , " first_layer_acceleration " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_default_acceleration ) ;
2018-01-12 11:41:13 +00:00
bool have_skirt = m_config - > opt_int ( " skirts " ) > 0 | | m_config - > opt_float ( " min_skirt_length " ) > 0 ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " skirt_distance " , " skirt_height " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_skirt ) ;
2018-01-12 11:41:13 +00:00
bool have_brim = m_config - > opt_float ( " brim_width " ) > 0 ;
2018-01-11 09:33:17 +00:00
// perimeter_extruder uses the same logic as in Print::extruders()
get_field ( " perimeter_extruder " ) - > toggle ( have_perimeters | | have_brim ) ;
2018-01-12 11:41:13 +00:00
bool have_raft = m_config - > opt_int ( " raft_layers " ) > 0 ;
bool have_support_material = m_config - > opt_bool ( " support_material " ) | | have_raft ;
2018-09-17 13:12:13 +00:00
bool have_support_material_auto = have_support_material & & m_config - > opt_bool ( " support_material_auto " ) ;
2018-01-12 11:41:13 +00:00
bool have_support_interface = m_config - > opt_int ( " support_material_interface_layers " ) > 0 ;
bool have_support_soluble = have_support_material & & m_config - > opt_float ( " support_material_contact_distance " ) = = 0 ;
2018-09-17 13:12:13 +00:00
for ( auto el : { " support_material_pattern " , " support_material_with_sheath " ,
2018-02-23 08:16:35 +00:00
" support_material_spacing " , " support_material_angle " , " support_material_interface_layers " ,
" dont_support_bridges " , " support_material_extrusion_width " , " support_material_contact_distance " ,
2018-04-04 08:18:26 +00:00
" support_material_xy_spacing " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_support_material ) ;
2018-09-17 13:12:13 +00:00
get_field ( " support_material_threshold " ) - > toggle ( have_support_material_auto ) ;
2018-01-11 09:33:17 +00:00
2018-04-04 08:18:26 +00:00
for ( auto el : { " support_material_interface_spacing " , " support_material_interface_extruder " ,
" support_material_interface_speed " , " support_material_interface_contact_loops " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_support_material & & have_support_interface ) ;
get_field ( " support_material_synchronize_layers " ) - > toggle ( have_support_soluble ) ;
get_field ( " perimeter_extrusion_width " ) - > toggle ( have_perimeters | | have_skirt | | have_brim ) ;
get_field ( " support_material_extruder " ) - > toggle ( have_support_material | | have_skirt ) ;
get_field ( " support_material_speed " ) - > toggle ( have_support_material | | have_brim | | have_skirt ) ;
2018-01-12 11:41:13 +00:00
bool have_sequential_printing = m_config - > opt_bool ( " complete_objects " ) ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " extruder_clearance_radius " , " extruder_clearance_height " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_sequential_printing ) ;
2018-01-12 11:41:13 +00:00
bool have_ooze_prevention = m_config - > opt_bool ( " ooze_prevention " ) ;
2018-01-11 09:33:17 +00:00
get_field ( " standby_temperature_delta " ) - > toggle ( have_ooze_prevention ) ;
2018-01-12 11:41:13 +00:00
bool have_wipe_tower = m_config - > opt_bool ( " wipe_tower " ) ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " wipe_tower_x " , " wipe_tower_y " , " wipe_tower_width " , " wipe_tower_rotation_angle " , " wipe_tower_bridging " } )
2018-01-11 09:33:17 +00:00
get_field ( el ) - > toggle ( have_wipe_tower ) ;
2018-01-05 14:11:33 +00:00
2018-01-15 11:13:05 +00:00
m_recommended_thin_wall_thickness_description_line - > SetText (
2018-02-26 12:57:36 +00:00
from_u8 ( PresetHints : : recommended_thin_wall_thickness ( * m_preset_bundle ) ) ) ;
2018-01-15 11:13:05 +00:00
2019-03-18 11:48:39 +00:00
// Thaw();
2019-02-22 08:38:56 +00:00
m_update_cnt - - ;
if ( m_update_cnt = = 0 )
wxGetApp ( ) . mainframe - > on_config_changed ( m_config ) ;
2018-01-05 14:11:33 +00:00
}
2018-01-15 11:13:05 +00:00
void TabPrint : : OnActivate ( )
{
2018-02-26 12:57:36 +00:00
m_recommended_thin_wall_thickness_description_line - > SetText (
from_u8 ( PresetHints : : recommended_thin_wall_thickness ( * m_preset_bundle ) ) ) ;
2018-06-28 16:30:22 +00:00
Tab : : OnActivate ( ) ;
2018-01-15 11:13:05 +00:00
}
2018-01-05 14:11:33 +00:00
void TabFilament : : build ( )
2017-12-22 10:50:28 +00:00
{
2018-01-12 11:41:13 +00:00
m_presets = & m_preset_bundle - > filaments ;
2018-03-16 11:56:03 +00:00
load_initial_data ( ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
auto page = add_options_page ( _ ( L ( " Filament " ) ) , " spool.png " ) ;
auto optgroup = page - > new_optgroup ( _ ( L ( " Filament " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " filament_colour " ) ;
optgroup - > append_single_option_line ( " filament_diameter " ) ;
optgroup - > append_single_option_line ( " extrusion_multiplier " ) ;
optgroup - > append_single_option_line ( " filament_density " ) ;
optgroup - > append_single_option_line ( " filament_cost " ) ;
2017-12-22 10:50:28 +00:00
2018-06-07 20:54:26 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Temperature " ) ) + wxString ( " °C " , wxConvUTF8 ) ) ;
2018-02-23 08:16:35 +00:00
Line line = { _ ( L ( " Extruder " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
line . append_option ( optgroup - > get_option ( " first_layer_temperature " ) ) ;
line . append_option ( optgroup - > get_option ( " temperature " ) ) ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2018-02-23 08:16:35 +00:00
line = { _ ( L ( " Bed " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
line . append_option ( optgroup - > get_option ( " first_layer_bed_temperature " ) ) ;
line . append_option ( optgroup - > get_option ( " bed_temperature " ) ) ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2019-04-04 07:20:11 +00:00
page = add_options_page ( _ ( L ( " Cooling " ) ) , " cooling " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Enable " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " fan_always_on " ) ;
optgroup - > append_single_option_line ( " cooling " ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
line = { " " , " " } ;
2017-12-22 10:50:28 +00:00
line . full_width = 1 ;
2017-12-26 22:04:54 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-01-15 11:13:05 +00:00
return description_line_widget ( parent , & m_cooling_description_line ) ;
2017-12-26 22:04:54 +00:00
} ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Fan settings " ) ) ) ;
line = { _ ( L ( " Fan speed " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
line . append_option ( optgroup - > get_option ( " min_fan_speed " ) ) ;
line . append_option ( optgroup - > get_option ( " max_fan_speed " ) ) ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " bridge_fan_speed " ) ;
optgroup - > append_single_option_line ( " disable_fan_first_layers " ) ;
2017-12-22 10:50:28 +00:00
2019-04-13 21:46:52 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Cooling thresholds " ) ) , 25 ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " fan_below_layer_time " ) ;
optgroup - > append_single_option_line ( " slowdown_below_layer_time " ) ;
optgroup - > append_single_option_line ( " min_print_speed " ) ;
2017-12-22 10:50:28 +00:00
2019-04-12 10:08:52 +00:00
page = add_options_page ( _ ( L ( " Advanced " ) ) , " wrench " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Filament properties " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " filament_type " ) ;
optgroup - > append_single_option_line ( " filament_soluble " ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Print speed override " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " filament_max_volumetric_speed " ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
line = { " " , " " } ;
2017-12-22 10:50:28 +00:00
line . full_width = 1 ;
2017-12-26 22:04:54 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-01-15 11:13:05 +00:00
return description_line_widget ( parent , & m_volumetric_speed_description_line ) ;
2017-12-26 22:04:54 +00:00
} ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2018-05-02 08:52:17 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Toolchange parameters with single extruder MM printers " ) ) ) ;
2018-08-21 12:36:24 +00:00
optgroup - > append_single_option_line ( " filament_loading_speed_start " ) ;
optgroup - > append_single_option_line ( " filament_loading_speed " ) ;
2018-08-14 14:23:23 +00:00
optgroup - > append_single_option_line ( " filament_unloading_speed_start " ) ;
2018-03-02 14:52:16 +00:00
optgroup - > append_single_option_line ( " filament_unloading_speed " ) ;
2018-07-31 07:44:29 +00:00
optgroup - > append_single_option_line ( " filament_load_time " ) ;
optgroup - > append_single_option_line ( " filament_unload_time " ) ;
2018-03-02 14:52:16 +00:00
optgroup - > append_single_option_line ( " filament_toolchange_delay " ) ;
2018-04-24 11:02:08 +00:00
optgroup - > append_single_option_line ( " filament_cooling_moves " ) ;
optgroup - > append_single_option_line ( " filament_cooling_initial_speed " ) ;
optgroup - > append_single_option_line ( " filament_cooling_final_speed " ) ;
2018-08-02 13:14:12 +00:00
optgroup - > append_single_option_line ( " filament_minimal_purge_on_wipe_tower " ) ;
2018-04-24 11:10:33 +00:00
2018-10-19 11:55:29 +00:00
line = optgroup - > create_single_option_line ( " filament_ramming_parameters " ) ; // { _(L("Ramming")), "" };
2018-10-31 11:56:08 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-06-07 20:10:23 +00:00
auto ramming_dialog_btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Ramming settings " ) ) + dots , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT ) ;
2019-03-18 19:54:01 +00:00
ramming_dialog_btn - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2018-03-13 14:54:29 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( ramming_dialog_btn ) ;
ramming_dialog_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent & e )
2018-03-12 14:41:25 +00:00
{
2018-03-15 13:04:12 +00:00
RammingDialog dlg ( this , ( m_config - > option < ConfigOptionStrings > ( " filament_ramming_parameters " ) ) - > get_at ( 0 ) ) ;
2018-03-28 13:37:10 +00:00
if ( dlg . ShowModal ( ) = = wxID_OK )
( m_config - > option < ConfigOptionStrings > ( " filament_ramming_parameters " ) ) - > get_at ( 0 ) = dlg . get_parameters ( ) ;
2018-03-13 14:54:29 +00:00
} ) ) ;
2018-03-12 14:41:25 +00:00
return sizer ;
} ;
optgroup - > append_line ( line ) ;
2019-04-13 21:46:52 +00:00
const int gcode_field_height = 15 ; // 150
const int notes_field_height = 25 ; // 250
2018-03-02 14:52:16 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Custom G-code " ) ) , " cog " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Start G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
Option option = optgroup - > get_option ( " start_filament_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; // 150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " End G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " end_filament_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; // 150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Notes " ) ) , " note.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Notes " ) ) , 0 ) ;
2017-12-22 10:50:28 +00:00
optgroup - > label_width = 0 ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " filament_notes " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = notes_field_height ; // 250;
2017-12-26 22:04:54 +00:00
optgroup - > append_single_option_line ( option ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
2018-12-04 16:56:49 +00:00
line = optgroup - > create_single_option_line ( " compatible_printers " ) ;
line . widget = [ this ] ( wxWindow * parent ) {
return compatible_widget_create ( parent , m_compatible_printers ) ;
2017-12-26 22:04:54 +00:00
} ;
2018-04-13 16:22:06 +00:00
optgroup - > append_line ( line , & m_colored_Label ) ;
2018-01-12 11:41:13 +00:00
option = optgroup - > get_option ( " compatible_printers_condition " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2018-03-22 10:46:15 +00:00
2018-12-04 16:56:49 +00:00
line = optgroup - > create_single_option_line ( " compatible_prints " ) ;
line . widget = [ this ] ( wxWindow * parent ) {
return compatible_widget_create ( parent , m_compatible_prints ) ;
} ;
optgroup - > append_line ( line , & m_colored_Label ) ;
option = optgroup - > get_option ( " compatible_prints_condition " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2018-03-22 10:46:15 +00:00
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
2018-01-12 11:41:13 +00:00
}
// Reload current config (aka presets->edited_preset->config) into the UI fields.
2018-10-31 11:56:08 +00:00
void TabFilament : : reload_config ( )
{
2018-12-04 16:56:49 +00:00
this - > compatible_widget_reload ( m_compatible_printers ) ;
this - > compatible_widget_reload ( m_compatible_prints ) ;
2018-01-12 11:41:13 +00:00
Tab : : reload_config ( ) ;
}
void TabFilament : : update ( )
{
2018-10-04 14:43:10 +00:00
if ( m_preset_bundle - > printers . get_selected_preset ( ) . printer_technology ( ) = = ptSLA )
2018-08-06 15:01:41 +00:00
return ; // ys_FIXME
2019-02-22 08:38:56 +00:00
m_update_cnt + + ;
2019-03-18 11:48:39 +00:00
// Freeze();
2018-02-22 10:34:41 +00:00
wxString text = from_u8 ( PresetHints : : cooling_description ( m_presets - > get_edited_preset ( ) ) ) ;
2018-01-15 11:13:05 +00:00
m_cooling_description_line - > SetText ( text ) ;
2018-02-22 10:34:41 +00:00
text = from_u8 ( PresetHints : : maximum_volumetric_flow_description ( * m_preset_bundle ) ) ;
2018-01-15 11:13:05 +00:00
m_volumetric_speed_description_line - > SetText ( text ) ;
2018-01-12 11:41:13 +00:00
bool cooling = m_config - > opt_bool ( " cooling " , 0 ) ;
bool fan_always_on = cooling | | m_config - > opt_bool ( " fan_always_on " , 0 ) ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " max_fan_speed " , " fan_below_layer_time " , " slowdown_below_layer_time " , " min_print_speed " } )
2018-01-12 11:41:13 +00:00
get_field ( el ) - > toggle ( cooling ) ;
2018-04-04 08:18:26 +00:00
for ( auto el : { " min_fan_speed " , " disable_fan_first_layers " } )
2018-01-12 11:41:13 +00:00
get_field ( el ) - > toggle ( fan_always_on ) ;
2019-03-18 11:48:39 +00:00
// Thaw();
2019-02-22 08:38:56 +00:00
m_update_cnt - - ;
if ( m_update_cnt = = 0 )
wxGetApp ( ) . mainframe - > on_config_changed ( m_config ) ;
2018-01-12 11:41:13 +00:00
}
void TabFilament : : OnActivate ( )
{
2018-02-22 10:34:41 +00:00
m_volumetric_speed_description_line - > SetText ( from_u8 ( PresetHints : : maximum_volumetric_flow_description ( * m_preset_bundle ) ) ) ;
2018-06-28 16:30:22 +00:00
Tab : : OnActivate ( ) ;
2017-12-22 10:50:28 +00:00
}
2018-01-15 11:13:05 +00:00
wxSizer * Tab : : description_line_widget ( wxWindow * parent , ogStaticText * * StaticText )
2017-12-22 10:50:28 +00:00
{
2018-01-15 11:13:05 +00:00
* StaticText = new ogStaticText ( parent , " " ) ;
2019-04-13 21:46:52 +00:00
// auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
( * StaticText ) - > SetFont ( wxGetApp ( ) . normal_font ( ) ) ;
2017-12-22 10:50:28 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2018-04-26 10:40:17 +00:00
sizer - > Add ( * StaticText , 1 , wxEXPAND | wxALL , 0 ) ;
2017-12-22 10:50:28 +00:00
return sizer ;
}
2018-01-25 12:46:04 +00:00
bool Tab : : current_preset_is_dirty ( )
{
return m_presets - > current_is_dirty ( ) ;
}
2018-12-18 13:34:16 +00:00
void TabPrinter : : build_printhost ( ConfigOptionsGroup * optgroup )
{
2019-03-12 16:41:43 +00:00
const PrinterTechnology tech = m_presets - > get_selected_preset ( ) . printer_technology ( ) ;
2018-12-18 13:34:16 +00:00
// Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment)
2019-03-12 16:41:43 +00:00
if ( tech = = ptFFF ) {
2018-12-18 13:34:16 +00:00
optgroup - > append_single_option_line ( " host_type " ) ;
}
2019-03-12 16:41:43 +00:00
auto printhost_browse = [ = ] ( wxWindow * parent ) {
2019-04-14 11:49:22 +00:00
add_scaled_button ( parent , & m_printhost_browse_btn , " browse " , _ ( L ( " Browse " ) ) + dots , wxBU_LEFT | wxBU_EXACTFIT ) ;
2019-04-24 23:45:00 +00:00
ScalableButton * btn = m_printhost_browse_btn ;
2019-03-18 19:54:01 +00:00
btn - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2019-04-14 11:49:22 +00:00
2018-12-18 13:34:16 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2019-03-12 16:41:43 +00:00
btn - > Bind ( wxEVT_BUTTON , [ = ] ( wxCommandEvent & e ) {
BonjourDialog dialog ( parent , tech ) ;
2018-12-18 13:34:16 +00:00
if ( dialog . show_and_lookup ( ) ) {
optgroup - > set_value ( " print_host " , std : : move ( dialog . get_selected ( ) ) , true ) ;
2019-01-29 14:57:22 +00:00
optgroup - > get_field ( " print_host " ) - > field_changed ( ) ;
2018-12-18 13:34:16 +00:00
}
} ) ;
return sizer ;
} ;
auto print_host_test = [ this ] ( wxWindow * parent ) {
2019-04-14 11:57:15 +00:00
add_scaled_button ( parent , & m_print_host_test_btn , " test " , _ ( L ( " Test " ) ) , wxBU_LEFT | wxBU_EXACTFIT ) ;
2019-04-24 23:45:00 +00:00
ScalableButton * btn = m_print_host_test_btn ;
2019-04-13 21:46:52 +00:00
btn - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2018-12-18 13:34:16 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2019-01-29 14:57:22 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this ] ( wxCommandEvent & e ) {
2018-12-18 13:34:16 +00:00
std : : unique_ptr < PrintHost > host ( PrintHost : : get_print_host ( m_config ) ) ;
if ( ! host ) {
const auto text = wxString : : Format ( " %s " ,
_ ( L ( " Could not get a valid Printer Host reference " ) ) ) ;
show_error ( this , text ) ;
return ;
}
wxString msg ;
if ( host - > test ( msg ) ) {
show_info ( this , host - > get_test_ok_msg ( ) , _ ( L ( " Success! " ) ) ) ;
} else {
show_error ( this , host - > get_test_failed_msg ( msg ) ) ;
}
} ) ;
return sizer ;
} ;
Line host_line = optgroup - > create_single_option_line ( " print_host " ) ;
host_line . append_widget ( printhost_browse ) ;
host_line . append_widget ( print_host_test ) ;
optgroup - > append_line ( host_line ) ;
optgroup - > append_single_option_line ( " printhost_apikey " ) ;
2018-12-20 17:48:49 +00:00
const auto ca_file_hint = _ ( L ( " HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate. " ) ) ;
2018-12-18 13:34:16 +00:00
2018-12-20 17:48:49 +00:00
if ( Http : : ca_file_supported ( ) ) {
2018-12-18 13:34:16 +00:00
Line cafile_line = optgroup - > create_single_option_line ( " printhost_cafile " ) ;
auto printhost_cafile_browse = [ this , optgroup ] ( wxWindow * parent ) {
auto btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Browse " ) ) + dots , wxDefaultPosition , wxDefaultSize , wxBU_LEFT ) ;
2019-03-18 19:54:01 +00:00
btn - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2019-04-12 15:10:04 +00:00
btn - > SetBitmap ( create_scaled_bitmap ( this , " browse " ) ) ;
2018-12-18 13:34:16 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
btn - > Bind ( wxEVT_BUTTON , [ this , optgroup ] ( wxCommandEvent e ) {
static const auto filemasks = _ ( L ( " Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.* " ) ) ;
wxFileDialog openFileDialog ( this , _ ( L ( " Open CA certificate file " ) ) , " " , " " , filemasks , wxFD_OPEN | wxFD_FILE_MUST_EXIST ) ;
if ( openFileDialog . ShowModal ( ) ! = wxID_CANCEL ) {
optgroup - > set_value ( " printhost_cafile " , std : : move ( openFileDialog . GetPath ( ) ) , true ) ;
2019-01-29 14:57:22 +00:00
optgroup - > get_field ( " printhost_cafile " ) - > field_changed ( ) ;
2018-12-18 13:34:16 +00:00
}
} ) ;
return sizer ;
} ;
cafile_line . append_widget ( printhost_cafile_browse ) ;
optgroup - > append_line ( cafile_line ) ;
2018-12-20 17:48:49 +00:00
Line cafile_hint { " " , " " } ;
cafile_hint . full_width = 1 ;
cafile_hint . widget = [ this , ca_file_hint ] ( wxWindow * parent ) {
auto txt = new wxStaticText ( parent , wxID_ANY , ca_file_hint ) ;
2018-12-18 13:34:16 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( txt ) ;
return sizer ;
} ;
optgroup - > append_line ( cafile_hint ) ;
2018-12-20 17:48:49 +00:00
} else {
Line line { " " , " " } ;
line . full_width = 1 ;
2018-12-18 13:34:16 +00:00
2018-12-20 17:48:49 +00:00
line . widget = [ this , ca_file_hint ] ( wxWindow * parent ) {
auto txt = new wxStaticText ( parent , wxID_ANY , wxString : : Format ( " %s \n \n \t %s " ,
2019-04-26 08:52:38 +00:00
wxString : : Format ( _ ( L ( " HTTPS CA File: \n \
\ tOn this system , % s uses HTTPS certificates from the system Certificate Store or Keychain . \ n \
\ tTo use a custom CA file , please import your CA file into Certificate Store / Keychain . " )), SLIC3R_APP_NAME),
2018-12-20 17:48:49 +00:00
ca_file_hint ) ) ;
2019-03-18 19:54:01 +00:00
txt - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2018-12-20 17:48:49 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( txt ) ;
return sizer ;
} ;
optgroup - > append_line ( line ) ;
2018-12-18 13:34:16 +00:00
}
}
2018-01-05 14:11:33 +00:00
void TabPrinter : : build ( )
2017-12-22 10:50:28 +00:00
{
2018-01-12 11:41:13 +00:00
m_presets = & m_preset_bundle - > printers ;
2018-03-16 11:56:03 +00:00
load_initial_data ( ) ;
2017-12-22 10:50:28 +00:00
2018-08-07 09:58:27 +00:00
m_printer_technology = m_presets - > get_selected_preset ( ) . printer_technology ( ) ;
2018-08-06 15:01:41 +00:00
2018-08-07 09:58:27 +00:00
m_presets - > get_selected_preset ( ) . printer_technology ( ) = = ptSLA ? build_sla ( ) : build_fff ( ) ;
}
2018-08-03 12:34:52 +00:00
2018-08-07 09:58:27 +00:00
void TabPrinter : : build_fff ( )
{
if ( ! m_pages . empty ( ) )
m_pages . resize ( 0 ) ;
2018-04-23 09:52:03 +00:00
// to avoid redundant memory allocation / deallocation during extruders count changing
2018-04-23 13:09:01 +00:00
m_pages . reserve ( 30 ) ;
2018-04-23 09:52:03 +00:00
2018-01-12 11:41:13 +00:00
auto * nozzle_diameter = dynamic_cast < const ConfigOptionFloats * > ( m_config - > option ( " nozzle_diameter " ) ) ;
2018-03-07 14:05:41 +00:00
m_initial_extruders_count = m_extruders_count = nozzle_diameter - > values . size ( ) ;
2019-04-21 23:51:10 +00:00
wxGetApp ( ) . sidebar ( ) . update_objects_list_extruder_column ( m_initial_extruders_count ) ;
2018-03-21 21:21:37 +00:00
const Preset * parent_preset = m_presets - > get_selected_preset_parent ( ) ;
m_sys_extruders_count = parent_preset = = nullptr ? 0 :
static_cast < const ConfigOptionFloats * > ( parent_preset - > config . option ( " nozzle_diameter " ) ) - > values . size ( ) ;
2017-12-22 10:50:28 +00:00
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " General " ) ) , " printer " ) ;
2018-02-23 08:16:35 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Size and coordinates " ) ) ) ;
2017-12-22 10:50:28 +00:00
2018-10-19 11:55:29 +00:00
Line line = optgroup - > create_single_option_line ( " bed_shape " ) ; //{ _(L("Bed shape")), "" };
2018-10-31 11:56:08 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2019-04-24 23:45:00 +00:00
ScalableButton * btn ;
2019-04-13 21:46:52 +00:00
add_scaled_button ( parent , & btn , " printer_white " , _ ( L ( " Set " ) ) + dots , wxBU_LEFT | wxBU_EXACTFIT ) ;
btn - > SetFont ( wxGetApp ( ) . normal_font ( ) ) ;
2017-12-26 22:04:54 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2018-01-25 12:46:04 +00:00
btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent e )
2017-12-26 22:04:54 +00:00
{
2018-01-25 12:46:04 +00:00
auto dlg = new BedShapeDialog ( this ) ;
dlg - > build_dialog ( m_config - > option < ConfigOptionPoints > ( " bed_shape " ) ) ;
2018-10-31 11:56:08 +00:00
if ( dlg - > ShowModal ( ) = = wxID_OK ) {
2018-01-30 11:10:12 +00:00
load_key_value ( " bed_shape " , dlg - > GetValue ( ) ) ;
2018-03-23 16:27:43 +00:00
update_changed_ui ( ) ;
}
2017-12-26 22:04:54 +00:00
} ) ) ;
return sizer ;
} ;
2018-04-13 16:22:06 +00:00
optgroup - > append_line ( line , & m_colored_Label ) ;
2018-03-09 09:40:42 +00:00
optgroup - > append_single_option_line ( " max_print_height " ) ;
optgroup - > append_single_option_line ( " z_offset " ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Capabilities " ) ) ) ;
2017-12-22 10:50:28 +00:00
ConfigOptionDef def ;
def . type = coInt ,
def . default_value = new ConfigOptionInt ( 1 ) ;
2018-02-23 08:16:35 +00:00
def . label = L ( " Extruders " ) ;
def . tooltip = L ( " Number of extruders of the printer. " ) ;
2017-12-22 10:50:28 +00:00
def . min = 1 ;
2018-10-19 11:55:29 +00:00
def . mode = comExpert ;
2017-12-22 10:50:28 +00:00
Option option ( def , " extruders_count " ) ;
optgroup - > append_single_option_line ( option ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " single_extruder_multi_material " ) ;
2017-12-22 10:50:28 +00:00
2018-10-31 11:56:08 +00:00
optgroup - > m_on_change = [ this , optgroup ] ( t_config_option_key opt_key , boost : : any value ) {
2018-01-12 16:16:59 +00:00
size_t extruders_count = boost : : any_cast < int > ( optgroup - > get_value ( " extruders_count " ) ) ;
2018-10-31 11:56:08 +00:00
wxTheApp - > CallAfter ( [ this , opt_key , value , extruders_count ] ( ) {
2018-12-04 16:56:49 +00:00
if ( opt_key = = " extruders_count " | | opt_key = = " single_extruder_multi_material " ) {
2018-01-12 16:16:59 +00:00
extruders_count_changed ( extruders_count ) ;
2018-12-21 11:58:03 +00:00
init_options_list ( ) ; // m_options_list should be updated before UI updating
2018-01-12 16:16:59 +00:00
update_dirty ( ) ;
2018-12-04 16:56:49 +00:00
if ( opt_key = = " single_extruder_multi_material " ) // the single_extruder_multimaterial was added to force pages
2018-04-05 08:44:31 +00:00
on_value_change ( opt_key , value ) ; // rebuild - let's make sure the on_value_change is not skipped
2018-01-12 16:16:59 +00:00
}
else {
update_dirty ( ) ;
on_value_change ( opt_key , value ) ;
}
} ) ;
} ;
2017-12-22 10:50:28 +00:00
2018-03-22 15:13:41 +00:00
2018-09-17 10:01:02 +00:00
#if 0
2018-01-12 16:16:59 +00:00
if ( ! m_no_controller )
2018-01-03 09:12:42 +00:00
{
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " USB/Serial connection " ) ) ) ;
line = { _ ( L ( " Serial port " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
Option serial_port = optgroup - > get_option ( " serial_port " ) ;
2018-10-31 11:56:08 +00:00
serial_port . side_widget = ( [ this ] ( wxWindow * parent ) {
2018-02-22 10:34:41 +00:00
auto btn = new wxBitmapButton ( parent , wxID_ANY , wxBitmap ( from_u8 ( Slic3r : : var ( " arrow_rotate_clockwise.png " ) ) , wxBITMAP_TYPE_PNG ) ,
2017-12-22 10:50:28 +00:00
wxDefaultPosition , wxDefaultSize , wxBORDER_NONE ) ;
2018-02-23 08:16:35 +00:00
btn - > SetToolTip ( _ ( L ( " Rescan serial ports " ) ) ) ;
2017-12-22 10:50:28 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2018-01-12 16:16:59 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this ] ( wxCommandEvent e ) { update_serial_ports ( ) ; } ) ;
2017-12-22 10:50:28 +00:00
return sizer ;
} ) ;
2018-10-31 11:56:08 +00:00
auto serial_test = [ this ] ( wxWindow * parent ) {
2018-01-12 16:16:59 +00:00
auto btn = m_serial_test_btn = new wxButton ( parent , wxID_ANY ,
2018-02-23 08:16:35 +00:00
_ ( L ( " Test " ) ) , wxDefaultPosition , wxDefaultSize , wxBU_LEFT | wxBU_EXACTFIT ) ;
2018-05-24 14:57:35 +00:00
btn - > SetFont ( Slic3r : : GUI : : small_font ( ) ) ;
2018-02-22 10:34:41 +00:00
btn - > SetBitmap ( wxBitmap ( from_u8 ( Slic3r : : var ( " wrench.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
2017-12-22 10:50:28 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2018-10-31 11:56:08 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this , parent ] ( wxCommandEvent e ) {
2018-07-02 15:18:09 +00:00
auto sender = Slic3r : : make_unique < GCodeSender > ( ) ;
2018-01-03 09:12:42 +00:00
auto res = sender - > connect (
2018-01-12 16:16:59 +00:00
m_config - > opt_string ( " serial_port " ) ,
m_config - > opt_int ( " serial_speed " )
2018-01-03 09:12:42 +00:00
) ;
if ( res & & sender - > wait_connected ( ) ) {
2018-02-23 08:16:35 +00:00
show_info ( parent , _ ( L ( " Connection to printer works correctly. " ) ) , _ ( L ( " Success! " ) ) ) ;
2018-01-03 09:12:42 +00:00
}
else {
2018-02-23 08:16:35 +00:00
show_error ( parent , _ ( L ( " Connection failed. " ) ) ) ;
2018-01-03 09:12:42 +00:00
}
2017-12-26 22:04:54 +00:00
} ) ;
2017-12-22 10:50:28 +00:00
return sizer ;
2017-12-26 22:04:54 +00:00
} ;
2017-12-22 10:50:28 +00:00
line . append_option ( serial_port ) ;
2018-01-26 00:44:34 +00:00
line . append_option ( optgroup - > get_option ( " serial_speed " ) ) ;
2017-12-22 10:50:28 +00:00
line . append_widget ( serial_test ) ;
optgroup - > append_line ( line ) ;
2018-01-03 09:12:42 +00:00
}
2018-09-17 10:01:02 +00:00
# endif
2018-01-03 09:12:42 +00:00
2018-12-18 13:34:16 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Print Host upload " ) ) ) ;
build_printhost ( optgroup . get ( ) ) ;
2018-03-15 17:06:26 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Firmware " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " gcode_flavor " ) ;
2018-06-20 12:20:48 +00:00
optgroup - > append_single_option_line ( " silent_mode " ) ;
2018-08-04 15:38:25 +00:00
optgroup - > append_single_option_line ( " remaining_times " ) ;
2018-06-20 12:20:48 +00:00
2018-10-31 11:56:08 +00:00
optgroup - > m_on_change = [ this , optgroup ] ( t_config_option_key opt_key , boost : : any value ) {
wxTheApp - > CallAfter ( [ this , opt_key , value ] ( ) {
2018-12-04 16:56:49 +00:00
if ( opt_key = = " silent_mode " ) {
2018-06-22 11:01:41 +00:00
bool val = boost : : any_cast < bool > ( value ) ;
if ( m_use_silent_mode ! = val ) {
2018-06-25 14:03:43 +00:00
m_rebuild_kinematics_page = true ;
2018-06-22 11:01:41 +00:00
m_use_silent_mode = val ;
}
}
2019-04-21 21:12:39 +00:00
build_unregular_pages ( ) ;
2018-06-20 12:20:48 +00:00
update_dirty ( ) ;
on_value_change ( opt_key , value ) ;
} ) ;
} ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Advanced " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " use_relative_e_distances " ) ;
optgroup - > append_single_option_line ( " use_firmware_retraction " ) ;
optgroup - > append_single_option_line ( " use_volumetric_e " ) ;
optgroup - > append_single_option_line ( " variable_layer_height " ) ;
2017-12-22 10:50:28 +00:00
2019-04-13 21:46:52 +00:00
const int gcode_field_height = 15 ; // 150
const int notes_field_height = 25 ; // 250
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Custom G-code " ) ) , " cog " ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Start G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " start_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " End G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " end_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Before layer change G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " before_layer_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " After layer change G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " layer_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Tool change G-code " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " toolchange_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Between objects G-code (for sequential printing) " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " between_objects_gcode " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = gcode_field_height ; //150;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Notes " ) ) , " note.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Notes " ) ) , 0 ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " printer_notes " ) ;
2017-12-22 10:50:28 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = notes_field_height ; //250;
2017-12-22 10:50:28 +00:00
optgroup - > append_single_option_line ( option ) ;
2018-03-22 10:46:15 +00:00
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
2019-04-21 21:12:39 +00:00
build_unregular_pages ( ) ;
2017-12-22 10:50:28 +00:00
2018-09-17 10:01:02 +00:00
#if 0
2018-01-12 16:16:59 +00:00
if ( ! m_no_controller )
update_serial_ports ( ) ;
2018-09-17 10:01:02 +00:00
# endif
2017-12-22 10:50:28 +00:00
}
2018-08-03 12:34:52 +00:00
void TabPrinter : : build_sla ( )
{
2018-08-07 09:58:27 +00:00
if ( ! m_pages . empty ( ) )
m_pages . resize ( 0 ) ;
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " General " ) ) , " printer " ) ;
2018-08-03 12:34:52 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Size and coordinates " ) ) ) ;
2018-10-22 10:07:40 +00:00
Line line = optgroup - > create_single_option_line ( " bed_shape " ) ; //{ _(L("Bed shape")), "" };
2018-10-31 11:56:08 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2019-04-24 23:45:00 +00:00
ScalableButton * btn ;
2019-04-13 21:46:52 +00:00
add_scaled_button ( parent , & btn , " printer_white " , _ ( L ( " Set " ) ) + dots , wxBU_LEFT | wxBU_EXACTFIT ) ;
btn - > SetFont ( wxGetApp ( ) . normal_font ( ) ) ;
2018-08-03 12:34:52 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent e )
{
auto dlg = new BedShapeDialog ( this ) ;
dlg - > build_dialog ( m_config - > option < ConfigOptionPoints > ( " bed_shape " ) ) ;
2018-10-31 11:56:08 +00:00
if ( dlg - > ShowModal ( ) = = wxID_OK ) {
2018-08-03 12:34:52 +00:00
load_key_value ( " bed_shape " , dlg - > GetValue ( ) ) ;
update_changed_ui ( ) ;
}
} ) ) ;
return sizer ;
} ;
optgroup - > append_line ( line , & m_colored_Label ) ;
optgroup - > append_single_option_line ( " max_print_height " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Display " ) ) ) ;
optgroup - > append_single_option_line ( " display_width " ) ;
optgroup - > append_single_option_line ( " display_height " ) ;
2018-08-08 15:47:59 +00:00
auto option = optgroup - > get_option ( " display_pixels_x " ) ;
line = { _ ( option . opt . full_label ) , " " } ;
line . append_option ( option ) ;
2018-08-03 12:34:52 +00:00
line . append_option ( optgroup - > get_option ( " display_pixels_y " ) ) ;
optgroup - > append_line ( line ) ;
2018-12-13 11:42:45 +00:00
optgroup - > append_single_option_line ( " display_orientation " ) ;
2018-08-03 12:34:52 +00:00
2019-02-18 15:04:55 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Tilt " ) ) ) ;
line = { _ ( L ( " Tilt time " ) ) , " " } ;
line . append_option ( optgroup - > get_option ( " fast_tilt_time " ) ) ;
line . append_option ( optgroup - > get_option ( " slow_tilt_time " ) ) ;
optgroup - > append_line ( line ) ;
optgroup - > append_single_option_line ( " area_fill " ) ;
2018-08-03 12:34:52 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Corrections " ) ) ) ;
2019-04-09 11:42:32 +00:00
line = Line { m_config - > def ( ) - > get ( " relative_correction " ) - > full_label , " " } ;
2019-04-09 16:15:25 +00:00
// std::vector<std::string> axes{ "X", "Y", "Z" };
std : : vector < std : : string > axes { " XY " , " Z " } ;
2018-08-03 14:20:39 +00:00
int id = 0 ;
for ( auto & axis : axes ) {
2019-04-09 11:42:32 +00:00
auto opt = optgroup - > get_option ( " relative_correction " , id ) ;
2018-08-03 14:20:39 +00:00
opt . opt . label = axis ;
line . append_option ( opt ) ;
+ + id ;
}
optgroup - > append_line ( line ) ;
2019-04-09 11:42:32 +00:00
optgroup - > append_single_option_line ( " absolute_correction " ) ;
optgroup - > append_single_option_line ( " gamma_correction " ) ;
2018-08-03 12:34:52 +00:00
2018-12-18 13:34:16 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Print Host upload " ) ) ) ;
build_printhost ( optgroup . get ( ) ) ;
2019-04-13 21:46:52 +00:00
const int notes_field_height = 25 ; // 250
2019-02-04 11:07:15 +00:00
2018-08-03 12:34:52 +00:00
page = add_options_page ( _ ( L ( " Notes " ) ) , " note.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Notes " ) ) , 0 ) ;
2018-08-08 15:47:59 +00:00
option = optgroup - > get_option ( " printer_notes " ) ;
2018-08-03 12:34:52 +00:00
option . opt . full_width = true ;
2019-02-04 11:07:15 +00:00
option . opt . height = notes_field_height ; //250;
2018-08-03 12:34:52 +00:00
optgroup - > append_single_option_line ( option ) ;
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
2017-12-22 10:50:28 +00:00
}
2018-10-31 11:56:08 +00:00
void TabPrinter : : update_serial_ports ( )
{
2018-01-12 16:16:59 +00:00
Field * field = get_field ( " serial_port " ) ;
Choice * choice = static_cast < Choice * > ( field ) ;
2018-05-21 14:14:20 +00:00
choice - > set_values ( Utils : : scan_serial_ports ( ) ) ;
2018-01-12 16:16:59 +00:00
}
2018-01-02 11:50:27 +00:00
2018-10-31 11:56:08 +00:00
void TabPrinter : : extruders_count_changed ( size_t extruders_count )
{
2019-04-21 21:12:39 +00:00
bool is_count_changed = false ;
if ( m_extruders_count ! = extruders_count ) {
m_extruders_count = extruders_count ;
m_preset_bundle - > printers . get_edited_preset ( ) . set_num_extruders ( extruders_count ) ;
m_preset_bundle - > update_multi_material_filament_presets ( ) ;
is_count_changed = true ;
}
/* This function should be call in any case because of correct updating/rebuilding
* of unregular pages of a Printer Settings
*/
build_unregular_pages ( ) ;
if ( is_count_changed ) {
on_value_change ( " extruders_count " , extruders_count ) ;
wxGetApp ( ) . sidebar ( ) . update_objects_list_extruder_column ( extruders_count ) ;
}
2018-01-12 16:16:59 +00:00
}
2018-06-22 11:01:41 +00:00
void TabPrinter : : append_option_line ( ConfigOptionsGroupShp optgroup , const std : : string opt_key )
2018-06-21 14:15:56 +00:00
{
auto option = optgroup - > get_option ( opt_key , 0 ) ;
auto line = Line { option . opt . full_label , " " } ;
line . append_option ( option ) ;
2018-06-22 11:01:41 +00:00
if ( m_use_silent_mode )
line . append_option ( optgroup - > get_option ( opt_key , 1 ) ) ;
2018-06-21 14:15:56 +00:00
optgroup - > append_line ( line ) ;
}
2018-06-22 14:13:34 +00:00
PageShp TabPrinter : : build_kinematics_page ( )
2018-06-20 12:20:48 +00:00
{
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " Machine limits " ) ) , " cog " , true ) ;
2018-06-21 14:15:56 +00:00
2018-06-22 11:01:41 +00:00
if ( m_use_silent_mode ) {
// Legend for OptionsGroups
2019-01-21 11:34:28 +00:00
auto optgroup = page - > new_optgroup ( " " ) ;
2018-06-22 11:01:41 +00:00
optgroup - > set_show_modified_btns_val ( false ) ;
2019-04-13 21:46:52 +00:00
optgroup - > label_width = 23 ; // 230;
2018-06-22 11:01:41 +00:00
auto line = Line { " " , " " } ;
2018-06-21 14:15:56 +00:00
2018-06-22 11:01:41 +00:00
ConfigOptionDef def ;
def . type = coString ;
2019-04-13 21:46:52 +00:00
def . width = 15 ;
2018-06-22 11:01:41 +00:00
def . gui_type = " legend " ;
2018-12-21 08:19:00 +00:00
def . mode = comAdvanced ;
2018-06-22 11:01:41 +00:00
def . tooltip = L ( " Values in this column are for Full Power mode " ) ;
def . default_value = new ConfigOptionString { L ( " Full Power " ) } ;
2018-06-21 14:15:56 +00:00
2018-06-22 11:01:41 +00:00
auto option = Option ( def , " full_power_legend " ) ;
line . append_option ( option ) ;
2018-06-21 14:15:56 +00:00
2018-06-22 11:01:41 +00:00
def . tooltip = L ( " Values in this column are for Silent mode " ) ;
def . default_value = new ConfigOptionString { L ( " Silent " ) } ;
option = Option ( def , " silent_legend " ) ;
line . append_option ( option ) ;
2018-06-21 14:15:56 +00:00
2018-06-22 11:01:41 +00:00
optgroup - > append_line ( line ) ;
}
2018-06-21 14:15:56 +00:00
std : : vector < std : : string > axes { " x " , " y " , " z " , " e " } ;
2018-07-18 13:08:55 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Maximum feedrates " ) ) ) ;
2018-06-21 14:15:56 +00:00
for ( const std : : string & axis : axes ) {
2018-07-18 13:08:55 +00:00
append_option_line ( optgroup , " machine_max_feedrate_ " + axis ) ;
2018-06-21 14:15:56 +00:00
}
2018-06-20 12:20:48 +00:00
2018-07-18 13:08:55 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Maximum accelerations " ) ) ) ;
2018-06-21 14:15:56 +00:00
for ( const std : : string & axis : axes ) {
2018-07-18 13:08:55 +00:00
append_option_line ( optgroup , " machine_max_acceleration_ " + axis ) ;
2018-06-21 14:15:56 +00:00
}
append_option_line ( optgroup , " machine_max_acceleration_extruding " ) ;
append_option_line ( optgroup , " machine_max_acceleration_retracting " ) ;
2018-06-20 12:20:48 +00:00
2018-07-18 13:08:55 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Jerk limits " ) ) ) ;
2018-06-21 14:15:56 +00:00
for ( const std : : string & axis : axes ) {
append_option_line ( optgroup , " machine_max_jerk_ " + axis ) ;
}
2018-06-20 12:20:48 +00:00
2018-07-18 13:08:55 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Minimum feedrates " ) ) ) ;
append_option_line ( optgroup , " machine_min_extruding_rate " ) ;
append_option_line ( optgroup , " machine_min_travel_rate " ) ;
2018-06-20 12:20:48 +00:00
return page ;
}
2019-04-21 21:12:39 +00:00
/* Previous name build_extruder_pages().
*
* This function was renamed because of now it implements not just an extruder pages building ,
* but " Machine limits " and " Single extruder MM setup " too
* ( These pages can changes according to the another values of a current preset )
* */
void TabPrinter : : build_unregular_pages ( )
2018-06-20 12:20:48 +00:00
{
2018-04-23 13:39:55 +00:00
size_t n_before_extruders = 2 ; // Count of pages before Extruder pages
2018-06-20 12:20:48 +00:00
bool is_marlin_flavor = m_config - > option < ConfigOptionEnum < GCodeFlavor > > ( " gcode_flavor " ) - > value = = gcfMarlin ;
2019-04-21 22:17:56 +00:00
/* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages
* and be cause of application crash , when try to change Preset in moment ,
* when one of unregular pages is selected .
* */
Freeze ( ) ;
2018-06-20 12:20:48 +00:00
// Add/delete Kinematics page according to is_marlin_flavor
size_t existed_page = 0 ;
for ( int i = n_before_extruders ; i < m_pages . size ( ) ; + + i ) // first make sure it's not there already
2018-06-20 14:30:55 +00:00
if ( m_pages [ i ] - > title ( ) . find ( _ ( L ( " Machine limits " ) ) ) ! = std : : string : : npos ) {
2018-06-25 14:03:43 +00:00
if ( ! is_marlin_flavor | | m_rebuild_kinematics_page )
2018-06-20 12:20:48 +00:00
m_pages . erase ( m_pages . begin ( ) + i ) ;
else
existed_page = i ;
break ;
}
2018-10-31 11:56:08 +00:00
if ( existed_page < n_before_extruders & & is_marlin_flavor ) {
2018-06-22 14:13:34 +00:00
auto page = build_kinematics_page ( ) ;
2018-06-20 12:20:48 +00:00
m_pages . insert ( m_pages . begin ( ) + n_before_extruders , page ) ;
}
if ( is_marlin_flavor )
n_before_extruders + + ;
2018-04-23 13:39:55 +00:00
size_t n_after_single_extruder_MM = 2 ; // Count of pages after single_extruder_multi_material page
2018-05-21 12:36:09 +00:00
if ( m_extruders_count_old = = m_extruders_count | |
( m_has_single_extruder_MM_page & & m_extruders_count = = 1 ) )
2018-04-18 11:32:21 +00:00
{
// if we have a single extruder MM setup, add a page with configuration options:
for ( int i = 0 ; i < m_pages . size ( ) ; + + i ) // first make sure it's not there already
if ( m_pages [ i ] - > title ( ) . find ( _ ( L ( " Single extruder MM setup " ) ) ) ! = std : : string : : npos ) {
m_pages . erase ( m_pages . begin ( ) + i ) ;
break ;
}
2018-05-21 12:36:09 +00:00
m_has_single_extruder_MM_page = false ;
}
if ( m_extruders_count > 1 & & m_config - > opt_bool ( " single_extruder_multi_material " ) & & ! m_has_single_extruder_MM_page ) {
// create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " Single extruder MM setup " ) ) , " printer " , true ) ;
2018-05-21 12:36:09 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Single extruder multimaterial parameters " ) ) ) ;
optgroup - > append_single_option_line ( " cooling_tube_retraction " ) ;
optgroup - > append_single_option_line ( " cooling_tube_length " ) ;
optgroup - > append_single_option_line ( " parking_pos_retraction " ) ;
2018-05-23 17:34:33 +00:00
optgroup - > append_single_option_line ( " extra_loading_move " ) ;
2018-12-14 19:09:10 +00:00
optgroup - > append_single_option_line ( " high_current_on_filament_swap " ) ;
2018-05-21 12:36:09 +00:00
m_pages . insert ( m_pages . end ( ) - n_after_single_extruder_MM , page ) ;
m_has_single_extruder_MM_page = true ;
2018-04-18 11:32:21 +00:00
}
2018-05-21 12:36:09 +00:00
2019-04-21 21:12:39 +00:00
// Build missed extruder pages
2018-10-31 11:56:08 +00:00
for ( auto extruder_idx = m_extruders_count_old ; extruder_idx < m_extruders_count ; + + extruder_idx ) {
2017-12-22 10:50:28 +00:00
//# build page
2019-04-21 22:17:56 +00:00
const wxString & page_name = wxString : : Format ( _ ( L ( " Extruder %d " ) ) , int ( extruder_idx + 1 ) ) ;
auto page = add_options_page ( page_name , " funnel " , true ) ;
2018-04-23 13:39:55 +00:00
m_pages . insert ( m_pages . begin ( ) + n_before_extruders + extruder_idx , page ) ;
2018-01-02 11:50:27 +00:00
2018-02-23 08:16:35 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Size " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " nozzle_diameter " , extruder_idx ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Layer height limits " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " min_layer_height " , extruder_idx ) ;
optgroup - > append_single_option_line ( " max_layer_height " , extruder_idx ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Position (for multi-extruder printers) " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " extruder_offset " , extruder_idx ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Retraction " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " retract_length " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_lift " , extruder_idx ) ;
2018-02-23 08:16:35 +00:00
Line line = { _ ( L ( " Only lift Z " ) ) , " " } ;
2018-01-07 17:41:40 +00:00
line . append_option ( optgroup - > get_option ( " retract_lift_above " , extruder_idx ) ) ;
line . append_option ( optgroup - > get_option ( " retract_lift_below " , extruder_idx ) ) ;
2017-12-22 10:50:28 +00:00
optgroup - > append_line ( line ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " retract_speed " , extruder_idx ) ;
optgroup - > append_single_option_line ( " deretract_speed " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_restart_extra " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_before_travel " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_layer_change " , extruder_idx ) ;
optgroup - > append_single_option_line ( " wipe " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_before_wipe " , extruder_idx ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Retraction when tool is disabled (advanced settings for multi-extruder setups) " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " retract_length_toolchange " , extruder_idx ) ;
optgroup - > append_single_option_line ( " retract_restart_extra_toolchange " , extruder_idx ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Preview " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " extruder_colour " , extruder_idx ) ;
2018-01-02 11:50:27 +00:00
}
// # remove extra pages
2018-04-18 11:32:21 +00:00
if ( m_extruders_count < m_extruders_count_old )
2018-04-23 13:39:55 +00:00
m_pages . erase ( m_pages . begin ( ) + n_before_extruders + m_extruders_count ,
m_pages . begin ( ) + n_before_extruders + m_extruders_count_old ) ;
2018-01-02 11:50:27 +00:00
2019-04-21 22:17:56 +00:00
Thaw ( ) ;
2018-04-18 11:32:21 +00:00
m_extruders_count_old = m_extruders_count ;
2018-01-02 11:50:27 +00:00
rebuild_page_tree ( ) ;
2019-04-21 21:12:39 +00:00
// Reload preset pages with current configuration values
reload_config ( ) ;
2017-12-22 10:50:28 +00:00
}
2018-01-16 15:28:01 +00:00
// this gets executed after preset is loaded and before GUI fields are updated
void TabPrinter : : on_preset_loaded ( )
{
// update the extruders count field
auto * nozzle_diameter = dynamic_cast < const ConfigOptionFloats * > ( m_config - > option ( " nozzle_diameter " ) ) ;
int extruders_count = nozzle_diameter - > values . size ( ) ;
set_value ( " extruders_count " , extruders_count ) ;
// update the GUI field according to the number of nozzle diameters supplied
extruders_count_changed ( extruders_count ) ;
}
2018-08-07 09:58:27 +00:00
void TabPrinter : : update_pages ( )
{
// update m_pages ONLY if printer technology is changed
2018-10-31 15:22:36 +00:00
const PrinterTechnology new_printer_technology = m_presets - > get_edited_preset ( ) . printer_technology ( ) ;
if ( new_printer_technology = = m_printer_technology )
2018-08-07 09:58:27 +00:00
return ;
// hide all old pages
for ( auto & el : m_pages )
el . get ( ) - > Hide ( ) ;
// set m_pages to m_pages_(technology before changing)
m_printer_technology = = ptFFF ? m_pages . swap ( m_pages_fff ) : m_pages . swap ( m_pages_sla ) ;
// build Tab according to the technology, if it's not exist jet OR
// set m_pages_(technology after changing) to m_pages
2018-10-31 15:22:36 +00:00
// m_printer_technology will be set by Tab::load_current_preset()
if ( new_printer_technology = = ptFFF )
2018-08-07 09:58:27 +00:00
m_pages_fff . empty ( ) ? build_fff ( ) : m_pages . swap ( m_pages_fff ) ;
else
m_pages_sla . empty ( ) ? build_sla ( ) : m_pages . swap ( m_pages_sla ) ;
2019-03-20 15:22:01 +00:00
rebuild_page_tree ( ) ;
2018-08-07 09:58:27 +00:00
}
void TabPrinter : : update ( )
{
2019-02-22 08:38:56 +00:00
m_update_cnt + + ;
2018-08-07 09:58:27 +00:00
m_presets - > get_edited_preset ( ) . printer_technology ( ) = = ptFFF ? update_fff ( ) : update_sla ( ) ;
2019-02-22 08:38:56 +00:00
m_update_cnt - - ;
if ( m_update_cnt = = 0 )
wxGetApp ( ) . mainframe - > on_config_changed ( m_config ) ;
2018-08-07 09:58:27 +00:00
}
void TabPrinter : : update_fff ( )
{
2019-03-18 11:48:39 +00:00
// Freeze();
2018-01-12 16:16:59 +00:00
bool en ;
auto serial_speed = get_field ( " serial_speed " ) ;
if ( serial_speed ! = nullptr ) {
en = ! m_config - > opt_string ( " serial_port " ) . empty ( ) ;
get_field ( " serial_speed " ) - > toggle ( en ) ;
if ( m_config - > opt_int ( " serial_speed " ) ! = 0 & & en )
m_serial_test_btn - > Enable ( ) ;
else
m_serial_test_btn - > Disable ( ) ;
}
2018-08-21 09:10:32 +00:00
{
std : : unique_ptr < PrintHost > host ( PrintHost : : get_print_host ( m_config ) ) ;
m_print_host_test_btn - > Enable ( ! m_config - > opt_string ( " print_host " ) . empty ( ) & & host - > can_test ( ) ) ;
m_printhost_browse_btn - > Enable ( host - > has_auto_discovery ( ) ) ;
}
2018-01-12 16:16:59 +00:00
bool have_multiple_extruders = m_extruders_count > 1 ;
get_field ( " toolchange_gcode " ) - > toggle ( have_multiple_extruders ) ;
get_field ( " single_extruder_multi_material " ) - > toggle ( have_multiple_extruders ) ;
2018-06-20 12:20:48 +00:00
bool is_marlin_flavor = m_config - > option < ConfigOptionEnum < GCodeFlavor > > ( " gcode_flavor " ) - > value = = gcfMarlin ;
2018-06-28 10:40:27 +00:00
2018-07-17 17:37:24 +00:00
{
Field * sm = get_field ( " silent_mode " ) ;
if ( ! is_marlin_flavor )
// Disable silent mode for non-marlin firmwares.
get_field ( " silent_mode " ) - > toggle ( false ) ;
if ( is_marlin_flavor )
sm - > enable ( ) ;
else
sm - > disable ( ) ;
}
2018-06-28 10:40:27 +00:00
2018-07-17 17:37:24 +00:00
if ( m_use_silent_mode ! = m_config - > opt_bool ( " silent_mode " ) ) {
2018-06-25 14:03:43 +00:00
m_rebuild_kinematics_page = true ;
m_use_silent_mode = m_config - > opt_bool ( " silent_mode " ) ;
}
2018-06-20 12:20:48 +00:00
2018-01-12 16:16:59 +00:00
for ( size_t i = 0 ; i < m_extruders_count ; + + i ) {
bool have_retract_length = m_config - > opt_float ( " retract_length " , i ) > 0 ;
// when using firmware retraction, firmware decides retraction length
bool use_firmware_retraction = m_config - > opt_bool ( " use_firmware_retraction " ) ;
get_field ( " retract_length " , i ) - > toggle ( ! use_firmware_retraction ) ;
// user can customize travel length if we have retraction length or we"re using
// firmware retraction
get_field ( " retract_before_travel " , i ) - > toggle ( have_retract_length | | use_firmware_retraction ) ;
// user can customize other retraction options if retraction is enabled
bool retraction = ( have_retract_length | | use_firmware_retraction ) ;
std : : vector < std : : string > vec = { " retract_lift " , " retract_layer_change " } ;
for ( auto el : vec )
get_field ( el , i ) - > toggle ( retraction ) ;
// retract lift above / below only applies if using retract lift
vec . resize ( 0 ) ;
vec = { " retract_lift_above " , " retract_lift_below " } ;
for ( auto el : vec )
get_field ( el , i ) - > toggle ( retraction & & m_config - > opt_float ( " retract_lift " , i ) > 0 ) ;
// some options only apply when not using firmware retraction
vec . resize ( 0 ) ;
vec = { " retract_speed " , " deretract_speed " , " retract_before_wipe " , " retract_restart_extra " , " wipe " } ;
for ( auto el : vec )
get_field ( el , i ) - > toggle ( retraction & & ! use_firmware_retraction ) ;
bool wipe = m_config - > opt_bool ( " wipe " , i ) ;
get_field ( " retract_before_wipe " , i ) - > toggle ( wipe ) ;
if ( use_firmware_retraction & & wipe ) {
auto dialog = new wxMessageDialog ( parent ( ) ,
2018-02-23 08:16:35 +00:00
_ ( L ( " The Wipe option is not available when using the Firmware Retraction mode. \n "
" \n Shall I disable it in order to enable Firmware Retraction? " ) ) ,
_ ( L ( " Firmware Retraction " ) ) , wxICON_WARNING | wxYES | wxNO ) ;
2018-01-12 16:16:59 +00:00
DynamicPrintConfig new_conf = * m_config ;
if ( dialog - > ShowModal ( ) = = wxID_YES ) {
2018-03-09 16:17:51 +00:00
auto wipe = static_cast < ConfigOptionBools * > ( m_config - > option ( " wipe " ) - > clone ( ) ) ;
2018-03-12 15:52:21 +00:00
for ( int w = 0 ; w < wipe - > values . size ( ) ; w + + )
wipe - > values [ w ] = false ;
2018-01-12 16:16:59 +00:00
new_conf . set_key_value ( " wipe " , wipe ) ;
}
else {
new_conf . set_key_value ( " use_firmware_retraction " , new ConfigOptionBool ( false ) ) ;
}
load_config ( new_conf ) ;
}
get_field ( " retract_length_toolchange " , i ) - > toggle ( have_multiple_extruders ) ;
bool toolchange_retraction = m_config - > opt_float ( " retract_length_toolchange " , i ) > 0 ;
get_field ( " retract_restart_extra_toolchange " , i ) - > toggle
( have_multiple_extruders & & toolchange_retraction ) ;
}
2019-03-18 11:48:39 +00:00
// Thaw();
2018-01-12 16:16:59 +00:00
}
2018-10-31 11:56:08 +00:00
void TabPrinter : : update_sla ( )
{ ; }
2018-08-07 09:58:27 +00:00
2018-01-16 15:28:01 +00:00
// Initialize the UI from the current preset
2018-01-05 14:11:33 +00:00
void Tab : : load_current_preset ( )
{
2019-01-09 09:43:17 +00:00
const Preset & preset = m_presets - > get_edited_preset ( ) ;
2018-03-16 16:25:11 +00:00
2018-04-26 10:40:17 +00:00
( preset . is_default | | preset . is_system ) ? m_btn_delete_preset - > Disable ( ) : m_btn_delete_preset - > Enable ( true ) ;
2018-08-06 15:01:41 +00:00
2018-08-07 09:58:27 +00:00
update ( ) ;
2019-03-22 11:11:23 +00:00
if ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) {
2019-01-10 17:08:38 +00:00
// For the printer profile, generate the extruder pages.
if ( preset . printer_technology ( ) = = ptFFF )
on_preset_loaded ( ) ;
else
wxGetApp ( ) . sidebar ( ) . update_objects_list_extruder_column ( 1 ) ;
}
2018-08-07 09:58:27 +00:00
// Reload preset pages with the new configuration values.
reload_config ( ) ;
2018-08-06 15:01:41 +00:00
2018-04-16 09:03:08 +00:00
m_bmp_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_bmp_value_unlock : & m_bmp_white_bullet ;
2018-04-24 12:11:23 +00:00
m_ttg_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_ttg_value_unlock : & m_ttg_white_bullet_ns ;
2018-08-07 15:23:48 +00:00
m_tt_non_system = m_presets - > get_selected_preset_parent ( ) ? & m_tt_value_unlock : & m_ttg_white_bullet_ns ;
2018-03-13 15:14:36 +00:00
2018-07-02 11:51:50 +00:00
m_undo_to_sys_btn - > Enable ( ! preset . is_default ) ;
2019-01-09 09:43:17 +00:00
#if 0
2018-01-16 15:28:01 +00:00
// use CallAfter because some field triggers schedule on_change calls using CallAfter,
// and we don't want them to be called after this update_dirty() as they would mark the
// preset dirty again
// (not sure this is true anymore now that update_dirty is idempotent)
2019-01-09 09:43:17 +00:00
wxTheApp - > CallAfter ( [ this ]
# endif
{
2018-02-09 10:04:34 +00:00
// checking out if this Tab exists till this moment
2018-10-01 13:09:31 +00:00
if ( ! wxGetApp ( ) . checked_tab ( this ) )
2018-02-09 10:04:34 +00:00
return ;
2018-01-16 15:28:01 +00:00
update_tab_ui ( ) ;
2018-08-06 15:01:41 +00:00
// update show/hide tabs
2019-03-22 11:11:23 +00:00
if ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) {
2019-01-10 17:08:38 +00:00
const PrinterTechnology printer_technology = m_presets - > get_edited_preset ( ) . printer_technology ( ) ;
2018-08-07 09:58:27 +00:00
if ( printer_technology ! = static_cast < TabPrinter * > ( this ) - > m_printer_technology )
2018-08-06 15:01:41 +00:00
{
2018-11-19 12:17:14 +00:00
for ( auto tab : wxGetApp ( ) . tabs_list ) {
if ( tab - > type ( ) = = Preset : : TYPE_PRINTER ) // Printer tab is shown every time
continue ;
if ( tab - > supports_printer_technology ( printer_technology ) )
2019-01-01 21:08:46 +00:00
{
2018-11-19 12:17:14 +00:00
wxGetApp ( ) . tab_panel ( ) - > InsertPage ( wxGetApp ( ) . tab_panel ( ) - > FindPage ( this ) , tab , tab - > title ( ) ) ;
2019-01-01 21:08:46 +00:00
# ifdef __linux__ // the tabs apparently need to be explicitly shown on Linux (pull request #1563)
int page_id = wxGetApp ( ) . tab_panel ( ) - > FindPage ( tab ) ;
wxGetApp ( ) . tab_panel ( ) - > GetPage ( page_id ) - > Show ( true ) ;
# endif // __linux__
}
2018-11-19 12:17:14 +00:00
else {
int page_id = wxGetApp ( ) . tab_panel ( ) - > FindPage ( tab ) ;
2018-09-20 23:33:41 +00:00
wxGetApp ( ) . tab_panel ( ) - > GetPage ( page_id ) - > Show ( false ) ;
wxGetApp ( ) . tab_panel ( ) - > RemovePage ( page_id ) ;
2018-11-19 12:17:14 +00:00
}
2018-08-06 15:01:41 +00:00
}
2018-08-08 14:22:56 +00:00
static_cast < TabPrinter * > ( this ) - > m_printer_technology = printer_technology ;
2018-08-06 15:01:41 +00:00
}
2018-10-31 15:22:36 +00:00
on_presets_changed ( ) ;
if ( printer_technology = = ptFFF ) {
static_cast < TabPrinter * > ( this ) - > m_initial_extruders_count = static_cast < TabPrinter * > ( this ) - > m_extruders_count ;
const Preset * parent_preset = m_presets - > get_selected_preset_parent ( ) ;
static_cast < TabPrinter * > ( this ) - > m_sys_extruders_count = parent_preset = = nullptr ? 0 :
static_cast < const ConfigOptionFloats * > ( parent_preset - > config . option ( " nozzle_diameter " ) ) - > values . size ( ) ;
}
2018-03-21 21:21:37 +00:00
}
2018-10-31 15:22:36 +00:00
else {
on_presets_changed ( ) ;
2019-03-22 11:11:23 +00:00
if ( m_type = = Preset : : TYPE_SLA_PRINT | | m_type = = Preset : : TYPE_PRINT )
2018-10-31 15:22:36 +00:00
update_frequently_changed_parameters ( ) ;
}
2018-04-18 11:32:21 +00:00
m_opt_status_value = ( m_presets - > get_selected_preset_parent ( ) ? osSystemValue : 0 ) | osInitValue ;
init_options_list ( ) ;
2018-12-21 11:58:03 +00:00
update_visibility ( ) ;
2018-03-14 14:38:54 +00:00
update_changed_ui ( ) ;
2019-01-09 09:43:17 +00:00
}
#if 0
) ;
# endif
2018-01-05 14:11:33 +00:00
}
2017-12-13 13:45:10 +00:00
//Regerenerate content of the page tree.
2019-03-20 15:22:01 +00:00
void Tab : : rebuild_page_tree ( )
2017-12-13 13:45:10 +00:00
{
// get label of the currently selected item
2018-09-20 23:33:41 +00:00
const auto sel_item = m_treectrl - > GetSelection ( ) ;
const auto selected = sel_item ? m_treectrl - > GetItemText ( sel_item ) : " " ;
const auto rootItem = m_treectrl - > GetRootItem ( ) ;
2018-04-23 13:09:01 +00:00
2017-12-13 13:45:10 +00:00
auto have_selection = 0 ;
2018-04-23 13:39:55 +00:00
m_treectrl - > DeleteChildren ( rootItem ) ;
2017-12-26 22:04:54 +00:00
for ( auto p : m_pages )
2017-12-13 13:45:10 +00:00
{
2017-12-26 22:04:54 +00:00
auto itemId = m_treectrl - > AppendItem ( rootItem , p - > title ( ) , p - > iconID ( ) ) ;
2018-04-23 13:39:55 +00:00
m_treectrl - > SetItemTextColour ( itemId , p - > get_item_colour ( ) ) ;
2017-12-13 13:45:10 +00:00
if ( p - > title ( ) = = selected ) {
2017-12-26 22:04:54 +00:00
m_treectrl - > SelectItem ( itemId ) ;
2017-12-13 13:45:10 +00:00
have_selection = 1 ;
}
}
2018-04-23 13:39:55 +00:00
2017-12-13 13:45:10 +00:00
if ( ! have_selection ) {
// this is triggered on first load, so we don't disable the sel change event
2019-03-22 19:49:17 +00:00
auto item = m_treectrl - > GetFirstVisibleItem ( ) ;
if ( item ) {
2019-03-22 22:08:13 +00:00
m_treectrl - > SelectItem ( item ) ;
2019-03-22 19:49:17 +00:00
}
2017-12-13 13:45:10 +00:00
}
}
2018-10-21 21:09:24 +00:00
void Tab : : update_page_tree_visibility ( )
{
const auto sel_item = m_treectrl - > GetSelection ( ) ;
const auto selected = sel_item ? m_treectrl - > GetItemText ( sel_item ) : " " ;
const auto rootItem = m_treectrl - > GetRootItem ( ) ;
auto have_selection = 0 ;
m_treectrl - > DeleteChildren ( rootItem ) ;
for ( auto p : m_pages )
{
if ( ! p - > get_show ( ) )
continue ;
auto itemId = m_treectrl - > AppendItem ( rootItem , p - > title ( ) , p - > iconID ( ) ) ;
m_treectrl - > SetItemTextColour ( itemId , p - > get_item_colour ( ) ) ;
if ( p - > title ( ) = = selected ) {
m_treectrl - > SelectItem ( itemId ) ;
have_selection = 1 ;
}
}
if ( ! have_selection ) {
// this is triggered on first load, so we don't disable the sel change event
2019-03-22 19:49:17 +00:00
auto item = m_treectrl - > GetFirstVisibleItem ( ) ;
if ( item ) {
m_treectrl - > SelectItem ( item ) ;
}
2018-10-21 21:09:24 +00:00
}
}
2019-03-22 11:11:23 +00:00
// Called by the UI combo box when the user switches profiles, and also to delete the current profile.
2018-01-16 15:28:01 +00:00
// Select a preset by a name.If !defined(name), then the default preset is selected.
// If the current profile is modified, user is asked to save the changes.
2019-03-22 11:11:23 +00:00
void Tab : : select_preset ( std : : string preset_name , bool delete_current )
{
if ( preset_name . empty ( ) ) {
if ( delete_current ) {
// Find an alternate preset to be selected after the current preset is deleted.
const std : : deque < Preset > & presets = this - > m_presets - > get_presets ( ) ;
size_t idx_current = this - > m_presets - > get_idx_selected ( ) ;
// Find the next visible preset.
size_t idx_new = idx_current + 1 ;
if ( idx_new < presets . size ( ) )
for ( ; idx_new < presets . size ( ) & & ! presets [ idx_new ] . is_visible ; + + idx_new ) ;
if ( idx_new = = presets . size ( ) )
for ( idx_new = idx_current - 1 ; idx_new > 0 & & ! presets [ idx_new ] . is_visible ; - - idx_new ) ;
preset_name = presets [ idx_new ] . name ;
} else {
// If no name is provided, select the "-- default --" preset.
preset_name = m_presets - > default_preset ( ) . name ;
}
}
assert ( ! delete_current | | ( m_presets - > get_edited_preset ( ) . name ! = preset_name & & m_presets - > get_edited_preset ( ) . is_user ( ) ) ) ;
bool current_dirty = ! delete_current & & m_presets - > current_is_dirty ( ) ;
2018-12-04 16:56:49 +00:00
bool print_tab = m_presets - > type ( ) = = Preset : : TYPE_PRINT | | m_presets - > type ( ) = = Preset : : TYPE_SLA_PRINT ;
bool printer_tab = m_presets - > type ( ) = = Preset : : TYPE_PRINTER ;
bool canceled = false ;
2018-11-16 10:14:56 +00:00
m_dependent_tabs = { } ;
2019-03-22 11:11:23 +00:00
if ( current_dirty & & ! may_discard_current_dirty_preset ( ) ) {
2018-01-16 15:28:01 +00:00
canceled = true ;
2018-12-04 16:56:49 +00:00
} else if ( print_tab ) {
// Before switching the print profile to a new one, verify, whether the currently active filament or SLA material
// are compatible with the new print.
// If it is not compatible and the current filament or SLA material are dirty, let user decide
// whether to discard the changes or keep the current print selection.
PrinterTechnology printer_technology = m_preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) ;
PresetCollection & dependent = ( printer_technology = = ptFFF ) ? m_preset_bundle - > filaments : m_preset_bundle - > sla_materials ;
bool old_preset_dirty = dependent . current_is_dirty ( ) ;
bool new_preset_compatible = dependent . get_edited_preset ( ) . is_compatible_with_print ( * m_presets - > find_preset ( preset_name , true ) ) ;
if ( ! canceled )
canceled = old_preset_dirty & & ! new_preset_compatible & & ! may_discard_current_dirty_preset ( & dependent , preset_name ) ;
if ( ! canceled ) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
m_dependent_tabs . emplace_back ( ( printer_technology = = ptFFF ) ? Preset : : Type : : TYPE_FILAMENT : Preset : : Type : : TYPE_SLA_MATERIAL ) ;
if ( old_preset_dirty )
dependent . discard_current_changes ( ) ;
}
2018-08-01 09:09:51 +00:00
} else if ( printer_tab ) {
2018-01-16 15:28:01 +00:00
// Before switching the printer to a new one, verify, whether the currently active print and filament
// are compatible with the new printer.
// If they are not compatible and the current print or filament are dirty, let user decide
// whether to discard the changes or keep the current printer selection.
2018-08-01 09:09:51 +00:00
//
// With the introduction of the SLA printer types, we need to support switching between
// the FFF and SLA printers.
const Preset & new_printer_preset = * m_presets - > find_preset ( preset_name , true ) ;
PrinterTechnology old_printer_technology = m_presets - > get_edited_preset ( ) . printer_technology ( ) ;
PrinterTechnology new_printer_technology = new_printer_preset . printer_technology ( ) ;
2018-11-29 11:33:04 +00:00
if ( new_printer_technology = = ptSLA & & old_printer_technology = = ptFFF & & ! may_switch_to_SLA_preset ( ) )
canceled = true ;
else {
struct PresetUpdate {
Preset : : Type tab_type ;
PresetCollection * presets ;
PrinterTechnology technology ;
bool old_preset_dirty ;
bool new_preset_compatible ;
} ;
std : : vector < PresetUpdate > updates = {
{ Preset : : Type : : TYPE_PRINT , & m_preset_bundle - > prints , ptFFF } ,
{ Preset : : Type : : TYPE_SLA_PRINT , & m_preset_bundle - > sla_prints , ptSLA } ,
{ Preset : : Type : : TYPE_FILAMENT , & m_preset_bundle - > filaments , ptFFF } ,
{ Preset : : Type : : TYPE_SLA_MATERIAL , & m_preset_bundle - > sla_materials , ptSLA }
} ;
for ( PresetUpdate & pu : updates ) {
pu . old_preset_dirty = ( old_printer_technology = = pu . technology ) & & pu . presets - > current_is_dirty ( ) ;
pu . new_preset_compatible = ( new_printer_technology = = pu . technology ) & & pu . presets - > get_edited_preset ( ) . is_compatible_with_printer ( new_printer_preset ) ;
if ( ! canceled )
canceled = pu . old_preset_dirty & & ! pu . new_preset_compatible & & ! may_discard_current_dirty_preset ( pu . presets , preset_name ) ;
}
if ( ! canceled ) {
for ( PresetUpdate & pu : updates ) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
if ( pu . technology = = new_printer_technology )
m_dependent_tabs . emplace_back ( pu . tab_type ) ;
2019-03-04 11:52:30 +00:00
if ( pu . old_preset_dirty & & ! pu . new_preset_compatible )
2018-11-29 11:33:04 +00:00
pu . presets - > discard_current_changes ( ) ;
}
}
}
2018-01-16 15:28:01 +00:00
}
2019-03-22 11:11:23 +00:00
if ( ! canceled & & delete_current ) {
// Delete the file and select some other reasonable preset.
// It does not matter which preset will be made active as the preset will be re-selected from the preset_name variable.
// The 'external' presets will only be removed from the preset list, their files will not be deleted.
try {
m_presets - > delete_current_preset ( ) ;
} catch ( const std : : exception & /* e */ ) {
//FIXME add some error reporting!
canceled = true ;
}
}
2018-01-16 15:28:01 +00:00
if ( canceled ) {
update_tab_ui ( ) ;
// Trigger the on_presets_changed event so that we also restore the previous value in the plater selector,
// if this action was initiated from the platter.
on_presets_changed ( ) ;
2018-08-01 09:09:51 +00:00
} else {
if ( current_dirty )
2018-12-04 16:56:49 +00:00
m_presets - > discard_current_changes ( ) ;
2019-03-22 11:11:23 +00:00
const bool is_selected = m_presets - > select_preset_by_name ( preset_name , false ) | | delete_current ;
assert ( m_presets - > get_edited_preset ( ) . name = = preset_name | | ! is_selected ) ;
2018-01-16 15:28:01 +00:00
// Mark the print & filament enabled if they are compatible with the currently selected preset.
// The following method should not discard changes of current print or filament presets on change of a printer profile,
// if they are compatible with the current printer.
2019-03-22 11:11:23 +00:00
if ( current_dirty | | delete_current | | print_tab | | printer_tab )
2018-12-04 16:56:49 +00:00
m_preset_bundle - > update_compatible ( true ) ;
2018-01-16 15:28:01 +00:00
// Initialize the UI from the current preset.
2018-08-07 09:58:27 +00:00
if ( printer_tab )
static_cast < TabPrinter * > ( this ) - > update_pages ( ) ;
2019-03-15 13:21:32 +00:00
2019-03-22 11:11:23 +00:00
if ( ! is_selected & & printer_tab )
2019-03-15 13:21:32 +00:00
{
/* There is a case, when :
* after Config Wizard applying we try to select previously selected preset , but
* in a current configuration this one :
* 1. doesn ' t exist now ,
* 2. have another printer_technology
* So , it is necessary to update list of dependent tabs
* to the corresponding printer_technology
*/
const PrinterTechnology printer_technology = m_presets - > get_edited_preset ( ) . printer_technology ( ) ;
2019-03-22 11:11:23 +00:00
if ( printer_technology = = ptFFF & & m_dependent_tabs . front ( ) ! = Preset : : Type : : TYPE_PRINT )
m_dependent_tabs = { Preset : : Type : : TYPE_PRINT , Preset : : Type : : TYPE_FILAMENT } ;
else if ( printer_technology = = ptSLA & & m_dependent_tabs . front ( ) ! = Preset : : Type : : TYPE_SLA_PRINT )
m_dependent_tabs = { Preset : : Type : : TYPE_SLA_PRINT , Preset : : Type : : TYPE_SLA_MATERIAL } ;
2019-03-15 13:21:32 +00:00
}
2018-01-26 00:44:34 +00:00
load_current_preset ( ) ;
2018-01-16 15:28:01 +00:00
}
}
// If the current preset is dirty, the user is asked whether the changes may be discarded.
// if the current preset was not dirty, or the user agreed to discard the changes, 1 is returned.
2018-04-13 10:35:04 +00:00
bool Tab : : may_discard_current_dirty_preset ( PresetCollection * presets /*= nullptr*/ , const std : : string & new_printer_name /*= ""*/ )
2018-01-16 15:28:01 +00:00
{
if ( presets = = nullptr ) presets = m_presets ;
// Display a dialog showing the dirty options in a human readable form.
2018-12-04 18:10:31 +00:00
const Preset & old_preset = presets - > get_edited_preset ( ) ;
std : : string type_name = presets - > name ( ) ;
wxString tab = " " ;
wxString name = old_preset . is_default ?
2019-01-21 11:34:28 +00:00
wxString : : Format ( _ ( L ( " Default preset (%s) " ) ) , _ ( type_name ) ) : //_(L("Default ")) + type_name + _(L(" preset")) :
wxString : : Format ( _ ( L ( " Preset (%s) " ) ) , _ ( type_name ) ) + " \n " + tab + old_preset . name ; //type_name + _(L(" preset\n")) + tab + old_preset.name;
2018-01-16 15:28:01 +00:00
// Collect descriptions of the dirty options.
2018-12-04 18:10:31 +00:00
wxString changes ;
for ( const std : : string & opt_key : presets - > current_dirty_options ( ) ) {
const ConfigOptionDef & opt = m_config - > def ( ) - > options . at ( opt_key ) ;
2019-01-21 11:34:28 +00:00
/*std::string*/ wxString name = " " ;
2018-12-04 18:10:31 +00:00
if ( ! opt . category . empty ( ) )
2019-01-21 11:34:28 +00:00
name + = _ ( opt . category ) + " > " ;
2018-01-16 15:28:01 +00:00
name + = ! opt . full_label . empty ( ) ?
2019-01-21 11:34:28 +00:00
_ ( opt . full_label ) :
_ ( opt . label ) ;
changes + = tab + /*from_u8*/ ( name ) + " \n " ;
2018-01-16 15:28:01 +00:00
}
// Show a confirmation dialog with the list of dirty options.
2018-12-04 18:10:31 +00:00
wxString message = name + " \n \n " ;
2018-12-04 16:56:49 +00:00
if ( new_printer_name . empty ( ) )
message + = _ ( L ( " has the following unsaved changes: " ) ) ;
else {
message + = ( m_type = = Slic3r : : Preset : : TYPE_PRINTER ) ?
_ ( L ( " is not compatible with printer " ) ) :
_ ( L ( " is not compatible with print profile " ) ) ;
2018-12-04 18:21:53 +00:00
message + = wxString ( " \n " ) + tab + from_u8 ( new_printer_name ) + " \n \n " ;
2018-12-04 16:56:49 +00:00
message + = _ ( L ( " and it has the following unsaved changes: " ) ) ;
}
2018-01-16 15:28:01 +00:00
auto confirm = new wxMessageDialog ( parent ( ) ,
2019-01-21 11:34:28 +00:00
message + " \n " + changes + " \n \n " + _ ( L ( " Discard changes and continue anyway? " ) ) ,
2018-02-23 08:16:35 +00:00
_ ( L ( " Unsaved Changes " ) ) , wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ) ;
2018-01-16 15:28:01 +00:00
return confirm - > ShowModal ( ) = = wxID_YES ;
}
2018-11-29 11:33:04 +00:00
// If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s).
// Because of we can't to print the multi-part objects with SLA technology.
bool Tab : : may_switch_to_SLA_preset ( )
{
if ( wxGetApp ( ) . obj_list ( ) - > has_multi_part_objects ( ) )
{
show_info ( parent ( ) ,
2019-01-21 11:34:28 +00:00
_ ( L ( " It's impossible to print multi-part object(s) with SLA technology. " ) ) + " \n \n " +
_ ( L ( " Please check your object list before preset changing. " ) ) ,
2018-11-29 11:33:04 +00:00
_ ( L ( " Attention! " ) ) ) ;
return false ;
}
return true ;
}
2018-01-05 14:11:33 +00:00
void Tab : : OnTreeSelChange ( wxTreeEvent & event )
2017-12-13 13:45:10 +00:00
{
2019-04-21 22:17:56 +00:00
if ( m_disable_tree_sel_changed_event )
return ;
2018-06-11 14:56:35 +00:00
// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
# ifdef __linux__
std : : unique_ptr < wxWindowUpdateLocker > no_updates ( new wxWindowUpdateLocker ( this ) ) ;
# else
2019-03-18 11:48:39 +00:00
// wxWindowUpdateLocker noUpdates(this);
2018-06-11 14:56:35 +00:00
# endif
2018-04-17 08:15:48 +00:00
2018-10-23 07:48:01 +00:00
if ( m_pages . empty ( ) )
return ;
2018-01-05 14:11:33 +00:00
Page * page = nullptr ;
2018-09-20 23:33:41 +00:00
const auto sel_item = m_treectrl - > GetSelection ( ) ;
const auto selection = sel_item ? m_treectrl - > GetItemText ( sel_item ) : " " ;
2018-10-23 07:48:01 +00:00
for ( auto p : m_pages )
2017-12-13 13:45:10 +00:00
if ( p - > title ( ) = = selection )
2017-12-05 14:54:01 +00:00
{
2017-12-13 13:45:10 +00:00
page = p . get ( ) ;
2018-03-22 08:37:42 +00:00
m_is_nonsys_values = page - > m_is_nonsys_values ;
m_is_modified_values = page - > m_is_modified_values ;
2017-12-05 14:54:01 +00:00
break ;
}
if ( page = = nullptr ) return ;
2017-12-26 22:04:54 +00:00
for ( auto & el : m_pages )
2019-03-18 11:48:39 +00:00
// if (el.get()->IsShown()) {
el . get ( ) - > Hide ( ) ;
// break;
// }
2018-06-11 14:56:35 +00:00
2019-03-18 11:48:39 +00:00
# ifdef __linux__
no_updates . reset ( nullptr ) ;
# endif
2018-03-22 08:37:42 +00:00
update_undo_buttons ( ) ;
2019-03-18 11:48:39 +00:00
page - > Show ( ) ;
// if (! page->layout_valid) {
page - > layout_valid = true ;
m_hsizer - > Layout ( ) ;
Refresh ( ) ;
// }
2017-12-13 13:45:10 +00:00
}
2017-12-05 14:54:01 +00:00
2018-01-05 14:11:33 +00:00
void Tab : : OnKeyDown ( wxKeyEvent & event )
2017-12-05 14:54:01 +00:00
{
2018-01-21 20:56:20 +00:00
if ( event . GetKeyCode ( ) = = WXK_TAB )
m_treectrl - > Navigate ( event . ShiftDown ( ) ? wxNavigationKeyEvent : : IsBackward : wxNavigationKeyEvent : : IsForward ) ;
else
2017-12-05 14:54:01 +00:00
event . Skip ( ) ;
2018-01-16 15:28:01 +00:00
}
// Save the current preset into file.
// This removes the "dirty" flag of the preset, possibly creates a new preset under a new name,
// and activates the new preset.
// Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method
// opens a Slic3r::GUI::SavePresetWindow dialog.
void Tab : : save_preset ( std : : string name /*= ""*/ )
{
// since buttons(and choices too) don't get focus on Mac, we set focus manually
// to the treectrl so that the EVT_* events are fired for the input field having
// focus currently.is there anything better than this ?
//! m_treectrl->OnSetFocus();
if ( name . empty ( ) ) {
2019-03-22 11:11:23 +00:00
const Preset & preset = m_presets - > get_selected_preset ( ) ;
2018-01-16 15:28:01 +00:00
auto default_name = preset . is_default ? " Untitled " : preset . name ;
2019-03-22 11:11:23 +00:00
if ( preset . is_system ) {
default_name + = " - " ;
default_name + = _ ( L ( " Copy " ) ) . ToUTF8 ( ) . data ( ) ;
}
2018-01-18 10:45:25 +00:00
bool have_extention = boost : : iends_with ( default_name , " .ini " ) ;
2019-03-22 11:11:23 +00:00
if ( have_extention ) {
2018-01-18 10:45:25 +00:00
size_t len = default_name . length ( ) - 4 ;
default_name . resize ( len ) ;
}
//[map $_->name, grep !$_->default && !$_->external, @{$self->{presets}}],
std : : vector < std : : string > values ;
for ( size_t i = 0 ; i < m_presets - > size ( ) ; + + i ) {
const Preset & preset = m_presets - > preset ( i ) ;
2018-03-09 15:37:33 +00:00
if ( preset . is_default | | preset . is_system | | preset . is_external )
2018-01-18 10:45:25 +00:00
continue ;
values . push_back ( preset . name ) ;
}
auto dlg = new SavePresetWindow ( parent ( ) ) ;
dlg - > build ( title ( ) , default_name , values ) ;
if ( dlg - > ShowModal ( ) ! = wxID_OK )
return ;
name = dlg - > get_name ( ) ;
2018-10-31 11:56:08 +00:00
if ( name = = " " ) {
2018-02-23 08:16:35 +00:00
show_error ( this , _ ( L ( " The supplied name is empty. It can't be saved. " ) ) ) ;
2018-01-18 10:45:25 +00:00
return ;
}
2018-03-09 15:37:33 +00:00
const Preset * existing = m_presets - > find_preset ( name , false ) ;
if ( existing & & ( existing - > is_default | | existing - > is_system ) ) {
show_error ( this , _ ( L ( " Cannot overwrite a system profile. " ) ) ) ;
return ;
}
if ( existing & & ( existing - > is_external ) ) {
2018-05-14 10:59:19 +00:00
show_error ( this , _ ( L ( " Cannot overwrite an external profile. " ) ) ) ;
2018-03-09 15:37:33 +00:00
return ;
}
2018-01-16 15:28:01 +00:00
}
2018-02-16 14:41:33 +00:00
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
m_presets - > save_current_preset ( name ) ;
2018-01-16 15:28:01 +00:00
// Mark the print & filament enabled if they are compatible with the currently selected preset.
2018-12-04 16:56:49 +00:00
m_preset_bundle - > update_compatible ( false ) ;
2018-01-16 15:28:01 +00:00
// Add the new item into the UI component, remove dirty flags and activate the saved item.
update_tab_ui ( ) ;
// Update the selection boxes at the platter.
on_presets_changed ( ) ;
2018-07-03 10:19:34 +00:00
// If current profile is saved, "delete preset" button have to be enabled
m_btn_delete_preset - > Enable ( true ) ;
2018-03-16 11:56:03 +00:00
2019-03-22 11:11:23 +00:00
if ( m_type = = Preset : : TYPE_PRINTER )
2018-03-19 16:21:37 +00:00
static_cast < TabPrinter * > ( this ) - > m_initial_extruders_count = static_cast < TabPrinter * > ( this ) - > m_extruders_count ;
2018-03-16 11:56:03 +00:00
update_changed_ui ( ) ;
2018-01-16 15:28:01 +00:00
}
// Called for a currently selected preset.
2018-01-18 10:45:25 +00:00
void Tab : : delete_preset ( )
2018-01-16 15:28:01 +00:00
{
auto current_preset = m_presets - > get_selected_preset ( ) ;
// Don't let the user delete the ' - default - ' configuration.
2018-02-23 08:16:35 +00:00
wxString action = current_preset . is_external ? _ ( L ( " remove " ) ) : _ ( L ( " delete " ) ) ;
wxString msg = _ ( L ( " Are you sure you want to " ) ) + action + _ ( L ( " the selected preset? " ) ) ;
action = current_preset . is_external ? _ ( L ( " Remove " ) ) : _ ( L ( " Delete " ) ) ;
wxString title = action + _ ( L ( " Preset " ) ) ;
2018-01-16 15:28:01 +00:00
if ( current_preset . is_default | |
2018-02-13 15:05:53 +00:00
wxID_YES ! = wxMessageDialog ( parent ( ) , msg , title , wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ) . ShowModal ( ) )
2018-01-16 15:28:01 +00:00
return ;
2019-03-22 11:11:23 +00:00
// Select will handle of the preset dependencies, of saving & closing the depending profiles, and
// finally of deleting the preset.
this - > select_preset ( " " , true ) ;
2018-01-16 15:28:01 +00:00
}
2017-12-05 14:54:01 +00:00
2018-01-18 10:45:25 +00:00
void Tab : : toggle_show_hide_incompatible ( )
2018-01-16 15:28:01 +00:00
{
m_show_incompatible_presets = ! m_show_incompatible_presets ;
update_show_hide_incompatible_button ( ) ;
update_tab_ui ( ) ;
}
2017-12-05 14:54:01 +00:00
2018-01-16 15:28:01 +00:00
void Tab : : update_show_hide_incompatible_button ( )
{
2019-04-13 21:46:52 +00:00
m_btn_hide_incompatible_presets - > SetBitmap_ ( m_show_incompatible_presets ?
2018-04-16 09:03:08 +00:00
m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets ) ;
2018-01-16 15:28:01 +00:00
m_btn_hide_incompatible_presets - > SetToolTip ( m_show_incompatible_presets ?
" Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer. " :
" Only compatible presets are shown. Click to show both the presets compatible and not compatible with the current printer. " ) ;
}
void Tab : : update_ui_from_settings ( )
{
// Show the 'show / hide presets' button only for the print and filament tabs, and only if enabled
// in application preferences.
2018-09-20 23:33:41 +00:00
m_show_btn_incompatible_presets = wxGetApp ( ) . app_config - > get ( " show_incompatible_presets " ) [ 0 ] = = ' 1 ' ? true : false ;
2018-12-04 16:56:49 +00:00
bool show = m_show_btn_incompatible_presets & & m_type ! = Slic3r : : Preset : : TYPE_PRINTER ;
2018-11-16 10:14:56 +00:00
Layout ( ) ;
2018-01-16 15:28:01 +00:00
show ? m_btn_hide_incompatible_presets - > Show ( ) : m_btn_hide_incompatible_presets - > Hide ( ) ;
// If the 'show / hide presets' button is hidden, hide the incompatible presets.
if ( show ) {
update_show_hide_incompatible_button ( ) ;
}
else {
if ( m_show_incompatible_presets ) {
m_show_incompatible_presets = false ;
update_tab_ui ( ) ;
}
}
}
// Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
2018-12-04 16:56:49 +00:00
wxSizer * Tab : : compatible_widget_create ( wxWindow * parent , PresetDependencies & deps )
2017-12-19 10:59:42 +00:00
{
2018-12-04 16:56:49 +00:00
deps . checkbox = new wxCheckBox ( parent , wxID_ANY , _ ( L ( " All " ) ) ) ;
2019-03-18 19:54:01 +00:00
deps . checkbox - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2019-04-13 21:46:52 +00:00
add_scaled_button ( parent , & deps . btn , " printer_white " , _ ( L ( " Set " ) ) + dots , wxBU_LEFT | wxBU_EXACTFIT ) ;
deps . btn - > SetFont ( Slic3r : : GUI : : wxGetApp ( ) . normal_font ( ) ) ;
2018-01-15 11:13:05 +00:00
2017-12-19 10:59:42 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2018-12-04 16:56:49 +00:00
sizer - > Add ( ( deps . checkbox ) , 0 , wxALIGN_CENTER_VERTICAL ) ;
sizer - > Add ( ( deps . btn ) , 0 , wxALIGN_CENTER_VERTICAL ) ;
2017-12-19 10:59:42 +00:00
2018-12-04 16:56:49 +00:00
deps . checkbox - > Bind ( wxEVT_CHECKBOX , ( [ this , & deps ] ( wxCommandEvent e )
2017-12-19 10:59:42 +00:00
{
2018-12-04 16:56:49 +00:00
deps . btn - > Enable ( ! deps . checkbox - > GetValue ( ) ) ;
2018-01-12 11:41:13 +00:00
// All printers have been made compatible with this preset.
2018-12-04 16:56:49 +00:00
if ( deps . checkbox - > GetValue ( ) )
this - > load_key_value ( deps . key_list , std : : vector < std : : string > { } ) ;
this - > get_field ( deps . key_condition ) - > toggle ( deps . checkbox - > GetValue ( ) ) ;
this - > update_changed_ui ( ) ;
2017-12-19 10:59:42 +00:00
} ) ) ;
2018-12-04 16:56:49 +00:00
deps . btn - > Bind ( wxEVT_BUTTON , ( [ this , parent , & deps ] ( wxCommandEvent e )
2017-12-19 10:59:42 +00:00
{
2018-12-04 16:56:49 +00:00
// Collect names of non-default non-external profiles.
PrinterTechnology printer_technology = m_preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) ;
PresetCollection & depending_presets = ( deps . type = = Preset : : TYPE_PRINTER ) ? m_preset_bundle - > printers :
( printer_technology = = ptFFF ) ? m_preset_bundle - > prints : m_preset_bundle - > sla_prints ;
2017-12-19 10:59:42 +00:00
wxArrayString presets ;
2018-12-04 16:56:49 +00:00
for ( size_t idx = 0 ; idx < depending_presets . size ( ) ; + + idx )
2017-12-19 10:59:42 +00:00
{
2018-12-04 16:56:49 +00:00
Preset & preset = depending_presets . preset ( idx ) ;
bool add = ! preset . is_default & & ! preset . is_external ;
if ( add & & deps . type = = Preset : : TYPE_PRINTER )
// Only add printers with the same technology as the active printer.
add & = preset . printer_technology ( ) = = printer_technology ;
if ( add )
presets . Add ( from_u8 ( preset . name ) ) ;
2017-12-19 10:59:42 +00:00
}
2018-12-04 16:56:49 +00:00
wxMultiChoiceDialog dlg ( parent , deps . dialog_title , deps . dialog_label , presets ) ;
// Collect and set indices of depending_presets marked as compatible.
2017-12-19 10:59:42 +00:00
wxArrayInt selections ;
2018-12-04 16:56:49 +00:00
auto * compatible_printers = dynamic_cast < const ConfigOptionStrings * > ( m_config - > option ( deps . key_list ) ) ;
2017-12-19 10:59:42 +00:00
if ( compatible_printers ! = nullptr | | ! compatible_printers - > values . empty ( ) )
for ( auto preset_name : compatible_printers - > values )
for ( size_t idx = 0 ; idx < presets . GetCount ( ) ; + + idx )
2018-12-04 16:56:49 +00:00
if ( presets [ idx ] = = preset_name ) {
2017-12-19 10:59:42 +00:00
selections . Add ( idx ) ;
break ;
}
2018-04-11 10:21:15 +00:00
dlg . SetSelections ( selections ) ;
2018-01-12 11:41:13 +00:00
std : : vector < std : : string > value ;
// Show the dialog.
2018-04-11 10:21:15 +00:00
if ( dlg . ShowModal ( ) = = wxID_OK ) {
2017-12-19 10:59:42 +00:00
selections . Clear ( ) ;
2018-04-11 10:21:15 +00:00
selections = dlg . GetSelections ( ) ;
2017-12-19 10:59:42 +00:00
for ( auto idx : selections )
2019-01-03 13:34:53 +00:00
value . push_back ( presets [ idx ] . ToUTF8 ( ) . data ( ) ) ;
2018-01-12 11:41:13 +00:00
if ( value . empty ( ) ) {
2018-12-04 16:56:49 +00:00
deps . checkbox - > SetValue ( 1 ) ;
deps . btn - > Disable ( ) ;
2017-12-19 10:59:42 +00:00
}
2018-12-04 16:56:49 +00:00
// All depending_presets have been made compatible with this preset.
this - > load_key_value ( deps . key_list , value ) ;
this - > update_changed_ui ( ) ;
2017-12-19 10:59:42 +00:00
}
} ) ) ;
2018-12-04 16:56:49 +00:00
return sizer ;
}
void Tab : : compatible_widget_reload ( PresetDependencies & deps )
{
bool has_any = ! m_config - > option < ConfigOptionStrings > ( deps . key_list ) - > values . empty ( ) ;
has_any ? deps . btn - > Enable ( ) : deps . btn - > Disable ( ) ;
deps . checkbox - > SetValue ( ! has_any ) ;
this - > get_field ( deps . key_condition ) - > toggle ( ! has_any ) ;
2017-12-19 10:59:42 +00:00
}
2018-04-20 10:58:07 +00:00
void Tab : : fill_icon_descriptions ( )
{
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_value_lock , L ( " LOCKED LOCK; "
2018-04-24 06:49:37 +00:00
" indicates that the settings are the same as the system values for the current option group " ) ) ) ;
2018-04-20 10:58:07 +00:00
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_value_unlock , L ( " UNLOCKED LOCK; "
2018-04-24 06:49:37 +00:00
" indicates that some settings were changed and are not equal to the system values for "
" the current option group. \n "
" Click the UNLOCKED LOCK icon to reset all settings for current option group to "
" the system values. " ) ) ) ;
2018-04-20 10:58:07 +00:00
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_white_bullet , L ( " WHITE BULLET; "
2018-04-24 06:49:37 +00:00
" for the left button: \t indicates a non-system preset, \n "
" for the right button: \t indicates that the settings hasn't been modified. " ) ) ) ;
2018-04-20 10:58:07 +00:00
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_value_revert , L ( " BACK ARROW; "
2018-04-24 06:49:37 +00:00
" indicates that the settings were changed and are not equal to the last saved preset for "
" the current option group. \n "
" Click the BACK ARROW icon to reset all settings for the current option group to "
" the last saved preset. " ) ) ) ;
2018-04-20 10:58:07 +00:00
}
2018-04-24 12:11:23 +00:00
void Tab : : set_tooltips_text ( )
{
// m_undo_to_sys_btn->SetToolTip(_(L( "LOCKED LOCK icon indicates that the settings are the same as the system values "
// "for the current option group.\n"
// "UNLOCKED LOCK icon indicates that some settings were changed and are not equal "
// "to the system values for the current option group.\n"
// "WHITE BULLET icon indicates a non system preset.\n\n"
// "Click the UNLOCKED LOCK icon to reset all settings for current option group to "
// "the system values.")));
//
// m_undo_btn->SetToolTip(_(L( "WHITE BULLET icon indicates that the settings are the same as in the last saved"
// "preset for the current option group.\n"
// "BACK ARROW icon indicates that the settings were changed and are not equal to "
// "the last saved preset for the current option group.\n\n"
// "Click the BACK ARROW icon to reset all settings for the current option group to "
// "the last saved preset.")));
// --- Tooltip text for reset buttons (for whole options group)
// Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
m_ttg_value_lock = _ ( L ( " LOCKED LOCK icon indicates that the settings are the same as the system values "
" for the current option group " ) ) ;
m_ttg_value_unlock = _ ( L ( " UNLOCKED LOCK icon indicates that some settings were changed and are not equal "
" to the system values for the current option group. \n "
" Click to reset all settings for current option group to the system values. " ) ) ;
m_ttg_white_bullet_ns = _ ( L ( " WHITE BULLET icon indicates a non system preset. " ) ) ;
m_ttg_non_system = & m_ttg_white_bullet_ns ;
// Text to be shown on the "Undo user changes" button next to each input field.
m_ttg_white_bullet = _ ( L ( " WHITE BULLET icon indicates that the settings are the same as in the last saved "
" preset for the current option group. " ) ) ;
m_ttg_value_revert = _ ( L ( " BACK ARROW icon indicates that the settings were changed and are not equal to "
" the last saved preset for the current option group. \n "
" Click to reset all settings for the current option group to the last saved preset. " ) ) ;
// --- Tooltip text for reset buttons (for each option in group)
// Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
m_tt_value_lock = _ ( L ( " LOCKED LOCK icon indicates that the value is the same as the system value. " ) ) ;
m_tt_value_unlock = _ ( L ( " UNLOCKED LOCK icon indicates that the value was changed and is not equal "
" to the system value. \n "
" Click to reset current value to the system value. " ) ) ;
// m_tt_white_bullet_ns= _(L("WHITE BULLET icon indicates a non system preset."));
m_tt_non_system = & m_ttg_white_bullet_ns ;
// Text to be shown on the "Undo user changes" button next to each input field.
m_tt_white_bullet = _ ( L ( " WHITE BULLET icon indicates that the value is the same as in the last saved preset. " ) ) ;
m_tt_value_revert = _ ( L ( " BACK ARROW icon indicates that the value was changed and is not equal to the last saved preset. \n "
" Click to reset current value to the last saved preset. " ) ) ;
}
2018-01-11 09:33:17 +00:00
void Page : : reload_config ( )
{
for ( auto group : m_optgroups )
group - > reload_config ( ) ;
}
2018-10-19 11:55:29 +00:00
void Page : : update_visibility ( ConfigOptionMode mode )
{
2018-10-21 21:09:24 +00:00
bool ret_val = false ;
for ( auto group : m_optgroups )
ret_val = group - > update_visibility ( mode ) | | ret_val ;
m_show = ret_val ;
2018-10-19 11:55:29 +00:00
}
2019-04-24 23:45:00 +00:00
void Page : : msw_rescale ( )
2019-04-13 21:46:52 +00:00
{
for ( auto group : m_optgroups )
2019-04-24 23:45:00 +00:00
group - > msw_rescale ( ) ;
2019-04-13 21:46:52 +00:00
}
2018-04-13 10:35:04 +00:00
Field * Page : : get_field ( const t_config_option_key & opt_key , int opt_index /*= -1*/ ) const
2018-01-11 09:33:17 +00:00
{
Field * field = nullptr ;
2018-10-31 11:56:08 +00:00
for ( auto opt : m_optgroups ) {
2018-01-11 09:33:17 +00:00
field = opt - > get_fieldc ( opt_key , opt_index ) ;
if ( field ! = nullptr )
return field ;
}
return field ;
}
2018-10-31 11:56:08 +00:00
bool Page : : set_value ( const t_config_option_key & opt_key , const boost : : any & value ) {
2018-01-16 15:28:01 +00:00
bool changed = false ;
for ( auto optgroup : m_optgroups ) {
if ( optgroup - > set_value ( opt_key , value ) )
changed = 1 ;
}
return changed ;
}
2017-12-13 13:45:10 +00:00
// package Slic3r::GUI::Tab::Page;
2018-04-13 10:35:04 +00:00
ConfigOptionsGroupShp Page : : new_optgroup ( const wxString & title , int noncommon_label_width /*= -1*/ )
2017-12-13 13:45:10 +00:00
{
2019-04-13 21:46:52 +00:00
auto extra_column = [ this ] ( wxWindow * parent , const Line & line )
2018-10-19 11:55:29 +00:00
{
std : : string bmp_name ;
2018-12-21 08:19:00 +00:00
const std : : vector < Option > & options = line . get_options ( ) ;
2019-04-16 12:06:09 +00:00
int mode_id = int ( options [ 0 ] . opt . mode ) ;
2019-04-13 21:46:52 +00:00
const wxBitmap & bitmap = options . size ( ) = = 0 | | options [ 0 ] . opt . gui_type = = " legend " ? wxNullBitmap :
2019-04-16 12:06:09 +00:00
m_mode_bitmap_cache [ mode_id ] . bmp ( ) ;
2019-04-13 21:46:52 +00:00
auto bmp = new wxStaticBitmap ( parent , wxID_ANY , bitmap ) ;
2019-04-16 12:06:09 +00:00
bmp - > SetClientData ( ( void * ) & m_mode_bitmap_cache [ mode_id ] ) ;
2019-04-13 21:46:52 +00:00
2019-03-18 11:48:39 +00:00
bmp - > SetBackgroundStyle ( wxBG_STYLE_PAINT ) ;
2018-10-19 11:55:29 +00:00
return bmp ;
} ;
2017-12-13 13:45:10 +00:00
//! config_ have to be "right"
2018-10-19 11:55:29 +00:00
ConfigOptionsGroupShp optgroup = std : : make_shared < ConfigOptionsGroup > ( this , title , m_config , true , extra_column ) ;
2017-12-22 10:50:28 +00:00
if ( noncommon_label_width > = 0 )
optgroup - > label_width = noncommon_label_width ;
2017-12-13 13:45:10 +00:00
2018-07-02 11:51:50 +00:00
# ifdef __WXOSX__
auto tab = GetParent ( ) - > GetParent ( ) ;
# else
auto tab = GetParent ( ) ;
# endif
2018-10-31 11:56:08 +00:00
optgroup - > m_on_change = [ this , tab ] ( t_config_option_key opt_key , boost : : any value ) {
2018-01-18 15:36:26 +00:00
//! This function will be called from OptionGroup.
//! Using of CallAfter is redundant.
2018-01-26 00:44:34 +00:00
//! And in some cases it causes update() function to be recalled again
2018-01-18 15:36:26 +00:00
//! wxTheApp->CallAfter([this, opt_key, value]() {
2018-07-02 11:51:50 +00:00
static_cast < Tab * > ( tab ) - > update_dirty ( ) ;
static_cast < Tab * > ( tab ) - > on_value_change ( opt_key , value ) ;
2018-01-18 15:36:26 +00:00
//! });
} ;
2017-12-13 13:45:10 +00:00
2018-10-31 11:56:08 +00:00
optgroup - > m_get_initial_config = [ this , tab ] ( ) {
2018-07-02 11:51:50 +00:00
DynamicPrintConfig config = static_cast < Tab * > ( tab ) - > m_presets - > get_selected_preset ( ) . config ;
2018-03-06 11:34:20 +00:00
return config ;
} ;
2018-10-31 11:56:08 +00:00
optgroup - > m_get_sys_config = [ this , tab ] ( ) {
2018-07-02 11:51:50 +00:00
DynamicPrintConfig config = static_cast < Tab * > ( tab ) - > m_presets - > get_selected_preset_parent ( ) - > config ;
2018-03-16 16:25:11 +00:00
return config ;
} ;
2018-10-31 11:56:08 +00:00
optgroup - > have_sys_config = [ this , tab ] ( ) {
2018-07-02 11:51:50 +00:00
return static_cast < Tab * > ( tab ) - > m_presets - > get_selected_preset_parent ( ) ! = nullptr ;
2018-03-16 16:25:11 +00:00
} ;
2019-04-16 08:05:45 +00:00
optgroup - > rescale_extra_column_item = [ this ] ( wxWindow * win ) {
2019-04-13 21:46:52 +00:00
auto * ctrl = dynamic_cast < wxStaticBitmap * > ( win ) ;
if ( ctrl = = nullptr )
return ;
2019-04-24 23:45:00 +00:00
ctrl - > SetBitmap ( reinterpret_cast < ScalableBitmap * > ( ctrl - > GetClientData ( ) ) - > bmp ( ) ) ;
2019-04-13 21:46:52 +00:00
} ;
2017-12-13 13:45:10 +00:00
vsizer ( ) - > Add ( optgroup - > sizer , 0 , wxEXPAND | wxALL , 10 ) ;
2017-12-26 22:04:54 +00:00
m_optgroups . push_back ( optgroup ) ;
2017-12-13 13:45:10 +00:00
return optgroup ;
}
2018-04-13 10:35:04 +00:00
void SavePresetWindow : : build ( const wxString & title , const std : : string & default_name , std : : vector < std : : string > & values )
2018-01-18 10:45:25 +00:00
{
2018-02-23 08:16:35 +00:00
auto text = new wxStaticText ( this , wxID_ANY , _ ( L ( " Save " ) ) + title + _ ( L ( " as: " ) ) ,
2018-02-08 09:58:13 +00:00
wxDefaultPosition , wxDefaultSize ) ;
2018-02-22 10:34:41 +00:00
m_combo = new wxComboBox ( this , wxID_ANY , from_u8 ( default_name ) ,
2018-02-05 10:03:13 +00:00
wxDefaultPosition , wxDefaultSize , 0 , 0 , wxTE_PROCESS_ENTER ) ;
2018-01-18 10:45:25 +00:00
for ( auto value : values )
2018-02-22 10:34:41 +00:00
m_combo - > Append ( from_u8 ( value ) ) ;
2018-01-18 10:45:25 +00:00
auto buttons = CreateStdDialogButtonSizer ( wxOK | wxCANCEL ) ;
auto sizer = new wxBoxSizer ( wxVERTICAL ) ;
sizer - > Add ( text , 0 , wxEXPAND | wxALL , 10 ) ;
sizer - > Add ( m_combo , 0 , wxEXPAND | wxLEFT | wxRIGHT , 10 ) ;
sizer - > Add ( buttons , 0 , wxALIGN_CENTER_HORIZONTAL | wxALL , 10 ) ;
wxButton * btn = static_cast < wxButton * > ( FindWindowById ( wxID_OK , this ) ) ;
btn - > Bind ( wxEVT_BUTTON , [ this ] ( wxCommandEvent & ) { accept ( ) ; } ) ;
m_combo - > Bind ( wxEVT_TEXT_ENTER , [ this ] ( wxCommandEvent & ) { accept ( ) ; } ) ;
SetSizer ( sizer ) ;
sizer - > SetSizeHints ( this ) ;
}
void SavePresetWindow : : accept ( )
{
2018-02-05 10:03:13 +00:00
m_chosen_name = normalize_utf8_nfc ( m_combo - > GetValue ( ) . ToUTF8 ( ) ) ;
2018-01-18 10:45:25 +00:00
if ( ! m_chosen_name . empty ( ) ) {
const char * unusable_symbols = " <>:/ \\ |?* \" " ;
bool is_unusable_symbol = false ;
2018-06-25 09:40:40 +00:00
bool is_unusable_postfix = false ;
2018-07-23 13:44:01 +00:00
const std : : string unusable_postfix = PresetCollection : : get_suffix_modified ( ) ; //"(modified)";
2018-10-31 11:56:08 +00:00
for ( size_t i = 0 ; i < std : : strlen ( unusable_symbols ) ; i + + ) {
if ( m_chosen_name . find_first_of ( unusable_symbols [ i ] ) ! = std : : string : : npos ) {
2018-01-18 10:45:25 +00:00
is_unusable_symbol = true ;
break ;
}
}
2018-06-25 09:40:40 +00:00
if ( m_chosen_name . find ( unusable_postfix ) ! = std : : string : : npos )
is_unusable_postfix = true ;
2018-01-18 10:45:25 +00:00
if ( is_unusable_symbol ) {
2018-06-25 09:40:40 +00:00
show_error ( this , _ ( L ( " The supplied name is not valid; " ) ) + " \n " +
_ ( L ( " the following characters are not allowed: " ) ) + " <>:/ \\ |?* \" " ) ;
}
2018-10-31 11:56:08 +00:00
else if ( is_unusable_postfix ) {
2018-07-23 13:44:01 +00:00
show_error ( this , _ ( L ( " The supplied name is not valid; " ) ) + " \n " +
_ ( L ( " the following postfix are not allowed: " ) ) + " \n \t " + //unusable_postfix);
wxString : : FromUTF8 ( unusable_postfix . c_str ( ) ) ) ;
2018-01-18 10:45:25 +00:00
}
2018-12-04 16:56:49 +00:00
else if ( m_chosen_name = = " - default - " ) {
2018-02-23 08:16:35 +00:00
show_error ( this , _ ( L ( " The supplied name is not available. " ) ) ) ;
2018-01-18 10:45:25 +00:00
}
else {
EndModal ( wxID_OK ) ;
}
}
}
2018-08-03 11:04:41 +00:00
void TabSLAMaterial : : build ( )
{
m_presets = & m_preset_bundle - > sla_materials ;
load_initial_data ( ) ;
2019-04-10 07:41:04 +00:00
auto page = add_options_page ( _ ( L ( " Material " ) ) , " resin " ) ;
2018-08-03 11:04:41 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Layers " ) ) ) ;
2018-11-16 16:36:23 +00:00
// optgroup->append_single_option_line("layer_height");
2018-08-03 11:04:41 +00:00
optgroup - > append_single_option_line ( " initial_layer_height " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Exposure " ) ) ) ;
optgroup - > append_single_option_line ( " exposure_time " ) ;
optgroup - > append_single_option_line ( " initial_exposure_time " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Corrections " ) ) ) ;
2019-04-13 21:46:52 +00:00
optgroup - > label_width = 19 ; //190;
2019-04-03 15:34:46 +00:00
std : : vector < std : : string > corrections = { " material_correction " } ;
2019-04-11 15:07:41 +00:00
// std::vector<std::string> axes{ "X", "Y", "Z" };
std : : vector < std : : string > axes { " XY " , " Z " } ;
2018-10-31 11:56:08 +00:00
for ( auto & opt_key : corrections ) {
2018-08-03 14:20:39 +00:00
auto line = Line { m_config - > def ( ) - > get ( opt_key ) - > full_label , " " } ;
int id = 0 ;
for ( auto & axis : axes ) {
auto opt = optgroup - > get_option ( opt_key , id ) ;
opt . opt . label = axis ;
2019-04-13 21:46:52 +00:00
opt . opt . width = 6 ;
2018-08-03 14:20:39 +00:00
line . append_option ( opt ) ;
+ + id ;
}
optgroup - > append_line ( line ) ;
}
2018-08-03 11:04:41 +00:00
page = add_options_page ( _ ( L ( " Notes " ) ) , " note.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Notes " ) ) , 0 ) ;
optgroup - > label_width = 0 ;
Option option = optgroup - > get_option ( " material_notes " ) ;
option . opt . full_width = true ;
2019-04-13 21:46:52 +00:00
option . opt . height = 25 ; //250;
2018-08-03 11:04:41 +00:00
optgroup - > append_single_option_line ( option ) ;
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
2018-12-04 16:56:49 +00:00
Line line = optgroup - > create_single_option_line ( " compatible_printers " ) ;
2018-10-31 11:56:08 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-12-04 16:56:49 +00:00
return compatible_widget_create ( parent , m_compatible_printers ) ;
2018-08-03 11:04:41 +00:00
} ;
optgroup - > append_line ( line , & m_colored_Label ) ;
option = optgroup - > get_option ( " compatible_printers_condition " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2018-12-04 16:56:49 +00:00
line = optgroup - > create_single_option_line ( " compatible_prints " ) ;
line . widget = [ this ] ( wxWindow * parent ) {
return compatible_widget_create ( parent , m_compatible_prints ) ;
} ;
optgroup - > append_line ( line , & m_colored_Label ) ;
option = optgroup - > get_option ( " compatible_prints_condition " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2018-08-03 11:04:41 +00:00
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
}
2018-12-04 16:56:49 +00:00
// Reload current config (aka presets->edited_preset->config) into the UI fields.
void TabSLAMaterial : : reload_config ( )
{
this - > compatible_widget_reload ( m_compatible_printers ) ;
this - > compatible_widget_reload ( m_compatible_prints ) ;
Tab : : reload_config ( ) ;
}
2018-08-03 11:04:41 +00:00
void TabSLAMaterial : : update ( )
{
2018-10-04 14:43:10 +00:00
if ( m_preset_bundle - > printers . get_selected_preset ( ) . printer_technology ( ) = = ptFFF )
2018-11-16 16:36:23 +00:00
return ; // #ys_FIXME
2019-02-22 08:38:56 +00:00
// #ys_FIXME
// m_update_cnt++;
// ! something to update
// m_update_cnt--;
//
// if (m_update_cnt == 0)
wxGetApp ( ) . mainframe - > on_config_changed ( m_config ) ;
2018-11-16 16:36:23 +00:00
}
void TabSLAPrint : : build ( )
{
m_presets = & m_preset_bundle - > sla_prints ;
load_initial_data ( ) ;
2019-04-08 07:37:23 +00:00
auto page = add_options_page ( _ ( L ( " Layers and perimeters " ) ) , " layers " ) ;
2018-11-16 16:36:23 +00:00
auto optgroup = page - > new_optgroup ( _ ( L ( " Layers " ) ) ) ;
optgroup - > append_single_option_line ( " layer_height " ) ;
2019-02-18 15:04:55 +00:00
optgroup - > append_single_option_line ( " faded_layers " ) ;
2018-11-16 16:36:23 +00:00
2019-04-12 15:10:04 +00:00
page = add_options_page ( _ ( L ( " Supports " ) ) , " support " /*"sla_supports"*/ ) ;
2018-11-22 17:02:05 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Supports " ) ) ) ;
optgroup - > append_single_option_line ( " supports_enable " ) ;
2018-11-19 08:15:53 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Support head " ) ) ) ;
2018-11-23 12:03:07 +00:00
optgroup - > append_single_option_line ( " support_head_front_diameter " ) ;
2018-11-19 08:15:53 +00:00
optgroup - > append_single_option_line ( " support_head_penetration " ) ;
optgroup - > append_single_option_line ( " support_head_width " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Support pillar " ) ) ) ;
2018-11-23 12:03:07 +00:00
optgroup - > append_single_option_line ( " support_pillar_diameter " ) ;
2019-01-09 11:21:43 +00:00
optgroup - > append_single_option_line ( " support_pillar_connection_mode " ) ;
2019-02-05 10:16:03 +00:00
optgroup - > append_single_option_line ( " support_buildplate_only " ) ;
2019-03-11 13:55:28 +00:00
// TODO: This parameter is not used at the moment.
// optgroup->append_single_option_line("support_pillar_widening_factor");
2018-11-23 12:03:07 +00:00
optgroup - > append_single_option_line ( " support_base_diameter " ) ;
2018-11-19 08:15:53 +00:00
optgroup - > append_single_option_line ( " support_base_height " ) ;
2018-11-19 16:58:08 +00:00
optgroup - > append_single_option_line ( " support_object_elevation " ) ;
2018-11-19 08:15:53 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Connection of the support sticks and junctions " ) ) ) ;
optgroup - > append_single_option_line ( " support_critical_angle " ) ;
optgroup - > append_single_option_line ( " support_max_bridge_length " ) ;
2019-03-08 10:39:34 +00:00
optgroup - > append_single_option_line ( " support_max_pillar_link_distance " ) ;
2018-11-19 08:15:53 +00:00
2018-12-07 13:10:16 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Automatic generation " ) ) ) ;
2019-02-19 15:34:52 +00:00
optgroup - > append_single_option_line ( " support_points_density_relative " ) ;
optgroup - > append_single_option_line ( " support_points_minimal_distance " ) ;
2018-12-07 13:10:16 +00:00
2019-04-12 15:10:04 +00:00
page = add_options_page ( _ ( L ( " Pad " ) ) , " pad " ) ;
2018-11-19 08:15:53 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Pad " ) ) ) ;
2018-11-20 15:12:04 +00:00
optgroup - > append_single_option_line ( " pad_enable " ) ;
2018-11-19 08:15:53 +00:00
optgroup - > append_single_option_line ( " pad_wall_thickness " ) ;
optgroup - > append_single_option_line ( " pad_wall_height " ) ;
optgroup - > append_single_option_line ( " pad_max_merge_distance " ) ;
2019-02-25 11:06:38 +00:00
// TODO: Disabling this parameter for the beta release
// optgroup->append_single_option_line("pad_edge_radius");
2019-02-25 15:04:46 +00:00
optgroup - > append_single_option_line ( " pad_wall_slope " ) ;
2018-11-19 08:15:53 +00:00
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Advanced " ) ) , " wrench " ) ;
2019-03-01 16:53:02 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Slicing " ) ) ) ;
optgroup - > append_single_option_line ( " slice_closing_radius " ) ;
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Output options " ) ) , " output+page_white " ) ;
2018-12-03 12:14:28 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Output file " ) ) ) ;
Option option = optgroup - > get_option ( " output_filename_format " ) ;
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
2019-04-08 07:37:23 +00:00
page = add_options_page ( _ ( L ( " Dependencies " ) ) , " wrench " ) ;
2018-11-16 16:36:23 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Profile dependencies " ) ) ) ;
Line line = optgroup - > create_single_option_line ( " compatible_printers " ) ; //Line { _(L("Compatible printers")), "" };
line . widget = [ this ] ( wxWindow * parent ) {
2018-12-04 16:56:49 +00:00
return compatible_widget_create ( parent , m_compatible_printers ) ;
2018-11-16 16:36:23 +00:00
} ;
optgroup - > append_line ( line , & m_colored_Label ) ;
2018-12-03 12:14:28 +00:00
option = optgroup - > get_option ( " compatible_printers_condition " ) ;
2018-11-16 16:36:23 +00:00
option . opt . full_width = true ;
optgroup - > append_single_option_line ( option ) ;
line = Line { " " , " " } ;
line . full_width = 1 ;
line . widget = [ this ] ( wxWindow * parent ) {
return description_line_widget ( parent , & m_parent_preset_description_line ) ;
} ;
optgroup - > append_line ( line ) ;
}
2018-12-04 16:56:49 +00:00
// Reload current config (aka presets->edited_preset->config) into the UI fields.
void TabSLAPrint : : reload_config ( )
{
this - > compatible_widget_reload ( m_compatible_printers ) ;
Tab : : reload_config ( ) ;
}
2018-11-16 16:36:23 +00:00
void TabSLAPrint : : update ( )
{
if ( m_preset_bundle - > printers . get_selected_preset ( ) . printer_technology ( ) = = ptFFF )
return ; // #ys_FIXME
2019-02-22 08:38:56 +00:00
// #ys_FIXME
2019-03-11 15:27:54 +00:00
m_update_cnt + + ;
double head_penetration = m_config - > opt_float ( " support_head_penetration " ) ;
double head_width = m_config - > opt_float ( " support_head_width " ) ;
if ( head_penetration > head_width ) {
wxString msg_text = _ ( L ( " Head penetration should not be greater than the head width. " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Invalid Head penetration " ) ) , wxICON_WARNING | wxOK ) ;
DynamicPrintConfig new_conf = * m_config ;
if ( dialog - > ShowModal ( ) = = wxID_OK ) {
new_conf . set_key_value ( " support_head_penetration " , new ConfigOptionFloat ( head_width ) ) ;
}
load_config ( new_conf ) ;
}
double pinhead_d = m_config - > opt_float ( " support_head_front_diameter " ) ;
double pillar_d = m_config - > opt_float ( " support_pillar_diameter " ) ;
if ( pinhead_d > pillar_d ) {
wxString msg_text = _ ( L ( " Pinhead diameter should be smaller than the pillar diameter. " ) ) ;
auto dialog = new wxMessageDialog ( parent ( ) , msg_text , _ ( L ( " Invalid pinhead diameter " ) ) , wxICON_WARNING | wxOK ) ;
DynamicPrintConfig new_conf = * m_config ;
if ( dialog - > ShowModal ( ) = = wxID_OK ) {
new_conf . set_key_value ( " support_head_front_diameter " , new ConfigOptionFloat ( pillar_d / 2.0 ) ) ;
}
load_config ( new_conf ) ;
}
m_update_cnt - - ;
if ( m_update_cnt = = 0 )
2019-02-22 08:38:56 +00:00
wxGetApp ( ) . mainframe - > on_config_changed ( m_config ) ;
2018-08-03 11:04:41 +00:00
}
2017-12-05 14:54:01 +00:00
} // GUI
} // Slic3r