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