diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index d678143da..752dcf096 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -32,6 +32,10 @@ sub OnInit { EVT_MENU($frame, wxID_EXIT, sub {$_[0]->Close(1)}); EVT_MENU($frame, wxID_ABOUT, \&About); + # status bar + $frame->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($frame, -1); + $frame->SetStatusBar($frame->{statusbar}); + # File menu my $fileMenu = Wx::Menu->new; $fileMenu->Append(1, "Save Config…"); @@ -87,4 +91,132 @@ sub warning_catcher { }; } +package Slic3r::GUI::ProgressStatusBar; +use base 'Wx::StatusBar'; + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + + $self->{_changed} = 0; + $self->{busy} = 0; + $self->{timer} = Wx::Timer->new($self); + $self->{prog} = Wx::Gauge->new($self, &Wx::wxGA_HORIZONTAL, 100, [-1,-1], [-1,-1]); + $self->{prog}->Hide; + + $self->SetFieldsCount(2); + $self->SetStatusWidths(-1, 155); + + Wx::Event::EVT_IDLE($self, sub { $self->_Reposition }); + Wx::Event::EVT_TIMER($self, \&OnTimer, $self->{timer}); + Wx::Event::EVT_SIZE($self, \&OnSize); + + return $self; +} + +sub DESTROY { + my $self = shift; + $self->{timer}->Stop if $self->{timer} && $self->{timer}->IsRunning; +} + +sub _Reposition { + my $self = shift; + + ##if ($self->{_changed}) { + my $rect = $self->GetFieldRect($self->GetFieldsCount - 1); + my $prog_pos = [$rect->GetX + 2, $rect->GetY + 2]; + $self->{prog}->Move($prog_pos); + $self->{prog}->SetSize($rect->GetWidth - 8, $rect->GetHeight - 4); + ##} + $self->{_changed} = 0; +} + +sub OnSize { + my ($self, $event) = @_; + + $self->{_changed} = 1; + $self->_Reposition; + $event->Skip; +} + +sub OnTimer { + my ($self, $event) = @_; + + if ($self->{prog}->IsShown) { + $self->{timer}->Stop; + } + $self->{prog}->Pulse if $self->{_busy}; +} + +sub Run { + my $self = shift; + my $rate = shift || 100; + if (!$self->{timer}->IsRunning) { + $self->{timer}->Start($rate); + } +} + +sub GetProgress { + my $self = shift; + return $self->{prog}->GetValue; +} + +sub SetProgress { + my $self = shift; + my ($val) = @_; + if (!$self->{prog}->IsShown) { + $self->ShowProgress(1); + } + if ($val == $self->{prog}->GetRange) { + $self->{prog}->SetValue(0); + $self->ShowProgress(0); + } else { + $self->{prog}->SetValue($val); + } +} + +sub SetRange { + my $self = shift; + my ($val) = @_; + + if ($val != $self->{prog}->GetRange) { + $self->{prog}->SetRange($val); + } +} + +sub ShowProgress { + my $self = shift; + my ($show) = @_; + + $self->_Reposition; + $self->{prog}->Show($show); + $self->{prog}->Pulse; +} + +sub StartBusy { + my $self = shift; + my $rate = shift || 100; + + $self->{_busy} = 1; + $self->_Reposition; + $self->ShowProgress(1); + if (!$self->{timer}->IsRunning) { + $self->{timer}->Start($rate); + } +} + +sub StopBusy { + my $self = shift; + + $self->{timer}->Stop; + $self->ShowProgress(0); + $self->{prog}->SetValue(0); + $self->{_busy} = 0; +} + +sub IsBusy { + my $self = shift; + return $self->{_busy}; +} + 1; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index fbbac9473..3c555ec05 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -49,13 +49,10 @@ sub new { EVT_LIST_ITEM_SELECTED($self, $self->{list}, \&list_item_selected); EVT_LIST_ITEM_DESELECTED($self, $self->{list}, \&list_item_deselected); - #$self->{vtoolbar} = Wx::ToolBar->new($self, -1, [-1, -1], [30, 180], &Wx::wxTB_VERTICAL); - #$self->{vtoolbar}->AddTool(1, '', Wx::Bitmap->new("$FindBin::Bin/var/brick_add.png", &Wx::wxBITMAP_TYPE_PNG), 'Foo...'); - Wx::ToolTip::Enable(1); - # toolbar for object manipulation $self->{htoolbar} = Wx::ToolBar->new($self, -1, [-1, -1], [-1, -1], &Wx::wxTB_HORIZONTAL | &Wx::wxTB_HORZ_TEXT); if ($self->{htoolbar}) { + Wx::ToolTip::Enable(1); $self->{htoolbar}->AddTool(TB_MORE, "More", Wx::Bitmap->new("$FindBin::Bin/var/add.png", &Wx::wxBITMAP_TYPE_PNG), ''); $self->{htoolbar}->AddTool(TB_LESS, "Less", Wx::Bitmap->new("$FindBin::Bin/var/delete.png", &Wx::wxBITMAP_TYPE_PNG), ''); $self->{htoolbar}->AddSeparator; @@ -121,8 +118,8 @@ sub new { EVT_TOOL($self, TB_LESS, \&decrease); EVT_TOOL($self, TB_45CW, sub { $_[0]->rotate(-45) }); EVT_TOOL($self, TB_45CCW, sub { $_[0]->rotate(45) }); - EVT_TOOL($self, TB_ROTATE, \&changescale); - EVT_TOOL($self, TB_SCALE, sub { $_[0]->rotate(undef) }); + EVT_TOOL($self, TB_ROTATE, sub { $_[0]->rotate(undef) }); + EVT_TOOL($self, TB_SCALE, \&changescale); EVT_TOOL($self, TB_SPLIT, \&split_object); } else { EVT_BUTTON($self, $self->{btn_increase}, \&increase); @@ -207,6 +204,7 @@ sub load_file { $process_dialog->Destroy; $self->object_loaded($obj_idx); + $self->statusbar->SetStatusText("Loaded $input_file"); } sub object_loaded { @@ -312,6 +310,9 @@ sub rotate { return if !$angle || $angle == -1; } + $self->statusbar->SetStatusText("Rotating object..."); + $self->statusbar->StartBusy; + # rotate, realign to 0,0 and update size $object->mesh->rotate($angle); $object->mesh->align_to_origin; @@ -321,6 +322,8 @@ sub rotate { $self->make_thumbnail($obj_idx); $self->arrange; + $self->statusbar->StopBusy; + $self->statusbar->SetStatusText(""); } sub arrange { @@ -343,6 +346,9 @@ sub changescale { $scale = Wx::GetNumberFromUser("", "Enter the scale % for the selected object:", "Scale", $scale*100, 0, 1000, $self); return if !$scale || $scale == -1; + $self->statusbar->SetStatusText("Scaling object..."); + $self->statusbar->StartBusy; + my $object = $self->{print}->objects->[$obj_idx]; my $mesh = $object->mesh; $mesh->scale($scale/100 / $self->{scale}[$obj_idx]); @@ -356,6 +362,8 @@ sub changescale { $self->make_thumbnail($obj_idx); $self->arrange; + $self->statusbar->StopBusy; + $self->statusbar->SetStatusText(""); } sub split_object { @@ -429,7 +437,6 @@ sub export_gcode { } else { $print->export_gcode(%params); } - $print->cleanup; Slic3r::GUI::warning_catcher($self)->($_) for @warnings; } $process_dialog->Destroy; @@ -445,8 +452,10 @@ sub export_gcode { $self->{growler}->notify(Event => 'SKEIN_DONE', Title => 'Slicing Done!', Message => $message) if ($self->{growler}); }; + $self->statusbar->SetStatusText("G-code file exported to $output_file"); Wx::MessageDialog->new($self, $message, 'Done!', wxOK | wxICON_INFORMATION)->ShowModal; + $print->cleanup; }; Slic3r::GUI::catch_error($self, sub { $process_dialog->Destroy if $process_dialog }); } @@ -485,6 +494,7 @@ sub export_stl { $mesh->align_to_origin; Slic3r::Format::STL->write_file($output_file, $mesh, 1); + $self->statusbar->SetStatusText("STL file exported to $output_file"); } sub make_thumbnail { @@ -703,6 +713,11 @@ sub selected_object_idx { return $self->{selected_objects}[0] ? $self->{selected_objects}[0][0] : $self->{list}->GetFirstSelected; } +sub statusbar { + my $self = shift; + return $self->GetParent->GetParent->GetParent->{statusbar}; +} + sub to_pixel { my $self = shift; return unscale $_[0] * $self->{scaling_factor};