mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07: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