diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 7f4a028a5..58c4964d9 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -269,6 +269,13 @@ sub save_settings { Slic3r::Config->write_ini("$datadir/slic3r.ini", $Settings); } +# Called after the Preferences dialog is closed and the program settings are saved. +# Update the UI based on the current preferences. +sub update_ui_from_settings { + my ($self) = @_; + $self->{mainframe}->update_ui_from_settings; +} + sub presets { my ($self, $section) = @_; diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 9aefb7b6c..ac81c48e0 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -83,6 +83,8 @@ sub new { # propagate event $event->Skip; }); + + $self->update_ui_from_settings; return $self; } @@ -212,9 +214,9 @@ sub _init_menubar { $self->_append_menu_item($fileMenu, "Slice to SV&G…\tCtrl+G", 'Slice file to SVG', sub { $self->quick_slice(save_as => 1, export_svg => 1); }, undef, 'shape_handles.png'); - $self->_append_menu_item($fileMenu, "(&Re)Slice Now\tCtrl+S", 'Start new slicing process', sub { - $self->reslice_now; - }, undef, 'shape_handles.png'); + $self->{menu_item_reslice_now} = $self->_append_menu_item( + $fileMenu, "(&Re)Slice Now\tCtrl+S", 'Start new slicing process', + sub { $self->reslice_now; }, undef, 'shape_handles.png'); $fileMenu->AppendSeparator(); $self->_append_menu_item($fileMenu, "Repair STL file…", 'Automatically repair an STL file', sub { $self->repair_stl; @@ -448,6 +450,13 @@ sub quick_slice { Slic3r::GUI::catch_error($self, sub { $progress_dialog->Destroy if $progress_dialog }); } +sub reslice_now { + my ($self) = @_; + if ($self->{plater}) { + $self->{plater}->reslice; + } +} + sub repair_stl { my $self = shift; @@ -803,4 +812,12 @@ sub _set_menu_item_icon { } } +# Called after the Preferences dialog is closed and the program settings are saved. +# Update the UI based on the current preferences. +sub update_ui_from_settings { + my ($self) = @_; + $self->{menu_item_reslice_now}->Enable(! $Slic3r::GUI::Settings->{_}{background_processing}); + $self->{plater}->update_ui_from_settings if ($self->{plater}); +} + 1; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 648fd3b1e..a8c117ccd 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -33,6 +33,7 @@ use constant TB_SETTINGS => &Wx::NewId; our $THUMBNAIL_DONE_EVENT : shared = Wx::NewEventType; our $PROGRESS_BAR_EVENT : shared = Wx::NewEventType; our $ERROR_EVENT : shared = Wx::NewEventType; +# Emitted from the worker thread when the G-code export is finished. our $EXPORT_COMPLETED_EVENT : shared = Wx::NewEventType; our $PROCESS_COMPLETED_EVENT : shared = Wx::NewEventType; @@ -191,8 +192,7 @@ sub new { # right pane buttons $self->{btn_export_gcode} = Wx::Button->new($self, -1, "Export G-code…", wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_reslice} = Wx::Button->new($self, -1, "Slice now…", wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_print} = Wx::Button->new($self, -1, "Print…", wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_reslice} = Wx::Button->new($self, -1, "Slice now", wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_print} = Wx::Button->new($self, -1, "Print…", wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_send_gcode} = Wx::Button->new($self, -1, "Send to printer", wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_export_stl} = Wx::Button->new($self, -1, "Export STL…", wxDefaultPosition, [-1, 30], wxBU_LEFT); @@ -210,6 +210,7 @@ sub new { export_gcode cog_go.png print arrow_up.png send_gcode arrow_up.png + reslice reslice.png export_stl brick_go.png increase add.png @@ -239,6 +240,7 @@ sub new { EVT_BUTTON($self, $self->{btn_send_gcode}, sub { $self->{send_gcode_file} = $self->export_gcode(Wx::StandardPaths::Get->GetTempDir()); }); + EVT_BUTTON($self, $self->{btn_reslice}, \&reslice); EVT_BUTTON($self, $self->{btn_export_stl}, \&export_stl); if ($self->{htoolbar}) { @@ -391,8 +393,10 @@ sub new { } my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); + $self->{buttons_sizer} = $buttons_sizer; $buttons_sizer->AddStretchSpacer(1); $buttons_sizer->Add($self->{btn_export_stl}, 0, wxALIGN_RIGHT, 0); + $buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); @@ -416,6 +420,8 @@ sub new { $sizer->SetSizeHints($self); $self->SetSizer($sizer); } + + $self->update_ui_from_settings(); return $self; } @@ -453,6 +459,25 @@ sub GetFrame { return &Wx::GetTopLevelParent($self); } +# Called after the Preferences dialog is closed and the program settings are saved. +# Update the UI based on the current preferences. +sub update_ui_from_settings +{ + my ($self) = @_; + if (defined($self->{btn_reslice}) && $self->{buttons_sizer}->IsShown($self->{btn_reslice}) != (! $Slic3r::GUI::Settings->{_}{background_processing})) { + $self->{buttons_sizer}->Show($self->{btn_reslice}, ! $Slic3r::GUI::Settings->{_}{background_processing}); + $self->{buttons_sizer}->Layout; + } +} + +# Update presets (Print settings, Filament, Printer) from their respective tabs. +# Called by +# Slic3r::GUI::Tab::Print::_on_presets_changed +# Slic3r::GUI::Tab::Filament::_on_presets_changed +# Slic3r::GUI::Tab::Printer::_on_presets_changed +# when the presets are loaded or the user selects another preset. +# For Print settings and Printer, synchronize the selection index with their tabs. +# For Filament, synchronize the selection index for a single extruder printer only, otherwise keep the selection. sub update_presets { my $self = shift; my ($group, $presets, $selected, $is_dirty) = @_; @@ -1109,6 +1134,22 @@ sub resume_background_process { } } +sub reslice { + # explicitly cancel a previous thread and start a new one. + my ($self) = @_; + # Don't reslice if export of G-code or sending to OctoPrint is running. + if ($Slic3r::have_threads && ! defined($self->{export_gcode_output_file}) && ! defined($self->{send_gcode_file})) { + $self->stop_background_process; + $self->statusbar->SetCancelCallback(sub { + $self->stop_background_process; + $self->statusbar->SetStatusText("Slicing cancelled"); + # this updates buttons status + $self->object_list_changed; + }); + $self->start_background_process; + } +} + sub export_gcode { my ($self, $output_file) = @_; @@ -1243,6 +1284,7 @@ sub on_progress_event { $self->statusbar->SetStatusText("$message…"); } +# Called when the G-code export finishes, either successfully or with an error. # This gets called also if we don't have threads. sub on_export_completed { my ($self, $result) = @_; @@ -1259,6 +1301,7 @@ sub on_export_completed { my $send_gcode = 0; my $do_print = 0; if ($result) { + # G-code file exported successfully. if ($self->{print_file}) { $message = "File added to print queue"; $do_print = 1; @@ -1276,6 +1319,7 @@ sub on_export_completed { wxTheApp->notify($message); $self->do_print if $do_print; + # Send $self->{send_gcode_file} to OctoPrint. $self->send_gcode if $send_gcode; $self->{print_file} = undef; $self->{send_gcode_file} = undef; @@ -1301,6 +1345,8 @@ sub do_print { $self->GetFrame->select_tab(1); } +# Send $self->{send_gcode_file} to OctoPrint. +#FIXME Currently this call blocks the UI. Make it asynchronous. sub send_gcode { my ($self) = @_; @@ -1611,15 +1657,19 @@ sub object_settings_dialog { } } +# Called to update various buttons depending on whether there are any objects or +# whether background processing (export of a G-code, sending to Octoprint, forced background re-slicing) is active. sub object_list_changed { my $self = shift; + # Enable/disable buttons depending on whether there are any objects on the platter. my $have_objects = @{$self->{objects}} ? 1 : 0; my $method = $have_objects ? 'Enable' : 'Disable'; $self->{"btn_$_"}->$method - for grep $self->{"btn_$_"}, qw(reslice reset arrange export_gcode export_stl print send_gcode); + for grep $self->{"btn_$_"}, qw(reset arrange reslice export_gcode export_stl print send_gcode); if ($self->{export_gcode_output_file} || $self->{send_gcode_file}) { + $self->{btn_reslice}->Disable; $self->{btn_export_gcode}->Disable; $self->{btn_print}->Disable; $self->{btn_send_gcode}->Disable; diff --git a/lib/Slic3r/GUI/Preferences.pm b/lib/Slic3r/GUI/Preferences.pm index ed210d229..8455304e9 100644 --- a/lib/Slic3r/GUI/Preferences.pm +++ b/lib/Slic3r/GUI/Preferences.pm @@ -91,6 +91,9 @@ sub _accept { $self->EndModal(wxID_OK); $self->Close; # needed on Linux + + # Nothify the UI to update itself from the ini file. + wxTheApp->update_ui_from_settings; } 1; diff --git a/var/reslice.png b/var/reslice.png new file mode 100644 index 000000000..167c0eccd Binary files /dev/null and b/var/reslice.png differ