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/Slic3r
This commit is contained in:
		
						commit
						6b72c16985
					
				
					 32 changed files with 1295 additions and 1093 deletions
				
			
		
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -213,7 +213,7 @@ void PrintConfigDef::init_fff_params() | |||
| 
 | ||||
|     def = this->add("clip_multipart_objects", coBool); | ||||
|     def->label = L("Clip multi-part objects"); | ||||
|     def->tooltip = L("When printing multi-material objects, this settings will make slic3r " | ||||
|     def->tooltip = L("When printing multi-material objects, this settings will make Slic3r " | ||||
|                    "to clip the overlapping object parts one by the other " | ||||
|                    "(2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc)."); | ||||
|     def->mode = comExpert; | ||||
|  | @ -2266,7 +2266,7 @@ void PrintConfigDef::init_sla_params() | |||
|     def->tooltip  = L("Printer scaling correction"); | ||||
|     def->min = 0; | ||||
|     def->mode = comExpert; | ||||
|     def->default_value = new ConfigOptionFloats( { 1., 1., 1. } ); | ||||
|     def->default_value = new ConfigOptionFloats( { 1., 1. } ); | ||||
|      | ||||
|     def = this->add("absolute_correction", coFloat); | ||||
|     def->label = L("Printer absolute correction"); | ||||
|  | @ -2323,7 +2323,7 @@ void PrintConfigDef::init_sla_params() | |||
|     def->tooltip  = L("Correction for expansion"); | ||||
|     def->min = 0; | ||||
|     def->mode = comExpert; | ||||
|     def->default_value = new ConfigOptionFloats( { 1. , 1., 1. } ); | ||||
|     def->default_value = new ConfigOptionFloats( { 1. , 1. } ); | ||||
| 
 | ||||
|     def = this->add("material_notes", coString); | ||||
|     def->label = L("SLA print material notes"); | ||||
|  |  | |||
|  | @ -248,20 +248,21 @@ RawBytes Raster::save(Raster::Compression comp) | |||
| { | ||||
|     assert(m_impl); | ||||
| 
 | ||||
|     std::uint8_t *ptr = nullptr; size_t s = 0; | ||||
|     std::vector<std::uint8_t> data; size_t s = 0; | ||||
| 
 | ||||
|     switch(comp) { | ||||
|     case Compression::PNG: { | ||||
| 
 | ||||
|         void *rawdata = tdefl_write_image_to_png_file_in_memory( | ||||
|                     m_impl->buffer().data(), | ||||
|                     int(resolution().width_px), | ||||
|                     int(resolution().height_px), 1, &s); | ||||
| 
 | ||||
|         if(rawdata == nullptr) break; | ||||
|         auto ptr = static_cast<std::uint8_t*>(rawdata); | ||||
|          | ||||
|         ptr = static_cast<std::uint8_t*>(rawdata); | ||||
|         data.reserve(s); std::copy(ptr, ptr + s, std::back_inserter(data)); | ||||
|          | ||||
|         MZ_FREE(rawdata); | ||||
|         break; | ||||
|     } | ||||
|     case Compression::RAW: { | ||||
|  | @ -270,21 +271,19 @@ RawBytes Raster::save(Raster::Compression comp) | |||
|                 std::to_string(m_impl->resolution().height_px) + " " + "255 "; | ||||
| 
 | ||||
|         auto sz = m_impl->buffer().size()*sizeof(Impl::TBuffer::value_type); | ||||
| 
 | ||||
|         s = sz + header.size(); | ||||
|         ptr = static_cast<std::uint8_t*>(MZ_MALLOC(s)); | ||||
|          | ||||
|         data.reserve(s); | ||||
|          | ||||
|         auto buff = reinterpret_cast<std::uint8_t*>(m_impl->buffer().data()); | ||||
|         std::copy(buff, buff+sz, ptr + header.size()); | ||||
|         std::copy(header.begin(), header.end(), std::back_inserter(data)); | ||||
|         std::copy(buff, buff+sz, std::back_inserter(data)); | ||||
|          | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
| 
 | ||||
|     return {ptr, s}; | ||||
| } | ||||
| 
 | ||||
| void RawBytes::MinzDeleter::operator()(uint8_t *rawptr) | ||||
| { | ||||
|     MZ_FREE(rawptr); | ||||
|     return {std::move(data)}; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -15,17 +15,11 @@ class ExPolygon; | |||
| // Raw byte buffer paired with its size. Suitable for compressed PNG data.
 | ||||
| class RawBytes { | ||||
| 
 | ||||
|     class MinzDeleter { | ||||
|     public: | ||||
|         void operator()(std::uint8_t *rawptr); | ||||
|     }; | ||||
| 
 | ||||
|     std::vector<std::uint8_t> m_buffer; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     RawBytes() = default; | ||||
|     RawBytes(std::uint8_t *rawptr, size_t s): m_buffer(rawptr, rawptr + s) { MinzDeleter()(rawptr); } | ||||
|     RawBytes(std::vector<std::uint8_t>&& data): m_buffer(std::move(data)) {} | ||||
|      | ||||
|     size_t size() const { return m_buffer.size(); } | ||||
|     const uint8_t * data() { return m_buffer.data(); } | ||||
|  |  | |||
|  | @ -847,6 +847,16 @@ public: | |||
|         return model_height; | ||||
|     } | ||||
|      | ||||
|     // Intended to be called after the generation is fully complete
 | ||||
|     void clear_support_data() { | ||||
|         merged_mesh(); // in case the mesh is not generated, it should be...
 | ||||
|         m_heads.clear(); | ||||
|         m_pillars.clear(); | ||||
|         m_junctions.clear(); | ||||
|         m_bridges.clear(); | ||||
|         m_compact_bridges.clear(); | ||||
|     } | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| // This function returns the position of the centroid in the input 'clust'
 | ||||
|  | @ -2285,6 +2295,7 @@ SLASupportTree::SLASupportTree(const std::vector<SupportPoint> &points, | |||
| { | ||||
|     m_impl->ground_level = emesh.ground_level() - cfg.object_elevation_mm; | ||||
|     generate(points, emesh, cfg, ctl); | ||||
|     m_impl->clear_support_data(); | ||||
| } | ||||
| 
 | ||||
| SLASupportTree::SLASupportTree(const SLASupportTree &c): | ||||
|  |  | |||
|  | @ -437,6 +437,12 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf | |||
|             update_apply_status(false); | ||||
|     } | ||||
|      | ||||
|     if(m_objects.empty()) { | ||||
|         m_printer.release(); | ||||
|         m_printer_input.clear(); | ||||
|         m_print_statistics.clear(); | ||||
|     } | ||||
| 
 | ||||
| #ifdef _DEBUG | ||||
|     check_model_ids_equal(m_model, model); | ||||
| #endif /* _DEBUG */ | ||||
|  | @ -668,8 +674,8 @@ void SLAPrint::process() | |||
| 
 | ||||
|     // Slicing the model object. This method is oversimplified and needs to
 | ||||
|     // be compared with the fff slicing algorithm for verification
 | ||||
|     auto slice_model = [this, ilhs, ilh](SLAPrintObject& po) { | ||||
|         TriangleMesh mesh = po.transformed_mesh(); | ||||
|     auto slice_model = [this, ilhs, ilh, ilhd](SLAPrintObject& po) { | ||||
|         const TriangleMesh& mesh = po.transformed_mesh(); | ||||
| 
 | ||||
|         // We need to prepare the slice index...
 | ||||
| 
 | ||||
|  | @ -685,12 +691,14 @@ void SLAPrint::process() | |||
|         auto maxZs = coord_t(maxZ / SCALING_FACTOR); | ||||
| 
 | ||||
|         po.m_slice_index.clear(); | ||||
|         po.m_slice_index.reserve(size_t(maxZs - (minZs + ilhs) / lhs) + 1); | ||||
|         po.m_slice_index.emplace_back(minZs + ilhs, float(minZ) + ilh / 2.f, ilh); | ||||
|          | ||||
|         for(coord_t h = minZs + ilhs + lhs; h <= maxZs; h += lhs) { | ||||
|             po.m_slice_index.emplace_back(h, float(h*SCALING_FACTOR) - lh / 2.f, lh); | ||||
|         } | ||||
|         size_t cap = size_t(1 + (maxZs - minZs - ilhs) / lhs); | ||||
|         po.m_slice_index.reserve(cap); | ||||
|          | ||||
|         po.m_slice_index.emplace_back(minZs + ilhs, minZ + ilhd / 2.0, ilh); | ||||
| 
 | ||||
|         for(coord_t h = minZs + ilhs + lhs; h <= maxZs; h += lhs)  | ||||
|             po.m_slice_index.emplace_back(h, h*SCALING_FACTOR - lhd / 2.0, lh); | ||||
|         | ||||
|         // Just get the first record that is form the model:
 | ||||
|         auto slindex_it = | ||||
|  | @ -704,11 +712,8 @@ void SLAPrint::process() | |||
|         po.m_model_height_levels.clear(); | ||||
|         po.m_model_height_levels.reserve(po.m_slice_index.size()); | ||||
|         for(auto it = slindex_it; it != po.m_slice_index.end(); ++it) | ||||
|         { | ||||
|             po.m_model_height_levels.emplace_back(it->slice_level()); | ||||
|         } | ||||
| 
 | ||||
|         mesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | ||||
|         TriangleMeshSlicer slicer(&mesh); | ||||
| 
 | ||||
|         po.m_model_slices.clear(); | ||||
|  | @ -1169,8 +1174,9 @@ void SLAPrint::process() | |||
|             for(const SliceRecord& record : layer.slices()) { | ||||
|                 const SLAPrintObject *po = record.print_obj(); | ||||
| 
 | ||||
|                 const ExPolygons &rawmodelslices = record.get_slice(soModel); | ||||
|                 const ExPolygons &modelslices = clpr_back_offs != 0 ? offset_ex(rawmodelslices, clpr_back_offs) : rawmodelslices; | ||||
|                 // const ExPolygons &rawmodelslices = record.get_slice(soModel);
 | ||||
|                 // const ExPolygons &modelslices = clpr_back_offs != 0 ? offset_ex(rawmodelslices, clpr_back_offs) : rawmodelslices;
 | ||||
|                 const ExPolygons &modelslices = record.get_slice(soModel); | ||||
|                  | ||||
|                 bool is_lefth = record.print_obj()->is_left_handed(); | ||||
|                 if (!modelslices.empty()) { | ||||
|  | @ -1178,8 +1184,9 @@ void SLAPrint::process() | |||
|                     for(ClipperPolygon& p_tmp : v) model_polygons.emplace_back(std::move(p_tmp)); | ||||
|                 } | ||||
| 
 | ||||
|                 const ExPolygons &rawsupportslices = record.get_slice(soSupport); | ||||
|                 const ExPolygons &supportslices = clpr_back_offs != 0 ? offset_ex(rawsupportslices, clpr_back_offs) : rawsupportslices; | ||||
|                 // const ExPolygons &rawsupportslices = record.get_slice(soSupport);
 | ||||
|                 // const ExPolygons &supportslices = clpr_back_offs != 0 ? offset_ex(rawsupportslices, clpr_back_offs) : rawsupportslices;
 | ||||
|                 const ExPolygons &supportslices = record.get_slice(soSupport); | ||||
|                  | ||||
|                 if (!supportslices.empty()) { | ||||
|                     ClipperPolygons v = get_all_polygons(supportslices, po->instances(), is_lefth); | ||||
|  | @ -1534,7 +1541,7 @@ SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object): | |||
|     Inherited(print, model_object), | ||||
|     m_stepmask(slaposCount, true), | ||||
|     m_transformed_rmesh( [this](TriangleMesh& obj){ | ||||
|             obj = m_model_object->raw_mesh(); obj.transform(m_trafo); | ||||
|             obj = m_model_object->raw_mesh(); obj.transform(m_trafo); obj.require_shared_vertices(); | ||||
|         }) | ||||
| { | ||||
| } | ||||
|  | @ -1657,16 +1664,16 @@ Vec3d SLAPrint::relative_correction() const | |||
| { | ||||
|     Vec3d corr(1., 1., 1.); | ||||
| 
 | ||||
|     if(printer_config().relative_correction.values.size() == 2) { | ||||
|     if(printer_config().relative_correction.values.size() >= 2) { | ||||
|         corr(X) = printer_config().relative_correction.values[0]; | ||||
|         corr(Y) = printer_config().relative_correction.values[0]; | ||||
|         corr(Z) = printer_config().relative_correction.values[1]; | ||||
|         corr(Z) = printer_config().relative_correction.values.back(); | ||||
|     }  | ||||
| 
 | ||||
|     if(material_config().material_correction.values.size() == 2) { | ||||
|     if(material_config().material_correction.values.size() >= 2) { | ||||
|         corr(X) *= material_config().material_correction.values[0]; | ||||
|         corr(Y) *= material_config().material_correction.values[0]; | ||||
|         corr(Z) *= material_config().material_correction.values[1]; | ||||
|         corr(Z) *= material_config().material_correction.values.back(); | ||||
|     } | ||||
| 
 | ||||
|     return corr; | ||||
|  |  | |||
|  | @ -149,7 +149,10 @@ set(SLIC3R_GUI_SOURCES | |||
| ) | ||||
| 
 | ||||
| if (APPLE) | ||||
|     list(APPEND SLIC3R_GUI_SOURCES Utils/RetinaHelperImpl.mm) | ||||
|     list(APPEND SLIC3R_GUI_SOURCES | ||||
|             Utils/RetinaHelperImpl.mm | ||||
|             Utils/MacDarkMode.mm | ||||
|         ) | ||||
| endif () | ||||
| 
 | ||||
| add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| 
 | ||||
| #include "GUI_App.hpp" | ||||
| #include "PresetBundle.hpp" | ||||
| #include "Gizmos/GLGizmoBase.hpp" | ||||
| 
 | ||||
| #include <GL/glew.h> | ||||
| 
 | ||||
|  | @ -232,7 +233,7 @@ void Bed3D::Axes::render() const | |||
|     glsafe(::glEnable(GL_LIGHTING)); | ||||
| 
 | ||||
|     // x axis
 | ||||
|     glsafe(::glColor3f(1.0f, 0.0f, 0.0f)); | ||||
|     glsafe(::glColor3fv(AXES_COLOR[0])); | ||||
|     glsafe(::glPushMatrix()); | ||||
|     glsafe(::glTranslated(origin(0), origin(1), origin(2))); | ||||
|     glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); | ||||
|  | @ -240,7 +241,7 @@ void Bed3D::Axes::render() const | |||
|     glsafe(::glPopMatrix()); | ||||
| 
 | ||||
|     // y axis
 | ||||
|     glsafe(::glColor3f(0.0f, 1.0f, 0.0f)); | ||||
|     glsafe(::glColor3fv(AXES_COLOR[1])); | ||||
|     glsafe(::glPushMatrix()); | ||||
|     glsafe(::glTranslated(origin(0), origin(1), origin(2))); | ||||
|     glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); | ||||
|  | @ -248,7 +249,7 @@ void Bed3D::Axes::render() const | |||
|     glsafe(::glPopMatrix()); | ||||
| 
 | ||||
|     // z axis
 | ||||
|     glsafe(::glColor3f(0.0f, 0.0f, 1.0f)); | ||||
|     glsafe(::glColor3fv(AXES_COLOR[2])); | ||||
|     glsafe(::glPushMatrix()); | ||||
|     glsafe(::glTranslated(origin(0), origin(1), origin(2))); | ||||
|     render_axis(length(2)); | ||||
|  |  | |||
|  | @ -67,7 +67,7 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve | |||
|     } | ||||
| 
 | ||||
|     if (! compatible) { | ||||
|         text += "<p align=\"right\">" + _(L("Incompatible with this Slic3r")) + "</p>"; | ||||
|         text += "<p align=\"right\">" + wxString::Format(_(L("Incompatible with this %s")), SLIC3R_APP_NAME) + "</p>"; | ||||
|     } | ||||
|     else if (! snapshot_active) | ||||
|         text += "<p align=\"right\"><a href=\"" + snapshot.id + "\">" + _(L("Activate")) + "</a></p>"; | ||||
|  |  | |||
|  | @ -649,12 +649,6 @@ void PageTemperatures::apply_custom_config(DynamicPrintConfig &config) | |||
| 
 | ||||
| ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) | ||||
|     : wxPanel(parent) | ||||
|     /* #ys_FIXME_delete_after_testing by VK
 | ||||
|     , bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG) | ||||
|     , bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG) | ||||
|     , bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG) | ||||
|     , bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG) | ||||
|     */ | ||||
|     , bg(ScalableBitmap(parent, "Slic3r_192px_transparent.png", 192)) | ||||
|     , bullet_black(ScalableBitmap(parent, "bullet_black.png")) | ||||
|     , bullet_blue(ScalableBitmap(parent, "bullet_blue.png")) | ||||
|  | @ -675,9 +669,6 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) | |||
|     // In some cases it didn't work at all. And so wxStaticBitmap is used here instead,
 | ||||
|     // because it has all the platform quirks figured out.
 | ||||
|     auto *sizer = new wxBoxSizer(wxVERTICAL); | ||||
|     /* #ys_FIXME_delete_after_testing by VK
 | ||||
|     auto *logo = new wxStaticBitmap(this, wxID_ANY, bg); | ||||
|     */ | ||||
|     logo = new wxStaticBitmap(this, wxID_ANY, bg.bmp()); | ||||
|     sizer->AddStretchSpacer(); | ||||
|     sizer->Add(logo); | ||||
|  | @ -786,10 +777,6 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) | |||
| 
 | ||||
|     wxPaintDC dc(this); | ||||
| 
 | ||||
|     /* #ys_FIXME_delete_after_testing by VK
 | ||||
|     const auto bullet_w = bullet_black.GetSize().GetWidth(); | ||||
|     const auto bullet_h = bullet_black.GetSize().GetHeight(); | ||||
|     */ | ||||
|     const auto bullet_w = bullet_black.bmp().GetSize().GetWidth(); | ||||
|     const auto bullet_h = bullet_black.bmp().GetSize().GetHeight(); | ||||
|     const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0; | ||||
|  | @ -804,12 +791,6 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) | |||
|         unsigned x = em_w/2 + item.indent * em_w; | ||||
| 
 | ||||
|         if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) { | ||||
|             /*#ys_FIXME_delete_after_testing by VK
 | ||||
|             dc.DrawBitmap(bullet_blue,  x, y + yoff_icon, false); | ||||
|         } | ||||
|         else if (i < item_active)  { dc.DrawBitmap(bullet_black, x, y + yoff_icon, false); } | ||||
|         else if (i > item_active)  { dc.DrawBitmap(bullet_white, x, y + yoff_icon, false); } | ||||
|             */ | ||||
|             dc.DrawBitmap(bullet_blue.bmp(), x, y + yoff_icon, false); | ||||
|         } | ||||
|         else if (i < item_active)  { dc.DrawBitmap(bullet_black.bmp(), x, y + yoff_icon, false); } | ||||
|  | @ -848,6 +829,10 @@ void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt) | |||
| 
 | ||||
| void ConfigWizardIndex::msw_rescale() | ||||
| { | ||||
|     const wxSize size = GetTextExtent("m"); | ||||
|     em_w = size.x; | ||||
|     em_h = size.y; | ||||
| 
 | ||||
|     bg.msw_rescale(); | ||||
|     SetMinSize(bg.bmp().GetSize()); | ||||
|     logo->SetBitmap(bg.bmp()); | ||||
|  | @ -897,6 +882,29 @@ void ConfigWizard::priv::load_pages(bool custom_setup) | |||
|     q->Layout(); | ||||
| } | ||||
| 
 | ||||
| void ConfigWizard::priv::init_dialog_size() | ||||
| { | ||||
|     // Clamp the Wizard size based on screen dimensions
 | ||||
| 
 | ||||
|     const auto idx = wxDisplay::GetFromWindow(q); | ||||
|     wxDisplay display(idx != wxNOT_FOUND ? idx : 0u); | ||||
| 
 | ||||
|     const auto disp_rect = display.GetClientArea(); | ||||
|     wxRect window_rect( | ||||
|         disp_rect.x + disp_rect.width / 20, | ||||
|         disp_rect.y + disp_rect.height / 20, | ||||
|         9*disp_rect.width / 10, | ||||
|         9*disp_rect.height / 10); | ||||
| 
 | ||||
|     const int width_hint = index->GetSize().GetWidth() + page_fff->get_width() + 30 * em();    // XXX: magic constant, I found no better solution
 | ||||
|     if (width_hint < window_rect.width) { | ||||
|         window_rect.x += (window_rect.width - width_hint) / 2; | ||||
|         window_rect.width = width_hint; | ||||
|     } | ||||
| 
 | ||||
|     q->SetSize(window_rect); | ||||
| } | ||||
| 
 | ||||
| bool ConfigWizard::priv::check_first_variant() const | ||||
| { | ||||
|     return run_reason == RR_DATA_EMPTY || run_reason == RR_DATA_LEGACY; | ||||
|  | @ -982,11 +990,12 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese | |||
| 
 | ||||
|         size_t size_sum = 0; | ||||
|         for (const auto &model : vendor->second) { size_sum += model.second.size(); } | ||||
|         if (size_sum == 0) { continue; } | ||||
| 
 | ||||
|         if (size_sum > 0) { | ||||
|             // This vendor needs to be installed
 | ||||
|             install_bundles.emplace_back(vendor_rsrc.second); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Decide whether to create snapshot based on run_reason and the reset profile checkbox
 | ||||
|     bool snapshot = true; | ||||
|  | @ -1011,9 +1020,26 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese | |||
|     app_config->set_vendors(appconfig_vendors); | ||||
|     app_config->set("version_check", page_update->version_check ? "1" : "0"); | ||||
|     app_config->set("preset_update", page_update->preset_update ? "1" : "0"); | ||||
|     app_config->reset_selections(); | ||||
|     preset_bundle->load_presets(*app_config); | ||||
| 
 | ||||
|     std::string preferred_model; | ||||
| 
 | ||||
|     // Figure out the default pre-selected printer based on the seletions in the picker.
 | ||||
|     // The default is the first selected printer model (one with at least 1 variant selected).
 | ||||
|     // The default is only applied by load_presets() if the user doesn't have a (visible) printer
 | ||||
|     // selected already.
 | ||||
|     const auto vendor_prusa = vendors.find("PrusaResearch"); | ||||
|     const auto config_prusa = enabled_vendors.find("PrusaResearch"); | ||||
|     if (vendor_prusa != vendors.end() && config_prusa != enabled_vendors.end()) { | ||||
|         for (const auto &model : vendor_prusa->second.models) { | ||||
|             const auto model_it = config_prusa->second.find(model.id); | ||||
|             if (model_it != config_prusa->second.end() && model_it->second.size() > 0) { | ||||
|                 preferred_model = model.id; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     preset_bundle->load_presets(*app_config, preferred_model); | ||||
| 
 | ||||
|     if (page_custom->custom_wanted()) { | ||||
|         page_firmware->apply_custom_config(*custom_config); | ||||
|  | @ -1107,25 +1133,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) | |||
|     p->hscroll->SetScrollRate(30, 30); | ||||
| 
 | ||||
|     on_window_geometry(this, [this]() { | ||||
|         // Clamp the Wizard size based on screen dimensions
 | ||||
| 
 | ||||
|         const auto idx = wxDisplay::GetFromWindow(this); | ||||
|         wxDisplay display(idx != wxNOT_FOUND ? idx : 0u); | ||||
| 
 | ||||
|         const auto disp_rect = display.GetClientArea(); | ||||
|         wxRect window_rect( | ||||
|             disp_rect.x + disp_rect.width / 20, | ||||
|             disp_rect.y + disp_rect.height / 20, | ||||
|             9*disp_rect.width / 10, | ||||
|             9*disp_rect.height / 10); | ||||
| 
 | ||||
|         const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 30 * p->em();    // XXX: magic constant, I found no better solution
 | ||||
|         if (width_hint < window_rect.width) { | ||||
|             window_rect.x += (window_rect.width - width_hint) / 2; | ||||
|             window_rect.width = width_hint; | ||||
|         } | ||||
| 
 | ||||
|         SetSize(window_rect); | ||||
|         p->init_dialog_size(); | ||||
|     }); | ||||
| 
 | ||||
|     p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->p->index->go_prev(); }); | ||||
|  | @ -1194,7 +1202,7 @@ void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect) | |||
|     for (auto printer_picker: p->page_fff->printer_pickers) | ||||
|         msw_buttons_rescale(this, em, printer_picker->get_button_indexes()); | ||||
| 
 | ||||
|     // FIXME VK SetSize(???)
 | ||||
|     p->init_dialog_size(); | ||||
| 
 | ||||
|     Refresh(); | ||||
| } | ||||
|  |  | |||
|  | @ -292,6 +292,7 @@ struct ConfigWizard::priv | |||
|     priv(ConfigWizard *q) : q(q) {} | ||||
| 
 | ||||
|     void load_pages(bool custom_setup); | ||||
|     void init_dialog_size(); | ||||
| 
 | ||||
|     bool check_first_variant() const; | ||||
|     void load_vendors(); | ||||
|  |  | |||
|  | @ -100,6 +100,7 @@ wxString Field::get_tooltip_text(const wxString& default_string) | |||
| { | ||||
| 	wxString tooltip_text(""); | ||||
| 	wxString tooltip = _(m_opt.tooltip); | ||||
|     edit_tooltip(tooltip); | ||||
| 	if (tooltip.length() > 0) | ||||
|         tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " + | ||||
|         (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string + | ||||
|  | @ -504,6 +505,11 @@ void SpinCtrl::BUILD() { | |||
|         else tmp_value = -9999; | ||||
| #ifdef __WXOSX__ | ||||
|         propagate_value(); | ||||
| 
 | ||||
|         // Forcibly set the input value for SpinControl, since the value 
 | ||||
| 	    // inserted from the clipboard is not updated under OSX
 | ||||
|         if (tmp_value > -9999) | ||||
|             dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value); | ||||
| #endif | ||||
| 	}), temp->GetId()); | ||||
| 	 | ||||
|  |  | |||
|  | @ -794,10 +794,15 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL | |||
|     wxString msg = GUI::from_u8(msg_utf8); | ||||
| 
 | ||||
|     wxMemoryDC memDC; | ||||
| 
 | ||||
| #ifdef __WXMSW__ | ||||
|     // set scaled application normal font as default font 
 | ||||
|     wxFont font = wxGetApp().normal_font(); | ||||
| #else | ||||
|     // select default font
 | ||||
|     const float scale = canvas.get_canvas_size().get_scale_factor(); | ||||
| //     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
 | ||||
|     wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment
 | ||||
|     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale); | ||||
| #endif | ||||
| 
 | ||||
|     font.MakeLarger(); | ||||
|     font.MakeBold(); | ||||
|  | @ -899,7 +904,7 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::WarningTexture::rescale(const GLCanvas3D& canvas) | ||||
| void GLCanvas3D::WarningTexture::msw_rescale(const GLCanvas3D& canvas) | ||||
| { | ||||
|     if (m_msg_text.empty()) | ||||
|         return; | ||||
|  | @ -976,14 +981,16 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
|     const int scaled_square_contour = Px_Square_Contour * scale; | ||||
|     const int scaled_border = Px_Border * scale; | ||||
| 
 | ||||
|     // select default font
 | ||||
| //     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl);
 | ||||
|     wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment
 | ||||
| #ifdef __WXMSW__ | ||||
|     // set scaled application normal font as default font 
 | ||||
|     wxFont font = wxGetApp().normal_font(); | ||||
| 
 | ||||
|     // Disabling ClearType works, but the font returned is very different (much thicker) from the default.
 | ||||
| //    msw_disable_cleartype(font);
 | ||||
|     bool cleartype = is_font_cleartype(font); | ||||
| #else | ||||
|     // select default font
 | ||||
|     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); | ||||
|     bool cleartype = false; | ||||
| #endif /* __WXMSW__ */ | ||||
| 
 | ||||
|  | @ -3190,7 +3197,7 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const | |||
| 
 | ||||
| void GLCanvas3D::msw_rescale() | ||||
| { | ||||
|     m_warning_texture.rescale(*this); | ||||
|     m_warning_texture.msw_rescale(*this); | ||||
| } | ||||
| 
 | ||||
| bool GLCanvas3D::_is_shown_on_screen() const | ||||
|  | @ -4994,6 +5001,10 @@ bool GLCanvas3D::_travel_paths_by_tool(const GCodePreviewData& preview_data, con | |||
|     // creates a new volume for each tool
 | ||||
|     for (Tool& tool : tools) | ||||
|     { | ||||
|         // tool.value could be invalid (as it was with https://github.com/prusa3d/Slic3r/issues/2179), we better check
 | ||||
|         if (tool.value >= tool_colors.size()) | ||||
|             continue; | ||||
| 
 | ||||
|         GLVolume* volume = new GLVolume(tool_colors.data() + tool.value * 4); | ||||
|         if (volume == nullptr) | ||||
|             return false; | ||||
|  | @ -5008,7 +5019,7 @@ bool GLCanvas3D::_travel_paths_by_tool(const GCodePreviewData& preview_data, con | |||
|     for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines) | ||||
|     { | ||||
|         ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id)); | ||||
|         if (tool != tools.end()) | ||||
|         if (tool != tools.end() && tool->volume != nullptr) | ||||
|         { | ||||
|             tool->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2))); | ||||
|             tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.quad_indices.size()); | ||||
|  |  | |||
|  | @ -354,7 +354,7 @@ private: | |||
|         void render(const GLCanvas3D& canvas) const; | ||||
| 
 | ||||
|         // function used to get an information for rescaling of the warning
 | ||||
|         void rescale(const GLCanvas3D& canvas); | ||||
|         void msw_rescale(const GLCanvas3D& canvas); | ||||
| 
 | ||||
|     private: | ||||
|         static const unsigned char Background_Color[3]; | ||||
|  |  | |||
|  | @ -125,9 +125,6 @@ void config_wizard(int reason) | |||
|     if (! wxGetApp().check_unsaved_changes()) | ||||
|     	return; | ||||
| 
 | ||||
|     // save selected preset before config wizard running
 | ||||
|     const auto printer_preset_name = wxGetApp().preset_bundle->printers.get_edited_preset().name; | ||||
| 
 | ||||
| 	try { | ||||
| 		ConfigWizard wizard(nullptr, static_cast<ConfigWizard::RunReason>(reason)); | ||||
|         wizard.run(wxGetApp().preset_bundle, wxGetApp().preset_updater); | ||||
|  | @ -136,10 +133,8 @@ void config_wizard(int reason) | |||
| 		show_error(nullptr, e.what()); | ||||
| 	} | ||||
| 
 | ||||
|     // select old(before config wizard running) preset
 | ||||
| 	wxGetApp().get_tab(Preset::TYPE_PRINTER)->select_preset(printer_preset_name);  | ||||
|     // If old preset if invisible now, then first visible preset will be selected
 | ||||
|     // So, let control the case if multi-part object is on the scene and first visible preset is SLA
 | ||||
| 	wxGetApp().load_current_presets(); | ||||
| 
 | ||||
|     if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && | ||||
|         wxGetApp().obj_list()->has_multi_part_objects()) | ||||
|     { | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ | |||
| 
 | ||||
| #include "../Utils/PresetUpdater.hpp" | ||||
| #include "../Utils/PrintHost.hpp" | ||||
| #include "../Utils/MacDarkMode.hpp" | ||||
| #include "ConfigWizard.hpp" | ||||
| #include "slic3r/Config/Snapshot.hpp" | ||||
| #include "ConfigSnapshotDialog.hpp" | ||||
|  | @ -284,10 +285,24 @@ unsigned GUI_App::get_colour_approx_luma(const wxColour &colour) | |||
|         )); | ||||
| } | ||||
| 
 | ||||
| bool GUI_App::dark_mode() | ||||
| { | ||||
|     const unsigned luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
|     return luma < 128; | ||||
| } | ||||
| 
 | ||||
| bool GUI_App::dark_mode_menus() | ||||
| { | ||||
| #if __APPLE__ | ||||
|     return mac_dark_mode(); | ||||
| #else | ||||
|     return dark_mode(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void GUI_App::init_label_colours() | ||||
| { | ||||
|     auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
|     if (luma >= 128) { | ||||
|     if (dark_mode()) { | ||||
|         m_color_label_modified = wxColour(252, 77, 1); | ||||
|         m_color_label_sys = wxColour(26, 132, 57); | ||||
|     } | ||||
|  | @ -451,7 +466,7 @@ void GUI_App::update_ui_from_settings() | |||
|     mainframe->update_ui_from_settings(); | ||||
| } | ||||
| 
 | ||||
| void GUI_App::persist_window_geometry(wxTopLevelWindow *window) | ||||
| void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized) | ||||
| { | ||||
|     const std::string name = into_u8(window->GetName()); | ||||
| 
 | ||||
|  | @ -460,7 +475,7 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window) | |||
|         event.Skip(); | ||||
|     }); | ||||
| 
 | ||||
|     window_pos_restore(window, name); | ||||
|     window_pos_restore(window, name, default_maximized); | ||||
| 
 | ||||
|     on_window_geometry(window, [=]() { | ||||
|         window_pos_sanitize(window); | ||||
|  | @ -663,7 +678,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) | |||
|     Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comAdvanced); }, config_id_base + ConfigMenuModeAdvanced); | ||||
|     Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comExpert); }, config_id_base + ConfigMenuModeExpert); | ||||
| 
 | ||||
|     local_menu->AppendSubMenu(mode_menu, _(L("Mode")), _(L("Slic3r View Mode"))); | ||||
|     local_menu->AppendSubMenu(mode_menu, _(L("Mode")), wxString::Format(_(L("%s View Mode")), SLIC3R_APP_NAME)); | ||||
|     local_menu->AppendSeparator(); | ||||
|     local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application &Language"))); | ||||
|     local_menu->AppendSeparator(); | ||||
|  | @ -868,15 +883,21 @@ void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) | |||
|     app_config->save(); | ||||
| } | ||||
| 
 | ||||
| void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name) | ||||
| void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized) | ||||
| { | ||||
|     if (name.empty()) { return; } | ||||
|     const auto config_key = (boost::format("window_%1%") % name).str(); | ||||
| 
 | ||||
|     if (! app_config->has(config_key)) { return; } | ||||
|     if (! app_config->has(config_key)) { | ||||
|         window->Maximize(default_maximized); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     auto metrics = WindowMetrics::deserialize(app_config->get(config_key)); | ||||
|     if (! metrics) { return; } | ||||
|     if (! metrics) { | ||||
|         window->Maximize(default_maximized); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     window->SetSize(metrics->get_rect()); | ||||
|     window->Maximize(metrics->get_maximized()); | ||||
|  |  | |||
|  | @ -94,7 +94,9 @@ public: | |||
| 
 | ||||
|     GUI_App(); | ||||
| 
 | ||||
|     unsigned        get_colour_approx_luma(const wxColour &colour); | ||||
|     static unsigned get_colour_approx_luma(const wxColour &colour); | ||||
|     static bool     dark_mode(); | ||||
|     static bool     dark_mode_menus(); | ||||
|     void            init_label_colours(); | ||||
|     void            update_label_colours_from_appconfig(); | ||||
|     void            init_fonts(); | ||||
|  | @ -122,7 +124,7 @@ public: | |||
|                                 const std::string& err); | ||||
| //     void            notify(/*message*/);
 | ||||
| 
 | ||||
|     void            persist_window_geometry(wxTopLevelWindow *window); | ||||
|     void            persist_window_geometry(wxTopLevelWindow *window, bool default_maximized = false); | ||||
|     void            update_ui_from_settings(); | ||||
| 
 | ||||
|     bool            select_language(wxArrayString & names, wxArrayLong & identifiers); | ||||
|  | @ -174,7 +176,7 @@ public: | |||
| private: | ||||
|     bool            on_init_inner(); | ||||
|     void            window_pos_save(wxTopLevelWindow* window, const std::string &name); | ||||
|     void            window_pos_restore(wxTopLevelWindow* window, const std::string &name); | ||||
|     void            window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false); | ||||
|     void            window_pos_sanitize(wxTopLevelWindow* window); | ||||
| }; | ||||
| DECLARE_APP(GUI_App) | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ namespace GUI { | |||
| static const float DEFAULT_BASE_COLOR[3] = { 0.625f, 0.625f, 0.625f }; | ||||
| static const float DEFAULT_DRAG_COLOR[3] = { 1.0f, 1.0f, 1.0f }; | ||||
| static const float DEFAULT_HIGHLIGHT_COLOR[3] = { 1.0f, 0.38f, 0.0f }; | ||||
| static const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; | ||||
| static const float AXES_COLOR[3][3] = { { 0.75f, 0.0f, 0.0f }, { 0.0f, 0.75f, 0.0f }, { 0.0f, 0.0f, 0.75f } }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -129,7 +129,7 @@ DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAU | |||
|         event.Skip(); | ||||
|     }); | ||||
| 
 | ||||
|     wxGetApp().persist_window_geometry(this); | ||||
|     wxGetApp().persist_window_geometry(this, true); | ||||
| 
 | ||||
|     update_ui_from_settings();    // FIXME (?)
 | ||||
| } | ||||
|  | @ -276,12 +276,26 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) | |||
|     for (auto tab : wxGetApp().tabs_list) | ||||
|         tab->msw_rescale(); | ||||
| 
 | ||||
|     // Workarounds for correct Window rendering after rescale
 | ||||
| 
 | ||||
|     /* Even if Window is maximized during moving, 
 | ||||
|      * first of all we should imitate Window resizing. So: | ||||
|      * 1. cancel maximization, if it was set | ||||
|      * 2. imitate resizing | ||||
|      * 3. set maximization, if it was set | ||||
|      */ | ||||
|     const bool is_maximized = this->IsMaximized(); | ||||
|     if (is_maximized) | ||||
|         this->Maximize(false); | ||||
| 
 | ||||
|     /* To correct window rendering (especially redraw of a status bar)
 | ||||
|      * we should imitate window resizing. | ||||
|      */ | ||||
|     const wxSize& sz = this->GetSize(); | ||||
|     this->SetSize(sz.x + 1, sz.y + 1); | ||||
|     this->SetSize(sz); | ||||
| 
 | ||||
|     this->Maximize(is_maximized); | ||||
| } | ||||
| 
 | ||||
| void MainFrame::init_menubar() | ||||
|  | @ -360,7 +374,7 @@ void MainFrame::init_menubar() | |||
|         append_menu_item(fileMenu, wxID_ANY, _(L("&Repair STL file")) + dots, _(L("Automatically repair an STL file")), | ||||
|             [this](wxCommandEvent&) { repair_stl(); }, "wrench"); | ||||
|         fileMenu->AppendSeparator(); | ||||
|         append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")), | ||||
|         append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), wxString::Format(_(L("Quit %s")), SLIC3R_APP_NAME), | ||||
|             [this](wxCommandEvent&) { Close(false); }); | ||||
| 
 | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater != nullptr); }, item_open->GetId()); | ||||
|  | @ -497,9 +511,11 @@ void MainFrame::init_menubar() | |||
| //#            wxTheApp->check_version(1);
 | ||||
| //#        });
 | ||||
| //#        $versioncheck->Enable(wxTheApp->have_version_check);
 | ||||
|         append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Website")), _(L("Open the Slic3r website in your browser")), | ||||
|         append_menu_item(helpMenu, wxID_ANY, wxString::Format(_(L("%s &Website")), SLIC3R_APP_NAME),  | ||||
|                                              wxString::Format(_(L("Open the %s website in your browser")), SLIC3R_APP_NAME), | ||||
|             [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://slic3r.org/"); }); | ||||
|         append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Manual")), _(L("Open the Slic3r manual in your browser")), | ||||
|         append_menu_item(helpMenu, wxID_ANY, wxString::Format(_(L("%s &Manual")), SLIC3R_APP_NAME), | ||||
|                                              wxString::Format(_(L("Open the %s manual in your browser")), SLIC3R_APP_NAME), | ||||
|             [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); }); | ||||
|         helpMenu->AppendSeparator(); | ||||
|         append_menu_item(helpMenu, wxID_ANY, _(L("System &Info")), _(L("Show system information")),  | ||||
|  |  | |||
|  | @ -70,7 +70,8 @@ MsgDialog::~MsgDialog() {} | |||
| // ErrorDialog
 | ||||
| 
 | ||||
| ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg) | ||||
| 	: MsgDialog(parent, _(L("Slic3r error")), _(L("Slic3r has encountered an error")), | ||||
|     : MsgDialog(parent, wxString::Format(_(L("%s error")), SLIC3R_APP_NAME),  | ||||
|                         wxString::Format(_(L("%s has encountered an error")), SLIC3R_APP_NAME), | ||||
| 		wxID_NONE) | ||||
| 	, msg(msg) | ||||
| { | ||||
|  |  | |||
|  | @ -307,7 +307,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| } | ||||
| 
 | ||||
| Line OptionsGroup::create_single_option_line(const Option& option) const { | ||||
| 	Line retval{ _(option.opt.label), _(option.opt.tooltip) }; | ||||
| // 	Line retval{ _(option.opt.label), _(option.opt.tooltip) };
 | ||||
|     wxString tooltip = _(option.opt.tooltip); | ||||
|     edit_tooltip(tooltip); | ||||
| 	Line retval{ _(option.opt.label), tooltip }; | ||||
|     Option tmp(option); | ||||
|     tmp.opt.label = std::string(""); | ||||
|     retval.append_option(tmp); | ||||
|  |  | |||
|  | @ -127,7 +127,7 @@ void PreferencesDialog::accept() | |||
| { | ||||
| 	if (m_values.find("no_defaults")       != m_values.end() || | ||||
| 		m_values.find("use_legacy_opengl") != m_values.end()) { | ||||
| 		warning_catcher(this, _(L("You need to restart Slic3r to make the changes effective."))); | ||||
|         warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME)); | ||||
| 	} | ||||
| 
 | ||||
| 	auto app_config = get_app_config(); | ||||
|  |  | |||
|  | @ -1330,4 +1330,15 @@ const Preset& PrinterPresetCollection::default_preset_for(const DynamicPrintConf | |||
| 	return this->default_preset((opt_printer_technology == nullptr || opt_printer_technology->value == ptFFF) ? 0 : 1); | ||||
| } | ||||
| 
 | ||||
| const Preset* PrinterPresetCollection::find_by_model_id(const std::string &model_id) const | ||||
| { | ||||
|     if (model_id.empty()) { return nullptr; } | ||||
| 
 | ||||
|     const auto it = std::find_if(cbegin(), cend(), [&](const Preset &preset) { | ||||
|         return preset.config.opt_string("printer_model") == model_id; | ||||
|     }); | ||||
| 
 | ||||
|     return it != cend() ? &*it : nullptr; | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -312,7 +312,7 @@ public: | |||
|     const Preset&   get_edited_preset() const   { return m_edited_preset; } | ||||
| 
 | ||||
| 	// used to update preset_choice from Tab
 | ||||
| 	const std::deque<Preset>&	get_presets()	{ return m_presets; } | ||||
| 	const std::deque<Preset>&	get_presets() const	{ return m_presets; } | ||||
| 	int						get_idx_selected()	{ return m_idx_selected; } | ||||
| 	static const std::string&	get_suffix_modified(); | ||||
| 
 | ||||
|  | @ -503,6 +503,8 @@ public: | |||
|     PrinterPresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -") : | ||||
| 		PresetCollection(type, keys, defaults, default_name) {} | ||||
|     const Preset&   default_preset_for(const DynamicPrintConfig &config) const override; | ||||
| 
 | ||||
|     const Preset*   find_by_model_id(const std::string &model_id) const; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -191,7 +191,7 @@ void PresetBundle::setup_directories() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void PresetBundle::load_presets(const AppConfig &config) | ||||
| void PresetBundle::load_presets(const AppConfig &config, const std::string &preferred_model_id) | ||||
| { | ||||
|     // First load the vendor specific system presets.
 | ||||
|     std::string errors_cummulative = this->load_system_presets(); | ||||
|  | @ -234,7 +234,7 @@ void PresetBundle::load_presets(const AppConfig &config) | |||
|     if (! errors_cummulative.empty()) | ||||
|         throw std::runtime_error(errors_cummulative); | ||||
| 
 | ||||
|     this->load_selections(config); | ||||
|     this->load_selections(config, preferred_model_id); | ||||
| } | ||||
| 
 | ||||
| // Load system presets into this PresetBundle.
 | ||||
|  | @ -324,7 +324,7 @@ void PresetBundle::load_installed_printers(const AppConfig &config) | |||
| 
 | ||||
| // Load selections (current print, current filaments, current printer) from config.ini
 | ||||
| // This is done on application start up or after updates are applied.
 | ||||
| void PresetBundle::load_selections(const AppConfig &config) | ||||
| void PresetBundle::load_selections(const AppConfig &config, const std::string &preferred_model_id) | ||||
| { | ||||
| 	// Update visibility of presets based on application vendor / model / variant configuration.
 | ||||
| 	this->load_installed_printers(config); | ||||
|  | @ -336,11 +336,21 @@ void PresetBundle::load_selections(const AppConfig &config) | |||
|     std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", "sla_material")); | ||||
| 	std::string initial_printer_profile_name      = remove_ini_suffix(config.get("presets", "printer")); | ||||
| 
 | ||||
| 	// Activate print / filament / printer profiles from the config.
 | ||||
|     // Activate print / filament / printer profiles from either the config,
 | ||||
|     // or from the preferred_model_id suggestion passed in by ConfigWizard.
 | ||||
|     // If the printer profile enumerated by the config are not visible, select an alternate preset.
 | ||||
|     // Do not select alternate profiles for the print / filament profiles as those presets
 | ||||
|     // will be selected by the following call of this->update_compatible(true).
 | ||||
| 
 | ||||
|     const Preset *initial_printer = printers.find_preset(initial_printer_profile_name); | ||||
|     const Preset *preferred_printer = printers.find_by_model_id(preferred_model_id); | ||||
| 
 | ||||
|     if (preferred_printer != nullptr && (initial_printer == nullptr || !initial_printer->is_visible)) { | ||||
|         printers.select_preset_by_name(preferred_printer->name, true); | ||||
|     } else { | ||||
|         printers.select_preset_by_name(initial_printer_profile_name, true); | ||||
|     } | ||||
| 
 | ||||
|     PrinterTechnology printer_technology = printers.get_selected_preset().printer_technology(); | ||||
|     if (printer_technology == ptFFF) { | ||||
|         prints.select_preset_by_name_strict(initial_print_profile_name); | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ public: | |||
|     // Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets.
 | ||||
|     // Load selections (current print, current filaments, current printer) from config.ini
 | ||||
|     // This is done just once on application start up.
 | ||||
|     void            load_presets(const AppConfig &config); | ||||
|     void            load_presets(const AppConfig &config, const std::string &preferred_model_id = ""); | ||||
| 
 | ||||
|     // Export selections (current print, current filaments, current printer) into config.ini
 | ||||
|     void            export_selections(AppConfig &config); | ||||
|  | @ -143,7 +143,7 @@ private: | |||
| 
 | ||||
|     // Load selections (current print, current filaments, current printer) from config.ini
 | ||||
|     // This is done just once on application start up.
 | ||||
|     void                        load_selections(const AppConfig &config); | ||||
|     void                        load_selections(const AppConfig &config, const std::string &preferred_model_id = ""); | ||||
| 
 | ||||
|     // Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path.
 | ||||
|     // and the external config is just referenced, not stored into user profile directory.
 | ||||
|  |  | |||
|  | @ -1770,9 +1770,9 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 
 | ||||
| 		line.widget = [this, ca_file_hint] (wxWindow* parent) { | ||||
| 			auto txt = new wxStaticText(parent, wxID_ANY, wxString::Format("%s\n\n\t%s", | ||||
| 				_(L("HTTPS CA File:\n\
 | ||||
| \tOn this system, Slic3r uses HTTPS certificates from the system Certificate Store or Keychain.\n\ | ||||
| \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), | ||||
| 	wxString::Format(_(L("HTTPS CA File:\n\
 | ||||
|     \tOn this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.\n\ | ||||
|     \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), SLIC3R_APP_NAME), | ||||
| 				ca_file_hint)); | ||||
| 			txt->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 			auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|  |  | |||
|  | @ -109,7 +109,8 @@ MsgUpdateConfig::~MsgUpdateConfig() {} | |||
| // MsgDataIncompatible
 | ||||
| 
 | ||||
| MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats) : | ||||
| 	MsgDialog(nullptr, _(L("Slic3r incompatibility")), _(L("Slic3r configuration is incompatible")), wxID_NONE) | ||||
|     MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME),  | ||||
|                        wxString::Format(_(L("%s configuration is incompatible")), SLIC3R_APP_NAME), wxID_NONE) | ||||
| { | ||||
| 	logo->SetBitmap(create_scaled_bitmap(this, "Slic3r_192px_grayscale.png", 192)); | ||||
| 
 | ||||
|  | @ -117,9 +118,9 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w | |||
| 		"This version of %s is not compatible with currently installed configuration bundles.\n" | ||||
| 		"This probably happened as a result of running an older %s after using a newer one.\n\n" | ||||
| 
 | ||||
| 		"You may either exit Slic3r and try again with a newer version, or you may re-run the initial configuration. " | ||||
| 		"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this Slic3r.\n" | ||||
| 		)), SLIC3R_APP_NAME, SLIC3R_APP_NAME)); | ||||
| 		"You may either exit %s and try again with a newer version, or you may re-run the initial configuration. " | ||||
| 		"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this %s.\n" | ||||
| 		)), SLIC3R_APP_NAME, SLIC3R_APP_NAME, SLIC3R_APP_NAME, SLIC3R_APP_NAME)); | ||||
| 	text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); | ||||
| 	content_sizer->Add(text); | ||||
| 
 | ||||
|  | @ -144,7 +145,7 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w | |||
| 	content_sizer->Add(versions); | ||||
| 	content_sizer->AddSpacer(2*VERT_SPACING); | ||||
| 
 | ||||
| 	auto *btn_exit = new wxButton(this, wxID_EXIT, _(L("Exit Slic3r"))); | ||||
|     auto *btn_exit = new wxButton(this, wxID_EXIT, wxString::Format(_(L("Exit %s")), SLIC3R_APP_NAME)); | ||||
| 	btn_sizer->Add(btn_exit); | ||||
| 	btn_sizer->AddSpacer(HORIZ_SPACING); | ||||
| 	auto *btn_reconf = new wxButton(this, wxID_REPLACE, _(L("Re-configure"))); | ||||
|  | @ -187,7 +188,7 @@ MsgDataLegacy::MsgDataLegacy() : | |||
| 	auto *text2 = new wxStaticText(this, wxID_ANY, _(L("For more information please visit our wiki page:"))); | ||||
| 	static const wxString url("https://github.com/prusa3d/Slic3r/wiki/Slic3r-PE-1.40-configuration-update"); | ||||
| 	// The wiki page name is intentionally not localized:
 | ||||
| 	auto *link = new wxHyperlinkCtrl(this, wxID_ANY, "Slic3r PE 1.40 configuration update", CONFIG_UPDATE_WIKI_URL); | ||||
| 	auto *link = new wxHyperlinkCtrl(this, wxID_ANY, wxString::Format("%s 1.40 configuration update", SLIC3R_APP_NAME), CONFIG_UPDATE_WIKI_URL); | ||||
| 	content_sizer->Add(text2); | ||||
| 	content_sizer->Add(link); | ||||
| 	content_sizer->AddSpacer(VERT_SPACING); | ||||
|  |  | |||
|  | @ -267,6 +267,13 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e | |||
| 	cmb->SetText(selected); | ||||
| } | ||||
| 
 | ||||
| // edit tooltip : change Slic3r to SLIC3R_APP_KEY
 | ||||
| // Temporary workaround for localization
 | ||||
| void edit_tooltip(wxString& tooltip) | ||||
| { | ||||
|     tooltip.Replace("Slic3r", SLIC3R_APP_KEY, true); | ||||
| } | ||||
| 
 | ||||
| /* Function for rescale of buttons in Dialog under MSW if dpi is changed.
 | ||||
|  * btn_ids - vector of buttons identifiers | ||||
|  */ | ||||
|  | @ -2344,8 +2351,9 @@ void ModeButton::SetState(const bool state) | |||
| 
 | ||||
| void ModeButton::focus_button(const bool focus) | ||||
| { | ||||
|     wxFont font = GetFont(); | ||||
|     const wxFont& new_font = focus ? font.Bold() : font.GetBaseFont(); | ||||
|     const wxFont& new_font = focus ?  | ||||
|                              Slic3r::GUI::wxGetApp().bold_font() :  | ||||
|                              Slic3r::GUI::wxGetApp().normal_font(); | ||||
| 
 | ||||
|     SetFont(new_font); | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, | |||
|     std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler); | ||||
| 
 | ||||
| class wxDialog; | ||||
| void    edit_tooltip(wxString& tooltip); | ||||
| void    msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids); | ||||
| int     em_unit(wxWindow* win); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/slic3r/Utils/MacDarkMode.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/slic3r/Utils/MacDarkMode.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| #ifndef slic3r_MacDarkMode_hpp_ | ||||
| #define slic3r_MacDarkMode_hpp_ | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| #if __APPLE__ | ||||
| extern bool mac_dark_mode(); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif // MacDarkMode_h
 | ||||
							
								
								
									
										22
									
								
								src/slic3r/Utils/MacDarkMode.mm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/slic3r/Utils/MacDarkMode.mm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #import "MacDarkMode.hpp" | ||||
| 
 | ||||
| #import <Foundation/Foundation.h> | ||||
| 
 | ||||
| 
 | ||||
| @implementation MacDarkMode | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| bool mac_dark_mode() | ||||
| { | ||||
|     NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; | ||||
|     return style && [style isEqualToString:@"Dark"]; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| } | ||||
| 
 | ||||
| @end | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv