OverrideSettingsPanel.pm 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # Included in ObjectSettingsDialog -> ObjectPartsPanel.
  2. # Maintains, displays, adds and removes overrides of slicing parameters for an object and its modifier mesh.
  3. package Slic3r::GUI::Plater::OverrideSettingsPanel;
  4. use strict;
  5. use warnings;
  6. use utf8;
  7. use List::Util qw(first);
  8. use Wx qw(:misc :sizer :button wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG
  9. wxTheApp);
  10. use Wx::Event qw(EVT_BUTTON EVT_LEFT_DOWN EVT_MENU);
  11. use base 'Wx::ScrolledWindow';
  12. use constant ICON_MATERIAL => 0;
  13. use constant ICON_SOLIDMESH => 1;
  14. use constant ICON_MODIFIERMESH => 2;
  15. my %icons = (
  16. 'Advanced' => 'wand.png',
  17. 'Extruders' => 'funnel.png',
  18. 'Extrusion Width' => 'funnel.png',
  19. 'Infill' => 'infill.png',
  20. 'Layers and Perimeters' => 'layers.png',
  21. 'Skirt and brim' => 'box.png',
  22. 'Speed' => 'time.png',
  23. 'Speed > Acceleration' => 'time.png',
  24. 'Support material' => 'building.png',
  25. );
  26. sub new {
  27. my ($class, $parent, %params) = @_;
  28. my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
  29. # C++ class Slic3r::DynamicPrintConfig, initially empty.
  30. $self->{default_config} = Slic3r::Config->new;
  31. $self->{config} = Slic3r::Config->new;
  32. # On change callback.
  33. $self->{on_change} = $params{on_change};
  34. $self->{fixed_options} = {};
  35. $self->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
  36. $self->{options_sizer} = Wx::BoxSizer->new(wxVERTICAL);
  37. $self->{sizer}->Add($self->{options_sizer}, 0, wxEXPAND | wxALL, 0);
  38. # option selector
  39. {
  40. # create the button
  41. my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("add.png"), wxBITMAP_TYPE_PNG),
  42. wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
  43. EVT_LEFT_DOWN($btn, sub {
  44. my $menu = Wx::Menu->new;
  45. # create category submenus
  46. my %categories = (); # category => submenu
  47. foreach my $opt_key (@{$self->{options}}) {
  48. if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) {
  49. $categories{$cat} //= Wx::Menu->new;
  50. }
  51. }
  52. # append submenus to main menu
  53. my @categories = ('Layers and Perimeters', 'Infill', 'Support material', 'Speed', 'Extruders', 'Extrusion Width', 'Advanced');
  54. #foreach my $cat (sort keys %categories) {
  55. foreach my $cat (@categories) {
  56. wxTheApp->append_submenu($menu, $cat, "", $categories{$cat}, undef, $icons{$cat});
  57. }
  58. # append options to submenus
  59. foreach my $opt_key (@{$self->{options}}) {
  60. my $cat = $Slic3r::Config::Options->{$opt_key}{category} or next;
  61. my $cb = sub {
  62. $self->{config}->set($opt_key, $self->{default_config}->get($opt_key));
  63. $self->update_optgroup;
  64. $self->{on_change}->($opt_key) if $self->{on_change};
  65. };
  66. wxTheApp->append_menu_item($categories{$cat}, $self->{option_labels}{$opt_key},
  67. $Slic3r::Config::Options->{$opt_key}{tooltip}, $cb);
  68. }
  69. $self->PopupMenu($menu, $btn->GetPosition);
  70. $menu->Destroy;
  71. });
  72. my $h_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
  73. $h_sizer->Add($btn, 0, wxALL, 0);
  74. $self->{sizer}->Add($h_sizer, 0, wxEXPAND | wxBOTTOM, 10);
  75. }
  76. $self->SetSizer($self->{sizer});
  77. $self->SetScrollbars(0, 1, 0, 1);
  78. $self->set_opt_keys($params{opt_keys}) if $params{opt_keys};
  79. $self->update_optgroup;
  80. return $self;
  81. }
  82. sub set_default_config {
  83. my ($self, $config) = @_;
  84. $self->{default_config} = $config;
  85. }
  86. sub set_config {
  87. my ($self, $config) = @_;
  88. $self->{config} = $config;
  89. $self->update_optgroup;
  90. }
  91. sub set_opt_keys {
  92. my ($self, $opt_keys) = @_;
  93. # sort options by category+label
  94. $self->{option_labels} = { map { $_ => $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label} } @$opt_keys };
  95. $self->{options} = [ sort { $self->{option_labels}{$a} cmp $self->{option_labels}{$b} } @$opt_keys ];
  96. }
  97. sub set_fixed_options {
  98. my ($self, $opt_keys) = @_;
  99. $self->{fixed_options} = { map {$_ => 1} @$opt_keys };
  100. $self->update_optgroup;
  101. }
  102. sub update_optgroup {
  103. my $self = shift;
  104. $self->{options_sizer}->Clear(1);
  105. return if !defined $self->{config};
  106. my %categories = ();
  107. foreach my $opt_key (@{$self->{config}->get_keys}) {
  108. my $category = $Slic3r::Config::Options->{$opt_key}{category};
  109. $categories{$category} ||= [];
  110. push @{$categories{$category}}, $opt_key;
  111. }
  112. foreach my $category (sort keys %categories) {
  113. my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
  114. parent => $self,
  115. title => $category,
  116. config => $self->{config},
  117. full_labels => 1,
  118. label_font => $Slic3r::GUI::small_font,
  119. sidetext_font => $Slic3r::GUI::small_font,
  120. label_width => 120,
  121. on_change => sub { $self->{on_change}->() if $self->{on_change} },
  122. extra_column => sub {
  123. my ($line) = @_;
  124. my $opt_key = $line->get_options->[0]->opt_id; # we assume that we have one option per line
  125. # disallow deleting fixed options
  126. return undef if $self->{fixed_options}{$opt_key};
  127. my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("delete.png"), wxBITMAP_TYPE_PNG),
  128. wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
  129. EVT_BUTTON($self, $btn, sub {
  130. $self->{config}->erase($opt_key);
  131. $self->{on_change}->() if $self->{on_change};
  132. wxTheApp->CallAfter(sub { $self->update_optgroup });
  133. });
  134. return $btn;
  135. },
  136. );
  137. foreach my $opt_key (sort @{$categories{$category}}) {
  138. $optgroup->append_single_option_line($opt_key);
  139. }
  140. $self->{options_sizer}->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 0);
  141. }
  142. $self->GetParent->Layout; # we need this for showing scrollbars
  143. }
  144. # work around a wxMAC bug causing controls not being disabled when calling Disable() on a Window
  145. sub enable {
  146. my ($self) = @_;
  147. $self->{btn_add}->Enable;
  148. $self->Enable;
  149. }
  150. sub disable {
  151. my ($self) = @_;
  152. $self->{btn_add}->Disable;
  153. $self->Disable;
  154. }
  155. 1;