Enable/disable GUI controls according to the others in order to guide the user through option dependency

This commit is contained in:
Alessandro Ranellucci 2014-07-01 18:18:23 +02:00
parent 04b67f0cb0
commit a06fad9e13
5 changed files with 207 additions and 16 deletions

View file

@ -195,6 +195,18 @@ sub _build_field {
: $field->wxSizer;
}
sub get_option {
my ($self, $opt_id) = @_;
return undef if !exists $self->_options->{$opt_id};
return $self->_options->{$opt_id};
}
sub get_field {
my ($self, $opt_id) = @_;
return undef if !exists $self->_fields->{$opt_id};
return $self->_fields->{$opt_id};
}
sub get_value {
my ($self, $opt_id) = @_;
@ -267,6 +279,8 @@ has 'readonly' => (is => 'rw', default => sub { 0 });
package Slic3r::GUI::ConfigOptionsGroup;
use Moo;
use List::Util qw(first);
extends 'Slic3r::GUI::OptionsGroup';
has 'config' => (is => 'ro', required => 1);
has 'full_labels' => (is => 'ro', default => sub { 0 });
@ -328,6 +342,15 @@ sub reload_config {
}
}
sub get_fieldc {
my ($self, $opt_key, $opt_index) = @_;
$opt_index //= -1;
my $opt_id = first { $self->_opt_map->{$_}[0] eq $opt_key && $self->_opt_map->{$_}[1] == $opt_index }
keys %{$self->_opt_map};
return defined($opt_id) ? $self->get_field($opt_id) : undef;
}
sub _get_config_value {
my ($self, $opt_key, $opt_index, $deserialize) = @_;

View file

@ -28,6 +28,11 @@ sub set_tooltip {
if $tooltip && $self->can('SetToolTipString');
}
sub toggle {
my ($self, $enable) = @_;
$enable ? $self->enable : $self->disable;
}
sub _on_change {
my ($self, $opt_id) = @_;
@ -80,6 +85,20 @@ sub get_value {
return $self->wxWindow->GetValue;
}
sub enable {
my ($self) = @_;
$self->wxWindow->Enable;
$self->wxWindow->Refresh;
}
sub disable {
my ($self) = @_;
$self->wxWindow->Disable;
$self->wxWindow->Refresh;
}
package Slic3r::GUI::OptionsGroup::Field::Checkbox;
use Moo;
@ -154,6 +173,20 @@ sub BUILD {
});
}
sub enable {
my ($self) = @_;
$self->wxWindow->Enable;
$self->wxWindow->SetEditable(1);
}
sub disable {
my ($self) = @_;
$self->wxWindow->Disable;
$self->wxWindow->SetEditable(0);
}
package Slic3r::GUI::OptionsGroup::Field::Choice;
use Moo;
@ -343,6 +376,20 @@ sub get_value {
];
}
sub enable {
my ($self) = @_;
$self->x_textctrl->Enable;
$self->y_textctrl->Enable;
}
sub disable {
my ($self) = @_;
$self->x_textctrl->Disable;
$self->y_textctrl->Disable;
}
package Slic3r::GUI::OptionsGroup::Field::Slider;
use Moo;

View file

@ -31,13 +31,26 @@ sub new {
on_change => sub {
my ($opt_id) = @_;
my $value = $optgroup->get_value($opt_id);
$self->{cut_options}{$opt_id} = $value;
if ($opt_id eq 'z') {
$self->{cut_options}{$opt_id} = $optgroup->get_value($opt_id);
# update canvas
if ($self->{canvas}) {
$self->{canvas}->SetCuttingPlane($value);
$self->{canvas}->SetCuttingPlane($self->{cut_options}{z});
$self->{canvas}->Render;
}
# update controls
my $z = $self->{cut_options}{z};
$optgroup->get_field('keep_upper')->toggle(my $have_upper = abs($z - $optgroup->get_option('z')->max) > 0.1);
$optgroup->get_field('keep_lower')->toggle(my $have_lower = $z > 0.1);
$optgroup->get_field('rotate_lower')->toggle($z > 0 && $self->{cut_options}{keep_lower});
# update cut button
if (($self->{cut_options}{keep_upper} && $have_upper)
|| ($self->{cut_options}{keep_lower} && $have_lower)) {
$self->{btn_cut}->Enable;
} else {
$self->{btn_cut}->Disable;
}
},
label_width => 120,

View file

@ -103,6 +103,7 @@ sub new {
$self->{config} = Slic3r::Config->new;
$self->build;
$self->_update;
if ($self->hidden_options) {
$self->{config}->apply(Slic3r::Config->new_from_defaults($self->hidden_options));
}
@ -166,8 +167,11 @@ sub _on_value_change {
$self->set_dirty(1);
$self->{on_value_change}->(@_) if $self->{on_value_change};
$self->_update;
}
sub _update {}
sub _on_presets_changed {
my $self = shift;
@ -390,6 +394,16 @@ sub load_config {
$self->reload_config;
}
sub get_field {
my ($self, $opt_key, $opt_index) = @_;
foreach my $page (@{ $self->{pages} }) {
my $field = $page->get_field($opt_key, $opt_index);
return $field if defined $field;
}
return undef;
}
package Slic3r::GUI::Tab::Print;
use base 'Slic3r::GUI::Tab';
@ -663,6 +677,47 @@ sub build {
}
}
sub _update {
my ($self) = @_;
my $config = $self->{config};
my $have_perimeters = $config->perimeters > 0;
$self->get_field('spiral_vase')->toggle($config->perimeters == 1 && $config->top_solid_layers == 0 && $config->fill_density == 0);
$self->get_field($_)->toggle($have_perimeters)
for qw(extra_perimeters thin_walls overhangs seam_position external_perimeters_first);
my $have_infill = $config->fill_density > 0;
$self->get_field($_)->toggle($have_infill)
for qw(fill_pattern infill_every_layers infill_only_where_needed solid_infill_every_layers);
my $have_default_acceleration = $config->default_acceleration > 0;
$self->get_field($_)->toggle($have_default_acceleration)
for qw(perimeter_acceleration infill_acceleration bridge_acceleration first_layer_acceleration);
my $have_skirt = $config->skirts > 0 || $config->min_skirt_length > 0;
$self->get_field($_)->toggle($have_skirt)
for qw(skirt_distance skirt_height);
my $have_support_material = $config->support_material || $config->raft_layers > 0;
my $have_support_interface = $config->support_material_interface_layers > 0;
$self->get_field($_)->toggle($have_support_material)
for qw(support_material_threshold support_material_enforce_layers
support_material_pattern support_material_spacing support_material_angle
support_material_interface_layers dont_support_bridges
support_material_extruder);
$self->get_field($_)->toggle($have_support_material && $have_support_interface)
for qw(support_material_interface_spacing support_material_interface_extruder);
my $have_sequential_printing = $config->complete_objects;
$self->get_field($_)->toggle($have_sequential_printing)
for qw(extruder_clearance_radius extruder_clearance_height);
my $have_ooze_prevention = $config->ooze_prevention;
$self->get_field($_)->toggle($have_ooze_prevention)
for qw(standby_temperature_delta);
}
sub hidden_options { !$Slic3r::have_threads ? qw(threads) : () }
package Slic3r::GUI::Tab::Filament;
@ -754,8 +809,23 @@ sub build {
$optgroup->append_single_option_line('min_print_speed');
}
}
}
sub _on_value_change {
my $self = shift;
my ($opt_key) = @_;
$self->SUPER::_on_value_change(@_);
}
sub _update {
my ($self) = @_;
$self->_update_description;
my $cooling = $self->{config}->cooling;
$self->get_field($_)->toggle($cooling)
for qw(min_fan_speed max_fan_speed disable_fan_first_layers
fan_below_layer_time slowdown_below_layer_time min_print_speed);
}
sub _update_description {
@ -787,14 +857,6 @@ sub _update_description {
$self->{description_line}->SetText($msg);
}
sub _on_value_change {
my $self = shift;
my ($opt_key) = @_;
$self->SUPER::_on_value_change(@_);
$self->_update_description;
}
package Slic3r::GUI::Tab::Printer;
use base 'Slic3r::GUI::Tab';
use Wx qw(:sizer :button :bitmap :misc :id);
@ -879,6 +941,7 @@ sub build {
if ($opt_id eq 'extruders_count') {
$self->{extruders_count} = $optgroup->get_value('extruders_count');
$self->_build_extruder_pages;
$self->_update;
}
});
}
@ -1000,6 +1063,41 @@ sub _build_extruder_pages {
$self->update_tree(0);
}
sub _update {
my ($self) = @_;
my $config = $self->{config};
$self->get_field('toolchange_gcode')->toggle($self->{extruders_count} > 1);
for my $i (0 .. ($self->{extruders_count}-1)) {
# disable extruder offset for first extruder
$self->get_field('extruder_offset', $i)->toggle($i != 0);
my $have_retract_length = $config->get_at('retract_length', $i) > 0;
# when using firmware retraction, firmware decides retraction length
$self->get_field('retract_length', $i)->toggle(!$config->use_firmware_retraction);
# user can customize travel length if we have retraction length or we're using
# firmware retraction
$self->get_field('retract_before_travel', $i)->toggle($have_retract_length || $config->use_firmware_retraction);
# user can customize other retraction options if retraction is enabled
my $retraction = ($have_retract_length || $config->use_firmware_retraction);
$self->get_field($_, $i)->toggle($retraction)
for qw(retract_lift retract_layer_change);
# some options only apply when not using firmware retraction
$self->get_field($_, $i)->toggle($retraction && !$config->use_firmware_retraction)
for qw(retract_speed retract_restart_extra wipe);
my $toolchange_retraction = $config->get_at('retract_length_toolchange', $i) > 0;
$self->get_field($_, $i)->toggle($toolchange_retraction)
for qw(retract_restart_extra_toolchange);
}
}
# this gets executed after preset is loaded and before GUI fields are updated
sub on_preset_loaded {
my $self = shift;
@ -1067,6 +1165,16 @@ sub reload_config {
$_->reload_config for @{$self->{optgroups}};
}
sub get_field {
my ($self, $opt_key, $opt_index) = @_;
foreach my $optgroup (@{ $self->{optgroups} }) {
my $field = $optgroup->get_fieldc($opt_key, $opt_index);
return $field if defined $field;
}
return undef;
}
sub set_value {
my $self = shift;
my ($opt_key, $value) = @_;

View file

@ -724,7 +724,7 @@ PrintConfigDef::build_def() {
Options["spiral_vase"].type = coBool;
Options["spiral_vase"].label = "Spiral vase";
Options["spiral_vase"].tooltip = "This experimental feature will raise Z gradually while printing a single-walled object in order to remove any visible seam. By enabling this option other settings will be overridden to enforce a single perimeter, no infill, no top solid layers, no support material. You can still set any number of bottom solid layers as well as skirt/brim loops. It won't work when printing more than an object.";
Options["spiral_vase"].tooltip = "This feature will raise Z gradually while printing a single-walled object in order to remove any visible seam. This option requires a single perimeter, no infill, no top solid layers and no support material. You can still set any number of bottom solid layers as well as skirt/brim loops. It won't work when printing more than an object.";
Options["spiral_vase"].cli = "spiral-vase!";
Options["standby_temperature_delta"].type = coInt;