Removed some obsolete Perl binding.
Added Version Index "version" method. Implemented automatic selection of default_print_profile and default_filament_profile, when the print / filament profiles are not compatible with the selected printer profile. Fixed selection of a printer profile, if the currently selected printer profile becomes invisible.
This commit is contained in:
parent
0f6fc689aa
commit
82890ec815
@ -1,458 +0,0 @@
|
|||||||
# The config wizard is executed when the Slic3r is first started.
|
|
||||||
# The wizard helps the user to specify the 3D printer properties.
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard;
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use utf8;
|
|
||||||
|
|
||||||
use Wx;
|
|
||||||
use base 'Wx::Wizard';
|
|
||||||
|
|
||||||
# adhere to various human interface guidelines
|
|
||||||
our $wizard = 'Wizard';
|
|
||||||
$wizard = 'Assistant' if &Wx::wxMAC || &Wx::wxGTK;
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my ($class, $parent, $presets, $fresh_start) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, -1, "Configuration $wizard");
|
|
||||||
|
|
||||||
# initialize an empty repository
|
|
||||||
$self->{config} = Slic3r::Config->new;
|
|
||||||
|
|
||||||
my $welcome_page = Slic3r::GUI::ConfigWizard::Page::Welcome->new($self, $fresh_start);
|
|
||||||
$self->add_page($welcome_page);
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Firmware->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Bed->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Nozzle->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Filament->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Temperature->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::BedTemperature->new($self));
|
|
||||||
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Finished->new($self));
|
|
||||||
|
|
||||||
$_->build_index for @{$self->{pages}};
|
|
||||||
|
|
||||||
$welcome_page->set_selection_presets([@{$presets}, 'Other']);
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub add_page {
|
|
||||||
my ($self, $page) = @_;
|
|
||||||
|
|
||||||
my $n = push @{$self->{pages}}, $page;
|
|
||||||
# add first page to the page area sizer
|
|
||||||
$self->GetPageAreaSizer->Add($page) if $n == 1;
|
|
||||||
# link pages
|
|
||||||
$self->{pages}[$n-2]->set_next_page($page) if $n >= 2;
|
|
||||||
$page->set_previous_page($self->{pages}[$n-2]) if $n >= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub run {
|
|
||||||
my ($self) = @_;
|
|
||||||
my $result;
|
|
||||||
if (Wx::Wizard::RunWizard($self, $self->{pages}[0])) {
|
|
||||||
my $preset_name = $self->{pages}[0]->{preset_name};
|
|
||||||
$result = {
|
|
||||||
preset_name => $preset_name,
|
|
||||||
reset_user_profile => $self->{pages}[0]->{reset_user_profile}
|
|
||||||
};
|
|
||||||
if ($preset_name eq 'Other') {
|
|
||||||
# it would be cleaner to have these defined inside each page class,
|
|
||||||
# in some event getting called before leaving the page
|
|
||||||
# set first_layer_height + layer_height based on nozzle_diameter
|
|
||||||
my $nozzle = $self->{config}->nozzle_diameter;
|
|
||||||
$self->{config}->set('first_layer_height', $nozzle->[0]);
|
|
||||||
$self->{config}->set('layer_height', $nozzle->[0] - 0.1);
|
|
||||||
|
|
||||||
# set first_layer_temperature to temperature + 5
|
|
||||||
$self->{config}->set('first_layer_temperature', [$self->{config}->temperature->[0] + 5]);
|
|
||||||
|
|
||||||
# set first_layer_bed_temperature to temperature + 5
|
|
||||||
$self->{config}->set('first_layer_bed_temperature',
|
|
||||||
[ ($self->{config}->bed_temperature->[0] > 0) ? ($self->{config}->bed_temperature->[0] + 5) : 0 ]);
|
|
||||||
$result->{config} = $self->{config};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$self->Destroy;
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Index;
|
|
||||||
use Wx qw(:bitmap :dc :font :misc :sizer :systemsettings :window);
|
|
||||||
use Wx::Event qw(EVT_ERASE_BACKGROUND EVT_PAINT);
|
|
||||||
use base 'Wx::Panel';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent, $title) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent);
|
|
||||||
|
|
||||||
push @{$self->{titles}}, $title;
|
|
||||||
$self->{own_index} = 0;
|
|
||||||
|
|
||||||
$self->{bullets}->{before} = Wx::Bitmap->new(Slic3r::var("bullet_black.png"), wxBITMAP_TYPE_PNG);
|
|
||||||
$self->{bullets}->{own} = Wx::Bitmap->new(Slic3r::var("bullet_blue.png"), wxBITMAP_TYPE_PNG);
|
|
||||||
$self->{bullets}->{after} = Wx::Bitmap->new(Slic3r::var("bullet_white.png"), wxBITMAP_TYPE_PNG);
|
|
||||||
|
|
||||||
$self->{background} = Wx::Bitmap->new(Slic3r::var("Slic3r_192px_transparent.png"), wxBITMAP_TYPE_PNG);
|
|
||||||
$self->SetMinSize(Wx::Size->new($self->{background}->GetWidth, $self->{background}->GetHeight));
|
|
||||||
|
|
||||||
EVT_PAINT($self, \&repaint);
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub repaint {
|
|
||||||
my ($self, $event) = @_;
|
|
||||||
my $size = $self->GetClientSize;
|
|
||||||
my $gap = 5;
|
|
||||||
|
|
||||||
my $dc = Wx::PaintDC->new($self);
|
|
||||||
$dc->SetBackgroundMode(wxTRANSPARENT);
|
|
||||||
$dc->SetFont($self->GetFont);
|
|
||||||
$dc->SetTextForeground($self->GetForegroundColour);
|
|
||||||
|
|
||||||
my $background_h = $self->{background}->GetHeight;
|
|
||||||
my $background_w = $self->{background}->GetWidth;
|
|
||||||
$dc->DrawBitmap($self->{background}, ($size->GetWidth - $background_w) / 2, ($size->GetHeight - $background_h) / 2, 1);
|
|
||||||
|
|
||||||
my $label_h = $self->{bullets}->{own}->GetHeight;
|
|
||||||
$label_h = $dc->GetCharHeight if $dc->GetCharHeight > $label_h;
|
|
||||||
my $label_w = $size->GetWidth;
|
|
||||||
|
|
||||||
my $i = 0;
|
|
||||||
foreach (@{$self->{titles}}) {
|
|
||||||
my $bullet = $self->{bullets}->{own};
|
|
||||||
$bullet = $self->{bullets}->{before} if $i < $self->{own_index};
|
|
||||||
$bullet = $self->{bullets}->{after} if $i > $self->{own_index};
|
|
||||||
|
|
||||||
$dc->SetTextForeground(Wx::Colour->new(128, 128, 128)) if $i > $self->{own_index};
|
|
||||||
$dc->DrawLabel($_, $bullet, Wx::Rect->new(0, $i * ($label_h + $gap), $label_w, $label_h));
|
|
||||||
# Only show the first bullet if this is the only wizard page to be displayed.
|
|
||||||
last if $i == 0 && $self->{just_welcome};
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$event->Skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub prepend_title {
|
|
||||||
my $self = shift;
|
|
||||||
my ($title) = @_;
|
|
||||||
|
|
||||||
unshift @{$self->{titles}}, $title;
|
|
||||||
$self->{own_index}++;
|
|
||||||
$self->Refresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub append_title {
|
|
||||||
my $self = shift;
|
|
||||||
my ($title) = @_;
|
|
||||||
|
|
||||||
push @{$self->{titles}}, $title;
|
|
||||||
$self->Refresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page;
|
|
||||||
use Wx qw(:font :misc :sizer :staticline :systemsettings);
|
|
||||||
use base 'Wx::WizardPage';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent, $title, $short_title) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent);
|
|
||||||
|
|
||||||
my $sizer = Wx::FlexGridSizer->new(0, 2, 10, 10);
|
|
||||||
$sizer->AddGrowableCol(1, 1);
|
|
||||||
$sizer->AddGrowableRow(1, 1);
|
|
||||||
$sizer->AddStretchSpacer(0);
|
|
||||||
$self->SetSizer($sizer);
|
|
||||||
|
|
||||||
# title
|
|
||||||
my $text = Wx::StaticText->new($self, -1, $title, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
|
||||||
my $bold_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
|
||||||
$bold_font->SetWeight(wxFONTWEIGHT_BOLD);
|
|
||||||
$bold_font->SetPointSize(14);
|
|
||||||
$text->SetFont($bold_font);
|
|
||||||
$sizer->Add($text, 0, wxALIGN_LEFT, 0);
|
|
||||||
|
|
||||||
# index
|
|
||||||
$self->{short_title} = $short_title ? $short_title : $title;
|
|
||||||
$self->{index} = Slic3r::GUI::ConfigWizard::Index->new($self, $self->{short_title});
|
|
||||||
$sizer->Add($self->{index}, 1, wxEXPAND | wxTOP | wxRIGHT, 10);
|
|
||||||
|
|
||||||
# contents
|
|
||||||
$self->{width} = 430;
|
|
||||||
$self->{vsizer} = Wx::BoxSizer->new(wxVERTICAL);
|
|
||||||
$sizer->Add($self->{vsizer}, 1);
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub append_text {
|
|
||||||
my $self = shift;
|
|
||||||
my ($text) = @_;
|
|
||||||
|
|
||||||
my $para = Wx::StaticText->new($self, -1, $text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
|
||||||
$para->Wrap($self->{width});
|
|
||||||
$para->SetMinSize([$self->{width}, -1]);
|
|
||||||
$self->{vsizer}->Add($para, 0, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub append_option {
|
|
||||||
my $self = shift;
|
|
||||||
my ($full_key) = @_;
|
|
||||||
|
|
||||||
# populate repository with the factory default
|
|
||||||
my ($opt_key, $opt_index) = split /#/, $full_key, 2;
|
|
||||||
$self->config->apply(Slic3r::Config::new_from_defaults_keys([$opt_key]));
|
|
||||||
|
|
||||||
# draw the control
|
|
||||||
my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
|
|
||||||
parent => $self,
|
|
||||||
title => '',
|
|
||||||
config => $self->config,
|
|
||||||
full_labels => 1,
|
|
||||||
);
|
|
||||||
$optgroup->append_single_option_line($opt_key, $opt_index);
|
|
||||||
$self->{vsizer}->Add($optgroup->sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub append_panel {
|
|
||||||
my ($self, $panel) = @_;
|
|
||||||
$self->{vsizer}->Add($panel, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub set_previous_page {
|
|
||||||
my $self = shift;
|
|
||||||
my ($previous_page) = @_;
|
|
||||||
$self->{previous_page} = $previous_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub GetPrev {
|
|
||||||
my $self = shift;
|
|
||||||
return $self->{previous_page};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub set_next_page {
|
|
||||||
my $self = shift;
|
|
||||||
my ($next_page) = @_;
|
|
||||||
$self->{next_page} = $next_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub GetNext {
|
|
||||||
my $self = shift;
|
|
||||||
return $self->{next_page};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub get_short_title {
|
|
||||||
my $self = shift;
|
|
||||||
return $self->{short_title};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub build_index {
|
|
||||||
my $self = shift;
|
|
||||||
|
|
||||||
my $page = $self;
|
|
||||||
$self->{index}->prepend_title($page->get_short_title) while ($page = $page->GetPrev);
|
|
||||||
$page = $self;
|
|
||||||
$self->{index}->append_title($page->get_short_title) while ($page = $page->GetNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub config {
|
|
||||||
my ($self) = @_;
|
|
||||||
return $self->GetParent->{config};
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Welcome;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
use Wx qw(:misc :sizer wxID_FORWARD);
|
|
||||||
use Wx::Event qw(EVT_ACTIVATE EVT_CHOICE EVT_CHECKBOX);
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my ($class, $parent, $fresh_start) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, "Welcome to the Slic3r Configuration $wizard", 'Welcome');
|
|
||||||
$self->{full_wizard_workflow} = 1;
|
|
||||||
$self->{reset_user_profile} = 0;
|
|
||||||
|
|
||||||
# Test for the existence of the old config path.
|
|
||||||
my $message_has_legacy;
|
|
||||||
{
|
|
||||||
my $datadir = Slic3r::data_dir;
|
|
||||||
if ($datadir =~ /Slic3rPE/) {
|
|
||||||
# Check for existence of the legacy Slic3r directory.
|
|
||||||
my $datadir_legacy = substr $datadir, 0, -2;
|
|
||||||
my $dir_enc = Slic3r::encode_path($datadir_legacy);
|
|
||||||
if (-e $dir_enc && -d $dir_enc &&
|
|
||||||
-e ($dir_enc . '/print') && -d ($dir_enc . '/print') &&
|
|
||||||
-e ($dir_enc . '/filament') && -d ($dir_enc . '/filament') &&
|
|
||||||
-e ($dir_enc . '/printer') && -d ($dir_enc . '/printer') &&
|
|
||||||
-e ($dir_enc . '/slic3r.ini')) {
|
|
||||||
$message_has_legacy = "Starting with Slic3r 1.38.4, the user profile directory has been renamed to $datadir. You may consider closing Slic3r and renaming $datadir_legacy to $datadir.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->append_text('Hello, welcome to Slic3r Prusa Edition! This '.lc($wizard).' helps you with the initial configuration; just a few settings and you will be ready to print.');
|
|
||||||
$self->append_text('Please select your printer vendor and printer type. If your printer is not listed, you may try your luck and select a similar one. If you select "Other", this ' . lc($wizard) . ' will let you set the basic 3D printer parameters.');
|
|
||||||
$self->append_text($message_has_legacy) if defined $message_has_legacy;
|
|
||||||
# To import an existing configuration instead, cancel this '.lc($wizard).' and use the Open Config menu item found in the File menu.');
|
|
||||||
$self->append_text('If you received a configuration file or a config bundle from your 3D printer vendor, cancel this '.lc($wizard).' and use the "File->Load Config" or "File->Load Config Bundle" menu.');
|
|
||||||
|
|
||||||
$self->{choice} = my $choice = Wx::Choice->new($self, -1, wxDefaultPosition, wxDefaultSize, []);
|
|
||||||
$self->{vsizer}->Add($choice, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
|
||||||
if (! $fresh_start) {
|
|
||||||
$self->{reset_checkbox} = Wx::CheckBox->new($self, -1, "Reset user profile, install from scratch");
|
|
||||||
$self->{vsizer}->Add($self->{reset_checkbox}, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
EVT_CHOICE($parent, $choice, sub {
|
|
||||||
my $sel = $self->{choice}->GetStringSelection;
|
|
||||||
$self->{preset_name} = $sel;
|
|
||||||
$self->set_full_wizard_workflow(($sel eq 'Other') || ($sel eq ''));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (! $fresh_start) {
|
|
||||||
EVT_CHECKBOX($self, $self->{reset_checkbox}, sub {
|
|
||||||
$self->{reset_user_profile} = $self->{reset_checkbox}->GetValue();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
EVT_ACTIVATE($parent, sub {
|
|
||||||
$self->set_full_wizard_workflow($self->{preset_name} eq 'Other');
|
|
||||||
});
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub set_full_wizard_workflow {
|
|
||||||
my ($self, $full_workflow) = @_;
|
|
||||||
$self->{full_wizard_workflow} = $full_workflow;
|
|
||||||
$self->{index}->{just_welcome} = !$full_workflow;
|
|
||||||
$self->{index}->Refresh;
|
|
||||||
my $next_button = $self->GetParent->FindWindow(wxID_FORWARD);
|
|
||||||
$next_button->SetLabel($full_workflow ? "&Next >" : "&Finish");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set the preset names, select the first item.
|
|
||||||
sub set_selection_presets {
|
|
||||||
my ($self, $names) = @_;
|
|
||||||
$self->{choice}->Append($names);
|
|
||||||
$self->{choice}->SetSelection(0);
|
|
||||||
$self->{preset_name} = $names->[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
sub GetNext {
|
|
||||||
my $self = shift;
|
|
||||||
return $self->{full_wizard_workflow} ? $self->{next_page} : undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Firmware;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Firmware Type');
|
|
||||||
|
|
||||||
$self->append_text('Choose the type of firmware used by your printer, then click Next.');
|
|
||||||
$self->append_option('gcode_flavor');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Bed;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Bed Size');
|
|
||||||
|
|
||||||
$self->append_text('Set the shape of your printer\'s bed, then click Next.');
|
|
||||||
|
|
||||||
$self->config->apply(Slic3r::Config::new_from_defaults_keys(['bed_shape']));
|
|
||||||
$self->{bed_shape_panel} = my $panel = Slic3r::GUI::BedShapePanel->new($self, $self->config->bed_shape);
|
|
||||||
$self->{bed_shape_panel}->on_change(sub {
|
|
||||||
$self->config->set('bed_shape', $self->{bed_shape_panel}->GetValue);
|
|
||||||
});
|
|
||||||
$self->append_panel($self->{bed_shape_panel});
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Nozzle;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Nozzle Diameter');
|
|
||||||
|
|
||||||
$self->append_text('Enter the diameter of your printer\'s hot end nozzle, then click Next.');
|
|
||||||
$self->append_option('nozzle_diameter#0');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Filament;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Filament Diameter');
|
|
||||||
|
|
||||||
$self->append_text('Enter the diameter of your filament, then click Next.');
|
|
||||||
$self->append_text('Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.');
|
|
||||||
$self->append_option('filament_diameter#0');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Temperature;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Extrusion Temperature');
|
|
||||||
|
|
||||||
$self->append_text('Enter the temperature needed for extruding your filament, then click Next.');
|
|
||||||
$self->append_text('A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.');
|
|
||||||
$self->append_option('temperature#0');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::BedTemperature;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Bed Temperature');
|
|
||||||
|
|
||||||
$self->append_text('Enter the bed temperature needed for getting your filament to stick to your heated bed, then click Next.');
|
|
||||||
$self->append_text('A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.');
|
|
||||||
$self->append_option('bed_temperature#0');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
package Slic3r::GUI::ConfigWizard::Page::Finished;
|
|
||||||
use base 'Slic3r::GUI::ConfigWizard::Page';
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my ($parent) = @_;
|
|
||||||
my $self = $class->SUPER::new($parent, 'Congratulations!', 'Finish');
|
|
||||||
|
|
||||||
$self->append_text("You have successfully completed the Slic3r Configuration $wizard. " .
|
|
||||||
'Slic3r is now configured for your printer and filament.');
|
|
||||||
$self->append_text('To close this '.lc($wizard).' and apply the newly created configuration, click Finish.');
|
|
||||||
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
|
@ -1,6 +1,9 @@
|
|||||||
# This is an example configuration version index.
|
# This is an example configuration version index.
|
||||||
# The index contains version numbers
|
# The index contains version numbers
|
||||||
min_slic3r_version =1.39.0
|
min_slic3r_version =1.39.0
|
||||||
|
max_slic3r_version= 1.39.5
|
||||||
|
1.1.1
|
||||||
|
1.1.0
|
||||||
0.2.0-alpha "some test comment"
|
0.2.0-alpha "some test comment"
|
||||||
max_slic3r_version= 1.39.4
|
max_slic3r_version= 1.39.4
|
||||||
0.1.0 another test comment
|
0.1.0 another test comment
|
||||||
|
@ -62,7 +62,6 @@ REGISTER_CLASS(GLVolumeCollection, "GUI::_3DScene::GLVolume::Collection");
|
|||||||
REGISTER_CLASS(Preset, "GUI::Preset");
|
REGISTER_CLASS(Preset, "GUI::Preset");
|
||||||
REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
|
REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
|
||||||
REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
|
REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
|
||||||
REGISTER_CLASS(PresetHints, "GUI::PresetHints");
|
|
||||||
REGISTER_CLASS(TabIface, "GUI::Tab");
|
REGISTER_CLASS(TabIface, "GUI::Tab");
|
||||||
REGISTER_CLASS(PresetUpdater, "PresetUpdater");
|
REGISTER_CLASS(PresetUpdater, "PresetUpdater");
|
||||||
REGISTER_CLASS(OctoPrint, "OctoPrint");
|
REGISTER_CLASS(OctoPrint, "OctoPrint");
|
||||||
|
@ -175,6 +175,9 @@ semver_parse_version (const char *str, semver_t *ver) {
|
|||||||
slice = (char *) str;
|
slice = (char *) str;
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
|
// non mandatory
|
||||||
|
ver->patch = 0;
|
||||||
|
|
||||||
while (slice != NULL && index++ < 4) {
|
while (slice != NULL && index++ < 4) {
|
||||||
next = strchr(slice, DELIMITER[0]);
|
next = strchr(slice, DELIMITER[0]);
|
||||||
if (next == NULL)
|
if (next == NULL)
|
||||||
@ -200,7 +203,8 @@ semver_parse_version (const char *str, semver_t *ver) {
|
|||||||
slice = next + 1;
|
slice = next + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (index == 3) ? 0 : -1;
|
// Major and minor versions are mandatory, patch version is not mandatory.
|
||||||
|
return (index == 2 || index == 3) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -632,4 +636,5 @@ semver_copy(const semver_t *ver) {
|
|||||||
if (ver->prerelease != NULL) {
|
if (ver->prerelease != NULL) {
|
||||||
res.prerelease = strdup(ver->prerelease);
|
res.prerelease = strdup(ver->prerelease);
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
@ -141,6 +141,15 @@ size_t Index::load(const boost::filesystem::path &path)
|
|||||||
return m_configs.size();
|
return m_configs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Semver Index::version() const
|
||||||
|
{
|
||||||
|
Semver ver = Semver::zero();
|
||||||
|
for (const Version &cv : m_configs)
|
||||||
|
if (cv.config_version >= ver)
|
||||||
|
ver = cv.config_version;
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
Index::const_iterator Index::find(const Semver &ver)
|
Index::const_iterator Index::find(const Semver &ver)
|
||||||
{
|
{
|
||||||
Version key;
|
Version key;
|
||||||
|
@ -59,6 +59,9 @@ public:
|
|||||||
size_t load(const boost::filesystem::path &path);
|
size_t load(const boost::filesystem::path &path);
|
||||||
|
|
||||||
const std::string& vendor() const { return m_vendor; }
|
const std::string& vendor() const { return m_vendor; }
|
||||||
|
// Returns version of the index as the highest version of all the configs.
|
||||||
|
// If there is no config, Semver::zero() is returned.
|
||||||
|
Semver version() const;
|
||||||
|
|
||||||
const_iterator begin() const { return m_configs.begin(); }
|
const_iterator begin() const { return m_configs.begin(); }
|
||||||
const_iterator end() const { return m_configs.end(); }
|
const_iterator end() const { return m_configs.end(); }
|
||||||
|
@ -619,7 +619,7 @@ void ConfigWizard::priv::on_custom_setup()
|
|||||||
set_page(page_firmware);
|
set_page(page_firmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle)
|
void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, bool fresh_start)
|
||||||
{
|
{
|
||||||
const bool is_custom_setup = page_welcome->page_next() == page_firmware;
|
const bool is_custom_setup = page_welcome->page_next() == page_firmware;
|
||||||
|
|
||||||
@ -627,7 +627,8 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
|||||||
app_config->set_vendors(appconfig_vendors);
|
app_config->set_vendors(appconfig_vendors);
|
||||||
app_config->set("version_check", page_update->version_check ? "1" : "0");
|
app_config->set("version_check", page_update->version_check ? "1" : "0");
|
||||||
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
|
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
|
||||||
app_config->reset_selections(); // XXX: only on "fresh start"?
|
if (fresh_start)
|
||||||
|
app_config->reset_selections();
|
||||||
preset_bundle->load_presets(*app_config);
|
preset_bundle->load_presets(*app_config);
|
||||||
} else {
|
} else {
|
||||||
for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) {
|
for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) {
|
||||||
@ -635,6 +636,8 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
|||||||
}
|
}
|
||||||
preset_bundle->load_config("My Settings", *custom_config);
|
preset_bundle->load_config("My Settings", *custom_config);
|
||||||
}
|
}
|
||||||
|
// Update the selections from the compatibilty.
|
||||||
|
preset_bundle->export_selections(*app_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public
|
// Public
|
||||||
@ -698,11 +701,11 @@ ConfigWizard::ConfigWizard(wxWindow *parent) :
|
|||||||
|
|
||||||
ConfigWizard::~ConfigWizard() {}
|
ConfigWizard::~ConfigWizard() {}
|
||||||
|
|
||||||
bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle)
|
bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle, bool fresh_start)
|
||||||
{
|
{
|
||||||
ConfigWizard wizard(parent);
|
ConfigWizard wizard(parent);
|
||||||
if (wizard.ShowModal() == wxID_OK) {
|
if (wizard.ShowModal() == wxID_OK) {
|
||||||
wizard.p->apply_config(GUI::get_app_config(), preset_bundle);
|
wizard.p->apply_config(GUI::get_app_config(), preset_bundle, fresh_start);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
||||||
~ConfigWizard();
|
~ConfigWizard();
|
||||||
|
|
||||||
static bool run(wxWindow *parent, PresetBundle *preset_bundle);
|
static bool run(wxWindow *parent, PresetBundle *preset_bundle, bool fresh_start);
|
||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
|
@ -202,7 +202,7 @@ struct ConfigWizard::priv
|
|||||||
void on_other_vendors();
|
void on_other_vendors();
|
||||||
void on_custom_setup();
|
void on_custom_setup();
|
||||||
|
|
||||||
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle);
|
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, bool fresh_start);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ bool config_wizard(bool fresh_start)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: Offer "reset user profile" ???
|
// TODO: Offer "reset user profile" ???
|
||||||
if (! ConfigWizard::run(g_wxMainFrame, g_PresetBundle))
|
if (! ConfigWizard::run(g_wxMainFrame, g_PresetBundle, fresh_start))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||||
|
@ -521,18 +521,6 @@ size_t PresetCollection::first_visible_idx() const
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
|
||||||
size_t PresetCollection::first_compatible_idx() const
|
|
||||||
{
|
|
||||||
size_t idx = m_default_suppressed ? 1 : 0;
|
|
||||||
for (; idx < this->m_presets.size(); ++ idx)
|
|
||||||
if (m_presets[idx].is_compatible)
|
|
||||||
break;
|
|
||||||
if (idx == this->m_presets.size())
|
|
||||||
idx = 0;
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PresetCollection::set_default_suppressed(bool default_suppressed)
|
void PresetCollection::set_default_suppressed(bool default_suppressed)
|
||||||
{
|
{
|
||||||
if (m_default_suppressed != default_suppressed) {
|
if (m_default_suppressed != default_suppressed) {
|
||||||
@ -541,7 +529,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresetCollection::update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
|
size_t PresetCollection::update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible)
|
||||||
{
|
{
|
||||||
DynamicPrintConfig config;
|
DynamicPrintConfig config;
|
||||||
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
|
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
|
||||||
@ -552,14 +540,12 @@ void PresetCollection::update_compatible_with_printer(const Preset &active_print
|
|||||||
Preset &preset_selected = m_presets[idx_preset];
|
Preset &preset_selected = m_presets[idx_preset];
|
||||||
Preset &preset_edited = selected ? m_edited_preset : preset_selected;
|
Preset &preset_edited = selected ? m_edited_preset : preset_selected;
|
||||||
if (! preset_edited.update_compatible_with_printer(active_printer, &config) &&
|
if (! preset_edited.update_compatible_with_printer(active_printer, &config) &&
|
||||||
selected && select_other_if_incompatible)
|
selected && unselect_if_incompatible)
|
||||||
m_idx_selected = (size_t)-1;
|
m_idx_selected = (size_t)-1;
|
||||||
if (selected)
|
if (selected)
|
||||||
preset_selected.is_compatible = preset_edited.is_compatible;
|
preset_selected.is_compatible = preset_edited.is_compatible;
|
||||||
}
|
}
|
||||||
if (m_idx_selected == (size_t)-1)
|
return m_idx_selected;
|
||||||
// Find some other compatible preset, or the "-- default --" preset.
|
|
||||||
this->select_preset(first_compatible_idx());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the preset under a new name. If the name is different from the old one,
|
// Save the preset under a new name. If the name is different from the old one,
|
||||||
@ -689,8 +675,8 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
|
|||||||
// 1) Try to find the preset by its name.
|
// 1) Try to find the preset by its name.
|
||||||
auto it = this->find_preset_internal(name);
|
auto it = this->find_preset_internal(name);
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
if (it != m_presets.end() && it->name == name)
|
if (it != m_presets.end() && it->name == name && it->is_visible)
|
||||||
// Preset found by its name.
|
// Preset found by its name and it is visible.
|
||||||
idx = it - m_presets.begin();
|
idx = it - m_presets.begin();
|
||||||
else {
|
else {
|
||||||
// Find the first visible preset.
|
// Find the first visible preset.
|
||||||
@ -711,6 +697,23 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PresetCollection::select_preset_by_name_strict(const std::string &name)
|
||||||
|
{
|
||||||
|
// 1) Try to find the preset by its name.
|
||||||
|
auto it = this->find_preset_internal(name);
|
||||||
|
size_t idx = (size_t)-1;
|
||||||
|
if (it != m_presets.end() && it->name == name && it->is_visible)
|
||||||
|
// Preset found by its name.
|
||||||
|
idx = it - m_presets.begin();
|
||||||
|
// 2) Select the new preset.
|
||||||
|
if (idx != (size_t)-1) {
|
||||||
|
this->select_preset(idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
m_idx_selected = idx;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PresetCollection::name() const
|
std::string PresetCollection::name() const
|
||||||
{
|
{
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
|
@ -18,6 +18,7 @@ class wxItemContainer;
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class AppConfig;
|
class AppConfig;
|
||||||
|
class PresetBundle;
|
||||||
|
|
||||||
enum ConfigFileType
|
enum ConfigFileType
|
||||||
{
|
{
|
||||||
@ -243,19 +244,49 @@ public:
|
|||||||
{ return const_cast<PresetCollection*>(this)->find_preset(name, first_visible_if_not_found); }
|
{ return const_cast<PresetCollection*>(this)->find_preset(name, first_visible_if_not_found); }
|
||||||
|
|
||||||
size_t first_visible_idx() const;
|
size_t first_visible_idx() const;
|
||||||
size_t first_compatible_idx() const;
|
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
||||||
|
// If one of the prefered_alternates is compatible, select it.
|
||||||
|
template<typename PreferedCondition>
|
||||||
|
size_t first_compatible_idx(PreferedCondition prefered_condition) const
|
||||||
|
{
|
||||||
|
size_t i = m_default_suppressed ? 1 : 0;
|
||||||
|
size_t n = this->m_presets.size();
|
||||||
|
size_t i_compatible = n;
|
||||||
|
for (; i < n; ++ i)
|
||||||
|
if (m_presets[i].is_compatible) {
|
||||||
|
if (prefered_condition(m_presets[i].name))
|
||||||
|
return i;
|
||||||
|
if (i_compatible == n)
|
||||||
|
// Store the first compatible profile into i_compatible.
|
||||||
|
i_compatible = i;
|
||||||
|
}
|
||||||
|
return (i_compatible == n) ? 0 : i_compatible;
|
||||||
|
}
|
||||||
|
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
||||||
|
size_t first_compatible_idx() const { return this->first_compatible_idx([](const std::string&){return true;}); }
|
||||||
|
|
||||||
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
||||||
// Return the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
// Return the first visible preset. Certainly at least the '- default -' preset shall be visible.
|
||||||
Preset& first_visible() { return this->preset(this->first_visible_idx()); }
|
Preset& first_visible() { return this->preset(this->first_visible_idx()); }
|
||||||
const Preset& first_visible() const { return this->preset(this->first_visible_idx()); }
|
const Preset& first_visible() const { return this->preset(this->first_visible_idx()); }
|
||||||
Preset& first_compatible() { return this->preset(this->first_compatible_idx()); }
|
Preset& first_compatible() { return this->preset(this->first_compatible_idx()); }
|
||||||
|
template<typename PreferedCondition>
|
||||||
|
Preset& first_compatible(PreferedCondition prefered_condition) { return this->preset(this->first_compatible_idx(prefered_condition)); }
|
||||||
const Preset& first_compatible() const { return this->preset(this->first_compatible_idx()); }
|
const Preset& first_compatible() const { return this->preset(this->first_compatible_idx()); }
|
||||||
|
|
||||||
// Return number of presets including the "- default -" preset.
|
// Return number of presets including the "- default -" preset.
|
||||||
size_t size() const { return this->m_presets.size(); }
|
size_t size() const { return this->m_presets.size(); }
|
||||||
|
|
||||||
// For Print / Filament presets, disable those, which are not compatible with the printer.
|
// For Print / Filament presets, disable those, which are not compatible with the printer.
|
||||||
void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible);
|
template<typename PreferedCondition>
|
||||||
|
void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible, PreferedCondition prefered_condition)
|
||||||
|
{
|
||||||
|
if (this->update_compatible_with_printer_internal(active_printer, select_other_if_incompatible) == (size_t)-1)
|
||||||
|
// Find some other compatible preset, or the "-- default --" preset.
|
||||||
|
this->select_preset(this->first_compatible_idx(prefered_condition));
|
||||||
|
}
|
||||||
|
void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
|
||||||
|
{ this->update_compatible_with_printer(active_printer, select_other_if_incompatible, [](const std::string&){return true;}); }
|
||||||
|
|
||||||
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }
|
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }
|
||||||
|
|
||||||
@ -291,6 +322,11 @@ public:
|
|||||||
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
|
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
|
||||||
std::string path_from_name(const std::string &new_name) const;
|
std::string path_from_name(const std::string &new_name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Select a preset, if it exists. If it does not exist, select an invalid (-1) index.
|
||||||
|
// This is a temporary state, which shall be fixed immediately by the following step.
|
||||||
|
bool select_preset_by_name_strict(const std::string &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PresetCollection();
|
PresetCollection();
|
||||||
PresetCollection(const PresetCollection &other);
|
PresetCollection(const PresetCollection &other);
|
||||||
@ -308,6 +344,8 @@ private:
|
|||||||
std::deque<Preset>::const_iterator find_preset_internal(const std::string &name) const
|
std::deque<Preset>::const_iterator find_preset_internal(const std::string &name) const
|
||||||
{ return const_cast<PresetCollection*>(this)->find_preset_internal(name); }
|
{ return const_cast<PresetCollection*>(this)->find_preset_internal(name); }
|
||||||
|
|
||||||
|
size_t update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible);
|
||||||
|
|
||||||
static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference);
|
static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference);
|
||||||
|
|
||||||
// Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
|
// Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
|
||||||
@ -333,6 +371,9 @@ private:
|
|||||||
wxBitmap *m_bitmap_main_frame;
|
wxBitmap *m_bitmap_main_frame;
|
||||||
// Path to the directory to store the config files into.
|
// Path to the directory to store the config files into.
|
||||||
std::string m_dir_path;
|
std::string m_dir_path;
|
||||||
|
|
||||||
|
// to access select_preset_by_name_strict()
|
||||||
|
friend class PresetBundle;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -209,22 +209,34 @@ void PresetBundle::load_installed_printers(const AppConfig &config)
|
|||||||
// This is done just once on application start up.
|
// This is done just once on application start up.
|
||||||
void PresetBundle::load_selections(const AppConfig &config)
|
void PresetBundle::load_selections(const AppConfig &config)
|
||||||
{
|
{
|
||||||
prints.select_preset_by_name(remove_ini_suffix(config.get("presets", "print")), true);
|
// Update visibility of presets based on application vendor / model / variant configuration.
|
||||||
filaments.select_preset_by_name(remove_ini_suffix(config.get("presets", "filament")), true);
|
this->load_installed_printers(config);
|
||||||
printers.select_preset_by_name(remove_ini_suffix(config.get("presets", "printer")), true);
|
|
||||||
|
// Parse the initial print / filament / printer profile names.
|
||||||
|
std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print"));
|
||||||
|
std::vector<std::string> initial_filament_profile_names;
|
||||||
|
std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", "printer"));
|
||||||
|
|
||||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
|
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
|
||||||
size_t num_extruders = nozzle_diameter->values.size();
|
size_t num_extruders = nozzle_diameter->values.size();
|
||||||
this->set_filament_preset(0, filaments.get_selected_preset().name);
|
initial_filament_profile_names.emplace_back(remove_ini_suffix(config.get("presets", "filament")));
|
||||||
|
this->set_filament_preset(0, initial_filament_profile_names.back());
|
||||||
for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
|
for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
|
||||||
char name[64];
|
char name[64];
|
||||||
sprintf(name, "filament_%d", i);
|
sprintf(name, "filament_%d", i);
|
||||||
if (! config.has("presets", name))
|
if (! config.has("presets", name))
|
||||||
break;
|
break;
|
||||||
this->set_filament_preset(i, remove_ini_suffix(config.get("presets", name)));
|
initial_filament_profile_names.emplace_back(remove_ini_suffix(config.get("presets", name)));
|
||||||
|
this->set_filament_preset(i, initial_filament_profile_names.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update visibility of presets based on application vendor / model / variant configuration.
|
// Activate print / filament / printer profiles from the config.
|
||||||
this->load_installed_printers(config);
|
// If the printer profile enumerated by the config are not visible, select an alternate preset.
|
||||||
|
// Do not select alternate profiles for the print / filament profiles as those presets
|
||||||
|
// will be selected by the following call of this->update_compatible_with_printer(true).
|
||||||
|
prints.select_preset_by_name_strict(initial_print_profile_name);
|
||||||
|
filaments.select_preset_by_name_strict(initial_filament_profile_names.front());
|
||||||
|
printers.select_preset_by_name(initial_printer_profile_name, true);
|
||||||
|
|
||||||
// Update visibility of presets based on their compatibility with the active printer.
|
// Update visibility of presets based on their compatibility with the active printer.
|
||||||
// Always try to select a compatible print and filament preset to the current printer preset,
|
// Always try to select a compatible print and filament preset to the current printer preset,
|
||||||
@ -861,14 +873,35 @@ void PresetBundle::update_multi_material_filament_presets()
|
|||||||
|
|
||||||
void PresetBundle::update_compatible_with_printer(bool select_other_if_incompatible)
|
void PresetBundle::update_compatible_with_printer(bool select_other_if_incompatible)
|
||||||
{
|
{
|
||||||
this->prints.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
|
const Preset &printer_preset = this->printers.get_edited_preset();
|
||||||
this->filaments.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
|
const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
|
||||||
|
const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
|
||||||
|
prefered_print_profile.empty() ?
|
||||||
|
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
|
||||||
|
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
|
||||||
|
[&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
|
||||||
|
prefered_filament_profiles.empty() ?
|
||||||
|
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
|
||||||
|
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
|
||||||
|
[&prefered_filament_profiles](const std::string& profile_name)
|
||||||
|
{ return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); });
|
||||||
if (select_other_if_incompatible) {
|
if (select_other_if_incompatible) {
|
||||||
// Verify validity of the current filament presets.
|
// Verify validity of the current filament presets.
|
||||||
for (std::string &filament_name : this->filament_presets) {
|
this->filament_presets.front() = this->filaments.get_edited_preset().name;
|
||||||
|
for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) {
|
||||||
|
std::string &filament_name = this->filament_presets[idx];
|
||||||
Preset *preset = this->filaments.find_preset(filament_name, false);
|
Preset *preset = this->filaments.find_preset(filament_name, false);
|
||||||
if (preset == nullptr || ! preset->is_compatible)
|
if (preset == nullptr || ! preset->is_compatible) {
|
||||||
|
// Pick a compatible profile. If there are prefered_filament_profiles, use them.
|
||||||
|
if (prefered_filament_profiles.empty())
|
||||||
filament_name = this->filaments.first_compatible().name;
|
filament_name = this->filaments.first_compatible().name;
|
||||||
|
else {
|
||||||
|
const std::string &preferred = (idx < prefered_filament_profiles.size()) ?
|
||||||
|
prefered_filament_profiles[idx] : prefered_filament_profiles.front();
|
||||||
|
filament_name = this->filaments.first_compatible(
|
||||||
|
[&preferred](const std::string& profile_name){ return profile_name == preferred; }).name;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,7 +540,8 @@ void Tab::load_key_value(std::string opt_key, boost::any value)
|
|||||||
change_opt_value(*m_config, opt_key, value);
|
change_opt_value(*m_config, opt_key, value);
|
||||||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||||
if (opt_key.compare("compatible_printers") == 0) {
|
if (opt_key.compare("compatible_printers") == 0) {
|
||||||
m_preset_bundle->update_compatible_with_printer(0);
|
// Don't select another profile if this profile happens to become incompatible.
|
||||||
|
m_preset_bundle->update_compatible_with_printer(false);
|
||||||
}
|
}
|
||||||
m_presets->update_dirty_ui(m_presets_choice);
|
m_presets->update_dirty_ui(m_presets_choice);
|
||||||
on_presets_changed();
|
on_presets_changed();
|
||||||
@ -1772,7 +1773,7 @@ void Tab::rebuild_page_tree()
|
|||||||
// Called by the UI combo box when the user switches profiles.
|
// Called by the UI combo box when the user switches profiles.
|
||||||
// Select a preset by a name.If !defined(name), then the default preset is selected.
|
// Select a preset by a name.If !defined(name), then the default preset is selected.
|
||||||
// If the current profile is modified, user is asked to save the changes.
|
// If the current profile is modified, user is asked to save the changes.
|
||||||
void Tab::select_preset(std::string preset_name /*= ""*/)
|
void Tab::select_preset(const std::string &preset_name /*= ""*/)
|
||||||
{
|
{
|
||||||
std::string name = preset_name;
|
std::string name = preset_name;
|
||||||
auto force = false;
|
auto force = false;
|
||||||
|
@ -143,7 +143,7 @@ public:
|
|||||||
void create_preset_tab(PresetBundle *preset_bundle);
|
void create_preset_tab(PresetBundle *preset_bundle);
|
||||||
void load_current_preset();
|
void load_current_preset();
|
||||||
void rebuild_page_tree();
|
void rebuild_page_tree();
|
||||||
void select_preset(std::string preset_name = "");
|
void select_preset(const std::string &preset_name = "");
|
||||||
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, std::string new_printer_name = "");
|
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, std::string new_printer_name = "");
|
||||||
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
|
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
|
||||||
|
|
||||||
|
@ -44,9 +44,6 @@
|
|||||||
|
|
||||||
Ref<Preset> find_preset(char *name, bool first_visible_if_not_found = false) %code%{ RETVAL = THIS->find_preset(name, first_visible_if_not_found); %};
|
Ref<Preset> find_preset(char *name, bool first_visible_if_not_found = false) %code%{ RETVAL = THIS->find_preset(name, first_visible_if_not_found); %};
|
||||||
|
|
||||||
bool current_is_dirty();
|
|
||||||
std::vector<std::string> current_dirty_options();
|
|
||||||
|
|
||||||
void update_tab_ui(SV *ui, bool show_incompatible)
|
void update_tab_ui(SV *ui, bool show_incompatible)
|
||||||
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
|
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
|
||||||
THIS->update_tab_ui(cb, show_incompatible); %};
|
THIS->update_tab_ui(cb, show_incompatible); %};
|
||||||
@ -55,30 +52,6 @@
|
|||||||
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
|
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
|
||||||
THIS->update_platter_ui(cb); %};
|
THIS->update_platter_ui(cb); %};
|
||||||
|
|
||||||
bool update_dirty_ui(SV *ui)
|
|
||||||
%code%{ RETVAL = THIS->update_dirty_ui((wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox")); %};
|
|
||||||
|
|
||||||
void select_preset(int idx);
|
|
||||||
bool select_preset_by_name(char *name) %code%{ RETVAL = THIS->select_preset_by_name(name, true); %};
|
|
||||||
void discard_current_changes();
|
|
||||||
|
|
||||||
void save_current_preset(char *new_name)
|
|
||||||
%code%{
|
|
||||||
try {
|
|
||||||
THIS->save_current_preset(new_name);
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
croak("Error saving a preset %s:\n%s\n", new_name, e.what());
|
|
||||||
}
|
|
||||||
%};
|
|
||||||
void delete_current_preset()
|
|
||||||
%code%{
|
|
||||||
try {
|
|
||||||
THIS->delete_current_preset();
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
croak("Error deleting a preset file %s:\n%s\n", THIS->get_selected_preset().file.c_str(), e.what());
|
|
||||||
}
|
|
||||||
%};
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
||||||
SV*
|
SV*
|
||||||
@ -173,9 +146,6 @@ PresetCollection::arrayref()
|
|||||||
|
|
||||||
std::vector<std::string> filament_presets() %code%{ RETVAL = THIS->filament_presets; %};
|
std::vector<std::string> filament_presets() %code%{ RETVAL = THIS->filament_presets; %};
|
||||||
void set_filament_preset(int idx, const char *name);
|
void set_filament_preset(int idx, const char *name);
|
||||||
void update_multi_material_filament_presets();
|
|
||||||
|
|
||||||
void update_compatible_with_printer(bool select_other_if_incompatible);
|
|
||||||
|
|
||||||
Clone<DynamicPrintConfig> full_config() %code%{ RETVAL = THIS->full_config(); %};
|
Clone<DynamicPrintConfig> full_config() %code%{ RETVAL = THIS->full_config(); %};
|
||||||
|
|
||||||
@ -183,15 +153,3 @@ PresetCollection::arrayref()
|
|||||||
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox");
|
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox");
|
||||||
THIS->update_platter_filament_ui(extruder_idx, cb); %};
|
THIS->update_platter_filament_ui(extruder_idx, cb); %};
|
||||||
};
|
};
|
||||||
|
|
||||||
%name{Slic3r::GUI::PresetHints} class PresetHints {
|
|
||||||
PresetHints();
|
|
||||||
~PresetHints();
|
|
||||||
|
|
||||||
static std::string cooling_description(Preset *preset)
|
|
||||||
%code%{ RETVAL = PresetHints::cooling_description(*preset); %};
|
|
||||||
static std::string maximum_volumetric_flow_description(PresetBundle *preset)
|
|
||||||
%code%{ RETVAL = PresetHints::maximum_volumetric_flow_description(*preset); %};
|
|
||||||
static std::string recommended_thin_wall_thickness(PresetBundle *preset)
|
|
||||||
%code%{ RETVAL = PresetHints::recommended_thin_wall_thickness(*preset); %};
|
|
||||||
};
|
|
||||||
|
@ -231,8 +231,6 @@ PresetCollection* O_OBJECT_SLIC3R
|
|||||||
Ref<PresetCollection> O_OBJECT_SLIC3R_T
|
Ref<PresetCollection> O_OBJECT_SLIC3R_T
|
||||||
PresetBundle* O_OBJECT_SLIC3R
|
PresetBundle* O_OBJECT_SLIC3R
|
||||||
Ref<PresetBundle> O_OBJECT_SLIC3R_T
|
Ref<PresetBundle> O_OBJECT_SLIC3R_T
|
||||||
PresetHints* O_OBJECT_SLIC3R
|
|
||||||
Ref<PresetHints> O_OBJECT_SLIC3R_T
|
|
||||||
TabIface* O_OBJECT_SLIC3R
|
TabIface* O_OBJECT_SLIC3R
|
||||||
Ref<TabIface> O_OBJECT_SLIC3R_T
|
Ref<TabIface> O_OBJECT_SLIC3R_T
|
||||||
|
|
||||||
|
@ -208,8 +208,6 @@
|
|||||||
%typemap{Ref<PresetCollection>}{simple};
|
%typemap{Ref<PresetCollection>}{simple};
|
||||||
%typemap{PresetBundle*};
|
%typemap{PresetBundle*};
|
||||||
%typemap{Ref<PresetBundle>}{simple};
|
%typemap{Ref<PresetBundle>}{simple};
|
||||||
%typemap{PresetHints*};
|
|
||||||
%typemap{Ref<PresetHints>}{simple};
|
|
||||||
%typemap{TabIface*};
|
%typemap{TabIface*};
|
||||||
%typemap{Ref<TabIface>}{simple};
|
%typemap{Ref<TabIface>}{simple};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user