diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index a88e513b0f..6a19461992 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -42,6 +42,17 @@ use constant MI_PLATER_EXPORT_GCODE => &Wx::NewId; use constant MI_PLATER_EXPORT_STL => &Wx::NewId; use constant MI_PLATER_EXPORT_AMF => &Wx::NewId; +use constant MI_OBJECT_REMOVE => &Wx::NewId; +use constant MI_OBJECT_MORE => &Wx::NewId; +use constant MI_OBJECT_FEWER => &Wx::NewId; +use constant MI_OBJECT_ROTATE_45CW => &Wx::NewId; +use constant MI_OBJECT_ROTATE_45CCW => &Wx::NewId; +use constant MI_OBJECT_ROTATE => &Wx::NewId; +use constant MI_OBJECT_SCALE => &Wx::NewId; +use constant MI_OBJECT_SPLIT => &Wx::NewId; +use constant MI_OBJECT_VIEWCUT => &Wx::NewId; +use constant MI_OBJECT_SETTINGS => &Wx::NewId; + use constant MI_TAB_PLATER => &Wx::NewId; use constant MI_TAB_PRINT => &Wx::NewId; use constant MI_TAB_FILAMENT => &Wx::NewId; @@ -160,15 +171,41 @@ sub OnInit { } # Plater menu - my $platerMenu; unless ($no_plater) { - $platerMenu = Wx::Menu->new; - $platerMenu->Append(MI_PLATER_EXPORT_GCODE, "Export G-code...", 'Export current plate as G-code'); - $platerMenu->Append(MI_PLATER_EXPORT_STL, "Export STL...", 'Export current plate as STL'); - $platerMenu->Append(MI_PLATER_EXPORT_AMF, "Export AMF...", 'Export current plate as AMF'); - EVT_MENU($frame, MI_PLATER_EXPORT_GCODE, sub { $self->{skeinpanel}{plater}->export_gcode }); - EVT_MENU($frame, MI_PLATER_EXPORT_STL, sub { $self->{skeinpanel}{plater}->export_stl }); - EVT_MENU($frame, MI_PLATER_EXPORT_AMF, sub { $self->{skeinpanel}{plater}->export_amf }); + my $plater = $self->{skeinpanel}{plater}; + + $frame->{plater_menu} = Wx::Menu->new; + $frame->{plater_menu}->Append(MI_PLATER_EXPORT_GCODE, "Export G-code...", 'Export current plate as G-code'); + $frame->{plater_menu}->Append(MI_PLATER_EXPORT_STL, "Export STL...", 'Export current plate as STL'); + $frame->{plater_menu}->Append(MI_PLATER_EXPORT_AMF, "Export AMF...", 'Export current plate as AMF'); + EVT_MENU($frame, MI_PLATER_EXPORT_GCODE, sub { $plater->export_gcode }); + EVT_MENU($frame, MI_PLATER_EXPORT_STL, sub { $plater->export_stl }); + EVT_MENU($frame, MI_PLATER_EXPORT_AMF, sub { $plater->export_amf }); + + $frame->{object_menu} = Wx::Menu->new; + $frame->{object_menu}->Append(MI_OBJECT_REMOVE, "Delete\tCtrl+Del", 'Remove the selected object'); + $frame->{object_menu}->Append(MI_OBJECT_MORE, "Increase copies\tCtrl++", 'Place one more copy of the selected object'); + $frame->{object_menu}->Append(MI_OBJECT_FEWER, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object'); + $frame->{object_menu}->AppendSeparator(); + $frame->{object_menu}->Append(MI_OBJECT_ROTATE_45CW, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise'); + $frame->{object_menu}->Append(MI_OBJECT_ROTATE_45CCW, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise'); + $frame->{object_menu}->Append(MI_OBJECT_ROTATE, "Rotate…", 'Rotate the selected object by an arbitrary angle around Z axis'); + $frame->{object_menu}->Append(MI_OBJECT_SCALE, "Scale…", 'Scale the selected object by an arbitrary factor'); + $frame->{object_menu}->Append(MI_OBJECT_SPLIT, "Split", 'Split the selected object into individual parts'); + $frame->{object_menu}->Append(MI_OBJECT_VIEWCUT, "View/Cut…", 'Open the 3D cutting tool'); + $frame->{object_menu}->AppendSeparator(); + $frame->{object_menu}->Append(MI_OBJECT_SETTINGS, "Settings…", 'Open the object editor dialog'); + EVT_MENU($frame, MI_OBJECT_REMOVE, sub { $plater->remove }); + EVT_MENU($frame, MI_OBJECT_MORE, sub { $plater->increase }); + EVT_MENU($frame, MI_OBJECT_FEWER, sub { $plater->decrease }); + EVT_MENU($frame, MI_OBJECT_ROTATE_45CW, sub { $plater->rotate(-45) }); + EVT_MENU($frame, MI_OBJECT_ROTATE_45CCW, sub { $plater->rotate(45) }); + EVT_MENU($frame, MI_OBJECT_ROTATE, sub { $plater->rotate(undef) }); + EVT_MENU($frame, MI_OBJECT_SCALE, sub { $plater->changescale }); + EVT_MENU($frame, MI_OBJECT_SPLIT, sub { $plater->split_object }); + EVT_MENU($frame, MI_OBJECT_VIEWCUT, sub { $plater->object_cut_dialog }); + EVT_MENU($frame, MI_OBJECT_SETTINGS, sub { $plater->object_settings_dialog }); + $self->on_plater_selection_changed(0); } # Window menu @@ -209,7 +246,8 @@ sub OnInit { { my $menubar = Wx::MenuBar->new; $menubar->Append($fileMenu, "&File"); - $menubar->Append($platerMenu, "&Plater") if $platerMenu; + $menubar->Append($frame->{plater_menu}, "&Plater") if $frame->{plater_menu}; + $menubar->Append($frame->{object_menu}, "&Object") if $frame->{object_menu}; $menubar->Append($windowMenu, "&Window"); $menubar->Append($helpMenu, "&Help"); $frame->SetMenuBar($menubar); @@ -254,6 +292,14 @@ sub OnInit { return 1; } +sub on_plater_selection_changed { + my ($self, $have_selection) = @_; + + return if !defined $self->{object_menu}; + $self->{object_menu}->Enable($_->GetId, $have_selection) + for $self->{object_menu}->GetMenuItems; +} + sub about { my $frame = shift; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 8dd1ab05f6..9f4f1ab2de 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -8,7 +8,8 @@ use List::Util qw(sum first); use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale); use threads::shared qw(shared_clone); use Thread::Semaphore; -use Wx qw(:button :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc :panel :sizer :toolbar :window); +use Wx qw(:button :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc + :panel :sizer :toolbar :window); use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE EVT_TIMER); @@ -357,6 +358,11 @@ sub on_select_preset { $self->skeinpanel->{options_tabs}{$group}->select_preset($choice->GetSelection); } +sub GetFrame { + my ($self) = @_; + return &Wx::GetTopLevelParent($self); +} + sub skeinpanel { my $self = shift; return $self->GetParent->GetParent; @@ -569,7 +575,7 @@ sub rotate { $model_object->update_bounding_box; # update print and start background processing - $self->suspend_background_process; + $self->stop_background_process; $self->{print}->add_model_object($model_object, $obj_idx); $self->schedule_background_process; @@ -606,7 +612,7 @@ sub changescale { $model_object->update_bounding_box; # update print and start background processing - $self->suspend_background_process; + $self->stop_background_process; $self->{print}->add_model_object($model_object, $obj_idx); $self->schedule_background_process; @@ -653,7 +659,7 @@ sub split_object { return; } - $self->suspend_background_process; + $self->stop_background_process; # create a bogus Model object, we only need to instantiate the new Model::Object objects my $new_model = Slic3r::Model->new; @@ -814,7 +820,6 @@ sub suspend_background_process { sub resume_background_process { my ($self) = @_; - $sema->up; } @@ -1244,6 +1249,10 @@ sub selection_changed { } $self->Layout; } + + # prepagate the event to the frame (a custom Wx event would be cleaner) + ###$self->GetFrame->on_plater_selection_changed($have_sel); + Slic3r::GUI::on_plater_selection_changed($self->GetFrame, $have_sel); } sub select_object {