2018-01-03 09:12:42 +00:00
# include "../../libslic3r/GCodeSender.hpp"
2018-01-25 12:46:04 +00:00
# include "Tab.hpp"
# include "PresetBundle.hpp"
# include "PresetHints.hpp"
# 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"
# include "slic3r/Utils/OctoPrint.hpp"
# 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-04-18 11:32:21 +00:00
# include <chrono>
2017-12-05 14:54:01 +00:00
namespace Slic3r {
namespace GUI {
// sub new
2018-01-05 14:11:33 +00:00
void Tab : : create_preset_tab ( PresetBundle * preset_bundle )
2017-12-05 14:54:01 +00:00
{
2017-12-26 22:04:54 +00:00
m_preset_bundle = 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-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 ) ;
// preset chooser
2018-01-16 15:28:01 +00:00
m_presets_choice = new wxBitmapComboBox ( panel , wxID_ANY , " " , wxDefaultPosition , wxSize ( 270 , - 1 ) , 0 , 0 , wxCB_READONLY ) ;
2018-04-11 11:56:37 +00:00
/*
m_cc_presets_choice = new wxComboCtrl ( panel , wxID_ANY , L ( " " ) , wxDefaultPosition , wxDefaultSize , wxCB_READONLY ) ;
2018-04-06 11:37:00 +00:00
wxDataViewTreeCtrlComboPopup * popup = new wxDataViewTreeCtrlComboPopup ;
if ( popup ! = nullptr )
{
// FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
// On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
2018-04-09 10:41:25 +00:00
// m_cc_presets_choice->UseAltPopupWindow();
2018-04-09 07:55:24 +00:00
2018-04-09 10:41:25 +00:00
// m_cc_presets_choice->EnablePopupAnimation(false);
2018-04-06 11:37:00 +00:00
m_cc_presets_choice - > SetPopupControl ( popup ) ;
popup - > SetStringValue ( from_u8 ( " Text1 " ) ) ;
2018-03-06 08:44:53 +00:00
2018-04-06 11:37:00 +00:00
popup - > Bind ( wxEVT_DATAVIEW_SELECTION_CHANGED , [ this , popup ] ( wxCommandEvent & evt )
{
auto selected = popup - > GetItemText ( popup - > GetSelection ( ) ) ;
if ( selected ! = _ ( L ( " System presets " ) ) & & selected ! = _ ( L ( " Default presets " ) ) )
2018-04-06 13:42:52 +00:00
{
2018-04-06 11:37:00 +00:00
m_cc_presets_choice - > SetText ( selected ) ;
2018-04-06 13:42:52 +00:00
std : : string selected_string = selected . ToUTF8 ( ) . data ( ) ;
2018-04-10 12:52:03 +00:00
# ifdef __APPLE__
# else
select_preset ( selected_string ) ;
# endif
2018-04-06 13:42:52 +00:00
}
2018-04-06 11:37:00 +00:00
} ) ;
2018-04-06 13:42:52 +00:00
2018-04-09 14:50:17 +00:00
// popup->Bind(wxEVT_KEY_DOWN, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
// popup->Bind(wxEVT_KEY_UP, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
2018-04-06 11:37:00 +00:00
auto icons = new wxImageList ( 16 , 16 , true , 1 ) ;
popup - > SetImageList ( icons ) ;
icons - > Add ( * new wxIcon ( from_u8 ( Slic3r : : var ( " flag-green-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
2018-04-06 13:42:52 +00:00
icons - > Add ( * new wxIcon ( from_u8 ( Slic3r : : var ( " flag-red-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
2018-04-06 11:37:00 +00:00
}
2018-04-11 11:56:37 +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
wxBitmap bmpMenu ;
2018-02-22 10:34:41 +00:00
bmpMenu = wxBitmap ( from_u8 ( Slic3r : : var ( " disk.png " ) ) , wxBITMAP_TYPE_PNG ) ;
2017-12-26 22:04:54 +00:00
m_btn_save_preset = new wxBitmapButton ( panel , wxID_ANY , bmpMenu , wxDefaultPosition , wxDefaultSize , wxBORDER_NONE ) ;
2018-03-06 12:34:39 +00:00
if ( wxMSW ) m_btn_save_preset - > SetBackgroundColour ( color ) ;
2018-02-22 10:34:41 +00:00
bmpMenu = wxBitmap ( from_u8 ( Slic3r : : var ( " delete.png " ) ) , wxBITMAP_TYPE_PNG ) ;
2017-12-26 22:04:54 +00:00
m_btn_delete_preset = new wxBitmapButton ( panel , wxID_ANY , bmpMenu , wxDefaultPosition , wxDefaultSize , wxBORDER_NONE ) ;
2018-03-06 12:34:39 +00:00
if ( wxMSW ) m_btn_delete_preset - > SetBackgroundColour ( color ) ;
2017-12-05 14:54:01 +00:00
2018-01-16 15:28:01 +00:00
m_show_incompatible_presets = false ;
2018-04-16 09:03:08 +00:00
m_bmp_show_incompatible_presets . LoadFile ( from_u8 ( Slic3r : : var ( " flag-red-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ;
m_bmp_hide_incompatible_presets . LoadFile ( from_u8 ( Slic3r : : var ( " flag-green-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ;
m_btn_hide_incompatible_presets = new wxBitmapButton ( panel , wxID_ANY , m_bmp_hide_incompatible_presets , wxDefaultPosition , wxDefaultSize , wxBORDER_NONE ) ;
2018-03-06 12:34:39 +00:00
if ( wxMSW ) m_btn_hide_incompatible_presets - > SetBackgroundColour ( color ) ;
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
2018-03-21 21:21:37 +00:00
m_undo_btn = new wxButton ( panel , wxID_ANY , " " , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT | wxNO_BORDER ) ;
m_undo_to_sys_btn = new wxButton ( panel , wxID_ANY , " " , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT | wxNO_BORDER ) ;
2018-04-19 14:20:30 +00:00
m_question_btn = new wxButton ( panel , wxID_ANY , " " , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT | wxNO_BORDER ) ;
2018-04-20 10:58:07 +00:00
// m_undo_btns_legent = new wxStaticText(panel, wxID_ANY, _(L("For more information about buttons hover the mouse cursor over them.")), wxDefaultPosition, wxDefaultSize);
2018-03-21 21:21:37 +00:00
if ( wxMSW ) {
m_undo_btn - > SetBackgroundColour ( color ) ;
m_undo_to_sys_btn - > SetBackgroundColour ( color ) ;
2018-04-19 14:20:30 +00:00
m_question_btn - > SetBackgroundColour ( color ) ;
2018-03-21 21:21:37 +00:00
}
2018-04-19 14:20:30 +00:00
2018-04-20 10:58:07 +00:00
m_undo_to_sys_btn - > SetToolTip ( _ ( L ( " UNLOCKED LOCK icon indicates about some value changes compared with system values "
2018-04-19 14:20:30 +00:00
" in current option group. \n "
2018-04-20 10:58:07 +00:00
" LOCKED LOCK icon indicates about same values compared with system values "
2018-04-19 14:20:30 +00:00
" in current option group. \n "
2018-04-20 10:58:07 +00:00
" WHITE BULLET icon indicates about nonsystem preset. \n \n "
" Click the UNLOCKED LOCK to revert all values in current option group to system values. " ) ) ) ;
m_undo_btn - > SetToolTip ( _ ( L ( " BACK ARROW icon indicates about some value changes compared with last saved preset values "
2018-04-19 14:20:30 +00:00
" in current option group. \n "
2018-04-20 10:58:07 +00:00
" WHITE BULLET icon indicates about same values compared with last saved preset values "
" in current option group. \n \n "
" Click the BACK ARROW to revert all values in current option group to last saved preset values. " ) ) ) ;
2018-04-19 14:20:30 +00:00
m_question_btn - > SetToolTip ( _ ( L ( " Hover the cursor over buttons to find more information. " ) ) ) ;
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.
m_bmp_value_lock . LoadFile ( from_u8 ( var ( " sys_lock.png " ) ) , wxBITMAP_TYPE_PNG ) ;
m_bmp_value_unlock . LoadFile ( from_u8 ( var ( " sys_unlock.png " ) ) , wxBITMAP_TYPE_PNG ) ;
m_bmp_non_system = & m_bmp_white_bullet ;
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
m_bmp_value_revert . LoadFile ( from_u8 ( var ( " action_undo.png " ) ) , wxBITMAP_TYPE_PNG ) ;
m_bmp_white_bullet . LoadFile ( from_u8 ( var ( " bullet_white.png " ) ) , wxBITMAP_TYPE_PNG ) ;
2018-04-19 14:20:30 +00:00
m_bmp_question . LoadFile ( from_u8 ( var ( " question_mark_01.png " ) ) , wxBITMAP_TYPE_PNG ) ;
2018-04-20 10:58:07 +00:00
fill_icon_descriptions ( ) ;
2018-04-16 09:03:08 +00:00
m_undo_btn - > SetBitmap ( m_bmp_white_bullet ) ;
2018-04-19 14:20:30 +00:00
m_undo_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent ) { on_roll_back_value ( ) ; } ) ) ;
2018-04-16 09:03:08 +00:00
m_undo_to_sys_btn - > SetBitmap ( m_bmp_white_bullet ) ;
2018-04-19 14:20:30 +00:00
m_undo_to_sys_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent ) { on_roll_back_value ( true ) ; } ) ) ;
m_question_btn - > SetBitmap ( m_bmp_question ) ;
2018-04-20 10:58:07 +00:00
m_question_btn - > Bind ( wxEVT_BUTTON , ( [ this ] ( wxCommandEvent )
{
auto dlg = new ButtonsDescription ( parent ( ) , & m_icon_descriptions ) ;
dlg - > ShowModal ( ) ;
} ) ) ;
2018-03-21 21:21:37 +00:00
2018-04-17 08:15:48 +00:00
// Colors for ui "decoration"
m_sys_label_clr = get_sys_label_clr ( ) ;
m_modified_label_clr = get_modified_label_clr ( ) ;
2018-04-18 11:32:21 +00:00
m_default_text_clr = get_default_label_clr ( ) ;
2018-04-17 08:15:48 +00:00
2017-12-26 22:04:54 +00:00
m_hsizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( m_hsizer , 0 , wxBOTTOM , 3 ) ;
m_hsizer - > Add ( m_presets_choice , 1 , wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL , 3 ) ;
m_hsizer - > AddSpacer ( 4 ) ;
m_hsizer - > Add ( m_btn_save_preset , 0 , wxALIGN_CENTER_VERTICAL ) ;
m_hsizer - > AddSpacer ( 4 ) ;
m_hsizer - > Add ( m_btn_delete_preset , 0 , wxALIGN_CENTER_VERTICAL ) ;
m_hsizer - > AddSpacer ( 16 ) ;
m_hsizer - > Add ( m_btn_hide_incompatible_presets , 0 , wxALIGN_CENTER_VERTICAL ) ;
2018-03-21 21:21:37 +00:00
m_hsizer - > AddSpacer ( 64 ) ;
m_hsizer - > Add ( m_undo_to_sys_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
m_hsizer - > Add ( m_undo_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
2018-04-20 10:58:07 +00:00
m_hsizer - > AddSpacer ( 32 ) ;
2018-04-19 14:20:30 +00:00
m_hsizer - > Add ( m_question_btn , 0 , wxALIGN_CENTER_VERTICAL ) ;
2018-04-20 10:58:07 +00:00
// m_hsizer->Add(m_undo_btns_legent, 0, wxALIGN_CENTER_VERTICAL);
2018-04-11 11:56:37 +00:00
// m_hsizer->AddSpacer(64);
// m_hsizer->Add(m_cc_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
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
2018-04-10 12:00:48 +00:00
2018-04-11 11:56:37 +00:00
/*
2018-04-10 12:00:48 +00:00
//temporary left vertical sizer
m_left_sizer = new wxBoxSizer ( wxVERTICAL ) ;
m_hsizer - > Add ( m_left_sizer , 0 , wxEXPAND | wxLEFT | wxTOP | wxBOTTOM , 3 ) ;
// tree
m_presetctrl = new wxDataViewTreeCtrl ( panel , wxID_ANY , wxDefaultPosition , wxSize ( 200 , - 1 ) , wxDV_NO_HEADER ) ;
m_left_sizer - > Add ( m_presetctrl , 1 , wxEXPAND ) ;
m_preset_icons = new wxImageList ( 16 , 16 , true , 1 ) ;
m_presetctrl - > SetImageList ( m_preset_icons ) ;
m_preset_icons - > Add ( * new wxIcon ( from_u8 ( Slic3r : : var ( " flag-green-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
m_preset_icons - > Add ( * new wxIcon ( from_u8 ( Slic3r : : var ( " flag-red-icon.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
m_presetctrl - > Bind ( wxEVT_DATAVIEW_SELECTION_CHANGED , [ this ] ( wxCommandEvent & evt )
{
auto selected = m_presetctrl - > GetItemText ( m_presetctrl - > GetSelection ( ) ) ;
if ( selected ! = _ ( L ( " System presets " ) ) & & selected ! = _ ( L ( " Default presets " ) ) )
{
std : : string selected_string = selected . ToUTF8 ( ) . data ( ) ;
2018-04-10 12:52:03 +00:00
# ifdef __APPLE__
# else
2018-04-10 12:00:48 +00:00
select_preset ( selected_string ) ;
2018-04-10 12:52:03 +00:00
# endif
2018-04-10 12:00:48 +00:00
}
} ) ;
2018-04-11 11:56:37 +00:00
*/
2018-04-10 12:00:48 +00:00
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
2018-01-18 10:45:25 +00:00
m_treectrl = new wxTreeCtrl ( panel , wxID_ANY , wxDefaultPosition , wxSize ( 185 , - 1 ) ,
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 ) ;
2018-01-26 00:44:34 +00:00
m_icons = new wxImageList ( 16 , 16 , 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-01-16 15:28:01 +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:
//! select_preset(m_presets_choice->GetStringSelection().ToStdString());
//! we doing next:
int selected_item = m_presets_choice - > GetSelection ( ) ;
2018-04-19 10:08:59 +00:00
if ( m_selected_preset_item = = selected_item )
return ;
2018-02-01 11:09:09 +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 ( ) ;
2018-04-19 10:08:59 +00:00
if ( selected_string = = " ------- System presets ------- " | |
selected_string = = " ------- User presets ------- " ) {
m_presets_choice - > SetSelection ( m_selected_preset_item ) ;
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-01-18 10:45:25 +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 ) {
toggle_show_hide_incompatible ( ) ;
2018-01-16 15:28:01 +00:00
} ) ) ;
2017-12-13 13:45:10 +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 ( ) ;
2018-01-09 08:41:07 +00:00
update ( ) ;
2017-12-05 14:54:01 +00:00
}
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-03-16 11:56:03 +00:00
}
2018-04-13 10:35:04 +00:00
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.
2018-02-22 10:34:41 +00:00
const auto img_icon = new wxIcon ( from_u8 ( Slic3r : : var ( icon ) ) , wxBITMAP_TYPE_PNG ) ;
2017-12-26 22:04:54 +00:00
m_icons - > Add ( * img_icon ) ;
2018-02-08 09:58:13 +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-01-05 14:11:33 +00:00
PageShp page ( new Page ( this , title , icon_idx ) ) ;
2017-12-13 13:45:10 +00:00
page - > SetScrollbars ( 1 , 1 , 1 , 1 ) ;
page - > Hide ( ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Add ( page . get ( ) , 1 , wxEXPAND | wxLEFT , 5 ) ;
2018-01-02 11:50:27 +00:00
if ( ! is_extruder_pages )
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-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
2018-04-18 11:32:21 +00:00
const bool is_printer_type = ( name ( ) = = " printer " ) ;
2018-04-18 12:15:13 +00:00
auto dirty_options = m_presets - > current_dirty_options ( is_printer_type ) ;
auto nonsys_options = m_presets - > current_different_from_parent_options ( is_printer_type ) ;
2018-04-18 11:32:21 +00:00
if ( is_printer_type ) {
TabPrinter * tab = static_cast < TabPrinter * > ( this ) ;
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
}
for ( auto & it : m_options_list )
it . second = m_opt_status_value ;
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-04-18 11:32:21 +00:00
Freeze ( ) ;
//update options "decoration"
2018-04-18 12:15:13 +00:00
for ( const auto opt : m_options_list )
2018-04-18 11:32:21 +00:00
{
bool is_nonsys_value = false ;
bool is_modified_value = true ;
const wxBitmap * sys_icon = & m_bmp_value_lock ;
const wxBitmap * icon = & m_bmp_value_revert ;
const wxColour * color = & m_sys_label_clr ;
if ( ( opt . second & osSystemValue ) = = 0 ) {
is_nonsys_value = true ;
sys_icon = m_bmp_non_system ;
if ( ( opt . second & osInitValue ) ! = 0 )
color = & m_default_text_clr ;
else
color = & m_modified_label_clr ;
}
if ( ( opt . second & osInitValue ) ! = 0 )
{
is_modified_value = false ;
icon = & m_bmp_white_bullet ;
}
if ( opt . first = = " bed_shape " | | opt . first = = " compatible_printers " ) {
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 - > m_is_nonsys_value = is_nonsys_value ;
field - > m_is_modified_value = is_modified_value ;
field - > set_undo_bitmap ( icon ) ;
field - > set_undo_to_sys_bitmap ( sys_icon ) ;
field - > set_label_colour ( color ) ;
}
Thaw ( ) ;
2018-04-13 16:22:06 +00:00
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-04-18 11:32:21 +00:00
void add_correct_opts_to_options_list ( const std : : string & opt_key , std : : map < std : : string , int > & map , TabPrinter * 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-03-21 21:21:37 +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-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 ;
if ( ! modified_page ) 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 ( )
{
auto cur_item = m_treectrl - > GetFirstVisibleItem ( ) ;
2018-03-22 08:37:42 +00:00
auto selection = m_treectrl - > GetItemText ( m_treectrl - > GetSelection ( ) ) ;
2018-03-21 21:21:37 +00:00
while ( cur_item ) {
auto title = m_treectrl - > GetItemText ( cur_item ) ;
for ( auto page : m_pages )
2018-03-16 11:56:03 +00:00
{
2018-03-21 21:21:37 +00:00
if ( page - > title ( ) ! = title )
continue ;
bool sys_page = true ;
bool modified_page = false ;
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-04-18 11:32:21 +00:00
if ( title = = _ ( " Dependencies " ) & & name ( ) ! = " printer " ) {
2018-04-13 16:22:06 +00:00
get_sys_and_mod_flags ( " compatible_printers " , sys_page , modified_page ) ;
}
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 ;
if ( selection = = title ) {
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-03-21 21:21:37 +00:00
auto next_item = m_treectrl - > GetNextVisible ( cur_item ) ;
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 ( )
{
2018-04-16 09:03:08 +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-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 ) {
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-03-23 16:27:43 +00:00
if ( group - > title = = _ ( " Size and coordinates " ) ) {
2018-04-18 11:32:21 +00:00
if ( ( m_options_list [ " bed_shape " ] & os ) = = 0 ) {
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-23 16:27:43 +00:00
}
2018-04-18 11:32:21 +00:00
if ( group - > title = = _ ( " Profile dependencies " ) & & name ( ) ! = " printer " ) {
if ( ( m_options_list [ " compatible_printers " ] & os ) = = 0 ) {
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 ( ) ;
m_compatible_printers_checkbox - > SetValue ( is_empty ) ;
is_empty ? m_compatible_printers_btn - > Disable ( ) : m_compatible_printers_btn - > Enable ( ) ;
}
2018-04-13 16:22:06 +00:00
}
2018-03-22 09:56:57 +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-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}.
void Tab : : update_dirty ( ) {
m_presets - > update_dirty_ui ( m_presets_choice ) ;
on_presets_changed ( ) ;
update_changed_ui ( ) ;
2018-04-06 13:42:52 +00:00
// update_dirty_presets(m_cc_presets_choice);
2018-03-09 07:34:32 +00:00
}
2018-01-16 15:28:01 +00:00
void Tab : : update_tab_ui ( )
{
2018-04-19 10:08:59 +00:00
m_selected_preset_item = m_presets - > update_tab_ui ( m_presets_choice , m_show_incompatible_presets ) ;
2018-04-11 11:56:37 +00:00
// update_tab_presets(m_cc_presets_choice, m_show_incompatible_presets);
// update_presetsctrl(m_presetctrl, m_show_incompatible_presets);
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.
void Tab : : reload_config ( ) {
Freeze ( ) ;
for ( auto page : m_pages )
page - > reload_config ( ) ;
2018-02-15 16:30:33 +00:00
Thaw ( ) ;
2018-01-09 08:41:07 +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 ;
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-04-13 10:35:04 +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.
2017-12-22 10:50:28 +00:00
if ( opt_key . compare ( " compatible_printers " ) = = 0 ) {
2018-01-12 11:41:13 +00:00
m_preset_bundle - > update_compatible_with_printer ( 0 ) ;
}
m_presets - > update_dirty_ui ( m_presets_choice ) ;
on_presets_changed ( ) ;
update ( ) ;
}
2018-01-21 22:35:00 +00:00
extern wxFrame * g_wxMainFrame ;
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
{
if ( m_event_value_change > 0 ) {
wxCommandEvent event ( m_event_value_change ) ;
2018-01-25 20:44:22 +00:00
std : : string str_out = opt_key + " " + m_name ;
2018-01-25 12:46:04 +00:00
event . SetString ( str_out ) ;
if ( opt_key = = " extruders_count " )
{
int val = boost : : any_cast < size_t > ( value ) ;
event . SetInt ( val ) ;
}
2018-01-21 22:35:00 +00:00
g_wxMainFrame - > ProcessWindowEvent ( event ) ;
}
2018-03-12 15:52:21 +00:00
if ( opt_key = = " fill_density " )
{
2018-04-13 10:35:04 +00:00
boost : : any val = get_optgroup ( ) - > get_config_value ( * m_config , opt_key ) ;
get_optgroup ( ) - > set_value ( opt_key , val ) ;
2018-03-12 15:52:21 +00:00
}
2018-03-13 15:14:36 +00:00
if ( opt_key = = " support_material " | | opt_key = = " support_material_buildplate_only " )
2018-03-12 15:52:21 +00:00
{
2018-03-13 15:14:36 +00:00
wxString new_selection = ! m_config - > opt_bool ( " support_material " ) ?
_ ( " None " ) :
m_config - > opt_bool ( " support_material_buildplate_only " ) ?
_ ( " Support on build plate only " ) :
_ ( " Everywhere " ) ;
get_optgroup ( ) - > set_value ( " support " , new_selection ) ;
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 ;
get_optgroup ( ) - > set_value ( " brim " , val ) ;
}
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 ( ) ;
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 ( ) {
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 ;
if ( wipe_tower_enabled & & multiple_extruders & & single_extruder_mm )
get_wiping_dialog_button ( ) - > Show ( ) ;
else get_wiping_dialog_button ( ) - > Hide ( ) ;
( get_wiping_dialog_button ( ) - > GetParent ( ) ) - > Layout ( ) ;
}
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,
// to uddate 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
{
if ( m_event_presets_changed > 0 ) {
wxCommandEvent event ( m_event_presets_changed ) ;
2018-01-25 20:44:22 +00:00
event . SetString ( m_name ) ;
2018-01-21 22:35:00 +00:00
g_wxMainFrame - > ProcessWindowEvent ( event ) ;
}
2018-03-23 08:41:04 +00:00
const Preset * parent = m_presets - > get_selected_preset_parent ( ) ;
const wxString description_line = parent = = nullptr ?
_ ( L ( " It's default preset " ) ) : parent = = & m_presets - > get_selected_preset ( ) ?
_ ( L ( " It's system preset " ) ) :
_ ( L ( " Current preset is inherited from " ) ) + " : \n " + parent - > name ;
m_parent_preset_description_line - > SetText ( description_line ) ;
2018-01-16 15:28:01 +00:00
}
2018-03-13 15:14:36 +00:00
void Tab : : update_frequently_changed_parameters ( )
{
boost : : any value = get_optgroup ( ) - > get_config_value ( * m_config , " fill_density " ) ;
get_optgroup ( ) - > set_value ( " fill_density " , value ) ;
wxString new_selection = ! m_config - > opt_bool ( " support_material " ) ?
_ ( " None " ) :
m_config - > opt_bool ( " support_material_buildplate_only " ) ?
_ ( " Support on build plate only " ) :
_ ( " Everywhere " ) ;
get_optgroup ( ) - > set_value ( " support " , new_selection ) ;
bool val = m_config - > opt_float ( " brim_width " ) > 0.0 ? true : false ;
get_optgroup ( ) - > set_value ( " brim " , val ) ;
2018-04-04 09:13:28 +00:00
2018-04-05 08:44:31 +00:00
update_wiping_button_visibility ( ) ;
2018-03-13 15:14:36 +00:00
}
2018-01-12 11:41:13 +00:00
void Tab : : reload_compatible_printers_widget ( )
{
bool has_any = ! m_config - > option < ConfigOptionStrings > ( " compatible_printers " ) - > values . empty ( ) ;
has_any ? m_compatible_printers_btn - > Enable ( ) : m_compatible_printers_btn - > Disable ( ) ;
m_compatible_printers_checkbox - > SetValue ( ! has_any ) ;
get_field ( " compatible_printers_condition " ) - > toggle ( ! has_any ) ;
2017-12-22 10:50:28 +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
2018-02-23 08:16:35 +00:00
auto page = add_options_page ( _ ( L ( " Layers and perimeters " ) ) , " layers.png " ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Infill " ) ) , " infill.png " ) ;
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 " ) ;
optgroup - > append_single_option_line ( " external_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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Skirt and brim " ) ) , " box.png " ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Support material " ) ) , " building.png " ) ;
optgroup = page - > new_optgroup ( _ ( L ( " Support material " ) ) ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " support_material " ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Speed " ) ) , " time.png " ) ;
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 " ) ;
optgroup - > append_single_option_line ( " max_volumetric_extrusion_rate_slope_positive " ) ;
optgroup - > append_single_option_line ( " max_volumetric_extrusion_rate_slope_negative " ) ;
2017-12-13 13:45:10 +00:00
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Multiple Extruders " ) ) , " funnel.png " ) ;
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 " ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Advanced " ) ) , " wrench.png " ) ;
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
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 " ) ;
optgroup - > append_single_option_line ( " elefant_foot_compensation " ) ;
optgroup - > append_single_option_line ( " xy_size_compensation " ) ;
// # optgroup->append_single_option_line("threads");
optgroup - > append_single_option_line ( " resolution " ) ;
2017-12-13 13:45:10 +00:00
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Output options " ) ) , " page_white_go.png " ) ;
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 " ) ;
2017-12-14 13:42:47 +00:00
option . opt . width = 60 ;
line . append_option ( option ) ;
2018-01-07 17:41:40 +00:00
option = optgroup - > get_option ( " extruder_clearance_height " ) ;
2017-12-14 13:42:47 +00:00
option . opt . width = 60 ;
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 " ) ;
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 ;
2017-12-14 13:42:47 +00:00
option . opt . height = 50 ;
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 ;
2017-12-14 13:42:47 +00:00
option . opt . height = 250 ;
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 " ) ) ) ;
line = { _ ( L ( " Compatible printers " ) ) , " " } ;
2017-12-26 22:04:54 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-01-15 11:13:05 +00:00
return compatible_printers_widget ( parent , & m_compatible_printers_checkbox , & m_compatible_printers_btn ) ;
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.
void TabPrint : : reload_config ( ) {
reload_compatible_printers_widget ( ) ;
Tab : : reload_config ( ) ;
}
2018-01-05 14:11:33 +00:00
void TabPrint : : update ( )
{
Freeze ( ) ;
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 ) ;
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 ) ;
2018-01-05 14:11:33 +00:00
}
2018-02-13 15:05:53 +00:00
auto first_layer_height = m_config - > option < ConfigOptionFloatOrPercent > ( " first_layer_height " ) - > value ;
auto layer_height = m_config - > opt_float ( " layer_height " ) ;
2018-01-12 11:41:13 +00:00
if ( m_config - > opt_bool ( " wipe_tower " ) & &
2018-02-23 08:16:35 +00:00
( first_layer_height ! = 0.2 | | layer_height < 0.15 | | layer_height > 0.35 ) ) {
wxString msg_text = _ ( L ( " The Wipe Tower currently supports only: \n "
2018-01-11 09:33:17 +00:00
" - first layer height 0.2mm \n "
" - layer height from 0.15mm to 0.35mm \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 ) {
2018-01-12 11:41:13 +00:00
const auto & val = * m_config - > option < ConfigOptionFloatOrPercent > ( " first_layer_height " ) ;
2018-03-07 14:05:41 +00:00
auto percent = val . percent ;
new_conf . set_key_value ( " first_layer_height " , new ConfigOptionFloatOrPercent ( 0.2 , percent ) ) ;
2018-01-11 09:33:17 +00:00
2018-02-23 08:16:35 +00:00
if ( m_config - > opt_float ( " layer_height " ) < 0.15 ) new_conf . set_key_value ( " layer_height " , new ConfigOptionFloat ( 0.15 ) ) ;
2018-01-12 11:41:13 +00:00
if ( m_config - > opt_float ( " layer_height " ) > 0.35 ) new_conf . set_key_value ( " layer_height " , new ConfigOptionFloat ( 0.35 ) ) ;
2018-01-11 09:33:17 +00:00
}
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_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 ;
}
}
if ( ! str_fill_pattern . empty ( ) ) {
2018-01-12 11:41:13 +00:00
auto external_fill_pattern = m_config - > def ( ) - > get ( " external_fill_pattern " ) - > enum_values ;
2018-01-11 09:33:17 +00:00
bool correct_100p_fill = false ;
for ( auto fill : external_fill_pattern )
{
if ( str_fill_pattern . compare ( fill ) = = 0 )
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-01-11 09:33:17 +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()
2018-04-04 08:18:26 +00:00
for ( auto el : { " external_fill_pattern " , " infill_first " , " solid_infill_extruder " ,
" 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 ;
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-04-04 08:18:26 +00:00
for ( auto el : { " support_material_threshold " , " 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-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
2018-01-05 14:11:33 +00:00
Thaw ( ) ;
}
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-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-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Temperature " ) ) + " ( \u00B0 C) " ) ; // degree sign
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 ) ;
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Cooling " ) ) , " hourglass.png " ) ;
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
2018-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Cooling thresholds " ) ) , 250 ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Advanced " ) ) , " wrench.png " ) ;
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-03-09 14:10:15 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " Toolchange behaviour " ) ) ) ;
2018-03-02 14:52:16 +00:00
optgroup - > append_single_option_line ( " filament_loading_speed " ) ;
optgroup - > append_single_option_line ( " filament_unloading_speed " ) ;
optgroup - > append_single_option_line ( " filament_toolchange_delay " ) ;
2018-03-12 14:41:25 +00:00
optgroup - > append_single_option_line ( " filament_cooling_time " ) ;
line = { _ ( L ( " Ramming " ) ) , " " } ;
line . widget = [ this ] ( wxWindow * parent ) {
2018-03-28 18:31:36 +00:00
auto ramming_dialog_btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Ramming settings " ) ) + " \u2026 " , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT ) ;
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 ) ;
2018-03-02 14:52:16 +00:00
2018-03-09 14:10:15 +00:00
page = add_options_page ( _ ( L ( " Custom G-code " ) ) , " cog.png " ) ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . 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 " ) ) ) ;
line = { _ ( L ( " Compatible printers " ) ) , " " } ;
2017-12-26 22:04:54 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-01-15 11:13:05 +00:00
return compatible_printers_widget ( parent , & m_compatible_printers_checkbox , & m_compatible_printers_btn ) ;
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
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.
void TabFilament : : reload_config ( ) {
reload_compatible_printers_widget ( ) ;
Tab : : reload_config ( ) ;
}
void TabFilament : : update ( )
{
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 ) ;
}
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 ) ) ) ;
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 , " " ) ;
2017-12-22 10:50:28 +00:00
auto font = ( new wxSystemSettings ) - > GetFont ( wxSYS_DEFAULT_GUI_FONT ) ;
2018-01-15 11:13:05 +00:00
( * StaticText ) - > SetFont ( font ) ;
2017-12-22 10:50:28 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2018-01-15 11:13:05 +00:00
sizer - > Add ( * StaticText ) ;
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-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-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 ( ) ;
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
2018-02-23 08:16:35 +00:00
auto page = add_options_page ( _ ( L ( " General " ) ) , " printer_empty.png " ) ;
auto optgroup = page - > new_optgroup ( _ ( L ( " Size and coordinates " ) ) ) ;
2017-12-22 10:50:28 +00:00
2018-02-23 08:16:35 +00:00
Line line { _ ( L ( " Bed shape " ) ) , " " } ;
2018-01-25 12:46:04 +00:00
line . widget = [ this ] ( wxWindow * parent ) {
2018-03-06 08:44:53 +00:00
auto btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Set " ) ) + " \u2026 " , wxDefaultPosition , wxDefaultSize , wxBU_LEFT | wxBU_EXACTFIT ) ;
2018-02-23 08:16:35 +00:00
// btn->SetFont(Slic3r::GUI::small_font);
2018-02-22 10:34:41 +00:00
btn - > SetBitmap ( wxBitmap ( from_u8 ( Slic3r : : var ( " printer_empty.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
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-03-23 16:27:43 +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 ;
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-01-12 16:16:59 +00:00
optgroup - > m_on_change = [ this , optgroup ] ( t_config_option_key opt_key , boost : : any value ) {
size_t extruders_count = boost : : any_cast < int > ( optgroup - > get_value ( " extruders_count " ) ) ;
wxTheApp - > CallAfter ( [ this , opt_key , value , extruders_count ] ( ) {
2018-03-22 15:13:41 +00:00
if ( opt_key . compare ( " extruders_count " ) = = 0 | | opt_key . compare ( " single_extruder_multi_material " ) = = 0 ) {
2018-01-12 16:16:59 +00:00
extruders_count_changed ( extruders_count ) ;
update_dirty ( ) ;
2018-04-05 08:44:31 +00:00
if ( opt_key . compare ( " single_extruder_multi_material " ) = = 0 ) // the single_extruder_multimaterial was added to force pages
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-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-01-12 16:16:59 +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-01-12 16:16:59 +00:00
auto serial_test = [ this ] ( wxWindow * parent ) {
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 ) ;
2017-12-22 10:50:28 +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-01-12 16:16:59 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this , parent ] ( wxCommandEvent e ) {
2018-01-03 09:12:42 +00:00
auto sender = new GCodeSender ( ) ;
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-02-23 08:16:35 +00:00
optgroup = page - > new_optgroup ( _ ( L ( " OctoPrint upload " ) ) ) ;
2018-03-15 17:06:26 +00:00
auto octoprint_host_browse = [ this , optgroup ] ( wxWindow * parent ) {
2018-02-23 08:16:35 +00:00
auto btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Browse " ) ) + " \u2026 " , wxDefaultPosition , wxDefaultSize , wxBU_LEFT ) ;
2018-02-22 10:34:41 +00:00
btn - > SetBitmap ( wxBitmap ( from_u8 ( Slic3r : : var ( " zoom.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
2017-12-22 10:50:28 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( btn ) ;
2018-03-15 17:06:26 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this , parent , optgroup ] ( wxCommandEvent e ) {
BonjourDialog dialog ( parent ) ;
if ( dialog . show_and_lookup ( ) ) {
optgroup - > set_value ( " octoprint_host " , std : : move ( dialog . get_selected ( ) ) , true ) ;
2018-01-26 00:44:34 +00:00
}
2018-01-03 09:12:42 +00:00
} ) ;
2017-12-22 10:50:28 +00:00
return sizer ;
2017-12-26 22:04:54 +00:00
} ;
auto octoprint_host_test = [ this ] ( wxWindow * parent ) {
2018-02-23 08:16:35 +00:00
auto btn = m_octoprint_host_test_btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Test " ) ) ,
2018-01-26 00:44:34 +00:00
wxDefaultPosition , wxDefaultSize , wxBU_LEFT | wxBU_EXACTFIT ) ;
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-03-15 17:06:26 +00:00
btn - > Bind ( wxEVT_BUTTON , [ this ] ( wxCommandEvent e ) {
OctoPrint octoprint ( m_config ) ;
wxString msg ;
if ( octoprint . test ( msg ) ) {
show_info ( this , _ ( L ( " Connection to OctoPrint works correctly. " ) ) , _ ( L ( " Success! " ) ) ) ;
} else {
const auto text = wxString : : Format ( " %s: %s \n \n %s " ,
_ ( L ( " Could not connect to OctoPrint " ) ) , msg , _ ( L ( " Note: OctoPrint version at least 1.1.0 is required. " ) )
) ;
show_error ( this , text ) ;
2018-01-26 00:44:34 +00:00
}
2018-03-15 17:06:26 +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
2018-01-07 17:41:40 +00:00
Line host_line = optgroup - > create_single_option_line ( " octoprint_host " ) ;
2017-12-22 10:50:28 +00:00
host_line . append_widget ( octoprint_host_browse ) ;
host_line . append_widget ( octoprint_host_test ) ;
optgroup - > append_line ( host_line ) ;
2018-01-07 17:41:40 +00:00
optgroup - > append_single_option_line ( " octoprint_apikey " ) ;
2017-12-22 10:50:28 +00:00
2018-03-15 17:06:26 +00:00
if ( Http : : ca_file_supported ( ) ) {
Line cafile_line = optgroup - > create_single_option_line ( " octoprint_cafile " ) ;
auto octoprint_cafile_browse = [ this , optgroup ] ( wxWindow * parent ) {
auto btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Browse " ) ) + " \u2026 " , wxDefaultPosition , wxDefaultSize , wxBU_LEFT ) ;
btn - > SetBitmap ( wxBitmap ( from_u8 ( Slic3r : : var ( " zoom.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
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 ( " octoprint_cafile " , std : : move ( openFileDialog . GetPath ( ) ) , true ) ;
}
} ) ;
return sizer ;
} ;
cafile_line . append_widget ( octoprint_cafile_browse ) ;
optgroup - > append_line ( cafile_line ) ;
auto octoprint_cafile_hint = [ this , optgroup ] ( wxWindow * parent ) {
auto txt = new wxStaticText ( parent , wxID_ANY ,
_ ( L ( " HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate. " ) ) ) ;
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
sizer - > Add ( txt ) ;
return sizer ;
} ;
Line cafile_hint { " " , " " } ;
cafile_hint . full_width = 1 ;
cafile_hint . widget = std : : move ( octoprint_cafile_hint ) ;
optgroup - > append_line ( cafile_hint ) ;
}
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 " ) ;
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
2018-02-23 08:16:35 +00:00
page = add_options_page ( _ ( L ( " Custom G-code " ) ) , " cog.png " ) ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 150 ;
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 ;
option . opt . height = 250 ;
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 ) ;
2017-12-26 22:04:54 +00:00
build_extruder_pages ( ) ;
2017-12-22 10:50:28 +00:00
2018-01-12 16:16:59 +00:00
if ( ! m_no_controller )
update_serial_ports ( ) ;
2017-12-22 10:50:28 +00:00
}
2018-01-12 16:16:59 +00:00
void TabPrinter : : update_serial_ports ( ) {
Field * field = get_field ( " serial_port " ) ;
Choice * choice = static_cast < Choice * > ( field ) ;
choice - > set_values ( scan_serial_ports ( ) ) ;
}
2018-01-02 11:50:27 +00:00
2018-01-12 16:16:59 +00:00
void TabPrinter : : extruders_count_changed ( size_t 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 ( ) ;
build_extruder_pages ( ) ;
2018-03-07 14:05:41 +00:00
reload_config ( ) ;
2018-01-12 16:16:59 +00:00
on_value_change ( " extruders_count " , extruders_count ) ;
}
void TabPrinter : : build_extruder_pages ( ) {
2018-04-18 11:32:21 +00:00
if ( m_extruders_count_old = = m_extruders_count )
{
// 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 ;
}
if ( m_extruders_count > 1 & & m_config - > opt_bool ( " single_extruder_multi_material " ) ) {
// create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
auto page = add_options_page ( _ ( L ( " Single extruder MM setup " ) ) , " printer_empty.png " , true ) ;
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 " ) ;
m_pages . insert ( m_pages . end ( ) - 2 , page ) ;
}
rebuild_page_tree ( ) ;
return ;
}
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
2018-02-28 14:39:20 +00:00
char buf [ MIN_BUF_LENGTH_FOR_L ] ;
sprintf ( buf , _CHB ( L ( " Extruder %d " ) ) , extruder_idx + 1 ) ;
auto page = add_options_page ( from_u8 ( buf ) , " funnel.png " , true ) ;
2018-04-18 11:32:21 +00:00
m_pages . insert ( m_pages . begin ( ) + 2 + 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 )
m_pages . erase ( m_pages . begin ( ) + 2 + m_extruders_count , m_pages . begin ( ) + 2 + m_extruders_count_old ) ;
m_extruders_count_old = m_extruders_count ;
2018-01-02 11:50:27 +00:00
rebuild_page_tree ( ) ;
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-01-12 16:16:59 +00:00
void TabPrinter : : update ( ) {
Freeze ( ) ;
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-03-15 17:06:26 +00:00
m_octoprint_host_test_btn - > Enable ( ! m_config - > opt_string ( " octoprint_host " ) . empty ( ) ) ;
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 ) ;
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 ) ;
}
Thaw ( ) ;
}
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 ( )
{
2018-01-16 15:28:01 +00:00
auto preset = m_presets - > get_edited_preset ( ) ;
2018-03-16 16:25:11 +00:00
2018-03-13 15:14:36 +00:00
preset . is_default ? m_btn_delete_preset - > Disable ( ) : m_btn_delete_preset - > Enable ( true ) ;
update ( ) ;
// For the printer profile, generate the extruder pages.
on_preset_loaded ( ) ;
// Reload preset pages with the new configuration values.
reload_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-03-13 15:14:36 +00:00
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)
2018-01-26 02:24:01 +00:00
wxTheApp - > CallAfter ( [ this ] {
2018-02-09 10:04:34 +00:00
// checking out if this Tab exists till this moment
if ( ! checked_tab ( this ) )
return ;
2018-01-16 15:28:01 +00:00
update_tab_ui ( ) ;
on_presets_changed ( ) ;
2018-03-13 15:14:36 +00:00
2018-03-14 14:38:54 +00:00
if ( name ( ) = = " print " )
2018-03-13 15:14:36 +00:00
update_frequently_changed_parameters ( ) ;
2018-03-21 21:21:37 +00:00
if ( m_name = = " printer " ) {
2018-03-14 14:38:54 +00:00
static_cast < TabPrinter * > ( this ) - > m_initial_extruders_count = static_cast < TabPrinter * > ( this ) - > m_extruders_count ;
2018-03-21 21:21:37 +00:00
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-04-18 11:32:21 +00:00
m_opt_status_value = ( m_presets - > get_selected_preset_parent ( ) ? osSystemValue : 0 ) | osInitValue ;
init_options_list ( ) ;
2018-03-14 14:38:54 +00:00
update_changed_ui ( ) ;
2018-01-26 02:24:01 +00:00
} ) ;
2018-01-05 14:11:33 +00:00
}
2017-12-13 13:45:10 +00:00
//Regerenerate content of the page tree.
2018-01-05 14:11:33 +00:00
void Tab : : rebuild_page_tree ( )
2017-12-13 13:45:10 +00:00
{
Freeze ( ) ;
// get label of the currently selected item
2017-12-26 22:04:54 +00:00
auto selected = m_treectrl - > GetItemText ( m_treectrl - > GetSelection ( ) ) ;
auto rootItem = m_treectrl - > GetRootItem ( ) ;
m_treectrl - > DeleteChildren ( rootItem ) ;
2017-12-13 13:45:10 +00:00
auto have_selection = 0 ;
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-18 11:32:21 +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_disable_tree_sel_changed_event = 1 ;
m_treectrl - > SelectItem ( itemId ) ;
m_disable_tree_sel_changed_event = 0 ;
2017-12-13 13:45:10 +00:00
have_selection = 1 ;
}
}
if ( ! have_selection ) {
// this is triggered on first load, so we don't disable the sel change event
2017-12-26 22:04:54 +00:00
m_treectrl - > SelectItem ( m_treectrl - > GetFirstVisibleItem ( ) ) ; //! (treectrl->GetFirstChild(rootItem));
2017-12-13 13:45:10 +00:00
}
Thaw ( ) ;
}
2018-01-16 15:28:01 +00:00
// Called by the UI combo box when the user switches profiles.
// 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.
2018-04-13 10:35:04 +00:00
void Tab : : select_preset ( const std : : string & preset_name /*= ""*/ )
2018-01-16 15:28:01 +00:00
{
2018-01-26 00:44:34 +00:00
std : : string name = preset_name ;
2018-01-16 15:28:01 +00:00
auto force = false ;
auto presets = m_presets ;
// If no name is provided, select the "-- default --" preset.
if ( name . empty ( ) )
name = presets - > default_preset ( ) . name ;
auto current_dirty = presets - > current_is_dirty ( ) ;
auto canceled = false ;
auto printer_tab = presets - > name ( ) . compare ( " printer " ) = = 0 ;
m_reload_dependent_tabs = { } ;
if ( ! force & & current_dirty & & ! may_discard_current_dirty_preset ( ) ) {
canceled = true ;
} else if ( printer_tab ) {
// 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.
auto new_printer_preset = presets - > find_preset ( name , true ) ;
auto print_presets = & m_preset_bundle - > prints ;
bool print_preset_dirty = print_presets - > current_is_dirty ( ) ;
bool print_preset_compatible = print_presets - > get_edited_preset ( ) . is_compatible_with_printer ( * new_printer_preset ) ;
canceled = ! force & & print_preset_dirty & & ! print_preset_compatible & &
! may_discard_current_dirty_preset ( print_presets , name ) ;
auto filament_presets = & m_preset_bundle - > filaments ;
bool filament_preset_dirty = filament_presets - > current_is_dirty ( ) ;
bool filament_preset_compatible = filament_presets - > get_edited_preset ( ) . is_compatible_with_printer ( * new_printer_preset ) ;
if ( ! canceled & & ! force ) {
canceled = filament_preset_dirty & & ! filament_preset_compatible & &
! may_discard_current_dirty_preset ( filament_presets , name ) ;
}
if ( ! canceled ) {
if ( ! print_preset_compatible ) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
2018-01-25 12:46:04 +00:00
m_reload_dependent_tabs . push_back ( " print " ) ;
2018-01-16 15:28:01 +00:00
if ( print_preset_dirty ) print_presets - > discard_current_changes ( ) ;
}
if ( ! filament_preset_compatible ) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
2018-01-25 12:46:04 +00:00
m_reload_dependent_tabs . push_back ( " filament " ) ;
2018-01-16 15:28:01 +00:00
if ( filament_preset_dirty ) filament_presets - > discard_current_changes ( ) ;
}
}
}
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 ( ) ;
}
else {
if ( current_dirty ) presets - > discard_current_changes ( ) ;
presets - > select_preset_by_name ( name , force ) ;
// 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.
if ( current_dirty | | printer_tab )
m_preset_bundle - > update_compatible_with_printer ( true ) ;
// Initialize the UI from the current preset.
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.
auto old_preset = presets - > get_edited_preset ( ) ;
auto type_name = presets - > name ( ) ;
auto tab = " " ;
auto name = old_preset . is_default ?
2018-02-23 08:16:35 +00:00
_ ( L ( " Default " ) ) + type_name + _ ( L ( " preset " ) ) :
( type_name + _ ( L ( " preset \n " ) ) + tab + old_preset . name ) ;
2018-01-16 15:28:01 +00:00
// Collect descriptions of the dirty options.
std : : vector < std : : string > option_names ;
for ( auto opt_key : presets - > current_dirty_options ( ) ) {
auto opt = m_config - > def ( ) - > options . at ( opt_key ) ;
std : : string name = " " ;
if ( ! opt . category . empty ( ) )
name + = opt . category + " > " ;
name + = ! opt . full_label . empty ( ) ?
opt . full_label :
opt . label ;
option_names . push_back ( name ) ;
}
// Show a confirmation dialog with the list of dirty options.
std : : string changes = " " ;
for ( auto changed_name : option_names )
changes + = tab + changed_name + " \n " ;
auto message = ( ! new_printer_name . empty ( ) ) ?
2018-02-23 08:16:35 +00:00
name + _ ( L ( " \n \n is not compatible with printer \n " ) ) + tab + new_printer_name + _ ( L ( " \n \n and it has the following unsaved changes: " ) ) :
name + _ ( L ( " \n \n has the following unsaved changes: " ) ) ;
2018-01-16 15:28:01 +00:00
auto confirm = new wxMessageDialog ( parent ( ) ,
2018-02-23 08:16:35 +00:00
message + " \n " + changes + _ ( L ( " \n \n Discard changes and continue anyway? " ) ) ,
_ ( L ( " Unsaved Changes " ) ) , wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ) ;
2018-01-16 15:28:01 +00:00
return confirm - > ShowModal ( ) = = wxID_YES ;
}
2018-01-05 14:11:33 +00:00
void Tab : : OnTreeSelChange ( wxTreeEvent & event )
2017-12-13 13:45:10 +00:00
{
2017-12-26 22:04:54 +00:00
if ( m_disable_tree_sel_changed_event ) return ;
2018-04-17 08:15:48 +00:00
wxWindowUpdateLocker noUpdates ( this ) ;
2018-01-05 14:11:33 +00:00
Page * page = nullptr ;
2017-12-26 22:04:54 +00:00
auto selection = m_treectrl - > GetItemText ( m_treectrl - > GetSelection ( ) ) ;
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 )
2017-12-13 13:45:10 +00:00
el . get ( ) - > Hide ( ) ;
2017-12-05 14:54:01 +00:00
page - > Show ( ) ;
2017-12-26 22:04:54 +00:00
m_hsizer - > Layout ( ) ;
2017-12-13 13:45:10 +00:00
Refresh ( ) ;
2018-03-22 08:37:42 +00:00
update_undo_buttons ( ) ;
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 ( ) ) {
auto preset = m_presets - > get_selected_preset ( ) ;
auto default_name = preset . is_default ? " Untitled " : preset . name ;
2018-01-18 10:45:25 +00:00
bool have_extention = boost : : iends_with ( default_name , " .ini " ) ;
if ( have_extention )
{
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 ( ) ;
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 ) ) {
show_error ( this , _ ( L ( " Cannot overwrite an external. " ) ) ) ;
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.
m_preset_bundle - > update_compatible_with_printer ( false ) ;
// 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-03-16 11:56:03 +00:00
2018-03-19 16:21:37 +00:00
if ( m_name = = " printer " )
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 ;
// Delete the file and select some other reasonable preset.
// 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 )
{
return ;
}
// Load the newly selected preset into the UI, update selection combo boxes with their dirty flags.
load_current_preset ( ) ;
}
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 ( )
{
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-02-27 08:51:14 +00:00
m_show_btn_incompatible_presets = get_app_config ( ) - > get ( " show_incompatible_presets " ) [ 0 ] = = ' 1 ' ? true : false ;
2018-01-16 15:28:01 +00:00
bool show = m_show_btn_incompatible_presets & & m_presets - > name ( ) . compare ( " printer " ) ! = 0 ;
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-01-15 11:13:05 +00:00
wxSizer * Tab : : compatible_printers_widget ( wxWindow * parent , wxCheckBox * * checkbox , wxButton * * btn )
2017-12-19 10:59:42 +00:00
{
2018-02-23 08:16:35 +00:00
* checkbox = new wxCheckBox ( parent , wxID_ANY , _ ( L ( " All " ) ) ) ;
* btn = new wxButton ( parent , wxID_ANY , _ ( L ( " Set " ) ) + " \u2026 " , wxDefaultPosition , wxDefaultSize , wxBU_LEFT | wxBU_EXACTFIT ) ;
2018-01-15 11:13:05 +00:00
2018-02-22 10:34:41 +00:00
( * btn ) - > SetBitmap ( wxBitmap ( from_u8 ( Slic3r : : var ( " printer_empty.png " ) ) , wxBITMAP_TYPE_PNG ) ) ;
2017-12-19 10:59:42 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2018-01-15 11:13:05 +00:00
sizer - > Add ( ( * checkbox ) , 0 , wxALIGN_CENTER_VERTICAL ) ;
sizer - > Add ( ( * btn ) , 0 , wxALIGN_CENTER_VERTICAL ) ;
2017-12-19 10:59:42 +00:00
2018-01-15 11:13:05 +00:00
( * checkbox ) - > Bind ( wxEVT_CHECKBOX , ( [ = ] ( wxCommandEvent e )
2017-12-19 10:59:42 +00:00
{
2018-01-15 11:13:05 +00:00
( * btn ) - > Enable ( ! ( * checkbox ) - > GetValue ( ) ) ;
2018-01-12 11:41:13 +00:00
// All printers have been made compatible with this preset.
2018-01-15 11:13:05 +00:00
if ( ( * checkbox ) - > GetValue ( ) )
2018-01-12 11:41:13 +00:00
load_key_value ( " compatible_printers " , std : : vector < std : : string > { } ) ;
2018-01-15 11:13:05 +00:00
get_field ( " compatible_printers_condition " ) - > toggle ( ( * checkbox ) - > GetValue ( ) ) ;
2018-04-13 16:22:06 +00:00
update_changed_ui ( ) ;
2017-12-19 10:59:42 +00:00
} ) ) ;
2018-01-15 11:13:05 +00:00
( * btn ) - > Bind ( wxEVT_BUTTON , ( [ this , parent , checkbox , btn ] ( wxCommandEvent e )
2017-12-19 10:59:42 +00:00
{
// # Collect names of non-default non-external printer profiles.
2018-01-12 16:16:59 +00:00
PresetCollection * printers = & m_preset_bundle - > printers ;
2017-12-19 10:59:42 +00:00
wxArrayString presets ;
for ( size_t idx = 0 ; idx < printers - > size ( ) ; + + idx )
{
Preset & preset = printers - > preset ( idx ) ;
2018-03-09 15:37:33 +00:00
if ( ! preset . is_default & & ! preset . is_external & & ! preset . is_system )
2017-12-19 10:59:42 +00:00
presets . Add ( preset . name ) ;
}
auto dlg = new wxMultiChoiceDialog ( parent ,
2018-02-23 08:16:35 +00:00
_ ( L ( " Select the printers this profile is compatible with. " ) ) ,
_ ( L ( " Compatible printers " ) ) , presets ) ;
2017-12-19 10:59:42 +00:00
// # Collect and set indices of printers marked as compatible.
wxArrayInt selections ;
2018-01-12 11:41:13 +00:00
auto * compatible_printers = dynamic_cast < const ConfigOptionStrings * > ( m_config - > option ( " compatible_printers " ) ) ;
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 )
if ( presets [ idx ] . compare ( preset_name ) = = 0 )
{
selections . Add ( idx ) ;
break ;
}
dlg - > SetSelections ( selections ) ;
2018-01-12 11:41:13 +00:00
std : : vector < std : : string > value ;
// Show the dialog.
2017-12-19 10:59:42 +00:00
if ( dlg - > ShowModal ( ) = = wxID_OK ) {
selections . Clear ( ) ;
selections = dlg - > GetSelections ( ) ;
for ( auto idx : selections )
value . push_back ( presets [ idx ] . ToStdString ( ) ) ;
2018-01-12 11:41:13 +00:00
if ( value . empty ( ) ) {
2018-01-15 11:13:05 +00:00
( * checkbox ) - > SetValue ( 1 ) ;
( * btn ) - > Disable ( ) ;
2017-12-19 10:59:42 +00:00
}
2018-01-12 11:41:13 +00:00
// All printers have been made compatible with this preset.
load_key_value ( " compatible_printers " , value ) ;
2018-04-13 16:22:06 +00:00
update_changed_ui ( ) ;
2017-12-19 10:59:42 +00:00
}
} ) ) ;
return sizer ;
}
2018-04-10 12:00:48 +00:00
void Tab : : update_presetsctrl ( wxDataViewTreeCtrl * ui , bool show_incompatible )
{
if ( ui = = nullptr )
return ;
ui - > Freeze ( ) ;
ui - > DeleteAllItems ( ) ;
auto presets = m_presets - > get_presets ( ) ;
auto idx_selected = m_presets - > get_idx_selected ( ) ;
auto suffix_modified = m_presets - > get_suffix_modified ( ) ;
int icon_compatible = 0 ;
int icon_incompatible = 1 ;
int cnt_items = 0 ;
auto root_sys = ui - > AppendContainer ( wxDataViewItem ( 0 ) , _ ( L ( " System presets " ) ) ) ;
auto root_def = ui - > AppendContainer ( wxDataViewItem ( 0 ) , _ ( L ( " Default presets " ) ) ) ;
auto show_def = get_app_config ( ) - > get ( " no_defaults " ) [ 0 ] ! = ' 1 ' ;
for ( size_t i = presets . front ( ) . is_visible ? 0 : 1 ; i < presets . size ( ) ; + + i ) {
const Preset & preset = presets [ i ] ;
if ( ! preset . is_visible | | ( ! show_incompatible & & ! preset . is_compatible & & i ! = idx_selected ) )
continue ;
auto preset_name = wxString : : FromUTF8 ( ( preset . name + ( preset . is_dirty ? suffix_modified : " " ) ) . c_str ( ) ) ;
wxDataViewItem item ;
if ( preset . is_system )
item = ui - > AppendItem ( root_sys , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
else if ( show_def & & preset . is_default )
item = ui - > AppendItem ( root_def , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
else
{
auto parent = m_presets - > get_preset_parent ( preset ) ;
if ( parent = = nullptr )
item = ui - > AppendItem ( root_def , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
else
{
auto parent_name = parent - > name ;
wxDataViewTreeStoreContainerNode * node = ui - > GetStore ( ) - > FindContainerNode ( root_sys ) ;
if ( node )
{
wxDataViewTreeStoreNodeList : : iterator iter ;
for ( iter = node - > GetChildren ( ) . begin ( ) ; iter ! = node - > GetChildren ( ) . end ( ) ; iter + + )
{
wxDataViewTreeStoreNode * child = * iter ;
auto child_item = child - > GetItem ( ) ;
auto item_text = ui - > GetItemText ( child_item ) ;
if ( item_text = = parent_name )
{
auto added_child = ui - > AppendItem ( child - > GetItem ( ) , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
if ( ! added_child ) {
ui - > DeleteItem ( child - > GetItem ( ) ) ;
auto new_parent = ui - > AppendContainer ( root_sys , parent_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
ui - > AppendItem ( new_parent , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
}
break ;
}
}
}
}
}
cnt_items + + ;
if ( i = = idx_selected ) {
ui - > Select ( item ) ;
m_cc_presets_choice - > SetText ( preset_name ) ;
}
}
if ( ui - > GetStore ( ) - > GetChildCount ( root_def ) = = 0 )
ui - > DeleteItem ( root_def ) ;
ui - > Thaw ( ) ;
}
2018-04-06 13:42:52 +00:00
void Tab : : update_tab_presets ( wxComboCtrl * ui , bool show_incompatible )
{
if ( ui = = nullptr )
return ;
ui - > Freeze ( ) ;
ui - > Clear ( ) ;
auto presets = m_presets - > get_presets ( ) ;
auto idx_selected = m_presets - > get_idx_selected ( ) ;
auto suffix_modified = m_presets - > get_suffix_modified ( ) ;
int icon_compatible = 0 ;
int icon_incompatible = 1 ;
int cnt_items = 0 ;
wxDataViewTreeCtrlComboPopup * popup = wxDynamicCast ( m_cc_presets_choice - > GetPopupControl ( ) , wxDataViewTreeCtrlComboPopup ) ;
if ( popup ! = nullptr )
{
popup - > DeleteAllItems ( ) ;
2018-04-09 14:50:17 +00:00
2018-04-06 13:42:52 +00:00
auto root_sys = popup - > AppendContainer ( wxDataViewItem ( 0 ) , _ ( L ( " System presets " ) ) ) ;
2018-04-09 14:50:17 +00:00
auto root_def = popup - > AppendContainer ( wxDataViewItem ( 0 ) , _ ( L ( " Default presets " ) ) ) ;
2018-04-09 10:41:25 +00:00
auto show_def = get_app_config ( ) - > get ( " no_defaults " ) [ 0 ] ! = ' 1 ' ;
2018-04-06 13:42:52 +00:00
for ( size_t i = presets . front ( ) . is_visible ? 0 : 1 ; i < presets . size ( ) ; + + i ) {
const Preset & preset = presets [ i ] ;
if ( ! preset . is_visible | | ( ! show_incompatible & & ! preset . is_compatible & & i ! = idx_selected ) )
continue ;
auto preset_name = wxString : : FromUTF8 ( ( preset . name + ( preset . is_dirty ? suffix_modified : " " ) ) . c_str ( ) ) ;
2018-04-09 07:55:24 +00:00
wxDataViewItem item ;
2018-04-09 10:41:25 +00:00
if ( preset . is_system )
item = popup - > AppendItem ( root_sys , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
else if ( show_def & & preset . is_default )
item = popup - > AppendItem ( root_def , preset_name ,
2018-04-09 07:55:24 +00:00
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
2018-04-09 14:50:17 +00:00
else
{
auto parent = m_presets - > get_preset_parent ( preset ) ;
if ( parent = = nullptr )
item = popup - > AppendItem ( root_def , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
else
{
auto parent_name = parent - > name ;
wxDataViewTreeStoreContainerNode * node = popup - > GetStore ( ) - > FindContainerNode ( root_sys ) ;
if ( node )
{
wxDataViewTreeStoreNodeList : : iterator iter ;
for ( iter = node - > GetChildren ( ) . begin ( ) ; iter ! = node - > GetChildren ( ) . end ( ) ; iter + + )
{
wxDataViewTreeStoreNode * child = * iter ;
auto child_item = child - > GetItem ( ) ;
auto item_text = popup - > GetItemText ( child_item ) ;
if ( item_text = = parent_name )
{
auto added_child = popup - > AppendItem ( child - > GetItem ( ) , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
if ( ! added_child ) {
popup - > DeleteItem ( child - > GetItem ( ) ) ;
auto new_parent = popup - > AppendContainer ( root_sys , parent_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
popup - > AppendItem ( new_parent , preset_name ,
preset . is_compatible ? icon_compatible : icon_incompatible ) ;
}
break ;
}
}
}
}
2018-04-09 07:55:24 +00:00
}
2018-04-06 13:42:52 +00:00
cnt_items + + ;
if ( i = = idx_selected ) {
popup - > Select ( item ) ;
m_cc_presets_choice - > SetText ( preset_name ) ;
}
}
2018-04-09 14:50:17 +00:00
if ( popup - > GetStore ( ) - > GetChildCount ( root_def ) = = 0 )
popup - > DeleteItem ( root_def ) ;
2018-04-06 13:42:52 +00:00
}
ui - > Thaw ( ) ;
}
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; "
" indicates about same values compared with system values in current option group " ) ) ) ;
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_value_unlock , L ( " UNLOCKED LOCK; "
" indicates about some value changes compared with system values in current option group " ) ) ) ;
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_white_bullet , L ( " WHITE BULLET; "
" indicates about : \n - nonsystem preset (on left button) "
" \n - same values compared with last saved preset values in current option group(on right button) " ) ) ) ;
m_icon_descriptions . push_back ( t_icon_description ( & m_bmp_value_revert , L ( " BACK ARROW; "
" indicates about some value changes compared with last saved preset values in current option group " ) ) ) ;
}
2018-01-11 09:33:17 +00:00
void Page : : reload_config ( )
{
for ( auto group : m_optgroups )
group - > reload_config ( ) ;
}
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 ;
for ( auto opt : m_optgroups ) {
field = opt - > get_fieldc ( opt_key , opt_index ) ;
if ( field ! = nullptr )
return field ;
}
return field ;
}
2018-04-13 10:35:04 +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
{
//! config_ have to be "right"
2018-03-07 14:05:41 +00:00
ConfigOptionsGroupShp optgroup = std : : make_shared < ConfigOptionsGroup > ( this , title , m_config , true ) ;
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-01-05 14:11:33 +00:00
optgroup - > m_on_change = [ this ] ( 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-01-05 14:11:33 +00:00
static_cast < Tab * > ( GetParent ( ) ) - > update_dirty ( ) ;
static_cast < Tab * > ( GetParent ( ) ) - > on_value_change ( opt_key , value ) ;
2018-01-18 15:36:26 +00:00
//! });
} ;
2017-12-13 13:45:10 +00:00
2018-03-06 11:34:20 +00:00
optgroup - > m_get_initial_config = [ this ] ( ) {
DynamicPrintConfig config = static_cast < Tab * > ( GetParent ( ) ) - > m_presets - > get_selected_preset ( ) . config ;
return config ;
} ;
2018-03-16 16:25:11 +00:00
optgroup - > m_get_sys_config = [ this ] ( ) {
DynamicPrintConfig config = static_cast < Tab * > ( GetParent ( ) ) - > m_presets - > get_selected_preset_parent ( ) - > config ;
return config ;
} ;
optgroup - > have_sys_config = [ this ] ( ) {
return static_cast < Tab * > ( GetParent ( ) ) - > m_presets - > get_selected_preset_parent ( ) ! = nullptr ;
} ;
2018-04-16 09:03:08 +00:00
// optgroup->nonsys_btn_icon = m_bmp_non_system;
2018-03-16 11:56:03 +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 ;
for ( size_t i = 0 ; i < std : : strlen ( unusable_symbols ) ; i + + ) {
if ( m_chosen_name . find_first_of ( unusable_symbols [ i ] ) ! = std : : string : : npos ) {
is_unusable_symbol = true ;
break ;
}
}
if ( is_unusable_symbol ) {
2018-02-23 08:16:35 +00:00
show_error ( this , _ ( L ( " The supplied name is not valid; the following characters are not allowed: " ) ) + " <>:/ \\ |?* \" " ) ;
2018-01-18 10:45:25 +00:00
}
else if ( m_chosen_name . compare ( " - default - " ) = = 0 ) {
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 ) ;
}
}
}
2017-12-05 14:54:01 +00:00
} // GUI
} // Slic3r