mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-15 23:15:56 +08:00
Merge branch 'gui3-shortcuts'
This commit is contained in:
commit
b2a6dce75b
@ -88,6 +88,7 @@ our $Settings = {
|
||||
no_controller => 0,
|
||||
threads => $Slic3r::Config::Options->{threads}{default},
|
||||
color_toolpaths_by => 'role',
|
||||
tabbed_preset_editors => 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,13 +47,13 @@ sub new {
|
||||
delete $presets{$_} for map $_->printer_name, @panels;
|
||||
|
||||
foreach my $preset_name (sort keys %presets) {
|
||||
my $config = $presets{$preset_name}->dirty_config;
|
||||
next if !$config->serial_port;
|
||||
my $preset = $presets{$preset_name};
|
||||
next if !$preset->dirty_config->serial_port;
|
||||
|
||||
my $id = &Wx::NewId();
|
||||
$menu->Append($id, $preset_name);
|
||||
EVT_MENU($menu, $id, sub {
|
||||
$self->add_printer($preset_name, $config);
|
||||
$self->add_printer($preset);
|
||||
});
|
||||
}
|
||||
$self->PopupMenu($menu, $btn->GetPosition);
|
||||
@ -100,10 +100,10 @@ sub OnActivate {
|
||||
|
||||
# get all available presets
|
||||
my %presets = ();
|
||||
{
|
||||
my %all = map { $_->name => $_ } @{wxTheApp->presets->{printer}};
|
||||
my %configs = map { my $name = $_; $name => $all{$name}->load_config } keys %all;
|
||||
%presets = map { $_ => $configs{$_} } grep $configs{$_}->serial_port, keys %all;
|
||||
foreach my $preset (@{wxTheApp->presets->{printer}}) {
|
||||
$preset->load_config;
|
||||
next if !$preset->dirty_config->serial_port;
|
||||
$presets{$preset->name} = $preset;
|
||||
}
|
||||
|
||||
# decide which ones we want to keep
|
||||
@ -124,7 +124,7 @@ sub OnActivate {
|
||||
# enable printers whose port is available
|
||||
my %ports = map { $_ => 1 } wxTheApp->scan_serial_ports;
|
||||
$active{$_} = 1
|
||||
for grep exists $ports{$presets{$_}->serial_port}, keys %presets;
|
||||
for grep exists $ports{$presets{$_}->dirty_config->serial_port}, keys %presets;
|
||||
}
|
||||
if (!%active && $self->_selected_printer_preset) {
|
||||
# enable currently selected printer if it is configured
|
||||
@ -140,7 +140,7 @@ sub OnActivate {
|
||||
$self->{sizer}->DetachWindow($panel);
|
||||
$panel->Destroy;
|
||||
}
|
||||
$self->add_printer($_, $presets{$_}) for sort keys %active;
|
||||
$self->add_printer($presets{$_}) for sort keys %active;
|
||||
|
||||
# show/hide the warning about no printers
|
||||
$self->{text_no_printers}->Show(!%presets);
|
||||
@ -156,16 +156,16 @@ sub OnActivate {
|
||||
}
|
||||
|
||||
sub add_printer {
|
||||
my ($self, $printer_name, $config) = @_;
|
||||
my ($self, $preset) = @_;
|
||||
|
||||
# check that printer doesn't exist already
|
||||
foreach my $panel ($self->print_panels) {
|
||||
if ($panel->printer_name eq $printer_name) {
|
||||
if ($panel->printer_name eq $preset->name) {
|
||||
return $panel;
|
||||
}
|
||||
}
|
||||
|
||||
my $printer_panel = Slic3r::GUI::Controller::PrinterPanel->new($self, $printer_name, $config);
|
||||
my $printer_panel = Slic3r::GUI::Controller::PrinterPanel->new($self, $preset->name, $preset);
|
||||
$self->{sizer}->Prepend($printer_panel, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10);
|
||||
$self->Layout;
|
||||
|
||||
|
@ -16,11 +16,11 @@ use constant STATUS_TIMER_INTERVAL => 1000; # milliseconds
|
||||
use constant TEMP_TIMER_INTERVAL => 5000; # milliseconds
|
||||
|
||||
sub new {
|
||||
my ($class, $parent, $printer_name, $config) = @_;
|
||||
my ($class, $parent, $printer_name, $preset) = @_;
|
||||
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [500, 250]);
|
||||
|
||||
$self->printer_name($printer_name || 'Printer');
|
||||
$self->config($config);
|
||||
$self->config($preset->dirty_config);
|
||||
$self->manual_control_config({
|
||||
xy_travel_speed => 130,
|
||||
z_travel_speed => 10,
|
||||
@ -103,7 +103,7 @@ sub new {
|
||||
}
|
||||
my $serial_port_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
{
|
||||
$self->{serial_port_combobox} = Wx::ComboBox->new($self, -1, $config->serial_port, wxDefaultPosition, wxDefaultSize, []);
|
||||
$self->{serial_port_combobox} = Wx::ComboBox->new($self, -1, $self->config->serial_port, wxDefaultPosition, wxDefaultSize, []);
|
||||
$self->{serial_port_combobox}->SetFont($Slic3r::GUI::small_font);
|
||||
$self->update_serial_ports;
|
||||
$serial_port_sizer->Add($self->{serial_port_combobox}, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 1);
|
||||
@ -125,7 +125,7 @@ sub new {
|
||||
}
|
||||
my $serial_speed_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
{
|
||||
$self->{serial_speed_combobox} = Wx::ComboBox->new($self, -1, $config->serial_speed, wxDefaultPosition, wxDefaultSize,
|
||||
$self->{serial_speed_combobox} = Wx::ComboBox->new($self, -1, $self->config->serial_speed, wxDefaultPosition, wxDefaultSize,
|
||||
["57600", "115200", "250000"]);
|
||||
$self->{serial_speed_combobox}->SetFont($Slic3r::GUI::small_font);
|
||||
$serial_speed_sizer->Add($self->{serial_speed_combobox}, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
@ -8,9 +8,10 @@ use utf8;
|
||||
use File::Basename qw(basename dirname);
|
||||
use List::Util qw(min);
|
||||
use Slic3r::Geometry qw(X Y Z);
|
||||
use Wx qw(:frame :bitmap :id :misc :notebook :panel :sizer :menu :dialog :filedialog
|
||||
:font :icon wxTheApp);
|
||||
use Wx::Event qw(EVT_CLOSE EVT_NOTEBOOK_PAGE_CHANGED);
|
||||
use Wx qw(:frame :bitmap :id :misc :panel :sizer :menu :dialog :filedialog
|
||||
:font :icon :aui wxTheApp);
|
||||
use Wx::AUI;
|
||||
use Wx::Event qw(EVT_CLOSE EVT_AUINOTEBOOK_PAGE_CHANGED EVT_AUINOTEBOOK_PAGE_CLOSE);
|
||||
use base 'Wx::Frame';
|
||||
|
||||
our $qs_last_input_file;
|
||||
@ -28,6 +29,7 @@ sub new {
|
||||
}
|
||||
|
||||
$self->{loaded} = 0;
|
||||
$self->{preset_editor_tabs} = {}; # group => panel
|
||||
|
||||
# initialize tabpanel and menubar
|
||||
$self->_init_tabpanel;
|
||||
@ -92,10 +94,24 @@ sub new {
|
||||
sub _init_tabpanel {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{tabpanel} = my $panel = Wx::Notebook->new($self, -1, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL);
|
||||
EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub {
|
||||
my $panel = $self->{tabpanel}->GetCurrentPage;
|
||||
$self->{tabpanel} = my $panel = Wx::AuiNotebook->new($self, -1, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP);
|
||||
EVT_AUINOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub {
|
||||
my $panel = $self->{tabpanel}->GetPage($self->{tabpanel}->GetSelection);
|
||||
$panel->OnActivate if $panel->can('OnActivate');
|
||||
if ($self->{tabpanel}->GetSelection > 1) {
|
||||
$self->{tabpanel}->SetWindowStyle($self->{tabpanel}->GetWindowStyleFlag | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
|
||||
} else {
|
||||
$self->{tabpanel}->SetWindowStyle($self->{tabpanel}->GetWindowStyleFlag & ~wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
|
||||
}
|
||||
});
|
||||
EVT_AUINOTEBOOK_PAGE_CLOSE($self, $self->{tabpanel}, sub {
|
||||
my $panel = $self->{tabpanel}->GetPage($self->{tabpanel}->GetSelection);
|
||||
if ($panel->isa('Slic3r::GUI::PresetEditor')) {
|
||||
delete $self->{preset_editor_tabs}{$panel->name};
|
||||
}
|
||||
wxTheApp->CallAfter(sub {
|
||||
$self->{tabpanel}->SetSelection(0);
|
||||
});
|
||||
});
|
||||
|
||||
$panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel), "Plater");
|
||||
|
@ -49,7 +49,7 @@ sub new {
|
||||
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
$self->{config} = Slic3r::Config->new_from_defaults(qw(
|
||||
bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width
|
||||
serial_port serial_speed octoprint_host octoprint_apikey overridable filament_colour
|
||||
serial_port serial_speed octoprint_host octoprint_apikey shortcuts filament_colour
|
||||
));
|
||||
$self->{model} = Slic3r::Model->new;
|
||||
$self->{print} = Slic3r::Print->new;
|
||||
@ -366,9 +366,37 @@ sub new {
|
||||
{
|
||||
my $o = $self->{settings_override_panel} = Slic3r::GUI::Plater::OverrideSettingsPanel->new($self,
|
||||
on_change => sub {
|
||||
my ($opt_key) = @_;
|
||||
|
||||
my ($preset) = $self->selected_presets('print');
|
||||
$preset->load_config;
|
||||
|
||||
# If this option is not in the override panel it means it was manually deleted,
|
||||
# so let's restore the profile value.
|
||||
if (!$self->{settings_override_config}->has($opt_key)) {
|
||||
$preset->_dirty_config->set($opt_key, $preset->_config->get($opt_key));
|
||||
} else {
|
||||
# Apply the overrides to the current Print preset, potentially making it dirty
|
||||
$preset->_dirty_config->apply($self->{settings_override_config});
|
||||
|
||||
# If this is a configured shortcut (and not just a dirty option),
|
||||
# save it now.
|
||||
if (any { $_ eq $opt_key } @{$preset->dirty_config->shortcuts}) {
|
||||
$preset->save([$opt_key]);
|
||||
}
|
||||
}
|
||||
|
||||
$self->load_presets;
|
||||
$self->config_changed;
|
||||
|
||||
# Reload the open tab if any
|
||||
if (my $print_tab = $self->GetFrame->{preset_editor_tabs}{print}) {
|
||||
$print_tab->load_presets;
|
||||
$print_tab->reload_preset;
|
||||
}
|
||||
});
|
||||
$o->set_editable(1);
|
||||
$o->can_add(0);
|
||||
$o->can_delete(1);
|
||||
$o->set_opt_keys([ Slic3r::GUI::PresetEditor::Print->options ]);
|
||||
$self->{settings_override_config} = Slic3r::Config->new;
|
||||
$o->set_default_config($self->{settings_override_config});
|
||||
@ -534,6 +562,14 @@ sub _on_change_combobox {
|
||||
return 0 if !$self->prompt_unsaved_changes;
|
||||
}
|
||||
wxTheApp->CallAfter(sub {
|
||||
# Close the preset editor tab if any
|
||||
if (exists $self->GetFrame->{preset_editor_tabs}{$group}) {
|
||||
my $tabpanel = $self->GetFrame->{tabpanel};
|
||||
$tabpanel->DeletePage($tabpanel->GetPageIndex($self->GetFrame->{preset_editor_tabs}{$group}));
|
||||
delete $self->GetFrame->{preset_editor_tabs}{$group};
|
||||
$tabpanel->SetSelection(0); # without this, a newly created tab will not be selected by wx
|
||||
}
|
||||
|
||||
$self->_on_select_preset($group);
|
||||
|
||||
# This will remove the "(modified)" mark from any dirty preset handled here.
|
||||
@ -562,31 +598,19 @@ sub _on_select_preset {
|
||||
my $o_config = $self->{settings_override_config};
|
||||
my $o_panel = $self->{settings_override_panel};
|
||||
|
||||
if ($changed) {
|
||||
# Preserve current options if re-selecting the same preset
|
||||
$o_config->clear;
|
||||
}
|
||||
my $shortcuts = $config->get('shortcuts');
|
||||
|
||||
my $overridable = $config->get('overridable');
|
||||
|
||||
# Add/remove options (we do it this way for preserving current options)
|
||||
foreach my $opt_key (@$overridable) {
|
||||
# Populate option with the default value taken from configuration
|
||||
# (re-set the override always, because if we here it means user
|
||||
# switched to this preset or opened/closed the editor, so he expects
|
||||
# the new values set in the editor to be used).
|
||||
# Re-populate the override panel with the configured shortcuts
|
||||
# and the dirty options.
|
||||
$o_config->clear;
|
||||
foreach my $opt_key (@$shortcuts, $presets[0]->dirty_options) {
|
||||
# Don't add shortcut for shortcuts!
|
||||
next if $opt_key eq 'shortcuts';
|
||||
$o_config->set($opt_key, $config->get($opt_key));
|
||||
}
|
||||
foreach my $opt_key (@{$o_config->get_keys}) {
|
||||
# Keep options listed among overridable and options added on the fly
|
||||
if ((none { $_ eq $opt_key } @$overridable)
|
||||
&& (any { $_ eq $opt_key } $o_panel->fixed_options)) {
|
||||
$o_config->erase($opt_key);
|
||||
}
|
||||
}
|
||||
|
||||
$o_panel->set_default_config($config);
|
||||
$o_panel->set_fixed_options(\@$overridable);
|
||||
$o_panel->set_fixed_options(\@$shortcuts);
|
||||
$o_panel->update_optgroup;
|
||||
} elsif ($group eq 'printer') {
|
||||
# reload print and filament settings to honor their compatible_printer options
|
||||
@ -699,7 +723,7 @@ sub load_presets {
|
||||
}
|
||||
}
|
||||
|
||||
$self->{print}->placeholder_parser->set("${group}_preset", [ @preset_names ]);
|
||||
$self->{print}->placeholder_parser->set_multiple("${group}_preset", [ @preset_names ]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,19 +766,54 @@ sub selected_presets {
|
||||
sub show_preset_editor {
|
||||
my ($self, $group, $i) = @_;
|
||||
|
||||
my $class = "Slic3r::GUI::PresetEditorDialog::" . ucfirst($group);
|
||||
my $dlg = $class->new($self);
|
||||
wxTheApp->CallAfter(sub {
|
||||
my @presets = $self->selected_presets($group);
|
||||
|
||||
my @presets = $self->selected_presets($group);
|
||||
$dlg->preset_editor->select_preset_by_name($presets[$i // 0]->name);
|
||||
$dlg->ShowModal;
|
||||
my $preset_editor;
|
||||
my $dlg;
|
||||
my $mainframe = $self->GetFrame;
|
||||
my $tabpanel = $mainframe->{tabpanel};
|
||||
if (exists $mainframe->{preset_editor_tabs}{$group}) {
|
||||
# we already have an open editor
|
||||
$tabpanel->SetSelection($tabpanel->GetPageIndex($mainframe->{preset_editor_tabs}{$group}));
|
||||
return;
|
||||
} elsif ($Slic3r::GUI::Settings->{_}{tabbed_preset_editors}) {
|
||||
my $class = "Slic3r::GUI::PresetEditor::" . ucfirst($group);
|
||||
$mainframe->{preset_editor_tabs}{$group} = $preset_editor = $class->new($self->GetFrame);
|
||||
$tabpanel->AddPage($preset_editor, ucfirst($group) . " Settings", 1);
|
||||
} else {
|
||||
my $class = "Slic3r::GUI::PresetEditorDialog::" . ucfirst($group);
|
||||
$dlg = $class->new($self);
|
||||
$preset_editor = $dlg->preset_editor;
|
||||
}
|
||||
|
||||
# Re-load the presets as they might have changed.
|
||||
$self->load_presets;
|
||||
$preset_editor->select_preset_by_name($presets[$i // 0]->name);
|
||||
$preset_editor->on_value_change(sub {
|
||||
# Re-load the presets in order to toggle the (modified) suffix
|
||||
$self->load_presets;
|
||||
|
||||
# Select the preset that was last selected in the editor.
|
||||
$self->select_preset_by_name
|
||||
($dlg->preset_editor->current_preset->name, $group, $i, 1);
|
||||
# Update shortcuts
|
||||
$self->_on_select_preset($group);
|
||||
|
||||
# Use the new config wherever we actually use its contents
|
||||
$self->config_changed;
|
||||
});
|
||||
my $cb = sub {
|
||||
my ($group, $preset) = @_;
|
||||
|
||||
# Re-load the presets as they might have changed.
|
||||
$self->load_presets;
|
||||
|
||||
# Select the preset in plater too
|
||||
$self->select_preset_by_name($preset->name, $group, $i, 1);
|
||||
};
|
||||
$preset_editor->on_select_preset($cb);
|
||||
$preset_editor->on_save_preset($cb);
|
||||
|
||||
if ($dlg) {
|
||||
$dlg->ShowModal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
# Returns the current config by merging the selected presets and the overrides.
|
||||
@ -765,7 +824,7 @@ sub config {
|
||||
my $config = Slic3r::Config->new_from_defaults;
|
||||
|
||||
# get defaults also for the values tracked by the Plater's config
|
||||
# (for example 'overridable')
|
||||
# (for example 'shortcuts')
|
||||
$config->apply(Slic3r::Config->new_from_defaults(@{$self->{config}->get_keys}));
|
||||
|
||||
my %classes = map { $_ => "Slic3r::GUI::PresetEditor::".ucfirst($_) }
|
||||
|
@ -34,7 +34,8 @@ sub new {
|
||||
$self->{default_config} = Slic3r::Config->new;
|
||||
$self->{config} = Slic3r::Config->new;
|
||||
$self->{on_change} = $params{on_change};
|
||||
$self->{editable} = 1;
|
||||
$self->{can_add} = 1;
|
||||
$self->{can_delete} = 1;
|
||||
$self->{fixed_options} = {};
|
||||
|
||||
$self->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
|
||||
@ -144,7 +145,7 @@ sub update_optgroup {
|
||||
$self->{options_sizer}->Clear(1);
|
||||
return if !defined $self->{config};
|
||||
|
||||
$self->{btn_add}->Show($self->{editable});
|
||||
$self->{btn_add}->Show($self->{can_add});
|
||||
|
||||
my %categories = ();
|
||||
foreach my $opt_key (@{$self->{config}->get_keys}) {
|
||||
@ -173,7 +174,7 @@ sub update_optgroup {
|
||||
my ($opt_key, $opt_index) = @{ $optgroup->_opt_map->{$opt_id} };
|
||||
|
||||
# disallow deleting fixed options
|
||||
return undef if $self->{fixed_options}{$opt_key} || !$self->{editable};
|
||||
return undef if $self->{fixed_options}{$opt_key} || !$self->{can_delete};
|
||||
|
||||
my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new($Slic3r::var->("delete.png"), wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
|
||||
@ -210,11 +211,27 @@ sub disable {
|
||||
$self->Disable;
|
||||
}
|
||||
|
||||
# Shows or hides the Add button.
|
||||
# Shows or hides the Add/Delete buttons.
|
||||
sub set_editable {
|
||||
my ($self, $editable) = @_;
|
||||
|
||||
$self->{editable} = $editable;
|
||||
$self->{can_add} = $self->{can_delete} = $editable;
|
||||
}
|
||||
|
||||
# Shows or hides the Add button.
|
||||
sub can_add {
|
||||
my ($self, $can) = @_;
|
||||
|
||||
$self->{can_add} = $can if defined $can;
|
||||
return $can;
|
||||
}
|
||||
|
||||
# Shows or hides the Delete button.
|
||||
sub can_delete {
|
||||
my ($self, $can) = @_;
|
||||
|
||||
$self->{can_delete} = $can if defined $can;
|
||||
return $can;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -71,6 +71,13 @@ sub new {
|
||||
tooltip => 'Disable communication with the printer over a serial / USB cable. This simplifies the user interface in case the printer is never attached to the computer.',
|
||||
default => $Slic3r::GUI::Settings->{_}{no_controller},
|
||||
));
|
||||
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
|
||||
opt_id => 'tabbed_preset_editors',
|
||||
type => 'bool',
|
||||
label => 'Display profile editors as tabs',
|
||||
tooltip => 'When opening a profile editor, it will be shown in a dialog or in a tab according to this option.',
|
||||
default => $Slic3r::GUI::Settings->{_}{tabbed_preset_editors},
|
||||
));
|
||||
|
||||
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
|
@ -94,7 +94,7 @@ sub prompt_unsaved_changes {
|
||||
if ($res == wxID_CANCEL) {
|
||||
return 0;
|
||||
} elsif ($res == wxID_YES) {
|
||||
return $self->save($self->default ? undef : $self->name);
|
||||
return $self->default ? $self->save_prompt($parent) : $self->save;
|
||||
} elsif ($res == wxID_NO) {
|
||||
$self->dismiss_changes;
|
||||
return 1;
|
||||
@ -104,20 +104,29 @@ sub prompt_unsaved_changes {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub save_prompt {
|
||||
my ($self, $parent) = @_;
|
||||
|
||||
my $default_name = $self->default ? 'Untitled' : $self->name;
|
||||
$default_name =~ s/\.ini$//i;
|
||||
|
||||
my $dlg = Slic3r::GUI::SavePresetWindow->new($parent,
|
||||
default => $default_name,
|
||||
values => [ map $_->name, grep !$_->default && !$_->external, @{wxTheApp->presets->{$self->name}} ],
|
||||
);
|
||||
return 0 unless $dlg->ShowModal == wxID_OK;
|
||||
|
||||
$self->save_as($dlg->get_name);
|
||||
}
|
||||
|
||||
sub save {
|
||||
my ($self, $name, $parent) = @_;
|
||||
my ($self, $opt_keys) = @_;
|
||||
|
||||
if (!$name) {
|
||||
my $default_name = $self->default ? 'Untitled' : $self->name;
|
||||
$default_name =~ s/\.ini$//i;
|
||||
return $self->save_as($self->name, $opt_keys);
|
||||
}
|
||||
|
||||
my $dlg = Slic3r::GUI::SavePresetWindow->new($parent,
|
||||
default => $default_name,
|
||||
values => [ map $_->name, grep !$_->default && !$_->external, @{wxTheApp->presets->{$self->name}} ],
|
||||
);
|
||||
return 0 unless $dlg->ShowModal == wxID_OK;
|
||||
$name = $dlg->get_name;
|
||||
}
|
||||
sub save_as {
|
||||
my ($self, $name, $opt_keys) = @_;
|
||||
|
||||
$self->rename($name);
|
||||
|
||||
@ -125,8 +134,15 @@ sub save {
|
||||
die "Calling save() without setting filename";
|
||||
}
|
||||
|
||||
$self->_config->clear;
|
||||
$self->_config->apply($self->_dirty_config);
|
||||
if ($opt_keys) {
|
||||
$self->_config->apply_only($self->_dirty_config, $opt_keys);
|
||||
} else {
|
||||
$self->_config->clear;
|
||||
$self->_config->apply($self->_dirty_config);
|
||||
}
|
||||
|
||||
# unlink the file first to avoid problems on case-insensitive file systems
|
||||
unlink Slic3r::encode_path($self->file);
|
||||
$self->_config->save($self->file);
|
||||
wxTheApp->load_presets;
|
||||
|
||||
@ -167,6 +183,8 @@ sub dirty_config {
|
||||
sub load_config {
|
||||
my ($self) = @_;
|
||||
|
||||
return if $self->_loaded;
|
||||
|
||||
my @keys = $self->_group_class->options;
|
||||
my @extra_keys = $self->_group_class->overriding_options;
|
||||
|
||||
|
@ -87,7 +87,7 @@ sub new {
|
||||
});
|
||||
|
||||
EVT_CHOICE($parent, $self->{presets_choice}, sub {
|
||||
$self->on_select_preset;
|
||||
$self->_on_select_preset;
|
||||
});
|
||||
|
||||
EVT_BUTTON($self, $self->{btn_save_preset}, sub { $self->save_preset });
|
||||
@ -123,13 +123,20 @@ sub save_preset {
|
||||
$self->{treectrl}->SetFocus;
|
||||
|
||||
my $preset = $self->current_preset;
|
||||
$preset->save(undef, $self);
|
||||
$preset->save_prompt($self);
|
||||
$self->load_presets;
|
||||
$self->select_preset_by_name($preset->name);
|
||||
|
||||
$self->{on_save_preset}->($self->name, $preset) if $self->{on_save_preset};
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub on_save_preset {
|
||||
my ($self, $cb) = @_;
|
||||
$self->{on_save_preset} = $cb;
|
||||
}
|
||||
|
||||
sub on_value_change {
|
||||
my ($self, $cb) = @_;
|
||||
$self->{on_value_change} = $cb;
|
||||
@ -141,10 +148,12 @@ sub on_value_change {
|
||||
sub _on_value_change {
|
||||
my ($self, $opt_key) = @_;
|
||||
|
||||
$self->current_preset->_dirty_config->apply($self->config);
|
||||
$self->{on_value_change}->($opt_key) if $self->{on_value_change};
|
||||
$self->load_presets;
|
||||
$self->_update;
|
||||
wxTheApp->CallAfter(sub {
|
||||
$self->current_preset->_dirty_config->apply($self->config);
|
||||
$self->{on_value_change}->($opt_key) if $self->{on_value_change};
|
||||
$self->load_presets;
|
||||
$self->_update;
|
||||
});
|
||||
}
|
||||
|
||||
sub _update {}
|
||||
@ -155,7 +164,7 @@ sub select_preset {
|
||||
my ($self, $i, $force) = @_;
|
||||
|
||||
$self->{presets_choice}->SetSelection($i);
|
||||
$self->on_select_preset($force);
|
||||
$self->_on_select_preset($force);
|
||||
}
|
||||
|
||||
sub select_preset_by_name {
|
||||
@ -163,8 +172,12 @@ sub select_preset_by_name {
|
||||
|
||||
my $presets = wxTheApp->presets->{$self->name};
|
||||
my $i = first { $presets->[$_]->name eq $name } 0..$#$presets;
|
||||
if (!defined $i) {
|
||||
warn "No preset named $name";
|
||||
return 0;
|
||||
}
|
||||
$self->{presets_choice}->SetSelection($i);
|
||||
$self->on_select_preset($force);
|
||||
$self->_on_select_preset($force);
|
||||
}
|
||||
|
||||
sub prompt_unsaved_changes {
|
||||
@ -175,6 +188,11 @@ sub prompt_unsaved_changes {
|
||||
}
|
||||
|
||||
sub on_select_preset {
|
||||
my ($self, $cb) = @_;
|
||||
$self->{on_select_preset} = $cb;
|
||||
}
|
||||
|
||||
sub _on_select_preset {
|
||||
my ($self, $force) = @_;
|
||||
|
||||
# This method is called:
|
||||
@ -185,9 +203,6 @@ sub on_select_preset {
|
||||
# Get the selected name.
|
||||
my $preset = wxTheApp->presets->{$self->name}->[$self->{presets_choice}->GetSelection];
|
||||
|
||||
# If selection didn't change, do nothing.
|
||||
return if defined $self->current_preset && $preset->name eq $self->current_preset->name;
|
||||
|
||||
# If we have unsaved changes, prompt user.
|
||||
if (!$force && !$self->prompt_unsaved_changes) {
|
||||
# User decided not to save the current changes, so we restore the previous selection.
|
||||
@ -199,13 +214,16 @@ sub on_select_preset {
|
||||
|
||||
$self->current_preset($preset);
|
||||
|
||||
# If selection didn't change, do nothing.
|
||||
# Only after resetting current_preset because it might contain an older object of the
|
||||
# current preset.
|
||||
return if defined $self->current_preset && $preset->name eq $self->current_preset->name;
|
||||
|
||||
# We reload presets in order to remove the "(modified)" suffix in case user was
|
||||
# prompted and chose to discard changes.
|
||||
$self->load_presets;
|
||||
|
||||
$preset->load_config if !$preset->_loaded;
|
||||
$self->config->clear;
|
||||
$self->config->apply($preset->dirty_config);
|
||||
$self->reload_preset;
|
||||
|
||||
eval {
|
||||
local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self);
|
||||
@ -215,12 +233,13 @@ sub on_select_preset {
|
||||
|
||||
$self->_update;
|
||||
$self->on_preset_loaded;
|
||||
$self->reload_config;
|
||||
};
|
||||
if ($@) {
|
||||
$@ = "I was unable to load the selected config file: $@";
|
||||
Slic3r::GUI::catch_error($self);
|
||||
}
|
||||
|
||||
$self->{on_select_preset}->($self->name, $preset) if $self->{on_select_preset};
|
||||
}
|
||||
|
||||
sub add_options_page {
|
||||
@ -240,6 +259,15 @@ sub add_options_page {
|
||||
return $page;
|
||||
}
|
||||
|
||||
sub reload_preset {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->current_preset->load_config if !$self->current_preset->_loaded;
|
||||
$self->config->clear;
|
||||
$self->config->apply($self->current_preset->dirty_config);
|
||||
$self->reload_config;
|
||||
}
|
||||
|
||||
sub reload_config {
|
||||
my $self = shift;
|
||||
|
||||
@ -441,7 +469,7 @@ sub options {
|
||||
external_perimeter_extrusion_width infill_extrusion_width solid_infill_extrusion_width
|
||||
top_infill_extrusion_width support_material_extrusion_width
|
||||
infill_overlap bridge_flow_ratio
|
||||
xy_size_compensation resolution overridable compatible_printers
|
||||
xy_size_compensation resolution shortcuts compatible_printers
|
||||
print_settings_id
|
||||
)
|
||||
}
|
||||
@ -449,7 +477,7 @@ sub options {
|
||||
sub build {
|
||||
my $self = shift;
|
||||
|
||||
my $overridable_widget = sub {
|
||||
my $shortcuts_widget = sub {
|
||||
my ($parent) = @_;
|
||||
|
||||
my $Options = $Slic3r::Config::Options;
|
||||
@ -458,15 +486,15 @@ sub build {
|
||||
grep { exists $Options->{$_} && $Options->{$_}{category} } $self->options
|
||||
);
|
||||
my @opt_keys = sort { $options{$a} cmp $options{$b} } keys %options;
|
||||
$self->{overridable_opt_keys} = [ @opt_keys ];
|
||||
$self->{shortcuts_opt_keys} = [ @opt_keys ];
|
||||
|
||||
my $listbox = $self->{overridable_list} = Wx::CheckListBox->new($parent, -1,
|
||||
my $listbox = $self->{shortcuts_list} = Wx::CheckListBox->new($parent, -1,
|
||||
wxDefaultPosition, [-1, 320], [ map $options{$_}, @opt_keys ]);
|
||||
|
||||
EVT_CHECKLISTBOX($self, $listbox, sub {
|
||||
my $value = [ map $opt_keys[$_], grep $listbox->IsChecked($_), 0..$#opt_keys ];
|
||||
$self->config->set('overridable', $value);
|
||||
$self->_on_value_change('overridable');
|
||||
$self->config->set('shortcuts', $value);
|
||||
$self->_on_value_change('shortcuts');
|
||||
});
|
||||
|
||||
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
@ -715,7 +743,7 @@ sub build {
|
||||
}
|
||||
|
||||
{
|
||||
my $page = $self->add_options_page('Overrides', 'wrench.png');
|
||||
my $page = $self->add_options_page('Shortcuts', 'wrench.png');
|
||||
{
|
||||
my $optgroup = $page->new_optgroup('Profile preferences');
|
||||
{
|
||||
@ -727,10 +755,10 @@ sub build {
|
||||
}
|
||||
}
|
||||
{
|
||||
my $optgroup = $page->new_optgroup('Overridable settings (they will be displayed in the plater for quick changes)');
|
||||
my $optgroup = $page->new_optgroup('Show shortcuts for the following settings');
|
||||
{
|
||||
my $line = Slic3r::GUI::OptionsGroup::Line->new(
|
||||
widget => $overridable_widget,
|
||||
widget => $shortcuts_widget,
|
||||
full_width => 1,
|
||||
);
|
||||
$optgroup->append_line($line);
|
||||
@ -745,9 +773,9 @@ sub reload_config {
|
||||
$self->_reload_compatible_printers_widget;
|
||||
|
||||
{
|
||||
my %overridable = map { $_ => 1 } @{ $self->config->get('overridable') };
|
||||
for my $i (0..$#{$self->{overridable_opt_keys}}) {
|
||||
$self->{overridable_list}->Check($i, $overridable{ $self->{overridable_opt_keys}[$i] });
|
||||
my %shortcuts = map { $_ => 1 } @{ $self->config->get('shortcuts') };
|
||||
for my $i (0..$#{$self->{shortcuts_opt_keys}}) {
|
||||
$self->{shortcuts_list}->Check($i, $shortcuts{ $self->{shortcuts_opt_keys}[$i] });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -853,8 +853,9 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->cli = "overhangs|detect-bridging-perimeters!";
|
||||
def->default_value = new ConfigOptionBool(true);
|
||||
|
||||
def = this->add("overridable", coStrings);
|
||||
def->label = "Overridable options";
|
||||
def = this->add("shortcuts", coStrings);
|
||||
def->label = "Shortcuts";
|
||||
def->aliases.push_back("overridable");
|
||||
{
|
||||
ConfigOptionStrings* opt = new ConfigOptionStrings();
|
||||
opt->values.push_back("support_material");
|
||||
@ -1383,7 +1384,7 @@ PrintConfigDef::PrintConfigDef()
|
||||
|
||||
def = this->add("support_material_interface_speed", coFloatOrPercent);
|
||||
def->label = "↳ interface";
|
||||
def->category = "Support material interface speed";
|
||||
def->full_label = "Support material interface speed";
|
||||
def->gui_type = "f_enum_open";
|
||||
def->category = "Support material";
|
||||
def->tooltip = "Speed for printing support material interface layers. If expressed as percentage (for example 50%) it will be calculated over support material speed.";
|
||||
|
Loading…
x
Reference in New Issue
Block a user