2011-10-03 11:55:32 +02:00
package Slic3r::GUI::SkeinPanel ;
use strict ;
use warnings ;
2011-10-03 13:08:43 +02:00
use utf8 ;
2011-10-03 11:55:32 +02:00
2011-12-09 14:07:50 +01:00
use File::Basename qw(basename dirname) ;
2012-04-11 15:58:09 +02:00
use Slic3r::Geometry qw(X Y) ;
2012-02-05 16:43:44 +01:00
use Wx qw(:sizer :progressdialog wxOK wxICON_INFORMATION wxICON_WARNING wxICON_ERROR wxICON_QUESTION
wxOK wxCANCEL wxID_OK wxFD_OPEN wxFD_SAVE wxDEFAULT wxNORMAL) ;
2011-10-03 11:55:32 +02:00
use Wx::Event qw(EVT_BUTTON) ;
use base 'Wx::Panel' ;
2012-04-30 14:56:01 +02:00
our $last_skein_dir ;
our $last_config_dir ;
our $last_input_file ;
our $last_output_file ;
2011-12-26 19:45:01 +01:00
our $last_config ;
2011-12-09 14:07:50 +01:00
2011-10-03 11:55:32 +02:00
sub new {
my $class = shift ;
my ( $parent ) = @_ ;
my $self = $class -> SUPER:: new ( $parent , - 1 );
2011-11-13 22:22:34 +01:00
my $tabpanel = Wx::Notebook -> new ( $self , - 1 , Wx:: wxDefaultPosition , Wx:: wxDefaultSize , & Wx:: wxNB_TOP );
2012-06-19 17:23:10 +02:00
$tabpanel -> AddPage ( $self -> { plater } = Slic3r::GUI::Plater -> new ( $tabpanel ), "Plater" );
$self -> { options_tabs } = {
print => Slic3r::GUI::Tab::Print -> new ( $tabpanel , sync_presets_with => $self -> { plater }{ preset_choosers }{ print }),
filament => Slic3r::GUI::Tab::Filament -> new ( $tabpanel , sync_presets_with => $self -> { plater }{ preset_choosers }{ filament }),
printer => Slic3r::GUI::Tab::Printer -> new ( $tabpanel , sync_presets_with => $self -> { plater }{ preset_choosers }{ printer }),
};
2012-06-24 10:20:42 +02:00
$tabpanel -> AddPage ( $self -> { options_tabs }{ print }, $self -> { options_tabs }{ print } -> title );
$tabpanel -> AddPage ( $self -> { options_tabs }{ filament }, $self -> { options_tabs }{ filament } -> title );
$tabpanel -> AddPage ( $self -> { options_tabs }{ printer }, $self -> { options_tabs }{ printer } -> title );
2012-06-19 17:23:10 +02:00
2011-11-13 22:22:34 +01:00
my $buttons_sizer ;
2011-10-05 18:13:47 +02:00
{
2011-11-13 22:22:34 +01:00
$buttons_sizer = Wx::BoxSizer -> new ( wxHORIZONTAL );
2012-04-30 14:56:01 +02:00
my $slice_button = Wx::Button -> new ( $self , - 1 , "Quick slice…" );
2012-02-28 23:04:19 +00:00
$slice_button -> SetDefault ();
2012-03-03 22:53:12 +01:00
$buttons_sizer -> Add ( $slice_button , 0 , wxRIGHT , 20 );
2012-02-28 23:04:19 +00:00
EVT_BUTTON ( $self , $slice_button , sub { $self -> do_slice });
2012-06-19 14:47:02 +02:00
my $save_button = Wx::Button -> new ( $self , - 1 , "Export config..." );
2012-05-01 13:27:57 +02:00
$buttons_sizer -> Add ( $save_button , 0 , wxRIGHT , 5 );
2012-03-03 22:50:08 +01:00
EVT_BUTTON ( $self , $save_button , sub { $self -> save_config });
2012-03-03 22:53:12 +01:00
my $load_button = Wx::Button -> new ( $self , - 1 , "Load config..." );
2012-05-01 13:27:57 +02:00
$buttons_sizer -> Add ( $load_button , 0 , wxRIGHT , 5 );
2012-03-03 22:50:08 +01:00
EVT_BUTTON ( $self , $load_button , sub { $self -> load_config });
my $text = Wx::StaticText -> new ( $self , - 1 , "Remember to check for updates at http://slic3r.org/\nVersion: $Slic3r::VERSION" , Wx:: wxDefaultPosition , Wx:: wxDefaultSize , wxALIGN_RIGHT );
my $font = Wx::Font -> new ( 10 , wxDEFAULT , wxNORMAL , wxNORMAL );
$text -> SetFont ( $font );
$buttons_sizer -> Add ( $text , 1 , wxEXPAND | wxALIGN_RIGHT );
2011-10-03 11:55:32 +02:00
}
2011-10-05 18:13:47 +02:00
my $sizer = Wx::BoxSizer -> new ( wxVERTICAL );
2012-03-03 22:50:08 +01:00
$sizer -> Add ( $buttons_sizer , 0 , wxEXPAND | wxALL , 10 );
2012-06-18 11:26:21 +02:00
$sizer -> Add ( $tabpanel , 1 , wxEXPAND );
2011-10-05 18:13:47 +02:00
2011-10-03 11:55:32 +02:00
$sizer -> SetSizeHints ( $self );
$self -> SetSizer ( $sizer );
2011-10-03 13:08:43 +02:00
$self -> Layout ;
2011-10-03 11:55:32 +02:00
return $self ;
}
2012-05-20 11:40:37 +02:00
our $model_wildcard = "STL files (*.stl)|*.stl;*.STL|OBJ files (*.obj)|*.obj;*.OBJ|AMF files (*.amf)|*.amf;*.AMF;*.xml;*.XML" ;
2012-04-30 14:56:01 +02:00
our $ini_wildcard = "INI files *.ini|*.ini;*.INI" ;
our $gcode_wildcard = "G-code files *.gcode|*.gcode;*.GCODE" ;
2012-05-30 12:06:01 +02:00
our $svg_wildcard = "SVG files *.svg|*.svg;*.SVG" ;
2011-12-22 17:38:37 +01:00
2011-10-03 11:55:32 +02:00
sub do_slice {
my $self = shift ;
2011-12-22 17:38:37 +01:00
my %params = @_ ;
2011-10-03 11:55:32 +02:00
2011-10-03 17:41:45 +02:00
my $process_dialog ;
2011-10-03 11:55:32 +02:00
eval {
# validate configuration
Slic3r::Config -> validate ;
2012-02-05 16:43:44 +01:00
# confirm slicing of more than one copies
2012-04-11 15:58:09 +02:00
my $copies = $ Slic3r:: duplicate_grid -> [ X ] * $ Slic3r:: duplicate_grid -> [ Y ];
$copies = $ Slic3r:: duplicate if $ Slic3r:: duplicate > 1 ;
2012-02-05 16:43:44 +01:00
if ( $copies > 1 ) {
my $confirmation = Wx::MessageDialog -> new ( $self , "Are you sure you want to slice $copies copies?" ,
'Confirm' , wxICON_QUESTION | wxOK | wxCANCEL );
return unless $confirmation -> ShowModal == wxID_OK ;
}
2011-10-03 11:55:32 +02:00
# select input file
2012-02-03 20:22:45 +01:00
my $dir = $last_skein_dir || $last_config_dir || "" ;
2012-03-12 19:52:23 +02:00
my $input_file ;
if ( ! $params { reslice }) {
2012-05-31 09:26:30 +02:00
my $dialog = Wx::FileDialog -> new ( $self , 'Choose a file to slice (STL/OBJ/AMF):' , $dir , "" , $model_wildcard , wxFD_OPEN | & Wx:: wxFD_FILE_MUST_EXIST );
2012-04-18 17:16:01 +03:00
if ( $dialog -> ShowModal != wxID_OK ) {
$dialog -> Destroy ;
return ;
}
2012-03-12 19:52:23 +02:00
$input_file = $dialog -> GetPaths ;
2012-04-18 17:16:01 +03:00
$dialog -> Destroy ;
2012-03-12 19:52:23 +02:00
$last_input_file = $input_file ;
} else {
if ( ! defined $last_input_file ) {
Wx::MessageDialog -> new ( $self , "No previously sliced file" ,
'Confirm' , wxICON_ERROR | wxOK ) -> ShowModal ();
return ;
}
if ( ! - e $last_input_file ) {
Wx::MessageDialog -> new ( $self , "Cannot find previously sliced file!" ,
'Confirm' , wxICON_ERROR | wxOK ) -> ShowModal ();
return ;
}
$input_file = $last_input_file ;
}
2011-10-03 11:55:32 +02:00
my $input_file_basename = basename ( $input_file );
2012-02-03 19:57:49 +01:00
$last_skein_dir = dirname ( $input_file );
2011-10-03 11:55:32 +02:00
2012-04-30 14:56:01 +02:00
my $print = Slic3r::Print -> new ;
$print -> add_object_from_file ( $input_file );
2012-05-23 11:47:52 +02:00
$print -> validate ;
2011-12-26 04:20:45 -05:00
# select output file
2012-04-30 14:56:01 +02:00
my $output_file = $ main:: opt { output };
2012-03-12 19:52:23 +02:00
if ( $params { reslice }) {
2012-04-30 14:56:01 +02:00
$output_file = $last_output_file if defined $last_output_file ;
2012-03-12 19:52:23 +02:00
} elsif ( $params { save_as }) {
2012-04-30 14:56:01 +02:00
$output_file = $print -> expanded_output_filepath ( $output_file );
2012-03-26 17:57:54 +02:00
$output_file =~ s/\.gcode$/.svg/i if $params { export_svg };
my $dlg = Wx::FileDialog -> new ( $self , 'Save ' . ( $params { export_svg } ? 'SVG' : 'G-code' ) . ' file as:' , dirname ( $output_file ),
2012-05-30 12:06:01 +02:00
basename ( $output_file ), $params { export_svg } ? $svg_wildcard : $gcode_wildcard , wxFD_SAVE );
2012-04-18 17:16:01 +03:00
if ( $dlg -> ShowModal != wxID_OK ) {
$dlg -> Destroy ;
return ;
}
2012-04-30 14:56:01 +02:00
$output_file = $last_output_file = $dlg -> GetPath ;
2012-04-18 17:16:01 +03:00
$dlg -> Destroy ;
2011-12-26 04:20:45 -05:00
}
# show processbar dialog
$process_dialog = Wx::ProgressDialog -> new ( 'Slicing...' , "Processing $input_file_basename..." ,
2012-02-05 14:23:15 +01:00
100 , $self , 0 );
2011-12-26 04:20:45 -05:00
$process_dialog -> Pulse ;
2011-11-27 11:40:03 +01:00
{
2011-12-18 13:43:31 +01:00
my @warnings = ();
local $SIG { __WARN__ } = sub { push @warnings , $_ [ 0 ] };
2012-05-30 12:06:01 +02:00
my %export_params = (
2012-04-30 14:56:01 +02:00
output_file => $output_file ,
status_cb => sub {
my ( $percent , $message ) = @_ ;
if ( & Wx:: wxVERSION_STRING =~ / 2\.(8\.|9\.[2-9])/ ) {
$process_dialog -> Update ( $percent , "$message..." );
}
},
);
2012-03-26 17:57:54 +02:00
if ( $params { export_svg }) {
2012-05-30 12:06:01 +02:00
$print -> export_svg ( %export_params );
2012-03-26 17:57:54 +02:00
} else {
2012-05-30 12:06:01 +02:00
$print -> export_gcode ( %export_params );
2012-03-26 17:57:54 +02:00
}
2012-04-30 14:56:01 +02:00
Slic3r::GUI:: warning_catcher ( $self ) -> ( $_ ) for @warnings ;
2011-11-27 11:40:03 +01:00
}
2011-10-03 11:55:32 +02:00
$process_dialog -> Destroy ;
2011-10-03 17:41:45 +02:00
undef $process_dialog ;
2011-10-03 11:55:32 +02:00
2012-03-26 17:57:54 +02:00
my $message = "$input_file_basename was successfully sliced" ;
$message .= sprintf " in %d minutes and %.3f seconds" ,
2012-04-30 14:56:01 +02:00
int ( $print -> processing_time / 60 ),
$print -> processing_time - int ( $print -> processing_time / 60 ) * 60
if $print -> processing_time ;
2012-03-26 17:57:54 +02:00
$message .= "." ;
2012-06-14 13:49:50 +02:00
Slic3r::GUI:: notify ( $message );
2012-02-16 22:52:57 +01:00
Wx::MessageDialog -> new ( $self , $message , 'Done!' ,
wxOK | wxICON_INFORMATION ) -> ShowModal ;
2011-10-03 11:55:32 +02:00
};
2012-04-30 14:56:01 +02:00
Slic3r::GUI:: catch_error ( $self , sub { $process_dialog -> Destroy if $process_dialog });
2011-10-05 18:13:47 +02:00
}
sub save_config {
my $self = shift ;
2011-10-03 11:55:32 +02:00
2012-02-06 16:52:11 +01:00
my $process_dialog ;
eval {
# validate configuration
Slic3r::Config -> validate ;
};
2012-04-30 14:56:01 +02:00
Slic3r::GUI:: catch_error ( $self , sub { $process_dialog -> Destroy if $process_dialog }) and return ;
2012-02-06 16:52:11 +01:00
2012-02-03 20:22:45 +01:00
my $dir = $last_config ? dirname ( $last_config ) : $last_config_dir || $last_skein_dir || "" ;
2011-12-26 19:06:57 +01:00
my $filename = $last_config ? basename ( $last_config ) : "config.ini" ;
my $dlg = Wx::FileDialog -> new ( $self , 'Save configuration as:' , $dir , $filename ,
2012-05-30 11:55:46 +02:00
$ini_wildcard , wxFD_SAVE | & Wx:: wxFD_OVERWRITE_PROMPT );
2011-10-05 18:13:47 +02:00
if ( $dlg -> ShowModal == wxID_OK ) {
2011-12-09 14:07:50 +01:00
my $file = $dlg -> GetPath ;
2012-02-03 19:57:49 +01:00
$last_config_dir = dirname ( $file );
2011-12-26 19:06:57 +01:00
$last_config = $file ;
2011-12-09 14:07:50 +01:00
Slic3r::Config -> save ( $file );
2011-10-05 18:13:47 +02:00
}
2012-04-18 17:16:01 +03:00
$dlg -> Destroy ;
2011-10-05 18:13:47 +02:00
}
sub load_config {
my $self = shift ;
2012-02-03 20:22:45 +01:00
my $dir = $last_config ? dirname ( $last_config ) : $last_config_dir || $last_skein_dir || "" ;
2012-02-03 19:57:49 +01:00
my $dlg = Wx::FileDialog -> new ( $self , 'Select configuration to load:' , $dir , "config.ini" ,
2012-05-31 09:26:30 +02:00
$ini_wildcard , wxFD_OPEN | & Wx:: wxFD_FILE_MUST_EXIST );
2011-10-05 18:13:47 +02:00
if ( $dlg -> ShowModal == wxID_OK ) {
my ( $file ) = $dlg -> GetPaths ;
2012-02-03 19:57:49 +01:00
$last_config_dir = dirname ( $file );
2011-12-26 19:06:57 +01:00
$last_config = $file ;
2011-10-05 18:13:47 +02:00
eval {
2012-04-30 14:56:01 +02:00
local $SIG { __WARN__ } = Slic3r::GUI:: warning_catcher ( $self );
2011-10-05 18:13:47 +02:00
Slic3r::Config -> load ( $file );
};
2012-05-01 11:46:17 +02:00
Slic3r::GUI:: catch_error ( $self );
2012-06-18 22:27:57 +02:00
$_ -> () for values % Slic3r::GUI::OptionsGroup:: reload_callbacks ;
2012-06-19 14:47:02 +02:00
$_ -> external_config_loaded ( $file ) for values % { $self -> { options_tabs }};
2011-10-05 18:13:47 +02:00
}
2012-04-18 17:16:01 +03:00
$dlg -> Destroy ;
2011-10-05 18:13:47 +02:00
}
2012-06-26 17:42:29 +02:00
sub config_wizard {
my $self = shift ;
if ( Slic3r::GUI::ConfigWizard -> new ( $self ) -> run ) {
$_ -> () for values % Slic3r::GUI::OptionsGroup:: reload_callbacks ;
$_ -> set_dirty ( 1 ) for values % { $self -> { options_tabs }};
}
}
2012-06-23 17:39:20 +02:00
sub on_close {
my $self = shift ;
my @dirty ;
2012-06-24 10:22:44 +02:00
foreach ( values % { $self -> { options_tabs }}) {
push ( @dirty , $_ -> title ) if $_ -> is_dirty ;
2012-06-23 17:39:20 +02:00
}
if ( @dirty ) {
my $titles = join ', ' , @dirty ;
my $confirm = Wx::MessageDialog -> new ( $self , "You have unsaved changes ($titles). Exit anyway?" ,
'Unsaved Presets' , wxICON_QUESTION | wxOK | wxCANCEL );
return ( $confirm -> ShowModal == wxID_OK );
}
return 1 ;
}
2011-10-03 11:55:32 +02:00
1 ;