mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_gcode_window
This commit is contained in:
		
						commit
						da7d7ae11b
					
				
					 61 changed files with 6895 additions and 646 deletions
				
			
		|  | @ -39,12 +39,11 @@ | |||
| #ifdef HAS_GLSAFE | ||||
| void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name) | ||||
| { | ||||
| #if defined(NDEBUG) && ENABLE_OPENGL_ERROR_LOGGING | ||||
|     // In release mode, if OpenGL debugging was forced by ENABLE_OPENGL_ERROR_LOGGING, only show
 | ||||
|     // OpenGL errors if sufficiently high loglevel.
 | ||||
| #if defined(NDEBUG) | ||||
|     // In release mode, only show OpenGL errors if sufficiently high loglevel.
 | ||||
|     if (Slic3r::get_logging_level() < 5) | ||||
|         return; | ||||
| #endif // ENABLE_OPENGL_ERROR_LOGGING
 | ||||
| #endif // NDEBUG
 | ||||
| 
 | ||||
|     GLenum err = glGetError(); | ||||
|     if (err == GL_NO_ERROR) | ||||
|  |  | |||
|  | @ -10,10 +10,7 @@ | |||
| 
 | ||||
| #include <functional> | ||||
| 
 | ||||
| #if ENABLE_OPENGL_ERROR_LOGGING || ! defined(NDEBUG) | ||||
|     #define HAS_GLSAFE | ||||
| #endif | ||||
| 
 | ||||
| #define HAS_GLSAFE | ||||
| #ifdef HAS_GLSAFE | ||||
|     extern void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char *function_name); | ||||
|     inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } | ||||
|  |  | |||
|  | @ -629,13 +629,13 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin | |||
|     append(html_window, 0, wxEXPAND); | ||||
| 
 | ||||
| 	list_printer->Bind(wxEVT_LISTBOX, [this](wxCommandEvent& evt) { | ||||
| 		update_lists(evt.GetInt(), list_type->GetSelection(), list_vendor->GetSelection()); | ||||
| 		update_lists(list_type->GetSelection(), list_vendor->GetSelection(), evt.GetInt()); | ||||
| 		}); | ||||
|     list_type->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { | ||||
|         update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection()); | ||||
|         update_lists(list_type->GetSelection(), list_vendor->GetSelection()); | ||||
|     }); | ||||
|     list_vendor->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { | ||||
|         update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection()); | ||||
|         update_lists(list_type->GetSelection(), list_vendor->GetSelection()); | ||||
|     }); | ||||
| 
 | ||||
|     list_profile->Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent &evt) { select_material(evt.GetInt()); }); | ||||
|  | @ -681,8 +681,7 @@ void PageMaterials::reload_presets() | |||
|     sort_list_data(list_printer, true, false); | ||||
|     if (list_printer->GetCount() > 0) { | ||||
|         list_printer->SetSelection(0); | ||||
| 		sel_printer_count_prev = wxNOT_FOUND; | ||||
|         sel_printer_item_prev = wxNOT_FOUND; | ||||
|         sel_printers_prev.Clear(); | ||||
|         sel_type_prev = wxNOT_FOUND; | ||||
|         sel_vendor_prev = wxNOT_FOUND; | ||||
|         update_lists(0, 0, 0); | ||||
|  | @ -812,7 +811,7 @@ void PageMaterials::on_material_highlighted(int sel_material) | |||
|     set_compatible_printers_html_window(names, names.size() == materials->printers.size()); | ||||
| } | ||||
| 
 | ||||
| void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor) | ||||
| void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected_printer/* = -1*/) | ||||
| { | ||||
| 	wxWindowUpdateLocker freeze_guard(this); | ||||
| 	(void)freeze_guard; | ||||
|  | @ -820,7 +819,22 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor) | |||
| 	wxArrayInt sel_printers; | ||||
| 	int sel_printers_count = list_printer->GetSelections(sel_printers); | ||||
| 
 | ||||
| 	if (sel_printers_count != sel_printer_count_prev || (sel_printers_count == 1 && sel_printer_item_prev != sel_printer && sel_printer != -1)) { | ||||
|     // Does our wxWidgets version support operator== for wxArrayInt ?
 | ||||
|     // https://github.com/prusa3d/PrusaSlicer/issues/5152#issuecomment-787208614
 | ||||
| #if wxCHECK_VERSION(3, 1, 1) | ||||
|     if (sel_printers != sel_printers_prev) { | ||||
| #else | ||||
|     auto are_equal = [](const wxArrayInt& arr_first, const wxArrayInt& arr_second) { | ||||
|         if (arr_first.GetCount() != arr_second.GetCount()) | ||||
|             return false; | ||||
|         for (size_t i = 0; i < arr_first.GetCount(); i++) | ||||
|             if (arr_first[i] != arr_second[i]) | ||||
|                 return false; | ||||
|         return true; | ||||
|     }; | ||||
|     if (!are_equal(sel_printers, sel_printers_prev)) { | ||||
| #endif | ||||
| 
 | ||||
|         // Refresh type list
 | ||||
| 		list_type->Clear(); | ||||
| 		list_type->append(_L("(All)"), &EMPTY); | ||||
|  | @ -828,7 +842,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor) | |||
|             // If all is selected with other printers
 | ||||
|             // unselect "all" or all printers depending on last value
 | ||||
|             if (sel_printers[0] == 0 && sel_printers_count > 1) { | ||||
|                 if (sel_printer == 0) { | ||||
|                 if (last_selected_printer == 0) { | ||||
|                     list_printer->SetSelection(wxNOT_FOUND); | ||||
|                     list_printer->SetSelection(0); | ||||
|                 } else { | ||||
|  | @ -869,8 +883,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor) | |||
|             sort_list_data(list_type, true, true); | ||||
| 		} | ||||
| 
 | ||||
| 		sel_printer_count_prev = sel_printers_count; | ||||
|         sel_printer_item_prev = sel_printer; | ||||
| 		sel_printers_prev = sel_printers; | ||||
| 		sel_type = 0; | ||||
| 		sel_type_prev = wxNOT_FOUND; | ||||
| 		list_type->SetSelection(sel_type); | ||||
|  | @ -1089,8 +1102,7 @@ void PageMaterials::clear() | |||
|     list_type->Clear(); | ||||
|     list_vendor->Clear(); | ||||
|     list_profile->Clear(); | ||||
| 	sel_printer_count_prev = wxNOT_FOUND; | ||||
|     sel_printer_item_prev = wxNOT_FOUND; | ||||
| 	sel_printers_prev.Clear(); | ||||
|     sel_type_prev = wxNOT_FOUND; | ||||
|     sel_vendor_prev = wxNOT_FOUND; | ||||
|     presets_loaded = false; | ||||
|  | @ -1189,7 +1201,6 @@ PageReloadFromDisk::PageReloadFromDisk(ConfigWizard* parent) | |||
|     box_pathnames->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->full_pathnames = event.IsChecked(); }); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
| PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent) | ||||
|     : ConfigWizardPage(parent, _L("Files association"), _L("Files association")) | ||||
|  | @ -1203,7 +1214,6 @@ PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent) | |||
| //    append(cb_gcode);
 | ||||
| } | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| PageMode::PageMode(ConfigWizard *parent) | ||||
|     : ConfigWizardPage(parent, _L("View mode"), _L("View mode")) | ||||
|  | @ -1816,11 +1826,9 @@ void ConfigWizard::priv::load_pages() | |||
| 
 | ||||
|     index->add_page(page_update); | ||||
|     index->add_page(page_reload_from_disk); | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
|     index->add_page(page_files_association); | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|     index->add_page(page_mode); | ||||
| 
 | ||||
|     index->go_to(former_active);   // Will restore the active item/page if possible
 | ||||
|  | @ -2414,7 +2422,6 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese | |||
|     app_config->set("preset_update", page_update->preset_update ? "1" : "0"); | ||||
|     app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0"); | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
|     app_config->set("associate_3mf", page_files_association->associate_3mf() ? "1" : "0"); | ||||
|     app_config->set("associate_stl", page_files_association->associate_stl() ? "1" : "0"); | ||||
|  | @ -2432,7 +2439,6 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese | |||
| //    }
 | ||||
| 
 | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
|     page_mode->serialize_mode(app_config); | ||||
| 
 | ||||
|  | @ -2597,11 +2603,9 @@ ConfigWizard::ConfigWizard(wxWindow *parent) | |||
|      | ||||
|     p->add_page(p->page_update   = new PageUpdate(this)); | ||||
|     p->add_page(p->page_reload_from_disk = new PageReloadFromDisk(this)); | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
|     p->add_page(p->page_files_association = new PageFilesAssociation(this)); | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|     p->add_page(p->page_mode     = new PageMode(this)); | ||||
|     p->add_page(p->page_firmware = new PageFirmware(this)); | ||||
|     p->add_page(p->page_bed      = new PageBedShape(this)); | ||||
|  |  | |||
|  | @ -327,7 +327,8 @@ struct PageMaterials: ConfigWizardPage | |||
|     Materials *materials; | ||||
|     StringList *list_printer, *list_type, *list_vendor; | ||||
|     PresetList *list_profile; | ||||
|     int sel_printer_count_prev, sel_printer_item_prev, sel_type_prev, sel_vendor_prev; | ||||
|     wxArrayInt sel_printers_prev; | ||||
|     int sel_type_prev, sel_vendor_prev; | ||||
|     bool presets_loaded; | ||||
| 
 | ||||
|     wxFlexGridSizer *grid; | ||||
|  | @ -342,7 +343,7 @@ struct PageMaterials: ConfigWizardPage | |||
|     PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name); | ||||
| 
 | ||||
|     void reload_presets(); | ||||
| 	void update_lists(int sel1, int sel2, int sel3); | ||||
| 	void update_lists(int sel_type, int sel_vendor, int last_selected_printer = -1); | ||||
| 	void on_material_highlighted(int sel_material); | ||||
|     void on_material_hovered(int sel_material); | ||||
|     void select_material(int i); | ||||
|  | @ -392,7 +393,6 @@ struct PageReloadFromDisk : ConfigWizardPage | |||
|     PageReloadFromDisk(ConfigWizard* parent); | ||||
| }; | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
| struct PageFilesAssociation : ConfigWizardPage | ||||
| { | ||||
|  | @ -409,7 +409,6 @@ public: | |||
| //    bool associate_gcode() const { return cb_gcode->IsChecked(); }
 | ||||
| }; | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| struct PageMode: ConfigWizardPage | ||||
| { | ||||
|  | @ -571,11 +570,9 @@ struct ConfigWizard::priv | |||
|     PageCustom       *page_custom = nullptr; | ||||
|     PageUpdate       *page_update = nullptr; | ||||
|     PageReloadFromDisk *page_reload_from_disk = nullptr; | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
|     PageFilesAssociation* page_files_association = nullptr; | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|     PageMode         *page_mode = nullptr; | ||||
|     PageVendors      *page_vendors = nullptr; | ||||
|     Pages3rdparty     pages_3rdparty; | ||||
|  |  | |||
|  | @ -183,11 +183,13 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsi | |||
|     // use rounding to reduce the number of generated paths
 | ||||
| #if ENABLE_SPLITTED_VERTEX_BUFFER | ||||
|     paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, | ||||
|         round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, | ||||
|         round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), | ||||
|         move.feedrate, move.fan_speed, move.temperature, | ||||
|         move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); | ||||
| #else | ||||
|     paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, | ||||
|         round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, | ||||
|         round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), | ||||
|         move.feedrate, move.fan_speed, move.temperature, | ||||
|         move.volumetric_rate(), move.extruder_id, move.cp_color_id }); | ||||
| #endif // ENABLE_SPLITTED_VERTEX_BUFFER
 | ||||
| } | ||||
|  | @ -654,6 +656,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: | |||
|             m_extrusions.ranges.height.update_from(round_to_nearest(curr.height, 2)); | ||||
|             m_extrusions.ranges.width.update_from(round_to_nearest(curr.width, 2)); | ||||
|             m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); | ||||
|             m_extrusions.ranges.temperature.update_from(curr.temperature); | ||||
|             m_extrusions.ranges.volumetric_rate.update_from(round_to_nearest(curr.volumetric_rate(), 2)); | ||||
|             [[fallthrough]]; | ||||
|         } | ||||
|  | @ -2898,6 +2901,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool | |||
|         case EViewType::Width:          { color = m_extrusions.ranges.width.get_color_at(path.width); break; } | ||||
|         case EViewType::Feedrate:       { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } | ||||
|         case EViewType::FanSpeed:       { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } | ||||
|         case EViewType::Temperature:    { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } | ||||
|         case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } | ||||
|         case EViewType::Tool:           { color = m_tool_colors[path.extruder_id]; break; } | ||||
|         case EViewType::ColorPrint:     { | ||||
|  | @ -3357,6 +3361,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool | |||
|         case EViewType::Width:          { color = m_extrusions.ranges.width.get_color_at(path.width); break; } | ||||
|         case EViewType::Feedrate:       { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } | ||||
|         case EViewType::FanSpeed:       { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } | ||||
|         case EViewType::Temperature:    { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } | ||||
|         case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } | ||||
|         case EViewType::Tool:           { color = m_tool_colors[path.extruder_id]; break; } | ||||
|         case EViewType::ColorPrint:     { | ||||
|  | @ -4191,6 +4196,7 @@ void GCodeViewer::render_legend() const | |||
|     case EViewType::Width:          { imgui.title(_u8L("Width (mm)")); break; } | ||||
|     case EViewType::Feedrate:       { imgui.title(_u8L("Speed (mm/s)")); break; } | ||||
|     case EViewType::FanSpeed:       { imgui.title(_u8L("Fan Speed (%)")); break; } | ||||
|     case EViewType::Temperature:    { imgui.title(_u8L("Temperature (°C)")); break; } | ||||
|     case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } | ||||
|     case EViewType::Tool:           { imgui.title(_u8L("Tool")); break; } | ||||
|     case EViewType::ColorPrint:     { imgui.title(_u8L("Color Print")); break; } | ||||
|  | @ -4225,6 +4231,7 @@ void GCodeViewer::render_legend() const | |||
|     case EViewType::Width:          { append_range(m_extrusions.ranges.width, 3); break; } | ||||
|     case EViewType::Feedrate:       { append_range(m_extrusions.ranges.feedrate, 1); break; } | ||||
|     case EViewType::FanSpeed:       { append_range(m_extrusions.ranges.fan_speed, 0); break; } | ||||
|     case EViewType::Temperature:    { append_range(m_extrusions.ranges.temperature, 0); break; } | ||||
|     case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } | ||||
|     case EViewType::Tool: | ||||
|     { | ||||
|  |  | |||
|  | @ -179,6 +179,7 @@ class GCodeViewer | |||
|         float width{ 0.0f }; | ||||
|         float feedrate{ 0.0f }; | ||||
|         float fan_speed{ 0.0f }; | ||||
|         float temperature{ 0.0f }; | ||||
|         float volumetric_rate{ 0.0f }; | ||||
|         unsigned char extruder_id{ 0 }; | ||||
|         unsigned char cp_color_id{ 0 }; | ||||
|  | @ -407,6 +408,8 @@ class GCodeViewer | |||
|             Range fan_speed; | ||||
|             // Color mapping by volumetric extrusion rate.
 | ||||
|             Range volumetric_rate; | ||||
|             // Color mapping by extrusion temperature.
 | ||||
|             Range temperature; | ||||
| 
 | ||||
|             void reset() { | ||||
|                 height.reset(); | ||||
|  | @ -414,6 +417,7 @@ class GCodeViewer | |||
|                 feedrate.reset(); | ||||
|                 fan_speed.reset(); | ||||
|                 volumetric_rate.reset(); | ||||
|                 temperature.reset(); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|  | @ -654,6 +658,7 @@ public: | |||
|         Width, | ||||
|         Feedrate, | ||||
|         FanSpeed, | ||||
|         Temperature, | ||||
|         VolumetricRate, | ||||
|         Tool, | ||||
|         ColorPrint, | ||||
|  |  | |||
|  | @ -2512,8 +2512,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
| #endif /* __APPLE__ */ | ||||
|             post_event(SimpleEvent(EVT_GLTOOLBAR_COPY)); | ||||
|         break; | ||||
| 
 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #ifdef __APPLE__ | ||||
|         case 'm': | ||||
|         case 'M': | ||||
|  | @ -2532,18 +2530,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
| #endif //_WIN32
 | ||||
|             break; | ||||
|         } | ||||
| #else | ||||
| #if defined(__linux__) || defined(__APPLE__) | ||||
|         case WXK_CONTROL_M: | ||||
|         { | ||||
|             Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller(); | ||||
|             controller.show_settings_dialog(!controller.is_settings_dialog_shown()); | ||||
|             m_dirty = true; | ||||
|             break; | ||||
|         } | ||||
| #endif /* __linux__ */ | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
|         case 'v': | ||||
|         case 'V': | ||||
|  |  | |||
|  | @ -835,14 +835,10 @@ bool GUI_App::on_init_inner() | |||
| 
 | ||||
|     if (is_editor()) { | ||||
| #ifdef __WXMSW__  | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
|         if (app_config->get("associate_3mf") == "1") | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|             associate_3mf_files(); | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
|         if (app_config->get("associate_stl") == "1") | ||||
|             associate_stl_files(); | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| #endif // __WXMSW__
 | ||||
| 
 | ||||
|         preset_updater = new PresetUpdater(); | ||||
|  | @ -858,9 +854,7 @@ bool GUI_App::on_init_inner() | |||
|     } | ||||
|     else { | ||||
| #ifdef __WXMSW__  | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
|         if (app_config->get("associate_gcode") == "1") | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|             associate_gcode_files(); | ||||
| #endif // __WXMSW__
 | ||||
|     } | ||||
|  | @ -1722,7 +1716,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu) | |||
|                 if (dlg.seq_top_layer_only_changed()) | ||||
| #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
 | ||||
|                     this->plater_->refresh_print(); | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
|                 if (is_editor()) { | ||||
|                     if (app_config->get("associate_3mf") == "1") | ||||
|  | @ -1735,7 +1728,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu) | |||
|                         associate_gcode_files(); | ||||
|                 } | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
|             } | ||||
|             if (app_layout_changed) { | ||||
|                 // hide full main_sizer for mainFrame
 | ||||
|  | @ -2303,7 +2295,6 @@ void GUI_App::associate_3mf_files() | |||
|         ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| void GUI_App::associate_stl_files() | ||||
| { | ||||
|     wchar_t app_path[MAX_PATH]; | ||||
|  | @ -2327,7 +2318,6 @@ void GUI_App::associate_stl_files() | |||
|         // notify Windows only when any of the values gets changed
 | ||||
|         ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); | ||||
| } | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| void GUI_App::associate_gcode_files() | ||||
| { | ||||
|  |  | |||
|  | @ -279,13 +279,11 @@ public: | |||
|     bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); } | ||||
|     bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); } | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef __WXMSW__ | ||||
|     void            associate_3mf_files(); | ||||
|     void            associate_stl_files(); | ||||
|     void            associate_gcode_files(); | ||||
| #endif // __WXMSW__
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| private: | ||||
|     bool            on_init_inner(); | ||||
|  | @ -297,13 +295,6 @@ private: | |||
| 
 | ||||
|     bool            config_wizard_startup(); | ||||
| 	void            check_updates(const bool verbose); | ||||
| 
 | ||||
| #if !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef __WXMSW__ | ||||
|     void            associate_3mf_files(); | ||||
|     void            associate_gcode_files(); | ||||
| #endif // __WXMSW__
 | ||||
| #endif // !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| }; | ||||
| 
 | ||||
| DECLARE_APP(GUI_App) | ||||
|  |  | |||
|  | @ -93,6 +93,7 @@ ObjectList::ObjectList(wxWindow* parent) : | |||
|         CATEGORY_ICON[L("Layers and Perimeters")]    = create_scaled_bitmap("layers"); | ||||
|         CATEGORY_ICON[L("Infill")]                   = create_scaled_bitmap("infill"); | ||||
|         CATEGORY_ICON[L("Ironing")]                  = create_scaled_bitmap("ironing"); | ||||
|         CATEGORY_ICON[L("Fuzzy Skin")]               = create_scaled_bitmap("fuzzy_skin"); | ||||
|         CATEGORY_ICON[L("Support material")]         = create_scaled_bitmap("support"); | ||||
|         CATEGORY_ICON[L("Speed")]                    = create_scaled_bitmap("time"); | ||||
|         CATEGORY_ICON[L("Extruders")]                = create_scaled_bitmap("funnel"); | ||||
|  |  | |||
|  | @ -211,6 +211,7 @@ bool Preview::init(wxWindow* parent, Model* model) | |||
|     m_choice_view_type->Append(_L("Width")); | ||||
|     m_choice_view_type->Append(_L("Speed")); | ||||
|     m_choice_view_type->Append(_L("Fan speed")); | ||||
|     m_choice_view_type->Append(_L("Temperature")); | ||||
|     m_choice_view_type->Append(_L("Volumetric flow rate")); | ||||
|     m_choice_view_type->Append(_L("Tool")); | ||||
|     m_choice_view_type->Append(_L("Color Print")); | ||||
|  |  | |||
|  | @ -26,11 +26,7 @@ class wxCheckBox; | |||
| class wxTopLevelWindow; | ||||
| class wxRect; | ||||
| 
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT | ||||
| #define wxVERSION_EQUAL_OR_GREATER_THAN(major, minor, release) ((wxMAJOR_VERSION > major) || ((wxMAJOR_VERSION == major) && (wxMINOR_VERSION > minor)) || ((wxMAJOR_VERSION == major) && (wxMINOR_VERSION == minor) && (wxRELEASE_NUMBER >= release))) | ||||
| #else | ||||
| #define wxVERSION_EQUAL_OR_GREATER_THAN(major, minor, release) 0 | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -99,12 +95,12 @@ public: | |||
| 
 | ||||
|         // Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3).
 | ||||
|         // So, calculate the m_em_unit value from the font size, as before
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && !defined(__WXGTK__) | ||||
| #if !defined(__WXGTK__) | ||||
|         m_em_unit = std::max<size_t>(10, 10.0f * m_scale_factor); | ||||
| #else | ||||
|         // initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
 | ||||
|         m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| #endif // __WXGTK__
 | ||||
| 
 | ||||
| //        recalc_font();
 | ||||
| 
 | ||||
|  | @ -235,11 +231,7 @@ private: | |||
|         m_normal_font = this->GetFont(); | ||||
| 
 | ||||
|         // update em_unit value for new window font
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT | ||||
|         m_em_unit = std::max<int>(10, 10.0f * m_scale_factor); | ||||
| #else | ||||
|         m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| 
 | ||||
|         // rescale missed controls sizes and images
 | ||||
|         on_dpi_changed(suggested_rect); | ||||
|  |  | |||
|  | @ -147,17 +147,11 @@ void KBShortcutsDialog::fill_shortcuts() | |||
|             { "O", L("Zoom out") }, | ||||
|             { "Tab", L("Switch between Editor/Preview") }, | ||||
|             { "Shift+Tab", L("Collapse/Expand the sidebar") }, | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #ifdef _WIN32 | ||||
|             { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog, if enabled") }, | ||||
| #else | ||||
|             { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") }, | ||||
| #endif // _WIN32
 | ||||
| #else | ||||
| #if defined(__linux__) || defined(__APPLE__) | ||||
|             { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") }, | ||||
| #endif // __linux__
 | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| #if ENABLE_RENDER_PICKING_PASS | ||||
|             // Don't localize debugging texts.
 | ||||
|             { "P", "Toggle picking pass texture rendering on/off" }, | ||||
|  |  | |||
|  | @ -549,9 +549,10 @@ void MainFrame::init_tabpanel() | |||
|         wxWindow* panel = m_tabpanel->GetCurrentPage(); | ||||
|         if (panel != nullptr) { | ||||
|             Tab* tab = dynamic_cast<Tab*>(panel); | ||||
|             if (tab && (tab->type() == Preset::TYPE_FILAMENT || tab->type() == Preset::TYPE_PRINTER)) | ||||
|                 if (!tab->validate_custom_gcodes()) | ||||
|                     evt.Veto(); | ||||
|             if (tab != nullptr) | ||||
|                 tab->validate_custom_gcodes(); | ||||
| //            if (tab != nullptr && !tab->validate_custom_gcodes())
 | ||||
| //                evt.Veto();
 | ||||
|         } | ||||
|         }); | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|  | @ -803,11 +804,7 @@ bool MainFrame::can_reslice() const | |||
| 
 | ||||
| void MainFrame::on_dpi_changed(const wxRect& suggested_rect) | ||||
| { | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT | ||||
|     wxGetApp().update_fonts(this); | ||||
| #else | ||||
|     wxGetApp().update_fonts(); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
|     this->SetFont(this->normal_font()); | ||||
| 
 | ||||
|     // update Plater
 | ||||
|  | @ -1848,14 +1845,14 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) | |||
|     if (wxGetApp().is_gcode_viewer()) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) | ||||
| #if defined(__WXMSW__) | ||||
|     // ys_FIXME! temporary workaround for correct font scaling
 | ||||
|     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
 | ||||
|     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
 | ||||
|     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); | ||||
| #else | ||||
|     this->SetFont(wxGetApp().normal_font()); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| #endif // __WXMSW__
 | ||||
|     this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
| 
 | ||||
|     // Load the icon either from the exe, or from the ico file.
 | ||||
|  |  | |||
|  | @ -100,7 +100,6 @@ void Mouse3DController::State::append_button(unsigned int id, size_t /* input_qu | |||
| } | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| static std::string format_device_string(int vid, int pid) | ||||
| { | ||||
|     std::string ret; | ||||
|  | @ -257,7 +256,6 @@ static std::string detect_attached_device() | |||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
| // Called by Win32 HID enumeration callback.
 | ||||
| void Mouse3DController::device_attached(const std::string &device) | ||||
|  | @ -274,7 +272,6 @@ void Mouse3DController::device_attached(const std::string &device) | |||
| 			// Never mind, enumeration will be performed until connected.
 | ||||
| 		    m_wakeup = true; | ||||
| 			m_stop_condition.notify_all(); | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
|             m_device_str = format_device_string(vid, pid); | ||||
|             if (auto it_params = m_params_by_device.find(m_device_str); it_params != m_params_by_device.end()) { | ||||
|                 tbb::mutex::scoped_lock lock(m_params_ui_mutex); | ||||
|  | @ -283,12 +280,10 @@ void Mouse3DController::device_attached(const std::string &device) | |||
|             else | ||||
|                 m_params_by_device[format_device_string(vid, pid)] = Params(); | ||||
|             m_connected = true; | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
|         } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| void Mouse3DController::device_detached(const std::string& device) | ||||
| { | ||||
|     int vid = 0; | ||||
|  | @ -302,7 +297,6 @@ void Mouse3DController::device_detached(const std::string& device) | |||
|     m_device_str = ""; | ||||
|     m_connected = false; | ||||
| } | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
| // Filter out mouse scroll events produced by the 3DConnexion driver.
 | ||||
| bool Mouse3DController::State::process_mouse_wheel() | ||||
|  | @ -415,7 +409,6 @@ bool Mouse3DController::apply(Camera& camera) | |||
|         m_settings_dialog_closed_by_user = false; | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #ifdef _WIN32 | ||||
|     { | ||||
|         tbb::mutex::scoped_lock lock(m_params_ui_mutex); | ||||
|  | @ -425,7 +418,6 @@ bool Mouse3DController::apply(Camera& camera) | |||
|         } | ||||
|     } | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
|     return m_state.apply(m_params, camera); | ||||
| } | ||||
|  | @ -661,7 +653,6 @@ bool Mouse3DController::handle_input(const DataPacketAxis& packet) | |||
| // Initialize the application.
 | ||||
| void Mouse3DController::init() | ||||
| { | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #ifdef _WIN32 | ||||
|     m_device_str = detect_attached_device(); | ||||
|     if (!m_device_str.empty()) { | ||||
|  | @ -670,7 +661,6 @@ void Mouse3DController::init() | |||
|             m_params = m_params_ui = it_params->second; | ||||
|     } | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
| 	assert(! m_thread.joinable()); | ||||
|     if (! m_thread.joinable()) { | ||||
|  | @ -698,12 +688,10 @@ void Mouse3DController::shutdown() | |||
|         m_stop = false; | ||||
| 	} | ||||
| 
 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #ifdef _WIN32 | ||||
|     if (!m_device_str.empty()) | ||||
|         m_params_by_device[m_device_str] = m_params_ui; | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| } | ||||
| 
 | ||||
| // Main routine of the worker thread.
 | ||||
|  | @ -1064,9 +1052,7 @@ bool Mouse3DController::handle_raw_input_win32(const unsigned char *data, const | |||
|         DataPacketRaw packet; | ||||
|     	memcpy(packet.data(), data, packet_length); | ||||
|         handle_packet(packet, packet_length, m_params, m_state); | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
|         m_connected = true; | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|  |  | |||
|  | @ -195,9 +195,7 @@ public: | |||
| 
 | ||||
|     // Called by Win32 HID enumeration callback.
 | ||||
|     void device_attached(const std::string &device); | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
|     void device_detached(const std::string& device); | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
|     // On Windows, the 3DConnexion driver sends out mouse wheel rotation events to an active application
 | ||||
|     // if the application does not register at the driver. This is a workaround to ignore these superfluous
 | ||||
|  |  | |||
|  | @ -14,14 +14,10 @@ | |||
| #include <wx/glcanvas.h> | ||||
| #include <wx/msgdlg.h> | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__ | ||||
| // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 | ||||
| #include <wx/platinfo.h> | ||||
| #endif // __APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| #include "../Utils/MacDarkMode.hpp" | ||||
| #endif // __APPLE__
 | ||||
| 
 | ||||
|  | @ -202,34 +198,26 @@ bool OpenGLManager::s_compressed_textures_supported = false; | |||
| OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown; | ||||
| OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown; | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
| // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 | ||||
| OpenGLManager::OSInfo OpenGLManager::s_os_info; | ||||
| #endif // __APPLE__ 
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
| 
 | ||||
| OpenGLManager::~OpenGLManager() | ||||
| { | ||||
|     m_shaders_manager.shutdown(); | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
|     // This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets
 | ||||
|     // The crash is triggered inside wxGLContext destructor
 | ||||
|     if (s_os_info.major != 10 || s_os_info.minor != 9 || s_os_info.micro != 5) | ||||
|     { | ||||
| #endif //__APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
| 
 | ||||
|         if (m_context != nullptr) | ||||
|             delete m_context; | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
|     } | ||||
| #endif //__APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
| } | ||||
| 
 | ||||
| bool OpenGLManager::init_gl() | ||||
|  | @ -286,14 +274,12 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) | |||
|     if (m_context == nullptr) { | ||||
|         m_context = new wxGLContext(&canvas); | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
|         // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 | ||||
|         s_os_info.major = wxPlatformInfo::Get().GetOSMajorVersion(); | ||||
|         s_os_info.minor = wxPlatformInfo::Get().GetOSMinorVersion(); | ||||
|         s_os_info.micro = wxPlatformInfo::Get().GetOSMicroVersion(); | ||||
| #endif //__APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
|     } | ||||
|     return m_context; | ||||
| } | ||||
|  |  | |||
|  | @ -51,7 +51,6 @@ public: | |||
|         void detect() const; | ||||
|     }; | ||||
| 
 | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
|     // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 | ||||
|     struct OSInfo | ||||
|  | @ -61,7 +60,6 @@ public: | |||
|         int micro{ 0 }; | ||||
|     }; | ||||
| #endif //__APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
| 
 | ||||
| private: | ||||
|     enum class EMultisampleState : unsigned char | ||||
|  | @ -75,12 +73,10 @@ private: | |||
|     wxGLContext* m_context{ nullptr }; | ||||
|     GLShadersManager m_shaders_manager; | ||||
|     static GLInfo s_gl_info; | ||||
| #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 | ||||
| #ifdef __APPLE__  | ||||
|     // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
 | ||||
|     static OSInfo s_os_info; | ||||
| #endif //__APPLE__
 | ||||
| #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
 | ||||
|     static bool s_compressed_textures_supported; | ||||
|     static EMultisampleState s_multisample; | ||||
|     static EFramebufferType s_framebuffers_type; | ||||
|  |  | |||
|  | @ -1931,11 +1931,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     this->q->Bind(EVT_HID_DEVICE_ATTACHED, [this](HIDDeviceAttachedEvent &evt) { | ||||
|     	mouse3d_controller.device_attached(evt.data); | ||||
|         }); | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
|     this->q->Bind(EVT_HID_DEVICE_DETACHED, [this](HIDDeviceAttachedEvent& evt) { | ||||
|         mouse3d_controller.device_detached(evt.data); | ||||
|         }); | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| #endif /* _WIN32 */ | ||||
| 
 | ||||
| 	notification_manager = new NotificationManager(this->q); | ||||
|  | @ -2191,9 +2189,56 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | |||
|                 { | ||||
|                     if (!config.empty()) { | ||||
|                         Preset::normalize(config); | ||||
|                         wxGetApp().preset_bundle->load_config_model(filename.string(), std::move(config)); | ||||
|                         PresetBundle* preset_bundle = wxGetApp().preset_bundle; | ||||
|                         preset_bundle->load_config_model(filename.string(), std::move(config)); | ||||
|                         { | ||||
|                             // After loading of the presets from project, check if they are visible.
 | ||||
|                             // Set them to visible if they are not.
 | ||||
| 
 | ||||
|                             auto update_selected_preset_visibility = [](PresetCollection& presets, std::vector<std::string>& names) { | ||||
|                                 if (!presets.get_selected_preset().is_visible) { | ||||
|                                     assert(presets.get_selected_preset().name == presets.get_edited_preset().name); | ||||
|                                     presets.get_selected_preset().is_visible = true; | ||||
|                                     presets.get_edited_preset().is_visible = true; | ||||
|                                     names.emplace_back(presets.get_selected_preset().name); | ||||
|                                 } | ||||
|                             }; | ||||
| 
 | ||||
|                             std::vector<std::string> names; | ||||
|                             if (printer_technology == ptFFF) { | ||||
|                                 update_selected_preset_visibility(preset_bundle->prints, names); | ||||
|                                 for (const std::string& filament : preset_bundle->filament_presets) { | ||||
|                                     Preset* preset = preset_bundle->filaments.find_preset(filament); | ||||
|                                     if (preset && !preset->is_visible) { | ||||
|                                         preset->is_visible = true; | ||||
|                                         names.emplace_back(preset->name); | ||||
|                                         if (preset->name == preset_bundle->filaments.get_edited_preset().name) | ||||
|                                             preset_bundle->filaments.get_selected_preset().is_visible = true; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             else { | ||||
|                                 update_selected_preset_visibility(preset_bundle->sla_prints, names); | ||||
|                                 update_selected_preset_visibility(preset_bundle->sla_materials, names); | ||||
|                             } | ||||
|                             update_selected_preset_visibility(preset_bundle->printers, names); | ||||
| 
 | ||||
|                             preset_bundle->update_compatible(PresetSelectCompatibleType::Never); | ||||
| 
 | ||||
|                             // show notification about temporary instaled presets
 | ||||
|                             if (!names.empty()) { | ||||
|                                 std::string notif_text = into_u8(_L_PLURAL("The preset below was temporary instaled on active instance of PrusaSlicer", | ||||
|                                                                            "The presets below were temporary instaled on active instance of PrusaSlicer", names.size())) + ":"; | ||||
|                                 for (std::string& name : names) | ||||
|                                     notif_text += "\n - " + name; | ||||
|                                 notification_manager->push_notification(NotificationType::CustomNotification, | ||||
|                                     NotificationManager::NotificationLevel::RegularNotification, notif_text); | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         if (printer_technology == ptFFF) | ||||
|                             CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &wxGetApp().preset_bundle->project_config); | ||||
|                             CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config); | ||||
| 
 | ||||
|                         // For exporting from the amf/3mf we shouldn't check printer_presets for the containing information about "Print Host upload"
 | ||||
|                         wxGetApp().load_current_presets(false); | ||||
|                         // Update filament colors for the MM-printer profile in the full config 
 | ||||
|  | @ -3346,16 +3391,14 @@ void Plater::priv::set_current_panel(wxPanel* panel) | |||
| 
 | ||||
| void Plater::priv::on_select_preset(wxCommandEvent &evt) | ||||
| { | ||||
|     auto preset_type = static_cast<Preset::Type>(evt.GetInt()); | ||||
|     auto *combo = static_cast<PlaterPresetComboBox*>(evt.GetEventObject()); | ||||
|     PlaterPresetComboBox* combo = static_cast<PlaterPresetComboBox*>(evt.GetEventObject()); | ||||
|     Preset::Type preset_type    = combo->get_type(); | ||||
| 
 | ||||
|     // see https://github.com/prusa3d/PrusaSlicer/issues/3889
 | ||||
|     // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender"),
 | ||||
|     // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
 | ||||
|     // So, use GetSelection() from event parameter 
 | ||||
|     // But in this function we couldn't use evt.GetSelection(), because m_commandInt is used for preset_type
 | ||||
|     // Thus, get selection in this way:
 | ||||
|     int selection = combo->FindString(evt.GetString(), true); | ||||
|     int selection = evt.GetSelection(); | ||||
| 
 | ||||
|     auto idx = combo->get_extruder_idx(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -106,7 +106,6 @@ void PreferencesDialog::build() | |||
| 		option = Option(def, "export_sources_full_pathnames"); | ||||
| 		m_optgroup_general->append_single_option_line(option); | ||||
| 
 | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
| 		// Please keep in sync with ConfigWizard
 | ||||
| 		def.label = L("Associate .3mf files to PrusaSlicer"); | ||||
|  | @ -123,7 +122,6 @@ void PreferencesDialog::build() | |||
| 		option = Option(def, "associate_stl"); | ||||
| 		m_optgroup_general->append_single_option_line(option); | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| 		// Please keep in sync with ConfigWizard
 | ||||
| 		def.label = L("Update built-in Presets automatically"); | ||||
|  | @ -184,7 +182,6 @@ void PreferencesDialog::build() | |||
| 		option = Option(def, "default_action_on_select_preset"); | ||||
| 		m_optgroup_general->append_single_option_line(option); | ||||
| 	} | ||||
| #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN | ||||
| #ifdef _WIN32 | ||||
| 	else { | ||||
| 		def.label = L("Associate .gcode files to PrusaSlicer G-code Viewer"); | ||||
|  | @ -195,7 +192,6 @@ void PreferencesDialog::build() | |||
| 		m_optgroup_general->append_single_option_line(option); | ||||
| 	} | ||||
| #endif // _WIN32
 | ||||
| #endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
 | ||||
| 
 | ||||
| #if __APPLE__ | ||||
| 	def.label = L("Use Retina resolution for the 3D scene"); | ||||
|  | @ -215,7 +211,6 @@ void PreferencesDialog::build() | |||
| 	option = Option(def, "show_splash_screen"); | ||||
| 	m_optgroup_general->append_single_option_line(option); | ||||
| 
 | ||||
| #if ENABLE_CTRL_M_ON_WINDOWS | ||||
| #if defined(_WIN32) || defined(__APPLE__) | ||||
| 	def.label = L("Enable support for legacy 3DConnexion devices"); | ||||
| 	def.type = coBool; | ||||
|  | @ -224,7 +219,6 @@ void PreferencesDialog::build() | |||
| 	option = Option(def, "use_legacy_3DConnexion"); | ||||
| 	m_optgroup_general->append_single_option_line(option); | ||||
| #endif // _WIN32 || __APPLE__
 | ||||
| #endif // ENABLE_CTRL_M_ON_WINDOWS
 | ||||
| 
 | ||||
| 	activate_options_tab(m_optgroup_general); | ||||
| 
 | ||||
|  |  | |||
|  | @ -121,23 +121,26 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const | |||
|     Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_suppress_change = false; }); | ||||
|     Bind(wxEVT_COMBOBOX_CLOSEUP,  [this](wxCommandEvent&) { m_suppress_change = true;  }); | ||||
| 
 | ||||
|     Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { | ||||
|         // see https://github.com/prusa3d/PrusaSlicer/issues/3889
 | ||||
|         // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
 | ||||
|         // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
 | ||||
|         // So, use GetSelection() from event parameter 
 | ||||
|         auto selected_item = evt.GetSelection(); | ||||
|     Bind(wxEVT_COMBOBOX, &PresetComboBox::OnSelect, this); | ||||
| } | ||||
| 
 | ||||
|         auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|         if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) | ||||
|             this->SetSelection(this->m_last_selected); | ||||
|         else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) { | ||||
|             m_last_selected = selected_item; | ||||
|             on_selection_changed(selected_item); | ||||
|             evt.StopPropagation(); | ||||
|         } | ||||
|         evt.Skip(); | ||||
|     }); | ||||
| void PresetComboBox::OnSelect(wxCommandEvent& evt) | ||||
| { | ||||
|     // see https://github.com/prusa3d/PrusaSlicer/issues/3889
 | ||||
|     // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
 | ||||
|     // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
 | ||||
|     // So, use GetSelection() from event parameter 
 | ||||
|     auto selected_item = evt.GetSelection(); | ||||
| 
 | ||||
|     auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|     if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) | ||||
|         this->SetSelection(this->m_last_selected); | ||||
|     else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) { | ||||
|         m_last_selected = selected_item; | ||||
|         on_selection_changed(selected_item); | ||||
|         evt.StopPropagation(); | ||||
|     } | ||||
|     evt.Skip(); | ||||
| } | ||||
| 
 | ||||
| PresetComboBox::~PresetComboBox() | ||||
|  | @ -602,34 +605,6 @@ void PresetComboBox::OnDrawItem(wxDC& dc, | |||
| PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type) : | ||||
|     PresetComboBox(parent, preset_type, wxSize(15 * wxGetApp().em_unit(), -1)) | ||||
| { | ||||
|     Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) { | ||||
|         auto selected_item = evt.GetSelection(); | ||||
| 
 | ||||
|         auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|         if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) { | ||||
|             this->SetSelection(this->m_last_selected); | ||||
|             evt.StopPropagation(); | ||||
|             if (marker == LABEL_ITEM_WIZARD_PRINTERS) | ||||
|                 show_add_menu(); | ||||
|             else | ||||
|             { | ||||
|                 ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME; | ||||
|                 switch (marker) { | ||||
|                 case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break; | ||||
|                 case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break; | ||||
|                 default: break; | ||||
|                 } | ||||
|                 wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); }); | ||||
|             } | ||||
|         } else if (marker == LABEL_ITEM_PHYSICAL_PRINTER || this->m_last_selected != selected_item || m_collection->current_is_dirty() ) { | ||||
|             this->m_last_selected = selected_item; | ||||
|             evt.SetInt(this->m_type); | ||||
|             evt.Skip(); | ||||
|         } else { | ||||
|             evt.StopPropagation(); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     if (m_type == Preset::TYPE_FILAMENT) | ||||
|     { | ||||
|         Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) { | ||||
|  | @ -717,6 +692,35 @@ PlaterPresetComboBox::~PlaterPresetComboBox() | |||
|         edit_btn->Destroy(); | ||||
| } | ||||
| 
 | ||||
| void PlaterPresetComboBox::OnSelect(wxCommandEvent &evt) | ||||
| { | ||||
|     auto selected_item = evt.GetSelection(); | ||||
| 
 | ||||
|     auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|     if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) { | ||||
|         this->SetSelection(this->m_last_selected); | ||||
|         evt.StopPropagation(); | ||||
|         if (marker == LABEL_ITEM_MARKER) | ||||
|             return; | ||||
|         if (marker == LABEL_ITEM_WIZARD_PRINTERS) | ||||
|             show_add_menu(); | ||||
|         else { | ||||
|             ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME; | ||||
|             switch (marker) { | ||||
|             case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break; | ||||
|             case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break; | ||||
|             default: break; | ||||
|             } | ||||
|             wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); }); | ||||
|         } | ||||
|         return; | ||||
|     } | ||||
|     else if (marker == LABEL_ITEM_PHYSICAL_PRINTER || this->m_last_selected != selected_item || m_collection->current_is_dirty()) | ||||
|         this->m_last_selected = selected_item; | ||||
|          | ||||
|     evt.Skip(); | ||||
| } | ||||
| 
 | ||||
| bool PlaterPresetComboBox::switch_to_tab() | ||||
| { | ||||
|     Tab* tab = wxGetApp().get_tab(m_type); | ||||
|  | @ -895,7 +899,7 @@ void PlaterPresetComboBox::update() | |||
|             for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { | ||||
|                 for (const std::string& preset_name : it->get_preset_names()) { | ||||
|                     Preset* preset = m_collection->find_preset(preset_name); | ||||
|                     if (!preset) | ||||
|                     if (!preset || !preset->is_visible) | ||||
|                         continue; | ||||
|                     std::string main_icon_name, bitmap_key = main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; | ||||
|                     wxBitmap* bmp = get_bmp(main_icon_name, wide_icons, main_icon_name); | ||||
|  | @ -957,40 +961,42 @@ void PlaterPresetComboBox::msw_rescale() | |||
| TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) : | ||||
|     PresetComboBox(parent, preset_type, wxSize(35 * wxGetApp().em_unit(), -1)) | ||||
| { | ||||
|     Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { | ||||
|         // see https://github.com/prusa3d/PrusaSlicer/issues/3889
 | ||||
|         // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
 | ||||
|         // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
 | ||||
|         // So, use GetSelection() from event parameter 
 | ||||
|         auto selected_item = evt.GetSelection(); | ||||
| } | ||||
| 
 | ||||
|         auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|         if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) { | ||||
|             this->SetSelection(this->m_last_selected); | ||||
|             if (marker == LABEL_ITEM_WIZARD_PRINTERS) | ||||
|                 wxTheApp->CallAfter([this]() { | ||||
|                 wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); | ||||
| void TabPresetComboBox::OnSelect(wxCommandEvent &evt) | ||||
| { | ||||
|     // see https://github.com/prusa3d/PrusaSlicer/issues/3889
 | ||||
|     // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
 | ||||
|     // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
 | ||||
|     // So, use GetSelection() from event parameter 
 | ||||
|     auto selected_item = evt.GetSelection(); | ||||
| 
 | ||||
|                 // update combobox if its parent is a PhysicalPrinterDialog
 | ||||
|                 PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent()); | ||||
|                 if (parent != nullptr) | ||||
|                     update(); | ||||
|             }); | ||||
|         } | ||||
|         else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty()) ) { | ||||
|             m_last_selected = selected_item; | ||||
|             on_selection_changed(selected_item); | ||||
|         } | ||||
|     auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item)); | ||||
|     if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) { | ||||
|         this->SetSelection(this->m_last_selected); | ||||
|         if (marker == LABEL_ITEM_WIZARD_PRINTERS) | ||||
|             wxTheApp->CallAfter([this]() { | ||||
|             wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); | ||||
| 
 | ||||
|         evt.StopPropagation(); | ||||
|             // update combobox if its parent is a PhysicalPrinterDialog
 | ||||
|             PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent()); | ||||
|             if (parent != nullptr) | ||||
|                 update(); | ||||
|         }); | ||||
|     } | ||||
|     else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) { | ||||
|         m_last_selected = selected_item; | ||||
|         on_selection_changed(selected_item); | ||||
|     } | ||||
| 
 | ||||
|     evt.StopPropagation(); | ||||
| #ifdef __WXMSW__ | ||||
|         // From the Win 2004 preset combobox lose a focus after change the preset selection
 | ||||
|         // and that is why the up/down arrow doesn't work properly
 | ||||
|         // (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
 | ||||
|         // So, set the focus to the combobox explicitly
 | ||||
|         this->SetFocus(); | ||||
| #endif     | ||||
|     }); | ||||
|     // From the Win 2004 preset combobox lose a focus after change the preset selection
 | ||||
|     // and that is why the up/down arrow doesn't work properly
 | ||||
|     // (see https://github.com/prusa3d/PrusaSlicer/issues/5531 ).
 | ||||
|     // So, set the focus to the combobox explicitly
 | ||||
|     this->SetFocus(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| wxString TabPresetComboBox::get_preset_name(const Preset& preset) | ||||
|  | @ -1080,7 +1086,7 @@ void TabPresetComboBox::update() | |||
|             for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { | ||||
|                 for (const std::string& preset_name : it->get_preset_names()) { | ||||
|                     Preset* preset = m_collection->find_preset(preset_name); | ||||
|                     if (!preset) | ||||
|                     if (!preset || !preset->is_visible) | ||||
|                         continue; | ||||
|                     std::string main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; | ||||
| 
 | ||||
|  |  | |||
|  | @ -71,6 +71,7 @@ public: | |||
|     void             show_all(bool show_all); | ||||
|     virtual void update(); | ||||
|     virtual void msw_rescale(); | ||||
|     virtual void OnSelect(wxCommandEvent& evt); | ||||
| 
 | ||||
| protected: | ||||
|     typedef std::size_t Marker; | ||||
|  | @ -167,6 +168,7 @@ public: | |||
|     wxString get_preset_name(const Preset& preset) override; | ||||
|     void update() override; | ||||
|     void msw_rescale() override; | ||||
|     void OnSelect(wxCommandEvent& evt) override; | ||||
| 
 | ||||
| private: | ||||
|     int     m_extruder_idx = -1; | ||||
|  | @ -193,6 +195,7 @@ public: | |||
|     void update() override; | ||||
|     void update_dirty(); | ||||
|     void msw_rescale() override; | ||||
|     void OnSelect(wxCommandEvent& evt) override; | ||||
| 
 | ||||
|     void set_enable_all(bool enable=true) { m_enable_all = enable; } | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,12 +209,12 @@ SavePresetDialog::~SavePresetDialog() | |||
| void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix) | ||||
| { | ||||
|     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) | ||||
| #if defined(__WXMSW__) | ||||
|     // ys_FIXME! temporary workaround for correct font scaling
 | ||||
|     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
 | ||||
|     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
 | ||||
|     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| #endif // __WXMSW__
 | ||||
| 
 | ||||
|     if (suffix.empty()) | ||||
|         suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName"); | ||||
|  |  | |||
|  | @ -1732,10 +1732,10 @@ bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode) | |||
|     return !invalid; | ||||
| } | ||||
| 
 | ||||
| static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const boost::any& value) { | ||||
| static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const t_config_option_key& opt_key, const boost::any& value) { | ||||
|     Tab::validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(value)); | ||||
|     tab->update_dirty(); | ||||
|     tab->update(); | ||||
|     tab->on_value_change(opt_key, value); | ||||
| } | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
| 
 | ||||
|  | @ -1964,7 +1964,7 @@ void TabFilament::build() | |||
|         optgroup = page->new_optgroup(L("Start G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, value); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("start_filament_gcode"); | ||||
|  | @ -1976,7 +1976,7 @@ void TabFilament::build() | |||
|         optgroup = page->new_optgroup(L("End G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, value); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("end_filament_gcode"); | ||||
|  | @ -2273,17 +2273,11 @@ void TabPrinter::build_fff() | |||
| 
 | ||||
|     const int gcode_field_height = 15; // 150
 | ||||
|     const int notes_field_height = 25; // 250
 | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|     // WARNING !!
 | ||||
|     // if you are going to change any of the following optgroup/option titles
 | ||||
|     // or to add/remove optgroups/options
 | ||||
|     // update also TabPrinter::validate_custom_gcodes()
 | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|     page = add_options_page(L("Custom G-code"), "cog"); | ||||
|         optgroup = page->new_optgroup(L("Start G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("start_gcode"); | ||||
|  | @ -2295,7 +2289,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("End G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("end_gcode"); | ||||
|  | @ -2307,7 +2301,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Before layer change G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("before_layer_gcode"); | ||||
|  | @ -2319,7 +2313,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("After layer change G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("layer_gcode"); | ||||
|  | @ -2331,7 +2325,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Tool change G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("toolchange_gcode"); | ||||
|  | @ -2343,7 +2337,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("between_objects_gcode"); | ||||
|  | @ -2355,7 +2349,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Color Change G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("color_change_gcode"); | ||||
|  | @ -2366,7 +2360,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Pause Print G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("pause_print_gcode"); | ||||
|  | @ -2377,7 +2371,7 @@ void TabPrinter::build_fff() | |||
|         optgroup = page->new_optgroup(L("Template Custom G-code"), 0); | ||||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
|         optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { | ||||
|             validate_custom_gcode_cb(this, optgroup, boost::any_cast<std::string>(value)); | ||||
|             validate_custom_gcode_cb(this, optgroup, opt_key, value); | ||||
|         }; | ||||
| #endif // ENABLE_VALIDATE_CUSTOM_GCODE
 | ||||
|         option = optgroup->get_option("template_custom_gcode"); | ||||
|  | @ -3832,15 +3826,35 @@ void TabPrinter::apply_extruder_cnt_from_cache() | |||
| #if ENABLE_VALIDATE_CUSTOM_GCODE | ||||
| bool Tab::validate_custom_gcodes() | ||||
| { | ||||
|     if (m_type != Preset::TYPE_FILAMENT && | ||||
|         (m_type != Preset::TYPE_PRINTER || static_cast<TabPrinter*>(this)->m_printer_technology != ptFFF)) | ||||
|         return true; | ||||
|     if (m_active_page->title() != L("Custom G-code")) | ||||
|         return true; | ||||
| 
 | ||||
|     bool valid = true; | ||||
|     if ((m_type == Preset::TYPE_FILAMENT ||  | ||||
|         m_type == Preset::TYPE_PRINTER && static_cast<TabPrinter*>(this)->m_printer_technology == ptFFF) && | ||||
|         m_active_page->title() == "Custom G-code") { | ||||
|             for (auto opt_group : m_active_page->m_optgroups) { | ||||
|                 assert(opt_group->opt_map().size() == 1); | ||||
|                 std::string key = opt_group->opt_map().begin()->first; | ||||
|                 valid &= validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(opt_group->get_value(key))); | ||||
|             } | ||||
|     for (auto opt_group : m_active_page->m_optgroups) { | ||||
|         assert(opt_group->opt_map().size() == 1); | ||||
|         std::string key = opt_group->opt_map().begin()->first; | ||||
|         std::string value = boost::any_cast<std::string>(opt_group->get_value(key)); | ||||
|         std::string config_value = m_config->opt_string(key); | ||||
|         valid &= validate_custom_gcode(opt_group->title, value); | ||||
|         Field* field = opt_group->get_field(key); | ||||
|         TextCtrl* text_ctrl = dynamic_cast<TextCtrl*>(field); | ||||
|         if (text_ctrl != nullptr && text_ctrl->m_on_change != nullptr && !text_ctrl->m_disable_change_event) { | ||||
|             Slic3r::GUI::t_change callback = opt_group->m_on_change; | ||||
|             // temporary disable the opt_group->m_on_change callback to avoid multiple validations
 | ||||
|             opt_group->m_on_change = nullptr; | ||||
|             text_ctrl->m_on_change(key, value); | ||||
|             // restore the opt_group->m_on_change callback
 | ||||
|             opt_group->m_on_change = callback; | ||||
| 
 | ||||
|             update_dirty(); | ||||
|             on_value_change(key, value); | ||||
|         } | ||||
| 
 | ||||
|         if (!valid) | ||||
|             break; | ||||
|     } | ||||
|     return valid; | ||||
| } | ||||
|  |  | |||
|  | @ -601,7 +601,7 @@ void DiffViewCtrl::AppendBmpTextColumn(const wxString& label, unsigned model_col | |||
| #ifdef SUPPORTS_MARKUP | ||||
|     rd->EnableMarkup(true); | ||||
| #endif | ||||
|     wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); | ||||
|     wxDataViewColumn* column = new wxDataViewColumn(label, rd, model_column, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); | ||||
| #else | ||||
|     wxDataViewColumn* column = new wxDataViewColumn(label, new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), model_column, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE); | ||||
| #endif //__linux__
 | ||||
|  | @ -792,12 +792,12 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_ | |||
|     wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); | ||||
|     SetBackgroundColour(bgr_clr); | ||||
| 
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) | ||||
| #if defined(__WXMSW__) | ||||
|     // ys_FIXME! temporary workaround for correct font scaling
 | ||||
|     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
 | ||||
|     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
 | ||||
|     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| #endif // __WXMSW__
 | ||||
| 
 | ||||
|     int border = 10; | ||||
|     int em = em_unit(); | ||||
|  | @ -806,7 +806,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_ | |||
|     m_action_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); | ||||
| 
 | ||||
|     m_tree = new DiffViewCtrl(this, wxSize(em * 60, em * 30)); | ||||
|     m_tree->AppendToggleColumn_(L"\u2714"      , DiffModel::colToggle, wxLinux ? 8 : 6); | ||||
|     m_tree->AppendToggleColumn_(L"\u2714"      , DiffModel::colToggle, wxLinux ? 9 : 6); | ||||
|     m_tree->AppendBmpTextColumn(""             , DiffModel::colIconText, 28); | ||||
|     m_tree->AppendBmpTextColumn(_L("Old Value"), DiffModel::colOldValue, 12); | ||||
|     m_tree->AppendBmpTextColumn(_L("New Value"), DiffModel::colNewValue, 12); | ||||
|  | @ -1375,12 +1375,12 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) | |||
|     wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); | ||||
|     SetBackgroundColour(bgr_clr); | ||||
| 
 | ||||
| #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) | ||||
| #if defined(__WXMSW__) | ||||
|     // ys_FIXME! temporary workaround for correct font scaling
 | ||||
|     // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
 | ||||
|     // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT
 | ||||
|     this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); | ||||
| #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT
 | ||||
| #endif // __WXMSW__
 | ||||
| 
 | ||||
|     int border = 10; | ||||
|     int em = em_unit(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966