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 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::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 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' | ||||
|     ? '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'; | ||||
| use constant FILAMENT_CHOOSERS_SPACING => 3; | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my ($parent) = @_; | ||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||||
|     $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); | ||||
|  | @ -219,11 +220,22 @@ sub new { | |||
|             printer     => 'Printer', | ||||
|         ); | ||||
|         $self->{preset_choosers} = {}; | ||||
|         $self->{preset_choosers_sizers} = {}; | ||||
|         for my $group (qw(print filament printer)) { | ||||
|             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($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); | ||||
|          | ||||
|  | @ -242,6 +254,25 @@ sub skeinpanel { | |||
|     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 { | ||||
|     my $self = shift; | ||||
|      | ||||
|  | @ -683,6 +714,19 @@ sub on_config_change { | |||
|     if (exists $self->{config}{$opt_key}) { | ||||
|         $self->{config}->set($opt_key, $value); | ||||
|         $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)) { | ||||
|         $self->{options_tabs}{$tab_name} = ("Slic3r::GUI::Tab::" . ucfirst $tab_name)->new( | ||||
|             $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 | ||||
|         ); | ||||
|         $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 { | ||||
|     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( | ||||
|         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 $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); | ||||
|     $self->{options} = []; # array of option names handled by this tab | ||||
|      | ||||
|     $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; | ||||
|     }); | ||||
|     $self->{$_} = $params{$_} for qw(plater on_value_change); | ||||
|      | ||||
|     # horizontal sizer | ||||
|     $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|  | @ -142,6 +137,11 @@ sub current_preset { | |||
|     return $self->{presets}[ $self->{presets_choice}->GetSelection ]; | ||||
| } | ||||
| 
 | ||||
| sub get_preset { | ||||
|     my $self = shift; | ||||
|     return $self->{presets}[ $_[0] ]; | ||||
| } | ||||
| 
 | ||||
| # propagate event to the parent | ||||
| sub on_value_change { | ||||
|     my $self = shift; | ||||
|  | @ -157,6 +157,12 @@ sub select_default_preset { | |||
|     $self->{presets_choice}->SetSelection(0); | ||||
| } | ||||
| 
 | ||||
| sub select_preset { | ||||
|     my $self = shift; | ||||
|     $self->{presets_choice}->SetSelection($_[0]); | ||||
|     $self->on_select_preset; | ||||
| } | ||||
| 
 | ||||
| sub on_select_preset { | ||||
|     my $self = shift; | ||||
|      | ||||
|  | @ -172,27 +178,18 @@ sub on_select_preset { | |||
|     } | ||||
|      | ||||
|     my $preset = $self->current_preset; | ||||
|     if ($preset->{default}) { | ||||
|         # default settings: disable the delete button | ||||
|         $self->{config}->apply(Slic3r::Config->new_from_defaults(@{$self->{options}})); | ||||
|         $self->{btn_delete_preset}->Disable; | ||||
|     } else { | ||||
|         if (!-e $preset->{file}) { | ||||
|             Slic3r::GUI::show_error($self, "The selected preset does not exist anymore ($preset->{file})."); | ||||
|             return; | ||||
|     my $preset_config = $self->get_preset_config($preset); | ||||
|     eval { | ||||
|         local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self); | ||||
|         foreach my $opt_key (@{$self->{options}}) { | ||||
|             $self->{config}->set($opt_key, $preset_config->get($opt_key)); | ||||
|         } | ||||
|         eval { | ||||
|             local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self); | ||||
|             my $external_config = Slic3r::Config->load($preset->{file}); | ||||
|             foreach my $opt_key (@{$self->{options}}) { | ||||
|                 $self->{config}->set($opt_key, $external_config->get($opt_key)); | ||||
|             } | ||||
|         }; | ||||
|         Slic3r::GUI::catch_error($self); | ||||
|         $preset->{external} | ||||
|             ? $self->{btn_delete_preset}->Disable | ||||
|             : $self->{btn_delete_preset}->Enable; | ||||
|     } | ||||
|     }; | ||||
|     Slic3r::GUI::catch_error($self); | ||||
|     ($preset->{default} || $preset->{external}) | ||||
|         ? $self->{btn_delete_preset}->Disable | ||||
|         : $self->{btn_delete_preset}->Enable; | ||||
|      | ||||
|     $self->on_preset_loaded; | ||||
|     $self->reload_values; | ||||
|     $self->set_dirty(0); | ||||
|  | @ -200,6 +197,25 @@ sub on_select_preset { | |||
|     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 { | ||||
|     my $self = shift; | ||||
|     my ($title, $icon, %params) = @_; | ||||
|  | @ -347,12 +363,7 @@ sub load_external_config { | |||
| 
 | ||||
| sub sync_presets { | ||||
|     my $self = shift; | ||||
|     return unless $self->{sync_presets_with}; | ||||
|     $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); | ||||
|     $self->{plater}->update_presets($self->name, [$self->{presets_choice}->GetStrings], $self->{presets_choice}->GetSelection); | ||||
| } | ||||
| 
 | ||||
| package Slic3r::GUI::Tab::Print; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci