Browse Source

Show contextual menu when right-clicking on a plater object

Alessandro Ranellucci 10 years ago
parent
commit
182c5eb809
3 changed files with 97 additions and 64 deletions
  1. 1 55
      lib/Slic3r/GUI/MainFrame.pm
  2. 73 0
      lib/Slic3r/GUI/Plater.pm
  3. 23 9
      lib/Slic3r/GUI/Plater/2D.pm

+ 1 - 55
lib/Slic3r/GUI/MainFrame.pm

@@ -176,61 +176,7 @@ sub _init_menubar {
             $plater->export_amf;
         });
         
-        $self->{object_menu} = Wx::Menu->new;
-        $self->_append_menu_item($self->{object_menu}, "Delete\tCtrl+Del", 'Remove the selected object', sub {
-            $plater->remove;
-        });
-        $self->_append_menu_item($self->{object_menu}, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub {
-            $plater->increase;
-        });
-        $self->_append_menu_item($self->{object_menu}, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub {
-            $plater->decrease;
-        });
-        $self->{object_menu}->AppendSeparator();
-        $self->_append_menu_item($self->{object_menu}, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub {
-            $plater->rotate(-45);
-        });
-        $self->_append_menu_item($self->{object_menu}, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub {
-            $plater->rotate(+45);
-        });
-        
-        my $rotateMenu = Wx::Menu->new;
-        $self->{object_menu}->AppendSubMenu($rotateMenu, "Rotate…", 'Rotate the selected object by an arbitrary angle');
-        $self->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub {
-            $plater->rotate(undef, X);
-        });
-        $self->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub {
-            $plater->rotate(undef, Y);
-        });
-        $self->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub {
-            $plater->rotate(undef, Z);
-        });
-        
-        my $flipMenu = Wx::Menu->new;
-        $self->{object_menu}->AppendSubMenu($flipMenu, "Flip…", 'Mirror the selected object');
-        $self->_append_menu_item($flipMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
-            $plater->flip(X);
-        });
-        $self->_append_menu_item($flipMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub {
-            $plater->flip(Y);
-        });
-        $self->_append_menu_item($flipMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub {
-            $plater->flip(Z);
-        });
-        
-        $self->_append_menu_item($self->{object_menu}, "Scale…", 'Scale the selected object by an arbitrary factor', sub {
-            $plater->changescale;
-        });
-        $self->_append_menu_item($self->{object_menu}, "Split", 'Split the selected object into individual parts', sub {
-            $plater->split_object;
-        });
-        $self->_append_menu_item($self->{object_menu}, "View/Cut…", 'Open the 3D cutting tool', sub {
-            $plater->object_cut_dialog;
-        });
-        $self->{object_menu}->AppendSeparator();
-        $self->_append_menu_item($self->{object_menu}, "Settings…", 'Open the object editor dialog', sub {
-            $plater->object_settings_dialog;
-        });
+        $self->{object_menu} = $self->{plater}->object_menu;
         $self->on_plater_selection_changed(0);
     }
     

+ 73 - 0
lib/Slic3r/GUI/Plater.pm

@@ -77,6 +77,16 @@ sub new {
     $self->{canvas}->on_double_click(sub {
         $self->object_cut_dialog if $self->selected_object;
     });
+    $self->{canvas}->on_right_click(sub {
+        my ($click_pos) = @_;
+        
+        my ($obj_idx, $object) = $self->selected_object;
+        return if !defined $obj_idx;
+        
+        my $menu = $self->object_menu;
+        $self->{canvas}->PopupMenu($menu, $click_pos);
+        $menu->Destroy;
+    });
     $self->{canvas}->on_instance_moved(sub {
         $self->update;
     });
@@ -1337,6 +1347,69 @@ sub statusbar {
     return $self->GetFrame->{statusbar};
 }
 
+sub object_menu {
+    my ($self) = @_;
+    
+    my $frame = $self->GetFrame;
+    my $menu = Wx::Menu->new;
+    $frame->_append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub {
+        $self->remove;
+    });
+    $frame->_append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub {
+        $self->increase;
+    });
+    $frame->_append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub {
+        $self->decrease;
+    });
+    $menu->AppendSeparator();
+    $frame->_append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub {
+        $self->rotate(-45);
+    });
+    $frame->_append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub {
+        $self->rotate(+45);
+    });
+    
+    my $rotateMenu = Wx::Menu->new;
+    $menu->AppendSubMenu($rotateMenu, "Rotate…", 'Rotate the selected object by an arbitrary angle');
+    $frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub {
+        $self->rotate(undef, X);
+    });
+    $frame->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub {
+        $self->rotate(undef, Y);
+    });
+    $frame->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub {
+        $self->rotate(undef, Z);
+    });
+    
+    my $flipMenu = Wx::Menu->new;
+    $menu->AppendSubMenu($flipMenu, "Flip…", 'Mirror the selected object');
+    $frame->_append_menu_item($flipMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
+        $self->flip(X);
+    });
+    $frame->_append_menu_item($flipMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub {
+        $self->flip(Y);
+    });
+    $frame->_append_menu_item($flipMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub {
+        $self->flip(Z);
+    });
+    
+    $frame->_append_menu_item($menu, "Scale…", 'Scale the selected object by an arbitrary factor', sub {
+        $self->changescale;
+    });
+    $frame->_append_menu_item($menu, "Split", 'Split the selected object into individual parts', sub {
+        $self->split_object;
+    });
+    $frame->_append_menu_item($menu, "View/Cut…", 'Open the 3D cutting tool', sub {
+        $self->object_cut_dialog;
+    });
+    $menu->AppendSeparator();
+    $frame->_append_menu_item($menu, "Settings…", 'Open the object editor dialog', sub {
+        $self->object_settings_dialog;
+    });
+    
+    return $menu;
+}
+
 package Slic3r::GUI::Plater::DropTarget;
 use Wx::DND;
 use base 'Wx::FileDropTarget';

+ 23 - 9
lib/Slic3r/GUI/Plater/2D.pm

@@ -26,6 +26,7 @@ sub new {
     $self->{config}             = $config;
     $self->{on_select_object}   = sub {};
     $self->{on_double_click}    = sub {};
+    $self->{on_right_click}     = sub {};
     $self->{on_instance_moved}  = sub {};
     
     $self->{objects_brush}      = Wx::Brush->new(Wx::Colour->new(210,210,210), wxSOLID);
@@ -53,6 +54,11 @@ sub on_double_click {
     $self->{on_double_click} = $cb;
 }
 
+sub on_right_click {
+    my ($self, $cb) = @_;
+    $self->{on_right_click} = $cb;
+}
+
 sub on_instance_moved {
     my ($self, $cb) = @_;
     $self->{on_instance_moved} = $cb;
@@ -170,21 +176,29 @@ sub mouse_event {
     my $point = $event->GetPosition;
     my $pos = $self->point_to_model_units([ $point->x, $point->y ]);  #]]
     $pos = Slic3r::Point->new_scale(@$pos);
-    if ($event->ButtonDown(&Wx::wxMOUSE_BTN_LEFT)) {
+    if ($event->ButtonDown) {
         $self->{on_select_object}->(undef);
-        for my $obj_idx (0 .. $#{$self->{objects}}) {
+        OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) {
             my $object = $self->{objects}->[$obj_idx];
             for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) {
                 my $thumbnail = $object->instance_thumbnails->[$instance_idx];
                 if (defined first { $_->contour->contains_point($pos) } @$thumbnail) {
                     $self->{on_select_object}->($obj_idx);
-                    my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx];
-                    my $instance_origin = [ map scale($_), @{$instance->offset} ];
-                    $self->{drag_start_pos} = [   # displacement between the click and the instance origin in scaled model units
-                        $pos->x - $instance_origin->[X],
-                        $pos->y - $instance_origin->[Y],  #-
-                    ];
-                    $self->{drag_object} = [ $obj_idx, $instance_idx ];
+                    
+                    if ($event->LeftDown) {
+                        # start dragging
+                        my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx];
+                        my $instance_origin = [ map scale($_), @{$instance->offset} ];
+                        $self->{drag_start_pos} = [   # displacement between the click and the instance origin in scaled model units
+                            $pos->x - $instance_origin->[X],
+                            $pos->y - $instance_origin->[Y],  #-
+                        ];
+                        $self->{drag_object} = [ $obj_idx, $instance_idx ];
+                    } elsif ($event->RightDown) {
+                        $self->{on_right_click}->($point);
+                    }
+                    
+                    last OBJECTS;
                 }
             }
         }