mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Allow to select multiple filaments in GUI when multiple extruders are configured
This commit is contained in:
		
							parent
							
								
									b7d8444ac8
								
							
						
					
					
						commit
						793301d319
					
				
					 3 changed files with 110 additions and 38 deletions
				
			
		|  | @ -9,7 +9,7 @@ use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 scale unscale); | ||||||
| use Slic3r::Geometry::Clipper qw(JT_ROUND); | use Slic3r::Geometry::Clipper qw(JT_ROUND); | ||||||
| use threads::shared qw(shared_clone); | use threads::shared qw(shared_clone); | ||||||
| use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window); | use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window); | ||||||
| use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL); | use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE); | ||||||
| use base 'Wx::Panel'; | use base 'Wx::Panel'; | ||||||
| 
 | 
 | ||||||
| use constant TB_MORE    => &Wx::NewId; | use constant TB_MORE    => &Wx::NewId; | ||||||
|  | @ -30,13 +30,14 @@ use constant CANVAS_SIZE => [300,300]; | ||||||
| use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8' | use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8' | ||||||
|     ? 'What do you want to print today? ™' # Sept. 13, 2006. The first part ever printed by a RepRap to make another RepRap. |     ? 'What do you want to print today? ™' # Sept. 13, 2006. The first part ever printed by a RepRap to make another RepRap. | ||||||
|     : 'Drag your objects here'; |     : 'Drag your objects here'; | ||||||
|  | use constant FILAMENT_CHOOSERS_SPACING => 3; | ||||||
| 
 | 
 | ||||||
| sub new { | sub new { | ||||||
|     my $class = shift; |     my $class = shift; | ||||||
|     my ($parent) = @_; |     my ($parent) = @_; | ||||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); |     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||||||
|     $self->{config} = Slic3r::Config->new_from_defaults(qw( |     $self->{config} = Slic3r::Config->new_from_defaults(qw( | ||||||
|         bed_size print_center complete_objects extruder_clearance_radius skirts skirt_distance |         bed_size print_center complete_objects extruder_clearance_radius skirts skirt_distance extruders_count | ||||||
|     )); |     )); | ||||||
|      |      | ||||||
|     $self->{canvas} = Wx::Panel->new($self, -1, wxDefaultPosition, CANVAS_SIZE, wxTAB_TRAVERSAL); |     $self->{canvas} = Wx::Panel->new($self, -1, wxDefaultPosition, CANVAS_SIZE, wxTAB_TRAVERSAL); | ||||||
|  | @ -219,11 +220,22 @@ sub new { | ||||||
|             printer     => 'Printer', |             printer     => 'Printer', | ||||||
|         ); |         ); | ||||||
|         $self->{preset_choosers} = {}; |         $self->{preset_choosers} = {}; | ||||||
|  |         $self->{preset_choosers_sizers} = {}; | ||||||
|         for my $group (qw(print filament printer)) { |         for my $group (qw(print filament printer)) { | ||||||
|             my $text = Wx::StaticText->new($self, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); |             my $text = Wx::StaticText->new($self, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||||||
|             $self->{preset_choosers}{$group} = Wx::Choice->new($self, -1, wxDefaultPosition, [150, -1], []); |             my $choice = Wx::Choice->new($self, -1, wxDefaultPosition, [150, -1], []); | ||||||
|  |             $self->{preset_choosers}{$group} = [$choice]; | ||||||
|  |             EVT_CHOICE($choice, $choice, sub { | ||||||
|  |                 my $choice = shift;  # avoid leaks | ||||||
|  |                 return if $group eq 'filament' && ($self->{config}->get('extruders_count') // 1) > 1; #/ | ||||||
|  |                 $self->skeinpanel->{options_tabs}{$group}->select_preset($choice->GetSelection); | ||||||
|  |             }); | ||||||
|  |              | ||||||
|  |             $self->{preset_choosers_sizers}{$group} = Wx::BoxSizer->new(wxVERTICAL); | ||||||
|  |             $self->{preset_choosers_sizers}{$group}->Add($choice, 0, wxEXPAND | wxBOTTOM, FILAMENT_CHOOSERS_SPACING); | ||||||
|  |              | ||||||
|             $presets->Add($text, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); |             $presets->Add($text, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); | ||||||
|             $presets->Add($self->{preset_choosers}{$group}, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 15); |             $presets->Add($self->{preset_choosers_sizers}{$group}, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 15); | ||||||
|         } |         } | ||||||
|         $presets->AddStretchSpacer(1); |         $presets->AddStretchSpacer(1); | ||||||
|          |          | ||||||
|  | @ -242,6 +254,25 @@ sub skeinpanel { | ||||||
|     return $self->GetParent->GetParent; |     return $self->GetParent->GetParent; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub update_presets { | ||||||
|  |     my $self = shift; | ||||||
|  |     my ($group, $items, $selected) = @_; | ||||||
|  |      | ||||||
|  |     foreach my $choice (@{ $self->{preset_choosers}{$group} }) { | ||||||
|  |         my $sel = $choice->GetSelection; | ||||||
|  |         $choice->Clear; | ||||||
|  |         $choice->Append($_) for @$items; | ||||||
|  |         $choice->SetSelection($sel) if $sel <= $#$items; | ||||||
|  |     } | ||||||
|  |     $self->{preset_choosers}{$group}[0]->SetSelection($selected); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | sub filament_presets { | ||||||
|  |     my $self = shift; | ||||||
|  |      | ||||||
|  |     return map $_->GetSelection, @{ $self->{preset_choosers}{filament} }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| sub load { | sub load { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|      |      | ||||||
|  | @ -683,6 +714,19 @@ sub on_config_change { | ||||||
|     if (exists $self->{config}{$opt_key}) { |     if (exists $self->{config}{$opt_key}) { | ||||||
|         $self->{config}->set($opt_key, $value); |         $self->{config}->set($opt_key, $value); | ||||||
|         $self->_update_bed_size if $opt_key eq 'bed_size'; |         $self->_update_bed_size if $opt_key eq 'bed_size'; | ||||||
|  |         if ($opt_key eq 'extruders_count' && defined $value) { | ||||||
|  |             my $choices = $self->{preset_choosers}{filament}; | ||||||
|  |             while (@$choices < $value) { | ||||||
|  |                 push @$choices, Wx::Choice->new($self, -1, wxDefaultPosition, [150, -1], [$choices->[0]->GetStrings]); | ||||||
|  |                 $self->{preset_choosers_sizers}{filament}->Add($choices->[-1], 0, wxEXPAND | wxBOTTOM, FILAMENT_CHOOSERS_SPACING); | ||||||
|  |             } | ||||||
|  |             while (@$choices > $value) { | ||||||
|  |                 $self->{preset_choosers_sizers}{filament}->Remove(-1); | ||||||
|  |                 $choices->[-1]->Destroy; | ||||||
|  |                 pop @$choices; | ||||||
|  |             } | ||||||
|  |             $self->Layout; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ sub new { | ||||||
|     for my $tab_name (qw(print filament printer)) { |     for my $tab_name (qw(print filament printer)) { | ||||||
|         $self->{options_tabs}{$tab_name} = ("Slic3r::GUI::Tab::" . ucfirst $tab_name)->new( |         $self->{options_tabs}{$tab_name} = ("Slic3r::GUI::Tab::" . ucfirst $tab_name)->new( | ||||||
|             $self->{tabpanel}, |             $self->{tabpanel}, | ||||||
|             sync_presets_with   => $self->{plater}{preset_choosers}{$tab_name}, |             plater              => $self->{plater}, | ||||||
|             on_value_change     => sub { $self->{plater}->on_config_change(@_) }, # propagate config change events to the plater |             on_value_change     => sub { $self->{plater}->on_config_change(@_) }, # propagate config change events to the plater | ||||||
|         ); |         ); | ||||||
|         $self->{tabpanel}->AddPage($self->{options_tabs}{$tab_name}, $self->{options_tabs}{$tab_name}->title); |         $self->{tabpanel}->AddPage($self->{options_tabs}{$tab_name}, $self->{options_tabs}{$tab_name}->title); | ||||||
|  | @ -235,9 +235,26 @@ This method collects all config values from the tabs and merges them into a sing | ||||||
| sub config { | sub config { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|      |      | ||||||
|  |     # retrieve filament presets and build a single config object for them | ||||||
|  |     my $filament_config; | ||||||
|  |     foreach my $preset_idx ($self->{plater}->filament_presets) { | ||||||
|  |         my $preset = $self->{options_tabs}{filament}->get_preset($preset_idx); | ||||||
|  |         my $config = $self->{options_tabs}{filament}->get_preset_config($preset); | ||||||
|  |         if (!$filament_config) { | ||||||
|  |             $filament_config = $config; | ||||||
|  |             next; | ||||||
|  |         } | ||||||
|  |         foreach my $opt_key (keys %$config) { | ||||||
|  |             next unless ref $filament_config->get($opt_key) eq 'ARRAY'; | ||||||
|  |             push @{ $filament_config->get($opt_key) }, $config->get($opt_key)->[0]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|     return Slic3r::Config->merge( |     return Slic3r::Config->merge( | ||||||
|         Slic3r::Config->new_from_defaults, |         Slic3r::Config->new_from_defaults, | ||||||
|         (map $_->config, values %{$self->{options_tabs}}), |         $self->{options_tabs}{print}->config, | ||||||
|  |         $self->{options_tabs}{printer}->config, | ||||||
|  |         $filament_config, | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,12 +14,7 @@ sub new { | ||||||
|     my ($parent, %params) = @_; |     my ($parent, %params) = @_; | ||||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); |     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); | ||||||
|     $self->{options} = []; # array of option names handled by this tab |     $self->{options} = []; # array of option names handled by this tab | ||||||
|      |     $self->{$_} = $params{$_} for qw(plater on_value_change); | ||||||
|     $self->{$_} = $params{$_} for qw(sync_presets_with on_value_change); |  | ||||||
|     EVT_CHOICE($parent, $self->{sync_presets_with}, sub { |  | ||||||
|         $self->{presets_choice}->SetSelection($self->{sync_presets_with}->GetSelection); |  | ||||||
|         $self->on_select_preset; |  | ||||||
|     }); |  | ||||||
|      |      | ||||||
|     # horizontal sizer |     # horizontal sizer | ||||||
|     $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); |     $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); | ||||||
|  | @ -142,6 +137,11 @@ sub current_preset { | ||||||
|     return $self->{presets}[ $self->{presets_choice}->GetSelection ]; |     return $self->{presets}[ $self->{presets_choice}->GetSelection ]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub get_preset { | ||||||
|  |     my $self = shift; | ||||||
|  |     return $self->{presets}[ $_[0] ]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| # propagate event to the parent | # propagate event to the parent | ||||||
| sub on_value_change { | sub on_value_change { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|  | @ -157,6 +157,12 @@ sub select_default_preset { | ||||||
|     $self->{presets_choice}->SetSelection(0); |     $self->{presets_choice}->SetSelection(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub select_preset { | ||||||
|  |     my $self = shift; | ||||||
|  |     $self->{presets_choice}->SetSelection($_[0]); | ||||||
|  |     $self->on_select_preset; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| sub on_select_preset { | sub on_select_preset { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|      |      | ||||||
|  | @ -172,27 +178,18 @@ sub on_select_preset { | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     my $preset = $self->current_preset; |     my $preset = $self->current_preset; | ||||||
|     if ($preset->{default}) { |     my $preset_config = $self->get_preset_config($preset); | ||||||
|         # default settings: disable the delete button |     eval { | ||||||
|         $self->{config}->apply(Slic3r::Config->new_from_defaults(@{$self->{options}})); |         local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self); | ||||||
|         $self->{btn_delete_preset}->Disable; |         foreach my $opt_key (@{$self->{options}}) { | ||||||
|     } else { |             $self->{config}->set($opt_key, $preset_config->get($opt_key)); | ||||||
|         if (!-e $preset->{file}) { |  | ||||||
|             Slic3r::GUI::show_error($self, "The selected preset does not exist anymore ($preset->{file})."); |  | ||||||
|             return; |  | ||||||
|         } |         } | ||||||
|         eval { |     }; | ||||||
|             local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self); |     Slic3r::GUI::catch_error($self); | ||||||
|             my $external_config = Slic3r::Config->load($preset->{file}); |     ($preset->{default} || $preset->{external}) | ||||||
|             foreach my $opt_key (@{$self->{options}}) { |         ? $self->{btn_delete_preset}->Disable | ||||||
|                 $self->{config}->set($opt_key, $external_config->get($opt_key)); |         : $self->{btn_delete_preset}->Enable; | ||||||
|             } |      | ||||||
|         }; |  | ||||||
|         Slic3r::GUI::catch_error($self); |  | ||||||
|         $preset->{external} |  | ||||||
|             ? $self->{btn_delete_preset}->Disable |  | ||||||
|             : $self->{btn_delete_preset}->Enable; |  | ||||||
|     } |  | ||||||
|     $self->on_preset_loaded; |     $self->on_preset_loaded; | ||||||
|     $self->reload_values; |     $self->reload_values; | ||||||
|     $self->set_dirty(0); |     $self->set_dirty(0); | ||||||
|  | @ -200,6 +197,25 @@ sub on_select_preset { | ||||||
|     Slic3r::GUI->save_settings; |     Slic3r::GUI->save_settings; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | sub get_preset_config { | ||||||
|  |     my $self = shift; | ||||||
|  |     my ($preset) = @_; | ||||||
|  |      | ||||||
|  |     my $config = Slic3r::Config->new_from_defaults(@{$self->{options}}); | ||||||
|  |      | ||||||
|  |     if (!$preset->{default}) { | ||||||
|  |         if (!-e $preset->{file}) { | ||||||
|  |             Slic3r::GUI::show_error($self, "The selected preset does not exist anymore ($preset->{file})."); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         # apply preset values on top of defaults | ||||||
|  |         $config->apply(Slic3r::Config->load($preset->{file})); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return $config; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| sub add_options_page { | sub add_options_page { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my ($title, $icon, %params) = @_; |     my ($title, $icon, %params) = @_; | ||||||
|  | @ -347,12 +363,7 @@ sub load_external_config { | ||||||
| 
 | 
 | ||||||
| sub sync_presets { | sub sync_presets { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     return unless $self->{sync_presets_with}; |     $self->{plater}->update_presets($self->name, [$self->{presets_choice}->GetStrings], $self->{presets_choice}->GetSelection); | ||||||
|     $self->{sync_presets_with}->Clear; |  | ||||||
|     foreach my $item ($self->{presets_choice}->GetStrings) { |  | ||||||
|         $self->{sync_presets_with}->Append($item); |  | ||||||
|     } |  | ||||||
|     $self->{sync_presets_with}->SetSelection($self->{presets_choice}->GetSelection); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| package Slic3r::GUI::Tab::Print; | package Slic3r::GUI::Tab::Print; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci