2012-06-17 20:27:05 +00:00
package Slic3r::GUI::Tab ;
use strict ;
use warnings ;
use utf8 ;
2012-06-19 12:47:02 +00:00
use File::Basename qw( basename ) ;
2012-06-18 20:27:57 +00:00
use List::Util qw( first ) ;
2012-07-24 10:42:58 +00:00
use Wx qw( :bookctrl :dialog :keycode :icon :id :misc :panel :sizer :treectrl :window ) ;
2012-07-24 12:17:10 +00:00
use Wx::Event qw( EVT_BUTTON EVT_CHOICE EVT_KEY_DOWN EVT_TREE_SEL_CHANGED ) ;
2012-06-18 14:46:43 +00:00
use base 'Wx::Panel' ;
2012-06-17 20:27:05 +00:00
sub new {
my $ class = shift ;
2012-07-18 18:36:34 +00:00
my ( $ parent , % params ) = @ _ ;
2012-07-24 10:42:58 +00:00
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , wxDefaultPosition , wxDefaultSize , wxBK_LEFT | wxTAB_TRAVERSAL ) ;
2012-06-17 20:54:08 +00:00
2012-06-19 15:23:10 +00:00
$ self - > { sync_presets_with } = $ params { sync_presets_with } ;
EVT_CHOICE ( $ parent , $ self - > { sync_presets_with } , sub {
$ self - > { presets_choice } - > SetSelection ( $ self - > { sync_presets_with } - > GetSelection ) ;
$ self - > on_select_preset ;
} ) ;
2012-06-18 20:27:57 +00:00
# horizontal sizer
2012-07-01 17:24:06 +00:00
$ self - > { sizer } = Wx::BoxSizer - > new ( wxHORIZONTAL ) ;
2012-06-18 14:46:43 +00:00
$ self - > { sizer } - > SetSizeHints ( $ self ) ;
$ self - > SetSizer ( $ self - > { sizer } ) ;
2012-06-18 20:27:57 +00:00
# left vertical sizer
2012-07-01 17:24:06 +00:00
my $ left_sizer = Wx::BoxSizer - > new ( wxVERTICAL ) ;
2012-07-15 18:05:57 +00:00
$ self - > { sizer } - > Add ( $ left_sizer , 0 , wxEXPAND | wxLEFT | wxTOP | wxBOTTOM , 3 ) ;
2012-06-18 20:27:57 +00:00
2012-07-18 10:00:19 +00:00
my $ left_col_width = 150 ;
2012-06-18 20:27:57 +00:00
# preset chooser
{
# choice menu
2012-07-18 10:00:19 +00:00
$ self - > { presets_choice } = Wx::Choice - > new ( $ self , - 1 , wxDefaultPosition , [ $ left_col_width , - 1 ] , [] ) ;
2012-06-19 15:23:10 +00:00
$ self - > { presets_choice } - > SetFont ( $ Slic3r:: GUI:: small_font ) ;
2012-06-18 20:27:57 +00:00
# buttons
2012-07-01 17:24:06 +00:00
$ self - > { btn_save_preset } = Wx::BitmapButton - > new ( $ self , - 1 , Wx::Bitmap - > new ( "$Slic3r::var/disk.png" , wxBITMAP_TYPE_PNG ) ) ;
$ self - > { btn_delete_preset } = Wx::BitmapButton - > new ( $ self , - 1 , Wx::Bitmap - > new ( "$Slic3r::var/delete.png" , wxBITMAP_TYPE_PNG ) ) ;
2012-07-18 18:36:34 +00:00
$ self - > { btn_save_preset } - > SetToolTipString ( "Save current " . lc ( $ self - > title ) ) ;
2012-06-18 20:27:57 +00:00
$ self - > { btn_delete_preset } - > SetToolTipString ( "Delete this preset" ) ;
$ self - > { btn_delete_preset } - > Disable ;
2012-06-20 15:08:38 +00:00
### These cause GTK warnings:
2012-07-02 23:20:30 +00:00
###my $box = Wx::StaticBox->new($self, -1, "Presets:", wxDefaultPosition, [$left_col_width, 50]);
2012-07-01 17:24:06 +00:00
###my $hsizer = Wx::StaticBoxSizer->new($box, wxHORIZONTAL);
2012-06-20 15:08:38 +00:00
2012-07-01 17:24:06 +00:00
my $ hsizer = Wx::BoxSizer - > new ( wxHORIZONTAL ) ;
2012-06-20 15:08:38 +00:00
2012-07-01 17:24:06 +00:00
$ left_sizer - > Add ( $ hsizer , 0 , wxEXPAND | wxBOTTOM , 5 ) ;
$ hsizer - > Add ( $ self - > { presets_choice } , 1 , wxRIGHT | wxALIGN_CENTER_VERTICAL , 3 ) ;
$ hsizer - > Add ( $ self - > { btn_save_preset } , 0 , wxALIGN_CENTER_VERTICAL ) ;
$ hsizer - > Add ( $ self - > { btn_delete_preset } , 0 , wxALIGN_CENTER_VERTICAL ) ;
2012-06-18 20:27:57 +00:00
}
2012-06-18 14:46:43 +00:00
2012-06-18 20:27:57 +00:00
# tree
2012-07-24 10:42:58 +00:00
$ self - > { treectrl } = Wx::TreeCtrl - > new ( $ self , - 1 , wxDefaultPosition , [ $ left_col_width , - 1 ] , wxTR_NO_BUTTONS | wxTR_HIDE_ROOT | wxTR_SINGLE | wxTR_NO_LINES | wxBORDER_SUNKEN | wxWANTS_CHARS ) ;
2012-07-01 17:24:06 +00:00
$ left_sizer - > Add ( $ self - > { treectrl } , 1 , wxEXPAND ) ;
2012-06-18 14:46:43 +00:00
$ self - > { icons } = Wx::ImageList - > new ( 16 , 16 , 1 ) ;
$ self - > { treectrl } - > AssignImageList ( $ self - > { icons } ) ;
$ self - > { iconcount } = - 1 ;
$ self - > { treectrl } - > AddRoot ( "root" ) ;
2012-07-18 18:36:34 +00:00
$ self - > { pages } = [] ;
2012-06-18 14:46:43 +00:00
$ self - > { treectrl } - > SetIndent ( 0 ) ;
EVT_TREE_SEL_CHANGED ( $ parent , $ self - > { treectrl } , sub {
2012-07-18 18:36:34 +00:00
my $ page = first { $ _ - > { title } eq $ self - > { treectrl } - > GetItemText ( $ self - > { treectrl } - > GetSelection ) } @ { $ self - > { pages } }
or return ;
$ _ - > Hide for @ { $ self - > { pages } } ;
2012-07-23 22:34:57 +00:00
$ page - > Show ;
2012-06-18 14:46:43 +00:00
$ self - > { sizer } - > Layout ;
2012-07-18 17:19:07 +00:00
$ self - > Refresh ;
2012-06-18 14:46:43 +00:00
} ) ;
2012-07-24 12:17:10 +00:00
EVT_KEY_DOWN ( $ self - > { treectrl } , sub {
2012-07-24 10:42:58 +00:00
my ( $ treectrl , $ event ) = @ _ ;
if ( $ event - > GetKeyCode == WXK_TAB ) {
2012-07-24 12:17:10 +00:00
$ treectrl - > Navigate ( $ event - > ShiftDown ? & Wx:: wxNavigateBackward : & Wx:: wxNavigateForward ) ;
2012-07-24 10:42:58 +00:00
} else {
$ event - > Skip ;
}
} ) ;
2012-06-17 20:54:08 +00:00
2012-06-18 20:27:57 +00:00
EVT_CHOICE ( $ parent , $ self - > { presets_choice } , sub {
2012-06-19 15:23:10 +00:00
$ self - > on_select_preset ;
$ self - > sync_presets ;
2012-06-18 20:27:57 +00:00
} ) ;
EVT_BUTTON ( $ self , $ self - > { btn_save_preset } , sub {
2012-07-15 15:54:57 +00:00
my $ preset = $ self - > current_preset ;
my $ default_name = $ preset - > { default } ? 'Untitled' : basename ( $ preset - > { name } ) ;
2012-07-15 16:37:00 +00:00
$ default_name =~ s/\.ini$//i ;
2012-06-18 20:27:57 +00:00
my $ dlg = Slic3r::GUI::SavePresetWindow - > new ( $ self ,
2012-07-18 18:36:34 +00:00
title = > lc ( $ self - > title ) ,
2012-07-15 15:54:57 +00:00
default = > $ default_name ,
2012-07-15 16:37:00 +00:00
values = > [ map { my $ name = $ _ - > { name } ; $ name =~ s/\.ini$//i ; $ name } @ { $ self - > { presets } } ] ,
2012-06-18 20:27:57 +00:00
) ;
2012-07-01 17:24:06 +00:00
return unless $ dlg - > ShowModal == wxID_OK ;
2012-06-18 20:27:57 +00:00
my $ file = sprintf "$Slic3r::GUI::datadir/$self->{presets_group}/%s.ini" , $ dlg - > get_name ;
Slic3r::Config - > save ( $ file , $ self - > { presets_group } ) ;
$ self - > set_dirty ( 0 ) ;
$ self - > load_presets ;
2012-07-15 16:37:00 +00:00
$ self - > { presets_choice } - > SetSelection ( first { basename ( $ self - > { presets } [ $ _ ] { file } ) eq $ dlg - > get_name . ".ini" } 1 .. $# { $ self - > { presets } } ) ;
2012-06-19 16:11:51 +00:00
$ self - > on_select_preset ;
2012-06-19 15:23:10 +00:00
$ self - > sync_presets ;
2012-06-18 20:27:57 +00:00
} ) ;
2012-06-19 15:47:48 +00:00
EVT_BUTTON ( $ self , $ self - > { btn_delete_preset } , sub {
my $ i = $ self - > { presets_choice } - > GetSelection ;
return if $ i == 0 ; # this shouldn't happen but let's trap it anyway
2012-07-01 17:24:06 +00:00
my $ res = Wx::MessageDialog - > new ( $ self , "Are you sure you want to delete the selected preset?" , 'Delete Preset' , wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ) - > ShowModal ;
return unless $ res == wxID_YES ;
2012-07-18 14:17:23 +00:00
if ( - e $ self - > { presets } [ $ i ] { file } ) {
unlink $ self - > { presets } [ $ i ] { file } ;
2012-06-19 15:47:48 +00:00
}
2012-07-18 14:17:23 +00:00
splice @ { $ self - > { presets } } , $ i , 1 ;
2012-06-19 15:47:48 +00:00
$ self - > { presets_choice } - > Delete ( $ i ) ;
$ self - > { presets_choice } - > SetSelection ( 0 ) ;
$ self - > on_select_preset ;
$ self - > sync_presets ;
} ) ;
2012-07-18 18:36:34 +00:00
$ self - > build ;
2012-06-17 20:27:05 +00:00
return $ self ;
}
2012-07-15 15:54:57 +00:00
sub current_preset {
my $ self = shift ;
return $ self - > { presets } [ $ self - > { presets_choice } - > GetSelection ] ;
}
2012-07-18 18:36:34 +00:00
sub on_value_change { }
sub on_preset_loaded { }
2012-06-19 15:23:10 +00:00
sub on_select_preset {
my $ self = shift ;
if ( defined $ self - > { dirty } ) {
# TODO: prompt user?
$ self - > set_dirty ( 0 ) ;
}
2012-07-15 15:54:57 +00:00
my $ preset = $ self - > current_preset ;
if ( $ preset - > { default } ) {
# default settings: disable the delete button
2012-06-19 15:23:10 +00:00
Slic3r::Config - > load_hash ( $ Slic3r:: Defaults , $ self - > { presets_group } , 1 ) ;
$ self - > { btn_delete_preset } - > Disable ;
} else {
2012-07-15 15:54:57 +00:00
if ( ! - e $ preset - > { file } ) {
Slic3r::GUI:: show_error ( $ self , "The selected preset does not exist anymore ($preset->{file})." ) ;
2012-06-19 15:23:10 +00:00
return ;
}
2012-07-15 15:54:57 +00:00
eval {
local $ SIG { __WARN__ } = Slic3r::GUI:: warning_catcher ( $ self ) ;
Slic3r::Config - > load ( $ preset - > { file } , $ self - > { presets_group } ) ;
} ;
Slic3r::GUI:: catch_error ( $ self ) ;
$ preset - > { external }
? $ self - > { btn_delete_preset } - > Disable
: $ self - > { btn_delete_preset } - > Enable ;
2012-06-19 15:23:10 +00:00
}
2012-07-18 18:36:34 +00:00
$ self - > on_preset_loaded ;
2012-06-19 15:23:10 +00:00
$ _ - > ( ) for @ Slic3r:: GUI:: OptionsGroup:: reload_callbacks { @ { $ Slic3r:: Config:: Groups { $ self - > { presets_group } } } } ;
$ self - > set_dirty ( 0 ) ;
2012-07-15 15:54:57 +00:00
$ Slic3r:: Settings - > { presets } { $ self - > { presets_group } } = $ preset - > { file } ? basename ( $ preset - > { file } ) : '' ;
2012-06-19 16:11:51 +00:00
Slic3r::Config - > save_settings ( "$Slic3r::GUI::datadir/slic3r.ini" ) ;
2012-06-19 15:23:10 +00:00
}
2012-06-18 20:27:57 +00:00
sub add_options_page {
2012-06-17 20:27:05 +00:00
my $ self = shift ;
2012-07-18 18:36:34 +00:00
my ( $ title , $ icon , % params ) = @ _ ;
2012-06-17 20:54:08 +00:00
2012-07-18 18:36:34 +00:00
if ( $ icon ) {
my $ bitmap = Wx::Bitmap - > new ( "$Slic3r::var/$icon" , wxBITMAP_TYPE_PNG ) ;
2012-06-18 14:46:43 +00:00
$ self - > { icons } - > Add ( $ bitmap ) ;
$ self - > { iconcount } + + ;
2012-06-17 20:54:08 +00:00
}
2012-07-18 18:36:34 +00:00
my $ page = Slic3r::GUI::Tab::Page - > new ( $ self , $ title , $ self - > { iconcount } , % params , on_change = > sub {
$ self - > on_value_change ( @ _ ) ;
$ self - > set_dirty ( 1 ) ;
$ self - > sync_presets ;
} ) ;
2012-06-18 14:46:43 +00:00
$ page - > Hide ;
2012-07-24 10:41:51 +00:00
$ self - > { sizer } - > Add ( $ page , 1 , wxEXPAND | wxLEFT , 5 ) ;
2012-07-18 18:36:34 +00:00
push @ { $ self - > { pages } } , $ page ;
$ self - > update_tree ;
return $ page ;
}
sub update_tree {
my $ self = shift ;
my ( $ select ) = @ _ ;
$ select // = 0 ; #/
my $ rootItem = $ self - > { treectrl } - > GetRootItem ;
$ self - > { treectrl } - > DeleteChildren ( $ rootItem ) ;
foreach my $ page ( @ { $ self - > { pages } } ) {
my $ itemId = $ self - > { treectrl } - > AppendItem ( $ rootItem , $ page - > { title } , $ page - > { iconID } ) ;
$ self - > { treectrl } - > SelectItem ( $ itemId ) if $ self - > { treectrl } - > GetChildrenCount ( $ rootItem ) == $ select + 1 ;
2012-06-18 20:27:57 +00:00
}
2012-06-17 20:27:05 +00:00
}
2012-06-18 20:27:57 +00:00
sub set_dirty {
my $ self = shift ;
my ( $ dirty ) = @ _ ;
my $ i = $ self - > { dirty } // $ self - > { presets_choice } - > GetSelection ; #/
my $ text = $ self - > { presets_choice } - > GetString ( $ i ) ;
2012-07-15 15:54:57 +00:00
2012-06-18 20:27:57 +00:00
if ( $ dirty ) {
$ self - > { dirty } = $ i ;
if ( $ text !~ / \(modified\)$/ ) {
$ self - > { presets_choice } - > SetString ( $ i , "$text (modified)" ) ;
2012-06-20 19:43:06 +00:00
$ self - > { presets_choice } - > SetSelection ( $ i ) ; # wxMSW needs this after every SetString()
2012-06-18 20:27:57 +00:00
}
} else {
$ self - > { dirty } = undef ;
$ text =~ s/ \(modified\)$// ;
$ self - > { presets_choice } - > SetString ( $ i , $ text ) ;
2012-06-20 19:43:06 +00:00
$ self - > { presets_choice } - > SetSelection ( $ i ) ; # wxMSW needs this after every SetString()
2012-06-18 20:27:57 +00:00
}
2012-06-19 15:23:10 +00:00
$ self - > sync_presets ;
2012-06-18 20:27:57 +00:00
}
2012-06-23 15:38:19 +00:00
sub is_dirty {
my $ self = shift ;
2012-06-30 20:34:13 +00:00
return ( defined $ self - > { dirty } ) ;
2012-06-23 15:38:19 +00:00
}
2012-06-18 20:27:57 +00:00
sub load_presets {
my $ self = shift ;
my ( $ group ) = @ _ ;
$ self - > { presets_group } || = $ group ;
2012-07-15 15:54:57 +00:00
$ self - > { presets } = [ {
default = > 1 ,
name = > '- default -' ,
} ] ;
2012-06-18 20:27:57 +00:00
opendir my $ dh , "$Slic3r::GUI::datadir/$self->{presets_group}" or die "Failed to read directory $Slic3r::GUI::datadir/$self->{presets_group} (errno: $!)\n" ;
2012-07-15 15:54:57 +00:00
foreach my $ file ( sort grep /\.ini$/i , readdir $ dh ) {
my $ name = basename ( $ file ) ;
$ name =~ s/\.ini$// ;
push @ { $ self - > { presets } } , {
file = > "$Slic3r::GUI::datadir/$self->{presets_group}/$file" ,
name = > $ name ,
} ;
}
2012-06-18 20:27:57 +00:00
closedir $ dh ;
$ self - > { presets_choice } - > Clear ;
2012-07-15 15:54:57 +00:00
$ self - > { presets_choice } - > Append ( $ _ - > { name } ) for @ { $ self - > { presets } } ;
2012-06-19 16:11:51 +00:00
{
2012-07-15 15:54:57 +00:00
# load last used preset
my $ i = first { basename ( $ self - > { presets } [ $ _ ] { file } ) eq ( $ Slic3r:: Settings - > { presets } { $ self - > { presets_group } } || '' ) } 1 .. $# { $ self - > { presets } } ;
$ self - > { presets_choice } - > SetSelection ( $ i || 0 ) ;
2012-06-20 15:17:07 +00:00
$ self - > on_select_preset ;
2012-06-19 16:11:51 +00:00
}
2012-06-19 15:23:10 +00:00
$ self - > sync_presets ;
2012-06-18 20:27:57 +00:00
}
2012-06-17 20:27:05 +00:00
2012-07-18 18:36:34 +00:00
sub load_external_config {
2012-06-19 12:47:02 +00:00
my $ self = shift ;
my ( $ file ) = @ _ ;
# look for the loaded config among the existing menu items
2012-07-15 15:54:57 +00:00
my $ i = first { $ self - > { presets } [ $ _ ] { file } eq $ file && $ self - > { presets } [ $ _ ] { external } } 1 .. $# { $ self - > { presets } } ;
2012-06-19 12:47:02 +00:00
if ( ! $ i ) {
2012-07-15 15:54:57 +00:00
my $ preset_name = basename ( $ file ) ; # keep the .ini suffix
push @ { $ self - > { presets } } , {
file = > $ file ,
name = > $ preset_name ,
external = > 1 ,
} ;
2012-06-19 12:47:02 +00:00
$ self - > { presets_choice } - > Append ( $ preset_name ) ;
$ i = $# { $ self - > { presets } } ;
}
2012-07-15 15:54:57 +00:00
$ self - > { presets_choice } - > SetSelection ( $ i ) ;
$ self - > on_select_preset ;
2012-06-19 15:23:10 +00:00
$ self - > sync_presets ;
}
sub sync_presets {
my $ self = shift ;
return unless $ self - > { sync_presets_with } ;
$ self - > { sync_presets_with } - > Clear ;
foreach my $ item ( $ self - > { presets_choice } - > GetStrings ) {
$ self - > { sync_presets_with } - > Append ( $ item ) ;
}
$ self - > { sync_presets_with } - > SetSelection ( $ self - > { presets_choice } - > GetSelection ) ;
2012-06-19 12:47:02 +00:00
}
2012-06-18 20:27:57 +00:00
package Slic3r::GUI::Tab::Print ;
2012-06-17 20:27:05 +00:00
use base 'Slic3r::GUI::Tab' ;
2012-07-18 18:36:34 +00:00
sub title { 'Print Settings' }
sub build {
my $ self = shift ;
2012-06-17 20:27:05 +00:00
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Layers and perimeters' , 'layers.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Layer height' ,
options = > [ qw( layer_height first_layer_height ) ] ,
} ,
{
title = > 'Vertical shells' ,
2012-07-18 13:48:04 +00:00
options = > [ qw( perimeters randomize_start extra_perimeters ) ] ,
2012-06-17 20:27:05 +00:00
} ,
{
title = > 'Horizontal shells' ,
options = > [ qw( solid_layers ) ] ,
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Infill' , 'shading.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Infill' ,
2012-06-18 08:19:24 +00:00
options = > [ qw( fill_density fill_angle fill_pattern solid_fill_pattern infill_every_layers ) ] ,
2012-06-17 20:27:05 +00:00
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Speed' , 'time.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Speed for print moves' ,
2012-07-23 07:43:59 +00:00
options = > [ qw( perimeter_speed small_perimeter_speed external_perimeter_speed infill_speed solid_infill_speed top_solid_infill_speed bridge_speed ) ] ,
2012-06-17 20:27:05 +00:00
} ,
{
title = > 'Speed for non-print moves' ,
options = > [ qw( travel_speed ) ] ,
} ,
{
2012-06-18 08:19:24 +00:00
title = > 'Modifiers' ,
2012-06-17 20:27:05 +00:00
options = > [ qw( first_layer_speed ) ] ,
} ,
] ) ;
2012-07-18 13:48:04 +00:00
$ self - > add_options_page ( 'Skirt and brim' , 'box.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Skirt' ,
options = > [ qw( skirts skirt_distance skirt_height ) ] ,
} ,
2012-07-18 13:48:04 +00:00
{
title = > 'Brim' ,
options = > [ qw( brim_width ) ] ,
} ,
2012-06-17 20:27:05 +00:00
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Support material' , 'building.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Support material' ,
2012-07-18 13:48:04 +00:00
options = > [ qw( support_material support_material_threshold support_material_pattern support_material_spacing support_material_angle ) ] ,
2012-06-17 20:27:05 +00:00
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Notes' , 'note.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Notes' ,
2012-06-17 21:24:10 +00:00
no_labels = > 1 ,
2012-06-17 20:27:05 +00:00
options = > [ qw( notes ) ] ,
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Output options' , 'page_white_go.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Sequential printing' ,
options = > [ qw( complete_objects extruder_clearance_radius extruder_clearance_height ) ] ,
} ,
{
title = > 'Output file' ,
options = > [ qw( gcode_comments output_filename_format ) ] ,
} ,
{
2012-06-17 21:24:10 +00:00
title = > 'Post-processing scripts' ,
no_labels = > 1 ,
2012-06-18 09:26:21 +00:00
options = > [ qw( post_process ) ] ,
2012-06-17 20:27:05 +00:00
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Advanced' , 'wrench.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Extrusion width' ,
2012-06-18 12:29:47 +00:00
label_width = > 180 ,
2012-07-18 16:14:32 +00:00
options = > [ qw( extrusion_width first_layer_extrusion_width perimeter_extrusion_width infill_extrusion_width support_material_extrusion_width ) ] ,
2012-06-17 20:27:05 +00:00
} ,
{
title = > 'Flow' ,
options = > [ qw( bridge_flow_ratio ) ] ,
} ,
2012-06-18 09:26:21 +00:00
{
title = > 'Other' ,
2012-07-18 13:48:04 +00:00
options = > [ qw( duplicate_distance ) , ( $ Slic3r:: have_threads ? qw( threads ) : ( ) ) ] ,
2012-06-18 09:26:21 +00:00
} ,
2012-06-17 20:27:05 +00:00
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > load_presets ( 'print' ) ;
2012-06-17 20:27:05 +00:00
}
2012-06-18 12:29:47 +00:00
package Slic3r::GUI::Tab::Filament ;
use base 'Slic3r::GUI::Tab' ;
2012-07-18 18:36:34 +00:00
sub title { 'Filament Settings' }
sub build {
my $ self = shift ;
2012-06-18 12:29:47 +00:00
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Filament' , 'spool.png' , optgroups = > [
2012-06-18 12:29:47 +00:00
{
title = > 'Filament' ,
2012-07-18 13:48:04 +00:00
options = > [ 'filament_diameter#0' , 'extrusion_multiplier#0' ] ,
2012-06-18 12:29:47 +00:00
} ,
{
title = > 'Temperature' ,
2012-07-18 13:48:04 +00:00
options = > [ 'temperature#0' , 'first_layer_temperature#0' , qw( bed_temperature first_layer_bed_temperature ) ] ,
2012-06-18 12:29:47 +00:00
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Cooling' , 'hourglass.png' , optgroups = > [
2012-06-18 12:29:47 +00:00
{
title = > 'Enable' ,
options = > [ qw( cooling ) ] ,
} ,
{
title = > 'Fan settings' ,
options = > [ qw( min_fan_speed max_fan_speed bridge_fan_speed disable_fan_first_layers fan_always_on ) ] ,
} ,
{
title = > 'Cooling thresholds' ,
label_width = > 250 ,
options = > [ qw( fan_below_layer_time slowdown_below_layer_time min_print_speed ) ] ,
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > load_presets ( 'filament' ) ;
2012-06-18 12:29:47 +00:00
}
2012-06-17 20:27:05 +00:00
package Slic3r::GUI::Tab::Printer ;
use base 'Slic3r::GUI::Tab' ;
2012-07-18 18:36:34 +00:00
sub title { 'Printer Settings' }
sub build {
my $ self = shift ;
2012-06-17 20:27:05 +00:00
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'General' , 'printer_empty.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
title = > 'Size and coordinates' ,
options = > [ qw( bed_size print_center z_offset ) ] ,
} ,
{
title = > 'Firmware' ,
options = > [ qw( gcode_flavor use_relative_e_distances ) ] ,
} ,
{
2012-07-18 18:36:34 +00:00
title = > 'Capabilities' ,
options = > [ qw( extruders_count ) ] ,
2012-06-17 20:27:05 +00:00
} ,
] ) ;
2012-06-18 20:27:57 +00:00
$ self - > add_options_page ( 'Custom G-code' , 'cog.png' , optgroups = > [
2012-06-17 20:27:05 +00:00
{
2012-06-17 21:24:10 +00:00
title = > 'Start G-code' ,
no_labels = > 1 ,
options = > [ qw( start_gcode ) ] ,
} ,
{
title = > 'End G-code' ,
no_labels = > 1 ,
options = > [ qw( end_gcode ) ] ,
} ,
{
title = > 'Layer change G-code' ,
no_labels = > 1 ,
options = > [ qw( layer_gcode ) ] ,
2012-06-17 20:27:05 +00:00
} ,
] ) ;
2012-07-18 18:36:34 +00:00
$ self - > { extruder_pages } = [] ;
$ self - > build_extruder_pages ;
2012-06-18 20:27:57 +00:00
$ self - > load_presets ( 'printer' ) ;
2012-07-18 18:36:34 +00:00
}
sub extruder_options { qw( nozzle_diameter ) }
sub build_extruder_pages {
my $ self = shift ;
2012-06-18 20:27:57 +00:00
2012-07-18 18:36:34 +00:00
foreach my $ extruder_idx ( 0 .. $ Slic3r:: extruders_count - 1 ) {
# set default values
for my $ opt_key ( $ self - > extruder_options ) {
Slic3r::Config - > get_raw ( $ opt_key ) - > [ $ extruder_idx ] // = Slic3r::Config - > get_raw ( $ opt_key ) - > [ 0 ] ; #/
}
# build page if it doesn't exist
$ self - > { extruder_pages } [ $ extruder_idx ] || = $ self - > add_options_page ( "Extruder " . ( $ extruder_idx + 1 ) , 'funnel.png' , optgroups = > [
{
title = > 'Size' ,
options = > [ 'nozzle_diameter#' . $ extruder_idx ] ,
} ,
{
title = > 'Retraction' ,
options = > [ qw( retract_length retract_lift retract_speed retract_restart_extra retract_before_travel ) ] ,
} ,
] ) ;
$ self - > { extruder_pages } [ $ extruder_idx ] { disabled } = 0 ;
}
# rebuild page list
@ { $ self - > { pages } } = (
( grep $ _ - > { title } !~ /^Extruder \d+/ , @ { $ self - > { pages } } ) ,
@ { $ self - > { extruder_pages } } [ 0 .. $ Slic3r:: extruders_count - 1 ] ,
) ;
}
sub on_value_change {
my $ self = shift ;
my ( $ opt_key ) = @ _ ;
$ self - > SUPER:: on_value_change ( @ _ ) ;
if ( $ opt_key eq 'extruders_count' ) {
# remove unused pages from list
my @ unused_pages = @ { $ self - > { extruder_pages } } [ $ Slic3r:: extruders_count .. $# { $ self - > { extruder_pages } } ] ;
for my $ page ( @ unused_pages ) {
@ { $ self - > { pages } } = grep $ _ ne $ page , @ { $ self - > { pages } } ;
$ page - > { disabled } = 1 ;
}
# delete values for unused extruders
for my $ opt_key ( $ self - > extruder_options ) {
my $ values = Slic3r::Config - > get_raw ( $ opt_key ) ;
splice @$ values , $ Slic3r:: extruders_count if $ Slic3r:: extruders_count <= $#$ values ;
}
# add extra pages
$ self - > build_extruder_pages ;
# update page list and select first page (General)
$ self - > update_tree ( 0 ) ;
}
}
# this gets executed after preset is loaded in repository and before GUI fields are updated
sub on_preset_loaded {
my $ self = shift ;
# update the extruders count field
2012-07-20 12:41:27 +00:00
{
2012-07-18 18:36:34 +00:00
# set value in repository according to the number of nozzle diameters supplied
Slic3r::Config - > set ( 'extruders_count' , scalar @ { Slic3r::Config - > get_raw ( 'nozzle_diameter' ) } ) ;
# update the GUI field
$ Slic3r:: GUI:: OptionsGroup:: reload_callbacks { extruders_count } - > ( ) ;
# update extruder page list
$ self - > on_value_change ( 'extruders_count' ) ;
}
2012-06-17 20:27:05 +00:00
}
package Slic3r::GUI::Tab::Page ;
2012-07-24 10:42:58 +00:00
use Wx qw( :misc :panel :sizer ) ;
2012-06-18 09:26:21 +00:00
use base 'Wx::ScrolledWindow' ;
2012-06-17 20:27:05 +00:00
sub new {
my $ class = shift ;
2012-07-18 18:36:34 +00:00
my ( $ parent , $ title , $ iconID , % params ) = @ _ ;
2012-07-24 10:42:58 +00:00
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , wxDefaultPosition , wxDefaultSize , wxTAB_TRAVERSAL ) ;
2012-07-18 18:36:34 +00:00
$ self - > { opt_keys } = [] ;
$ self - > { title } = $ title ;
$ self - > { iconID } = $ iconID ;
2012-06-17 20:27:05 +00:00
2012-06-18 09:26:21 +00:00
$ self - > SetScrollbars ( 1 , 1 , 1 , 1 ) ;
2012-07-01 17:24:06 +00:00
$ self - > { vsizer } = Wx::BoxSizer - > new ( wxVERTICAL ) ;
2012-06-17 20:27:05 +00:00
$ self - > SetSizer ( $ self - > { vsizer } ) ;
if ( $ params { optgroups } ) {
2012-06-18 20:27:57 +00:00
$ self - > append_optgroup ( %$ _ , on_change = > $ params { on_change } ) for @ { $ params { optgroups } } ;
2012-06-17 20:27:05 +00:00
}
return $ self ;
}
sub append_optgroup {
my $ self = shift ;
2012-07-18 18:36:34 +00:00
my % params = @ _ ;
2012-06-17 20:27:05 +00:00
2012-07-18 18:36:34 +00:00
my $ optgroup = Slic3r::GUI::OptionsGroup - > new ( $ self , label_width = > 200 , % params ) ;
2012-06-17 20:27:05 +00:00
$ self - > { vsizer } - > Add ( $ optgroup , 0 , wxEXPAND | wxALL , 5 ) ;
}
2012-06-18 20:27:57 +00:00
package Slic3r::GUI::SavePresetWindow ;
2012-07-02 23:20:30 +00:00
use Wx qw( :combobox :dialog :id :misc :sizer ) ;
2012-06-21 11:01:59 +00:00
use Wx::Event qw( EVT_BUTTON EVT_TEXT_ENTER ) ;
2012-06-18 20:27:57 +00:00
use base 'Wx::Dialog' ;
sub new {
my $ class = shift ;
my ( $ parent , % params ) = @ _ ;
2012-07-02 23:20:30 +00:00
my $ self = $ class - > SUPER:: new ( $ parent , - 1 , "Save preset" , wxDefaultPosition , wxDefaultSize ) ;
2012-06-18 20:27:57 +00:00
2012-07-02 23:20:30 +00:00
my $ text = Wx::StaticText - > new ( $ self , - 1 , "Save " . lc ( $ params { title } ) . " as:" , wxDefaultPosition , wxDefaultSize ) ;
$ self - > { combo } = Wx::ComboBox - > new ( $ self , - 1 , $ params { default } , wxDefaultPosition , wxDefaultSize , $ params { values } ,
2012-07-01 17:24:06 +00:00
wxTE_PROCESS_ENTER ) ;
my $ buttons = $ self - > CreateStdDialogButtonSizer ( wxOK | wxCANCEL ) ;
2012-06-18 20:27:57 +00:00
my $ sizer = Wx::BoxSizer - > new ( wxVERTICAL ) ;
$ sizer - > Add ( $ text , 0 , wxEXPAND | wxTOP | wxLEFT | wxRIGHT , 10 ) ;
2012-06-21 11:01:59 +00:00
$ sizer - > Add ( $ self - > { combo } , 0 , wxEXPAND | wxLEFT | wxRIGHT , 10 ) ;
2012-06-18 20:27:57 +00:00
$ sizer - > Add ( $ buttons , 0 , wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT , 10 ) ;
2012-07-01 17:24:06 +00:00
EVT_BUTTON ( $ self , wxID_OK , \ & accept ) ;
2012-06-21 11:01:59 +00:00
EVT_TEXT_ENTER ( $ self , $ self - > { combo } , \ & accept ) ;
2012-06-18 20:27:57 +00:00
$ self - > SetSizer ( $ sizer ) ;
$ sizer - > SetSizeHints ( $ self ) ;
return $ self ;
}
2012-06-21 11:01:59 +00:00
sub accept {
my ( $ self , $ event ) = @ _ ;
2012-07-15 16:55:01 +00:00
if ( ( $ self - > { chosen_name } = $ self - > { combo } - > GetValue ) ) {
if ( $ self - > { chosen_name } =~ /^[a-z0-9 _-]+$/i ) {
$ self - > EndModal ( wxID_OK ) ;
} else {
Slic3r::GUI:: show_error ( $ self , "The supplied name is not valid." ) ;
}
2012-06-21 11:01:59 +00:00
}
}
2012-06-18 20:27:57 +00:00
sub get_name {
my $ self = shift ;
return $ self - > { chosen_name } ;
}
2012-06-17 20:27:05 +00:00
1 ;