diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 1c96962a0..a030f57ca 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -36,9 +36,8 @@ use Slic3r::GUI::Tab; our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1"; our $have_LWP = eval "use LWP::UserAgent; 1"; -use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow - :filedialog :font); -use Wx::Event qw(EVT_IDLE EVT_COMMAND); +use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow :filedialog :font); +use Wx::Event qw(EVT_IDLE EVT_COMMAND EVT_MENU); use base 'Wx::App'; use constant FILE_WILDCARDS => { @@ -404,6 +403,39 @@ sub scan_serial_ports { return grep !/Bluetooth|FireFly/, @ports; } +sub append_menu_item { + my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_; + + $id //= &Wx::NewId(); + my $item = Wx::MenuItem->new($menu, $id, $string, $description // '', $kind // 0); + $self->set_menu_item_icon($item, $icon); + $menu->Append($item); + + EVT_MENU($self, $id, $cb); + return $item; +} + +sub append_submenu { + my ($self, $menu, $string, $description, $submenu, $id, $icon) = @_; + + $id //= &Wx::NewId(); + my $item = Wx::MenuItem->new($menu, $id, $string, $description // ''); + $self->set_menu_item_icon($item, $icon); + $item->SetSubMenu($submenu); + $menu->Append($item); + + return $item; +} + +sub set_menu_item_icon { + my ($self, $menuItem, $icon) = @_; + + # SetBitmap was not available on OS X before Wx 0.9927 + if ($icon && $menuItem->can('SetBitmap')) { + $menuItem->SetBitmap(Wx::Bitmap->new($Slic3r::var->($icon), wxBITMAP_TYPE_PNG)); + } +} + sub save_window_pos { my ($self, $window, $name) = @_; diff --git a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm index 543e7fe40..d99b470db 100644 --- a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm +++ b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm @@ -16,6 +16,18 @@ use constant ICON_MATERIAL => 0; use constant ICON_SOLIDMESH => 1; use constant ICON_MODIFIERMESH => 2; +my %icons = ( + 'Advanced' => 'wand.png', + 'Extruders' => 'funnel.png', + 'Extrusion Width' => 'funnel.png', + 'Infill' => 'infill.png', + 'Layers and Perimeters' => 'layers.png', + 'Skirt and brim' => 'box.png', + 'Speed' => 'time.png', + 'Speed > Acceleration' => 'time.png', + 'Support material' => 'building.png', +); + sub new { my $class = shift; my ($parent, %params) = @_; @@ -39,14 +51,29 @@ sub new { wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE); EVT_LEFT_DOWN($btn, sub { my $menu = Wx::Menu->new; + # create category submenus + my %categories = (); # category => submenu foreach my $opt_key (@{$self->{options}}) { - my $id = &Wx::NewId(); - $menu->Append($id, $self->{option_labels}{$opt_key}); - EVT_MENU($menu, $id, sub { + if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) { + $categories{$cat} //= Wx::Menu->new; + } + } + # append submenus to main menu + my @categories = ('Layers and Perimeters', 'Infill', 'Support material', 'Speed', 'Extruders', 'Extrusion Width', 'Advanced'); + #foreach my $cat (sort keys %categories) { + foreach my $cat (@categories) { + wxTheApp->append_submenu($menu, $cat, "", $categories{$cat}, undef, $icons{$cat}); + } + # append options to submenus + foreach my $opt_key (@{$self->{options}}) { + my $cat = $Slic3r::Config::Options->{$opt_key}{category} or next; + my $cb = sub { $self->{config}->set($opt_key, $self->{default_config}->get($opt_key)); $self->update_optgroup; - $self->{on_change}->() if $self->{on_change}; - }); + $self->{on_change}->($opt_key) if $self->{on_change}; + }; + wxTheApp->append_menu_item($categories{$cat}, $self->{option_labels}{$opt_key}, + $Slic3r::Config::Options->{$opt_key}{tooltip}, $cb); } $self->PopupMenu($menu, $btn->GetPosition); $menu->Destroy; @@ -79,11 +106,8 @@ sub set_config { sub set_opt_keys { my ($self, $opt_keys) = @_; - # sort options by category+label - $self->{option_labels} = { - map { $_ => sprintf('%s > %s', $Slic3r::Config::Options->{$_}{category}, $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label}) } @$opt_keys - }; + $self->{option_labels} = { map { $_ => $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label} } @$opt_keys }; $self->{options} = [ sort { $self->{option_labels}{$a} cmp $self->{option_labels}{$b} } @$opt_keys ]; } diff --git a/var/wand.png b/var/wand.png new file mode 100644 index 000000000..44ccbf812 Binary files /dev/null and b/var/wand.png differ diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 8688c1525..ff4de69ab 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1127,7 +1127,7 @@ PrintConfigDef::PrintConfigDef() def = this->add("seam_position", coEnum); def->label = "Seam position"; - def->category = "Layers and perimeters"; + def->category = "Layers and Perimeters"; def->tooltip = "Position of perimeters starting points."; def->cli = "seam-position=s"; def->enum_keys_map = ConfigOptionEnum::get_enum_values();