mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' into plater2
Conflicts: lib/Slic3r/GUI/Plater.pm
This commit is contained in:
		
						commit
						5b734f4a13
					
				
					 13 changed files with 292 additions and 72 deletions
				
			
		|  | @ -36,6 +36,7 @@ Slic3r::GUI::OptionsGroup - pre-filled Wx::StaticBoxSizer wrapper containing one | |||
|         on_change   => sub { print "new value for $_[0] is $_[1]\n" }, | ||||
|         no_labels   => 0, | ||||
|         label_width => 180, | ||||
|         extra_column => sub { ... }, | ||||
|     ); | ||||
|     $sizer->Add($optgroup->sizer); | ||||
| 
 | ||||
|  | @ -48,6 +49,7 @@ has 'lines'         => (is => 'lazy'); | |||
| has 'on_change'     => (is => 'ro', default => sub { sub {} }); | ||||
| has 'no_labels'     => (is => 'ro', default => sub { 0 }); | ||||
| has 'label_width'   => (is => 'ro', default => sub { 180 }); | ||||
| has 'extra_column'  => (is => 'ro'); | ||||
| 
 | ||||
| has 'sizer'         => (is => 'rw'); | ||||
| has '_triggers'     => (is => 'ro', default => sub { {} }); | ||||
|  | @ -63,7 +65,8 @@ sub BUILD { | |||
|         $self->sizer(Wx::StaticBoxSizer->new($box, wxVERTICAL)); | ||||
|     } | ||||
|      | ||||
|     my $grid_sizer = Wx::FlexGridSizer->new(scalar(@{$self->options}), 2, 0, 0); | ||||
|     my $num_columns = $self->extra_column ? 3 : 2; | ||||
|     my $grid_sizer = Wx::FlexGridSizer->new(scalar(@{$self->options}), $num_columns, 0, 0); | ||||
|     $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); | ||||
|     $grid_sizer->AddGrowableCol($self->no_labels ? 0 : 1); | ||||
|      | ||||
|  | @ -113,6 +116,10 @@ sub _build_line { | |||
|     my $self = shift; | ||||
|     my ($line, $grid_sizer) = @_; | ||||
|      | ||||
|     if ($self->extra_column) { | ||||
|         $grid_sizer->Add($self->extra_column->($line), 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
|     } | ||||
|      | ||||
|     my $label; | ||||
|     if (!$self->no_labels) { | ||||
|         $label = Wx::StaticText->new($self->parent, -1, $line->{label} ? "$line->{label}:" : "", wxDefaultPosition, [$self->label_width, -1]); | ||||
|  | @ -291,6 +298,7 @@ Slic3r::GUI::ConfigOptionsGroup - pre-filled Wx::StaticBoxSizer wrapper containi | |||
| use List::Util qw(first); | ||||
| 
 | ||||
| has 'config' => (is => 'ro', required => 1); | ||||
| has 'full_labels' => (is => 'ro', default => sub {0}); | ||||
| 
 | ||||
| sub _trigger_options { | ||||
|     my $self = shift; | ||||
|  | @ -304,7 +312,8 @@ sub _trigger_options { | |||
|             $opt = { | ||||
|                 opt_key     => $full_key, | ||||
|                 config      => 1, | ||||
|                 (map { $_   => $config_opt->{$_} } qw(type label tooltip sidetext width height full_width min max labels values multiline readonly)), | ||||
|                 label       => ($self->full_labels && defined $config_opt->{full_label}) ? $config_opt->{full_label} : $config_opt->{label}, | ||||
|                 (map { $_   => $config_opt->{$_} } qw(type tooltip sidetext width height full_width min max labels values multiline readonly)), | ||||
|                 default     => $self->_get_config($opt_key, $index), | ||||
|                 on_change   => sub { $self->_set_config($opt_key, $index, $_[0]) }, | ||||
|             }; | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ use constant TB_ARRANGE         => &Wx::NewId; | |||
| use constant TB_EXPORT_GCODE    => &Wx::NewId; | ||||
| use constant TB_EXPORT_STL      => &Wx::NewId; | ||||
| use constant TB_MORE    => &Wx::NewId; | ||||
| use constant TB_LESS    => &Wx::NewId; | ||||
| use constant TB_FEWER   => &Wx::NewId; | ||||
| use constant TB_INFO    => &Wx::NewId; | ||||
| use constant TB_45CW    => &Wx::NewId; | ||||
| use constant TB_45CCW   => &Wx::NewId; | ||||
|  | @ -71,11 +71,11 @@ sub new { | |||
|         $self->{htoolbar}->AddTool(TB_LOAD, "Add…", Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_REMOVE, "Delete", Wx::Bitmap->new("$Slic3r::var/brick_delete.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_RESET, "Delete All", Wx::Bitmap->new("$Slic3r::var/cross.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_ARRANGE, "Autoarrange", Wx::Bitmap->new("$Slic3r::var/bricks.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_ARRANGE, "Arrange", Wx::Bitmap->new("$Slic3r::var/bricks.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddSeparator; | ||||
|         $self->{htoolbar}->AddTool(TB_INFO, "Open", Wx::Bitmap->new("$Slic3r::var/package.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_MORE, "More", Wx::Bitmap->new("$Slic3r::var/add.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_LESS, "Fewer", Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_FEWER, "Fewer", Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddSeparator; | ||||
|         $self->{htoolbar}->AddTool(TB_45CCW, "45° ccw", Wx::Bitmap->new("$Slic3r::var/arrow_rotate_anticlockwise.png", wxBITMAP_TYPE_PNG), ''); | ||||
|         $self->{htoolbar}->AddTool(TB_45CW, "45° cw", Wx::Bitmap->new("$Slic3r::var/arrow_rotate_clockwise.png", wxBITMAP_TYPE_PNG), ''); | ||||
|  | @ -84,10 +84,22 @@ sub new { | |||
|         $self->{htoolbar}->AddSeparator; | ||||
|         $self->{htoolbar}->AddTool(TB_SPLIT, "Split", Wx::Bitmap->new("$Slic3r::var/shape_ungroup.png", wxBITMAP_TYPE_PNG), ''); | ||||
|     } else { | ||||
|         my %tbar_buttons = (info => "Open", increase => "More", decrease => "Less", rotate45ccw => "45°", rotate45cw => "45°", | ||||
|             rotate => "Rotate…", changescale => "Scale…", split => "Split"); | ||||
|         my %tbar_buttons = ( | ||||
|             load            => "Add…", | ||||
|             remove          => "Delete", | ||||
|             reset           => "Delete All", | ||||
|             arrange         => "Arrange", | ||||
|             info            => "Open", | ||||
|             increase        => "", | ||||
|             decrease        => "", | ||||
|             rotate45ccw     => "", | ||||
|             rotate45cw      => "", | ||||
|             rotate          => "Rotate…", | ||||
|             changescale     => "Scale…", | ||||
|             split           => "Split", | ||||
|         ); | ||||
|         $self->{btoolbar} = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|         for (qw(load remove reset arrange open increase decrease rotate45ccw rotate45cw rotate changescale split)) { | ||||
|         for (qw(load remove reset arrange info increase decrease rotate45ccw rotate45cw rotate changescale split)) { | ||||
|             $self->{"btn_$_"} = Wx::Button->new($self, -1, $tbar_buttons{$_}, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); | ||||
|             $self->{btoolbar}->Add($self->{"btn_$_"}); | ||||
|         } | ||||
|  | @ -124,7 +136,7 @@ sub new { | |||
|             export_gcode    cog_go.png | ||||
|             export_stl      brick_go.png | ||||
|              | ||||
|             open            package.png | ||||
|             info            package.png | ||||
|             increase        add.png | ||||
|             decrease        delete.png | ||||
|             rotate45cw      arrow_rotate_clockwise.png | ||||
|  | @ -147,16 +159,20 @@ sub new { | |||
|         EVT_TOOL($self, TB_REMOVE, sub { $self->remove() }); # explicitly pass no argument to remove | ||||
|         EVT_TOOL($self, TB_RESET, \&reset); | ||||
|         EVT_TOOL($self, TB_ARRANGE, \&arrange); | ||||
|         EVT_TOOL($self, TB_INFO, sub { $_[0]->object_dialog }); | ||||
|         EVT_TOOL($self, TB_MORE, \&increase); | ||||
|         EVT_TOOL($self, TB_LESS, \&decrease); | ||||
|         EVT_TOOL($self, TB_INFO, sub { $self->list_item_activated(undef, $self->{selected_objects}->[0][0]) }); | ||||
|         EVT_TOOL($self, TB_FEWER, \&decrease); | ||||
|         EVT_TOOL($self, TB_45CW, sub { $_[0]->rotate(-45) }); | ||||
|         EVT_TOOL($self, TB_45CCW, sub { $_[0]->rotate(45) }); | ||||
|         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_open}, sub { $self->list_item_activated(undef, $self->{selected_objects}->[0][0]) }); | ||||
|         EVT_BUTTON($self, $self->{btn_load}, \&load); | ||||
|         EVT_BUTTON($self, $self->{btn_remove}, sub { $self->remove() }); # explicitly pass no argument to remove | ||||
|         EVT_BUTTON($self, $self->{btn_reset}, \&reset); | ||||
|         EVT_BUTTON($self, $self->{btn_arrange}, \&arrange); | ||||
|         EVT_BUTTON($self, $self->{btn_info}, sub { $_[0]->object_dialog }); | ||||
|         EVT_BUTTON($self, $self->{btn_increase}, \&increase); | ||||
|         EVT_BUTTON($self, $self->{btn_decrease}, \&decrease); | ||||
|         EVT_BUTTON($self, $self->{btn_rotate45cw}, sub { $_[0]->rotate(-45) }); | ||||
|  | @ -379,7 +395,8 @@ sub object_loaded { | |||
|      | ||||
|     my $object = $self->{objects}[$obj_idx]; | ||||
|     $self->{list}->InsertStringItem($obj_idx, $object->name); | ||||
|     $self->{list}->SetItemFont($obj_idx, Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)); | ||||
|     $self->{list}->SetItemFont($obj_idx, Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)) | ||||
|         if $self->{list}->can('SetItemFont');  # legacy code for wxPerl < 0.9918 not supporting SetItemFont() | ||||
|      | ||||
|     $self->{list}->SetItem($obj_idx, 1, $object->instances_count); | ||||
|     $self->{list}->SetItem($obj_idx, 2, ($object->scale * 100) . "%"); | ||||
|  | @ -747,6 +764,7 @@ sub make_model { | |||
|         my $new_model_object = $model->add_object( | ||||
|             vertices    => $model_object->vertices, | ||||
|             input_file  => $plater_object->input_file, | ||||
|             config      => $plater_object->config, | ||||
|             layer_height_ranges => $plater_object->layer_height_ranges, | ||||
|         ); | ||||
|         foreach my $volume (@{$model_object->volumes}) { | ||||
|  | @ -980,8 +998,7 @@ sub mouse_event { | |||
|         $self->{drag_object} = undef; | ||||
|         $self->SetCursor(wxSTANDARD_CURSOR); | ||||
|     } elsif ($event->ButtonDClick) { | ||||
|     	$parent->list_item_activated(undef, $parent->{selected_objects}->[0][0]) | ||||
|     		if @{$parent->{selected_objects}}; | ||||
|     	$parent->object_dialog if @{$parent->{selected_objects}}; | ||||
|     } elsif ($event->Dragging) { | ||||
|         return if !$self->{drag_start_pos}; # concurrency problems | ||||
|         for my $preview ($self->{drag_object}) { | ||||
|  | @ -1025,7 +1042,18 @@ sub list_item_activated { | |||
|     my ($self, $event, $obj_idx) = @_; | ||||
|      | ||||
|     $obj_idx //= $event->GetIndex; | ||||
| 	my $dlg = Slic3r::GUI::Plater::ObjectDialog->new($self, | ||||
| 	$self->object_dialog($obj_idx); | ||||
| } | ||||
| 
 | ||||
| sub object_dialog { | ||||
|     my $self = shift; | ||||
|     my ($obj_idx) = @_; | ||||
|      | ||||
|     if (!defined $obj_idx) { | ||||
|         ($obj_idx, undef) = $self->selected_object; | ||||
|     } | ||||
|      | ||||
|     my $dlg = Slic3r::GUI::Plater::ObjectDialog->new($self, | ||||
| 		object => $self->{objects}[$obj_idx], | ||||
| 	); | ||||
| 	$dlg->ShowModal; | ||||
|  | @ -1045,11 +1073,11 @@ sub selection_changed { | |||
|      | ||||
|     my $method = $have_sel ? 'Enable' : 'Disable'; | ||||
|     $self->{"btn_$_"}->$method | ||||
|         for grep $self->{"btn_$_"}, qw(remove open increase decrease rotate45cw rotate45ccw rotate changescale split); | ||||
|         for grep $self->{"btn_$_"}, qw(remove info increase decrease rotate45cw rotate45ccw rotate changescale split); | ||||
|      | ||||
|     if ($self->{htoolbar}) { | ||||
|         $self->{htoolbar}->EnableTool($_, $have_sel) | ||||
|             for (TB_REMOVE, TB_INFO, TB_MORE, TB_LESS, TB_45CW, TB_45CCW, TB_ROTATE, TB_SCALE, TB_SPLIT); | ||||
|             for (TB_REMOVE, TB_INFO, TB_MORE, TB_FEWER, TB_45CW, TB_45CCW, TB_ROTATE, TB_SCALE, TB_SPLIT); | ||||
|     } | ||||
|      | ||||
|     if ($self->{object_info_size}) { # have we already loaded the info pane? | ||||
|  | @ -1139,6 +1167,7 @@ has 'instances'             => (is => 'rw', default => sub { [] }); # upward Y a | |||
| has 'thumbnail'             => (is => 'rw', trigger => \&_transform_thumbnail); | ||||
| has 'transformed_thumbnail' => (is => 'rw'); | ||||
| has 'thumbnail_scaling_factor' => (is => 'rw', trigger => \&_transform_thumbnail); | ||||
| has 'config'                => (is => 'rw', default => sub { Slic3r::Config->new }); | ||||
| has 'layer_height_ranges'   => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ] | ||||
| has 'mesh_stats'            => (is => 'rw'); | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,11 +17,13 @@ sub new { | |||
|     $self->{tabpanel}->AddPage($self->{preview} = Slic3r::GUI::Plater::ObjectDialog::PreviewTab->new($self->{tabpanel}, object => $self->{object}), "Preview") | ||||
|         if $Slic3r::GUI::have_OpenGL; | ||||
|     $self->{tabpanel}->AddPage($self->{info} = Slic3r::GUI::Plater::ObjectDialog::InfoTab->new($self->{tabpanel}, object => $self->{object}), "Info"); | ||||
|     $self->{tabpanel}->AddPage($self->{settings} = Slic3r::GUI::Plater::ObjectDialog::SettingsTab->new($self->{tabpanel}, object => $self->{object}), "Settings"); | ||||
|     $self->{tabpanel}->AddPage($self->{layers} = Slic3r::GUI::Plater::ObjectDialog::LayersTab->new($self->{tabpanel}, object => $self->{object}), "Layers"); | ||||
|      | ||||
|     my $buttons = $self->CreateStdDialogButtonSizer(wxOK); | ||||
|     EVT_BUTTON($self, wxID_OK, sub { | ||||
|         # validate user input | ||||
|         return if !$self->{settings}->CanClose; | ||||
|         return if !$self->{layers}->CanClose; | ||||
|          | ||||
|         # notify tabs | ||||
|  | @ -124,6 +126,111 @@ sub new { | |||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| package Slic3r::GUI::Plater::ObjectDialog::SettingsTab; | ||||
| use Wx qw(:dialog :id :misc :sizer :systemsettings :button :icon); | ||||
| use Wx::Grid; | ||||
| use Wx::Event qw(EVT_BUTTON); | ||||
| use base 'Wx::Panel'; | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my ($parent, %params) = @_; | ||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize); | ||||
|     $self->{object} = $params{object}; | ||||
|      | ||||
|     $self->{sizer} = Wx::BoxSizer->new(wxVERTICAL); | ||||
|      | ||||
|     # descriptive text | ||||
|     { | ||||
|         my $label = Wx::StaticText->new($self, -1, "You can use this section to override some settings just for this object.", | ||||
|             wxDefaultPosition, [-1, 25]); | ||||
|         $label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); | ||||
|         $self->{sizer}->Add($label, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10); | ||||
|     } | ||||
|      | ||||
|     # option selector | ||||
|     { | ||||
|         # get all options with object scope and sort them by category+label | ||||
|         my %settings = map { $_ => sprintf('%s > %s', $Slic3r::Config::Options->{$_}{category}, $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label}) } | ||||
|             grep { ($Slic3r::Config::Options->{$_}{scope} // '') eq 'object' } | ||||
|             keys %$Slic3r::Config::Options; | ||||
|         $self->{options} = [ sort { $settings{$a} cmp $settings{$b} } keys %settings ]; | ||||
|         my $choice = Wx::Choice->new($self, -1, wxDefaultPosition, [150, -1], [ map $settings{$_}, @{$self->{options}} ]); | ||||
|          | ||||
|         # create the button | ||||
|         my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/add.png", wxBITMAP_TYPE_PNG)); | ||||
|         EVT_BUTTON($self, $btn, sub { | ||||
|             my $opt_key = $self->{options}[$choice->GetSelection]; | ||||
|             $self->{object}->config->apply(Slic3r::Config->new_from_defaults($opt_key)); | ||||
|             $self->update_optgroup; | ||||
|         }); | ||||
|          | ||||
|         my $h_sizer = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|         $h_sizer->Add($choice, 1, wxEXPAND | wxALL, 0); | ||||
|         $h_sizer->Add($btn, 0, wxEXPAND | wxLEFT, 10); | ||||
|         $self->{sizer}->Add($h_sizer, 0, wxEXPAND | wxALL, 10); | ||||
|     } | ||||
|      | ||||
|     $self->{options_sizer} = Wx::BoxSizer->new(wxVERTICAL); | ||||
|     $self->{sizer}->Add($self->{options_sizer}, 0, wxEXPAND | wxALL, 10); | ||||
|      | ||||
|     $self->update_optgroup; | ||||
|      | ||||
|     $self->SetSizer($self->{sizer}); | ||||
|     $self->{sizer}->SetSizeHints($self); | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| sub update_optgroup { | ||||
|     my $self = shift; | ||||
|      | ||||
|     $self->{options_sizer}->Clear(1); | ||||
|      | ||||
|     my $config = $self->{object}->config; | ||||
|     my %categories = (); | ||||
|     foreach my $opt_key (keys %$config) { | ||||
|         my $category = $Slic3r::Config::Options->{$opt_key}{category}; | ||||
|         $categories{$category} ||= []; | ||||
|         push @{$categories{$category}}, $opt_key; | ||||
|     } | ||||
|     foreach my $category (sort keys %categories) { | ||||
|         my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new( | ||||
|             parent      => $self, | ||||
|             title       => $category, | ||||
|             config      => $config, | ||||
|             options     => [ sort @{$categories{$category}} ], | ||||
|             full_labels => 1, | ||||
|             extra_column => sub { | ||||
|                 my ($line) = @_; | ||||
|                 my ($opt_key) = @{$line->{options}};  # we assume that we have one option per line | ||||
|                 my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG)); | ||||
|                 EVT_BUTTON($self, $btn, sub { | ||||
|                     delete $self->{object}->config->{$opt_key}; | ||||
|                     Slic3r::GUI->CallAfter(sub { $self->update_optgroup }); | ||||
|                 }); | ||||
|                 return $btn; | ||||
|             }, | ||||
|         ); | ||||
|         $self->{options_sizer}->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 10); | ||||
|     } | ||||
|     $self->Layout; | ||||
| } | ||||
| 
 | ||||
| sub CanClose { | ||||
|     my $self = shift; | ||||
|      | ||||
|     # validate options before allowing user to dismiss the dialog | ||||
|     # the validate method only works on full configs so we have | ||||
|     # to merge our settings with the default ones | ||||
|     my $config = Slic3r::Config->merge($self->GetParent->GetParent->GetParent->GetParent->GetParent->config, $self->{object}->config); | ||||
|     eval { | ||||
|         $config->validate; | ||||
|     }; | ||||
|     return 0 if Slic3r::GUI::catch_error($self);     | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| package Slic3r::GUI::Plater::ObjectDialog::LayersTab; | ||||
| use Wx qw(:dialog :id :misc :sizer :systemsettings); | ||||
| use Wx::Grid; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci