123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- # The "Controller" tab to control the printer using serial / USB.
- # This feature is rarely used. Much more often, the firmware reads the G-codes from a SD card.
- # May there be multiple subtabs per each printer connected?
- package Slic3r::GUI::Controller;
- use strict;
- use warnings;
- use utf8;
- use Wx qw(wxTheApp :frame :id :misc :sizer :bitmap :button :icon :dialog);
- use Wx::Event qw(EVT_CLOSE EVT_LEFT_DOWN EVT_MENU);
- use base qw(Wx::ScrolledWindow Class::Accessor);
- use List::Util qw(first);
- __PACKAGE__->mk_accessors(qw(_selected_printer_preset));
- our @ConfigOptions = qw(bed_shape serial_port serial_speed);
- sub new {
- my ($class, $parent) = @_;
- my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [600,350]);
-
- $self->SetScrollbars(0, 1, 0, 1);
- $self->{sizer} = my $sizer = Wx::BoxSizer->new(wxVERTICAL);
-
- # warning to show when there are no printers configured
- {
- $self->{text_no_printers} = Wx::StaticText->new($self, -1,
- "No printers were configured for USB/serial control.",
- wxDefaultPosition, wxDefaultSize);
- $self->{sizer}->Add($self->{text_no_printers}, 0, wxTOP | wxLEFT, 30);
- }
-
- # button for adding new printer panels
- {
- my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("add.png"), wxBITMAP_TYPE_PNG),
- wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
- $btn->SetToolTipString("Add printer…")
- if $btn->can('SetToolTipString');
-
- EVT_LEFT_DOWN($btn, sub {
- my $menu = Wx::Menu->new;
- my @panels = $self->print_panels;
- # remove printers that already exist
- # update configs of currently loaded print panels
- foreach my $preset (@{wxTheApp->{preset_bundle}->printer}) {
- my $preset_name = $preset->name;
- next if ! $preset->config->serial_port ||
- defined first { defined $_ && $_->printer_name eq $preset_name } @panels;
- my $myconfig = $preset->config->clone_only(\@ConfigOptions);
- my $id = &Wx::NewId();
- $menu->Append($id, $preset_name);
- EVT_MENU($menu, $id, sub {
- $self->add_printer($preset_name, $myconfig);
- });
- }
- $self->PopupMenu($menu, $btn->GetPosition);
- $menu->Destroy;
- });
- $self->{sizer}->Add($btn, 0, wxTOP | wxLEFT, 10);
- }
-
- $self->SetSizer($sizer);
- $self->SetMinSize($self->GetSize);
- #$sizer->SetSizeHints($self);
-
- EVT_CLOSE($self, sub {
- my (undef, $event) = @_;
-
- if ($event->CanVeto) {
- foreach my $panel ($self->print_panels) {
- if ($panel->printing) {
- my $confirm = Wx::MessageDialog->new(
- $self, "Printer '" . $panel->printer_name . "' is printing.\n\nDo you want to stop printing?",
- 'Unfinished Print', wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
- );
- if ($confirm->ShowModal == wxID_NO) {
- $event->Veto;
- return;
- }
- }
- }
- }
- foreach my $panel ($self->print_panels) {
- $panel->disconnect;
- }
-
- $event->Skip;
- });
-
- $self->Layout;
-
- return $self;
- }
- sub OnActivate {
- my ($self) = @_;
-
- # get all available presets
- my %presets = map { $_->name => $_->config->clone_only(\@ConfigOptions) }
- grep { $_->config->serial_port } @{wxTheApp->{preset_bundle}->printer};
-
- # 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 (%presets) {
- # if there are no active panels, use sensible defaults
- if (!%active && keys %presets <= 2) {
- # if only one or two presets exist, load them
- $active{$_} = 1 for keys %presets;
- }
- if (!%active) {
- # enable printers whose port is available
- my %ports = map { $_ => 1 } Slic3r::GUI::scan_serial_ports;
- $active{$_} = 1
- for grep exists $ports{$presets{$_}->serial_port}, keys %presets;
- }
- if (!%active && $self->_selected_printer_preset) {
- # enable currently selected printer if it is configured
- $active{$self->_selected_printer_preset} = 1
- if $presets{$self->_selected_printer_preset};
- }
- }
-
- # 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;
-
- # show/hide the warning about no printers
- $self->{text_no_printers}->Show(!%presets);
-
- # show/hide the Add button
- $self->{btn_add}->Show(keys %presets != 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) = @_;
-
- # check that printer doesn't exist already
- foreach my $panel ($self->print_panels) {
- if ($panel->printer_name eq $printer_name) {
- return $panel;
- }
- }
-
- my $printer_panel = Slic3r::GUI::Controller::PrinterPanel->new($self, $printer_name, $config);
- $self->{sizer}->Prepend($printer_panel, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10);
- $self->Layout;
-
- return $printer_panel;
- }
- sub print_panels {
- my ($self) = @_;
- return grep $_->isa('Slic3r::GUI::Controller::PrinterPanel'),
- map $_->GetWindow, $self->{sizer}->GetChildren;
- }
- # Called by Slic3r::GUI::Tab::Printer::_on_presets_changed
- # when the presets are loaded or the user selects another preset.
- sub update_presets {
- my ($self, $presets) = @_;
- # update configs of currently loaded print panels
- my @presets = @$presets;
- foreach my $panel ($self->print_panels) {
- my $preset = $presets->find_preset($panel->printer_name, 0);
- $panel->config($preset->config->clone_only(\@ConfigOptions))
- if defined $preset;
- }
- $self->_selected_printer_preset($presets->get_selected_preset->name);
- }
- 1;
|