diff --git a/lib/Slic3r/GUI/Controller.pm b/lib/Slic3r/GUI/Controller.pm index aba007d9a0..5eb2606f63 100644 --- a/lib/Slic3r/GUI/Controller.pm +++ b/lib/Slic3r/GUI/Controller.pm @@ -23,6 +23,11 @@ sub new { EVT_LEFT_DOWN($btn, sub { my $menu = Wx::Menu->new; my %presets = wxTheApp->presets('printer'); + + # remove printers that already exist + my @panels = $self->print_panels; + delete $presets{$_} for map $_->printer_name, @panels; + foreach my $preset_name (sort keys %presets) { my $config = Slic3r::Config->load($presets{$preset_name}); next if !$config->serial_port; @@ -67,23 +72,59 @@ sub new { $event->Skip; }); - { - my %presets = wxTheApp->presets('printer'); - my %configs = map { my $name = $_; $name => Slic3r::Config->load($presets{$name}) } keys %presets; - my @presets_with_printer = grep $configs{$_}->serial_port, keys %presets; - - if (@presets_with_printer == 1) { - # if only one preset exists, load it - my $name = $presets_with_printer[0]; - $self->add_printer($name, $configs{$name}); - } - } - $self->Layout; return $self; } +sub OnActivate { + my ($self) = @_; + + # get all available presets + my %presets = (); + { + my %all = wxTheApp->presets('printer'); + my %configs = map { my $name = $_; $name => Slic3r::Config->load($all{$name}) } keys %all; + %presets = map { $_ => $configs{$_} } grep $configs{$_}->serial_port, keys %all; + } + + # decide which ones we want to keep + my %active = (); + + # keep the ones that are currently connected or have jobs in queue + $active{$_} = 1 for map $_->printer_name, + grep { $_->is_connected || @{$_->jobs} > 0 } + $self->print_panels; + + # if there are no active panels, use sensible defaults + if (!%active) { + if (keys %presets <= 2) { + # if only one or two presets exist, load them + $active{$_} = 1 for keys %presets; + } else { + # enable printers whose port is available + my %ports = map { $_ => 1 } wxTheApp->scan_serial_ports; + $active{$_} = 1 + for grep exists $ports{$presets{$_}->serial_port}, keys %presets; + } + } + + # apply changes + for my $panel ($self->print_panels) { + next if $active{$panel->printer_name}; + + $self->{sizer}->DetachWindow($panel); + $panel->Destroy; + } + $self->add_printer($_, $presets{$_}) for sort keys %active; + + $self->Layout; + + # we need this in order to trigger the OnSize event of wxScrolledWindow which + # recalculates the virtual size + Wx::GetTopLevelParent($self)->SendSizeEvent; +} + sub add_printer { my ($self, $printer_name, $config) = @_; diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 3111331df4..bc89eb7c82 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -8,7 +8,7 @@ use List::Util qw(min); use Slic3r::Geometry qw(X Y Z); use Wx qw(:frame :bitmap :id :misc :notebook :panel :sizer :menu :dialog :filedialog :font :icon wxTheApp); -use Wx::Event qw(EVT_CLOSE EVT_MENU); +use Wx::Event qw(EVT_CLOSE EVT_MENU EVT_NOTEBOOK_PAGE_CHANGED); use base 'Wx::Frame'; our $qs_last_input_file; @@ -89,6 +89,10 @@ sub _init_tabpanel { my ($self) = @_; $self->{tabpanel} = my $panel = Wx::Notebook->new($self, -1, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL); + EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub { + my $panel = $self->{tabpanel}->GetCurrentPage; + $panel->OnActivate if $panel->can('OnActivate'); + }); if (!$self->{no_plater}) { $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel), "Plater");