Add nice icons to the dropdown override menu

This commit is contained in:
Alessandro Ranellucci 2017-03-21 21:12:44 +01:00
parent cea9ff53d5
commit c2d933382a
5 changed files with 76 additions and 19 deletions

View File

@ -407,4 +407,13 @@ sub scan_serial_ports {
return grep !/Bluetooth|FireFly/, @ports; return grep !/Bluetooth|FireFly/, @ports;
} }
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));
}
}
1; 1;

View File

@ -638,19 +638,10 @@ sub _append_menu_item {
$id //= &Wx::NewId(); $id //= &Wx::NewId();
my $item = $menu->Append($id, $string, $description, $kind); my $item = $menu->Append($id, $string, $description, $kind);
$self->_set_menu_item_icon($item, $icon); wxTheApp->set_menu_item_icon($item, $icon);
EVT_MENU($self, $id, $cb); EVT_MENU($self, $id, $cb);
return $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));
}
}
1; 1;

View File

@ -2146,7 +2146,7 @@ sub object_menu {
my $rotateMenu = Wx::Menu->new; my $rotateMenu = Wx::Menu->new;
my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle'); my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle');
$frame->_set_menu_item_icon($rotateMenuItem, 'textfield.png'); wxTheApp->set_menu_item_icon($rotateMenuItem, 'textfield.png');
$frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub { $frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub {
$self->rotate(undef, X); $self->rotate(undef, X);
}, undef, 'bullet_red.png'); }, undef, 'bullet_red.png');
@ -2159,7 +2159,7 @@ sub object_menu {
my $mirrorMenu = Wx::Menu->new; my $mirrorMenu = Wx::Menu->new;
my $mirrorMenuItem = $menu->AppendSubMenu($mirrorMenu, "Mirror", 'Mirror the selected object'); my $mirrorMenuItem = $menu->AppendSubMenu($mirrorMenu, "Mirror", 'Mirror the selected object');
$frame->_set_menu_item_icon($mirrorMenuItem, 'shape_flip_horizontal.png'); wxTheApp->set_menu_item_icon($mirrorMenuItem, 'shape_flip_horizontal.png');
$frame->_append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub { $frame->_append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
$self->mirror(X); $self->mirror(X);
}, undef, 'bullet_red.png'); }, undef, 'bullet_red.png');
@ -2172,7 +2172,7 @@ sub object_menu {
my $scaleMenu = Wx::Menu->new; my $scaleMenu = Wx::Menu->new;
my $scaleMenuItem = $menu->AppendSubMenu($scaleMenu, "Scale", 'Scale the selected object along a single axis'); my $scaleMenuItem = $menu->AppendSubMenu($scaleMenu, "Scale", 'Scale the selected object along a single axis');
$frame->_set_menu_item_icon($scaleMenuItem, 'arrow_out.png'); wxTheApp->set_menu_item_icon($scaleMenuItem, 'arrow_out.png');
$frame->_append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { $frame->_append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef); $self->changescale(undef);
}); });
@ -2188,7 +2188,7 @@ sub object_menu {
my $scaleToSizeMenu = Wx::Menu->new; my $scaleToSizeMenu = Wx::Menu->new;
my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis'); my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis');
$frame->_set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png'); wxTheApp->set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png');
$frame->_append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub { $frame->_append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef, 1); $self->changescale(undef, 1);
}); });

View File

@ -15,6 +15,18 @@ use constant ICON_MATERIAL => 0;
use constant ICON_SOLIDMESH => 1; use constant ICON_SOLIDMESH => 1;
use constant ICON_MODIFIERMESH => 2; 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 { sub new {
my $class = shift; my $class = shift;
my ($parent, %params) = @_; my ($parent, %params) = @_;
@ -39,9 +51,23 @@ sub new {
if $btn->can('SetToolTipString'); if $btn->can('SetToolTipString');
EVT_LEFT_DOWN($btn, sub { EVT_LEFT_DOWN($btn, sub {
my $menu = Wx::Menu->new; my $menu = Wx::Menu->new;
my $last_cat = '';
foreach my $opt_key (@{$self->{options}}) { foreach my $opt_key (@{$self->{options}}) {
my $id = &Wx::NewId(); my $id = &Wx::NewId();
$menu->Append($id, $self->{option_labels}{$opt_key});
# add icon, if we have one for this category
my $icon;
if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) {
if ($last_cat && $cat ne $last_cat) {
$menu->AppendSeparator;
}
$last_cat = $cat;
$icon = $icons{$cat};
}
my $menuItem = $menu->Append($id, $self->{option_labels}{$opt_key});
wxTheApp->set_menu_item_icon($menuItem, $icon) if $icon;
EVT_MENU($menu, $id, sub { EVT_MENU($menu, $id, sub {
$self->{config}->set($opt_key, $self->{default_config}->get($opt_key)); $self->{config}->set($opt_key, $self->{default_config}->get($opt_key));
$self->update_optgroup; $self->update_optgroup;
@ -84,10 +110,18 @@ sub set_opt_keys {
my ($self, $opt_keys) = @_; my ($self, $opt_keys) = @_;
# sort options by category+label # sort options by category+label
$self->{option_labels} = { $self->{option_labels} = {};
map { $_ => sprintf('%s > %s', $Slic3r::Config::Options->{$_}{category}, $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label}) } @$opt_keys foreach my $opt_key (@$opt_keys) {
my $def = $Slic3r::Config::Options->{$opt_key} or next;
if (!$def->{category}) {
#printf "Skipping %s\n", $opt_key;
next;
}
$self->{option_labels}{$opt_key} = sprintf '%s > %s',
$def->{category},
$def->{full_label} // $def->{label};
}; };
$self->{options} = [ sort { $self->{option_labels}{$a} cmp $self->{option_labels}{$b} } @$opt_keys ]; $self->{options} = [ sort { $self->{option_labels}{$a} cmp $self->{option_labels}{$b} } keys %{$self->{option_labels}} ];
} }
# Sets the options that user can't remove. # Sets the options that user can't remove.

View File

@ -25,6 +25,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("avoid_crossing_perimeters", coBool); def = this->add("avoid_crossing_perimeters", coBool);
def->label = "Avoid crossing perimeters"; def->label = "Avoid crossing perimeters";
def->category = "Layers and Perimeters";
def->tooltip = "Optimize travel moves in order to minimize the crossing of perimeters. This is mostly useful with Bowden extruders which suffer from oozing. This feature slows down both the print and the G-code generation."; def->tooltip = "Optimize travel moves in order to minimize the crossing of perimeters. This is mostly useful with Bowden extruders which suffer from oozing. This feature slows down both the print and the G-code generation.";
def->cli = "avoid-crossing-perimeters!"; def->cli = "avoid-crossing-perimeters!";
def->default_value = new ConfigOptionBool(false); def->default_value = new ConfigOptionBool(false);
@ -82,6 +83,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("bridge_acceleration", coFloat); def = this->add("bridge_acceleration", coFloat);
def->label = "Bridge"; def->label = "Bridge";
def->category = "Speed > Acceleration";
def->tooltip = "This is the acceleration your printer will use for bridges. Set zero to disable acceleration control for bridges."; def->tooltip = "This is the acceleration your printer will use for bridges. Set zero to disable acceleration control for bridges.";
def->sidetext = "mm/s²"; def->sidetext = "mm/s²";
def->cli = "bridge-acceleration=f"; def->cli = "bridge-acceleration=f";
@ -120,6 +122,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("brim_connections_width", coFloat); def = this->add("brim_connections_width", coFloat);
def->label = "Brim connections width"; def->label = "Brim connections width";
def->category = "Skirt and brim";
def->tooltip = "If set to a positive value, straight connections will be built on the first layer between adjacent objects."; def->tooltip = "If set to a positive value, straight connections will be built on the first layer between adjacent objects.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "brim-connections-width=f"; def->cli = "brim-connections-width=f";
@ -128,6 +131,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("brim_width", coFloat); def = this->add("brim_width", coFloat);
def->label = "Exterior brim width"; def->label = "Exterior brim width";
def->category = "Skirt and brim";
def->tooltip = "Horizontal width of the brim that will be printed around each object on the first layer."; def->tooltip = "Horizontal width of the brim that will be printed around each object on the first layer.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "brim-width=f"; def->cli = "brim-width=f";
@ -152,6 +156,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("default_acceleration", coFloat); def = this->add("default_acceleration", coFloat);
def->label = "Default"; def->label = "Default";
def->category = "Speed > Acceleration";
def->tooltip = "This is the acceleration your printer will be reset to after the role-specific acceleration values are used (perimeter/infill). Set zero to prevent resetting acceleration at all."; def->tooltip = "This is the acceleration your printer will be reset to after the role-specific acceleration values are used (perimeter/infill). Set zero to prevent resetting acceleration at all.";
def->sidetext = "mm/s²"; def->sidetext = "mm/s²";
def->cli = "default-acceleration=f"; def->cli = "default-acceleration=f";
@ -505,6 +510,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("first_layer_acceleration", coFloat); def = this->add("first_layer_acceleration", coFloat);
def->label = "First layer"; def->label = "First layer";
def->category = "Speed > Acceleration";
def->tooltip = "This is the acceleration your printer will use for first layer. Set zero to disable acceleration control for first layer."; def->tooltip = "This is the acceleration your printer will use for first layer. Set zero to disable acceleration control for first layer.";
def->sidetext = "mm/s²"; def->sidetext = "mm/s²";
def->cli = "first-layer-acceleration=f"; def->cli = "first-layer-acceleration=f";
@ -543,6 +549,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("first_layer_speed", coFloatOrPercent); def = this->add("first_layer_speed", coFloatOrPercent);
def->label = "First layer speed"; def->label = "First layer speed";
def->category = "Speed";
def->tooltip = "If expressed as absolute value in mm/s, this speed will be applied to all the print moves of the first layer, regardless of their type. If expressed as a percentage (for example: 40%) it will scale the default speeds."; def->tooltip = "If expressed as absolute value in mm/s, this speed will be applied to all the print moves of the first layer, regardless of their type. If expressed as a percentage (for example: 40%) it will scale the default speeds.";
def->sidetext = "mm/s or %"; def->sidetext = "mm/s or %";
def->cli = "first-layer-speed=s"; def->cli = "first-layer-speed=s";
@ -614,6 +621,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("infill_acceleration", coFloat); def = this->add("infill_acceleration", coFloat);
def->label = "Infill"; def->label = "Infill";
def->category = "Speed > Acceleration";
def->tooltip = "This is the acceleration your printer will use for infill. Set zero to disable acceleration control for infill."; def->tooltip = "This is the acceleration your printer will use for infill. Set zero to disable acceleration control for infill.";
def->sidetext = "mm/s²"; def->sidetext = "mm/s²";
def->cli = "infill-acceleration=f"; def->cli = "infill-acceleration=f";
@ -652,6 +660,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("infill_first", coBool); def = this->add("infill_first", coBool);
def->label = "Infill before perimeters"; def->label = "Infill before perimeters";
def->category = "Infill";
def->tooltip = "This option will switch the print order of perimeters and infill, making the latter first."; def->tooltip = "This option will switch the print order of perimeters and infill, making the latter first.";
def->cli = "infill-first!"; def->cli = "infill-first!";
def->default_value = new ConfigOptionBool(false); def->default_value = new ConfigOptionBool(false);
@ -688,6 +697,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("interior_brim_width", coFloat); def = this->add("interior_brim_width", coFloat);
def->label = "Interior brim width"; def->label = "Interior brim width";
def->category = "Skirt and brim";
def->tooltip = "Horizontal width of the brim that will be printed inside object holes on the first layer."; def->tooltip = "Horizontal width of the brim that will be printed inside object holes on the first layer.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "interior-brim-width=f"; def->cli = "interior-brim-width=f";
@ -730,6 +740,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("max_print_speed", coFloat); def = this->add("max_print_speed", coFloat);
def->label = "Max print speed"; def->label = "Max print speed";
def->category = "Speed";
def->tooltip = "When setting other speed settings to 0 Slic3r will autocalculate the optimal speed in order to keep constant extruder pressure. This experimental setting is used to set the highest print speed you want to allow."; def->tooltip = "When setting other speed settings to 0 Slic3r will autocalculate the optimal speed in order to keep constant extruder pressure. This experimental setting is used to set the highest print speed you want to allow.";
def->sidetext = "mm/s"; def->sidetext = "mm/s";
def->cli = "max-print-speed=f"; def->cli = "max-print-speed=f";
@ -738,6 +749,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("max_volumetric_speed", coFloat); def = this->add("max_volumetric_speed", coFloat);
def->label = "Max volumetric speed"; def->label = "Max volumetric speed";
def->category = "Speed";
def->tooltip = "This experimental setting is used to set the maximum volumetric speed your extruder supports."; def->tooltip = "This experimental setting is used to set the maximum volumetric speed your extruder supports.";
def->sidetext = "mm³/s"; def->sidetext = "mm³/s";
def->cli = "max-volumetric-speed=f"; def->cli = "max-volumetric-speed=f";
@ -763,6 +775,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("min_skirt_length", coFloat); def = this->add("min_skirt_length", coFloat);
def->label = "Minimum extrusion length"; def->label = "Minimum extrusion length";
def->category = "Skirt and brim";
def->tooltip = "Generate no less than the number of skirt loops required to consume the specified amount of filament on the bottom layer. For multi-extruder machines, this minimum applies to each extruder."; def->tooltip = "Generate no less than the number of skirt loops required to consume the specified amount of filament on the bottom layer. For multi-extruder machines, this minimum applies to each extruder.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "min-skirt-length=f"; def->cli = "min-skirt-length=f";
@ -803,12 +816,14 @@ PrintConfigDef::PrintConfigDef()
def = this->add("only_retract_when_crossing_perimeters", coBool); def = this->add("only_retract_when_crossing_perimeters", coBool);
def->label = "Only retract when crossing perimeters"; def->label = "Only retract when crossing perimeters";
def->category = "Layers and Perimeters";
def->tooltip = "Disables retraction when the travel path does not exceed the upper layer's perimeters (and thus any ooze will be probably invisible)."; def->tooltip = "Disables retraction when the travel path does not exceed the upper layer's perimeters (and thus any ooze will be probably invisible).";
def->cli = "only-retract-when-crossing-perimeters!"; def->cli = "only-retract-when-crossing-perimeters!";
def->default_value = new ConfigOptionBool(true); def->default_value = new ConfigOptionBool(true);
def = this->add("ooze_prevention", coBool); def = this->add("ooze_prevention", coBool);
def->label = "Enable"; def->label = "Enable";
def->category = "Extruders";
def->tooltip = "During multi-extruder prints, this option will drop the temperature of the inactive extruders to prevent oozing. It will enable a tall skirt automatically and move extruders outside such skirt when changing temperatures."; def->tooltip = "During multi-extruder prints, this option will drop the temperature of the inactive extruders to prevent oozing. It will enable a tall skirt automatically and move extruders outside such skirt when changing temperatures.";
def->cli = "ooze-prevention!"; def->cli = "ooze-prevention!";
def->default_value = new ConfigOptionBool(false); def->default_value = new ConfigOptionBool(false);
@ -837,6 +852,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("perimeter_acceleration", coFloat); def = this->add("perimeter_acceleration", coFloat);
def->label = "Perimeters"; def->label = "Perimeters";
def->category = "Speed > Acceleration";
def->tooltip = "This is the acceleration your printer will use for perimeters. A high value like 9000 usually gives good results if your hardware is up to the job. Set zero to disable acceleration control for perimeters."; def->tooltip = "This is the acceleration your printer will use for perimeters. A high value like 9000 usually gives good results if your hardware is up to the job. Set zero to disable acceleration control for perimeters.";
def->sidetext = "mm/s²"; def->sidetext = "mm/s²";
def->cli = "perimeter-acceleration=f"; def->cli = "perimeter-acceleration=f";
@ -1059,7 +1075,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("seam_position", coEnum); def = this->add("seam_position", coEnum);
def->label = "Seam position"; def->label = "Seam position";
def->category = "Layers and perimeters"; def->category = "Layers and Perimeters";
def->tooltip = "Position of perimeters starting points."; def->tooltip = "Position of perimeters starting points.";
def->cli = "seam-position=s"; def->cli = "seam-position=s";
def->enum_keys_map = ConfigOptionEnum<SeamPosition>::get_enum_values(); def->enum_keys_map = ConfigOptionEnum<SeamPosition>::get_enum_values();
@ -1096,6 +1112,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("skirt_distance", coFloat); def = this->add("skirt_distance", coFloat);
def->label = "Distance from object"; def->label = "Distance from object";
def->category = "Skirt and brim";
def->tooltip = "Distance between skirt and object(s). Set this to zero to attach the skirt to the object(s) and get a brim for better adhesion."; def->tooltip = "Distance between skirt and object(s). Set this to zero to attach the skirt to the object(s) and get a brim for better adhesion.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "skirt-distance=f"; def->cli = "skirt-distance=f";
@ -1104,6 +1121,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("skirt_height", coInt); def = this->add("skirt_height", coInt);
def->label = "Skirt height"; def->label = "Skirt height";
def->category = "Skirt and brim";
def->tooltip = "Height of skirt expressed in layers. Set this to a tall value to use skirt as a shield against drafts."; def->tooltip = "Height of skirt expressed in layers. Set this to a tall value to use skirt as a shield against drafts.";
def->sidetext = "layers"; def->sidetext = "layers";
def->cli = "skirt-height=i"; def->cli = "skirt-height=i";
@ -1111,6 +1129,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("skirts", coInt); def = this->add("skirts", coInt);
def->label = "Loops (minimum)"; def->label = "Loops (minimum)";
def->category = "Skirt and brim";
def->full_label = "Skirt Loops"; def->full_label = "Skirt Loops";
def->tooltip = "Number of loops for the skirt. If the Minimum Extrusion Length option is set, the number of loops might be greater than the one configured here. Set this to zero to disable skirt completely."; def->tooltip = "Number of loops for the skirt. If the Minimum Extrusion Length option is set, the number of loops might be greater than the one configured here. Set this to zero to disable skirt completely.";
def->cli = "skirts=i"; def->cli = "skirts=i";
@ -1205,12 +1224,14 @@ PrintConfigDef::PrintConfigDef()
def = this->add("spiral_vase", coBool); def = this->add("spiral_vase", coBool);
def->label = "Spiral vase"; def->label = "Spiral vase";
def->category = "Layers and Perimeters";
def->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."; def->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.";
def->cli = "spiral-vase!"; def->cli = "spiral-vase!";
def->default_value = new ConfigOptionBool(false); def->default_value = new ConfigOptionBool(false);
def = this->add("standby_temperature_delta", coInt); def = this->add("standby_temperature_delta", coInt);
def->label = "Temperature variation"; def->label = "Temperature variation";
def->category = "Extruders";
def->tooltip = "Temperature difference to be applied when an extruder is not active. Enables a full-height \"sacrificial\" skirt on which the nozzles are periodically wiped."; def->tooltip = "Temperature difference to be applied when an extruder is not active. Enables a full-height \"sacrificial\" skirt on which the nozzles are periodically wiped.";
def->sidetext = "∆°C"; def->sidetext = "∆°C";
def->cli = "standby-temperature-delta=i"; def->cli = "standby-temperature-delta=i";
@ -1329,6 +1350,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("support_material_interface_speed", coFloatOrPercent); def = this->add("support_material_interface_speed", coFloatOrPercent);
def->label = "↳ interface"; def->label = "↳ interface";
def->label = "Interface Speed";
def->category = "Support material interface speed"; def->category = "Support material interface speed";
def->gui_type = "f_enum_open"; def->gui_type = "f_enum_open";
def->category = "Support material"; def->category = "Support material";
@ -1476,6 +1498,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("travel_speed", coFloat); def = this->add("travel_speed", coFloat);
def->label = "Travel"; def->label = "Travel";
def->category = "Speed";
def->tooltip = "Speed for travel moves (jumps between distant extrusion points)."; def->tooltip = "Speed for travel moves (jumps between distant extrusion points).";
def->sidetext = "mm/s"; def->sidetext = "mm/s";
def->cli = "travel-speed=f"; def->cli = "travel-speed=f";