2015-12-04 20:25:45 +00:00
# include "GUI.hpp"
2018-03-27 11:44:18 +00:00
# include "WipeTowerDialog.hpp"
2015-12-04 20:25:45 +00:00
2017-11-02 15:21:34 +00:00
# include <assert.h>
2018-04-09 12:41:55 +00:00
# include <cmath>
2017-11-02 15:21:34 +00:00
2018-01-07 17:41:40 +00:00
# include <boost/lexical_cast.hpp>
2018-05-21 20:10:38 +00:00
# include <boost/algorithm/string.hpp>
2018-02-07 10:37:15 +00:00
# include <boost/format.hpp>
2018-02-02 11:38:35 +00:00
2015-12-04 20:25:45 +00:00
# if __APPLE__
# import <IOKit / pwr_mgt / IOPMLib.h>
# elif _WIN32
# include <Windows.h>
2017-12-13 13:45:10 +00:00
// Undefine min/max macros incompatible with the standard library
// For example, std::numeric_limits<std::streamsize>::max()
// produces some weird errors
# ifdef min
# undef min
# endif
# ifdef max
# undef max
# endif
2017-11-02 15:21:34 +00:00
# include "boost/nowide/convert.hpp"
2015-12-04 20:25:45 +00:00
# endif
2017-12-04 09:48:40 +00:00
# include <wx/app.h>
# include <wx/button.h>
2018-02-15 17:13:37 +00:00
# include <wx/dir.h>
# include <wx/filename.h>
2017-12-04 09:48:40 +00:00
# include <wx/frame.h>
# include <wx/menu.h>
# include <wx/notebook.h>
# include <wx/panel.h>
# include <wx/sizer.h>
2018-02-02 11:38:35 +00:00
# include <wx/combo.h>
2017-12-13 13:45:10 +00:00
# include <wx/window.h>
2018-04-16 14:52:11 +00:00
# include <wx/msgdlg.h>
2018-04-09 12:41:55 +00:00
# include <wx/settings.h>
2018-06-11 16:24:13 +00:00
# include <wx/display.h>
2018-02-02 11:38:35 +00:00
2018-02-02 12:56:25 +00:00
# include "wxExtensions.hpp"
2017-12-04 09:48:40 +00:00
2018-01-23 10:42:04 +00:00
# include "Tab.hpp"
2018-01-23 10:37:19 +00:00
# include "TabIface.hpp"
2018-04-09 15:03:37 +00:00
# include "AboutDialog.hpp"
2018-01-05 14:11:33 +00:00
# include "AppConfig.hpp"
2018-04-10 14:27:42 +00:00
# include "ConfigSnapshotDialog.hpp"
2018-02-08 09:58:13 +00:00
# include "Utils.hpp"
2018-04-30 12:31:57 +00:00
# include "MsgDialog.hpp"
2018-03-13 11:39:57 +00:00
# include "ConfigWizard.hpp"
2018-02-22 10:12:29 +00:00
# include "Preferences.hpp"
2018-03-09 16:17:51 +00:00
# include "PresetBundle.hpp"
2018-04-27 10:29:18 +00:00
# include "UpdateDialogs.hpp"
2018-05-04 14:04:43 +00:00
# include "FirmwareDialog.hpp"
2017-12-05 14:54:01 +00:00
2018-04-16 14:52:11 +00:00
# include "../Utils/PresetUpdater.hpp"
2018-04-10 14:27:42 +00:00
# include "../Config/Snapshot.hpp"
2018-07-17 06:54:17 +00:00
2018-06-22 10:27:56 +00:00
# include "3DScene.hpp"
2018-06-20 16:33:46 +00:00
# include "libslic3r/I18N.hpp"
2018-04-19 08:35:47 +00:00
2015-12-04 20:25:45 +00:00
namespace Slic3r { namespace GUI {
2015-12-05 10:48:24 +00:00
# if __APPLE__
2015-12-04 20:25:45 +00:00
IOPMAssertionID assertionID ;
2015-12-05 10:48:24 +00:00
# endif
2015-12-04 20:25:45 +00:00
2017-10-25 10:53:31 +00:00
void disable_screensaver ( )
2015-12-04 20:25:45 +00:00
{
# if __APPLE__
CFStringRef reasonForActivity = CFSTR ( " Slic3r " ) ;
IOReturn success = IOPMAssertionCreateWithName ( kIOPMAssertionTypeNoDisplaySleep ,
kIOPMAssertionLevelOn , reasonForActivity , & assertionID ) ;
// ignore result: success == kIOReturnSuccess
# elif _WIN32
2015-12-06 10:17:50 +00:00
SetThreadExecutionState ( ES_DISPLAY_REQUIRED | ES_CONTINUOUS ) ;
2015-12-04 20:25:45 +00:00
# endif
}
2017-10-25 10:53:31 +00:00
void enable_screensaver ( )
2015-12-04 20:25:45 +00:00
{
# if __APPLE__
IOReturn success = IOPMAssertionRelease ( assertionID ) ;
# elif _WIN32
2015-12-06 10:17:50 +00:00
SetThreadExecutionState ( ES_CONTINUOUS ) ;
2015-12-04 20:25:45 +00:00
# endif
}
2017-10-25 10:53:31 +00:00
bool debugged ( )
2016-04-13 18:45:44 +00:00
{
2016-04-13 18:51:03 +00:00
# ifdef _WIN32
2016-04-13 18:45:44 +00:00
return IsDebuggerPresent ( ) ;
2016-04-13 18:51:03 +00:00
# else
return false ;
# endif /* _WIN32 */
2016-04-13 18:45:44 +00:00
}
2017-10-25 10:53:31 +00:00
void break_to_debugger ( )
2016-04-13 18:45:44 +00:00
{
# ifdef _WIN32
if ( IsDebuggerPresent ( ) )
DebugBreak ( ) ;
# endif /* _WIN32 */
}
2017-12-04 09:48:40 +00:00
// Passing the wxWidgets GUI classes instantiated by the Perl part to C++.
wxApp * g_wxApp = nullptr ;
wxFrame * g_wxMainFrame = nullptr ;
wxNotebook * g_wxTabPanel = nullptr ;
2018-02-20 07:58:46 +00:00
AppConfig * g_AppConfig = nullptr ;
2018-03-09 16:17:51 +00:00
PresetBundle * g_PresetBundle = nullptr ;
2018-04-16 14:52:11 +00:00
PresetUpdater * g_PresetUpdater = nullptr ;
2018-06-22 10:27:56 +00:00
_3DScene * g_3DScene = nullptr ;
2018-04-09 12:41:55 +00:00
wxColour g_color_label_modified ;
wxColour g_color_label_sys ;
2018-04-18 11:32:21 +00:00
wxColour g_color_label_default ;
2017-12-04 09:48:40 +00:00
2018-02-09 10:04:34 +00:00
std : : vector < Tab * > g_tabs_list ;
2018-02-12 07:57:32 +00:00
wxLocale * g_wxLocale ;
2018-02-08 09:58:13 +00:00
2018-06-20 12:20:48 +00:00
wxFont g_small_font ;
wxFont g_bold_font ;
2018-03-09 16:17:51 +00:00
std : : shared_ptr < ConfigOptionsGroup > m_optgroup ;
2018-03-13 15:14:36 +00:00
double m_brim_width = 0.0 ;
2018-04-03 20:07:59 +00:00
wxButton * g_wiping_dialog_button = nullptr ;
2018-03-09 16:17:51 +00:00
2018-04-09 12:41:55 +00:00
static void init_label_colours ( )
{
auto luma = get_colour_approx_luma ( wxSystemSettings : : GetColour ( wxSYS_COLOUR_WINDOW ) ) ;
if ( luma > = 128 ) {
2018-05-02 11:20:36 +00:00
g_color_label_modified = wxColour ( 252 , 77 , 1 ) ;
2018-04-30 12:20:33 +00:00
g_color_label_sys = wxColour ( 26 , 132 , 57 ) ;
2018-04-09 12:41:55 +00:00
} else {
g_color_label_modified = wxColour ( 253 , 111 , 40 ) ;
g_color_label_sys = wxColour ( 115 , 220 , 103 ) ;
}
2018-04-18 11:32:21 +00:00
g_color_label_default = wxSystemSettings : : GetColour ( wxSYS_COLOUR_WINDOWTEXT ) ;
2018-04-09 12:41:55 +00:00
}
2018-03-09 16:17:51 +00:00
2018-04-30 12:20:33 +00:00
void update_label_colours_from_appconfig ( )
{
if ( g_AppConfig - > has ( " label_clr_sys " ) ) {
auto str = g_AppConfig - > get ( " label_clr_sys " ) ;
if ( str ! = " " )
g_color_label_sys = wxColour ( str ) ;
}
if ( g_AppConfig - > has ( " label_clr_modified " ) ) {
auto str = g_AppConfig - > get ( " label_clr_modified " ) ;
if ( str ! = " " )
g_color_label_modified = wxColour ( str ) ;
}
}
2018-06-20 12:20:48 +00:00
static void init_fonts ( )
{
g_small_font = wxSystemSettings : : GetFont ( wxSYS_DEFAULT_GUI_FONT ) ;
g_bold_font = wxSystemSettings : : GetFont ( wxSYS_DEFAULT_GUI_FONT ) . Bold ( ) ;
# ifdef __WXMAC__
g_small_font . SetPointSize ( 11 ) ;
g_bold_font . SetPointSize ( 13 ) ;
# endif /*__WXMAC__*/
}
2018-06-20 17:26:19 +00:00
static std : : string libslic3r_translate_callback ( const char * s ) { return wxGetTranslation ( wxString ( s , wxConvUTF8 ) ) . utf8_str ( ) . data ( ) ; }
2018-06-20 16:33:46 +00:00
2017-12-04 09:48:40 +00:00
void set_wxapp ( wxApp * app )
{
g_wxApp = app ;
2018-06-20 16:33:46 +00:00
// Let the libslic3r know the callback, which will translate messages on demand.
Slic3r : : I18N : : set_translate_callback ( libslic3r_translate_callback ) ;
2018-04-09 12:41:55 +00:00
init_label_colours ( ) ;
2018-06-20 12:20:48 +00:00
init_fonts ( ) ;
2017-12-04 09:48:40 +00:00
}
void set_main_frame ( wxFrame * main_frame )
{
g_wxMainFrame = main_frame ;
}
void set_tab_panel ( wxNotebook * tab_panel )
{
g_wxTabPanel = tab_panel ;
}
2018-02-20 07:58:46 +00:00
void set_app_config ( AppConfig * app_config )
{
g_AppConfig = app_config ;
}
2018-03-09 16:17:51 +00:00
void set_preset_bundle ( PresetBundle * preset_bundle )
{
g_PresetBundle = preset_bundle ;
}
2018-04-16 14:52:11 +00:00
void set_preset_updater ( PresetUpdater * updater )
{
g_PresetUpdater = updater ;
}
2018-06-22 10:27:56 +00:00
void set_3DScene ( _3DScene * scene )
{
g_3DScene = scene ;
}
2018-02-09 10:04:34 +00:00
std : : vector < Tab * > & get_tabs_list ( )
2017-12-04 09:48:40 +00:00
{
2018-02-09 10:04:34 +00:00
return g_tabs_list ;
}
bool checked_tab ( Tab * tab )
{
bool ret = true ;
if ( find ( g_tabs_list . begin ( ) , g_tabs_list . end ( ) , tab ) = = g_tabs_list . end ( ) )
ret = false ;
return ret ;
}
void delete_tab_from_list ( Tab * tab )
{
std : : vector < Tab * > : : iterator itr = find ( g_tabs_list . begin ( ) , g_tabs_list . end ( ) , tab ) ;
if ( itr ! = g_tabs_list . end ( ) )
g_tabs_list . erase ( itr ) ;
}
2018-02-08 09:58:13 +00:00
bool select_language ( wxArrayString & names ,
wxArrayLong & identifiers )
{
wxCHECK_MSG ( names . Count ( ) = = identifiers . Count ( ) , false ,
2018-02-23 08:16:35 +00:00
_ ( L ( " Array of language names and identifiers should have the same size. " ) ) ) ;
2018-02-12 07:57:32 +00:00
int init_selection = 0 ;
long current_language = g_wxLocale ? g_wxLocale - > GetLanguage ( ) : wxLANGUAGE_UNKNOWN ;
for ( auto lang : identifiers ) {
if ( lang = = current_language )
break ;
else
+ + init_selection ;
}
if ( init_selection = = identifiers . size ( ) )
init_selection = 0 ;
2018-02-23 08:16:35 +00:00
long index = wxGetSingleChoiceIndex ( _ ( L ( " Select the language " ) ) , _ ( L ( " Language " ) ) ,
2018-02-12 07:57:32 +00:00
names , init_selection ) ;
2018-02-08 09:58:13 +00:00
if ( index ! = - 1 )
{
2018-02-12 07:57:32 +00:00
g_wxLocale = new wxLocale ;
g_wxLocale - > Init ( identifiers [ index ] ) ;
g_wxLocale - > AddCatalogLookupPathPrefix ( wxPathOnly ( localization_dir ( ) ) ) ;
g_wxLocale - > AddCatalog ( g_wxApp - > GetAppName ( ) ) ;
2018-03-06 08:44:53 +00:00
wxSetlocale ( LC_NUMERIC , " C " ) ;
2018-07-23 13:44:01 +00:00
Preset : : update_suffix_modified ( ) ;
2018-02-08 09:58:13 +00:00
return true ;
}
return false ;
}
bool load_language ( )
{
2018-05-03 07:21:01 +00:00
wxString language = wxEmptyString ;
if ( g_AppConfig - > has ( " translation_language " ) )
language = g_AppConfig - > get ( " translation_language " ) ;
2018-02-20 07:58:46 +00:00
2018-05-03 07:21:01 +00:00
if ( language . IsEmpty ( ) )
2018-02-12 07:57:32 +00:00
return false ;
wxArrayString names ;
wxArrayLong identifiers ;
2018-02-08 09:58:13 +00:00
get_installed_languages ( names , identifiers ) ;
for ( size_t i = 0 ; i < identifiers . Count ( ) ; i + + )
{
2018-05-03 07:21:01 +00:00
if ( wxLocale : : GetLanguageCanonicalName ( identifiers [ i ] ) = = language )
2018-02-08 09:58:13 +00:00
{
2018-02-12 07:57:32 +00:00
g_wxLocale = new wxLocale ;
g_wxLocale - > Init ( identifiers [ i ] ) ;
g_wxLocale - > AddCatalogLookupPathPrefix ( wxPathOnly ( localization_dir ( ) ) ) ;
g_wxLocale - > AddCatalog ( g_wxApp - > GetAppName ( ) ) ;
2018-03-06 08:44:53 +00:00
wxSetlocale ( LC_NUMERIC , " C " ) ;
2018-07-23 13:44:01 +00:00
Preset : : update_suffix_modified ( ) ;
2018-02-08 09:58:13 +00:00
return true ;
}
}
return false ;
}
2018-02-12 07:57:32 +00:00
void save_language ( )
2018-02-08 09:58:13 +00:00
{
2018-05-03 07:21:01 +00:00
wxString language = wxEmptyString ;
if ( g_wxLocale )
language = g_wxLocale - > GetCanonicalName ( ) ;
g_AppConfig - > set ( " translation_language " , language . ToStdString ( ) ) ;
2018-02-20 07:58:46 +00:00
g_AppConfig - > save ( ) ;
2017-12-04 09:48:40 +00:00
}
2018-02-08 09:58:13 +00:00
void get_installed_languages ( wxArrayString & names ,
wxArrayLong & identifiers )
2017-12-04 09:48:40 +00:00
{
2018-02-08 09:58:13 +00:00
names . Clear ( ) ;
identifiers . Clear ( ) ;
2018-02-12 07:57:32 +00:00
wxDir dir ( wxPathOnly ( localization_dir ( ) ) ) ;
2018-02-08 09:58:13 +00:00
wxString filename ;
const wxLanguageInfo * langinfo ;
wxString name = wxLocale : : GetLanguageName ( wxLANGUAGE_DEFAULT ) ;
if ( ! name . IsEmpty ( ) )
{
2018-02-23 08:16:35 +00:00
names . Add ( _ ( L ( " Default " ) ) ) ;
2018-02-08 09:58:13 +00:00
identifiers . Add ( wxLANGUAGE_DEFAULT ) ;
}
for ( bool cont = dir . GetFirst ( & filename , wxEmptyString , wxDIR_DIRS ) ;
cont ; cont = dir . GetNext ( & filename ) )
{
langinfo = wxLocale : : FindLanguageInfo ( filename ) ;
if ( langinfo ! = NULL )
{
auto full_file_name = dir . GetName ( ) + wxFileName : : GetPathSeparator ( ) +
filename + wxFileName : : GetPathSeparator ( ) +
g_wxApp - > GetAppName ( ) + wxT ( " .mo " ) ;
if ( wxFileExists ( full_file_name ) )
{
names . Add ( langinfo - > Description ) ;
identifiers . Add ( langinfo - > Language ) ;
}
}
}
}
2018-04-09 15:03:37 +00:00
enum ConfigMenuIDs {
ConfigMenuWizard ,
ConfigMenuSnapshots ,
ConfigMenuTakeSnapshot ,
ConfigMenuUpdate ,
ConfigMenuPreferences ,
ConfigMenuLanguage ,
2018-05-21 19:04:03 +00:00
ConfigMenuFlashFirmware ,
2018-04-09 15:03:37 +00:00
ConfigMenuCnt ,
} ;
2018-06-07 20:10:23 +00:00
static wxString dots ( " … " , wxConvUTF8 ) ;
2018-04-09 15:03:37 +00:00
void add_config_menu ( wxMenuBar * menu , int event_preferences_changed , int event_language_change )
2017-12-04 09:48:40 +00:00
{
2018-02-08 09:58:13 +00:00
auto local_menu = new wxMenu ( ) ;
2018-04-09 15:03:37 +00:00
wxWindowID config_id_base = wxWindow : : NewControlId ( ( int ) ConfigMenuCnt ) ;
2018-04-11 10:21:15 +00:00
2018-06-28 14:01:06 +00:00
const auto config_wizard_name = _ ( ConfigWizard : : name ( ) . wx_str ( ) ) ;
2018-06-27 07:07:04 +00:00
const auto config_wizard_tooltip = wxString : : Format ( _ ( L ( " Run %s " ) ) , config_wizard_name ) ;
2018-04-09 15:03:37 +00:00
// Cmd+, is standard on OS X - what about other operating systems?
2018-06-27 07:07:04 +00:00
local_menu - > Append ( config_id_base + ConfigMenuWizard , config_wizard_name + dots , config_wizard_tooltip ) ;
local_menu - > Append ( config_id_base + ConfigMenuSnapshots , _ ( L ( " Configuration Snapshots " ) ) + dots , _ ( L ( " Inspect / activate configuration snapshots " ) ) ) ;
2018-05-02 11:20:36 +00:00
local_menu - > Append ( config_id_base + ConfigMenuTakeSnapshot , _ ( L ( " Take Configuration Snapshot " ) ) , _ ( L ( " Capture a configuration snapshot " ) ) ) ;
2018-05-21 19:04:03 +00:00
// local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));
2018-04-09 15:03:37 +00:00
local_menu - > AppendSeparator ( ) ;
2018-06-07 20:10:23 +00:00
local_menu - > Append ( config_id_base + ConfigMenuPreferences , _ ( L ( " Preferences " ) ) + dots + " \t Ctrl+, " , _ ( L ( " Application preferences " ) ) ) ;
2018-04-09 15:03:37 +00:00
local_menu - > Append ( config_id_base + ConfigMenuLanguage , _ ( L ( " Change Application Language " ) ) ) ;
2018-05-21 19:04:03 +00:00
local_menu - > AppendSeparator ( ) ;
local_menu - > Append ( config_id_base + ConfigMenuFlashFirmware , _ ( L ( " Flash printer firmware " ) ) , _ ( L ( " Upload a firmware image into an Arduino based printer " ) ) ) ;
// TODO: for when we're able to flash dictionaries
// local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer")));
2018-04-09 15:03:37 +00:00
local_menu - > Bind ( wxEVT_MENU , [ config_id_base , event_language_change , event_preferences_changed ] ( wxEvent & event ) {
switch ( event . GetId ( ) - config_id_base ) {
2018-04-11 10:21:15 +00:00
case ConfigMenuWizard :
2018-04-24 16:06:42 +00:00
config_wizard ( ConfigWizard : : RR_USER ) ;
2018-04-11 10:21:15 +00:00
break ;
2018-04-10 14:27:42 +00:00
case ConfigMenuTakeSnapshot :
// Take a configuration snapshot.
2018-04-11 10:21:15 +00:00
if ( check_unsaved_changes ( ) ) {
wxTextEntryDialog dlg ( nullptr , _ ( L ( " Taking configuration snapshot " ) ) , _ ( L ( " Snapshot name " ) ) ) ;
if ( dlg . ShowModal ( ) = = wxID_OK )
2018-04-20 08:26:23 +00:00
g_AppConfig - > set ( " on_snapshot " ,
Slic3r : : GUI : : Config : : SnapshotDB : : singleton ( ) . take_snapshot (
* g_AppConfig , Slic3r : : GUI : : Config : : Snapshot : : SNAPSHOT_USER , dlg . GetValue ( ) . ToUTF8 ( ) . data ( ) ) . id ) ;
2018-04-11 10:21:15 +00:00
}
2018-04-10 14:27:42 +00:00
break ;
case ConfigMenuSnapshots :
2018-04-11 10:21:15 +00:00
if ( check_unsaved_changes ( ) ) {
2018-04-20 08:26:23 +00:00
std : : string on_snapshot ;
if ( Config : : SnapshotDB : : singleton ( ) . is_on_snapshot ( * g_AppConfig ) )
on_snapshot = g_AppConfig - > get ( " on_snapshot " ) ;
ConfigSnapshotDialog dlg ( Slic3r : : GUI : : Config : : SnapshotDB : : singleton ( ) , on_snapshot ) ;
2018-04-11 10:21:15 +00:00
dlg . ShowModal ( ) ;
if ( ! dlg . snapshot_to_activate ( ) . empty ( ) ) {
2018-04-20 08:26:23 +00:00
if ( ! Config : : SnapshotDB : : singleton ( ) . is_on_snapshot ( * g_AppConfig ) )
Config : : SnapshotDB : : singleton ( ) . take_snapshot ( * g_AppConfig , Config : : Snapshot : : SNAPSHOT_BEFORE_ROLLBACK ) ;
g_AppConfig - > set ( " on_snapshot " ,
Config : : SnapshotDB : : singleton ( ) . restore_snapshot ( dlg . snapshot_to_activate ( ) , * g_AppConfig ) . id ) ;
2018-04-11 10:21:15 +00:00
g_PresetBundle - > load_presets ( * g_AppConfig ) ;
// Load the currently selected preset into the GUI, update the preset selection box.
2018-06-06 08:52:19 +00:00
load_current_presets ( ) ;
2018-04-11 10:21:15 +00:00
}
}
2018-04-10 14:27:42 +00:00
break ;
2018-04-09 15:03:37 +00:00
case ConfigMenuPreferences :
{
2018-04-11 10:21:15 +00:00
PreferencesDialog dlg ( g_wxMainFrame , event_preferences_changed ) ;
dlg . ShowModal ( ) ;
2018-04-09 15:03:37 +00:00
break ;
}
case ConfigMenuLanguage :
{
wxArrayString names ;
wxArrayLong identifiers ;
get_installed_languages ( names , identifiers ) ;
if ( select_language ( names , identifiers ) ) {
save_language ( ) ;
show_info ( g_wxTabPanel , _ ( L ( " Application will be restarted " ) ) , _ ( L ( " Attention! " ) ) ) ;
if ( event_language_change > 0 ) {
2018-06-25 10:27:42 +00:00
_3DScene : : remove_all_canvases ( ) ; // remove all canvas before recreate GUI
2018-04-09 15:03:37 +00:00
wxCommandEvent event ( event_language_change ) ;
g_wxApp - > ProcessEvent ( event ) ;
}
2018-02-09 10:04:34 +00:00
}
2018-04-09 15:03:37 +00:00
break ;
2018-02-09 10:04:34 +00:00
}
2018-05-21 19:04:03 +00:00
case ConfigMenuFlashFirmware :
2018-05-04 14:04:43 +00:00
FirmwareDialog : : run ( g_wxMainFrame ) ;
break ;
default :
break ;
}
} ) ;
2018-05-21 19:04:03 +00:00
menu - > Append ( local_menu , _ ( L ( " &Configuration " ) ) ) ;
2018-05-04 14:04:43 +00:00
}
void add_menus ( wxMenuBar * menu , int event_preferences_changed , int event_language_change )
{
2018-06-04 07:24:48 +00:00
add_config_menu ( menu , event_preferences_changed , event_language_change ) ;
2018-05-04 14:04:43 +00:00
}
2018-04-11 10:21:15 +00:00
// This is called when closing the application, when loading a config file or when starting the config wizard
// to notify the user whether he is aware that some preset changes will be lost.
bool check_unsaved_changes ( )
{
std : : string dirty ;
for ( Tab * tab : g_tabs_list )
if ( tab - > current_preset_is_dirty ( ) )
if ( dirty . empty ( ) )
dirty = tab - > name ( ) ;
else
dirty + = std : : string ( " , " ) + tab - > name ( ) ;
if ( dirty . empty ( ) )
// No changes, the application may close or reload presets.
return true ;
// Ask the user.
auto dialog = new wxMessageDialog ( g_wxMainFrame ,
_ ( L ( " You have unsaved changes " ) ) + dirty + _ ( L ( " . Discard changes and continue anyway? " ) ) ,
_ ( L ( " Unsaved Presets " ) ) ,
wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT ) ;
return dialog - > ShowModal ( ) = = wxID_YES ;
}
2018-04-24 16:06:42 +00:00
bool config_wizard_startup ( bool app_config_exists )
2018-04-16 14:52:11 +00:00
{
2018-06-19 16:26:38 +00:00
if ( ! app_config_exists | | g_PresetBundle - > printers . size ( ) < = 1 ) {
2018-04-24 16:06:42 +00:00
config_wizard ( ConfigWizard : : RR_DATA_EMPTY ) ;
return true ;
2018-04-16 14:52:11 +00:00
} else if ( g_AppConfig - > legacy_datadir ( ) ) {
// Looks like user has legacy pre-vendorbundle data directory,
// explain what this is and run the wizard
2018-04-27 10:29:18 +00:00
MsgDataLegacy dlg ;
dlg . ShowModal ( ) ;
2018-04-16 14:52:11 +00:00
2018-04-24 16:06:42 +00:00
config_wizard ( ConfigWizard : : RR_DATA_LEGACY ) ;
return true ;
2018-04-16 14:52:11 +00:00
}
2018-04-24 16:06:42 +00:00
return false ;
2018-04-16 14:52:11 +00:00
}
2018-04-24 16:06:42 +00:00
void config_wizard ( int reason )
2018-03-13 11:39:57 +00:00
{
2018-04-11 10:21:15 +00:00
// Exit wizard if there are unsaved changes and the user cancels the action.
if ( ! check_unsaved_changes ( ) )
2018-04-16 14:52:11 +00:00
return ;
2018-04-11 10:21:15 +00:00
2018-06-04 07:07:29 +00:00
try {
ConfigWizard wizard ( nullptr , static_cast < ConfigWizard : : RunReason > ( reason ) ) ;
wizard . run ( g_PresetBundle , g_PresetUpdater ) ;
}
catch ( const std : : exception & e ) {
show_error ( nullptr , e . what ( ) ) ;
}
2018-04-11 10:21:15 +00:00
2018-06-06 08:52:19 +00:00
// Load the currently selected preset into the GUI, update the preset selection box.
load_current_presets ( ) ;
2018-03-13 11:39:57 +00:00
}
2018-02-22 10:12:29 +00:00
void open_preferences_dialog ( int event_preferences )
{
auto dlg = new PreferencesDialog ( g_wxMainFrame , event_preferences ) ;
dlg - > ShowModal ( ) ;
}
2018-03-15 17:06:26 +00:00
void create_preset_tabs ( bool no_controller , int event_value_change , int event_presets_changed )
2018-01-05 14:11:33 +00:00
{
2018-04-30 12:20:33 +00:00
update_label_colours_from_appconfig ( ) ;
2018-03-09 16:17:51 +00:00
add_created_tab ( new TabPrint ( g_wxTabPanel , no_controller ) ) ;
add_created_tab ( new TabFilament ( g_wxTabPanel , no_controller ) ) ;
2018-03-15 17:06:26 +00:00
add_created_tab ( new TabPrinter ( g_wxTabPanel , no_controller ) ) ;
2018-01-21 22:35:00 +00:00
for ( size_t i = 0 ; i < g_wxTabPanel - > GetPageCount ( ) ; + + i ) {
Tab * tab = dynamic_cast < Tab * > ( g_wxTabPanel - > GetPage ( i ) ) ;
if ( ! tab )
continue ;
tab - > set_event_value_change ( wxEventType ( event_value_change ) ) ;
tab - > set_event_presets_changed ( wxEventType ( event_presets_changed ) ) ;
}
2017-12-22 10:50:28 +00:00
}
2018-01-23 10:37:19 +00:00
TabIface * get_preset_tab_iface ( char * name )
{
for ( size_t i = 0 ; i < g_wxTabPanel - > GetPageCount ( ) ; + + i ) {
Tab * tab = dynamic_cast < Tab * > ( g_wxTabPanel - > GetPage ( i ) ) ;
if ( ! tab )
continue ;
2018-01-25 20:44:22 +00:00
if ( tab - > name ( ) = = name ) {
2018-01-23 10:37:19 +00:00
return new TabIface ( tab ) ;
}
}
return new TabIface ( nullptr ) ;
}
2018-02-15 16:30:33 +00:00
// opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element)
2018-04-13 10:35:04 +00:00
void change_opt_value ( DynamicPrintConfig & config , const t_config_option_key & opt_key , const boost : : any & value , int opt_index /*= 0*/ )
2018-01-07 17:41:40 +00:00
{
try {
switch ( config . def ( ) - > get ( opt_key ) - > type ) {
2018-01-09 12:52:01 +00:00
case coFloatOrPercent : {
2018-02-20 11:30:13 +00:00
std : : string str = boost : : any_cast < std : : string > ( value ) ;
bool percent = false ;
if ( str . back ( ) = = ' % ' ) {
str . pop_back ( ) ;
percent = true ;
}
double val = stod ( str ) ;
config . set_key_value ( opt_key , new ConfigOptionFloatOrPercent ( val , percent ) ) ;
2018-01-09 12:52:01 +00:00
break ; }
2018-01-07 17:41:40 +00:00
case coPercent :
2018-01-11 09:33:17 +00:00
config . set_key_value ( opt_key , new ConfigOptionPercent ( boost : : any_cast < double > ( value ) ) ) ;
2018-01-09 12:52:01 +00:00
break ;
case coFloat : {
2018-01-07 17:41:40 +00:00
double & val = config . opt_float ( opt_key ) ;
2018-01-09 08:41:07 +00:00
val = boost : : any_cast < double > ( value ) ;
2018-01-07 17:41:40 +00:00
break ;
}
2018-02-26 08:57:08 +00:00
case coPercents : {
ConfigOptionPercents * vec_new = new ConfigOptionPercents { boost : : any_cast < double > ( value ) } ;
config . option < ConfigOptionPercents > ( opt_key ) - > set_at ( vec_new , opt_index , opt_index ) ;
2018-01-09 12:52:01 +00:00
break ;
2018-02-26 08:57:08 +00:00
}
case coFloats : {
ConfigOptionFloats * vec_new = new ConfigOptionFloats { boost : : any_cast < double > ( value ) } ;
config . option < ConfigOptionFloats > ( opt_key ) - > set_at ( vec_new , opt_index , opt_index ) ;
break ;
2018-01-09 12:52:01 +00:00
}
2018-01-07 17:41:40 +00:00
case coString :
2018-01-09 12:52:01 +00:00
config . set_key_value ( opt_key , new ConfigOptionString ( boost : : any_cast < std : : string > ( value ) ) ) ;
2018-01-07 17:41:40 +00:00
break ;
2018-01-12 11:41:13 +00:00
case coStrings : {
2018-04-13 10:35:04 +00:00
if ( opt_key . compare ( " compatible_printers " ) = = 0 ) {
config . option < ConfigOptionStrings > ( opt_key ) - > values =
boost : : any_cast < std : : vector < std : : string > > ( value ) ;
}
else if ( config . def ( ) - > get ( opt_key ) - > gui_flags . compare ( " serialized " ) = = 0 ) {
std : : string str = boost : : any_cast < std : : string > ( value ) ;
if ( str . back ( ) = = ' ; ' ) str . pop_back ( ) ;
// Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
// Currently used for the post_process config value only.
std : : vector < std : : string > values ;
boost : : split ( values , str , boost : : is_any_of ( " ; " ) ) ;
if ( values . size ( ) = = 1 & & values [ 0 ] = = " " )
2018-03-07 14:05:41 +00:00
break ;
2018-03-23 16:27:43 +00:00
config . option < ConfigOptionStrings > ( opt_key ) - > values = values ;
2018-01-12 11:41:13 +00:00
}
else {
2018-01-25 12:46:04 +00:00
ConfigOptionStrings * vec_new = new ConfigOptionStrings { boost : : any_cast < std : : string > ( value ) } ;
2018-03-02 12:41:37 +00:00
config . option < ConfigOptionStrings > ( opt_key ) - > set_at ( vec_new , opt_index , 0 ) ;
2018-01-12 11:41:13 +00:00
}
}
2018-01-07 17:41:40 +00:00
break ;
case coBool :
config . set_key_value ( opt_key , new ConfigOptionBool ( boost : : any_cast < bool > ( value ) ) ) ;
break ;
2018-01-09 12:52:01 +00:00
case coBools : {
2018-03-09 16:17:51 +00:00
ConfigOptionBools * vec_new = new ConfigOptionBools { ( bool ) boost : : any_cast < unsigned char > ( value ) } ;
2018-03-02 12:41:37 +00:00
config . option < ConfigOptionBools > ( opt_key ) - > set_at ( vec_new , opt_index , 0 ) ;
2018-01-09 12:52:01 +00:00
break ; }
2018-01-07 17:41:40 +00:00
case coInt :
config . set_key_value ( opt_key , new ConfigOptionInt ( boost : : any_cast < int > ( value ) ) ) ;
break ;
2018-01-12 11:41:13 +00:00
case coInts : {
ConfigOptionInts * vec_new = new ConfigOptionInts { boost : : any_cast < int > ( value ) } ;
2018-03-02 12:41:37 +00:00
config . option < ConfigOptionInts > ( opt_key ) - > set_at ( vec_new , opt_index , 0 ) ;
2018-01-12 11:41:13 +00:00
}
2018-01-07 17:41:40 +00:00
break ;
2018-01-11 09:33:17 +00:00
case coEnum : {
if ( opt_key . compare ( " external_fill_pattern " ) = = 0 | |
opt_key . compare ( " fill_pattern " ) = = 0 )
config . set_key_value ( opt_key , new ConfigOptionEnum < InfillPattern > ( boost : : any_cast < InfillPattern > ( value ) ) ) ;
else if ( opt_key . compare ( " gcode_flavor " ) = = 0 )
config . set_key_value ( opt_key , new ConfigOptionEnum < GCodeFlavor > ( boost : : any_cast < GCodeFlavor > ( value ) ) ) ;
else if ( opt_key . compare ( " support_material_pattern " ) = = 0 )
config . set_key_value ( opt_key , new ConfigOptionEnum < SupportMaterialPattern > ( boost : : any_cast < SupportMaterialPattern > ( value ) ) ) ;
else if ( opt_key . compare ( " seam_position " ) = = 0 )
config . set_key_value ( opt_key , new ConfigOptionEnum < SeamPosition > ( boost : : any_cast < SeamPosition > ( value ) ) ) ;
}
2018-01-07 17:41:40 +00:00
break ;
2018-01-30 11:10:12 +00:00
case coPoints : {
2018-03-23 16:27:43 +00:00
if ( opt_key . compare ( " bed_shape " ) = = 0 ) {
2018-08-21 19:05:24 +00:00
config . option < ConfigOptionPoints > ( opt_key ) - > values = boost : : any_cast < std : : vector < Vec2d > > ( value ) ;
2018-03-23 16:27:43 +00:00
break ;
}
2018-08-21 19:05:24 +00:00
ConfigOptionPoints * vec_new = new ConfigOptionPoints { boost : : any_cast < Vec2d > ( value ) } ;
2018-03-08 10:58:06 +00:00
config . option < ConfigOptionPoints > ( opt_key ) - > set_at ( vec_new , opt_index , 0 ) ;
2018-01-30 11:10:12 +00:00
}
2018-01-07 17:41:40 +00:00
break ;
case coNone :
break ;
default :
break ;
}
}
catch ( const std : : exception & e )
{
2018-01-09 12:52:01 +00:00
int i = 0 ; //no reason, just experiment
2018-01-07 17:41:40 +00:00
}
}
2018-03-09 16:17:51 +00:00
void add_created_tab ( Tab * panel )
2017-12-22 10:50:28 +00:00
{
2018-03-09 16:17:51 +00:00
panel - > create_preset_tab ( g_PresetBundle ) ;
2018-01-05 14:11:33 +00:00
2018-01-16 15:28:01 +00:00
// Load the currently selected preset into the GUI, update the preset selection box.
panel - > load_current_preset ( ) ;
2017-12-22 10:50:28 +00:00
g_wxTabPanel - > AddPage ( panel , panel - > title ( ) ) ;
}
2018-06-06 08:52:19 +00:00
void load_current_presets ( )
{
for ( Tab * tab : g_tabs_list ) {
tab - > load_current_preset ( ) ;
}
}
2018-04-30 12:31:57 +00:00
void show_error ( wxWindow * parent , const wxString & message ) {
ErrorDialog msg ( parent , message ) ;
msg . ShowModal ( ) ;
}
void show_error_id ( int id , const std : : string & message ) {
auto * parent = id ! = 0 ? wxWindow : : FindWindowById ( id ) : nullptr ;
2018-05-22 12:33:11 +00:00
show_error ( parent , wxString : : FromUTF8 ( message . data ( ) ) ) ;
2017-12-22 10:50:28 +00:00
}
2018-04-13 10:35:04 +00:00
void show_info ( wxWindow * parent , const wxString & message , const wxString & title ) {
2018-04-30 12:31:57 +00:00
wxMessageDialog msg_wingow ( parent , message , title . empty ( ) ? _ ( L ( " Notice " ) ) : title , wxOK | wxICON_INFORMATION ) ;
msg_wingow . ShowModal ( ) ;
2017-12-04 09:48:40 +00:00
}
2018-04-13 10:35:04 +00:00
void warning_catcher ( wxWindow * parent , const wxString & message ) {
2018-05-02 11:20:36 +00:00
if ( message = = " GLUquadricObjPtr | " + _ ( L ( " Attempt to free unreferenced scalar " ) ) )
2018-02-22 10:12:29 +00:00
return ;
2018-04-30 12:31:57 +00:00
wxMessageDialog msg ( parent , message , _ ( L ( " Warning " ) ) , wxOK | wxICON_WARNING ) ;
msg . ShowModal ( ) ;
2018-02-22 10:12:29 +00:00
}
2018-02-05 15:12:16 +00:00
wxApp * get_app ( ) {
return g_wxApp ;
2017-12-04 09:48:40 +00:00
}
2018-04-24 16:06:42 +00:00
PresetBundle * get_preset_bundle ( )
{
return g_PresetBundle ;
}
2018-04-30 12:20:33 +00:00
const wxColour & get_label_clr_modified ( ) {
2018-04-09 12:41:55 +00:00
return g_color_label_modified ;
2018-03-02 08:08:11 +00:00
}
2018-04-30 12:20:33 +00:00
const wxColour & get_label_clr_sys ( ) {
2018-04-09 12:41:55 +00:00
return g_color_label_sys ;
}
2018-04-30 12:20:33 +00:00
void set_label_clr_modified ( const wxColour & clr ) {
g_color_label_modified = clr ;
auto clr_str = wxString : : Format ( wxT ( " #%02X%02X%02X " ) , clr . Red ( ) , clr . Green ( ) , clr . Blue ( ) ) ;
std : : string str = clr_str . ToStdString ( ) ;
g_AppConfig - > set ( " label_clr_modified " , str ) ;
g_AppConfig - > save ( ) ;
}
void set_label_clr_sys ( const wxColour & clr ) {
g_color_label_sys = clr ;
auto clr_str = wxString : : Format ( wxT ( " #%02X%02X%02X " ) , clr . Red ( ) , clr . Green ( ) , clr . Blue ( ) ) ;
std : : string str = clr_str . ToStdString ( ) ;
g_AppConfig - > set ( " label_clr_sys " , str ) ;
g_AppConfig - > save ( ) ;
}
2018-06-20 12:20:48 +00:00
const wxFont & small_font ( ) {
return g_small_font ;
}
const wxFont & bold_font ( ) {
return g_bold_font ;
}
2018-04-30 12:20:33 +00:00
const wxColour & get_label_clr_default ( ) {
2018-04-18 11:32:21 +00:00
return g_color_label_default ;
}
2018-04-09 12:41:55 +00:00
unsigned get_colour_approx_luma ( const wxColour & colour )
{
double r = colour . Red ( ) ;
double g = colour . Green ( ) ;
double b = colour . Blue ( ) ;
2018-04-10 09:43:04 +00:00
return std : : round ( std : : sqrt (
2018-04-09 12:41:55 +00:00
r * r * .241 +
g * g * .691 +
b * b * .068
) ) ;
2018-03-16 11:56:03 +00:00
}
2018-02-02 11:38:35 +00:00
void create_combochecklist ( wxComboCtrl * comboCtrl , std : : string text , std : : string items , bool initial_value )
{
2018-02-06 11:43:25 +00:00
if ( comboCtrl = = nullptr )
return ;
wxCheckListBoxComboPopup * popup = new wxCheckListBoxComboPopup ;
2018-02-02 11:38:35 +00:00
if ( popup ! = nullptr )
{
2018-02-20 14:22:30 +00:00
// FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
// On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
comboCtrl - > UseAltPopupWindow ( ) ;
comboCtrl - > EnablePopupAnimation ( false ) ;
2018-02-02 11:38:35 +00:00
comboCtrl - > SetPopupControl ( popup ) ;
2018-02-28 14:39:20 +00:00
popup - > SetStringValue ( from_u8 ( text ) ) ;
2018-02-20 10:40:15 +00:00
popup - > Bind ( wxEVT_CHECKLISTBOX , [ popup ] ( wxCommandEvent & evt ) { popup - > OnCheckListBox ( evt ) ; } ) ;
popup - > Bind ( wxEVT_LISTBOX , [ popup ] ( wxCommandEvent & evt ) { popup - > OnListBoxSelection ( evt ) ; } ) ;
2018-02-20 13:25:40 +00:00
popup - > Bind ( wxEVT_KEY_DOWN , [ popup ] ( wxKeyEvent & evt ) { popup - > OnKeyEvent ( evt ) ; } ) ;
popup - > Bind ( wxEVT_KEY_UP , [ popup ] ( wxKeyEvent & evt ) { popup - > OnKeyEvent ( evt ) ; } ) ;
2018-02-02 11:38:35 +00:00
std : : vector < std : : string > items_str ;
boost : : split ( items_str , items , boost : : is_any_of ( " | " ) , boost : : token_compress_off ) ;
for ( const std : : string & item : items_str )
{
2018-02-26 15:23:44 +00:00
popup - > Append ( from_u8 ( item ) ) ;
2018-02-02 11:38:35 +00:00
}
for ( unsigned int i = 0 ; i < popup - > GetCount ( ) ; + + i )
{
popup - > Check ( i , initial_value ) ;
}
}
}
int combochecklist_get_flags ( wxComboCtrl * comboCtrl )
{
int flags = 0 ;
wxCheckListBoxComboPopup * popup = wxDynamicCast ( comboCtrl - > GetPopupControl ( ) , wxCheckListBoxComboPopup ) ;
if ( popup ! = nullptr )
{
for ( unsigned int i = 0 ; i < popup - > GetCount ( ) ; + + i )
{
if ( popup - > IsChecked ( i ) )
2018-02-13 16:46:23 +00:00
flags | = 1 < < i ;
2018-02-02 11:38:35 +00:00
}
}
return flags ;
}
2018-02-22 10:12:29 +00:00
AppConfig * get_app_config ( )
{
return g_AppConfig ;
}
2018-03-06 08:44:53 +00:00
wxString L_str ( const std : : string & str )
2018-02-22 10:34:41 +00:00
{
2018-02-23 08:16:35 +00:00
//! Explicitly specify that the source string is already in UTF-8 encoding
2018-02-22 10:34:41 +00:00
return wxGetTranslation ( wxString ( str . c_str ( ) , wxConvUTF8 ) ) ;
}
2018-03-06 08:44:53 +00:00
wxString from_u8 ( const std : : string & str )
2018-02-22 10:34:41 +00:00
{
return wxString : : FromUTF8 ( str . c_str ( ) ) ;
}
2018-02-07 10:37:15 +00:00
2018-03-09 17:34:30 +00:00
void add_frequently_changed_parameters ( wxWindow * parent , wxBoxSizer * sizer , wxFlexGridSizer * preset_sizer )
{
DynamicPrintConfig * config = & g_PresetBundle - > prints . get_edited_preset ( ) . config ;
m_optgroup = std : : make_shared < ConfigOptionsGroup > ( parent , " " , config ) ;
2018-05-20 21:39:52 +00:00
const wxArrayInt & ar = preset_sizer - > GetColWidths ( ) ;
m_optgroup - > label_width = ar . IsEmpty ( ) ? 100 : ar . front ( ) - 4 ; // doesn't work
2018-03-12 15:52:21 +00:00
m_optgroup - > m_on_change = [ config ] ( t_config_option_key opt_key , boost : : any value ) {
TabPrint * tab_print = nullptr ;
for ( size_t i = 0 ; i < g_wxTabPanel - > GetPageCount ( ) ; + + i ) {
Tab * tab = dynamic_cast < Tab * > ( g_wxTabPanel - > GetPage ( i ) ) ;
if ( ! tab )
continue ;
if ( tab - > name ( ) = = " print " ) {
tab_print = static_cast < TabPrint * > ( tab ) ;
break ;
}
}
if ( tab_print = = nullptr )
return ;
if ( opt_key = = " fill_density " ) {
value = m_optgroup - > get_config_value ( * config , opt_key ) ;
tab_print - > set_value ( opt_key , value ) ;
2018-03-14 09:14:48 +00:00
tab_print - > update ( ) ;
2018-03-12 15:52:21 +00:00
}
2018-03-13 15:14:36 +00:00
else {
DynamicPrintConfig new_conf = * config ;
if ( opt_key = = " brim " ) {
double new_val ;
double brim_width = config - > opt_float ( " brim_width " ) ;
if ( boost : : any_cast < bool > ( value ) = = true )
{
new_val = m_brim_width = = 0.0 ? 10 :
m_brim_width < 0.0 ? m_brim_width * ( - 1 ) :
m_brim_width ;
}
else {
m_brim_width = brim_width * ( - 1 ) ;
new_val = 0 ;
}
new_conf . set_key_value ( " brim_width " , new ConfigOptionFloat ( new_val ) ) ;
}
else { //(opt_key == "support")
const wxString & selection = boost : : any_cast < wxString > ( value ) ;
auto support_material = selection = = _ ( " None " ) ? false : true ;
new_conf . set_key_value ( " support_material " , new ConfigOptionBool ( support_material ) ) ;
if ( selection = = _ ( " Everywhere " ) )
new_conf . set_key_value ( " support_material_buildplate_only " , new ConfigOptionBool ( false ) ) ;
else if ( selection = = _ ( " Support on build plate only " ) )
new_conf . set_key_value ( " support_material_buildplate_only " , new ConfigOptionBool ( true ) ) ;
2018-03-12 15:52:21 +00:00
}
2018-03-13 15:14:36 +00:00
tab_print - > load_config ( new_conf ) ;
2018-03-12 15:52:21 +00:00
}
tab_print - > update_dirty ( ) ;
2018-03-09 17:34:30 +00:00
} ;
2018-03-12 15:52:21 +00:00
Option option = m_optgroup - > get_option ( " fill_density " ) ;
option . opt . sidetext = " " ;
2018-04-25 09:10:34 +00:00
option . opt . full_width = true ;
2018-03-12 15:52:21 +00:00
m_optgroup - > append_single_option_line ( option ) ;
2018-03-09 17:34:30 +00:00
ConfigOptionDef def ;
def . label = L ( " Support " ) ;
2018-03-13 15:14:36 +00:00
def . type = coStrings ;
2018-03-09 17:34:30 +00:00
def . gui_type = " select_open " ;
def . tooltip = L ( " Select what kind of support do you need " ) ;
def . enum_labels . push_back ( L ( " None " ) ) ;
def . enum_labels . push_back ( L ( " Support on build plate only " ) ) ;
def . enum_labels . push_back ( L ( " Everywhere " ) ) ;
2018-03-13 15:14:36 +00:00
std : : string selection = ! config - > opt_bool ( " support_material " ) ?
" None " :
config - > opt_bool ( " support_material_buildplate_only " ) ?
" Support on build plate only " :
" Everywhere " ;
def . default_value = new ConfigOptionStrings { selection } ;
2018-03-12 15:52:21 +00:00
option = Option ( def , " support " ) ;
2018-04-25 09:10:34 +00:00
option . opt . full_width = true ;
2018-03-09 17:34:30 +00:00
m_optgroup - > append_single_option_line ( option ) ;
2018-03-13 15:14:36 +00:00
m_brim_width = config - > opt_float ( " brim_width " ) ;
2018-03-09 17:34:30 +00:00
def . label = L ( " Brim " ) ;
def . type = coBool ;
def . tooltip = L ( " This flag enables the brim that will be printed around each object on the first layer. " ) ;
def . gui_type = " " ;
2018-03-13 15:14:36 +00:00
def . default_value = new ConfigOptionBool { m_brim_width > 0.0 ? true : false } ;
2018-03-09 17:34:30 +00:00
option = Option ( def , " brim " ) ;
m_optgroup - > append_single_option_line ( option ) ;
2018-03-27 11:44:18 +00:00
2018-05-02 11:20:36 +00:00
Line line = { " " , " " } ;
2018-03-27 11:44:18 +00:00
line . widget = [ config ] ( wxWindow * parent ) {
2018-06-07 20:10:23 +00:00
g_wiping_dialog_button = new wxButton ( parent , wxID_ANY , _ ( L ( " Purging volumes " ) ) + dots , wxDefaultPosition , wxDefaultSize , wxBU_EXACTFIT ) ;
2018-03-27 11:44:18 +00:00
auto sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
2018-04-03 20:07:59 +00:00
sizer - > Add ( g_wiping_dialog_button ) ;
2018-04-04 08:18:26 +00:00
g_wiping_dialog_button - > Bind ( wxEVT_BUTTON , ( [ parent ] ( wxCommandEvent & e )
2018-03-27 11:44:18 +00:00
{
2018-04-04 08:18:26 +00:00
auto & config = g_PresetBundle - > project_config ;
2018-08-15 11:51:40 +00:00
const std : : vector < double > & init_matrix = ( config . option < ConfigOptionFloats > ( " wiping_volumes_matrix " ) ) - > values ;
const std : : vector < double > & init_extruders = ( config . option < ConfigOptionFloats > ( " wiping_volumes_extruders " ) ) - > values ;
2018-03-27 11:44:18 +00:00
Removed Point::scale(),translate(),coincides_with(),distance_to(),
distance_to_squared(),perp_distance_to(),negative(),vector_to(),
translate(), distance_to() etc,
replaced with the Eigen equivalents.
2018-08-17 12:14:24 +00:00
WipingDialog dlg ( parent , cast < float > ( init_matrix ) , cast < float > ( init_extruders ) ) ;
2018-03-27 11:44:18 +00:00
if ( dlg . ShowModal ( ) = = wxID_OK ) {
std : : vector < float > matrix = dlg . get_matrix ( ) ;
std : : vector < float > extruders = dlg . get_extruders ( ) ;
2018-04-04 08:18:26 +00:00
( config . option < ConfigOptionFloats > ( " wiping_volumes_matrix " ) ) - > values = std : : vector < double > ( matrix . begin ( ) , matrix . end ( ) ) ;
( config . option < ConfigOptionFloats > ( " wiping_volumes_extruders " ) ) - > values = std : : vector < double > ( extruders . begin ( ) , extruders . end ( ) ) ;
2018-08-01 13:34:33 +00:00
g_on_request_update_callback . call ( ) ;
2018-03-27 11:44:18 +00:00
}
} ) ) ;
return sizer ;
} ;
m_optgroup - > append_line ( line ) ;
2018-04-25 09:10:34 +00:00
sizer - > Add ( m_optgroup - > sizer , 1 , wxEXPAND | wxBOTTOM , 2 ) ;
2018-03-09 17:34:30 +00:00
}
2018-03-12 15:52:21 +00:00
ConfigOptionsGroup * get_optgroup ( )
{
return m_optgroup . get ( ) ;
}
2018-04-04 12:41:23 +00:00
wxButton * get_wiping_dialog_button ( )
{
2018-04-03 20:07:59 +00:00
return g_wiping_dialog_button ;
2018-04-04 12:41:23 +00:00
}
2018-04-04 11:06:46 +00:00
2018-03-22 12:49:48 +00:00
wxWindow * export_option_creator ( wxWindow * parent )
{
wxPanel * panel = new wxPanel ( parent , - 1 ) ;
wxSizer * sizer = new wxBoxSizer ( wxHORIZONTAL ) ;
wxCheckBox * cbox = new wxCheckBox ( panel , wxID_HIGHEST + 1 , L ( " Export print config " ) ) ;
2018-04-25 13:31:37 +00:00
cbox - > SetValue ( true ) ;
2018-03-22 12:49:48 +00:00
sizer - > AddSpacer ( 5 ) ;
sizer - > Add ( cbox , 0 , wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL , 5 ) ;
panel - > SetSizer ( sizer ) ;
sizer - > SetSizeHints ( panel ) ;
return panel ;
}
void add_export_option ( wxFileDialog * dlg , const std : : string & format )
{
if ( ( dlg ! = nullptr ) & & ( format = = " AMF " ) | | ( format = = " 3MF " ) )
{
if ( dlg - > SupportsExtraControl ( ) )
dlg - > SetExtraControlCreator ( export_option_creator ) ;
}
}
int get_export_option ( wxFileDialog * dlg )
{
if ( dlg ! = nullptr )
{
wxWindow * wnd = dlg - > GetExtraControl ( ) ;
if ( wnd ! = nullptr )
{
wxPanel * panel = dynamic_cast < wxPanel * > ( wnd ) ;
if ( panel ! = nullptr )
{
wxWindow * child = panel - > FindWindow ( wxID_HIGHEST + 1 ) ;
if ( child ! = nullptr )
{
wxCheckBox * cbox = dynamic_cast < wxCheckBox * > ( child ) ;
if ( cbox ! = nullptr )
return cbox - > IsChecked ( ) ? 1 : 0 ;
}
}
}
}
return 0 ;
2018-04-04 12:41:23 +00:00
2018-03-22 12:49:48 +00:00
}
2018-06-11 16:24:13 +00:00
void get_current_screen_size ( unsigned & width , unsigned & height )
{
wxDisplay display ( wxDisplay : : GetFromWindow ( g_wxMainFrame ) ) ;
const auto disp_size = display . GetClientArea ( ) ;
width = disp_size . GetWidth ( ) ;
height = disp_size . GetHeight ( ) ;
}
2018-04-09 15:03:37 +00:00
void about ( )
{
AboutDialog dlg ;
dlg . ShowModal ( ) ;
dlg . Destroy ( ) ;
}
2018-05-21 19:04:03 +00:00
void desktop_open_datadir_folder ( )
2018-06-04 07:07:29 +00:00
{
2018-05-21 20:10:38 +00:00
// Execute command to open a file explorer, platform dependent.
2018-06-04 07:07:29 +00:00
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
const auto path = data_dir ( ) ;
2018-05-21 19:04:03 +00:00
# ifdef _WIN32
2018-06-04 07:07:29 +00:00
const auto widepath = wxString : : FromUTF8 ( path . data ( ) ) ;
const wchar_t * argv [ ] = { L " explorer " , widepath . GetData ( ) , nullptr } ;
: : wxExecute ( const_cast < wchar_t * * > ( argv ) , wxEXEC_ASYNC , nullptr ) ;
2018-05-21 19:04:03 +00:00
# elif __APPLE__
2018-06-04 07:07:29 +00:00
const char * argv [ ] = { " open " , path . data ( ) , nullptr } ;
: : wxExecute ( const_cast < char * * > ( argv ) , wxEXEC_ASYNC , nullptr ) ;
2018-05-21 19:04:03 +00:00
# else
2018-06-04 07:07:29 +00:00
const char * argv [ ] = { " xdg-open " , path . data ( ) , nullptr } ;
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if ( wxGetEnv ( " APPIMAGE " , nullptr ) ) {
// We're running from AppImage
wxEnvVariableHashMap env_vars ;
wxGetEnvMap ( & env_vars ) ;
env_vars . erase ( " APPIMAGE " ) ;
env_vars . erase ( " APPDIR " ) ;
env_vars . erase ( " LD_LIBRARY_PATH " ) ;
env_vars . erase ( " LD_PRELOAD " ) ;
env_vars . erase ( " UNION_PRELOAD " ) ;
wxExecuteEnv exec_env ;
exec_env . env = std : : move ( env_vars ) ;
wxString owd ;
if ( wxGetEnv ( " OWD " , & owd ) ) {
// This is the original work directory from which the AppImage image was run,
// set it as CWD for the child process:
exec_env . cwd = std : : move ( owd ) ;
}
: : wxExecute ( const_cast < char * * > ( argv ) , wxEXEC_ASYNC , nullptr , & exec_env ) ;
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
: : wxExecute ( const_cast < char * * > ( argv ) , wxEXEC_ASYNC , nullptr , nullptr ) ;
}
2018-05-21 20:10:38 +00:00
# endif
2018-05-21 19:04:03 +00:00
}
2015-12-04 20:25:45 +00:00
} }