From 82573390c7c1b918ad4d2d7f9837984aca20316b Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Wed, 10 Apr 2019 09:56:32 +0200 Subject: [PATCH 01/28] First scaling experiments --- src/slic3r/GUI/BitmapCache.cpp | 2 ++ src/slic3r/GUI/GUI_Utils.hpp | 17 +++++++++- src/slic3r/GUI/MainFrame.cpp | 56 ++++++++++++++++++++++++++++++- src/slic3r/GUI/Plater.cpp | 58 ++++++++++++++++++++++++--------- src/slic3r/GUI/Plater.hpp | 1 + src/slic3r/GUI/Preset.cpp | 5 +++ src/slic3r/GUI/Preset.hpp | 2 ++ src/slic3r/GUI/PresetBundle.cpp | 8 +++++ src/slic3r/GUI/Tab.cpp | 10 ++++++ src/slic3r/GUI/Tab.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 8 +++-- 11 files changed, 148 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 7ad36f09b..b0da3b08a 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -23,6 +23,8 @@ void BitmapCache::clear() { for (std::pair<const std::string, wxBitmap*> &bitmap : m_map) delete bitmap.second; + + m_map.clear(); } static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image) diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index e12153625..d68ac8b0d 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -58,9 +58,18 @@ public: : P(parent, id, title, pos, size, style, name) { m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; + + // ->- + m_prev_scale_factor = -1; + // -<- + recalc_font(); this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { + // ->- + m_prev_scale_factor = m_scale_factor; + // -<- + m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; on_dpi_changed(evt.rect); }); @@ -69,14 +78,20 @@ public: virtual ~DPIAware() {} float scale_factor() const { return m_scale_factor; } + float prev_scale_factor() const { return m_prev_scale_factor; } int em_unit() const { return m_em_unit; } int font_size() const { return m_font_size; } + protected: virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; + // ->- +// virtual void scale(wxWindow *window, const float& scale) = 0; + // -<- private: - int m_scale_factor; + float m_scale_factor; + float m_prev_scale_factor; int m_em_unit; int m_font_size; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 059d04f85..fe5768dbb 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -256,9 +256,63 @@ bool MainFrame::can_delete_all() const return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false; } +static void scale(wxWindow *window, const float scale_f) +{ + auto children = window->GetChildren(); + + for (auto child : children) + { + scale(child, scale_f); + + child->SetFont(child->GetFont().Scaled(scale_f)); + +// const wxSize& sz = child->GetSize(); +// if (sz != wxDefaultSize) +// child->SetSize(sz*scale_f); + + child->Layout(); + } +} + void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { - // TODO + printf("WM_DPICHANGED: %.2f\n", scale_factor()); + + // ->- + const float old_sc_factor = prev_scale_factor(); + const float new_sc_factor = scale_factor(); + + if (fabs(old_sc_factor - new_sc_factor) > 0.001) + { + Freeze(); + + const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor; + + scale(this, new_sc_factor / old_sc_factor/*, 1/new_em_unit*/); + + wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); + + /* Load default preset bitmaps before a tabpanel initialization, + * but after filling of an em_unit value + */ + wxGetApp().preset_bundle->load_default_preset_bitmaps(); + + wxGetApp().sidebar().scrolled_panel()->SetSize(40 * wxGetApp().em_unit(), -1); + wxGetApp().sidebar().scrolled_panel()->Layout(); + + // update preset comboboxes on Tabs + for (auto tab : wxGetApp().tabs_list) + tab->rescale();//update_tab_ui(); + + // update preset comboboxes on Plater + wxGetApp().sidebar().update_all_preset_comboboxes(); + + Refresh(); + Layout(); + + Thaw(); + } + // -<- } void MainFrame::init_menubar() diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8f75d0ec9..344c9f079 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -781,6 +781,31 @@ void Sidebar::remove_unused_filament_combos(const int current_extruder_count) } } +void Sidebar::update_all_preset_comboboxes() +{ + PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); + +// wxWindowUpdateLocker noUpdates_scrolled(p->scrolled); + + // Update the print choosers to only contain the compatible presets, update the dirty flags. + if (print_tech == ptFFF) + preset_bundle.prints.update_platter_ui(p->combo_print); + else { + preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); + preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); + } + // Update the printer choosers, update the dirty flags. + preset_bundle.printers.update_platter_ui(p->combo_printer); + // Update the filament choosers to only contain the compatible presets, update the color preview, + // update the dirty flags. + if (print_tech == ptFFF) { + for (size_t i = 0; i < p->combos_filament.size(); ++i) + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); + } + p->show_preset_comboboxes(); +} + void Sidebar::update_presets(Preset::Type preset_type) { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; @@ -822,22 +847,23 @@ void Sidebar::update_presets(Preset::Type preset_type) { // wxWindowUpdateLocker noUpdates_scrolled(p->scrolled); - // Update the print choosers to only contain the compatible presets, update the dirty flags. - if (print_tech == ptFFF) - preset_bundle.prints.update_platter_ui(p->combo_print); - else { - preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); - preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); - } - // Update the printer choosers, update the dirty flags. - preset_bundle.printers.update_platter_ui(p->combo_printer); - // Update the filament choosers to only contain the compatible presets, update the color preview, - // update the dirty flags. - if (print_tech == ptFFF) { - for (size_t i = 0; i < p->combos_filament.size(); ++ i) - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); - } - p->show_preset_comboboxes(); +// // Update the print choosers to only contain the compatible presets, update the dirty flags. +// if (print_tech == ptFFF) +// preset_bundle.prints.update_platter_ui(p->combo_print); +// else { +// preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); +// preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); +// } +// // Update the printer choosers, update the dirty flags. +// preset_bundle.printers.update_platter_ui(p->combo_printer); +// // Update the filament choosers to only contain the compatible presets, update the color preview, +// // update the dirty flags. +// if (print_tech == ptFFF) { +// for (size_t i = 0; i < p->combos_filament.size(); ++ i) +// preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); +// } +// p->show_preset_comboboxes(); + update_all_preset_comboboxes(); break; } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f830edce3..75b71b982 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -79,6 +79,7 @@ public: void init_filament_combo(PresetComboBox **combo, const int extr_idx); void remove_unused_filament_combos(const int current_extruder_count); + void update_all_preset_comboboxes(); void update_presets(Slic3r::Preset::Type preset_type); void update_mode_sizer() const; void update_reslice_btn_tooltip() const; diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 7d1cedc96..9b642338a 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -1288,6 +1288,11 @@ std::string PresetCollection::path_from_name(const std::string &new_name) const return (boost::filesystem::path(m_dir_path) / file_name).make_preferred().string(); } +void PresetCollection::clear_bitmap_cache() +{ + m_bitmap_cache->clear(); +} + wxString PresetCollection::separator(const std::string &label) { return wxString::FromUTF8(PresetCollection::separator_head()) + _(label) + wxString::FromUTF8(PresetCollection::separator_tail()); diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index ac1171e18..989d0c392 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -411,6 +411,8 @@ public: // Generate a file path from a profile name. Add the ".ini" suffix if it is missing. std::string path_from_name(const std::string &new_name) const; + void clear_bitmap_cache(); + #ifdef __linux__ static const char* separator_head() { return "------- "; } static const char* separator_tail() { return " -------"; } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 19f9040bf..4d3890a02 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1448,6 +1448,14 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out void PresetBundle::load_default_preset_bitmaps() { + // Clear bitmap cache, before load new scaled default preset bitmaps + m_bitmapCache->clear(); + this->prints.clear_bitmap_cache(); + this->sla_prints.clear_bitmap_cache(); + this->filaments.clear_bitmap_cache(); + this->sla_materials.clear_bitmap_cache(); + this->printers.clear_bitmap_cache(); + this->prints.load_bitmap_default("cog"); this->sla_prints.load_bitmap_default("cog"); this->filaments.load_bitmap_default("spool.png"); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 5b200a194..d3618efdc 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -726,6 +726,16 @@ void Tab::update_visibility() update_changed_tree_ui(); } +void Tab::rescale() +{ + m_em_unit = wxGetApp().em_unit(); + + m_presets_choice->SetSize(25 * m_em_unit, -1); + m_treectrl->SetSize(20 * m_em_unit, -1); + + update_tab_ui(); +} + Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const { Field* field = nullptr; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 58950990c..1901c9b29 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -274,6 +274,7 @@ public: virtual void reload_config(); void update_mode(); void update_visibility(); + void rescale(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index a27b84058..9b8daecfa 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2387,7 +2387,7 @@ PrusaModeButton::PrusaModeButton( wxWindow *parent, const wxBitmap& bmp_on/* = wxNullBitmap*/, const wxSize& size/* = wxDefaultSize*/, const wxPoint& pos/* = wxDefaultPosition*/) : - wxButton(parent, id, mode, pos, size, /*wxBU_EXACTFIT | */wxNO_BORDER), + wxButton(parent, id, mode, pos, wxDefaultSize/*size*/, wxBU_EXACTFIT | wxNO_BORDER), m_bmp_on(bmp_on) { #ifdef __WXMSW__ @@ -2425,7 +2425,11 @@ void PrusaModeButton::focus_button(const bool focus) { // const wxBitmap& bmp = focus ? m_bmp_on : m_bmp_off; // SetBitmap(bmp); - const wxFont& new_font = focus ? Slic3r::GUI::wxGetApp().bold_font() : Slic3r::GUI::wxGetApp().small_font(); + +// const wxFont& new_font = focus ? Slic3r::GUI::wxGetApp().bold_font() : Slic3r::GUI::wxGetApp().small_font(); + wxFont font = GetFont(); + const wxFont& new_font = focus ? font.Bold() : font.GetBaseFont(); + SetFont(new_font); Refresh(); From f7ddddcff58b1c3de8740c70e3c297f2734602f5 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Sat, 13 Apr 2019 23:46:52 +0200 Subject: [PATCH 02/28] Application Scaling for MSW: Next big step - Added rescale() function for the most of controls - Created PrusaBitmap and PrusaButton classes like a wrap to wxBitmap and wxButton accordingly --- src/libslic3r/PrintConfig.cpp | 34 +-- src/slic3r/GUI/ButtonsDescription.cpp | 3 +- src/slic3r/GUI/ButtonsDescription.hpp | 4 +- src/slic3r/GUI/Field.cpp | 120 ++++++++-- src/slic3r/GUI/Field.hpp | 56 +++-- src/slic3r/GUI/GUI_App.cpp | 7 + src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/GUI_ObjectList.cpp | 12 + src/slic3r/GUI/GUI_ObjectList.hpp | 3 + src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +- src/slic3r/GUI/GUI_ObjectSettings.cpp | 32 ++- src/slic3r/GUI/GUI_ObjectSettings.hpp | 4 + src/slic3r/GUI/MainFrame.cpp | 24 +- src/slic3r/GUI/OptionsGroup.cpp | 62 +++++- src/slic3r/GUI/OptionsGroup.hpp | 7 +- src/slic3r/GUI/Plater.cpp | 95 +++++--- src/slic3r/GUI/Plater.hpp | 6 +- src/slic3r/GUI/Preferences.cpp | 4 +- src/slic3r/GUI/Tab.cpp | 258 +++++++++++++++------- src/slic3r/GUI/Tab.hpp | 61 ++--- src/slic3r/GUI/wxExtensions.cpp | 114 ++++++++-- src/slic3r/GUI/wxExtensions.hpp | 74 ++++++- 22 files changed, 737 insertions(+), 250 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a978a3175..46efceb9a 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -131,7 +131,7 @@ void PrintConfigDef::init_fff_params() "as [layer_num] and [layer_z]."); def->multiline = true; def->full_width = true; - def->height = 50; + def->height = 5; def->mode = comExpert; def->default_value = new ConfigOptionString(""); @@ -140,7 +140,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This code is inserted between objects when using sequential printing. By default extruder and bed temperature are reset using non-wait command; however if M104, M109, M140 or M190 are detected in this custom code, Slic3r will not add temperature commands. Note that you can use placeholder variables for all Slic3r settings, so you can put a \"M109 S[first_layer_temperature]\" command wherever you want."); def->multiline = true; def->full_width = true; - def->height = 120; + def->height = 12; def->mode = comExpert; def->default_value = new ConfigOptionString(""); @@ -360,7 +360,7 @@ void PrintConfigDef::init_fff_params() "Note that you can use placeholder variables for all Slic3r settings."); def->multiline = true; def->full_width = true; - def->height = 120; + def->height = 12; def->mode = comExpert; def->default_value = new ConfigOptionString("M104 S0 ; turn off temperature\nG28 X0 ; home X axis\nM84 ; disable motors\n"); @@ -539,7 +539,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("If layer print time is estimated below this number of seconds, fan will be enabled " "and its speed will be calculated by interpolating the minimum and maximum speeds."); def->sidetext = L("approximate seconds"); - def->width = 60; + def->width = 6; def->min = 0; def->max = 1000; def->mode = comExpert; @@ -556,7 +556,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("You can put your notes regarding the filament here."); def->multiline = true; def->full_width = true; - def->height = 130; + def->height = 13; def->mode = comAdvanced; def->default_value = new ConfigOptionStrings { "" }; @@ -1007,7 +1007,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Inherits profile"); def->tooltip = L("Name of the profile, from which this profile inherits."); def->full_width = true; - def->height = 50; + def->height = 5; def->default_value = new ConfigOptionString(); def->cli = ConfigOptionDef::nocli; @@ -1034,7 +1034,7 @@ void PrintConfigDef::init_fff_params() def->cli = "after-layer-gcode|layer-gcode"; def->multiline = true; def->full_width = true; - def->height = 50; + def->height = 5; def->mode = comExpert; def->default_value = new ConfigOptionString(""); @@ -1053,7 +1053,7 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->default_value = new ConfigOptionBool(true); - const int machine_limits_opt_width = 70; + const int machine_limits_opt_width = 7; { struct AxisDefault { std::string name; @@ -1252,7 +1252,7 @@ void PrintConfigDef::init_fff_params() "header comments."); def->multiline = true; def->full_width = true; - def->height = 130; + def->height = 13; def->mode = comAdvanced; def->default_value = new ConfigOptionString(""); @@ -1387,7 +1387,7 @@ void PrintConfigDef::init_fff_params() def->gui_flags = "serialized"; def->multiline = true; def->full_width = true; - def->height = 60; + def->height = 6; def->mode = comExpert; def->default_value = new ConfigOptionStrings(); @@ -1402,7 +1402,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("You can put your notes regarding the printer here."); def->multiline = true; def->full_width = true; - def->height = 130; + def->height = 13; def->mode = comAdvanced; def->default_value = new ConfigOptionString(""); @@ -1589,7 +1589,7 @@ void PrintConfigDef::init_fff_params() def->label = ""; def->full_label = L("Serial port"); def->tooltip = L("USB/serial port for printer connection."); - def->width = 200; + def->width = 20; def->default_value = new ConfigOptionString(""); def = this->add("serial_speed", coInt); @@ -1635,7 +1635,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("If layer print time is estimated below this number of seconds, print moves " "speed will be scaled down to extend duration to this value."); def->sidetext = L("approximate seconds"); - def->width = 60; + def->width = 6; def->min = 0; def->max = 1000; def->mode = comExpert; @@ -1742,7 +1742,7 @@ void PrintConfigDef::init_fff_params() "a \"M109 S[first_layer_temperature]\" command wherever you want."); def->multiline = true; def->full_width = true; - def->height = 120; + def->height = 12; def->mode = comExpert; def->default_value = new ConfigOptionString("G28 ; home all axes\nG1 Z5 F5000 ; lift nozzle\n"); @@ -1758,7 +1758,7 @@ void PrintConfigDef::init_fff_params() "in extruder order."); def->multiline = true; def->full_width = true; - def->height = 120; + def->height = 12; def->mode = comExpert; def->default_value = new ConfigOptionStrings { "; Filament gcode\n" }; @@ -2008,7 +2008,7 @@ void PrintConfigDef::init_fff_params() "as [previous_extruder] and [next_extruder]."); def->multiline = true; def->full_width = true; - def->height = 50; + def->height = 5; def->mode = comExpert; def->default_value = new ConfigOptionString(""); @@ -2330,7 +2330,7 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("You can put your notes regarding the SLA print material here."); def->multiline = true; def->full_width = true; - def->height = 130; + def->height = 13; def->mode = comAdvanced; def->default_value = new ConfigOptionString(""); diff --git a/src/slic3r/GUI/ButtonsDescription.cpp b/src/slic3r/GUI/ButtonsDescription.cpp index fb4c24286..9def34749 100644 --- a/src/slic3r/GUI/ButtonsDescription.cpp +++ b/src/slic3r/GUI/ButtonsDescription.cpp @@ -7,6 +7,7 @@ #include "GUI.hpp" #include "GUI_App.hpp" #include "I18N.hpp" +#include "wxExtensions.hpp" namespace Slic3r { namespace GUI { @@ -23,7 +24,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* ic // Icon description for (auto pair : *m_icon_descriptions) { - auto icon = new wxStaticBitmap(this, wxID_ANY, *pair.first); + auto icon = new wxStaticBitmap(this, wxID_ANY, /***/pair.first->bmp()); grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL); std::istringstream f(pair.second); diff --git a/src/slic3r/GUI/ButtonsDescription.hpp b/src/slic3r/GUI/ButtonsDescription.hpp index 81baaf191..ccd992406 100644 --- a/src/slic3r/GUI/ButtonsDescription.hpp +++ b/src/slic3r/GUI/ButtonsDescription.hpp @@ -4,10 +4,12 @@ #include <wx/dialog.h> #include <vector> +class PrusaBitmap; + namespace Slic3r { namespace GUI { -using t_icon_descriptions = std::vector<std::pair<wxBitmap*, std::string>>; +using t_icon_descriptions = std::vector<std::pair</*wxBitmap*/PrusaBitmap*, std::string>>; class ButtonsDescription : public wxDialog { diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index d77405230..22229d764 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -33,22 +33,21 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/) void Field::PostInitialize() { auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) { - m_Undo_btn->SetBackgroundColour(color); - m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); - m_Undo_to_sys_btn->SetBackgroundColour(color); - m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); - } + m_Undo_btn = new RevertButton(m_parent, "bullet_white.png");//(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png");//(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); +// if (wxMSW) { +// m_Undo_btn->SetBackgroundColour(color); +// m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); +// m_Undo_to_sys_btn->SetBackgroundColour(color); +// m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); +// } m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); //set default bitmap - wxBitmap bmp; - bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); - set_undo_bitmap(&bmp); - set_undo_to_sys_bitmap(&bmp); +// wxBitmap bmp = create_scaled_bitmap(m_parent, "bullet_white.png" ); +// set_undo_bitmap(&bmp); +// set_undo_to_sys_bitmap(&bmp); switch (m_opt.type) { @@ -213,8 +212,8 @@ bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type) void TextCtrl::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); wxString text_value = wxString(""); @@ -358,6 +357,21 @@ boost::any& TextCtrl::get_value() return m_value; } +void TextCtrl::rescale() +{ + Field::rescale(); + auto size = wxSize(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + + if (size != wxDefaultSize) + { + wxTextCtrl* field = dynamic_cast<wxTextCtrl*>(window); + field->SetMinSize(size); + } + +} + void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); } void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); } @@ -380,7 +394,8 @@ void CheckBox::BUILD() { static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) : false; - auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox + auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); @@ -505,10 +520,18 @@ void SpinCtrl::propagate_value() on_change_field(); } +void SpinCtrl::rescale() +{ + Field::rescale(); + + wxSpinCtrl* field = dynamic_cast<wxSpinCtrl*>(window); + field->SetMinSize(wxSize(-1, int(1.9f*field->GetFont().GetPixelSize().y))); +} + void Choice::BUILD() { - wxSize size(15 * wxGetApp().em_unit(), -1); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + wxSize size(m_width * wxGetApp().em_unit(), -1); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); wxBitmapComboBox* temp; if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { @@ -817,6 +840,48 @@ boost::any& Choice::get_value() return m_value; } +void Choice::rescale() +{ + Field::rescale(); + + wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); + + const wxString selection = field->GetStringSelection(); + + /* To correct scaling (set new controll size) of a wxBitmapCombobox + * we need to refill control with new bitmaps. So, in our case : + * 1. clear conrol + * 2. add content + * 3. add scaled "empty" bitmap to the at least one item + */ + field->Clear(); + wxSize size(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height * wxGetApp().em_unit()); + size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * wxGetApp().em_unit()); + + field->SetSize(size); + + size_t idx, counter = idx = 0; + if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()) {} + else{ + for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { + const wxString& str = _(el); + field->Append(str); + if (el.compare(selection) == 0) + idx = counter; + ++counter; + } + } + + wxBitmap empty_bmp(1, field->GetFont().GetPixelSize().y + 2); + empty_bmp.SetWidth(0); + field->SetItemBitmap(0, empty_bmp); + + idx == m_opt.enum_values.size() ? + field->SetValue(selection) : + field->SetSelection(idx); +} + void ColourPicker::BUILD() { auto size = wxSize(wxDefaultSize); @@ -944,8 +1009,8 @@ boost::any& PointCtrl::get_value() void StaticText::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); @@ -959,6 +1024,21 @@ void StaticText::BUILD() temp->SetToolTip(get_tooltip_text(legend)); } +void StaticText::rescale() +{ + Field::rescale(); + + auto size = wxSize(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + + if (size != wxDefaultSize) + { + wxStaticText* field = dynamic_cast<wxStaticText*>(window); + field->SetSize(size); + } +} + void SliderCtrl::BUILD() { auto size = wxSize(wxDefaultSize); diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 128d60d47..4dfb4e239 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -19,6 +19,7 @@ #include "libslic3r/Utils.hpp" #include "GUI.hpp" +#include "wxExtensions.hpp" #ifdef __WXMSW__ #define wxMSW true @@ -36,19 +37,24 @@ using t_back_to_init = std::function<void(const std::string&)>; wxString double_to_string(double const value, const int max_precision = 4); -class MyButton : public wxButton +class RevertButton : public /*wxButton*/PrusaButton { bool hidden = false; // never show button if it's hidden ones public: - MyButton() {} - MyButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxTextCtrlNameStr) - { - this->Create(parent, id, label, pos, size, style, validator, name); - } +// RevertButton() {} +// RevertButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString, +// const wxPoint& pos = wxDefaultPosition, +// const wxSize& size = wxDefaultSize, long style = 0, +// const wxValidator& validator = wxDefaultValidator, +// const wxString& name = wxTextCtrlNameStr) +// { +// this->Create(parent, id, label, pos, size, style, validator, name); +// } + RevertButton( + wxWindow *parent, + const std::string& icon_name = "" + ) : + PrusaButton(parent, wxID_ANY, icon_name) {} // overridden from wxWindow base class virtual bool @@ -154,19 +160,19 @@ public: return std::move(p); //!p; } - bool set_undo_bitmap(const wxBitmap *bmp) { + bool set_undo_bitmap(const /*wxBitmap*/PrusaBitmap *bmp) { if (m_undo_bitmap != bmp) { m_undo_bitmap = bmp; - m_Undo_btn->SetBitmap(*bmp); + m_Undo_btn->SetBitmap_(*bmp); return true; } return false; } - bool set_undo_to_sys_bitmap(const wxBitmap *bmp) { + bool set_undo_to_sys_bitmap(const /*wxBitmap*/PrusaBitmap *bmp) { if (m_undo_to_sys_bitmap != bmp) { m_undo_to_sys_bitmap = bmp; - m_Undo_to_sys_btn->SetBitmap(*bmp); + m_Undo_to_sys_btn->SetBitmap_(*bmp); return true; } return false; @@ -211,14 +217,19 @@ public: m_side_text = side_text; } + virtual void rescale() { + m_Undo_to_sys_btn->rescale(); + m_Undo_btn->rescale(); + } + protected: - MyButton* m_Undo_btn = nullptr; + RevertButton* m_Undo_btn = nullptr; // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. - const wxBitmap* m_undo_bitmap = nullptr; + const /*wxBitmap*/PrusaBitmap* m_undo_bitmap = nullptr; const wxString* m_undo_tooltip = nullptr; - MyButton* m_Undo_to_sys_btn = nullptr; + RevertButton* m_Undo_to_sys_btn = nullptr; // Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. - const wxBitmap* m_undo_to_sys_bitmap = nullptr; + const /*wxBitmap*/PrusaBitmap* m_undo_to_sys_bitmap = nullptr; const wxString* m_undo_to_sys_tooltip = nullptr; wxStaticText* m_Label = nullptr; @@ -273,6 +284,8 @@ public: } boost::any& get_value() override; + + void rescale() override; virtual void enable(); virtual void disable(); @@ -337,6 +350,8 @@ public: return m_value = tmp_value; } + void rescale() override; + void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); } void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); } wxWindow* getWindow() override { return window; } @@ -344,6 +359,7 @@ public: class Choice : public Field { using Field::Field; + int m_width{ 15 }; public: Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} @@ -363,6 +379,8 @@ public: void set_values(const std::vector<std::string> &values); boost::any& get_value() override; + void rescale() override; + void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); }; void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); }; wxWindow* getWindow() override { return window; } @@ -446,6 +464,8 @@ public: boost::any& get_value()override { return m_value; } + void rescale() override; + void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); }; void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); }; wxWindow* getWindow() override { return window; } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 049447e96..b0e585cb9 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -325,6 +325,13 @@ void GUI_App::init_fonts() #endif /*__WXMAC__*/ } +void GUI_App::scale_fonts(const float scale_f) +{ + m_small_font = m_small_font.Scaled(scale_f); + m_bold_font = m_bold_font.Scaled(scale_f); + m_normal_font = m_normal_font.Scaled(scale_f); +} + void GUI_App::set_label_clr_modified(const wxColour& clr) { m_color_label_modified = clr; auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue()); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 41805702b..87c773164 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -98,6 +98,7 @@ public: void init_label_colours(); void update_label_colours_from_appconfig(); void init_fonts(); + void scale_fonts(const float scale_f); void set_label_clr_modified(const wxColour& clr); void set_label_clr_sys(const wxColour& clr); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc3909351..c3bc808f4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2613,6 +2613,18 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co } } +void ObjectList::rescale() +{ + // update min size !!! Width shouldn't be a wxDefaultCoord + SetMinSize(wxSize(1, 15 * wxGetApp().em_unit())); + + GetColumn(0)->SetWidth(19 * wxGetApp().em_unit()); + GetColumn(1)->SetWidth(8 * wxGetApp().em_unit()); + GetColumn(2)->SetWidth(int(2 * wxGetApp().em_unit())); + + Layout(); +} + void ObjectList::ItemValueChanged(wxDataViewEvent &event) { if (event.GetColumn() == 0) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 2f465a4ab..c3d76f656 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -285,6 +285,9 @@ public: void rename_item(); void fix_through_netfabb() const; void update_item_error_icon(const int obj_idx, int vol_idx) const ; + + void rescale(); + private: void OnChar(wxKeyEvent& event); void OnContextMenu(wxDataViewEvent &event); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index df54f16d4..358d85721 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -23,7 +23,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : #endif // __APPLE__ { m_og->set_name(_(L("Object Manipulation"))); - m_og->label_width = 12 * wxGetApp().em_unit();//125; + m_og->label_width = 12;//125; m_og->set_grid_vgap(5); m_og->m_on_change = std::bind(&ObjectManipulation::on_change, this, std::placeholders::_1, std::placeholders::_2); @@ -45,11 +45,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : def.label = L("Name"); def.gui_type = "legend"; def.tooltip = L("Object name"); - def.width = 21 * wxGetApp().em_unit(); + def.width = 21; def.default_value = new ConfigOptionString{ " " }; m_og->append_single_option_line(Option(def, "object_name")); - const int field_width = 5 * wxGetApp().em_unit()/*50*/; + const int field_width = 5; // Legend for object modification auto line = Line{ "", "" }; diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 72eeb76de..fb9421a54 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -59,6 +59,8 @@ ObjectSettings::ObjectSettings(wxWindow* parent) : m_settings_list_sizer = new wxBoxSizer(wxVERTICAL); m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5); + + m_bmp_delete = PrusaBitmap(parent, "cross"); } void ObjectSettings::update_settings_list() @@ -77,11 +79,12 @@ void ObjectSettings::update_settings_list() { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line - auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "cross"/*"colorchange_delete_on.png"*/), - wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); -#ifdef __WXMSW__ - btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -#endif // __WXMSW__ +// auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "cross"/*"colorchange_delete_on.png"*/), +// wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + auto btn = new PrusaButton(parent, wxID_ANY, m_bmp_delete); +//#ifdef __WXMSW__ +// btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +//#endif // __WXMSW__ btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { config->erase(opt_key); wxGetApp().obj_list()->part_settings_changed(); @@ -123,7 +126,7 @@ void ObjectSettings::update_settings_list() continue; auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column); - optgroup->label_width = 15 * wxGetApp().em_unit(); + optgroup->label_width = 15; optgroup->sidetext_width = 5.5 * wxGetApp().em_unit(); optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { @@ -139,6 +142,15 @@ void ObjectSettings::update_settings_list() } optgroup->reload_config(); m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); + + // call back for rescaling of the extracolumn control + optgroup->rescale_extra_column = [this](wxWindow* win) { + auto *ctrl = dynamic_cast<PrusaButton*>(win); + if (ctrl == nullptr) + return; + ctrl->SetBitmap_(m_bmp_delete); + }; + m_og_settings.push_back(optgroup); categories.push_back(cat.first); @@ -163,5 +175,13 @@ void ObjectSettings::UpdateAndShow(const bool show) OG_Settings::UpdateAndShow(show); } +void ObjectSettings::rescale() +{ + m_bmp_delete.rescale(); + + for (auto group : m_og_settings) + group->rescale(); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectSettings.hpp b/src/slic3r/GUI/GUI_ObjectSettings.hpp index 12115e208..17accda18 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.hpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.hpp @@ -4,6 +4,7 @@ #include <memory> #include <vector> #include <wx/panel.h> +#include "wxExtensions.hpp" class wxBoxSizer; @@ -37,12 +38,15 @@ class ObjectSettings : public OG_Settings // option groups for settings std::vector <std::shared_ptr<ConfigOptionsGroup>> m_og_settings; + PrusaBitmap m_bmp_delete; + public: ObjectSettings(wxWindow* parent); ~ObjectSettings() {} void update_settings_list(); void UpdateAndShow(const bool show) override; + void rescale(); }; }} diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d6a3942d5..5f3434390 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -256,6 +256,7 @@ bool MainFrame::can_delete_all() const return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false; } +// scale font for existing controls static void scale(wxWindow *window, const float scale_f) { auto children = window->GetChildren(); @@ -268,10 +269,9 @@ static void scale(wxWindow *window, const float scale_f) // const wxSize& sz = child->GetSize(); // if (sz != wxDefaultSize) -// child->SetSize(sz*scale_f); - - child->Layout(); +// child->SetSize(sz*scale_f); } + window->Layout(); } void MainFrame::on_dpi_changed(const wxRect &suggested_rect) @@ -286,28 +286,24 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { Freeze(); + scale(this, new_sc_factor / old_sc_factor); + wxGetApp().scale_fonts(new_sc_factor / old_sc_factor); + const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor; - - scale(this, new_sc_factor / old_sc_factor/*, 1/new_em_unit*/); - wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); /* Load default preset bitmaps before a tabpanel initialization, * but after filling of an em_unit value */ - wxGetApp().preset_bundle->load_default_preset_bitmaps(); + wxGetApp().preset_bundle->load_default_preset_bitmaps(this); - wxGetApp().sidebar().scrolled_panel()->SetSize(40 * wxGetApp().em_unit(), -1); - wxGetApp().sidebar().scrolled_panel()->Layout(); + // update preset comboboxes on Plater + wxGetApp().sidebar().rescale(); // update preset comboboxes on Tabs for (auto tab : wxGetApp().tabs_list) - tab->rescale();//update_tab_ui(); + tab->rescale(); - // update preset comboboxes on Plater - wxGetApp().sidebar().update_all_preset_comboboxes(); - - Refresh(); Layout(); Thaw(); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index df2f7b582..fda6b80ca 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -166,8 +166,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n #endif /* __WXGTK__ */ // if we have an extra column, build it - if (extra_column) - grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); + if (extra_column) + { + m_extra_column_ptrs.push_back(extra_column(this->ctrl_parent(), line)); + grid_sizer->Add(m_extra_column_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3); + } // Build a label if we have it wxStaticText* label=nullptr; @@ -180,10 +183,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; #endif /* __WXGTK__ */ label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), - wxDefaultPosition, wxSize(label_width, -1), label_style); + wxDefaultPosition, wxSize(label_width*wxGetApp().em_unit(), -1), label_style); label->SetBackgroundStyle(wxBG_STYLE_PAINT); - label->SetFont(label_font); - label->Wrap(label_width); // avoid a Linux/GTK bug + label->SetFont(wxGetApp().normal_font()); + label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug if (!line.near_label_widget) grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); else if (line.near_label_widget && line.label.IsEmpty()) @@ -235,14 +238,13 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n wxSizer* sizer_tmp = sizer; // add label if any if (option.label != "") { -// wxString str_label = _(option.label); //! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 wxString str_label = (option.label == "Top" || option.label == "Bottom") ? _CTX(option.label, "Layers") : _(option.label); label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); label->SetBackgroundStyle(wxBG_STYLE_PAINT); - label->SetFont(label_font); + label->SetFont(wxGetApp().normal_font()); sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0); } @@ -269,7 +271,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); - sidetext->SetFont(sidetext_font); + sidetext->SetFont(wxGetApp().normal_font()); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); field->set_side_text_ptr(sidetext); } @@ -478,6 +480,50 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { return true; } +void ConfigOptionsGroup::rescale() +{ + // update bitmaps for mode markers : set new (rescaled) bitmaps + if (rescale_extra_column) + for (auto extra_col : m_extra_column_ptrs) + rescale_extra_column(extra_col); + + // update undo buttons : rescale bitmaps + for (const auto& field : m_fields) + field.second->rescale(); + + // rescale width of label column + if (!m_options_mode.empty() && label_width > 1) + { + const int cols = m_grid_sizer->GetCols(); + const int rows = m_grid_sizer->GetEffectiveRowsCount(); + const int label_col = extra_column == nullptr ? 0 : 1; + + for (int i = 0; i < rows; i++) + { + const wxSizerItem* label_item = m_grid_sizer->GetItem(i*cols+label_col); + if (label_item->IsWindow()) + { + auto label = dynamic_cast<wxStaticText*>(label_item->GetWindow()); + if (label != nullptr) { + label->SetMinSize(wxSize(label_width*wxGetApp().em_unit(), -1)); + } + } + else if (label_item->IsSizer()) // case when we nave near_label_widget + { + const wxSizerItem* l_item = label_item->GetSizer()->GetItem(1); + if (l_item->IsWindow()) + { + auto label = dynamic_cast<wxStaticText*>(l_item->GetWindow()); + if (label != nullptr) { + label->SetMinSize(wxSize(label_width*wxGetApp().em_unit(), -1)); + } + } + } + } + m_grid_sizer->Layout(); + } +} + boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) { if (deserialize) { diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index dbe1ea1a2..34f571603 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -72,7 +72,7 @@ private: std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()}; }; -using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;//std::function<wxSizer*(const Line&)>; +using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>; using t_optionfield_map = std::map<t_config_option_key, t_field>; using t_opt_map = std::map< std::string, std::pair<std::string, int> >; @@ -82,9 +82,10 @@ class OptionsGroup { public: const bool staticbox {true}; const wxString title {wxString("")}; - size_t label_width = 20 * wxGetApp().em_unit();// {200}; + size_t label_width = 20 ;// {200}; wxSizer* sizer {nullptr}; column_t extra_column {nullptr}; + std::function<void(wxWindow* win)> rescale_extra_column { nullptr }; t_change m_on_change { nullptr }; t_kill_focus m_fill_empty_value { nullptr }; t_kill_focus m_set_focus { nullptr }; @@ -191,6 +192,7 @@ protected: std::map<t_config_option_key, Option> m_options; wxWindow* m_parent {nullptr}; std::vector<ConfigOptionMode> m_options_mode; + std::vector<wxWindow*> m_extra_column_ptrs; /// Field list, contains unique_ptrs of the derived type. /// using types that need to know what it is beyond the public interface @@ -259,6 +261,7 @@ public: void Hide(); void Show(const bool show); bool update_visibility(ConfigOptionMode mode); + void rescale(); boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize); // return option value from config boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9a5fedfdc..5b7ac86fa 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -111,6 +111,7 @@ public: bool showing_manifold_warning_icon; void show_sizer(bool show); + void rescale(); }; ObjectInfo::ObjectInfo(wxWindow *parent) : @@ -118,10 +119,10 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : { GetStaticBox()->SetFont(wxGetApp().bold_font()); - auto *grid_sizer = new wxFlexGridSizer(4, 5, 5); + auto *grid_sizer = new wxFlexGridSizer(4, 5, 15); grid_sizer->SetFlexibleDirection(wxHORIZONTAL); - grid_sizer->AddGrowableCol(1, 1); - grid_sizer->AddGrowableCol(3, 1); +// grid_sizer->AddGrowableCol(1, 1); +// grid_sizer->AddGrowableCol(3, 1); auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString text_label) { auto *text = new wxStaticText(parent, wxID_ANY, text_label+":"); @@ -161,6 +162,11 @@ void ObjectInfo::show_sizer(bool show) manifold_warning_icon->Show(showing_manifold_warning_icon && show); } +void ObjectInfo::rescale() +{ + manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation_mark_")); +} + enum SlisedInfoIdx { siFilament_m, @@ -282,11 +288,12 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * }); } - edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); -#ifdef __WINDOWS__ - edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -#endif - edit_btn->SetBitmap(create_scaled_bitmap(this, "cog")); +// edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); +// #ifdef __WINDOWS__ +// edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +// #endif +// edit_btn->SetBitmap(create_scaled_bitmap(this, "cog")); + edit_btn = new PrusaButton(parent, wxID_ANY, "cog"); edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) @@ -332,6 +339,13 @@ void PresetComboBox::check_selection() this->last_selected = GetSelection(); } +void PresetComboBox::rescale() +{ + // update min control's height from new scaled size + this->SetMinSize(wxSize(20*wxGetApp().em_unit(), this->GetSize().GetHeight())); + edit_btn->rescale(); +} + // Frequently changed parameters class FreqChangedParams : public OG_Settings @@ -429,7 +443,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : option = m_og->get_option("fill_density"); option.opt.label = L("Infill"); - option.opt.width = 6 * wxGetApp().em_unit(); + option.opt.width = 6; option.opt.sidetext = " "; line.append_option(option); @@ -615,9 +629,9 @@ void Sidebar::priv::show_preset_comboboxes() // Sidebar / public Sidebar::Sidebar(Plater *parent) - : wxPanel(parent), p(new priv(parent)) + : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)), p(new priv(parent)) { - p->scrolled = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)); + p->scrolled = new wxScrolledWindow(this, wxID_ANY/*, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)*/); p->scrolled->SetScrollbars(0, 20, 1, 2); @@ -676,13 +690,8 @@ Sidebar::Sidebar(Plater *parent) init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false); init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false); - // calculate width of the preset labels -// p->sizer_presets->Layout(); -// const wxArrayInt& ar = p->sizer_presets->GetColWidths(); -// const int label_width = ar.IsEmpty() ? 10*wxGetApp().em_unit() : ar.front()-4; - const int margin_5 = int(0.5*wxGetApp().em_unit());// 5; - const int margin_10 = int(1.5*wxGetApp().em_unit());// 15; + const int margin_10 = 10;//int(1.5*wxGetApp().em_unit());// 15; p->sizer_params = new wxBoxSizer(wxVERTICAL); @@ -704,10 +713,6 @@ Sidebar::Sidebar(Plater *parent) p->object_settings->Hide(); p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, margin_5); - p->btn_send_gcode = new wxButton(this, wxID_ANY, _(L("Send to printer"))); - p->btn_send_gcode->SetFont(wxGetApp().bold_font()); - p->btn_send_gcode->Hide(); - // Info boxes p->object_info = new ObjectInfo(p->scrolled); p->sliced_info = new SlicedInfo(p->scrolled); @@ -722,10 +727,16 @@ Sidebar::Sidebar(Plater *parent) scrolled_sizer->Add(p->sliced_info, 0, wxEXPAND | wxTOP | wxLEFT, margin_5); // Buttons underneath the scrolled area - p->btn_export_gcode = new wxButton(this, wxID_ANY, _(L("Export G-code")) + dots); - p->btn_export_gcode->SetFont(wxGetApp().bold_font()); - p->btn_reslice = new wxButton(this, wxID_ANY, _(L("Slice now"))); - p->btn_reslice->SetFont(wxGetApp().bold_font()); + + auto init_btn = [this](wxButton **btn, wxString label) { + *btn = new wxButton(this, wxID_ANY, label); + (*btn)->SetFont(wxGetApp().bold_font()); + }; + + init_btn(&p->btn_send_gcode, _(L("Send to printer"))); + p->btn_send_gcode->Hide(); + init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots); + init_btn(&p->btn_reslice, _(L("Slice now"))); enable_buttons(false); auto *btns_sizer = new wxBoxSizer(wxVERTICAL); @@ -888,6 +899,40 @@ void Sidebar::update_reslice_btn_tooltip() const p->btn_reslice->SetToolTip(tooltip); } +void Sidebar::rescale() +{ + SetMinSize(wxSize(40 * wxGetApp().em_unit(), -1)); + + p->mode_sizer->rescale(); + + // first of all : recreate preset comboboxes, because of + // in AddBitmap() function autonaticaly set the size of controll + update_all_preset_comboboxes(); + // then rescale them to current min size to correct layout of the sidebar + for (PresetComboBox* combo : std::vector<PresetComboBox*> { p->combo_print, + p->combo_sla_print, + p->combo_sla_material, + p->combo_printer } ) + combo->rescale(); + + for (PresetComboBox* combo : p->combos_filament) + combo->rescale(); + + p->frequently_changed_parameters->get_og(true)->rescale(); + p->frequently_changed_parameters->get_og(false)->rescale(); + + p->object_list->rescale(); + + p->object_manipulation->get_og()->rescale(); + p->object_settings->rescale(); + + p->object_info->rescale(); + + p->scrolled->Layout(); + p->plater->Layout(); + p->plater->GetParent()->Layout(); +} + ObjectManipulation* Sidebar::obj_manipul() { return p->object_manipulation; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 75b71b982..b2d904a2e 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -14,6 +14,7 @@ #include "GLTexture.hpp" class wxButton; +class PrusaButton; class wxBoxSizer; class wxGLCanvas; class wxScrolledWindow; @@ -46,7 +47,7 @@ public: PresetComboBox(wxWindow *parent, Preset::Type preset_type); ~PresetComboBox(); - wxButton* edit_btn { nullptr }; + /*wxButton*/PrusaButton* edit_btn { nullptr }; enum LabelItemType { LABEL_ITEM_MARKER = 0x4d, @@ -58,6 +59,8 @@ public: int get_extruder_idx() const { return extruder_idx; } void check_selection(); + void rescale(); + private: typedef std::size_t Marker; @@ -83,6 +86,7 @@ public: void update_presets(Slic3r::Preset::Type preset_type); void update_mode_sizer() const; void update_reslice_btn_tooltip() const; + void rescale(); ObjectManipulation* obj_manipul(); ObjectList* obj_list(); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 8ffff1a41..96a2f3618 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -15,7 +15,7 @@ void PreferencesDialog::build() { auto app_config = get_app_config(); m_optgroup = std::make_shared<ConfigOptionsGroup>(this, _(L("General"))); - m_optgroup->label_width = 40 * wxGetApp().em_unit(); //400; + m_optgroup->label_width = 40; //400; m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; }; @@ -110,6 +110,8 @@ void PreferencesDialog::build() auto sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + SetFont(wxGetApp().normal_font()); + auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL); wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); }); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e1915f6f0..2dd277d7b 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -115,32 +115,43 @@ void Tab::create_preset_tab() auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); //buttons - wxBitmap bmpMenu; - bmpMenu = create_scaled_bitmap(this, "save"); - m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - if (wxMSW) m_btn_save_preset->SetBackgroundColour(color); - bmpMenu = create_scaled_bitmap(this, "cross"/*"delete.png"*/); - m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color); + m_scaled_buttons.reserve(6); + m_scaled_buttons.reserve(2); +// wxBitmap bmpMenu; +// bmpMenu = create_scaled_bitmap(this, "save"); +// m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); +// if (wxMSW) m_btn_save_preset->SetBackgroundColour(color); +// bmpMenu = create_scaled_bitmap(this, "cross"/*"delete.png"*/); +// m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); +// if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color); + + add_scaled_button(panel, &m_btn_save_preset, "save"); + add_scaled_button(panel, &m_btn_delete_preset, "cross"); m_show_incompatible_presets = false; - m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag_red"); - m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "flag_green"); - m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color); +// m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag_red"); +// m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "flag_green"); + add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red"); + add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green"); +// m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); +// if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color); + add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name()); m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title); m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->Disable(); - m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) { - m_undo_btn->SetBackgroundColour(color); - m_undo_to_sys_btn->SetBackgroundColour(color); - m_question_btn->SetBackgroundColour(color); - } +// m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); +// m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); +// m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + + add_scaled_button(panel, &m_question_btn, "question"); + +// if (wxMSW) { +// m_undo_btn->SetBackgroundColour(color); +// m_undo_to_sys_btn->SetBackgroundColour(color); +// m_question_btn->SetBackgroundColour(color); +// } m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n" "or click this button."))); @@ -148,22 +159,28 @@ void Tab::create_preset_tab() // Determine the theme color of OS (dark or light) auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - m_bmp_value_lock = create_scaled_bitmap(this, luma >= 128 ? "lock_closed" : "lock_closed_white"); - m_bmp_value_unlock = create_scaled_bitmap(this, "lock_open"); +// m_bmp_value_lock = create_scaled_bitmap(this, luma >= 128 ? "lock_closed" : "lock_closed_white"); +// m_bmp_value_unlock = create_scaled_bitmap(this, "lock_open"); + add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white"); + add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open"); m_bmp_non_system = &m_bmp_white_bullet; // Bitmaps to be shown on the "Undo user changes" button next to each input field. - m_bmp_value_revert = create_scaled_bitmap(this, "undo"); - m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png"); - m_bmp_question = create_scaled_bitmap(this, "question"); +// m_bmp_value_revert = create_scaled_bitmap(this, "undo"); +// m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png"); + add_scaled_bitmap(this, m_bmp_value_revert, "undo"); + add_scaled_bitmap(this, m_bmp_white_bullet, "bullet_white.png"); fill_icon_descriptions(); set_tooltips_text(); - m_undo_btn->SetBitmap(m_bmp_white_bullet); + add_scaled_button(panel, &m_undo_btn, m_bmp_white_bullet.name()); + add_scaled_button(panel, &m_undo_to_sys_btn, m_bmp_white_bullet.name()); + +// m_undo_btn->SetBitmap(m_bmp_white_bullet); m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); - m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); +// m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); - m_question_btn->SetBitmap(m_bmp_question); +// m_question_btn->SetBitmap(m_bmp_question); m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { auto dlg = new ButtonsDescription(this, &m_icon_descriptions); @@ -259,12 +276,32 @@ void Tab::create_preset_tab() toggle_show_hide_incompatible(); })); + // Fill cache for mode bitmaps + m_mode_bitmap_cache.reserve(3); + m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_simple_.png")); + m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_middle_.png")); + m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_expert_.png")); + // Initialize the DynamicPrintConfig by default keys/values. build(); rebuild_page_tree(); m_complited = true; } +void Tab::add_scaled_button(wxWindow* parent, PrusaButton** btn, const std::string& icon_name, + const wxString& label/* = wxEmptyString*/, + long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) +{ + *btn = new PrusaButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style); + m_scaled_buttons.push_back(*btn); +} + +void Tab::add_scaled_bitmap(wxWindow* parent, PrusaBitmap& bmp, const std::string& icon_name) +{ + bmp = PrusaBitmap(parent, icon_name); + m_scaled_bitmaps.push_back(&bmp); +} + void Tab::load_initial_data() { m_config = &m_presets->get_edited_preset().config; @@ -281,9 +318,9 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); if (icon_idx == -1) { // Add a new icon to the icon list. -// wxIcon img_icon(from_u8(Slic3r::var(icon)), wxBITMAP_TYPE_PNG); -// m_icons->Add(img_icon); - m_icons->Add(create_scaled_bitmap(this, icon)); +// m_icons->Add(create_scaled_bitmap(this, icon)); + m_scaled_icons_list.push_back(PrusaBitmap(this, icon)); + m_icons->Add(m_scaled_icons_list.back().bmp()); icon_idx = ++m_icon_count; m_icon_index[icon] = icon_idx; } @@ -294,7 +331,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str #else auto panel = this; #endif - PageShp page(new Page(panel, title, icon_idx)); + PageShp page(new Page(panel, title, icon_idx, m_mode_bitmap_cache)); // page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); #ifdef __WINDOWS__ // page->SetDoubleBuffered(true); @@ -402,8 +439,8 @@ void Tab::update_changed_ui() { bool is_nonsys_value = false; bool is_modified_value = true; - const wxBitmap *sys_icon = &m_bmp_value_lock; - const wxBitmap *icon = &m_bmp_value_revert; + const /*wxBitmap*/PrusaBitmap *sys_icon = &m_bmp_value_lock; + const /*wxBitmap*/PrusaBitmap *icon = &m_bmp_value_revert; const wxColour *color = &m_sys_label_clr; @@ -595,8 +632,8 @@ void Tab::update_changed_tree_ui() void Tab::update_undo_buttons() { - m_undo_btn->SetBitmap(m_is_modified_values ? m_bmp_value_revert : m_bmp_white_bullet); - m_undo_to_sys_btn->SetBitmap(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); + m_undo_btn-> SetBitmap_(m_is_modified_values ? m_bmp_value_revert: m_bmp_white_bullet); + m_undo_to_sys_btn-> SetBitmap_(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet); m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock); @@ -730,10 +767,36 @@ void Tab::rescale() { m_em_unit = wxGetApp().em_unit(); + m_mode_sizer->rescale(); + m_presets_choice->SetSize(25 * m_em_unit, -1); - m_treectrl->SetSize(20 * m_em_unit, -1); + m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1)); update_tab_ui(); + + // rescale buttons and cached bitmaps + for (const auto btn : m_scaled_buttons) + btn->rescale(); + for (const auto bmp : m_scaled_bitmaps) + bmp->rescale(); + for (PrusaBitmap& bmp : m_mode_bitmap_cache) + bmp.rescale(); + + // rescale icons for tree_ctrl + for (PrusaBitmap& bmp : m_scaled_icons_list) + bmp.rescale(); + // recreate and set new ImageList for tree_ctrl + m_icons->RemoveAll(); + m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight()); + for (PrusaBitmap& bmp : m_scaled_icons_list) + m_icons->Add(bmp.bmp()); + m_treectrl->AssignImageList(m_icons); + + // rescale options_groups + for (auto page : m_pages) + page->rescale(); + + Layout(); } Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const @@ -1131,10 +1194,10 @@ void TabPrint::build() optgroup->append_single_option_line("complete_objects"); line = { _(L("Extruder clearance (mm)")), "" }; Option option = optgroup->get_option("extruder_clearance_radius"); - option.opt.width = 60; + option.opt.width = 6; line.append_option(option); option = optgroup->get_option("extruder_clearance_height"); - option.opt.width = 60; + option.opt.width = 6; line.append_option(option); optgroup->append_line(line); @@ -1148,14 +1211,14 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0); option = optgroup->get_option("post_process"); option.opt.full_width = true; - option.opt.height = 5 * m_em_unit;//50; + option.opt.height = 5;//50; optgroup->append_single_option_line(option); page = add_options_page(_(L("Notes")), "note.png"); optgroup = page->new_optgroup(_(L("Notes")), 0); option = optgroup->get_option("notes"); option.opt.full_width = true; - option.opt.height = 25 * m_em_unit;//250; + option.opt.height = 25;//250; optgroup->append_single_option_line(option); page = add_options_page(_(L("Dependencies")), "wrench.png"); @@ -1468,7 +1531,7 @@ void TabFilament::build() optgroup->append_single_option_line("bridge_fan_speed"); optgroup->append_single_option_line("disable_fan_first_layers"); - optgroup = page->new_optgroup(_(L("Cooling thresholds")), 250); + optgroup = page->new_optgroup(_(L("Cooling thresholds")), 25); optgroup->append_single_option_line("fan_below_layer_time"); optgroup->append_single_option_line("slowdown_below_layer_time"); optgroup->append_single_option_line("min_print_speed"); @@ -1518,8 +1581,8 @@ void TabFilament::build() }; optgroup->append_line(line); - const int gcode_field_height = 15 * m_em_unit; // 150 - const int notes_field_height = 25 * m_em_unit; // 250 + const int gcode_field_height = 15; // 150 + const int notes_field_height = 25; // 250 page = add_options_page(_(L("Custom G-code")), "cog"); optgroup = page->new_optgroup(_(L("Start G-code")), 0); @@ -1616,8 +1679,8 @@ wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticTex { *StaticText = new ogStaticText(parent, ""); - auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT); - (*StaticText)->SetFont(font); +// auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT); + (*StaticText)->SetFont(wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0); @@ -1639,10 +1702,12 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) } auto printhost_browse = [=](wxWindow* parent) { - auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, - wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap(this, "zoom.png")); +// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, +// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); +// btn->SetBitmap(create_scaled_bitmap(this, "zoom.png")); + add_scaled_button(parent, &m_printhost_browse_btn, "zoom.png", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); + PrusaButton* btn = m_printhost_browse_btn; + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1657,11 +1722,13 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) return sizer; }; - auto print_host_test = [this](wxWindow* parent) { - auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), - wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap(this, "wrench.png")); + auto print_host_test = [this](wxWindow* parent) { +// auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), +// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); +// btn->SetBitmap(create_scaled_bitmap(this, "wrench.png")); + add_scaled_button(parent, &m_print_host_test_btn, "wrench_white", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT); + PrusaButton* btn = m_print_host_test_btn; + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1774,9 +1841,13 @@ void TabPrinter::build_fff() Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { - auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(wxGetApp().small_font()); - btn->SetBitmap(create_scaled_bitmap(this, "printer")); +// auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); +// btn->SetFont(wxGetApp().small_font()); +// btn->SetBitmap(create_scaled_bitmap(this, "printer")); + + PrusaButton* btn; + add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); + btn->SetFont(wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1903,8 +1974,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("use_volumetric_e"); optgroup->append_single_option_line("variable_layer_height"); - const int gcode_field_height = 15 * m_em_unit; // 150 - const int notes_field_height = 25 * m_em_unit; // 250 + const int gcode_field_height = 15; // 150 + const int notes_field_height = 25; // 250 page = add_options_page(_(L("Custom G-code")), "cog"); optgroup = page->new_optgroup(_(L("Start G-code")), 0); option = optgroup->get_option("start_gcode"); @@ -1975,9 +2046,14 @@ void TabPrinter::build_sla() Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { - auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(wxGetApp().small_font()); - btn->SetBitmap(create_scaled_bitmap(this, "printer")); +// auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); +// btn->SetFont(wxGetApp().small_font()); +// btn->SetBitmap(create_scaled_bitmap(this, "printer")); + + PrusaButton* btn; + add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); + btn->SetFont(wxGetApp().normal_font()); + auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -2033,7 +2109,7 @@ void TabPrinter::build_sla() optgroup = page->new_optgroup(_(L("Print Host upload"))); build_printhost(optgroup.get()); - const int notes_field_height = 25 * m_em_unit; // 250 + const int notes_field_height = 25; // 250 page = add_options_page(_(L("Notes")), "note.png"); optgroup = page->new_optgroup(_(L("Notes")), 0); @@ -2088,12 +2164,12 @@ PageShp TabPrinter::build_kinematics_page() // Legend for OptionsGroups auto optgroup = page->new_optgroup(""); optgroup->set_show_modified_btns_val(false); - optgroup->label_width = 23 * m_em_unit;// 230; + optgroup->label_width = 23;// 230; auto line = Line{ "", "" }; ConfigOptionDef def; def.type = coString; - def.width = 150; + def.width = 15; def.gui_type = "legend"; def.mode = comAdvanced; def.tooltip = L("Values in this column are for Full Power mode"); @@ -2887,7 +2963,7 @@ void Tab::toggle_show_hide_incompatible() void Tab::update_show_hide_incompatible_button() { - m_btn_hide_incompatible_presets->SetBitmap(m_show_incompatible_presets ? + m_btn_hide_incompatible_presets->SetBitmap_(m_show_incompatible_presets ? m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets); m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ? "Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." : @@ -2919,10 +2995,11 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep { deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); +// deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); + add_scaled_button(parent, &deps.btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); + deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - deps.btn->SetBitmap(create_scaled_bitmap(this, "printer")); +// deps.btn->SetBitmap(create_scaled_bitmap(this, "printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); @@ -3079,6 +3156,12 @@ void Page::update_visibility(ConfigOptionMode mode) m_show = ret_val; } +void Page::rescale() +{ + for (auto group : m_optgroups) + group->rescale(); +} + Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const { Field* field = nullptr; @@ -3102,18 +3185,23 @@ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value // package Slic3r::GUI::Tab::Page; ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/) { - auto extra_column = [](wxWindow* parent, const Line& line) + auto extra_column = [this](wxWindow* parent, const Line& line) { std::string bmp_name; const std::vector<Option>& options = line.get_options(); - if (options.size() == 0 || options[0].opt.gui_type == "legend") - bmp_name = "";// "error.png"; - else { - auto mode = options[0].opt.mode; //we assume that we have one option per line - bmp_name = mode == comExpert ? "mode_expert_.png" : - mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; - } - auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name)); +// if (options.size() == 0 || options[0].opt.gui_type == "legend") +// bmp_name = ""; +// else { +// auto mode = options[0].opt.mode; //we assume that we have one option per line +// bmp_name = mode == comExpert ? "mode_expert_.png" : +// mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; +// } +// auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name)); + const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap : + m_mode_bitmap_cache[int(options[0].opt.mode)].bmp(); + auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap); + bmp->SetClientData((void*)options[0].opt.mode); + bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; }; @@ -3152,6 +3240,14 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr; }; + optgroup->rescale_extra_column = [this](wxWindow* win) { + auto *ctrl = dynamic_cast<wxStaticBitmap*>(win); + if (ctrl == nullptr) + return; + + ctrl->SetBitmap(m_mode_bitmap_cache[reinterpret_cast<int>(ctrl->GetClientData())].bmp()); + }; + vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); m_optgroups.push_back(optgroup); @@ -3232,7 +3328,7 @@ void TabSLAMaterial::build() optgroup->append_single_option_line("initial_exposure_time"); optgroup = page->new_optgroup(_(L("Corrections"))); - optgroup->label_width = 19 * m_em_unit;//190; + optgroup->label_width = 19;//190; std::vector<std::string> corrections = {"material_correction"}; std::vector<std::string> axes{ "X", "Y", "Z" }; for (auto& opt_key : corrections) { @@ -3241,7 +3337,7 @@ void TabSLAMaterial::build() for (auto& axis : axes) { auto opt = optgroup->get_option(opt_key, id); opt.opt.label = axis; - opt.opt.width = 60; + opt.opt.width = 6; line.append_option(opt); ++id; } @@ -3253,7 +3349,7 @@ void TabSLAMaterial::build() optgroup->label_width = 0; Option option = optgroup->get_option("material_notes"); option.opt.full_width = true; - option.opt.height = 25 * m_em_unit;//250; + option.opt.height = 25;//250; optgroup->append_single_option_line(option); page = add_options_page(_(L("Dependencies")), "wrench.png"); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 1901c9b29..6743c58ac 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -30,14 +30,14 @@ #include "BedShapeDialog.hpp" #include "Event.hpp" - -class PrusaModeSizer; +#include "wxExtensions.hpp" namespace Slic3r { namespace GUI { -typedef std::pair<wxBitmap*, std::string> t_icon_description; -typedef std::vector<std::pair<wxBitmap*, std::string>> t_icon_descriptions; + +typedef std::pair</*wxBitmap*/PrusaBitmap*, std::string> t_icon_description; +typedef std::vector<std::pair</*wxBitmap*/PrusaBitmap*, std::string>> t_icon_descriptions; // Single Tab page containing a{ vsizer } of{ optgroups } // package Slic3r::GUI::Tab::Page; @@ -50,10 +50,11 @@ class Page : public wxScrolledWindow wxBoxSizer* m_vsizer; bool m_show = true; public: - Page(wxWindow* parent, const wxString title, const int iconID) : + Page(wxWindow* parent, const wxString title, const int iconID, const std::vector<PrusaBitmap>& mode_bmp_cache) : m_parent(parent), m_title(title), - m_iconID(iconID) + m_iconID(iconID), + m_mode_bitmap_cache(mode_bmp_cache) { Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); m_vsizer = new wxBoxSizer(wxVERTICAL); @@ -67,6 +68,7 @@ public: // Delayed layout after resizing the main window. bool layout_valid = false; + const std::vector<PrusaBitmap>& m_mode_bitmap_cache; public: std::vector <ConfigOptionsGroupShp> m_optgroups; @@ -79,6 +81,7 @@ public: void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } void reload_config(); void update_visibility(ConfigOptionMode mode); + void rescale(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1); @@ -119,9 +122,9 @@ protected: std::string m_name; const wxString m_title; wxBitmapComboBox* m_presets_choice; - wxBitmapButton* m_btn_save_preset; - wxBitmapButton* m_btn_delete_preset; - wxBitmapButton* m_btn_hide_incompatible_presets; + /*wxBitmap*/PrusaButton* m_btn_save_preset; + /*wxBitmap*/PrusaButton* m_btn_delete_preset; + /*wxBitmap*/PrusaButton* m_btn_hide_incompatible_presets; wxBoxSizer* m_hsizer; wxBoxSizer* m_left_sizer; wxTreeCtrl* m_treectrl; @@ -132,7 +135,7 @@ protected: struct PresetDependencies { Preset::Type type = Preset::TYPE_INVALID; wxCheckBox *checkbox = nullptr; - wxButton *btn = nullptr; + /*wxButton*/PrusaButton *btn = nullptr; std::string key_list; // "compatible_printers" std::string key_condition; std::string dialog_title; @@ -141,25 +144,27 @@ protected: PresetDependencies m_compatible_printers; PresetDependencies m_compatible_prints; - wxButton* m_undo_btn; - wxButton* m_undo_to_sys_btn; - wxButton* m_question_btn; - wxImageList* m_preset_icons; + /*wxButton*/PrusaButton* m_undo_btn; + /*wxButton*/PrusaButton* m_undo_to_sys_btn; + /*wxButton*/PrusaButton* m_question_btn; // Cached bitmaps. // A "flag" icon to be displayned next to the preset name in the Tab's combo box. - wxBitmap m_bmp_show_incompatible_presets; - wxBitmap m_bmp_hide_incompatible_presets; + /*wxBitmap*/PrusaBitmap m_bmp_show_incompatible_presets; + /*wxBitmap*/PrusaBitmap m_bmp_hide_incompatible_presets; // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - wxBitmap m_bmp_value_lock; - wxBitmap m_bmp_value_unlock; - wxBitmap m_bmp_white_bullet; + /*wxBitmap*/PrusaBitmap m_bmp_value_lock; + /*wxBitmap*/PrusaBitmap m_bmp_value_unlock; + /*wxBitmap*/PrusaBitmap m_bmp_white_bullet; // The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset. - wxBitmap *m_bmp_non_system; + /*wxBitmap*/PrusaBitmap *m_bmp_non_system; // Bitmaps to be shown on the "Undo user changes" button next to each input field. - wxBitmap m_bmp_value_revert; -// wxBitmap m_bmp_value_unmodified; - wxBitmap m_bmp_question; + /*wxBitmap*/PrusaBitmap m_bmp_value_revert; + + std::vector<PrusaButton*> m_scaled_buttons = {}; + std::vector<PrusaBitmap*> m_scaled_bitmaps = {}; + std::vector<PrusaBitmap> m_scaled_icons_list = {}; + std::vector<PrusaBitmap> m_mode_bitmap_cache = {}; // Colors for ui "decoration" wxColour m_sys_label_clr; @@ -236,7 +241,11 @@ public: virtual bool supports_printer_technology(const PrinterTechnology tech) = 0; void create_preset_tab(); - void load_current_preset(); + void add_scaled_button(wxWindow* parent, PrusaButton** btn, const std::string& icon_name, + const wxString& label = wxEmptyString, + long style = wxBU_EXACTFIT | wxNO_BORDER); + void add_scaled_bitmap(wxWindow* parent, PrusaBitmap& btn, const std::string& icon_name); + void load_current_preset(); void rebuild_page_tree(); void update_page_tree_visibility(); // Select a new preset, possibly delete the current one. @@ -346,8 +355,8 @@ class TabPrinter : public Tab void build_printhost(ConfigOptionsGroup *optgroup); public: wxButton* m_serial_test_btn = nullptr; - wxButton* m_print_host_test_btn = nullptr; - wxButton* m_printhost_browse_btn = nullptr; + /*wxButton*/PrusaButton* m_print_host_test_btn = nullptr; + /*wxButton*/PrusaButton* m_printhost_browse_btn = nullptr; size_t m_extruders_count; size_t m_extruders_count_old = 0; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index f3c6dd081..c98c45295 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2394,22 +2394,23 @@ void PrusaLockButton::enter_button(const bool enter) PrusaModeButton::PrusaModeButton( wxWindow *parent, wxWindowID id, + const std::string& icon_name/* = ""*/, const wxString& mode/* = wxEmptyString*/, - const wxBitmap& bmp_on/* = wxNullBitmap*/, const wxSize& size/* = wxDefaultSize*/, const wxPoint& pos/* = wxDefaultPosition*/) : - wxButton(parent, id, mode, pos, wxDefaultSize/*size*/, wxBU_EXACTFIT | wxNO_BORDER), - m_bmp_on(bmp_on) +// wxButton(parent, id, mode, pos, wxDefaultSize/*size*/, wxBU_EXACTFIT | wxNO_BORDER), + PrusaButton(parent, id, icon_name, mode, size, pos) +// m_bmp_on(bmp_on) { -#ifdef __WXMSW__ - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -#endif // __WXMSW__ - m_bmp_off = create_scaled_bitmap(this, "mode_off_sq.png"); +// #ifdef __WXMSW__ +// SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +// #endif // __WXMSW__ +// m_bmp_off = create_scaled_bitmap(this, "mode_off_sq.png"); m_tt_focused = wxString::Format(_(L("Switch to the %s mode")), mode); m_tt_selected = wxString::Format(_(L("Current mode is %s")), mode); - SetBitmap(m_bmp_on); +// SetBitmap(m_bmp_on); //button events Bind(wxEVT_BUTTON, &PrusaModeButton::OnButton, this); @@ -2457,19 +2458,19 @@ PrusaModeSizer::PrusaModeSizer(wxWindow *parent, int hgap/* = 10*/) : { SetFlexibleDirection(wxHORIZONTAL); - std::vector<std::pair<wxString, wxBitmap>> buttons = { - {_(L("Simple")), create_scaled_bitmap(parent, "mode_simple_sq.png")}, - {_(L("Advanced")), create_scaled_bitmap(parent, "mode_middle_sq.png")}, - {_(L("Expert")), create_scaled_bitmap(parent, "mode_expert_sq.png")} + std::vector < std::pair < wxString, std::string >> buttons = { + {_(L("Simple")), /*create_scaled_bitmap(parent, */"mode_simple_sq.png"/*)*/}, + {_(L("Advanced")), /*create_scaled_bitmap(parent, */"mode_middle_sq.png"/*)*/}, + {_(L("Expert")), /*create_scaled_bitmap(parent, */"mode_expert_sq.png"/*)*/} }; mode_btns.reserve(3); for (const auto& button : buttons) { - int x, y; - parent->GetTextExtent(button.first, &x, &y, nullptr, nullptr, &Slic3r::GUI::wxGetApp().bold_font()); - const wxSize size = wxSize(x + button.second.GetWidth() + Slic3r::GUI::wxGetApp().em_unit(), - y + Slic3r::GUI::wxGetApp().em_unit()); - mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, button.first, button.second, size)); +// int x, y; +// parent->GetTextExtent(button.first, &x, &y, nullptr, nullptr, &Slic3r::GUI::wxGetApp().bold_font()); +// const wxSize size = wxSize(x + button.second.GetWidth() + Slic3r::GUI::wxGetApp().em_unit(), +// y + Slic3r::GUI::wxGetApp().em_unit()); + mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, button.second, button.first/*, size*/)); } for (auto btn : mode_btns) @@ -2498,6 +2499,12 @@ void PrusaModeSizer::SetMode(const int mode) } +void PrusaModeSizer::rescale() +{ + for (int m = 0; m < mode_btns.size(); m++) + mode_btns[m]->rescale(); +} + // ---------------------------------------------------------------------------- // PrusaMenu // ---------------------------------------------------------------------------- @@ -2516,9 +2523,78 @@ void PrusaMenu::DestroySeparators() } -// ************************************** EXPERIMENTS *************************************** +// ---------------------------------------------------------------------------- +// PrusaBitmap +// ---------------------------------------------------------------------------- +PrusaBitmap::PrusaBitmap(wxWindow *parent, + const std::string& icon_name/* = ""*/): + m_parent(parent), m_icon_name(icon_name) +{ + m_bmp = create_scaled_bitmap(parent, icon_name); +} + + +void PrusaBitmap::rescale() +{ + m_bmp = create_scaled_bitmap(m_parent, m_icon_name); +} + +// ---------------------------------------------------------------------------- +// PrusaButton +// ---------------------------------------------------------------------------- + +PrusaButton::PrusaButton(wxWindow *parent, + wxWindowID id, + const std::string& icon_name/*= ""*/, + const wxString& label /* = wxEmptyString*/, + const wxSize& size /* = wxDefaultSize*/, + const wxPoint& pos /* = wxDefaultPosition*/, + long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : + m_current_icon_name(icon_name), + m_parent(parent) +{ + const wxBitmap bmp = create_scaled_bitmap(parent, icon_name); + Create(parent, id, label, pos, size, style); +#ifdef __WXMSW__ + if (style & wxNO_BORDER) + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif // __WXMSW__ + + SetBitmap(bmp); +} + + +PrusaButton::PrusaButton(wxWindow *parent, + wxWindowID id, + const PrusaBitmap& bitmap, + const wxString& label /*= wxEmptyString*/, + long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : + m_current_icon_name(bitmap.name()), + m_parent(parent) +{ + const wxBitmap& bmp = bitmap.bmp(); + Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); +#ifdef __WXMSW__ + if (style & wxNO_BORDER) + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif // __WXMSW__ + + SetBitmap(bmp); +} + +void PrusaButton::SetBitmap_(const PrusaBitmap& bmp) +{ + SetBitmap(bmp.bmp()); + m_current_icon_name = bmp.name(); +} + +void PrusaButton::rescale() +{ + const wxBitmap bmp = create_scaled_bitmap(m_parent, m_current_icon_name); + + SetBitmap(bmp); +} -// ***************************************************************************** diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 4a3482abc..bd45103c1 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -882,18 +882,79 @@ private: }; + +// ---------------------------------------------------------------------------- +// PrusaBitmap +// ---------------------------------------------------------------------------- + +class PrusaBitmap +{ +public: + PrusaBitmap() {}; + PrusaBitmap( wxWindow *parent, const std::string& icon_name = ""); + + ~PrusaBitmap() {} + + void rescale(); + + const wxBitmap& bmp() const { return m_bmp; } + const std::string& name() const { return m_icon_name; } + +private: + wxWindow* m_parent {nullptr}; + wxBitmap m_bmp; + std::string m_icon_name = ""; +}; + + +// ---------------------------------------------------------------------------- +// PrusaButton +// ---------------------------------------------------------------------------- + +class PrusaButton : public wxButton +{ +public: + PrusaButton(){} + PrusaButton( + wxWindow *parent, + wxWindowID id, + const std::string& icon_name = "", + const wxString& label = wxEmptyString, + const wxSize& size = wxDefaultSize, + const wxPoint& pos = wxDefaultPosition, + long style = wxBU_EXACTFIT | wxNO_BORDER); + + PrusaButton( + wxWindow *parent, + wxWindowID id, + const PrusaBitmap& bitmap, + const wxString& label = wxEmptyString, + long style = wxBU_EXACTFIT | wxNO_BORDER); + + ~PrusaButton() {} + + void SetBitmap_(const PrusaBitmap& bmp); + + void rescale(); + +private: + wxWindow* m_parent; + std::string m_current_icon_name = ""; +}; + + // ---------------------------------------------------------------------------- // PrusaModeButton // ---------------------------------------------------------------------------- -class PrusaModeButton : public wxButton +class PrusaModeButton : public PrusaButton/*wxButton*/ { public: PrusaModeButton( wxWindow *parent, wxWindowID id, + const std::string& icon_name = "", const wxString& mode = wxEmptyString, - const wxBitmap& bmp_on = wxNullBitmap, const wxSize& size = wxDefaultSize, const wxPoint& pos = wxDefaultPosition); ~PrusaModeButton() {} @@ -910,8 +971,8 @@ protected: private: bool m_is_selected = false; - wxBitmap m_bmp_on; - wxBitmap m_bmp_off; +// wxBitmap m_bmp_on; +// wxBitmap m_bmp_off; wxString m_tt_selected; wxString m_tt_focused; }; @@ -930,6 +991,8 @@ public: void SetMode(const /*ConfigOptionMode*/int mode); + void rescale(); + private: std::vector<PrusaModeButton*> mode_btns; }; @@ -958,8 +1021,5 @@ public: }; -// ******************************* EXPERIMENTS ********************************************** -// ****************************************************************************************** - #endif // slic3r_GUI_wxExtensions_hpp_ From 66fa280964e0797c84342c63e1c9b1342f1b8178 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Sun, 14 Apr 2019 10:57:03 +0200 Subject: [PATCH 03/28] Some code refactoring --- src/slic3r/GUI/BitmapCache.cpp | 3 --- src/slic3r/GUI/Plater.cpp | 10 +++++----- src/slic3r/GUI/PresetBundle.cpp | 24 ++++++++++++++++++------ src/slic3r/GUI/PresetBundle.hpp | 2 +- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index bb4145107..551882410 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -259,9 +259,6 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) { - width = width * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; - height = height * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; - wxImage image(width, height); image.InitAlpha(); unsigned char* imgdata = image.GetData(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cb14d9fe5..d809874b9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -274,7 +274,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * cfg.set_key_value("extruder_colour", colors); wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg); - wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this); + wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this, wxGetApp().em_unit()); wxGetApp().plater()->on_config_change(cfg); } dialog->Destroy(); @@ -800,7 +800,7 @@ void Sidebar::update_presets(Preset::Type preset_type) } for (size_t i = 0; i < filament_cnt; i++) { - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); } break; @@ -835,7 +835,7 @@ void Sidebar::update_presets(Preset::Type preset_type) // update the dirty flags. if (print_tech == ptFFF) { for (size_t i = 0; i < p->combos_filament.size(); ++ i) - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); } p->show_preset_comboboxes(); break; @@ -2580,7 +2580,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // TODO: ? if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) { // Only update the platter UI for the 2nd and other filaments. - wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo); + wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo, wxGetApp().em_unit()); } else { wxWindowUpdateLocker noUpdates(sidebar->presets_panel()); @@ -3548,7 +3548,7 @@ void Plater::on_extruders_change(int num_extruders) choices.push_back(choice); // initialize selection - wxGetApp().preset_bundle->update_platter_filament_ui(i, choice); + wxGetApp().preset_bundle->update_platter_filament_ui(i, choice, wxGetApp().em_unit()); ++i; } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index bcf76d958..5fdd38936 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1443,7 +1443,7 @@ void PresetBundle::load_default_preset_bitmaps(wxWindow *window) this->load_compatible_bitmaps(window); } -void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui) +void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em/* = 10*/) { if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA || this->filament_presets.size() <= idx_extruder ) @@ -1468,6 +1468,18 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr wxString selected_str = ""; if (!this->filaments().front().is_visible) ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap)); + + /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. + * So set sizes for solid_colored icons used for filament preset + * and scale then in respect to em_unit value + */ + const float scale_f = em * 0.1f; + const int icon_height = 16 * scale_f + 0.5f; + const int normal_icon_width = 16 * scale_f + 0.5f; + const int space_icon_width = 2 * scale_f + 0.5f; + const int wide_icon_width = 24 * scale_f + 0.5f; + const int thin_icon_width = 8 * scale_f + 0.5f; + for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) { const Preset &preset = this->filaments.preset(i); bool selected = this->filament_presets[idx_extruder] == preset.name; @@ -1491,17 +1503,17 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr std::vector<wxBitmap> bmps; if (wide_icons) // Paint a red flag for incompatible presets. - bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(16, 16) : *m_bitmapIncompatible); + bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(normal_icon_width, icon_height) : *m_bitmapIncompatible); // Paint the color bars. parse_color(filament_rgb, rgb); - bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? 24 : 16, 16, rgb)); + bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? wide_icon_width : normal_icon_width, icon_height, rgb)); if (! single_bar) { parse_color(extruder_rgb, rgb); - bmps.emplace_back(m_bitmapCache->mksolid(8, 16, rgb)); + bmps.emplace_back(m_bitmapCache->mksolid(thin_icon_width, icon_height, rgb)); } // Paint a lock at the system presets. - bmps.emplace_back(m_bitmapCache->mkclear(2, 16)); - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16)); + bmps.emplace_back(m_bitmapCache->mkclear(space_icon_width, icon_height)); + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(normal_icon_width, icon_height)); // (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16)); bitmap = m_bitmapCache->insert(bitmap_key, bmps); } diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 069ebd784..2309ceecd 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -107,7 +107,7 @@ public: void export_configbundle(const std::string &path, bool export_system_settings = false); // Update a filament selection combo box on the platter for an idx_extruder. - void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui); + void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em = 10); // Enable / disable the "- default -" preset. void set_default_suppressed(bool default_suppressed); From e502b33f41263203cd94039cf6683e511dac3547 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Sun, 14 Apr 2019 13:57:15 +0200 Subject: [PATCH 04/28] Post-merge fix --- src/slic3r/GUI/Tab.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8a7ac0433..8451ad072 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1709,9 +1709,6 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) // wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); // btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); // btn->SetBitmap(create_scaled_bitmap(this, "browse")); -// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, -// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetBitmap(create_scaled_bitmap(this, "zoom.png")); add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); PrusaButton* btn = m_printhost_browse_btn; btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); @@ -1731,15 +1728,11 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) }; auto print_host_test = [this](wxWindow* parent) { - auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), - wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap(this, "test")); - auto print_host_test = [this](wxWindow* parent) { // auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), // wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetBitmap(create_scaled_bitmap(this, "wrench.png")); - add_scaled_button(parent, &m_print_host_test_btn, "wrench_white", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT); +// btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); +// btn->SetBitmap(create_scaled_bitmap(this, "test")); + add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT); PrusaButton* btn = m_print_host_test_btn; btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); From ae2c61160f15e5e8f49e98ff7c329a2ebc4a4df2 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Tue, 16 Apr 2019 10:05:45 +0200 Subject: [PATCH 05/28] Application Scaling for MSW: Added rescale function for DoubleSlider (from Preview), ObjectList, ManipulationPanel and SettingsPanel + Set wider default size for Preset Comboboxes from Tabs (#2023) --- src/slic3r/GUI/Field.cpp | 8 +- src/slic3r/GUI/GUI_ObjectList.cpp | 96 ++++++++-- src/slic3r/GUI/GUI_ObjectList.hpp | 17 +- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 16 +- src/slic3r/GUI/GUI_ObjectSettings.cpp | 6 +- src/slic3r/GUI/GUI_Preview.cpp | 5 + src/slic3r/GUI/GUI_Preview.hpp | 2 + src/slic3r/GUI/MainFrame.cpp | 8 +- src/slic3r/GUI/OptionsGroup.cpp | 39 ++-- src/slic3r/GUI/OptionsGroup.hpp | 7 +- src/slic3r/GUI/Plater.cpp | 14 +- src/slic3r/GUI/Plater.hpp | 2 + src/slic3r/GUI/Tab.cpp | 6 +- src/slic3r/GUI/wxExtensions.cpp | 218 +++++++++++++++++----- src/slic3r/GUI/wxExtensions.hpp | 116 +++++++----- 15 files changed, 398 insertions(+), 162 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 22229d764..80d2753ab 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -424,8 +424,8 @@ int undef_spin_val = -9999; //! Probably, It's not necessary void SpinCtrl::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); wxString text_value = wxString(""); int default_value = 0; @@ -885,8 +885,8 @@ void Choice::rescale() void ColourPicker::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); // Validate the color wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx)); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b9cd2fc98..0a3984d9e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -203,7 +203,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) if (col->GetTitle() == " " && GetSelectedItemsCount()<2) GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); else if (col->GetTitle() == _("Name") && - m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) { + m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.bmp().GetRefData()) { int obj_idx = m_objects_model->GetIdByItem(item); auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats; int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + @@ -395,27 +395,83 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const void ObjectList::init_icons() { - m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier"); - m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part"); - m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer"); - m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker"); +// m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier"); +// m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part"); +// m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer"); +// m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker"); +// +// +// m_bmp_vector.reserve(4); // bitmaps for different types of parts +// m_bmp_vector.push_back(&m_bmp_solidmesh); +// m_bmp_vector.push_back(&m_bmp_modifiermesh); +// m_bmp_vector.push_back(&m_bmp_support_enforcer); +// m_bmp_vector.push_back(&m_bmp_support_blocker); + m_bmp_modifiermesh = PrusaBitmap(nullptr, "add_modifier"); // Add part + m_bmp_solidmesh = PrusaBitmap(nullptr, "add_part"); // Add modifier + m_bmp_support_enforcer = PrusaBitmap(nullptr, "support_enforcer");// Add support enforcer + m_bmp_support_blocker = PrusaBitmap(nullptr, "support_blocker"); // Add support blocker m_bmp_vector.reserve(4); // bitmaps for different types of parts - m_bmp_vector.push_back(&m_bmp_solidmesh); // Add part - m_bmp_vector.push_back(&m_bmp_modifiermesh); // Add modifier - m_bmp_vector.push_back(&m_bmp_support_enforcer); // Add support enforcer - m_bmp_vector.push_back(&m_bmp_support_blocker); // Add support blocker + m_bmp_vector.push_back(&m_bmp_solidmesh.bmp()); + m_bmp_vector.push_back(&m_bmp_modifiermesh.bmp()); + m_bmp_vector.push_back(&m_bmp_support_enforcer.bmp()); + m_bmp_vector.push_back(&m_bmp_support_blocker.bmp()); + + + // Set volumes default bitmaps for the model m_objects_model->SetVolumeBitmaps(m_bmp_vector); // init icon for manifold warning - m_bmp_manifold_warning = create_scaled_bitmap(nullptr, "exclamation"); + m_bmp_manifold_warning = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "exclamation"); // init bitmap for "Split to sub-objects" context menu - m_bmp_split = create_scaled_bitmap(nullptr, "split_parts_SMALL"); + m_bmp_split = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "split_parts_SMALL"); // init bitmap for "Add Settings" context menu - m_bmp_cog = create_scaled_bitmap(nullptr, "cog"); + m_bmp_cog = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "cog"); +} + +void ObjectList::rescale_icons() +{ + m_bmp_vector.clear(); + m_bmp_vector.reserve(4); // bitmaps for different types of parts + for (PrusaBitmap* bitmap : std::vector<PrusaBitmap*> { + &m_bmp_modifiermesh, // Add part + &m_bmp_solidmesh, // Add modifier + &m_bmp_support_enforcer, // Add support enforcer + &m_bmp_support_blocker }) // Add support blocker + { + bitmap->rescale(); + m_bmp_vector.push_back(& bitmap->bmp()); + } + // Set volumes default bitmaps for the model + m_objects_model->SetVolumeBitmaps(m_bmp_vector); + + m_bmp_manifold_warning.rescale(); + m_bmp_split.rescale(); + m_bmp_cog.rescale(); + + + // Update CATEGORY_ICON according to new scale + { + // Note: `this` isn't passed to create_scaled_bitmap() here because of bugs in the widget, + // see note in PresetBundle::load_compatible_bitmaps() + + // ptFFF + CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap(nullptr, "layers"); + CATEGORY_ICON[L("Infill")] = create_scaled_bitmap(nullptr, "infill"); + CATEGORY_ICON[L("Support material")] = create_scaled_bitmap(nullptr, "support"); + CATEGORY_ICON[L("Speed")] = create_scaled_bitmap(nullptr, "time"); + CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap(nullptr, "funnel"); + CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap(nullptr, "funnel"); +// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap(nullptr, "skirt+brim"); +// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap(nullptr, "time"); + CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap(nullptr, "wrench"); + // ptSLA + CATEGORY_ICON[L("Supports")] = create_scaled_bitmap(nullptr, "support"/*"sla_supports"*/); + CATEGORY_ICON[L("Pad")] = create_scaled_bitmap(nullptr, "pad"); + } } @@ -533,7 +589,7 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) if (title == " ") show_context_menu(); else if (title == _("Name") && pt.x >15 && - m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) + m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.bmp().GetRefData()) { if (is_windows10()) fix_through_netfabb(); @@ -995,7 +1051,7 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu) wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) { return append_menu_item(menu, wxID_ANY, _(L("Split to parts")), "", - [this](wxCommandEvent&) { split(); }, m_bmp_split, menu); + [this](wxCommandEvent&) { split(); }, m_bmp_split.bmp(), menu); } wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) @@ -1060,7 +1116,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) // Add full settings list auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name); - menu_item->SetBitmap(m_bmp_cog); + menu_item->SetBitmap(m_bmp_cog.bmp()); menu_item->SetSubMenu(create_settings_popupmenu(menu)); @@ -1821,7 +1877,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) stats.facets_added + stats.facets_reversed + stats.backwards_edges; if (errors > 0) { wxVariant variant; - variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning); + variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning.bmp()); m_objects_model->SetValue(variant, item, 0); } @@ -2677,13 +2733,19 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co void ObjectList::rescale() { - // update min size !!! Width shouldn't be a wxDefaultCoord + // update min size !!! A width of control shouldn't be a wxDefaultCoord SetMinSize(wxSize(1, 15 * wxGetApp().em_unit())); GetColumn(0)->SetWidth(19 * wxGetApp().em_unit()); GetColumn(1)->SetWidth(8 * wxGetApp().em_unit()); GetColumn(2)->SetWidth(int(2 * wxGetApp().em_unit())); + // rescale all icons, used by ObjectList + rescale_icons(); + + // rescale/update existingitems with bitmaps + m_objects_model->Rescale(); + Layout(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index d1651748e..8ceb546b5 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -108,13 +108,13 @@ class ObjectList : public wxDataViewCtrl wxBoxSizer *m_sizer {nullptr}; wxWindow *m_parent {nullptr}; - wxBitmap m_bmp_modifiermesh; - wxBitmap m_bmp_solidmesh; - wxBitmap m_bmp_support_enforcer; - wxBitmap m_bmp_support_blocker; - wxBitmap m_bmp_manifold_warning; - wxBitmap m_bmp_cog; - wxBitmap m_bmp_split; + /*wxBitmap*/PrusaBitmap m_bmp_modifiermesh; + /*wxBitmap*/PrusaBitmap m_bmp_solidmesh; + /*wxBitmap*/PrusaBitmap m_bmp_support_enforcer; + /*wxBitmap*/PrusaBitmap m_bmp_support_blocker; + /*wxBitmap*/PrusaBitmap m_bmp_manifold_warning; + /*wxBitmap*/PrusaBitmap m_bmp_cog; + /*wxBitmap*/PrusaBitmap m_bmp_split; PrusaMenu m_menu_object; PrusaMenu m_menu_part; @@ -125,7 +125,7 @@ class ObjectList : public wxDataViewCtrl wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; - std::vector<wxBitmap*> m_bmp_vector; + std::vector<wxBitmap* /*const wxBitmap&*/> m_bmp_vector; int m_selected_object_id = -1; bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select() @@ -176,6 +176,7 @@ public: void update_extruder_values_for_items(const int max_extruder); void init_icons(); + void rescale_icons(); void set_tooltip_for_item(const wxPoint& pt); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 358d85721..185ec26f8 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -117,15 +117,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : m_og->append_line(add_og_to_object_settings(L("Scale"), "%"), &m_scale_Label); m_og->append_line(add_og_to_object_settings(L("Size"), "mm")); - /* Unused parameter at this time - def.label = L("Place on bed"); - def.type = coBool; - def.tooltip = L("Automatic placing of models on printing bed in Y axis"); - def.gui_type = ""; - def.sidetext = ""; - def.default_value = new ConfigOptionBool{ false }; - m_og->append_single_option_line(Option(def, "place_on_bed")); - */ + // call back for a rescale of button "Set uniform scale" + m_og->rescale_near_label_widget = [this](wxWindow* win) { + auto *ctrl = dynamic_cast<PrusaLockButton*>(win); + if (ctrl == nullptr) + return; + ctrl->rescale(); + }; } void ObjectManipulation::Show(const bool show) diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index fb9421a54..a300b7d70 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -127,7 +127,7 @@ void ObjectSettings::update_settings_list() auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column); optgroup->label_width = 15; - optgroup->sidetext_width = 5.5 * wxGetApp().em_unit(); + optgroup->sidetext_width = 5.5; optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { wxGetApp().obj_list()->part_settings_changed(); }; @@ -137,14 +137,14 @@ void ObjectSettings::update_settings_list() if (opt == "extruder") continue; Option option = optgroup->get_option(opt); - option.opt.width = 12 * wxGetApp().em_unit(); + option.opt.width = 12; optgroup->append_single_option_line(option); } optgroup->reload_config(); m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); // call back for rescaling of the extracolumn control - optgroup->rescale_extra_column = [this](wxWindow* win) { + optgroup->rescale_extra_column_item = [this](wxWindow* win) { auto *ctrl = dynamic_cast<PrusaButton*>(win); if (ctrl == nullptr) return; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 206253451..c1961b649 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -396,6 +396,11 @@ void Preview::refresh_print() load_print(true); } +void Preview::rescale_slider() +{ + if (m_slider) m_slider->rescale(); +} + void Preview::bind_event_handlers() { this->Bind(wxEVT_SIZE, &Preview::on_size, this); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index a2929f2e6..34dbd8411 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -120,6 +120,8 @@ public: void reload_print(bool keep_volumes = false); void refresh_print(); + void rescale_slider(); + private: bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index fc4951473..b6fa3521d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -297,16 +297,18 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) */ wxGetApp().preset_bundle->load_default_preset_bitmaps(this); - // update preset comboboxes on Plater - wxGetApp().sidebar().rescale(); + // update Plater + wxGetApp().plater()->rescale(); - // update preset comboboxes on Tabs + // update Tabs for (auto tab : wxGetApp().tabs_list) tab->rescale(); Layout(); Thaw(); + + Refresh(); } // -<- } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index fda6b80ca..724b257d9 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -168,8 +168,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // if we have an extra column, build it if (extra_column) { - m_extra_column_ptrs.push_back(extra_column(this->ctrl_parent(), line)); - grid_sizer->Add(m_extra_column_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3); + m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line)); + grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3); } // Build a label if we have it @@ -189,15 +189,19 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug if (!line.near_label_widget) grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); - else if (line.near_label_widget && line.label.IsEmpty()) - grid_sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7); else { - // If we're here, we have some widget near the label - // so we need a horizontal sizer to arrange these things - auto sizer = new wxBoxSizer(wxHORIZONTAL); - grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); - sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7); - sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); + m_near_label_widget_ptrs.push_back(line.near_label_widget(this->ctrl_parent())); + + if (line.label.IsEmpty()) + grid_sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7); + else { + // If we're here, we have some widget near the label + // so we need a horizontal sizer to arrange these things + auto sizer = new wxBoxSizer(wxHORIZONTAL); + grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); + sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT, 7); + sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); + } } if (line.label_tooltip.compare("") != 0) label->SetToolTip(line.label_tooltip); @@ -269,7 +273,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // add sidetext if any if (option.sidetext != "") { auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, - wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); + /*wxSize(sidetext_width*wxGetApp().em_unit(), -1)*/wxDefaultSize, wxALIGN_LEFT); sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); sidetext->SetFont(wxGetApp().normal_font()); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); @@ -482,10 +486,15 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { void ConfigOptionsGroup::rescale() { - // update bitmaps for mode markers : set new (rescaled) bitmaps - if (rescale_extra_column) - for (auto extra_col : m_extra_column_ptrs) - rescale_extra_column(extra_col); + // update bitmaps for extra column items (like "mode markers" or buttons on settings panel) + if (rescale_extra_column_item) + for (auto extra_col : m_extra_column_item_ptrs) + rescale_extra_column_item(extra_col); + + // update bitmaps for near label widgets (like "Set uniform scale" button on settings panel) + if (rescale_near_label_widget) + for (auto near_label_widget : m_near_label_widget_ptrs) + rescale_near_label_widget(near_label_widget); // update undo buttons : rescale bitmaps for (const auto& field : m_fields) diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 34f571603..95b42591a 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -85,7 +85,6 @@ public: size_t label_width = 20 ;// {200}; wxSizer* sizer {nullptr}; column_t extra_column {nullptr}; - std::function<void(wxWindow* win)> rescale_extra_column { nullptr }; t_change m_on_change { nullptr }; t_kill_focus m_fill_empty_value { nullptr }; t_kill_focus m_set_focus { nullptr }; @@ -93,6 +92,9 @@ public: std::function<DynamicPrintConfig()> m_get_sys_config{ nullptr }; std::function<bool()> have_sys_config{ nullptr }; + std::function<void(wxWindow* win)> rescale_extra_column_item { nullptr }; + std::function<void(wxWindow* win)> rescale_near_label_widget { nullptr }; + wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; int sidetext_width{ -1 }; @@ -192,7 +194,8 @@ protected: std::map<t_config_option_key, Option> m_options; wxWindow* m_parent {nullptr}; std::vector<ConfigOptionMode> m_options_mode; - std::vector<wxWindow*> m_extra_column_ptrs; + std::vector<wxWindow*> m_extra_column_item_ptrs; + std::vector<wxWindow*> m_near_label_widget_ptrs; /// Field list, contains unique_ptrs of the derived type. /// using types that need to know what it is beyond the public interface diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2224eff5e..c06913cc8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -163,7 +163,7 @@ void ObjectInfo::show_sizer(bool show) void ObjectInfo::rescale() { - manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation_mark_")); + manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation")); } enum SlisedInfoIdx @@ -928,8 +928,6 @@ void Sidebar::rescale() p->object_info->rescale(); p->scrolled->Layout(); - p->plater->Layout(); - p->plater->GetParent()->Layout(); } ObjectManipulation* Sidebar::obj_manipul() @@ -3806,6 +3804,16 @@ bool Plater::can_paste_from_clipboard() const return true; } +void Plater::rescale() +{ + p->preview->rescale_slider(); + + p->sidebar->rescale(); + + Layout(); + GetParent()->Layout(); +} + bool Plater::can_delete() const { return p->can_delete(); } bool Plater::can_delete_all() const { return p->can_delete_all(); } bool Plater::can_increase_instances() const { return p->can_increase_instances(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 418e56c84..c40e4c309 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -203,6 +203,8 @@ public: bool can_copy() const; bool can_paste() const; + void rescale(); + private: struct priv; std::unique_ptr<priv> p; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8451ad072..169a2dad7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -110,7 +110,7 @@ void Tab::create_preset_tab() #endif //__WXOSX__ // preset chooser - m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(25 * m_em_unit, -1), 0, 0, wxCB_READONLY); + m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(35 * m_em_unit, -1), 0, 0, wxCB_READONLY); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); @@ -772,7 +772,7 @@ void Tab::rescale() m_mode_sizer->rescale(); - m_presets_choice->SetSize(25 * m_em_unit, -1); + m_presets_choice->SetSize(35 * m_em_unit, -1); m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1)); update_tab_ui(); @@ -3246,7 +3246,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr; }; - optgroup->rescale_extra_column = [this](wxWindow* win) { + optgroup->rescale_extra_column_item = [this](wxWindow* win) { auto *ctrl = dynamic_cast<wxStaticBitmap*>(win); if (ctrl == nullptr) return; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 4479ef70e..4588ab44d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -459,15 +459,43 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, con // ---------------------------------------------------------------------------- // PrusaObjectDataViewModelNode // ---------------------------------------------------------------------------- - +/* void PrusaObjectDataViewModelNode::set_object_action_icon() { m_action_icon = create_scaled_bitmap(nullptr, "advanced_plus"); // FIXME: pass window ptr } void PrusaObjectDataViewModelNode::set_part_action_icon() { m_action_icon = create_scaled_bitmap(nullptr, m_type == itVolume ? "cog" : "set_separate_obj"); // FIXME: pass window ptr } +*/ +void PrusaObjectDataViewModelNode::set_action_icon() +{ + m_action_icon_name = m_type == itObject ? "advanced_plus" : + m_type == itVolume ? "cog" : "set_separate_obj"; + m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); // FIXME: pass window ptr +} Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; +void PrusaObjectDataViewModelNode::update_settings_digest_bitmaps() +{ + m_bmp = m_empty_bmp; + + std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON; + + std::string scaled_bitmap_name = m_name.ToUTF8().data(); + scaled_bitmap_name += "-em" + std::to_string(Slic3r::GUI::wxGetApp().em_unit()); + + wxBitmap *bmp = m_bitmap_cache->find(scaled_bitmap_name); + if (bmp == nullptr) { + std::vector<wxBitmap> bmps; + for (auto& cat : m_opt_categories) + bmps.emplace_back( categories_icon.find(cat) == categories_icon.end() ? + wxNullBitmap : categories_icon.at(cat)); + bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps); + } + + m_bmp = *bmp; +} + bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std::string>& categories) { if (m_type != itSettings || m_opt_categories == categories) @@ -475,15 +503,15 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std: m_opt_categories = categories; m_name = wxEmptyString; - m_bmp = m_empty_bmp; +// m_bmp = m_empty_bmp; - std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON; +// std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON; for (auto& cat : m_opt_categories) m_name += cat + "; "; if (!m_name.IsEmpty()) m_name.erase(m_name.Length()-2, 2); // Delete last "; " - + /* wxBitmap *bmp = m_bitmap_cache->find(m_name.ToUTF8().data()); if (bmp == nullptr) { std::vector<wxBitmap> bmps; @@ -494,10 +522,22 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std: } m_bmp = *bmp; + */ + + update_settings_digest_bitmaps(); return true; } +void PrusaObjectDataViewModelNode::rescale() +{ + if (!m_action_icon_name.empty()) + m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); + + if (!m_opt_categories.empty()) + update_settings_digest_bitmaps(); +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModel @@ -554,6 +594,8 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa root->m_volumes_cnt++; if (insert_position > 0) insert_position++; + + node->m_volume_type = volume_type; } const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[int(volume_type)], extruder_str, root->m_volumes_cnt); @@ -563,6 +605,8 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa ItemAdded(parent_item, child); root->m_volumes_cnt++; + node->m_volume_type = volume_type; + return child; } @@ -1332,8 +1376,6 @@ bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const return node->m_type == itSettings; } - - void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories) { @@ -1354,6 +1396,29 @@ void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const S ItemChanged(item); } +void PrusaObjectDataViewModel::Rescale() +{ + wxDataViewItemArray all_items; + GetAllChildren(wxDataViewItem(0), all_items); + + for (wxDataViewItem item : all_items) + { + if (!item.IsOk()) + continue; + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + node->rescale(); + + if (node->m_type & itVolume) + node->m_bmp = *m_volume_bmps[node->volume_type()]; + + if (node->m_type & itObject && node->m_bmp.IsOk()) + node->m_bmp = create_scaled_bitmap(nullptr, "exclamation"); + + ItemChanged(item); + } +} + //----------------------------------------------------------------------------- // PrusaDataViewBitmapText //----------------------------------------------------------------------------- @@ -1506,21 +1571,21 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX - m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap(this, "right_half_circle.png") : create_scaled_bitmap(this, "up_half_circle.png", 16, true)); - m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap(this, "left_half_circle.png" ) : create_scaled_bitmap(this, "down_half_circle.png", 16, true)); - m_thumb_size = m_bmp_thumb_lower.GetSize(); + m_bmp_thumb_higher = /*wxBitmap*/(style == wxSL_HORIZONTAL ? /*create_scaled_bitmap*/PrusaBitmap(this, "right_half_circle.png") : /*create_scaled_bitmap*/PrusaBitmap(this, "up_half_circle.png", 16, true)); + m_bmp_thumb_lower = /*wxBitmap*/(style == wxSL_HORIZONTAL ? /*create_scaled_bitmap*/PrusaBitmap(this, "left_half_circle.png" ) : /*create_scaled_bitmap*/PrusaBitmap(this, "down_half_circle.png", 16, true)); + m_thumb_size = m_bmp_thumb_lower.bmp().GetSize(); - m_bmp_add_tick_on = create_scaled_bitmap(this, "colorchange_add_on.png"); - m_bmp_add_tick_off = create_scaled_bitmap(this, "colorchange_add_off.png"); - m_bmp_del_tick_on = create_scaled_bitmap(this, "colorchange_delete_on.png"); - m_bmp_del_tick_off = create_scaled_bitmap(this, "colorchange_delete_off.png"); - m_tick_icon_dim = m_bmp_add_tick_on.GetSize().x; + m_bmp_add_tick_on = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_add_on.png"); + m_bmp_add_tick_off = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_add_off.png"); + m_bmp_del_tick_on = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_delete_on.png"); + m_bmp_del_tick_off = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_delete_off.png"); + m_tick_icon_dim = m_bmp_add_tick_on.bmp().GetSize().x; - m_bmp_one_layer_lock_on = create_scaled_bitmap(this, "one_layer_lock_on.png"); - m_bmp_one_layer_lock_off = create_scaled_bitmap(this, "one_layer_lock_off.png"); - m_bmp_one_layer_unlock_on = create_scaled_bitmap(this, "one_layer_unlock_on.png"); - m_bmp_one_layer_unlock_off = create_scaled_bitmap(this, "one_layer_unlock_off.png"); - m_lock_icon_dim = m_bmp_one_layer_lock_on.GetSize().x; + m_bmp_one_layer_lock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_on.png"); + m_bmp_one_layer_lock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_off.png"); + m_bmp_one_layer_unlock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_on.png"); + m_bmp_one_layer_unlock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_off.png"); + m_lock_icon_dim = m_bmp_one_layer_lock_on.bmp().GetSize().x; m_selection = ssUndef; @@ -1538,7 +1603,7 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, Bind(wxEVT_RIGHT_UP, &PrusaDoubleSlider::OnRightUp, this); // control's view variables - SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit();//(style == wxSL_HORIZONTAL ? m_bmp_thumb_higher.GetWidth() : m_bmp_thumb_higher.GetHeight()); + SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); DARK_ORANGE_PEN = wxPen(wxColour(253, 84, 2)); ORANGE_PEN = wxPen(wxColour(253, 126, 66)); @@ -1555,6 +1620,33 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, m_font = is_osx ? font.Smaller().Smaller() : font.Smaller(); } +void PrusaDoubleSlider::rescale() +{ + const wxFont& font = Slic3r::GUI::wxGetApp().normal_font(); + m_font = is_osx ? font.Smaller().Smaller() : font.Smaller(); + + m_bmp_thumb_higher.rescale(); + m_bmp_thumb_lower .rescale(); + m_thumb_size = m_bmp_thumb_lower.bmp().GetSize(); + + m_bmp_add_tick_on .rescale(); + m_bmp_add_tick_off.rescale(); + m_bmp_del_tick_on .rescale(); + m_bmp_del_tick_off.rescale(); + m_tick_icon_dim = m_bmp_add_tick_on.bmp().GetSize().x; + + m_bmp_one_layer_lock_on .rescale(); + m_bmp_one_layer_lock_off .rescale(); + m_bmp_one_layer_unlock_on .rescale(); + m_bmp_one_layer_unlock_off.rescale(); + m_lock_icon_dim = m_bmp_one_layer_lock_on.bmp().GetSize().x; + + SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); + + SetMinSize(get_min_size()); + GetParent()->Layout(); +} + int PrusaDoubleSlider::GetActiveValue() const { return m_selection == ssLower ? @@ -1562,15 +1654,21 @@ int PrusaDoubleSlider::GetActiveValue() const m_higher_value : -1; } +wxSize PrusaDoubleSlider::get_min_size() const +{ + const int min_side = is_horizontal() ? + (is_osx ? 8 : 6) * Slic3r::GUI::wxGetApp().em_unit() : + /*(is_osx ? 10 : 8)*/10 * Slic3r::GUI::wxGetApp().em_unit(); + + return wxSize(min_side, min_side); +} + wxSize PrusaDoubleSlider::DoGetBestSize() const { const wxSize size = wxControl::DoGetBestSize(); if (size.x > 1 && size.y > 1) return size; - const int new_size = is_horizontal() ? - (is_osx ? 8 : 6) * Slic3r::GUI::wxGetApp().em_unit() : - (is_osx ? 10 : 8) * Slic3r::GUI::wxGetApp().em_unit(); - return wxSize(new_size, new_size); + return get_min_size(); } void PrusaDoubleSlider::SetLowerValue(const int lower_val) @@ -1786,9 +1884,12 @@ void PrusaDoubleSlider::render() void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off : &m_bmp_add_tick_on; +// wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off : &m_bmp_add_tick_on; +// if (m_ticks.find(tick) != m_ticks.end()) +// icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off : &m_bmp_del_tick_on; + wxBitmap& icon = m_is_action_icon_focesed ? m_bmp_add_tick_off.bmp() : m_bmp_add_tick_on.bmp(); if (m_ticks.find(tick) != m_ticks.end()) - icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off : &m_bmp_del_tick_on; + icon = m_is_action_icon_focesed ? m_bmp_del_tick_off.bmp() : m_bmp_del_tick_on.bmp(); wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim; @@ -1797,7 +1898,7 @@ void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const w else is_horizontal() ? y_draw = pt_beg.y - m_tick_icon_dim-2 : x_draw = pt_end.x + 3; - dc.DrawBitmap(*icon, x_draw, y_draw); + dc.DrawBitmap(/***/icon, x_draw, y_draw); //update rect of the tick action icon m_rect_tick_action = wxRect(x_draw, y_draw, m_tick_icon_dim, m_tick_icon_dim); @@ -1873,7 +1974,7 @@ void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const Sele y_draw = pos.y - m_thumb_size.y; } } - dc.DrawBitmap(selection == ssLower ? m_bmp_thumb_lower : m_bmp_thumb_higher, x_draw, y_draw); + dc.DrawBitmap(selection == ssLower ? m_bmp_thumb_lower.bmp() : m_bmp_thumb_higher.bmp(), x_draw, y_draw); // Update thumb rect update_thumb_rect(x_draw, y_draw, selection); @@ -1989,9 +2090,12 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc) void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc) { - wxBitmap* icon = m_is_one_layer ? - m_is_one_layer_icon_focesed ? &m_bmp_one_layer_lock_off : &m_bmp_one_layer_lock_on : - m_is_one_layer_icon_focesed ? &m_bmp_one_layer_unlock_off : &m_bmp_one_layer_unlock_on; +// wxBitmap* icon = m_is_one_layer ? +// m_is_one_layer_icon_focesed ? &m_bmp_one_layer_lock_off : &m_bmp_one_layer_lock_on : +// m_is_one_layer_icon_focesed ? &m_bmp_one_layer_unlock_off : &m_bmp_one_layer_unlock_on; + const wxBitmap& icon = m_is_one_layer ? + m_is_one_layer_icon_focesed ? m_bmp_one_layer_lock_off.bmp() : m_bmp_one_layer_lock_on.bmp() : + m_is_one_layer_icon_focesed ? m_bmp_one_layer_unlock_off.bmp() : m_bmp_one_layer_unlock_on.bmp(); int width, height; get_size(&width, &height); @@ -2000,7 +2104,7 @@ void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc) is_horizontal() ? x_draw = width-2 : x_draw = 0.5*width - 0.5*m_lock_icon_dim; is_horizontal() ? y_draw = 0.5*height - 0.5*m_lock_icon_dim : y_draw = height-2; - dc.DrawBitmap(*icon, x_draw, y_draw); + dc.DrawBitmap(/***/icon, x_draw, y_draw); //update rect of the lock/unlock icon m_rect_one_layer_icon = wxRect(x_draw, y_draw, m_lock_icon_dim, m_lock_icon_dim); @@ -2343,17 +2447,17 @@ PrusaLockButton::PrusaLockButton( wxWindow *parent, const wxSize& size /*= wxDefaultSize*/): wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER) { - m_bmp_lock_on = create_scaled_bitmap(this, "one_layer_lock_on.png"); - m_bmp_lock_off = create_scaled_bitmap(this, "one_layer_lock_off.png"); - m_bmp_unlock_on = create_scaled_bitmap(this, "one_layer_unlock_on.png"); - m_bmp_unlock_off = create_scaled_bitmap(this, "one_layer_unlock_off.png"); + m_bmp_lock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_on.png"); + m_bmp_lock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_off.png"); + m_bmp_unlock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_on.png"); + m_bmp_unlock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_off.png"); #ifdef __WXMSW__ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif // __WXMSW__ - SetBitmap(m_bmp_unlock_on); - SetBitmapDisabled(m_bmp_lock_on); + SetBitmap(m_bmp_unlock_on.bmp()); + SetBitmapDisabled(m_bmp_lock_on.bmp()); //button events Bind(wxEVT_BUTTON, &PrusaLockButton::OnButton, this); @@ -2375,12 +2479,25 @@ void PrusaLockButton::SetLock(bool lock) enter_button(true); } +void PrusaLockButton::rescale() +{ + m_bmp_lock_on .rescale(); + m_bmp_lock_off .rescale(); + m_bmp_unlock_on .rescale(); + m_bmp_unlock_off.rescale(); +} + void PrusaLockButton::enter_button(const bool enter) { - wxBitmap* icon = m_is_pushed ? - enter ? &m_bmp_lock_off : &m_bmp_lock_on : - enter ? &m_bmp_unlock_off : &m_bmp_unlock_on; - SetBitmap(*icon); +// wxBitmap* icon = m_is_pushed ? +// enter ? &m_bmp_lock_off : &m_bmp_lock_on : +// enter ? &m_bmp_unlock_off : &m_bmp_unlock_on; +// SetBitmap(*icon); + + const wxBitmap& icon = m_is_pushed ? + enter ? m_bmp_lock_off.bmp() : m_bmp_lock_on.bmp() : + enter ? m_bmp_unlock_off.bmp() : m_bmp_unlock_on.bmp(); + SetBitmap(icon); Refresh(); Update(); @@ -2527,16 +2644,19 @@ void PrusaMenu::DestroySeparators() // PrusaBitmap // ---------------------------------------------------------------------------- PrusaBitmap::PrusaBitmap(wxWindow *parent, - const std::string& icon_name/* = ""*/): - m_parent(parent), m_icon_name(icon_name) + const std::string& icon_name/* = ""*/, + const int px_cnt/* = 16*/, + const bool is_horizontal/* = false*/): + m_parent(parent), m_icon_name(icon_name), + m_px_cnt(px_cnt), m_is_horizontal(is_horizontal) { - m_bmp = create_scaled_bitmap(parent, icon_name); + m_bmp = create_scaled_bitmap(parent, icon_name, px_cnt, is_horizontal); } void PrusaBitmap::rescale() { - m_bmp = create_scaled_bitmap(m_parent, m_icon_name); + m_bmp = create_scaled_bitmap(m_parent, m_icon_name, m_px_cnt, m_is_horizontal); } // ---------------------------------------------------------------------------- @@ -2553,14 +2673,13 @@ PrusaButton::PrusaButton(wxWindow *parent, m_current_icon_name(icon_name), m_parent(parent) { - const wxBitmap bmp = create_scaled_bitmap(parent, icon_name); Create(parent, id, label, pos, size, style); #ifdef __WXMSW__ if (style & wxNO_BORDER) SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif // __WXMSW__ - SetBitmap(bmp); + SetBitmap(create_scaled_bitmap(parent, icon_name)); } @@ -2572,14 +2691,13 @@ PrusaButton::PrusaButton(wxWindow *parent, m_current_icon_name(bitmap.name()), m_parent(parent) { - const wxBitmap& bmp = bitmap.bmp(); Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); #ifdef __WXMSW__ if (style & wxNO_BORDER) SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif // __WXMSW__ - SetBitmap(bmp); + SetBitmap(bitmap.bmp()); } void PrusaButton::SetBitmap_(const PrusaBitmap& bmp) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 597b4fb94..df6191dad 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -233,6 +233,10 @@ class PrusaObjectDataViewModelNode wxBitmap m_empty_bmp; size_t m_volumes_cnt = 0; std::vector< std::string > m_opt_categories; + + std::string m_action_icon_name = ""; + Slic3r::ModelVolumeType m_volume_type; + public: PrusaObjectDataViewModelNode(const wxString &name, const wxString& extruder) { @@ -246,7 +250,9 @@ public: m_container = true; #endif //__WXGTK__ m_extruder = extruder; - set_object_action_icon(); + +// set_object_action_icon(); + set_action_icon(); } PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, @@ -266,7 +272,9 @@ public: // it will be produce "segmentation fault" m_container = true; #endif //__WXGTK__ - set_part_action_icon(); + +// set_part_action_icon(); + set_action_icon(); } PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const ItemType type) : @@ -286,7 +294,8 @@ public: else if (type == itInstance) { m_idx = parent->GetChildCount(); m_name = wxString::Format("Instance_%d", m_idx+1); - set_part_action_icon(); +// set_part_action_icon(); + set_action_icon(); } } @@ -428,9 +437,14 @@ public: } // Set action icons for node - void set_object_action_icon(); - void set_part_action_icon(); - bool update_settings_digest(const std::vector<std::string>& categories); +// void set_object_action_icon(); +// void set_part_action_icon(); + void set_action_icon(); + + void update_settings_digest_bitmaps(); + bool update_settings_digest(const std::vector<std::string>& categories); + int volume_type() const { return int(m_volume_type); } + void rescale(); private: friend class PrusaObjectDataViewModel; }; @@ -527,6 +541,8 @@ public: void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } + // Rescale bitmaps for existing Items + void Rescale(); }; // ---------------------------------------------------------------------------- @@ -675,6 +691,36 @@ private: }; +// ---------------------------------------------------------------------------- +// PrusaBitmap +// ---------------------------------------------------------------------------- + +class PrusaBitmap +{ +public: + PrusaBitmap() {}; + PrusaBitmap(wxWindow *parent, + const std::string& icon_name = "", + const int px_cnt = 16, + const bool is_horizontal = false); + + ~PrusaBitmap() {} + + void rescale(); + + const wxBitmap& bmp() const { return m_bmp; } + wxBitmap& bmp() { return m_bmp; } + const std::string& name() const{ return m_icon_name; } + +private: + wxWindow* m_parent{ nullptr }; + wxBitmap m_bmp = wxBitmap(); + std::string m_icon_name = ""; + int m_px_cnt {16}; + bool m_is_horizontal {false}; +}; + + // ---------------------------------------------------------------------------- // PrusaDoubleSlider // ---------------------------------------------------------------------------- @@ -710,6 +756,8 @@ public: const wxString& name = wxEmptyString); ~PrusaDoubleSlider() {} + void rescale(); + int GetMinValue() const { return m_min_value; } int GetMaxValue() const { return m_max_value; } double GetMinValueD() { return m_values.empty() ? 0. : m_values[m_min_value].second; } @@ -717,6 +765,7 @@ public: int GetLowerValue() const { return m_lower_value; } int GetHigherValue() const { return m_higher_value; } int GetActiveValue() const; + wxSize get_min_size() const ; double GetLowerValueD() { return get_double_value(ssLower); } double GetHigherValueD() { return get_double_value(ssHigher); } wxSize DoGetBestSize() const override; @@ -801,16 +850,16 @@ private: int m_max_value; int m_lower_value; int m_higher_value; - wxBitmap m_bmp_thumb_higher; - wxBitmap m_bmp_thumb_lower; - wxBitmap m_bmp_add_tick_on; - wxBitmap m_bmp_add_tick_off; - wxBitmap m_bmp_del_tick_on; - wxBitmap m_bmp_del_tick_off; - wxBitmap m_bmp_one_layer_lock_on; - wxBitmap m_bmp_one_layer_lock_off; - wxBitmap m_bmp_one_layer_unlock_on; - wxBitmap m_bmp_one_layer_unlock_off; + /*wxBitmap*/PrusaBitmap m_bmp_thumb_higher; + /*wxBitmap*/PrusaBitmap m_bmp_thumb_lower; + /*wxBitmap*/PrusaBitmap m_bmp_add_tick_on; + /*wxBitmap*/PrusaBitmap m_bmp_add_tick_off; + /*wxBitmap*/PrusaBitmap m_bmp_del_tick_on; + /*wxBitmap*/PrusaBitmap m_bmp_del_tick_off; + /*wxBitmap*/PrusaBitmap m_bmp_one_layer_lock_on; + /*wxBitmap*/PrusaBitmap m_bmp_one_layer_lock_off; + /*wxBitmap*/PrusaBitmap m_bmp_one_layer_unlock_on; + /*wxBitmap*/PrusaBitmap m_bmp_one_layer_unlock_off; SelectedSlider m_selection; bool m_is_left_down = false; bool m_is_right_down = false; @@ -869,41 +918,18 @@ public: bool IsLocked() const { return m_is_pushed; } void SetLock(bool lock); + void rescale(); + protected: void enter_button(const bool enter); private: bool m_is_pushed = false; - wxBitmap m_bmp_lock_on; - wxBitmap m_bmp_lock_off; - wxBitmap m_bmp_unlock_on; - wxBitmap m_bmp_unlock_off; -}; - - - -// ---------------------------------------------------------------------------- -// PrusaBitmap -// ---------------------------------------------------------------------------- - -class PrusaBitmap -{ -public: - PrusaBitmap() {}; - PrusaBitmap( wxWindow *parent, const std::string& icon_name = ""); - - ~PrusaBitmap() {} - - void rescale(); - - const wxBitmap& bmp() const { return m_bmp; } - const std::string& name() const { return m_icon_name; } - -private: - wxWindow* m_parent {nullptr}; - wxBitmap m_bmp; - std::string m_icon_name = ""; + /*wxBitmap*/PrusaBitmap m_bmp_lock_on; + /*wxBitmap*/PrusaBitmap m_bmp_lock_off; + /*wxBitmap*/PrusaBitmap m_bmp_unlock_on; + /*wxBitmap*/PrusaBitmap m_bmp_unlock_off; }; From fc63a28481ca71cdbd76dc8f50e73443dcb1de1a Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Tue, 16 Apr 2019 12:11:48 +0200 Subject: [PATCH 06/28] Application Scaling for MSW: + Experiments with toolBars scaling + Rescaled warning and printing legends --- src/slic3r/GUI/GLCanvas3D.cpp | 34 +++++++++++++++++++++++++++++----- src/slic3r/GUI/GLCanvas3D.hpp | 9 +++++++++ src/slic3r/GUI/GUI_Preview.cpp | 9 ++++++++- src/slic3r/GUI/GUI_Preview.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 4 +++- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0dc3ec83a..c4f0a3a91 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -703,6 +703,7 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool m_warnings.erase(it); if (m_warnings.empty()) { // nothing remains to be shown reset(); + m_msg_text = "";// save information for rescaling return; } } @@ -723,6 +724,10 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool } _generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...) + + // save information for rescaling + m_msg_text = text; + m_is_colored_red = red_colored; } @@ -791,7 +796,9 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL wxMemoryDC memDC; // 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 = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale); + wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment + font.MakeLarger(); font.MakeBold(); memDC.SetFont(font); @@ -892,6 +899,14 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const } } +void GLCanvas3D::WarningTexture::rescale(const GLCanvas3D& canvas) +{ + if (m_msg_text.empty()) + return; + + _generate(m_msg_text, canvas, m_is_colored_red); +} + const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; const unsigned char GLCanvas3D::LegendTexture::Default_Background_Color[3] = { (unsigned char)(DEFAULT_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[2] * 255.0f) }; const unsigned char GLCanvas3D::LegendTexture::Error_Background_Color[3] = { (unsigned char)(ERROR_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[2] * 255.0f) }; @@ -962,7 +977,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c const int scaled_border = Px_Border * scale; // select default font - wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); +// wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); + wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment #ifdef __WXMSW__ // Disabling ClearType works, but the font returned is very different (much thicker) from the default. // msw_disable_cleartype(font); @@ -3150,6 +3166,11 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const return factor * m_bed.get_bounding_box().max_size(); } +void GLCanvas3D::rescale() +{ + m_warning_texture.rescale(*this); +} + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; @@ -3794,7 +3815,8 @@ void GLCanvas3D::_render_gizmos_overlay() const #if ENABLE_RETINA_GL m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor()); #else - m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor()); +// m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor()); + m_gizmos.set_overlay_scale(wxGetApp().em_unit()*0.1f);//! #ys_FIXME_experiment #endif /* __WXMSW__ */ m_gizmos.render_overlay(*this, m_selection); @@ -3806,7 +3828,8 @@ void GLCanvas3D::_render_toolbar() const #if ENABLE_RETINA_GL m_toolbar.set_scale(m_retina_helper->get_scale_factor()); #else - m_toolbar.set_scale(m_canvas->GetContentScaleFactor()); +// m_toolbar.set_scale(m_canvas->GetContentScaleFactor()); + m_toolbar.set_scale(wxGetApp().em_unit()*0.1f);//! #ys_FIXME_experiment #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); @@ -3869,7 +3892,8 @@ void GLCanvas3D::_render_view_toolbar() const #if ENABLE_RETINA_GL m_view_toolbar.set_scale(m_retina_helper->get_scale_factor()); #else - m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor()); +// m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor()); + m_view_toolbar.set_scale(wxGetApp().em_unit()*0.1f); //! #ys_FIXME_experiment #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e81d46f11..32ed94221 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -353,6 +353,9 @@ private: void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas); void render(const GLCanvas3D& canvas) const; + // function used to get an information for rescaling of the warning + void rescale(const GLCanvas3D& canvas); + private: static const unsigned char Background_Color[3]; static const unsigned char Opacity; @@ -360,6 +363,10 @@ private: int m_original_width; int m_original_height; + // information for rescaling of the warning legend + std::string m_msg_text = ""; + bool m_is_colored_red{false}; + // Information about which warnings are currently active. std::vector<Warning> m_warnings; @@ -587,6 +594,8 @@ public: double get_size_proportional_to_max_bed_size(double factor) const; + void rescale(); + private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c1961b649..e4ba4922e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -396,9 +396,16 @@ void Preview::refresh_print() load_print(true); } -void Preview::rescale_slider() +void Preview::rescale() { + // rescale slider if (m_slider) m_slider->rescale(); + + // rescale warning legend on the canvas + get_canvas3d()->rescale(); + + // rescale legend + refresh_print(); } void Preview::bind_event_handlers() diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 34dbd8411..8e5bd2bd1 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -120,7 +120,7 @@ public: void reload_print(bool keep_volumes = false); void refresh_print(); - void rescale_slider(); + void rescale(); private: bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c06913cc8..4811b0555 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3806,7 +3806,9 @@ bool Plater::can_paste_from_clipboard() const void Plater::rescale() { - p->preview->rescale_slider(); + p->preview->rescale(); + + p->view3D->get_canvas3d()->rescale(); p->sidebar->rescale(); From 3b9803ba6ec02c2471ff03c05a7df70e8e40cff5 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Tue, 16 Apr 2019 14:06:09 +0200 Subject: [PATCH 07/28] Fixed crash of build under OSX and Linux. + Added flag to control if application rescale is possible --- src/slic3r/GUI/Field.cpp | 2 +- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/GUI_App.hpp | 2 +- src/slic3r/GUI/GUI_Utils.hpp | 12 +++++---- src/slic3r/GUI/MainFrame.cpp | 47 +++++++++++++++++++++++++++--------- src/slic3r/GUI/MainFrame.hpp | 2 ++ src/slic3r/GUI/Plater.cpp | 3 ++- src/slic3r/GUI/Tab.cpp | 7 +++--- 8 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 80d2753ab..8a98a1ed7 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -846,7 +846,7 @@ void Choice::rescale() wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); - const wxString selection = field->GetStringSelection(); + const wxString selection = field->GetString(field->GetSelection()); /* To correct scaling (set new controll size) of a wxBitmapCombobox * we need to refill control with new bitmaps. So, in our case : diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b0e585cb9..584a96a57 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -325,7 +325,7 @@ void GUI_App::init_fonts() #endif /*__WXMAC__*/ } -void GUI_App::scale_fonts(const float scale_f) +void GUI_App::scale_default_fonts(const float scale_f) { m_small_font = m_small_font.Scaled(scale_f); m_bold_font = m_bold_font.Scaled(scale_f); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 87c773164..8136973ae 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -98,7 +98,7 @@ public: void init_label_colours(); void update_label_colours_from_appconfig(); void init_fonts(); - void scale_fonts(const float scale_f); + void scale_default_fonts(const float scale_f); void set_label_clr_modified(const wxColour& clr); void set_label_clr_sys(const wxColour& clr); diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index d68ac8b0d..b9f98e094 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -67,7 +67,8 @@ public: this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { // ->- - m_prev_scale_factor = m_scale_factor; + if (m_prev_scale_factor < 0) + reset_prev_scale_factor(); // -<- m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; @@ -77,10 +78,11 @@ public: virtual ~DPIAware() {} - float scale_factor() const { return m_scale_factor; } - float prev_scale_factor() const { return m_prev_scale_factor; } - int em_unit() const { return m_em_unit; } - int font_size() const { return m_font_size; } + float scale_factor() const { return m_scale_factor; } + float prev_scale_factor() const { return m_prev_scale_factor; } + void reset_prev_scale_factor() { m_prev_scale_factor = m_scale_factor; } + int em_unit() const { return m_em_unit; } + int font_size() const { return m_font_size; } protected: diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b6fa3521d..03dbb0c0d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -129,6 +129,30 @@ DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAU event.Skip(); }); + Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event) + { + event.Skip(); + + // Suppress application rescaling, when a MainFrame moving is not ended + m_can_rescale_application = false; + // Cash scale factor value before a MainFrame moving + m_scale_factor_cache = scale_factor(); + }); + + Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event) + { + event.Skip(); + + // If scale factor is different after moving of MainFrame ... + m_can_rescale_application = fabs(m_scale_factor_cache - scale_factor()) > 0.0001; + + // ... rescale application + on_dpi_changed(event.GetRect()); + + // set value to _true_ in purpose of possibility of a display dpi changing from System Settings + m_can_rescale_application = true; + }); + wxGetApp().persist_window_geometry(this); update_ui_from_settings(); // FIXME (?) @@ -257,37 +281,38 @@ bool MainFrame::can_delete_all() const } // scale font for existing controls -static void scale(wxWindow *window, const float scale_f) +static void scale_controls_fonts(wxWindow *window, const float scale_f) { auto children = window->GetChildren(); for (auto child : children) { - scale(child, scale_f); + scale_controls_fonts(child, scale_f); child->SetFont(child->GetFont().Scaled(scale_f)); - -// const wxSize& sz = child->GetSize(); -// if (sz != wxDefaultSize) -// child->SetSize(sz*scale_f); } window->Layout(); } void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { + if (!m_can_rescale_application) + return; + printf("WM_DPICHANGED: %.2f\n", scale_factor()); - // ->- const float old_sc_factor = prev_scale_factor(); const float new_sc_factor = scale_factor(); if (fabs(old_sc_factor - new_sc_factor) > 0.001) { + printf("\told_sc_factor: %.2f\n", old_sc_factor); + printf("\tnew_sc_factor: %.2f\n", new_sc_factor); + Freeze(); - scale(this, new_sc_factor / old_sc_factor); - wxGetApp().scale_fonts(new_sc_factor / old_sc_factor); + scale_controls_fonts(this, new_sc_factor / old_sc_factor); + wxGetApp().scale_default_fonts(new_sc_factor / old_sc_factor); const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor; wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); @@ -309,8 +334,8 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) Thaw(); Refresh(); - } - // -<- + reset_prev_scale_factor(); + } } void MainFrame::init_menubar() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index a5d3a1f6d..b6d22f59a 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -44,6 +44,8 @@ struct PresetTab { class MainFrame : public DPIFrame { bool m_loaded {false}; + bool m_can_rescale_application {true}; + float m_scale_factor_cache; wxString m_qs_last_input_file = wxEmptyString; wxString m_qs_last_output_file = wxEmptyString; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4811b0555..93fbe263b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -728,7 +728,8 @@ Sidebar::Sidebar(Plater *parent) // Buttons underneath the scrolled area auto init_btn = [this](wxButton **btn, wxString label) { - *btn = new wxButton(this, wxID_ANY, label); + *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, + wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); (*btn)->SetFont(wxGetApp().bold_font()); }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 169a2dad7..4db781706 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3203,10 +3203,11 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la // mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; // } // auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name)); + int mode_id = int(options[0].opt.mode); const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap : - m_mode_bitmap_cache[int(options[0].opt.mode)].bmp(); + m_mode_bitmap_cache[mode_id].bmp(); auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap); - bmp->SetClientData((void*)options[0].opt.mode); + bmp->SetClientData((void*)&m_mode_bitmap_cache[mode_id]); bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; @@ -3251,7 +3252,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la if (ctrl == nullptr) return; - ctrl->SetBitmap(m_mode_bitmap_cache[reinterpret_cast<int>(ctrl->GetClientData())].bmp()); + ctrl->SetBitmap(reinterpret_cast<PrusaBitmap*>(ctrl->GetClientData())->bmp()); }; vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); From 3e9c0c396e22c2a474c6c4835898218bde4023ad Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Wed, 17 Apr 2019 11:22:30 +0200 Subject: [PATCH 08/28] Code refactoring --- src/slic3r/GUI/GUI_Utils.hpp | 83 ++++++++++++++++++++++++++++------- src/slic3r/GUI/MainFrame.cpp | 85 +++++++----------------------------- src/slic3r/GUI/MainFrame.hpp | 2 - 3 files changed, 84 insertions(+), 86 deletions(-) diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index b9f98e094..ac367a22e 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -59,20 +59,41 @@ public: { m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; - // ->- - m_prev_scale_factor = -1; - // -<- + m_prev_scale_factor = m_scale_factor; recalc_font(); this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { - // ->- - if (m_prev_scale_factor < 0) - reset_prev_scale_factor(); - // -<- - m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; - on_dpi_changed(evt.rect); + + if (!m_can_rescale) + return; + + if (is_new_scale_factor()) + rescale(evt.rect); + }); + + this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event) + { + event.Skip(); + + // Suppress application rescaling, when a MainFrame moving is not ended + m_can_rescale = false; + }); + + this->Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event) + { + event.Skip(); + + m_can_rescale = is_new_scale_factor(); + + // If scale factor is different after moving of MainFrame ... + if (m_can_rescale) + // ... rescale application + rescale(event.GetRect()); + else + // set value to _true_ in purpose of possibility of a display dpi changing from System Settings + m_can_rescale = true; }); } @@ -80,23 +101,21 @@ public: float scale_factor() const { return m_scale_factor; } float prev_scale_factor() const { return m_prev_scale_factor; } - void reset_prev_scale_factor() { m_prev_scale_factor = m_scale_factor; } + int em_unit() const { return m_em_unit; } int font_size() const { return m_font_size; } - protected: virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; - // ->- -// virtual void scale(wxWindow *window, const float& scale) = 0; - // -<- private: float m_scale_factor; - float m_prev_scale_factor; int m_em_unit; int m_font_size; + float m_prev_scale_factor; + bool m_can_rescale{ true }; + void recalc_font() { wxClientDC dc(this); @@ -104,6 +123,40 @@ private: m_font_size = metrics.height; m_em_unit = metrics.averageWidth; } + + // check if new scale is differ from previous + bool is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; } + + // recursive function for scaling fonts for all controls in Window + void scale_controls_fonts(wxWindow *window, const float scale_f) + { + auto children = window->GetChildren(); + + for (auto child : children) { + scale_controls_fonts(child, scale_f); + child->SetFont(child->GetFont().Scaled(scale_f)); + } + + window->Layout(); + } + + void rescale(const wxRect &suggested_rect) + { + this->Freeze(); + + // rescale fonts of all controls + scale_controls_fonts(this, m_scale_factor / m_prev_scale_factor); + + // rescale missed controls sizes and images + on_dpi_changed(suggested_rect); + + this->Layout(); + this->Thaw(); + + // reset previous scale factor from current scale factor value + m_prev_scale_factor = m_scale_factor; + } + }; typedef DPIAware<wxFrame> DPIFrame; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 03dbb0c0d..17f423621 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -129,30 +129,6 @@ DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAU event.Skip(); }); - Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event) - { - event.Skip(); - - // Suppress application rescaling, when a MainFrame moving is not ended - m_can_rescale_application = false; - // Cash scale factor value before a MainFrame moving - m_scale_factor_cache = scale_factor(); - }); - - Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event) - { - event.Skip(); - - // If scale factor is different after moving of MainFrame ... - m_can_rescale_application = fabs(m_scale_factor_cache - scale_factor()) > 0.0001; - - // ... rescale application - on_dpi_changed(event.GetRect()); - - // set value to _true_ in purpose of possibility of a display dpi changing from System Settings - m_can_rescale_application = true; - }); - wxGetApp().persist_window_geometry(this); update_ui_from_settings(); // FIXME (?) @@ -280,62 +256,33 @@ bool MainFrame::can_delete_all() const return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false; } -// scale font for existing controls -static void scale_controls_fonts(wxWindow *window, const float scale_f) -{ - auto children = window->GetChildren(); - - for (auto child : children) - { - scale_controls_fonts(child, scale_f); - - child->SetFont(child->GetFont().Scaled(scale_f)); - } - window->Layout(); -} - void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { - if (!m_can_rescale_application) - return; - - printf("WM_DPICHANGED: %.2f\n", scale_factor()); - const float old_sc_factor = prev_scale_factor(); const float new_sc_factor = scale_factor(); - if (fabs(old_sc_factor - new_sc_factor) > 0.001) - { - printf("\told_sc_factor: %.2f\n", old_sc_factor); - printf("\tnew_sc_factor: %.2f\n", new_sc_factor); + printf("old_sc_factor: %.2f \n", old_sc_factor); + printf("new_sc_factor: %.2f\n\n", new_sc_factor); - Freeze(); + const float relative_scale_factor = new_sc_factor / old_sc_factor; - scale_controls_fonts(this, new_sc_factor / old_sc_factor); - wxGetApp().scale_default_fonts(new_sc_factor / old_sc_factor); + wxGetApp().scale_default_fonts(relative_scale_factor); - const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor; - wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); + // _strange_ workaround for correct em_unit calculation + const int new_em_unit = new_sc_factor * 10;//int(relative_scale_factor*wxGetApp().em_unit()); + wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); - /* Load default preset bitmaps before a tabpanel initialization, - * but after filling of an em_unit value - */ - wxGetApp().preset_bundle->load_default_preset_bitmaps(this); + /* Load default preset bitmaps before a tabpanel initialization, + * but after filling of an em_unit value + */ + wxGetApp().preset_bundle->load_default_preset_bitmaps(this); - // update Plater - wxGetApp().plater()->rescale(); + // update Plater + wxGetApp().plater()->rescale(); - // update Tabs - for (auto tab : wxGetApp().tabs_list) - tab->rescale(); - - Layout(); - - Thaw(); - - Refresh(); - reset_prev_scale_factor(); - } + // update Tabs + for (auto tab : wxGetApp().tabs_list) + tab->rescale(); } void MainFrame::init_menubar() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index b6d22f59a..a5d3a1f6d 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -44,8 +44,6 @@ struct PresetTab { class MainFrame : public DPIFrame { bool m_loaded {false}; - bool m_can_rescale_application {true}; - float m_scale_factor_cache; wxString m_qs_last_input_file = wxEmptyString; wxString m_qs_last_output_file = wxEmptyString; From 077321b228814fbca66937812ea204842582f4b2 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Wed, 17 Apr 2019 21:35:53 +0200 Subject: [PATCH 09/28] Implemented em_unit() function for getting of em_unit value from correct parent. + Added correct em_unit to Fields --- src/slic3r/GUI/Field.cpp | 49 +++++++++++++++++++++------------ src/slic3r/GUI/Field.hpp | 7 +++++ src/slic3r/GUI/wxExtensions.cpp | 24 +++++++++++++++- src/slic3r/GUI/wxExtensions.hpp | 4 ++- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 8a98a1ed7..89310e7c3 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -65,6 +65,9 @@ void Field::PostInitialize() break; } + // initialize m_unit_value + m_em_unit = em_unit(m_parent); + BUILD(); } @@ -212,8 +215,8 @@ bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type) void TextCtrl::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); wxString text_value = wxString(""); @@ -361,8 +364,8 @@ void TextCtrl::rescale() { Field::rescale(); auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); if (size != wxDefaultSize) { @@ -424,8 +427,8 @@ int undef_spin_val = -9999; //! Probably, It's not necessary void SpinCtrl::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); wxString text_value = wxString(""); int default_value = 0; @@ -529,9 +532,9 @@ void SpinCtrl::rescale() } void Choice::BUILD() { - wxSize size(m_width * wxGetApp().em_unit(), -1); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + wxSize size(m_width * m_em_unit, -1); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); wxBitmapComboBox* temp; if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { @@ -856,8 +859,8 @@ void Choice::rescale() */ field->Clear(); wxSize size(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height * wxGetApp().em_unit()); - size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit); + size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * m_em_unit); field->SetSize(size); @@ -885,8 +888,8 @@ void Choice::rescale() void ColourPicker::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); // Validate the color wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx)); @@ -921,7 +924,7 @@ void PointCtrl::BUILD() { auto temp = new wxBoxSizer(wxHORIZONTAL); - const wxSize field_size(4 * wxGetApp().em_unit(), -1); + const wxSize field_size(4 * m_em_unit, -1); auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(0); double val = default_pt(0); @@ -964,6 +967,16 @@ void PointCtrl::BUILD() y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y)); } +void PointCtrl::rescale() +{ + Field::rescale(); + + const wxSize field_size(4 * m_em_unit, -1); + + x_textctrl->SetMinSize(field_size); + y_textctrl->SetMinSize(field_size); +} + void PointCtrl::propagate_value(wxTextCtrl* win) { if (!win->GetValue().empty()) @@ -1009,8 +1022,8 @@ boost::any& PointCtrl::get_value() void StaticText::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); @@ -1029,8 +1042,8 @@ void StaticText::rescale() Field::rescale(); auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height*wxGetApp().em_unit()); - if (m_opt.width >= 0) size.SetWidth(m_opt.width*wxGetApp().em_unit()); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); if (size != wxDefaultSize) { diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 4dfb4e239..c776cadea 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -220,6 +220,9 @@ public: virtual void rescale() { m_Undo_to_sys_btn->rescale(); m_Undo_btn->rescale(); + + // update em_unit value + m_em_unit = em_unit(m_parent); } protected: @@ -241,6 +244,8 @@ protected: // current value boost::any m_value; + int m_em_unit; + bool bEnterPressed = false; friend class OptionsGroup; @@ -432,6 +437,8 @@ public: void set_value(const boost::any& value, bool change_event = false); boost::any& get_value() override; + void rescale() override; + void enable() override { x_textctrl->Enable(); y_textctrl->Enable(); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 4588ab44d..570872363 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -18,6 +18,7 @@ #include "GUI_ObjectList.hpp" #include "libslic3r/GCode/PreviewData.hpp" #include "I18N.hpp" +#include "GUI_Utils.hpp" using Slic3r::GUI::from_u8; @@ -420,6 +421,27 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) } #endif //__WXMSW__ +/* Function for getting of em_unit value from correct parent. + * In most of cases it is m_em_unit value from GUI_App, + * but for DPIDialogs it's its own value. + * This value will be used to correct rescale after moving between + * Displays with different HDPI */ +int em_unit(wxWindow* win) +{ + if (win) { + // get TopLevelWindow for some window + wxWindow* top_win = win; + while (!top_win->IsTopLevel()) + top_win = top_win->GetParent(); + + Slic3r::GUI::DPIDialog* dlg = dynamic_cast<Slic3r::GUI::DPIDialog*>(top_win); + if (dlg) + // An analog of em_unit value from GUI_App. + return 10 * dlg->scale_factor(); + } + + return Slic3r::GUI::wxGetApp().em_unit(); +} // If an icon has horizontal orientation (width > height) call this function with is_horizontal = true wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/) @@ -436,7 +458,7 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, con unsigned int height, width = height = 0; unsigned int& scale_base = is_horizontal ? width : height; - scale_base = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * px_cnt * 0.1f + 0.5f); + scale_base = (unsigned int)(em_unit(win) * px_cnt * 0.1f + 0.5f); std::string bmp_name = bmp_name_in; boost::replace_last(bmp_name, ".png", ""); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index df6191dad..574712849 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,7 +31,9 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler); -wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); +int em_unit(wxWindow* win); + +wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { From e97e8c6af61c6c18634da46ad92b5aec1b932158 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 18 Apr 2019 02:03:40 +0200 Subject: [PATCH 10/28] Overrided on_dpi_changed() for some Dialogs: BedShapeDialog, KBShortcutsDialog, ConfigWizard, Preferences --- src/slic3r/GUI/BedShapeDialog.cpp | 19 +++++++++- src/slic3r/GUI/BedShapeDialog.hpp | 14 +++++--- src/slic3r/GUI/ConfigWizard.cpp | 42 ++++++++++++++++++++-- src/slic3r/GUI/ConfigWizard.hpp | 8 ++++- src/slic3r/GUI/ConfigWizard_private.hpp | 12 ++++++- src/slic3r/GUI/GUI_App.cpp | 12 ++++--- src/slic3r/GUI/GUI_App.hpp | 2 +- src/slic3r/GUI/KBShortcutsDialog.cpp | 46 ++++++++++++++++++------- src/slic3r/GUI/KBShortcutsDialog.hpp | 21 +++++++++-- src/slic3r/GUI/MainFrame.cpp | 16 ++++----- src/slic3r/GUI/OptionsGroup.cpp | 6 ++-- src/slic3r/GUI/Preferences.cpp | 19 ++++++++-- src/slic3r/GUI/Preferences.hpp | 6 +++- 13 files changed, 178 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 7bbf1ac7f..2762f0db7 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -18,6 +18,7 @@ namespace GUI { void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt) { + SetFont(wxGetApp().normal_font()); m_panel = new BedShapePanel(this); m_panel->build_panel(default_pt); @@ -36,6 +37,22 @@ void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt) })); } +void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + const int& em = em_unit(); + m_panel->m_shape_options_book->SetMinSize(wxSize(25 * em, -1)); + + for (auto og : m_panel->m_optgroups) + og->rescale(); + + const wxSize& size = wxSize(50 * em, -1); + + SetMinSize(size); + SetSize(size); + + Refresh(); +} + void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) { // on_change(nullptr); @@ -125,7 +142,7 @@ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title) ConfigOptionsGroupShp optgroup; optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings"))); - optgroup->label_width = 10*wxGetApp().em_unit();//100; + optgroup->label_width = 10; optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { update_shape(); }; diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp index 538fccc34..72e50a05d 100644 --- a/src/slic3r/GUI/BedShapeDialog.hpp +++ b/src/slic3r/GUI/BedShapeDialog.hpp @@ -16,11 +16,8 @@ namespace GUI { using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; class BedShapePanel : public wxPanel { - wxChoicebook* m_shape_options_book; Bed_2D* m_canvas; - std::vector <ConfigOptionsGroupShp> m_optgroups; - public: BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {} ~BedShapePanel() {} @@ -35,18 +32,25 @@ public: // Returns the resulting bed shape polygon. This value will be stored to the ini file. std::vector<Vec2d> GetValue() { return m_canvas->m_bed_shape; } + + wxChoicebook* m_shape_options_book; + std::vector <ConfigOptionsGroupShp> m_optgroups; + }; -class BedShapeDialog : public wxDialog +class BedShapeDialog : public DPIDialog { BedShapePanel* m_panel; public: - BedShapeDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, _(L("Bed Shape")), + BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {} ~BedShapeDialog() {} void build_dialog(ConfigOptionPoints* default_pt); std::vector<Vec2d> GetValue() { return m_panel->GetValue(); } + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; }; } // GUI diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 449c50ad2..641f1cb72 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -632,15 +632,21 @@ 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(PrusaBitmap(parent, "Slic3r_192px_transparent.png", 192)) + , bullet_black(PrusaBitmap(parent, "bullet_black.png")) + , bullet_blue(PrusaBitmap(parent, "bullet_blue.png")) + , bullet_white(PrusaBitmap(parent, "bullet_white.png")) , item_active(0) , item_hover(-1) , last_page((size_t)-1) { - SetMinSize(bg.GetSize()); + SetMinSize(bg.bmp().GetSize()); const wxSize size = GetTextExtent("m"); em = size.x; @@ -652,7 +658,10 @@ 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); SetSizer(sizer); @@ -760,8 +769,12 @@ 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; const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0; const int yinc = item_height(); @@ -772,10 +785,16 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) unsigned x = em/2 + item.indent * em; 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); } + else if (i > item_active) { dc.DrawBitmap(bullet_white.bmp(), x, y + yoff_icon, false); } dc.DrawText(item.label, x + bullet_w + em/2, y + yoff_text); y += yinc; @@ -797,6 +816,18 @@ void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt) evt.Skip(); } +void ConfigWizardIndex::rescale() +{ + bg.rescale(); + SetMinSize(bg.bmp().GetSize()); + logo->SetBitmap(bg.bmp()); + + bullet_black.rescale(); + bullet_blue.rescale(); + bullet_white.rescale(); + Refresh(); +} + // priv @@ -971,9 +1002,10 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese // Public ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) - : wxDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : DPIDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , p(new priv(this)) { + this->SetFont(wxGetApp().normal_font()); p->run_reason = reason; p->load_vendors(); @@ -1117,5 +1149,11 @@ const wxString& ConfigWizard::name(const bool from_menu/* = false*/) return from_menu ? config_wizard_name_menu : config_wizard_name; } +void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect) +{ + p->index->rescale(); + Refresh(); +} + } } diff --git a/src/slic3r/GUI/ConfigWizard.hpp b/src/slic3r/GUI/ConfigWizard.hpp index c9ee05529..b707e525b 100644 --- a/src/slic3r/GUI/ConfigWizard.hpp +++ b/src/slic3r/GUI/ConfigWizard.hpp @@ -5,6 +5,8 @@ #include <wx/dialog.h> +#include "GUI_Utils.hpp" + namespace Slic3r { class PresetBundle; @@ -13,7 +15,7 @@ class PresetUpdater; namespace GUI { -class ConfigWizard: public wxDialog +class ConfigWizard: public DPIDialog { public: // Why is the Wizard run @@ -35,6 +37,10 @@ public: bool run(PresetBundle *preset_bundle, const PresetUpdater *updater); static const wxString& name(const bool from_menu = false); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override ; + private: struct priv; std::unique_ptr<priv> p; diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index df7602adf..b85cc3118 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -210,6 +210,7 @@ public: void go_to(ConfigWizardPage *page); void clear(); + void rescale(); private: struct Item @@ -223,18 +224,27 @@ private: int em; int em_h; - + /* #ys_FIXME_delete_after_testing by VK const wxBitmap bg; const wxBitmap bullet_black; const wxBitmap bullet_blue; const wxBitmap bullet_white; + */ + PrusaBitmap bg; + PrusaBitmap bullet_black; + PrusaBitmap bullet_blue; + PrusaBitmap bullet_white; + wxStaticBitmap* logo; std::vector<Item> items; size_t item_active; ssize_t item_hover; size_t last_page; + /* #ys_FIXME_delete_after_testing by VK int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; } + */ + int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em) + em; } void on_paint(wxPaintEvent &evt); void on_mouse_move(wxMouseEvent &evt); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 584a96a57..39628a9cb 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -325,11 +325,15 @@ void GUI_App::init_fonts() #endif /*__WXMAC__*/ } -void GUI_App::scale_default_fonts(const float scale_f) +void GUI_App::update_fonts() { - m_small_font = m_small_font.Scaled(scale_f); - m_bold_font = m_bold_font.Scaled(scale_f); - m_normal_font = m_normal_font.Scaled(scale_f); + /* Only normal and bold fonts are used for an application rescale, + * because of under MSW small and normal fonts are the same. + * To avoid same rescaling twice, just fill this values + * from rescaled MainFrame + */ + m_normal_font = mainframe->normal_font(); + m_bold_font = mainframe->normal_font().Bold(); } void GUI_App::set_label_clr_modified(const wxColour& clr) { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 8136973ae..6a4626484 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -98,7 +98,7 @@ public: void init_label_colours(); void update_label_colours_from_appconfig(); void init_fonts(); - void scale_default_fonts(const float scale_f); + void update_fonts(); void set_label_clr_modified(const wxColour& clr); void set_label_clr_sys(const wxColour& clr); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index c7fbe8231..bf2ff8286 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -10,14 +10,15 @@ namespace Slic3r { namespace GUI { KBShortcutsDialog::KBShortcutsDialog() - : wxDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - Keyboard Shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) + : DPIDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - Keyboard Shortcuts")), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - auto main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer = new wxBoxSizer(wxVERTICAL); // logo - const wxBitmap logo_bmp = create_scaled_bitmap(this, "Slic3r_32px.png", 32); + m_logo_bmp = PrusaBitmap(this, "Slic3r_32px.png", 32); // fonts wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); @@ -27,7 +28,7 @@ KBShortcutsDialog::KBShortcutsDialog() head_font.SetPointSize(12); #endif // __WXOSX__ - const wxFont& font = wxGetApp().small_font(); + const wxFont& font = wxGetApp().normal_font(); const wxFont& bold_font = wxGetApp().bold_font(); fill_shortcuts(); @@ -43,22 +44,25 @@ KBShortcutsDialog::KBShortcutsDialog() wxBoxSizer* r_sizer = new wxBoxSizer(wxVERTICAL); main_grid_sizer->Add(r_sizer, 0); + m_head_bitmaps.reserve(m_full_shortcuts.size()); + const wxSize topic_size = wxSize(10 * wxGetApp().em_unit(), -1); + for (auto& sc : m_full_shortcuts) { -// auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer; - auto sizer = sc.second.second == 0 ? l_sizer : r_sizer; + auto sizer = sc.second.second == szLeft ? l_sizer : r_sizer; wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10); // logo - auto *logo = new wxStaticBitmap(panel, wxID_ANY, logo_bmp); - hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 15); + m_head_bitmaps.push_back(new wxStaticBitmap(panel, wxID_ANY, m_logo_bmp.bmp())); + hsizer->Add(m_head_bitmaps.back(), 0, wxEXPAND | wxLEFT | wxRIGHT, 15); // head - wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, wxSize(20 * wxGetApp().em_unit(), -1)); + wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, topic_size); head->SetFont(head_font); hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL); + // Shortcuts list auto grid_sizer = new wxFlexGridSizer(2, 5, 15); sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15); @@ -121,7 +125,7 @@ void KBShortcutsDialog::fill_shortcuts() main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list"))); main_shortcuts.push_back(Shortcut(ctrl+"LeftMouse" ,L("Select multiple object/Move multiple object"))); - m_full_shortcuts.push_back(std::make_pair( _(L("Main Shortcuts")), std::make_pair(main_shortcuts, 0) )); + m_full_shortcuts.push_back(std::make_pair(_(L("Main Shortcuts")), std::make_pair(main_shortcuts, szLeft))); Shortcuts plater_shortcuts; @@ -146,7 +150,7 @@ void KBShortcutsDialog::fill_shortcuts() plater_shortcuts.push_back(Shortcut("O", L("Zoom out"))); plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo, keep object selection"))); - m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, 1))); + m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, szRight))); // Shortcuts gizmo_shortcuts; @@ -166,7 +170,7 @@ void KBShortcutsDialog::fill_shortcuts() preview_shortcuts.push_back(Shortcut("U", L("Upper Layer"))); preview_shortcuts.push_back(Shortcut("D", L("Lower Layer"))); - m_full_shortcuts.push_back(std::make_pair( _(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, 0) )); + m_full_shortcuts.push_back(std::make_pair(_(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, szLeft))); Shortcuts layers_slider_shortcuts; @@ -179,7 +183,23 @@ void KBShortcutsDialog::fill_shortcuts() layers_slider_shortcuts.push_back(Shortcut("+", L("Add color change marker for current layer"))); layers_slider_shortcuts.push_back(Shortcut("-", L("Delete color change marker for current layer"))); - m_full_shortcuts.push_back(std::make_pair( _(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, 1) )); + m_full_shortcuts.push_back(std::make_pair(_(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, szRight))); +} + +void KBShortcutsDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + m_logo_bmp.rescale(); + + for (wxStaticBitmap* bmp : m_head_bitmaps) + bmp->SetBitmap(m_logo_bmp.bmp()); + + const int& em = em_unit(); + const wxSize& size = wxSize(85 * em, 75 * em); + + SetMinSize(size); + SetSize(size); + + Refresh(); } void KBShortcutsDialog::onCloseDialog(wxEvent &) diff --git a/src/slic3r/GUI/KBShortcutsDialog.hpp b/src/slic3r/GUI/KBShortcutsDialog.hpp index d8905e1ce..f18e78682 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.hpp +++ b/src/slic3r/GUI/KBShortcutsDialog.hpp @@ -5,24 +5,39 @@ #include <map> #include <vector> +#include "GUI_Utils.hpp" +#include "wxExtensions.hpp" + namespace Slic3r { namespace GUI { -class KBShortcutsDialog : public wxDialog +class KBShortcutsDialog : public DPIDialog/*wxDialog*/ { + enum PLACED_SIZER_ID + { + szLeft = 0, + szRight + }; + typedef std::pair<std::string, std::string> Shortcut; typedef std::vector< Shortcut > Shortcuts; - typedef std::vector< std::pair<wxString, std::pair<Shortcuts, int>> > ShortcutsVec; + typedef std::vector< std::pair<wxString, std::pair<Shortcuts, PLACED_SIZER_ID>> > ShortcutsVec; wxString text_info {wxEmptyString}; - ShortcutsVec m_full_shortcuts; + ShortcutsVec m_full_shortcuts; + wxSizer* main_sizer; + PrusaBitmap m_logo_bmp; + std::vector<wxStaticBitmap*> m_head_bitmaps; public: KBShortcutsDialog(); void fill_shortcuts(); +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + private: void onCloseDialog(wxEvent &); }; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 17f423621..ac4284c12 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -258,18 +258,16 @@ bool MainFrame::can_delete_all() const void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { - const float old_sc_factor = prev_scale_factor(); - const float new_sc_factor = scale_factor(); +// const float old_sc_factor = prev_scale_factor(); +// const float new_sc_factor = scale_factor(); +// +// printf("old_sc_factor: %.2f \n", old_sc_factor); +// printf("new_sc_factor: %.2f\n\n", new_sc_factor); - printf("old_sc_factor: %.2f \n", old_sc_factor); - printf("new_sc_factor: %.2f\n\n", new_sc_factor); - - const float relative_scale_factor = new_sc_factor / old_sc_factor; - - wxGetApp().scale_default_fonts(relative_scale_factor); + wxGetApp().update_fonts(); // _strange_ workaround for correct em_unit calculation - const int new_em_unit = new_sc_factor * 10;//int(relative_scale_factor*wxGetApp().em_unit()); + const int new_em_unit = scale_factor() * 10; wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit)); /* Load default preset bitmaps before a tabpanel initialization, diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 724b257d9..a951d9847 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -500,6 +500,8 @@ void ConfigOptionsGroup::rescale() for (const auto& field : m_fields) field.second->rescale(); + const int em = em_unit(parent()); + // rescale width of label column if (!m_options_mode.empty() && label_width > 1) { @@ -514,7 +516,7 @@ void ConfigOptionsGroup::rescale() { auto label = dynamic_cast<wxStaticText*>(label_item->GetWindow()); if (label != nullptr) { - label->SetMinSize(wxSize(label_width*wxGetApp().em_unit(), -1)); + label->SetMinSize(wxSize(label_width*em, -1)); } } else if (label_item->IsSizer()) // case when we nave near_label_widget @@ -524,7 +526,7 @@ void ConfigOptionsGroup::rescale() { auto label = dynamic_cast<wxStaticText*>(l_item->GetWindow()); if (label != nullptr) { - label->SetMinSize(wxSize(label_width*wxGetApp().em_unit(), -1)); + label->SetMinSize(wxSize(label_width*em, -1)); } } } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 96a2f3618..62bcb9d9b 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -7,7 +7,9 @@ namespace Slic3r { namespace GUI { PreferencesDialog::PreferencesDialog(wxWindow* parent) : - wxDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, wxDefaultSize) { + DPIDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, + wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ build(); } @@ -15,7 +17,7 @@ void PreferencesDialog::build() { auto app_config = get_app_config(); m_optgroup = std::make_shared<ConfigOptionsGroup>(this, _(L("General"))); - m_optgroup->label_width = 40; //400; + m_optgroup->label_width = 40; m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; }; @@ -140,5 +142,18 @@ void PreferencesDialog::accept() wxGetApp().update_ui_from_settings(); } +void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + m_optgroup->rescale(); + + const int& em = em_unit(); + const wxSize& size = wxSize(50 * em, 29 * em); + + SetMinSize(size); + SetSize(size); + + Refresh(); +} + } // GUI } // Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 363daebbc..096a2c906 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -2,6 +2,7 @@ #define slic3r_Preferences_hpp_ #include "GUI.hpp" +#include "GUI_Utils.hpp" #include <wx/dialog.h> #include <map> @@ -11,7 +12,7 @@ namespace GUI { class ConfigOptionsGroup; -class PreferencesDialog : public wxDialog +class PreferencesDialog : public DPIDialog { std::map<std::string, std::string> m_values; std::shared_ptr<ConfigOptionsGroup> m_optgroup; @@ -21,6 +22,9 @@ public: void build(); void accept(); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; }; } // GUI From 9cd3c594be10a92aa943f361c1b63c9a782ac5be Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 18 Apr 2019 15:05:17 +0200 Subject: [PATCH 11/28] Overrided on_dpi_changed() for some Dialogs: AboutDialog, ConfigSnapshotDialog, FirmwareDialog, SysInfoDialog + set correct fonts for KBShortcutsDialog --- src/slic3r/GUI/AboutDialog.cpp | 58 ++++++++++++++++------ src/slic3r/GUI/AboutDialog.hpp | 11 ++++- src/slic3r/GUI/ConfigSnapshotDialog.cpp | 33 +++++++++++-- src/slic3r/GUI/ConfigSnapshotDialog.hpp | 8 +++- src/slic3r/GUI/FirmwareDialog.cpp | 10 +++- src/slic3r/GUI/FirmwareDialog.hpp | 6 ++- src/slic3r/GUI/GUI_App.cpp | 7 ++- src/slic3r/GUI/GUI_Utils.hpp | 18 ++++++- src/slic3r/GUI/KBShortcutsDialog.cpp | 13 ++--- src/slic3r/GUI/SysInfoDialog.cpp | 64 ++++++++++++++++++------- src/slic3r/GUI/SysInfoDialog.hpp | 13 ++++- src/slic3r/GUI/wxExtensions.cpp | 17 ++----- 12 files changed, 194 insertions(+), 64 deletions(-) diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index af3b65530..44d1972bc 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -32,8 +32,11 @@ void AboutDialogLogo::onRepaint(wxEvent &event) } AboutDialog::AboutDialog() - : wxDialog(NULL, wxID_ANY, _(L("About Slic3r")), wxDefaultPosition, wxDefaultSize, wxCAPTION) + : DPIDialog(NULL, wxID_ANY, _(L("About Slic3r")), wxDefaultPosition, + wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { + SetFont(wxGetApp().normal_font()); + wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); SetBackgroundColour(bgr_clr); wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); @@ -42,8 +45,10 @@ AboutDialog::AboutDialog() main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20); // logo - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); - hsizer->Add(logo, 1, wxALIGN_CENTER_VERTICAL); + m_logo_bitmap = PrusaBitmap(this, "Slic3r_192px.png", 192); + m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp()); +// auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); + hsizer->Add(m_logo, 1, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); hsizer->Add(vsizer, 2, wxEXPAND|wxLEFT, 20); @@ -51,8 +56,8 @@ AboutDialog::AboutDialog() // title { wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r Prusa Edition", wxDefaultPosition, wxDefaultSize); - wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - title_font.SetWeight(wxFONTWEIGHT_BOLD); + wxFont title_font = GUI::wxGetApp().bold_font();// wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); +// title_font.SetWeight(wxFONTWEIGHT_BOLD); title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetPointSize(24); title->SetFont(title_font); @@ -63,9 +68,9 @@ AboutDialog::AboutDialog() { auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION); wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); - wxFont version_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont version_font = GetFont();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); #ifdef __WXMSW__ - version_font.SetPointSize(9); + version_font.SetPointSize(/*9*/version_font.GetPointSize()-1); #else version_font.SetPointSize(11); #endif @@ -74,18 +79,18 @@ AboutDialog::AboutDialog() } // text - wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/); + m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/); { - html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); - wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); + wxFont font = GetFont();//GUI::wxGetApp().normal_font(); // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); const int fs = font.GetPointSize()-1; int size[] = {fs,fs,fs,fs,fs,fs,fs}; - html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); - html->SetBorders(2); + m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); + m_html->SetBorders(2); const auto text = wxString::Format( "<html>" "<body bgcolor= %s link= %s>" @@ -101,9 +106,9 @@ AboutDialog::AboutDialog() "</font>" "</body>" "</html>", bgr_clr_str, text_clr_str, text_clr_str); - html->SetPage(text); - vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, 10); - html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); + m_html->SetPage(text); + vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, 10); + m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); } wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE); @@ -118,6 +123,29 @@ AboutDialog::AboutDialog() main_sizer->SetSizeHints(this); } +void AboutDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + m_logo_bitmap.rescale(); + m_logo->SetBitmap(m_logo_bitmap.bmp()); + + const wxFont& font = GetFont(); + const int fs = font.GetPointSize() - 1; + int font_size[] = { fs, fs, fs, fs, fs, fs, fs }; + m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); + + const int& em = em_unit(); + + m_html->SetMinSize(wxSize(-1, 16 * em)); + m_html->Refresh(); + + const wxSize& size = wxSize(65 * em, 30 * em); + + SetMinSize(size); + SetSize(size); + + Refresh(); +} + void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event) { wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref()); diff --git a/src/slic3r/GUI/AboutDialog.hpp b/src/slic3r/GUI/AboutDialog.hpp index 01f7564c5..f74ab52f3 100644 --- a/src/slic3r/GUI/AboutDialog.hpp +++ b/src/slic3r/GUI/AboutDialog.hpp @@ -7,6 +7,9 @@ #include <wx/intl.h> #include <wx/html/htmlwin.h> +#include "GUI_Utils.hpp" +#include "wxExtensions.hpp" + namespace Slic3r { namespace GUI { @@ -20,10 +23,16 @@ private: void onRepaint(wxEvent &event); }; -class AboutDialog : public wxDialog +class AboutDialog : public DPIDialog { + PrusaBitmap m_logo_bitmap; + wxHtmlWindow* m_html; + wxStaticBitmap* m_logo; public: AboutDialog(); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; private: void onLinkClicked(wxHtmlLinkEvent &event); diff --git a/src/slic3r/GUI/ConfigSnapshotDialog.cpp b/src/slic3r/GUI/ConfigSnapshotDialog.cpp index 205e84f57..dd3e46229 100644 --- a/src/slic3r/GUI/ConfigSnapshotDialog.cpp +++ b/src/slic3r/GUI/ConfigSnapshotDialog.cpp @@ -95,21 +95,26 @@ static wxString generate_html_page(const Config::SnapshotDB &snapshot_db, const } ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &on_snapshot) - : wxDialog(NULL, wxID_ANY, _(L("Configuration Snapshots")), wxDefaultPosition, + : DPIDialog(NULL, wxID_ANY, _(L("Configuration Snapshots")), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX) { + this->SetFont(wxGetApp().normal_font()); this->SetBackgroundColour(*wxWHITE); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); this->SetSizer(vsizer); // text - wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); { - wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont font = wxGetApp().normal_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); #ifdef __WXMSW__ - int size[] = {8,8,8,8,11,11,11}; + const int fs = font.GetPointSize(); + const int fs1 = static_cast<int>(0.8f*fs); + const int fs2 = static_cast<int>(1.1f*fs); + int size[] = {fs1, fs1, fs1, fs1, fs2, fs2, fs2}; +// int size[] = {8,8,8,8,11,11,11}; #else int size[] = {11,11,11,11,14,14,14}; #endif @@ -127,6 +132,26 @@ ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); } +void ConfigSnapshotDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + wxFont font = GetFont(); + const int fs = font.GetPointSize(); + const int fs1 = static_cast<int>(0.8f*fs); + const int fs2 = static_cast<int>(1.1f*fs); + int font_size[] = { fs1, fs1, fs1, fs1, fs2, fs2, fs2 }; + + html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); + html->Refresh(); + + const int& em = em_unit(); + const wxSize& size = wxSize(45 * em, 40 * em); + + SetMinSize(size); + SetSize(size); + + Refresh(); +} + void ConfigSnapshotDialog::onLinkClicked(wxHtmlLinkEvent &event) { m_snapshot_to_activate = event.GetLinkInfo().GetHref(); diff --git a/src/slic3r/GUI/ConfigSnapshotDialog.hpp b/src/slic3r/GUI/ConfigSnapshotDialog.hpp index f43fb8ed1..9b8b69ecf 100644 --- a/src/slic3r/GUI/ConfigSnapshotDialog.hpp +++ b/src/slic3r/GUI/ConfigSnapshotDialog.hpp @@ -2,6 +2,7 @@ #define slic3r_GUI_ConfigSnapshotDialog_hpp_ #include "GUI.hpp" +#include "GUI_Utils.hpp" #include <wx/wx.h> #include <wx/intl.h> @@ -14,18 +15,23 @@ namespace Config { class SnapshotDB; } -class ConfigSnapshotDialog : public wxDialog +class ConfigSnapshotDialog : public DPIDialog { public: ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &id); const std::string& snapshot_to_activate() const { return m_snapshot_to_activate; } +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + private: void onLinkClicked(wxHtmlLinkEvent &event); void onCloseDialog(wxEvent &); // If set, it contains a snapshot ID to be restored after the dialog closes. std::string m_snapshot_to_activate; + + wxHtmlWindow* html; }; } // namespace GUI diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 8095a3237..4fdc57679 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -732,7 +732,7 @@ const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) { // Public FirmwareDialog::FirmwareDialog(wxWindow *parent) : - wxDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + GUI::DPIDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), p(new priv(this)) { enum { @@ -748,7 +748,13 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : int min_height = MIN_HEIGHT * em; int min_height_expanded = MIN_HEIGHT_EXPANDED * em; - wxFont status_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + /* get current font from application, + * because of wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) function + * returns font for primary Display + */ + const wxFont& font = GUI::wxGetApp().normal_font(); + SetFont(font); + wxFont status_font = font;//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); status_font.MakeBold(); wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE)); mono_font.MakeSmaller(); diff --git a/src/slic3r/GUI/FirmwareDialog.hpp b/src/slic3r/GUI/FirmwareDialog.hpp index ad048bf5d..a1eac00de 100644 --- a/src/slic3r/GUI/FirmwareDialog.hpp +++ b/src/slic3r/GUI/FirmwareDialog.hpp @@ -4,12 +4,13 @@ #include <memory> #include <wx/dialog.h> +#include "GUI_Utils.hpp" namespace Slic3r { -class FirmwareDialog: public wxDialog +class FirmwareDialog: public GUI::DPIDialog { public: FirmwareDialog(wxWindow *parent); @@ -20,6 +21,9 @@ public: ~FirmwareDialog(); static void run(wxWindow *parent); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override{;} private: struct priv; std::unique_ptr<priv> p; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 39628a9cb..42385bd63 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -682,6 +682,12 @@ void GUI_App::add_config_menu(wxMenuBar *menu) // Take a configuration snapshot. if (check_unsaved_changes()) { wxTextEntryDialog dlg(nullptr, _(L("Taking configuration snapshot")), _(L("Snapshot name"))); + + // set current normal font for dialog children, + // because of just dlg.SetFont(normal_font()) has no result; + for (auto child : dlg.GetChildren()) + child->SetFont(normal_font()); + if (dlg.ShowModal() == wxID_OK) app_config->set("on_snapshot", Slic3r::GUI::Config::SnapshotDB::singleton().take_snapshot( @@ -731,7 +737,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu) get_installed_languages(names, identifiers); if (select_language(names, identifiers)) { save_language(); -// show_info(mainframe->m_tabpanel, _(L("Application will be restarted")), _(L("Attention!"))); _3DScene::remove_all_canvases();// remove all canvas before recreate GUI recreate_GUI(); } diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index ac367a22e..9da6bc8d8 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -58,6 +58,9 @@ public: : P(parent, id, title, pos, size, style, name) { m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; + m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + // An analog of em_unit value from GUI_App. + m_em_unit = std::max<size_t>(10, 10 * m_scale_factor); m_prev_scale_factor = m_scale_factor; @@ -104,6 +107,7 @@ public: int em_unit() const { return m_em_unit; } int font_size() const { return m_font_size; } + const wxFont& normal_font() const { return m_normal_font; } protected: virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; @@ -113,6 +117,7 @@ private: int m_em_unit; int m_font_size; + wxFont m_normal_font; float m_prev_scale_factor; bool m_can_rescale{ true }; @@ -121,7 +126,7 @@ private: wxClientDC dc(this); const auto metrics = dc.GetFontMetrics(); m_font_size = metrics.height; - m_em_unit = metrics.averageWidth; +// m_em_unit = metrics.averageWidth; } // check if new scale is differ from previous @@ -143,9 +148,18 @@ private: void rescale(const wxRect &suggested_rect) { this->Freeze(); + const float relative_scale_factor = m_scale_factor / m_prev_scale_factor; // rescale fonts of all controls - scale_controls_fonts(this, m_scale_factor / m_prev_scale_factor); + scale_controls_fonts(this, relative_scale_factor); + this->SetFont(this->GetFont().Scaled(relative_scale_factor)); + + + // rescale normal_font value + m_normal_font = m_normal_font.Scaled(relative_scale_factor); + + // An analog of em_unit value from GUI_App. + m_em_unit = std::max<size_t>(10, 10 * m_scale_factor); // rescale missed controls sizes and images on_dpi_changed(suggested_rect); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index bf2ff8286..63f331b92 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -13,7 +13,7 @@ KBShortcutsDialog::KBShortcutsDialog() : DPIDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - Keyboard Shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); main_sizer = new wxBoxSizer(wxVERTICAL); @@ -21,16 +21,17 @@ KBShortcutsDialog::KBShortcutsDialog() m_logo_bmp = PrusaBitmap(this, "Slic3r_32px.png", 32); // fonts - wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); + const wxFont& font = wxGetApp().normal_font(); + const wxFont& bold_font = wxGetApp().bold_font(); + SetFont(font); + + wxFont head_font = bold_font;// wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); #ifdef __WXOSX__ head_font.SetPointSize(14); #else - head_font.SetPointSize(12); + head_font.SetPointSize(/*12*/bold_font.GetPointSize() + 2); #endif // __WXOSX__ - const wxFont& font = wxGetApp().normal_font(); - const wxFont& bold_font = wxGetApp().bold_font(); - fill_shortcuts(); auto panel = new wxPanel(this); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 052656974..0067e6438 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -41,10 +41,12 @@ std::string get_main_info(bool format_as_html) } SysInfoDialog::SysInfoDialog() - : wxDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) + : DPIDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) { wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); SetBackgroundColour(bgr_clr); + SetFont(wxGetApp().normal_font()); + wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->SetMinSize(wxSize(50 * wxGetApp().em_unit(), -1)); @@ -52,8 +54,10 @@ SysInfoDialog::SysInfoDialog() main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10); // logo - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); - hsizer->Add(logo, 0, wxALIGN_CENTER_VERTICAL); + m_logo_bmp = PrusaBitmap(this, "Slic3r_192px.png", 192); +// auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); + m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bmp.bmp()); + hsizer->Add(m_logo, 0, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); hsizer->Add(vsizer, 1, wxEXPAND|wxLEFT, 20); @@ -61,8 +65,8 @@ SysInfoDialog::SysInfoDialog() // title { wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_FORK_NAME, wxDefaultPosition, wxDefaultSize); - wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - title_font.SetWeight(wxFONTWEIGHT_BOLD); + wxFont title_font = wxGetApp().bold_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); +// title_font.SetWeight(wxFONTWEIGHT_BOLD); title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetPointSize(22); title->SetFont(title_font); @@ -70,7 +74,7 @@ SysInfoDialog::SysInfoDialog() } // main_info_text - wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont font = wxGetApp().normal_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); @@ -78,10 +82,10 @@ SysInfoDialog::SysInfoDialog() const int fs = font.GetPointSize() - 1; int size[] = { static_cast<int>(fs*1.5), static_cast<int>(fs*1.4), static_cast<int>(fs*1.3), fs, fs, fs, fs }; - wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER); + m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER); { - html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); - html->SetBorders(2); + m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); + m_html->SetBorders(2); const auto text = wxString::Format( "<html>" "<body bgcolor= %s link= %s>" @@ -91,16 +95,16 @@ SysInfoDialog::SysInfoDialog() "</body>" "</html>", bgr_clr_str, text_clr_str, text_clr_str, get_main_info(true)); - html->SetPage(text); - vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit()); + m_html->SetPage(text); + vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit()); } // opengl_info - wxHtmlWindow* opengl_info_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + m_opengl_info_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); { - opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); - opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); - opengl_info_html->SetBorders(10); + m_opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); + m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); + m_opengl_info_html->SetBorders(10); const auto text = wxString::Format( "<html>" "<body bgcolor= %s link= %s>" @@ -110,8 +114,8 @@ SysInfoDialog::SysInfoDialog() "</body>" "</html>", bgr_clr_str, text_clr_str, text_clr_str, _3DScene::get_gl_info(true, true)); - opengl_info_html->SetPage(text); - main_sizer->Add(opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); + m_opengl_info_html->SetPage(text); + main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); } wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); @@ -130,6 +134,32 @@ SysInfoDialog::SysInfoDialog() main_sizer->SetSizeHints(this); } +void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + m_logo_bmp.rescale(); + m_logo->SetBitmap(m_logo_bmp.bmp()); + + wxFont font = GetFont(); + const int fs = font.GetPointSize() - 1; + int font_size[] = { static_cast<int>(fs*1.5), static_cast<int>(fs*1.4), static_cast<int>(fs*1.3), fs, fs, fs, fs }; + + m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); + m_html->Refresh(); + + const int& em = em_unit(); + + m_opengl_info_html->SetMinSize(wxSize(-1, 16 * em)); + m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); + m_opengl_info_html->Refresh(); + + const wxSize& size = wxSize(65 * em, 55 * em); + + SetMinSize(size); + SetSize(size); + + Refresh(); +} + void SysInfoDialog::onCopyToClipboard(wxEvent &) { wxTheClipboard->Open(); diff --git a/src/slic3r/GUI/SysInfoDialog.hpp b/src/slic3r/GUI/SysInfoDialog.hpp index ee1b85ce6..6215d90ca 100644 --- a/src/slic3r/GUI/SysInfoDialog.hpp +++ b/src/slic3r/GUI/SysInfoDialog.hpp @@ -4,14 +4,25 @@ #include <wx/wx.h> #include <wx/html/htmlwin.h> +#include "GUI_Utils.hpp" +#include "wxExtensions.hpp" + namespace Slic3r { namespace GUI { -class SysInfoDialog : public wxDialog +class SysInfoDialog : public DPIDialog { wxString text_info {wxEmptyString}; + PrusaBitmap m_logo_bmp; + wxStaticBitmap* m_logo; + wxHtmlWindow* m_opengl_info_html; + wxHtmlWindow* m_html; + public: SysInfoDialog(); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; private: void onCopyToClipboard(wxEvent &); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 570872363..4dc6b6e2a 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -428,16 +428,11 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) * Displays with different HDPI */ int em_unit(wxWindow* win) { - if (win) { - // get TopLevelWindow for some window - wxWindow* top_win = win; - while (!top_win->IsTopLevel()) - top_win = top_win->GetParent(); - - Slic3r::GUI::DPIDialog* dlg = dynamic_cast<Slic3r::GUI::DPIDialog*>(top_win); + if (win) + { + Slic3r::GUI::DPIDialog* dlg = dynamic_cast<Slic3r::GUI::DPIDialog*>(Slic3r::GUI::find_toplevel_parent(win)); if (dlg) - // An analog of em_unit value from GUI_App. - return 10 * dlg->scale_factor(); + return dlg->em_unit(); } return Slic3r::GUI::wxGetApp().em_unit(); @@ -2574,10 +2569,6 @@ void PrusaModeButton::SetState(const bool state) void PrusaModeButton::focus_button(const bool focus) { -// const wxBitmap& bmp = focus ? m_bmp_on : m_bmp_off; -// SetBitmap(bmp); - -// const wxFont& new_font = focus ? Slic3r::GUI::wxGetApp().bold_font() : Slic3r::GUI::wxGetApp().small_font(); wxFont font = GetFont(); const wxFont& new_font = focus ? font.Bold() : font.GetBaseFont(); From 08b01338a842f3a8dcd8ab9149270f60a13039aa Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Thu, 18 Apr 2019 15:22:58 +0200 Subject: [PATCH 12/28] Fixed missing header (clang is picky) --- src/slic3r/GUI/MainFrame.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index a5d3a1f6d..a8b2be2bc 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -4,6 +4,7 @@ #include "libslic3r/PrintConfig.hpp" #include <wx/frame.h> +#include <wx/settings.h> #include <wx/string.h> #include <string> From e7d65862201894ca7276653a99a21f346fc2f724 Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Thu, 18 Apr 2019 17:16:31 +0200 Subject: [PATCH 13/28] Another missing include --- src/slic3r/GUI/GUI_Utils.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index 9da6bc8d8..25cf25b16 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -16,6 +16,7 @@ #include <wx/panel.h> #include <wx/dcclient.h> #include <wx/debug.h> +#include <wx/settings.h> class wxCheckBox; class wxTopLevelWindow; From 4a20fd7f7e737a5e82773fc5e4693cfff7fb2741 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Sun, 21 Apr 2019 23:12:39 +0200 Subject: [PATCH 14/28] Fix of #1216 --- src/slic3r/GUI/Tab.cpp | 43 ++++++++++++++++++++++++++++++------------ src/slic3r/GUI/Tab.hpp | 2 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a697c7a71..fa064a967 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1881,7 +1881,7 @@ void TabPrinter::build_fff() m_use_silent_mode = val; } } - build_extruder_pages(); + build_unregular_pages(); update_dirty(); on_value_change(opt_key, value); }); @@ -1948,7 +1948,7 @@ void TabPrinter::build_fff() }; optgroup->append_line(line); - build_extruder_pages(); + build_unregular_pages(); #if 0 if (!m_no_controller) @@ -2051,13 +2051,24 @@ void TabPrinter::update_serial_ports() void TabPrinter::extruders_count_changed(size_t extruders_count) { - m_extruders_count = extruders_count; - m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); - m_preset_bundle->update_multi_material_filament_presets(); - build_extruder_pages(); - reload_config(); - on_value_change("extruders_count", extruders_count); - wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count); + bool is_count_changed = false; + if (m_extruders_count != extruders_count) { + m_extruders_count = extruders_count; + m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); + m_preset_bundle->update_multi_material_filament_presets(); + is_count_changed = true; + } + + /* This function should be call in any case because of correct updating/rebuilding + * of unregular pages of a Printer Settings + */ + build_unregular_pages(); +// reload_config(); // #ys_FIXME_delete_after_testing : This function is called from build_extruder_pages() now + + if (is_count_changed) { + on_value_change("extruders_count", extruders_count); + wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count); + } } void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) @@ -2125,8 +2136,13 @@ PageShp TabPrinter::build_kinematics_page() return page; } - -void TabPrinter::build_extruder_pages() +/* Previous name build_extruder_pages(). + * + * This function was renamed because of now it implements not just an extruder pages building, + * but "Machine limits" and "Single extruder MM setup" too + * (These pages can changes according to the another values of a current preset) + * */ +void TabPrinter::build_unregular_pages() { size_t n_before_extruders = 2; // Count of pages before Extruder pages bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin; @@ -2175,7 +2191,7 @@ void TabPrinter::build_extruder_pages() m_has_single_extruder_MM_page = true; } - + // Build missed extruder pages for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { //# build page char buf[512]; @@ -2225,6 +2241,9 @@ void TabPrinter::build_extruder_pages() m_extruders_count_old = m_extruders_count; rebuild_page_tree(); + + // Reload preset pages with current configuration values + reload_config(); } // this gets executed after preset is loaded and before GUI fields are updated diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 58950990c..69cf76043 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -368,7 +368,7 @@ public: void update_serial_ports(); void extruders_count_changed(size_t extruders_count); PageShp build_kinematics_page(); - void build_extruder_pages(); + void build_unregular_pages(); void on_preset_loaded() override; void init_options_list() override; bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; } From ff3f1c9ee044d2ccbda0f310f08b40e84b55f44e Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Mon, 22 Apr 2019 00:17:56 +0200 Subject: [PATCH 15/28] Fixed application crash, if try to change Preset in a moment, when one of unregular pages is selected. + small code refactoring --- src/slic3r/GUI/Tab.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index fa064a967..a73105c1d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2147,6 +2147,12 @@ void TabPrinter::build_unregular_pages() size_t n_before_extruders = 2; // Count of pages before Extruder pages bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin; + /* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages + * and be cause of application crash, when try to change Preset in moment, + * when one of unregular pages is selected. + * */ + Freeze(); + // Add/delete Kinematics page according to is_marlin_flavor size_t existed_page = 0; for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already @@ -2194,9 +2200,8 @@ void TabPrinter::build_unregular_pages() // Build missed extruder pages for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { //# build page - char buf[512]; - sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); - auto page = add_options_page(from_u8(buf), "funnel", true); + const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1)); + auto page = add_options_page(page_name, "funnel", true); m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); auto optgroup = page->new_optgroup(_(L("Size"))); @@ -2239,6 +2244,8 @@ void TabPrinter::build_unregular_pages() m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, m_pages.begin() + n_before_extruders + m_extruders_count_old); + Thaw(); + m_extruders_count_old = m_extruders_count; rebuild_page_tree(); @@ -2511,7 +2518,6 @@ void Tab::rebuild_page_tree() m_treectrl->SelectItem(item); } } -// Thaw(); } void Tab::update_page_tree_visibility() @@ -2747,7 +2753,8 @@ bool Tab::may_switch_to_SLA_preset() void Tab::OnTreeSelChange(wxTreeEvent& event) { - if (m_disable_tree_sel_changed_event) return; + if (m_disable_tree_sel_changed_event) + return; // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952. // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, From 1f02eb704ae2e7df51622c39fd0af60f0fd75114 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Mon, 22 Apr 2019 01:51:10 +0200 Subject: [PATCH 16/28] Code refactoring: Deleted unused variables and _cleaned_ overbusy functions --- src/slic3r/GUI/GUI_ObjectList.cpp | 41 ++++++-------------- src/slic3r/GUI/GUI_ObjectList.hpp | 9 ++--- src/slic3r/GUI/GUI_ObjectSettings.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 55 ++++++++++----------------- src/slic3r/GUI/Tab.cpp | 2 + 5 files changed, 39 insertions(+), 72 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index f8ad8b7bb..fe8b13fb7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -463,8 +463,7 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol items.Add(vol_item); } - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); if (items.size() > 1) { @@ -490,9 +489,7 @@ void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs) items.Add(m_objects_model->GetItemById(object)); } - m_parts_changed = true; wxGetApp().plater()->changed_objects(object_idxs); - m_parts_changed = false; select_items(items); #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME @@ -703,8 +700,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, m_objects_model->GetParent(item))); - m_parts_changed = true; - parts_changed(m_dragged_data.obj_idx()); + changed_object(m_dragged_data.obj_idx()); m_dragged_data.clear(); } @@ -1290,7 +1286,7 @@ void ObjectList::load_subobject(ModelVolumeType type) wxArrayString part_names; load_part((*m_objects)[obj_idx], part_names, type); - parts_changed(obj_idx); + changed_object(obj_idx); for (int i = 0; i < part_names.size(); ++i) { const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), type); @@ -1306,7 +1302,6 @@ void ObjectList::load_part( ModelObject* model_object, { wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); - m_parts_changed = false; wxArrayString input_files; wxGetApp().import_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { @@ -1342,8 +1337,6 @@ void ObjectList::load_part( ModelObject* model_object, // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - - m_parts_changed = true; } } } @@ -1493,8 +1486,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); const auto object_item = m_objects_model->GetTopParent(GetSelection()); select_item(m_objects_model->AddVolumeChild(object_item, name, type)); @@ -1558,8 +1550,7 @@ void ObjectList::del_instances_from_object(const int obj_idx) (*m_objects)[obj_idx]->invalidate_bounding_box(); // ? #ys_FIXME - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); } bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) @@ -1604,8 +1595,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con else return false; - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); return true; } @@ -1655,8 +1645,7 @@ void ObjectList::split() if (parent == item) Expand(parent); - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); } bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) @@ -1713,17 +1702,10 @@ bool ObjectList::can_split_instances() return selection.is_multiple_full_instance() || selection.is_single_full_instance(); } -void ObjectList::part_settings_changed() +// NO_PARAMETERS function call means that changed object index will be determine from Selection() +void ObjectList::changed_object(const int obj_idx/* = -1*/) const { - m_part_settings_changed = true; - wxGetApp().plater()->changed_object(get_selected_obj_idx()); - m_part_settings_changed = false; -} - -void ObjectList::parts_changed(int obj_idx) -{ - wxGetApp().plater()->changed_object(obj_idx); - m_parts_changed = false; + wxGetApp().plater()->changed_object(obj_idx < 0 ? get_selected_obj_idx() : obj_idx); } void ObjectList::part_selection_changed() @@ -2446,8 +2428,7 @@ void ObjectList::change_part_type() volume->set_type(new_type); m_objects_model->SetVolumeType(item, new_type); - m_parts_changed = true; - parts_changed(get_selected_obj_idx()); + changed_object(get_selected_obj_idx()); // Update settings showing, if we have it //(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index a0343100a..7b3b2c744 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -139,8 +139,8 @@ class ObjectList : public wxDataViewCtrl // update_settings_items - updating canvas selection is undesirable, // because it would turn off the gizmos (mainly a problem for the SLA gizmo) - bool m_parts_changed = false; - bool m_part_settings_changed = false; +// bool m_parts_changed = false; +// bool m_part_settings_changed = false; int m_selected_row = 0; wxDataViewItem m_last_selected_item {nullptr}; @@ -225,11 +225,8 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; - bool is_parts_changed() const { return m_parts_changed; } - bool is_part_settings_changed() const { return m_part_settings_changed; } - void part_settings_changed(); - void parts_changed(int obj_idx); + void changed_object(const int obj_idx = -1) const; void part_selection_changed(); // Add object to the list diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 72eeb76de..1c5ca5a32 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -84,7 +84,7 @@ void ObjectSettings::update_settings_list() #endif // __WXMSW__ btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { config->erase(opt_key); - wxGetApp().obj_list()->part_settings_changed(); + wxGetApp().obj_list()->changed_object(); wxTheApp->CallAfter([this]() { wxWindowUpdateLocker noUpdates(m_parent); update_settings_list(); @@ -127,7 +127,7 @@ void ObjectSettings::update_settings_list() optgroup->sidetext_width = 5.5 * wxGetApp().em_unit(); optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { - wxGetApp().obj_list()->part_settings_changed(); }; + wxGetApp().obj_list()->changed_object(); }; for (auto& opt : cat.second) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f908dca92..5bba6ce72 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3709,22 +3709,16 @@ void Plater::changed_object(int obj_idx) { if (obj_idx < 0) return; - auto list = wxGetApp().obj_list(); - wxASSERT(list != nullptr); - if (list == nullptr) - return; - - if (list->is_parts_changed()) { - // recenter and re - align to Z = 0 - auto model_object = p->model.objects[obj_idx]; - model_object->ensure_on_bed(); - if (this->p->printer_technology == ptSLA) { - // Update the SLAPrint from the current Model, so that the reload_scene() - // pulls the correct data, update the 3D scene. - this->p->update_restart_background_process(true, false); - } else - p->view3D->reload_scene(false); + // recenter and re - align to Z = 0 + auto model_object = p->model.objects[obj_idx]; + model_object->ensure_on_bed(); + if (this->p->printer_technology == ptSLA) { + // Update the SLAPrint from the current Model, so that the reload_scene() + // pulls the correct data, update the 3D scene. + this->p->update_restart_background_process(true, false); } + else + p->view3D->reload_scene(false); // update print this->p->schedule_background_process(); @@ -3735,26 +3729,19 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs) if (object_idxs.empty()) return; - auto list = wxGetApp().obj_list(); - wxASSERT(list != nullptr); - if (list == nullptr) - return; - - if (list->is_parts_changed()) { - for (int obj_idx : object_idxs) - { - if (obj_idx < p->model.objects.size()) - // recenter and re - align to Z = 0 - p->model.objects[obj_idx]->ensure_on_bed(); - } - if (this->p->printer_technology == ptSLA) { - // Update the SLAPrint from the current Model, so that the reload_scene() - // pulls the correct data, update the 3D scene. - this->p->update_restart_background_process(true, false); - } - else - p->view3D->reload_scene(false); + for (int obj_idx : object_idxs) + { + if (obj_idx < p->model.objects.size()) + // recenter and re - align to Z = 0 + p->model.objects[obj_idx]->ensure_on_bed(); } + if (this->p->printer_technology == ptSLA) { + // Update the SLAPrint from the current Model, so that the reload_scene() + // pulls the correct data, update the 3D scene. + this->p->update_restart_background_process(true, false); + } + else + p->view3D->reload_scene(false); // update print this->p->schedule_background_process(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a73105c1d..d1347d9e5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1755,6 +1755,8 @@ void TabPrinter::build_fff() auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter")); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); + wxGetApp().sidebar().update_objects_list_extruder_column(m_initial_extruders_count); + const Preset* parent_preset = m_presets->get_selected_preset_parent(); m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size(); From 31c02b6bfbc182ca765c0a238657f6bd2635b05f Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Tue, 23 Apr 2019 08:47:23 +0200 Subject: [PATCH 17/28] Added missing includes --- src/slic3r/GUI/GUI_Utils.hpp | 1 + src/slic3r/GUI/MainFrame.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index e12153625..5418ea430 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -16,6 +16,7 @@ #include <wx/panel.h> #include <wx/dcclient.h> #include <wx/debug.h> +#include <wx/settings.h> class wxCheckBox; class wxTopLevelWindow; diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index a5d3a1f6d..a8b2be2bc 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -4,6 +4,7 @@ #include "libslic3r/PrintConfig.hpp" #include <wx/frame.h> +#include <wx/settings.h> #include <wx/string.h> #include <string> From aa147482b7adac21ea4a979cdf06ec545877f7c5 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Tue, 23 Apr 2019 16:33:06 +0200 Subject: [PATCH 18/28] Added _fiction_ resizing for correct MainFrame rendering after DPI changed_object + Added a calculation of a empty bitmaps inside presets in respect to em_unit (to avoid assert) + Added scaling for PrintHostDialogs and MsgDialog + some code refactoring --- src/slic3r/GUI/MainFrame.cpp | 13 ++++----- src/slic3r/GUI/MsgDialog.cpp | 4 ++- src/slic3r/GUI/Plater.cpp | 30 +++++++++------------ src/slic3r/GUI/Plater.hpp | 2 ++ src/slic3r/GUI/Preset.cpp | 42 ++++++++++++++++++++++------- src/slic3r/GUI/Preset.hpp | 2 +- src/slic3r/GUI/PresetBundle.cpp | 10 ++++--- src/slic3r/GUI/PresetBundle.hpp | 2 +- src/slic3r/GUI/PrintHostDialogs.cpp | 2 +- src/slic3r/GUI/PrintHostDialogs.hpp | 6 ++++- src/slic3r/GUI/Tab.cpp | 2 +- 11 files changed, 73 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 302ab5a02..74cefcb46 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -258,12 +258,6 @@ bool MainFrame::can_delete_all() const void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { -// const float old_sc_factor = prev_scale_factor(); -// const float new_sc_factor = scale_factor(); -// -// printf("old_sc_factor: %.2f \n", old_sc_factor); -// printf("new_sc_factor: %.2f\n\n", new_sc_factor); - wxGetApp().update_fonts(); // _strange_ workaround for correct em_unit calculation @@ -281,6 +275,13 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) // update Tabs for (auto tab : wxGetApp().tabs_list) tab->rescale(); + + /* 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); } void MainFrame::init_menubar() diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index 771599b8e..1de0baff7 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -25,12 +25,14 @@ namespace GUI { MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id, wxBitmap bitmap) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) - , boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)) + , boldfont(wxGetApp().normal_font()/*wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)*/) , content_sizer(new wxBoxSizer(wxVERTICAL)) , btn_sizer(new wxBoxSizer(wxHORIZONTAL)) { boldfont.SetWeight(wxFONTWEIGHT_BOLD); + this->SetFont(wxGetApp().normal_font()); + auto *topsizer = new wxBoxSizer(wxHORIZONTAL); auto *rightsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 377c547e2..1bf8b07ce 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -235,7 +235,8 @@ void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text, const w PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) : wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), 0, nullptr, wxCB_READONLY), preset_type(preset_type), - last_selected(wxNOT_FOUND) + last_selected(wxNOT_FOUND), + m_em_unit(wxGetApp().em_unit()) { Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) { auto selected_item = this->GetSelection(); @@ -280,7 +281,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * cfg.set_key_value("extruder_colour", colors); wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg); - wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this, wxGetApp().em_unit()); + wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this); wxGetApp().plater()->on_config_change(cfg); } dialog->Destroy(); @@ -340,8 +341,7 @@ void PresetComboBox::check_selection() void PresetComboBox::rescale() { - // update min control's height from new scaled size - this->SetMinSize(wxSize(20*wxGetApp().em_unit(), this->GetSize().GetHeight())); + m_em_unit = wxGetApp().em_unit(); edit_btn->rescale(); } @@ -798,8 +798,6 @@ void Sidebar::update_all_preset_comboboxes() PresetBundle &preset_bundle = *wxGetApp().preset_bundle; const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); -// wxWindowUpdateLocker noUpdates_scrolled(p->scrolled); - // Update the print choosers to only contain the compatible presets, update the dirty flags. if (print_tech == ptFFF) preset_bundle.prints.update_platter_ui(p->combo_print); @@ -813,9 +811,8 @@ void Sidebar::update_all_preset_comboboxes() // update the dirty flags. if (print_tech == ptFFF) { for (size_t i = 0; i < p->combos_filament.size(); ++i) - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); } - p->show_preset_comboboxes(); } void Sidebar::update_presets(Preset::Type preset_type) @@ -837,7 +834,7 @@ void Sidebar::update_presets(Preset::Type preset_type) } for (size_t i = 0; i < filament_cnt; i++) { - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); } break; @@ -874,8 +871,8 @@ void Sidebar::update_presets(Preset::Type preset_type) // for (size_t i = 0; i < p->combos_filament.size(); ++ i) // preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); // } -// p->show_preset_comboboxes(); update_all_preset_comboboxes(); + p->show_preset_comboboxes(); break; } @@ -905,19 +902,18 @@ void Sidebar::rescale() p->mode_sizer->rescale(); - // first of all : recreate preset comboboxes, because of - // in AddBitmap() function autonaticaly set the size of controll - update_all_preset_comboboxes(); - // then rescale them to current min size to correct layout of the sidebar + // Rescale preset comboboxes in respect to the current em_unit ... for (PresetComboBox* combo : std::vector<PresetComboBox*> { p->combo_print, p->combo_sla_print, p->combo_sla_material, p->combo_printer } ) combo->rescale(); - for (PresetComboBox* combo : p->combos_filament) combo->rescale(); + // ... then refill them and set min size to correct layout of the sidebar + update_all_preset_comboboxes(); + p->frequently_changed_parameters->get_og(true)->rescale(); p->frequently_changed_parameters->get_og(false)->rescale(); @@ -2669,7 +2665,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // TODO: ? if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) { // Only update the platter UI for the 2nd and other filaments. - wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo, wxGetApp().em_unit()); + wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo); } else { wxWindowUpdateLocker noUpdates(sidebar->presets_panel()); @@ -3650,7 +3646,7 @@ void Plater::on_extruders_change(int num_extruders) choices.push_back(choice); // initialize selection - wxGetApp().preset_bundle->update_platter_filament_ui(i, choice, wxGetApp().em_unit()); + wxGetApp().preset_bundle->update_platter_filament_ui(i, choice); ++i; } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index d2ae72f62..c39256f50 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -57,6 +57,7 @@ public: void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER); void set_extruder_idx(const int extr_idx) { extruder_idx = extr_idx; } int get_extruder_idx() const { return extruder_idx; } + int em_unit() const { return m_em_unit; } void check_selection(); void rescale(); @@ -67,6 +68,7 @@ private: Preset::Type preset_type; int last_selected; int extruder_idx = -1; + int m_em_unit; }; class Sidebar : public wxPanel diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 01a74e15b..9875586ed 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -914,6 +914,16 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) // and draw a red flag in front of the selected preset. bool wide_icons = ! selected_preset.is_compatible && m_bitmap_incompatible != nullptr; + /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. + * So set sizes for solid_colored icons used for filament preset + * and scale them in respect to em_unit value + */ + const float scale_f = ui->em_unit() * 0.1f; + const int icon_height = 16 * scale_f + 0.5f; + const int icon_width = 16 * scale_f + 0.5f; + const int thin_space_icon_width = 4 * scale_f + 0.5f; + const int wide_space_icon_width = 6 * scale_f + 0.5f; + std::map<wxString, wxBitmap*> nonsys_presets; wxString selected = ""; if (!this->m_presets.front().is_visible) @@ -934,13 +944,13 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) std::vector<wxBitmap> bmps; if (wide_icons) // Paint a red flag for incompatible presets. - bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(16, 16) : *m_bitmap_incompatible); + bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(icon_width, icon_height) : *m_bitmap_incompatible); // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(4, 16)); + bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); bmps.emplace_back(*m_bitmap_main_frame); // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(6, 16)); - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); + bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); bmp = m_bitmap_cache->insert(bitmap_key, bmps); } @@ -981,12 +991,12 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) std::vector<wxBitmap> bmps; if (wide_icons) // Paint a red flag for incompatible presets. - bmps.emplace_back(m_bitmap_cache->mkclear(16, 16)); + bmps.emplace_back(m_bitmap_cache->mkclear(icon_width, icon_height)); // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(4, 16)); + bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); bmps.emplace_back(*m_bitmap_main_frame); // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(6, 16)); + bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap); bmp = m_bitmap_cache->insert(bitmap_key, bmps); } @@ -996,10 +1006,14 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) ui->SetSelection(selected_preset_item); ui->SetToolTip(ui->GetString(selected_preset_item)); ui->check_selection(); - ui->Thaw(); + ui->Thaw(); + + // Update control min size after rescale (changed Display DPI under MSW) + if (ui->GetMinWidth() != 20 * ui->em_unit()) + ui->SetMinSize(wxSize(20 * ui->em_unit(), ui->GetSize().GetHeight())); } -size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible) +size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible, const int em/* = 10*/) { if (ui == nullptr) return 0; @@ -1007,6 +1021,14 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati ui->Clear(); size_t selected_preset_item = 0; + /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. + * So set sizes for solid_colored(empty) icons used for preset + * and scale them in respect to em_unit value + */ + const float scale_f = em * 0.1f; + const int icon_height = 16 * scale_f + 0.5f; + const int icon_width = 16 * scale_f + 0.5f; + std::map<wxString, wxBitmap*> nonsys_presets; wxString selected = ""; if (!this->m_presets.front().is_visible) @@ -1025,7 +1047,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp); // Paint a lock at the system presets. - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); bmp = m_bitmap_cache->insert(bitmap_key, bmps); } diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index 6174af623..051a55f66 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -394,7 +394,7 @@ public: // Update the choice UI from the list of presets. // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown. // If an incompatible preset is selected, it is shown as well. - size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible); + size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible, const int em = 10); // Update the choice UI from the list of presets. // Only the compatible presets are shown. // If an incompatible preset is selected, it is shown as well. diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 7de8c99aa..b2fa0a857 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1451,7 +1451,7 @@ void PresetBundle::load_default_preset_bitmaps(wxWindow *window) this->load_compatible_bitmaps(window); } -void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em/* = 10*/) +void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui) { if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA || this->filament_presets.size() <= idx_extruder ) @@ -1479,9 +1479,9 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. * So set sizes for solid_colored icons used for filament preset - * and scale then in respect to em_unit value + * and scale them in respect to em_unit value */ - const float scale_f = em * 0.1f; + const float scale_f = ui->em_unit() * 0.1f; const int icon_height = 16 * scale_f + 0.5f; const int normal_icon_width = 16 * scale_f + 0.5f; const int space_icon_width = 2 * scale_f + 0.5f; @@ -1556,6 +1556,10 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr ui->SetToolTip(ui->GetString(selected_preset_item)); ui->check_selection(); ui->Thaw(); + + // Update control min size after rescale (changed Display DPI under MSW) + if (ui->GetMinWidth() != 20 * ui->em_unit()) + ui->SetMinSize(wxSize(20 * ui->em_unit(), ui->GetSize().GetHeight())); } void PresetBundle::set_default_suppressed(bool default_suppressed) diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 2309ceecd..069ebd784 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -107,7 +107,7 @@ public: void export_configbundle(const std::string &path, bool export_system_settings = false); // Update a filament selection combo box on the platter for an idx_extruder. - void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em = 10); + void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui); // Enable / disable the "- default -" preset. void set_default_suppressed(bool default_suppressed); diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 76185b1ba..4fb03594b 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -131,7 +131,7 @@ wxEvent *PrintHostQueueDialog::Event::Clone() const } PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) - : wxDialog(parent, wxID_ANY, _(L("Print host upload queue")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : DPIDialog(parent, wxID_ANY, _(L("Print host upload queue")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this) , on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this) , on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this) diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp index 105899cf0..e6c46aae6 100644 --- a/src/slic3r/GUI/PrintHostDialogs.hpp +++ b/src/slic3r/GUI/PrintHostDialogs.hpp @@ -41,7 +41,7 @@ private: }; -class PrintHostQueueDialog : public wxDialog +class PrintHostQueueDialog : public DPIDialog { public: class Event : public wxEvent @@ -62,6 +62,10 @@ public: PrintHostQueueDialog(wxWindow *parent); void append_job(const PrintHostJob &job); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override { Refresh(); } + private: enum Column { COL_ID, diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4db781706..ddff9ec49 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -713,7 +713,7 @@ void Tab::update_dirty() void Tab::update_tab_ui() { - m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets); + m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit); } // Load a provied DynamicConfig into the tab, modifying the active preset. From 7185125f9c9c1efeca427b507ea1d4b46d735449 Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Wed, 24 Apr 2019 10:12:23 +0200 Subject: [PATCH 19/28] Fixed out-of-bouds access in RammingChart.cpp in case the ramming was turned off --- src/slic3r/GUI/RammingChart.cpp | 163 ++++++++++++++++---------------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/src/slic3r/GUI/RammingChart.cpp b/src/slic3r/GUI/RammingChart.cpp index 41e5cdfe7..6f71e8616 100644 --- a/src/slic3r/GUI/RammingChart.cpp +++ b/src/slic3r/GUI/RammingChart.cpp @@ -141,6 +141,9 @@ void Chart::mouse_double_clicked(wxMouseEvent& event) { void Chart::recalculate_line() { + m_line_to_draw.clear(); + m_total_volume = 0.f; + std::vector<wxPoint> points; for (auto& but : m_buttons) { points.push_back(wxPoint(math_to_screen(but.get_pos()))); @@ -150,92 +153,88 @@ void Chart::recalculate_line() { break; } } - std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); - - m_line_to_draw.clear(); - m_total_volume = 0.f; - - - // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods - const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point - // false - second ---- || ------- - const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points - std::vector<float> diag(N+1); - std::vector<float> mu(N+1); - std::vector<float> lambda(N+1); - std::vector<float> h(N+1); - std::vector<float> rhs(N+1); - - // let's fill in inner equations - for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x; - std::fill(diag.begin(),diag.end(),2.f); - for (int i=1;i<=N-1;++i) { - mu[i] = h[i]/(h[i]+h[i+1]); - lambda[i] = 1.f - mu[i]; - rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) - - float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) ); - } - - // now fill in the first and last equations, according to boundary conditions: - if (boundary_first_derivative) { - const float endpoints_derivative = 0; - lambda[0] = 1; - mu[N] = 1; - rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative); - rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x)); - } - else { - lambda[0] = 0; - mu[N] = 0; - rhs[0] = 0; - rhs[N] = 0; - } + + // The calculation wouldn't work in case the ramming is to be turned off completely. + if (points.size()>1) { + std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); + + // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods + const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point + // false - second ---- || ------- + const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points + std::vector<float> diag(N+1); + std::vector<float> mu(N+1); + std::vector<float> lambda(N+1); + std::vector<float> h(N+1); + std::vector<float> rhs(N+1); - // the trilinear system is ready to be solved: - for (int i=1;i<=N;++i) { - float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation - diag[i]-= multiple * lambda[i-1]; - rhs[i] -= multiple * rhs[i-1]; - } - // now the back substitution (vector mu contains invalid values from now on): - rhs[N] = rhs[N]/diag[N]; - for (int i=N-1;i>=0;--i) - rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; - - - - - unsigned int i=1; - float y=0.f; - for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) { - if (splines) { - if (i<points.size()-1 && points[i].x < x ) { - ++i; + // let's fill in inner equations + for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x; + std::fill(diag.begin(),diag.end(),2.f); + for (int i=1;i<=N-1;++i) { + mu[i] = h[i]/(h[i]+h[i+1]); + lambda[i] = 1.f - mu[i]; + rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) - + float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) ); + } + + // now fill in the first and last equations, according to boundary conditions: + if (boundary_first_derivative) { + const float endpoints_derivative = 0; + lambda[0] = 1; + mu[N] = 1; + rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative); + rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x)); + } + else { + lambda[0] = 0; + mu[N] = 0; + rhs[0] = 0; + rhs[N] = 0; + } + + // the trilinear system is ready to be solved: + for (int i=1;i<=N;++i) { + float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation + diag[i]-= multiple * lambda[i-1]; + rhs[i] -= multiple * rhs[i-1]; + } + // now the back substitution (vector mu contains invalid values from now on): + rhs[N] = rhs[N]/diag[N]; + for (int i=N-1;i>=0;--i) + rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; + + unsigned int i=1; + float y=0.f; + for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) { + if (splines) { + if (i<points.size()-1 && points[i].x < x ) { + ++i; + } + if (points[0].x > x) + y = points[0].y; + else + if (points[N].x < x) + y = points[N].y; + else + y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + + (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + + (points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; + m_line_to_draw.push_back(y); } - if (points[0].x > x) - y = points[0].y; - else - if (points[N].x < x) - y = points[N].y; - else - y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + - (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + - (points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; - m_line_to_draw.push_back(y); + else { + float x_math = screen_to_math(wxPoint(x,0)).m_x; + if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) + ++i; + m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); + } + + m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); + m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); + m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); } - else { - float x_math = screen_to_math(wxPoint(x,0)).m_x; - if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) - ++i; - m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); - } - - - m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); - m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); - m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); } - + wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED)); Refresh(); } From 08cb5bc2c7e57424d8783ca4aa02626dd0a1a48a Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Wed, 24 Apr 2019 12:01:57 +0200 Subject: [PATCH 20/28] Wipe tower uses correct gcodes for RepRap gcode flavor (M907->M906, M900->M572 - should fix #1843) Also, fixed proper setting of the extruder current during toolchange (was broken since 6da83c7) --- src/libslic3r/GCode.cpp | 4 ++-- src/libslic3r/GCode/WipeTowerPrusaMM.cpp | 21 +++++++++++++-------- src/libslic3r/GCode/WipeTowerPrusaMM.hpp | 5 ++++- src/libslic3r/Print.cpp | 3 +-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c06d19cb9..bf1d24e8a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -184,7 +184,7 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T // Disable linear advance for the wipe tower operations. - gcode += "M900 K0\n"; + gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); // Move over the wipe tower. // Retract for a tool change, using the toolchange retract value and setting the priming extra length. gcode += gcodegen.retract(true); @@ -289,7 +289,7 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen) if (&m_priming != nullptr && ! m_priming.extrusions.empty()) { // Disable linear advance for the wipe tower operations. - gcode += "M900 K0\n"; + gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); // Let the tool change be executed by the wipe tower class. // Inform the G-code writer about the changes done behind its back. gcode += m_priming.gcode; diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp index 829fe1bb9..34065a491 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp @@ -40,7 +40,7 @@ namespace PrusaMultiMaterial { class Writer { public: - Writer(float layer_height, float line_width) : + Writer(float layer_height, float line_width, GCodeFlavor flavor) : m_current_pos(std::numeric_limits<float>::max(), std::numeric_limits<float>::max()), m_current_z(0.f), m_current_feedrate(0.f), @@ -48,7 +48,8 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), - m_default_analyzer_line_width(line_width) + m_default_analyzer_line_width(line_width), + m_gcode_flavor(flavor) { // adds tag for analyzer: char buf[64]; @@ -333,7 +334,10 @@ public: Writer& set_extruder_trimpot(int current) { char buf[128]; - sprintf(buf, "M907 E%d\n", current); + if (m_gcode_flavor == gcfRepRap) + sprintf(buf, "M906 E%d\n", current); + else + sprintf(buf, "M907 E%d\n", current); m_gcode += buf; return *this; }; @@ -407,6 +411,7 @@ private: int current_temp = -1; const float m_default_analyzer_line_width; float m_used_filament_length = 0.f; + GCodeFlavor m_gcode_flavor; std::string set_format_X(float x) { @@ -510,7 +515,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime( const float prime_section_width = std::min(240.f / tools.size(), 60.f); box_coordinates cleaning_box(xy(5.f, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -612,7 +617,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo (tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5*m_perimeter_width : m_wipe_tower_depth-m_perimeter_width)); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -631,7 +636,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo // Increase the extruder driver current to allow fast ramming. if (m_set_extruder_trimpot) - writer.set_extruder_trimpot(550); + writer.set_extruder_trimpot(750); // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool. if (tool != (unsigned int)-1){ // This is not the last change. @@ -693,7 +698,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo m_wipe_tower_width, m_wipe_tower_depth); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow * 1.1f) .set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop. .set_initial_tool(m_current_tool) @@ -1022,7 +1027,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer() // Otherwise the caller would likely travel to the wipe tower in vain. assert(! this->layer_finished()); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp index 2b5fa2241..90f50b57a 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp @@ -8,6 +8,7 @@ #include <algorithm> #include "WipeTower.hpp" +#include "PrintConfig.hpp" namespace Slic3r @@ -46,7 +47,7 @@ public: // wipe_area -- space available for one toolchange in mm WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction, float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, - float bridging, bool set_extruder_trimpot, + float bridging, bool set_extruder_trimpot, GCodeFlavor flavor, const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) : m_wipe_tower_pos(x, y), m_wipe_tower_width(width), @@ -60,6 +61,7 @@ public: m_extra_loading_move(extra_loading_move), m_bridging(bridging), m_set_extruder_trimpot(set_extruder_trimpot), + m_gcode_flavor(flavor), m_current_tool(initial_tool), wipe_volumes(wiping_matrix) {} @@ -223,6 +225,7 @@ private: bool m_set_extruder_trimpot = false; bool m_retain_speed_override = true; bool m_adhesion = true; + GCodeFlavor m_gcode_flavor; float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill. float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 0637ba7f0..d743a9b23 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -126,7 +126,6 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option "first_layer_bed_temperature", "first_layer_speed", "gcode_comments", - "gcode_flavor", "gcode_label_objects", "infill_acceleration", "layer_gcode", @@ -1777,7 +1776,7 @@ void Print::_make_wipe_tower() float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value), float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value), float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), - m_config.high_current_on_filament_swap.value, wipe_volumes, + m_config.high_current_on_filament_swap.value, m_config.gcode_flavor, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); //wipe_tower.set_retract(); From 5fd2e573a0c4469e4874395528a7c3fa811bdbfc Mon Sep 17 00:00:00 2001 From: Vojtech Kral <vojtech@kral.hk> Date: Wed, 17 Apr 2019 14:56:44 +0200 Subject: [PATCH 21/28] GUI_App: Add a language code getter --- src/slic3r/GUI/GUI_App.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 41805702b..3537f98e4 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -139,6 +139,8 @@ public: bool checked_tab(Tab* tab); void load_current_presets(); + wxString current_language_code() { return m_wxLocale != nullptr ? m_wxLocale->GetCanonicalName() : wxString("en_US"); } + virtual bool OnExceptionInMainLoop(); #ifdef __APPLE__ From cfa7802a8ae5a8390aa478cd62dd5126ee299b49 Mon Sep 17 00:00:00 2001 From: Vojtech Kral <vojtech@kral.hk> Date: Thu, 18 Apr 2019 17:21:46 +0200 Subject: [PATCH 22/28] ConfigWizard: Attempt to fix width hint --- src/slic3r/GUI/ConfigWizard.cpp | 9 +++++---- src/slic3r/GUI/ConfigWizard_private.hpp | 7 +++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 5da320830..0b5d7ffff 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -647,7 +647,7 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) SetMinSize(bg.GetSize()); const wxSize size = GetTextExtent("m"); - em = size.x; + em_w = size.x; em_h = size.y; // Add logo bitmap. @@ -775,7 +775,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) unsigned y = 0; for (size_t i = 0; i < items.size(); i++) { const Item& item = items[i]; - unsigned x = em/2 + item.indent * em; + unsigned x = em_w/2 + item.indent * em_w; if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) { dc.DrawBitmap(bullet_blue, x, y + yoff_icon, false); @@ -783,7 +783,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) 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); } - x += + bullet_w + em/2; + x += + bullet_w + em_w/2; const auto text_size = dc.GetTextExtent(item.label); dc.DrawText(item.label, x, y + yoff_text); @@ -794,6 +794,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) if (GetMinSize().x < index_width) { CallAfter([this, index_width]() { SetMinSize(wxSize(index_width, GetMinSize().y)); + Refresh(); }); } } @@ -1073,7 +1074,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) 9*disp_rect.width / 10, 9*disp_rect.height / 10); - const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 300; // XXX: magic constant, I found no better solution + 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; diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index df7602adf..792b92015 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -211,6 +211,7 @@ public: void clear(); + int em() const { return em_w; } private: struct Item { @@ -221,7 +222,7 @@ private: bool operator==(ConfigWizardPage *page) const { return this->page == page; } }; - int em; + int em_w; int em_h; const wxBitmap bg; @@ -234,7 +235,7 @@ private: ssize_t item_hover; size_t last_page; - int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; } + int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; } void on_paint(wxPaintEvent &evt); void on_mouse_move(wxMouseEvent &evt); @@ -286,6 +287,8 @@ struct ConfigWizard::priv void on_custom_setup(bool custom_wanted); void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater); + + int em() const { return index->em(); } }; From 98c8cef65703c94f8cfbf4ff7f81a5915f6bea61 Mon Sep 17 00:00:00 2001 From: Vojtech Kral <vojtech@kral.hk> Date: Wed, 24 Apr 2019 16:02:49 +0200 Subject: [PATCH 23/28] ConfigWizard: Don't blow up if a printer bitmap is missing --- src/slic3r/GUI/ConfigWizard.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 0b5d7ffff..e0bfccf30 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -18,6 +18,7 @@ #include <wx/dataview.h> #include <wx/notebook.h> #include <wx/display.h> +#include <wx/filefn.h> #include <wx/debug.h> #include "libslic3r/Utils.hpp" @@ -81,11 +82,17 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt for (const auto &model : models) { if (! filter(model)) { continue; } - wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG); + wxBitmap bitmap; + int bitmap_width = 0; + const wxString bitmap_file = GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())); + if (wxFileExists(bitmap_file)) { + bitmap.LoadFile(bitmap_file, wxBITMAP_TYPE_PNG); + bitmap_width = bitmap.GetWidth(); + } auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(font_name); - const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap.GetWidth()); + const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap_width); title->Wrap(wrap_width); current_row_width += wrap_width; From 065448e9e5f63f412ac59c8fbbea560f2cccf77e Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 25 Apr 2019 01:45:00 +0200 Subject: [PATCH 24/28] Big Refactoring: - deleted/renamed all _Prusa_ prefixes, - cleaned code from commented parts - rescale() -> msw_rescale() --- src/slic3r/GUI/AboutDialog.cpp | 14 +- src/slic3r/GUI/AboutDialog.hpp | 2 +- src/slic3r/GUI/BedShapeDialog.cpp | 2 +- src/slic3r/GUI/ButtonsDescription.hpp | 6 +- src/slic3r/GUI/ConfigWizard.cpp | 20 +- src/slic3r/GUI/ConfigWizard_private.hpp | 10 +- src/slic3r/GUI/Field.cpp | 38 +- src/slic3r/GUI/Field.hpp | 32 +- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 56 +- src/slic3r/GUI/GUI_ObjectList.hpp | 35 +- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 4 +- src/slic3r/GUI/GUI_ObjectSettings.cpp | 18 +- src/slic3r/GUI/GUI_ObjectSettings.hpp | 4 +- src/slic3r/GUI/GUI_Preview.cpp | 8 +- src/slic3r/GUI/GUI_Preview.hpp | 6 +- src/slic3r/GUI/KBShortcutsDialog.cpp | 10 +- src/slic3r/GUI/KBShortcutsDialog.hpp | 5 +- src/slic3r/GUI/MainFrame.cpp | 4 +- src/slic3r/GUI/OptionsGroup.cpp | 4 +- src/slic3r/GUI/OptionsGroup.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 70 +- src/slic3r/GUI/Plater.hpp | 10 +- src/slic3r/GUI/Preferences.cpp | 2 +- src/slic3r/GUI/SysInfoDialog.cpp | 10 +- src/slic3r/GUI/SysInfoDialog.hpp | 7 +- src/slic3r/GUI/Tab.cpp | 123 +--- src/slic3r/GUI/Tab.hpp | 58 +- src/slic3r/GUI/wxExtensions.cpp | 836 ++++++++-------------- src/slic3r/GUI/wxExtensions.hpp | 459 +++++------- 32 files changed, 726 insertions(+), 1139 deletions(-) diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index b2b025880..fb1450ba1 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -45,9 +45,8 @@ AboutDialog::AboutDialog() main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20); // logo - m_logo_bitmap = PrusaBitmap(this, "Slic3r_192px.png", 192); + m_logo_bitmap = ScalableBitmap(this, "Slic3r_192px.png", 192); m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp()); -// auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); hsizer->Add(m_logo, 1, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); @@ -56,8 +55,7 @@ AboutDialog::AboutDialog() // title { wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize); - wxFont title_font = GUI::wxGetApp().bold_font();// wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); -// title_font.SetWeight(wxFONTWEIGHT_BOLD); + wxFont title_font = GUI::wxGetApp().bold_font(); title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetPointSize(24); title->SetFont(title_font); @@ -68,9 +66,9 @@ AboutDialog::AboutDialog() { auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION); wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); - wxFont version_font = GetFont();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont version_font = GetFont(); #ifdef __WXMSW__ - version_font.SetPointSize(/*9*/version_font.GetPointSize()-1); + version_font.SetPointSize(version_font.GetPointSize()-1); #else version_font.SetPointSize(11); #endif @@ -82,7 +80,7 @@ AboutDialog::AboutDialog() m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/); { m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); - wxFont font = GetFont();//GUI::wxGetApp().normal_font(); // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont font = GetFont(); const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); @@ -125,7 +123,7 @@ AboutDialog::AboutDialog() void AboutDialog::on_dpi_changed(const wxRect &suggested_rect) { - m_logo_bitmap.rescale(); + m_logo_bitmap.msw_rescale(); m_logo->SetBitmap(m_logo_bitmap.bmp()); const wxFont& font = GetFont(); diff --git a/src/slic3r/GUI/AboutDialog.hpp b/src/slic3r/GUI/AboutDialog.hpp index f74ab52f3..7019b21f6 100644 --- a/src/slic3r/GUI/AboutDialog.hpp +++ b/src/slic3r/GUI/AboutDialog.hpp @@ -25,7 +25,7 @@ private: class AboutDialog : public DPIDialog { - PrusaBitmap m_logo_bitmap; + ScalableBitmap m_logo_bitmap; wxHtmlWindow* m_html; wxStaticBitmap* m_logo; public: diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 2762f0db7..00ebf117c 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -43,7 +43,7 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect) m_panel->m_shape_options_book->SetMinSize(wxSize(25 * em, -1)); for (auto og : m_panel->m_optgroups) - og->rescale(); + og->msw_rescale(); const wxSize& size = wxSize(50 * em, -1); diff --git a/src/slic3r/GUI/ButtonsDescription.hpp b/src/slic3r/GUI/ButtonsDescription.hpp index ccd992406..69005d2a5 100644 --- a/src/slic3r/GUI/ButtonsDescription.hpp +++ b/src/slic3r/GUI/ButtonsDescription.hpp @@ -4,12 +4,12 @@ #include <wx/dialog.h> #include <vector> -class PrusaBitmap; +class ScalableBitmap; namespace Slic3r { namespace GUI { -using t_icon_descriptions = std::vector<std::pair</*wxBitmap*/PrusaBitmap*, std::string>>; +using t_icon_descriptions = std::vector<std::pair<ScalableBitmap*, std::string>>; class ButtonsDescription : public wxDialog { @@ -17,8 +17,6 @@ class ButtonsDescription : public wxDialog public: ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions); ~ButtonsDescription() {} - - }; } // GUI diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 571a1dccb..5e9327ffb 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -648,10 +648,10 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) , 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(PrusaBitmap(parent, "Slic3r_192px_transparent.png", 192)) - , bullet_black(PrusaBitmap(parent, "bullet_black.png")) - , bullet_blue(PrusaBitmap(parent, "bullet_blue.png")) - , bullet_white(PrusaBitmap(parent, "bullet_white.png")) + , bg(ScalableBitmap(parent, "Slic3r_192px_transparent.png", 192)) + , bullet_black(ScalableBitmap(parent, "bullet_black.png")) + , bullet_blue(ScalableBitmap(parent, "bullet_blue.png")) + , bullet_white(ScalableBitmap(parent, "bullet_white.png")) , item_active(0) , item_hover(-1) , last_page((size_t)-1) @@ -839,15 +839,15 @@ void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt) evt.Skip(); } -void ConfigWizardIndex::rescale() +void ConfigWizardIndex::msw_rescale() { - bg.rescale(); + bg.msw_rescale(); SetMinSize(bg.bmp().GetSize()); logo->SetBitmap(bg.bmp()); - bullet_black.rescale(); - bullet_blue.rescale(); - bullet_white.rescale(); + bullet_black.msw_rescale(); + bullet_blue.msw_rescale(); + bullet_white.msw_rescale(); Refresh(); } @@ -1174,7 +1174,7 @@ const wxString& ConfigWizard::name(const bool from_menu/* = false*/) void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect) { - p->index->rescale(); + p->index->msw_rescale(); Refresh(); } diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index 06777ba88..31a990b60 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -210,7 +210,7 @@ public: void go_to(ConfigWizardPage *page); void clear(); - void rescale(); + void msw_rescale(); int em() const { return em_w; } private: @@ -231,10 +231,10 @@ private: const wxBitmap bullet_blue; const wxBitmap bullet_white; */ - PrusaBitmap bg; - PrusaBitmap bullet_black; - PrusaBitmap bullet_blue; - PrusaBitmap bullet_white; + ScalableBitmap bg; + ScalableBitmap bullet_black; + ScalableBitmap bullet_blue; + ScalableBitmap bullet_white; wxStaticBitmap* logo; std::vector<Item> items; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 89310e7c3..822361c5d 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -33,21 +33,11 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/) void Field::PostInitialize() { auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_Undo_btn = new RevertButton(m_parent, "bullet_white.png");//(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png");//(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); -// if (wxMSW) { -// m_Undo_btn->SetBackgroundColour(color); -// m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); -// m_Undo_to_sys_btn->SetBackgroundColour(color); -// m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); -// } - m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); - m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); + m_Undo_btn = new RevertButton(m_parent, "bullet_white.png"); + m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png"); - //set default bitmap -// wxBitmap bmp = create_scaled_bitmap(m_parent, "bullet_white.png" ); -// set_undo_bitmap(&bmp); -// set_undo_to_sys_bitmap(&bmp); + m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); + m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); switch (m_opt.type) { @@ -360,9 +350,9 @@ boost::any& TextCtrl::get_value() return m_value; } -void TextCtrl::rescale() +void TextCtrl::msw_rescale() { - Field::rescale(); + Field::msw_rescale(); auto size = wxSize(wxDefaultSize); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); @@ -523,9 +513,9 @@ void SpinCtrl::propagate_value() on_change_field(); } -void SpinCtrl::rescale() +void SpinCtrl::msw_rescale() { - Field::rescale(); + Field::msw_rescale(); wxSpinCtrl* field = dynamic_cast<wxSpinCtrl*>(window); field->SetMinSize(wxSize(-1, int(1.9f*field->GetFont().GetPixelSize().y))); @@ -843,9 +833,9 @@ boost::any& Choice::get_value() return m_value; } -void Choice::rescale() +void Choice::msw_rescale() { - Field::rescale(); + Field::msw_rescale(); wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); @@ -967,9 +957,9 @@ void PointCtrl::BUILD() y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y)); } -void PointCtrl::rescale() +void PointCtrl::msw_rescale() { - Field::rescale(); + Field::msw_rescale(); const wxSize field_size(4 * m_em_unit, -1); @@ -1037,9 +1027,9 @@ void StaticText::BUILD() temp->SetToolTip(get_tooltip_text(legend)); } -void StaticText::rescale() +void StaticText::msw_rescale() { - Field::rescale(); + Field::msw_rescale(); auto size = wxSize(wxDefaultSize); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index c776cadea..516570ea8 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -37,7 +37,7 @@ using t_back_to_init = std::function<void(const std::string&)>; wxString double_to_string(double const value, const int max_precision = 4); -class RevertButton : public /*wxButton*/PrusaButton +class RevertButton : public ScalableButton { bool hidden = false; // never show button if it's hidden ones public: @@ -54,7 +54,7 @@ public: wxWindow *parent, const std::string& icon_name = "" ) : - PrusaButton(parent, wxID_ANY, icon_name) {} + ScalableButton(parent, wxID_ANY, icon_name) {} // overridden from wxWindow base class virtual bool @@ -160,7 +160,7 @@ public: return std::move(p); //!p; } - bool set_undo_bitmap(const /*wxBitmap*/PrusaBitmap *bmp) { + bool set_undo_bitmap(const ScalableBitmap *bmp) { if (m_undo_bitmap != bmp) { m_undo_bitmap = bmp; m_Undo_btn->SetBitmap_(*bmp); @@ -169,7 +169,7 @@ public: return false; } - bool set_undo_to_sys_bitmap(const /*wxBitmap*/PrusaBitmap *bmp) { + bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) { if (m_undo_to_sys_bitmap != bmp) { m_undo_to_sys_bitmap = bmp; m_Undo_to_sys_btn->SetBitmap_(*bmp); @@ -217,9 +217,9 @@ public: m_side_text = side_text; } - virtual void rescale() { - m_Undo_to_sys_btn->rescale(); - m_Undo_btn->rescale(); + virtual void msw_rescale() { + m_Undo_to_sys_btn->msw_rescale(); + m_Undo_btn->msw_rescale(); // update em_unit value m_em_unit = em_unit(m_parent); @@ -228,12 +228,12 @@ public: protected: RevertButton* m_Undo_btn = nullptr; // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. - const /*wxBitmap*/PrusaBitmap* m_undo_bitmap = nullptr; - const wxString* m_undo_tooltip = nullptr; + const ScalableBitmap* m_undo_bitmap = nullptr; + const wxString* m_undo_tooltip = nullptr; RevertButton* m_Undo_to_sys_btn = nullptr; // Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. - const /*wxBitmap*/PrusaBitmap* m_undo_to_sys_bitmap = nullptr; - const wxString* m_undo_to_sys_tooltip = nullptr; + const ScalableBitmap* m_undo_to_sys_bitmap = nullptr; + const wxString* m_undo_to_sys_tooltip = nullptr; wxStaticText* m_Label = nullptr; // Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one. @@ -290,7 +290,7 @@ public: boost::any& get_value() override; - void rescale() override; + void msw_rescale() override; virtual void enable(); virtual void disable(); @@ -355,7 +355,7 @@ public: return m_value = tmp_value; } - void rescale() override; + void msw_rescale() override; void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); } void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); } @@ -384,7 +384,7 @@ public: void set_values(const std::vector<std::string> &values); boost::any& get_value() override; - void rescale() override; + void msw_rescale() override; void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); }; void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); }; @@ -437,7 +437,7 @@ public: void set_value(const boost::any& value, bool change_event = false); boost::any& get_value() override; - void rescale() override; + void msw_rescale() override; void enable() override { x_textctrl->Enable(); @@ -471,7 +471,7 @@ public: boost::any& get_value()override { return m_value; } - void rescale() override; + void msw_rescale() override; void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); }; void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cfae43027..649302341 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3188,7 +3188,7 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const return factor * m_bed.get_bounding_box().max_size(); } -void GLCanvas3D::rescale() +void GLCanvas3D::msw_rescale() { m_warning_texture.rescale(*this); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 32ed94221..45b5a58e7 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -594,7 +594,7 @@ public: double get_size_proportional_to_max_bed_size(double factor) const; - void rescale(); + void msw_rescale(); private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index ff6094f70..f9df2649c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -163,7 +163,7 @@ void ObjectList::create_objects_ctrl() m_sizer = new wxBoxSizer(wxVERTICAL); m_sizer->Add(this, 1, wxGROW); - m_objects_model = new PrusaObjectDataViewModel; + m_objects_model = new ObjectDataViewModel; AssociateModel(m_objects_model); m_objects_model->SetAssociatedControl(this); #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE @@ -173,7 +173,7 @@ void ObjectList::create_objects_ctrl() // column 0(Icon+Text) of the view control: // And Icon can be consisting of several bitmaps - AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), + AppendColumn(new wxDataViewColumn(_(L("Name")), new BitmapTextRenderer(), 0, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); // column 1 of the view control: @@ -395,22 +395,10 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const void ObjectList::init_icons() { -// m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier"); -// m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part"); -// m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer"); -// m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker"); -// -// -// m_bmp_vector.reserve(4); // bitmaps for different types of parts -// m_bmp_vector.push_back(&m_bmp_solidmesh); -// m_bmp_vector.push_back(&m_bmp_modifiermesh); -// m_bmp_vector.push_back(&m_bmp_support_enforcer); -// m_bmp_vector.push_back(&m_bmp_support_blocker); - - m_bmp_modifiermesh = PrusaBitmap(nullptr, "add_modifier"); // Add part - m_bmp_solidmesh = PrusaBitmap(nullptr, "add_part"); // Add modifier - m_bmp_support_enforcer = PrusaBitmap(nullptr, "support_enforcer");// Add support enforcer - m_bmp_support_blocker = PrusaBitmap(nullptr, "support_blocker"); // Add support blocker + m_bmp_modifiermesh = ScalableBitmap(nullptr, "add_modifier"); // Add part + m_bmp_solidmesh = ScalableBitmap(nullptr, "add_part"); // Add modifier + m_bmp_support_enforcer = ScalableBitmap(nullptr, "support_enforcer");// Add support enforcer + m_bmp_support_blocker = ScalableBitmap(nullptr, "support_blocker"); // Add support blocker m_bmp_vector.reserve(4); // bitmaps for different types of parts m_bmp_vector.push_back(&m_bmp_solidmesh.bmp()); @@ -423,34 +411,34 @@ void ObjectList::init_icons() m_objects_model->SetVolumeBitmaps(m_bmp_vector); // init icon for manifold warning - m_bmp_manifold_warning = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "exclamation"); + m_bmp_manifold_warning = ScalableBitmap(nullptr, "exclamation"); // init bitmap for "Split to sub-objects" context menu - m_bmp_split = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "split_parts_SMALL"); + m_bmp_split = ScalableBitmap(nullptr, "split_parts_SMALL"); // init bitmap for "Add Settings" context menu - m_bmp_cog = /*create_scaled_bitmap*/PrusaBitmap(nullptr, "cog"); + m_bmp_cog = ScalableBitmap(nullptr, "cog"); } void ObjectList::rescale_icons() { m_bmp_vector.clear(); m_bmp_vector.reserve(4); // bitmaps for different types of parts - for (PrusaBitmap* bitmap : std::vector<PrusaBitmap*> { + for (ScalableBitmap* bitmap : std::vector<ScalableBitmap*> { &m_bmp_modifiermesh, // Add part &m_bmp_solidmesh, // Add modifier &m_bmp_support_enforcer, // Add support enforcer &m_bmp_support_blocker }) // Add support blocker { - bitmap->rescale(); + bitmap->msw_rescale(); m_bmp_vector.push_back(& bitmap->bmp()); } // Set volumes default bitmaps for the model m_objects_model->SetVolumeBitmaps(m_bmp_vector); - m_bmp_manifold_warning.rescale(); - m_bmp_split.rescale(); - m_bmp_cog.rescale(); + m_bmp_manifold_warning.msw_rescale(); + m_bmp_split.msw_rescale(); + m_bmp_cog.msw_rescale(); // Update CATEGORY_ICON according to new scale @@ -1057,7 +1045,7 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) { - PrusaMenu* menu = dynamic_cast<PrusaMenu*>(menu_); + MenuWithSeparators* menu = dynamic_cast<MenuWithSeparators*>(menu_); const wxString menu_name = _(L("Add settings")); // Delete old items from settings popupmenu @@ -1105,7 +1093,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) if (printer_technology() == ptFFF || menu->GetMenuItems().size() > 0 && !menu->GetMenuItems().back()->IsSeparator()) - menu->m_separator_frst = menu->AppendSeparator(); + menu->SetFirstSeparator(); // Add frequently settings create_freq_settings_popupmenu(menu); @@ -1113,7 +1101,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) if (mode == comAdvanced) return nullptr; - menu->m_separator_scnd = menu->AppendSeparator(); + menu->SetSecondSeparator(); // Add full settings list auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name); @@ -1864,7 +1852,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) stats.facets_added + stats.facets_reversed + stats.backwards_edges; if (errors > 0) { wxVariant variant; - variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning.bmp()); + variant << DataViewBitmapText(item_name, m_bmp_manifold_warning.bmp()); m_objects_model->SetValue(variant, item, 0); } @@ -2664,7 +2652,7 @@ void ObjectList::rename_item() wxVariant valueOld; m_objects_model->GetValue(valueOld, item, 0); - PrusaDataViewBitmapText bmpText; + DataViewBitmapText bmpText; bmpText << valueOld; // But replace the text with the value entered by user. @@ -2712,12 +2700,12 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co if (errors == 0) { // delete Error_icon if all errors are fixed wxVariant variant; - variant << PrusaDataViewBitmapText(from_u8(model_object->name), wxNullBitmap); + variant << DataViewBitmapText(from_u8(model_object->name), wxNullBitmap); m_objects_model->SetValue(variant, item, 0); } } -void ObjectList::rescale() +void ObjectList::msw_rescale() { // update min size !!! A width of control shouldn't be a wxDefaultCoord SetMinSize(wxSize(1, 15 * wxGetApp().em_unit())); @@ -2748,7 +2736,7 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event) if (event.GetColumn() != 0) return; - const auto renderer = dynamic_cast<PrusaBitmapTextRenderer*>(GetColumn(0)->GetRenderer()); + const auto renderer = dynamic_cast<BitmapTextRenderer*>(GetColumn(0)->GetRenderer()); if (renderer->WasCanceled()) show_error(this, _(L("The supplied name is not valid;")) + "\n" + diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 9421c79c7..da082d1d4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -13,8 +13,8 @@ class wxBoxSizer; class wxMenuItem; -class PrusaObjectDataViewModel; -class PrusaMenu; +class ObjectDataViewModel; +class MenuWithSeparators; namespace Slic3r { class ConfigOptionsGroup; @@ -108,24 +108,24 @@ class ObjectList : public wxDataViewCtrl wxBoxSizer *m_sizer {nullptr}; wxWindow *m_parent {nullptr}; - /*wxBitmap*/PrusaBitmap m_bmp_modifiermesh; - /*wxBitmap*/PrusaBitmap m_bmp_solidmesh; - /*wxBitmap*/PrusaBitmap m_bmp_support_enforcer; - /*wxBitmap*/PrusaBitmap m_bmp_support_blocker; - /*wxBitmap*/PrusaBitmap m_bmp_manifold_warning; - /*wxBitmap*/PrusaBitmap m_bmp_cog; - /*wxBitmap*/PrusaBitmap m_bmp_split; + ScalableBitmap m_bmp_modifiermesh; + ScalableBitmap m_bmp_solidmesh; + ScalableBitmap m_bmp_support_enforcer; + ScalableBitmap m_bmp_support_blocker; + ScalableBitmap m_bmp_manifold_warning; + ScalableBitmap m_bmp_cog; + ScalableBitmap m_bmp_split; - PrusaMenu m_menu_object; - PrusaMenu m_menu_part; - PrusaMenu m_menu_sla_object; - PrusaMenu m_menu_instance; + MenuWithSeparators m_menu_object; + MenuWithSeparators m_menu_part; + MenuWithSeparators m_menu_sla_object; + MenuWithSeparators m_menu_instance; wxMenuItem* m_menu_item_split { nullptr }; wxMenuItem* m_menu_item_split_part { nullptr }; wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; - std::vector<wxBitmap* /*const wxBitmap&*/> m_bmp_vector; + std::vector<wxBitmap*> m_bmp_vector; int m_selected_object_id = -1; bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select() @@ -139,9 +139,6 @@ class ObjectList : public wxDataViewCtrl // update_settings_items - updating canvas selection is undesirable, // because it would turn off the gizmos (mainly a problem for the SLA gizmo) -// bool m_parts_changed = false; -// bool m_part_settings_changed = false; - int m_selected_row = 0; wxDataViewItem m_last_selected_item {nullptr}; @@ -157,7 +154,7 @@ public: std::map<std::string, wxBitmap> CATEGORY_ICON; - PrusaObjectDataViewModel *m_objects_model{ nullptr }; + ObjectDataViewModel *m_objects_model{ nullptr }; DynamicPrintConfig *m_config {nullptr}; std::vector<ModelObject*> *m_objects{ nullptr }; @@ -289,7 +286,7 @@ public: void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); void paste_objects_into_list(const std::vector<size_t>& object_idxs); - void rescale(); + void msw_rescale(); private: void OnChar(wxKeyEvent& event); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 526b07578..53f1923fd 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -78,7 +78,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Add "uniform scaling" button in front of "Scale" option if (option_name == "Scale") { line.near_label_widget = [this](wxWindow* parent) { - auto btn = new PrusaLockButton(parent, wxID_ANY); + auto btn = new LockButton(parent, wxID_ANY); btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){ event.Skip(); wxTheApp->CallAfter([btn, this]() { set_uniform_scaling(btn->IsLocked()); }); @@ -119,10 +119,10 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // call back for a rescale of button "Set uniform scale" m_og->rescale_near_label_widget = [this](wxWindow* win) { - auto *ctrl = dynamic_cast<PrusaLockButton*>(win); + auto *ctrl = dynamic_cast<LockButton*>(win); if (ctrl == nullptr) return; - ctrl->rescale(); + ctrl->msw_rescale(); }; } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index a5a180a56..d7b45e3c8 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -7,7 +7,7 @@ #include "GLCanvas3D.hpp" class wxStaticText; -class PrusaLockButton; +class LockButton; namespace Slic3r { namespace GUI { @@ -76,7 +76,7 @@ class ObjectManipulation : public OG_Settings Vec3d m_new_size; bool m_new_enabled; bool m_uniform_scale {true}; - PrusaLockButton* m_lock_bnt{ nullptr }; + LockButton* m_lock_bnt{ nullptr }; #ifndef __APPLE__ // Currently focused option name (empty if none) diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index b8c0c41ae..b7ba2d4fc 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -60,7 +60,7 @@ ObjectSettings::ObjectSettings(wxWindow* parent) : m_settings_list_sizer = new wxBoxSizer(wxVERTICAL); m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5); - m_bmp_delete = PrusaBitmap(parent, "cross"); + m_bmp_delete = ScalableBitmap(parent, "cross"); } void ObjectSettings::update_settings_list() @@ -79,12 +79,8 @@ void ObjectSettings::update_settings_list() { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line -// auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "cross"/*"colorchange_delete_on.png"*/), -// wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - auto btn = new PrusaButton(parent, wxID_ANY, m_bmp_delete); -//#ifdef __WXMSW__ -// btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -//#endif // __WXMSW__ + auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { config->erase(opt_key); wxGetApp().obj_list()->changed_object(); @@ -145,7 +141,7 @@ void ObjectSettings::update_settings_list() // call back for rescaling of the extracolumn control optgroup->rescale_extra_column_item = [this](wxWindow* win) { - auto *ctrl = dynamic_cast<PrusaButton*>(win); + auto *ctrl = dynamic_cast<ScalableButton*>(win); if (ctrl == nullptr) return; ctrl->SetBitmap_(m_bmp_delete); @@ -175,12 +171,12 @@ void ObjectSettings::UpdateAndShow(const bool show) OG_Settings::UpdateAndShow(show); } -void ObjectSettings::rescale() +void ObjectSettings::msw_rescale() { - m_bmp_delete.rescale(); + m_bmp_delete.msw_rescale(); for (auto group : m_og_settings) - group->rescale(); + group->msw_rescale(); } } //namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectSettings.hpp b/src/slic3r/GUI/GUI_ObjectSettings.hpp index 17accda18..3d49f13b7 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.hpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.hpp @@ -38,7 +38,7 @@ class ObjectSettings : public OG_Settings // option groups for settings std::vector <std::shared_ptr<ConfigOptionsGroup>> m_og_settings; - PrusaBitmap m_bmp_delete; + ScalableBitmap m_bmp_delete; public: ObjectSettings(wxWindow* parent); @@ -46,7 +46,7 @@ public: void update_settings_list(); void UpdateAndShow(const bool show) override; - void rescale(); + void msw_rescale(); }; }} diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e4ba4922e..88fea933e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -396,13 +396,13 @@ void Preview::refresh_print() load_print(true); } -void Preview::rescale() +void Preview::msw_rescale() { // rescale slider - if (m_slider) m_slider->rescale(); + if (m_slider) m_slider->msw_rescale(); // rescale warning legend on the canvas - get_canvas3d()->rescale(); + get_canvas3d()->msw_rescale(); // rescale legend refresh_print(); @@ -519,7 +519,7 @@ void Preview::on_checkbox_shells(wxCommandEvent& evt) void Preview::create_double_slider() { - m_slider = new PrusaDoubleSlider(this, wxID_ANY, 0, 0, 0, 100); + m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); // sizer, m_canvas_widget diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 8e5bd2bd1..2540980f4 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -13,7 +13,7 @@ class wxStaticText; class wxChoice; class wxComboCtrl; class wxCheckBox; -class PrusaDoubleSlider; +class DoubleSlider; namespace Slic3r { @@ -99,7 +99,7 @@ class Preview : public wxPanel bool m_loaded; bool m_enabled; - PrusaDoubleSlider* m_slider {nullptr}; + DoubleSlider* m_slider {nullptr}; public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, @@ -120,7 +120,7 @@ public: void reload_print(bool keep_volumes = false); void refresh_print(); - void rescale(); + void msw_rescale(); private: bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 9a4561f07..7f77474f2 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -15,21 +15,21 @@ KBShortcutsDialog::KBShortcutsDialog() { SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - main_sizer = new wxBoxSizer(wxVERTICAL); + auto main_sizer = new wxBoxSizer(wxVERTICAL); // logo - m_logo_bmp = PrusaBitmap(this, "Slic3r_32px.png", 32); + m_logo_bmp = ScalableBitmap(this, "Slic3r_32px.png", 32); // fonts const wxFont& font = wxGetApp().normal_font(); const wxFont& bold_font = wxGetApp().bold_font(); SetFont(font); - wxFont head_font = bold_font;// wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); + wxFont head_font = bold_font; #ifdef __WXOSX__ head_font.SetPointSize(14); #else - head_font.SetPointSize(/*12*/bold_font.GetPointSize() + 2); + head_font.SetPointSize(bold_font.GetPointSize() + 2); #endif // __WXOSX__ fill_shortcuts(); @@ -191,7 +191,7 @@ void KBShortcutsDialog::fill_shortcuts() void KBShortcutsDialog::on_dpi_changed(const wxRect &suggested_rect) { - m_logo_bmp.rescale(); + m_logo_bmp.msw_rescale(); for (wxStaticBitmap* bmp : m_head_bitmaps) bmp->SetBitmap(m_logo_bmp.bmp()); diff --git a/src/slic3r/GUI/KBShortcutsDialog.hpp b/src/slic3r/GUI/KBShortcutsDialog.hpp index f18e78682..66fe7c399 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.hpp +++ b/src/slic3r/GUI/KBShortcutsDialog.hpp @@ -11,7 +11,7 @@ namespace Slic3r { namespace GUI { -class KBShortcutsDialog : public DPIDialog/*wxDialog*/ +class KBShortcutsDialog : public DPIDialog { enum PLACED_SIZER_ID { @@ -26,8 +26,7 @@ class KBShortcutsDialog : public DPIDialog/*wxDialog*/ wxString text_info {wxEmptyString}; ShortcutsVec m_full_shortcuts; - wxSizer* main_sizer; - PrusaBitmap m_logo_bmp; + ScalableBitmap m_logo_bmp; std::vector<wxStaticBitmap*> m_head_bitmaps; public: diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 74cefcb46..ccba1aaaa 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -270,11 +270,11 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) wxGetApp().preset_bundle->load_default_preset_bitmaps(this); // update Plater - wxGetApp().plater()->rescale(); + wxGetApp().plater()->msw_rescale(); // update Tabs for (auto tab : wxGetApp().tabs_list) - tab->rescale(); + tab->msw_rescale(); /* To correct window rendering (especially redraw of a status bar) * we should imitate window resizing. diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index a951d9847..fdbe3b038 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -484,7 +484,7 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { return true; } -void ConfigOptionsGroup::rescale() +void ConfigOptionsGroup::msw_rescale() { // update bitmaps for extra column items (like "mode markers" or buttons on settings panel) if (rescale_extra_column_item) @@ -498,7 +498,7 @@ void ConfigOptionsGroup::rescale() // update undo buttons : rescale bitmaps for (const auto& field : m_fields) - field.second->rescale(); + field.second->msw_rescale(); const int em = em_unit(parent()); diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 868a4b8f7..67875587a 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -266,7 +266,7 @@ public: void Hide(); void Show(const bool show); bool update_visibility(ConfigOptionMode mode); - void rescale(); + void msw_rescale(); boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize); // return option value from config boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 71e121c58..02cdaf208 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -111,7 +111,7 @@ public: bool showing_manifold_warning_icon; void show_sizer(bool show); - void rescale(); + void msw_rescale(); }; ObjectInfo::ObjectInfo(wxWindow *parent) : @@ -161,7 +161,7 @@ void ObjectInfo::show_sizer(bool show) manifold_warning_icon->Show(showing_manifold_warning_icon && show); } -void ObjectInfo::rescale() +void ObjectInfo::msw_rescale() { manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation")); } @@ -288,12 +288,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * }); } -// edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); -// #ifdef __WINDOWS__ -// edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -// #endif -// edit_btn->SetBitmap(create_scaled_bitmap(this, "cog")); - edit_btn = new PrusaButton(parent, wxID_ANY, "cog"); + edit_btn = new ScalableButton(parent, wxID_ANY, "cog"); edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) @@ -339,10 +334,10 @@ void PresetComboBox::check_selection() this->last_selected = GetSelection(); } -void PresetComboBox::rescale() +void PresetComboBox::msw_rescale() { m_em_unit = wxGetApp().em_unit(); - edit_btn->rescale(); + edit_btn->msw_rescale(); } // Frequently changed parameters @@ -580,7 +575,7 @@ struct Sidebar::priv wxScrolledWindow *scrolled; wxPanel* presets_panel; // Used for MSW better layouts - PrusaModeSizer *mode_sizer; + ModeSizer *mode_sizer; wxFlexGridSizer *sizer_presets; PresetComboBox *combo_print; std::vector<PresetComboBox*> combos_filament; @@ -639,7 +634,7 @@ Sidebar::Sidebar(Plater *parent) p->scrolled->SetSizer(scrolled_sizer); // Sizer with buttons for mode changing - p->mode_sizer = new PrusaModeSizer(p->scrolled, 2 * wxGetApp().em_unit()); + p->mode_sizer = new ModeSizer(p->scrolled, 2 * wxGetApp().em_unit()); // The preset chooser p->sizer_presets = new wxFlexGridSizer(10, 1, 1, 2); @@ -854,23 +849,6 @@ void Sidebar::update_presets(Preset::Type preset_type) case Preset::TYPE_PRINTER: { -// wxWindowUpdateLocker noUpdates_scrolled(p->scrolled); - -// // Update the print choosers to only contain the compatible presets, update the dirty flags. -// if (print_tech == ptFFF) -// preset_bundle.prints.update_platter_ui(p->combo_print); -// else { -// preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print); -// preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material); -// } -// // Update the printer choosers, update the dirty flags. -// preset_bundle.printers.update_platter_ui(p->combo_printer); -// // Update the filament choosers to only contain the compatible presets, update the color preview, -// // update the dirty flags. -// if (print_tech == ptFFF) { -// for (size_t i = 0; i < p->combos_filament.size(); ++ i) -// preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); -// } update_all_preset_comboboxes(); p->show_preset_comboboxes(); break; @@ -896,33 +874,33 @@ void Sidebar::update_reslice_btn_tooltip() const p->btn_reslice->SetToolTip(tooltip); } -void Sidebar::rescale() +void Sidebar::msw_rescale() { SetMinSize(wxSize(40 * wxGetApp().em_unit(), -1)); - p->mode_sizer->rescale(); + p->mode_sizer->msw_rescale(); // Rescale preset comboboxes in respect to the current em_unit ... for (PresetComboBox* combo : std::vector<PresetComboBox*> { p->combo_print, p->combo_sla_print, p->combo_sla_material, p->combo_printer } ) - combo->rescale(); + combo->msw_rescale(); for (PresetComboBox* combo : p->combos_filament) - combo->rescale(); + combo->msw_rescale(); // ... then refill them and set min size to correct layout of the sidebar update_all_preset_comboboxes(); - p->frequently_changed_parameters->get_og(true)->rescale(); - p->frequently_changed_parameters->get_og(false)->rescale(); + p->frequently_changed_parameters->get_og(true)->msw_rescale(); + p->frequently_changed_parameters->get_og(false)->msw_rescale(); - p->object_list->rescale(); + p->object_list->msw_rescale(); - p->object_manipulation->get_og()->rescale(); - p->object_settings->rescale(); + p->object_manipulation->get_og()->msw_rescale(); + p->object_settings->msw_rescale(); - p->object_info->rescale(); + p->object_info->msw_rescale(); p->scrolled->Layout(); } @@ -1198,11 +1176,11 @@ struct Plater::priv MainFrame *main_frame; // Object popup menu - PrusaMenu object_menu; + MenuWithSeparators object_menu; // Part popup menu - PrusaMenu part_menu; + MenuWithSeparators part_menu; // SLA-Object popup menu - PrusaMenu sla_object_menu; + MenuWithSeparators sla_object_menu; // Removed/Prepended Items according to the view mode std::vector<wxMenuItem*> items_increase; @@ -3850,13 +3828,13 @@ bool Plater::can_paste_from_clipboard() const return true; } -void Plater::rescale() +void Plater::msw_rescale() { - p->preview->rescale(); + p->preview->msw_rescale(); - p->view3D->get_canvas3d()->rescale(); + p->view3D->get_canvas3d()->msw_rescale(); - p->sidebar->rescale(); + p->sidebar->msw_rescale(); Layout(); GetParent()->Layout(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index c39256f50..bedc31b35 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -14,7 +14,7 @@ #include "GLTexture.hpp" class wxButton; -class PrusaButton; +class ScalableButton; class wxBoxSizer; class wxGLCanvas; class wxScrolledWindow; @@ -47,7 +47,7 @@ public: PresetComboBox(wxWindow *parent, Preset::Type preset_type); ~PresetComboBox(); - /*wxButton*/PrusaButton* edit_btn { nullptr }; + ScalableButton* edit_btn { nullptr }; enum LabelItemType { LABEL_ITEM_MARKER = 0x4d, @@ -60,7 +60,7 @@ public: int em_unit() const { return m_em_unit; } void check_selection(); - void rescale(); + void msw_rescale(); private: typedef std::size_t Marker; @@ -88,7 +88,7 @@ public: void update_presets(Slic3r::Preset::Type preset_type); void update_mode_sizer() const; void update_reslice_btn_tooltip() const; - void rescale(); + void msw_rescale(); ObjectManipulation* obj_manipul(); ObjectList* obj_list(); @@ -206,7 +206,7 @@ public: bool can_copy() const; bool can_paste() const; - void rescale(); + void msw_rescale(); private: struct priv; diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 12d96624c..69f4e3493 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -144,7 +144,7 @@ void PreferencesDialog::accept() void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect) { - m_optgroup->rescale(); + m_optgroup->msw_rescale(); const int& em = em_unit(); const wxSize& size = wxSize(50 * em, 29 * em); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 471ba5486..31f75a926 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -54,8 +54,7 @@ SysInfoDialog::SysInfoDialog() main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10); // logo - m_logo_bmp = PrusaBitmap(this, "Slic3r_192px.png", 192); -// auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); + m_logo_bmp = ScalableBitmap(this, "Slic3r_192px.png", 192); m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bmp.bmp()); hsizer->Add(m_logo, 0, wxALIGN_CENTER_VERTICAL); @@ -65,8 +64,7 @@ SysInfoDialog::SysInfoDialog() // title { wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize); - wxFont title_font = wxGetApp().bold_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); -// title_font.SetWeight(wxFONTWEIGHT_BOLD); + wxFont title_font = wxGetApp().bold_font(); title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetPointSize(22); title->SetFont(title_font); @@ -74,7 +72,7 @@ SysInfoDialog::SysInfoDialog() } // main_info_text - wxFont font = wxGetApp().normal_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont font = wxGetApp().normal_font(); const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); @@ -136,7 +134,7 @@ SysInfoDialog::SysInfoDialog() void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect) { - m_logo_bmp.rescale(); + m_logo_bmp.msw_rescale(); m_logo->SetBitmap(m_logo_bmp.bmp()); wxFont font = GetFont(); diff --git a/src/slic3r/GUI/SysInfoDialog.hpp b/src/slic3r/GUI/SysInfoDialog.hpp index 6215d90ca..dec4b5635 100644 --- a/src/slic3r/GUI/SysInfoDialog.hpp +++ b/src/slic3r/GUI/SysInfoDialog.hpp @@ -12,11 +12,10 @@ namespace GUI { class SysInfoDialog : public DPIDialog { - wxString text_info {wxEmptyString}; - PrusaBitmap m_logo_bmp; + ScalableBitmap m_logo_bmp; wxStaticBitmap* m_logo; - wxHtmlWindow* m_opengl_info_html; - wxHtmlWindow* m_html; + wxHtmlWindow* m_opengl_info_html; + wxHtmlWindow* m_html; public: SysInfoDialog(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 69b1e7832..b57678e86 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -117,61 +117,34 @@ void Tab::create_preset_tab() //buttons m_scaled_buttons.reserve(6); m_scaled_buttons.reserve(2); -// wxBitmap bmpMenu; -// bmpMenu = create_scaled_bitmap(this, "save"); -// m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); -// if (wxMSW) m_btn_save_preset->SetBackgroundColour(color); -// bmpMenu = create_scaled_bitmap(this, "cross"/*"delete.png"*/); -// m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); -// if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color); add_scaled_button(panel, &m_btn_save_preset, "save"); add_scaled_button(panel, &m_btn_delete_preset, "cross"); m_show_incompatible_presets = false; -// m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag_red"); -// m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "flag_green"); add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red"); add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green"); -// m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); -// if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color); + add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name()); m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title); m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->Disable(); -// m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); -// m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); -// m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - add_scaled_button(panel, &m_question_btn, "question"); -// if (wxMSW) { -// m_undo_btn->SetBackgroundColour(color); -// m_undo_to_sys_btn->SetBackgroundColour(color); -// m_question_btn->SetBackgroundColour(color); -// } - m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n" "or click this button."))); // Determine the theme color of OS (dark or light) auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. -// m_bmp_value_lock = create_scaled_bitmap(this, luma >= 128 ? "lock_closed" : "lock_closed_white"); -// m_bmp_value_unlock = create_scaled_bitmap(this, "lock_open"); add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white"); add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open"); m_bmp_non_system = &m_bmp_white_bullet; // Bitmaps to be shown on the "Undo user changes" button next to each input field. -// m_bmp_value_revert = create_scaled_bitmap(this, "undo"); -// m_bmp_white_bullet = create_scaled_bitmap(this, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/); -// m_bmp_question = create_scaled_bitmap(this, "question"); -// m_bmp_value_revert = create_scaled_bitmap(this, "undo"); -// m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png"); add_scaled_bitmap(this, m_bmp_value_revert, "undo"); - add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/); + add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white"); fill_icon_descriptions(); set_tooltips_text(); @@ -179,11 +152,8 @@ void Tab::create_preset_tab() add_scaled_button(panel, &m_undo_btn, m_bmp_white_bullet.name()); add_scaled_button(panel, &m_undo_to_sys_btn, m_bmp_white_bullet.name()); -// m_undo_btn->SetBitmap(m_bmp_white_bullet); m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); -// m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); -// m_question_btn->SetBitmap(m_bmp_question); m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { auto dlg = new ButtonsDescription(this, &m_icon_descriptions); @@ -203,7 +173,7 @@ void Tab::create_preset_tab() m_default_text_clr = wxGetApp().get_label_clr_default(); // Sizer with buttons for mode changing - m_mode_sizer = new PrusaModeSizer(panel); + m_mode_sizer = new ModeSizer(panel); const float scale_factor = wxGetApp().em_unit()*0.1;// GetContentScaleFactor(); m_hsizer = new wxBoxSizer(wxHORIZONTAL); @@ -281,9 +251,9 @@ void Tab::create_preset_tab() // Fill cache for mode bitmaps m_mode_bitmap_cache.reserve(3); - m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_simple_.png")); - m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_middle_.png")); - m_mode_bitmap_cache.push_back(PrusaBitmap(this, "mode_expert_.png")); + m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_simple_.png")); + m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_middle_.png")); + m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_expert_.png")); // Initialize the DynamicPrintConfig by default keys/values. build(); @@ -291,17 +261,21 @@ void Tab::create_preset_tab() m_complited = true; } -void Tab::add_scaled_button(wxWindow* parent, PrusaButton** btn, const std::string& icon_name, +void Tab::add_scaled_button(wxWindow* parent, + ScalableButton** btn, + const std::string& icon_name, const wxString& label/* = wxEmptyString*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) { - *btn = new PrusaButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style); + *btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style); m_scaled_buttons.push_back(*btn); } -void Tab::add_scaled_bitmap(wxWindow* parent, PrusaBitmap& bmp, const std::string& icon_name) +void Tab::add_scaled_bitmap(wxWindow* parent, + ScalableBitmap& bmp, + const std::string& icon_name) { - bmp = PrusaBitmap(parent, icon_name); + bmp = ScalableBitmap(parent, icon_name); m_scaled_bitmaps.push_back(&bmp); } @@ -321,8 +295,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); if (icon_idx == -1) { // Add a new icon to the icon list. -// m_icons->Add(create_scaled_bitmap(this, icon)); - m_scaled_icons_list.push_back(PrusaBitmap(this, icon)); + m_scaled_icons_list.push_back(ScalableBitmap(this, icon)); m_icons->Add(m_scaled_icons_list.back().bmp()); icon_idx = ++m_icon_count; m_icon_index[icon] = icon_idx; @@ -442,8 +415,8 @@ void Tab::update_changed_ui() { bool is_nonsys_value = false; bool is_modified_value = true; - const /*wxBitmap*/PrusaBitmap *sys_icon = &m_bmp_value_lock; - const /*wxBitmap*/PrusaBitmap *icon = &m_bmp_value_revert; + const ScalableBitmap *sys_icon = &m_bmp_value_lock; + const ScalableBitmap *icon = &m_bmp_value_revert; const wxColour *color = &m_sys_label_clr; @@ -766,11 +739,11 @@ void Tab::update_visibility() update_changed_tree_ui(); } -void Tab::rescale() +void Tab::msw_rescale() { m_em_unit = wxGetApp().em_unit(); - m_mode_sizer->rescale(); + m_mode_sizer->msw_rescale(); m_presets_choice->SetSize(35 * m_em_unit, -1); m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1)); @@ -779,25 +752,25 @@ void Tab::rescale() // rescale buttons and cached bitmaps for (const auto btn : m_scaled_buttons) - btn->rescale(); + btn->msw_rescale(); for (const auto bmp : m_scaled_bitmaps) - bmp->rescale(); - for (PrusaBitmap& bmp : m_mode_bitmap_cache) - bmp.rescale(); + bmp->msw_rescale(); + for (ScalableBitmap& bmp : m_mode_bitmap_cache) + bmp.msw_rescale(); // rescale icons for tree_ctrl - for (PrusaBitmap& bmp : m_scaled_icons_list) - bmp.rescale(); + for (ScalableBitmap& bmp : m_scaled_icons_list) + bmp.msw_rescale(); // recreate and set new ImageList for tree_ctrl m_icons->RemoveAll(); m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight()); - for (PrusaBitmap& bmp : m_scaled_icons_list) + for (ScalableBitmap& bmp : m_scaled_icons_list) m_icons->Add(bmp.bmp()); m_treectrl->AssignImageList(m_icons); // rescale options_groups for (auto page : m_pages) - page->rescale(); + page->msw_rescale(); Layout(); } @@ -1705,12 +1678,8 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) } auto printhost_browse = [=](wxWindow* parent) { -// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, -// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); -// btn->SetBitmap(create_scaled_bitmap(this, "browse")); add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); - PrusaButton* btn = m_printhost_browse_btn; + ScalableButton* btn = m_printhost_browse_btn; btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1728,12 +1697,8 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) }; auto print_host_test = [this](wxWindow* parent) { -// auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), -// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); -// btn->SetBitmap(create_scaled_bitmap(this, "test")); add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT); - PrusaButton* btn = m_print_host_test_btn; + ScalableButton* btn = m_print_host_test_btn; btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1849,11 +1814,7 @@ void TabPrinter::build_fff() Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { -// auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetFont(wxGetApp().small_font()); -// btn->SetBitmap(create_scaled_bitmap(this, "printer")); - - PrusaButton* btn; + ScalableButton* btn; add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().normal_font()); @@ -2054,11 +2015,7 @@ void TabPrinter::build_sla() Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { -// auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetFont(wxGetApp().small_font()); -// btn->SetBitmap(create_scaled_bitmap(this, "printer")); - - PrusaButton* btn; + ScalableButton* btn; add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().normal_font()); @@ -2157,7 +2114,6 @@ void TabPrinter::extruders_count_changed(size_t extruders_count) * of unregular pages of a Printer Settings */ build_unregular_pages(); -// reload_config(); // #ys_FIXME_delete_after_testing : This function is called from build_extruder_pages() now if (is_count_changed) { on_value_change("extruders_count", extruders_count); @@ -3029,12 +2985,9 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep { deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); -// deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); add_scaled_button(parent, &deps.btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); -// deps.btn->SetBitmap(create_scaled_bitmap(this, "printer")); - auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); sizer->Add((deps.btn), 0, wxALIGN_CENTER_VERTICAL); @@ -3190,10 +3143,10 @@ void Page::update_visibility(ConfigOptionMode mode) m_show = ret_val; } -void Page::rescale() +void Page::msw_rescale() { for (auto group : m_optgroups) - group->rescale(); + group->msw_rescale(); } Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const @@ -3223,14 +3176,6 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la { std::string bmp_name; const std::vector<Option>& options = line.get_options(); -// if (options.size() == 0 || options[0].opt.gui_type == "legend") -// bmp_name = ""; -// else { -// auto mode = options[0].opt.mode; //we assume that we have one option per line -// bmp_name = mode == comExpert ? "mode_expert_.png" : -// mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; -// } -// auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name)); int mode_id = int(options[0].opt.mode); const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap : m_mode_bitmap_cache[mode_id].bmp(); @@ -3280,7 +3225,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la if (ctrl == nullptr) return; - ctrl->SetBitmap(reinterpret_cast<PrusaBitmap*>(ctrl->GetClientData())->bmp()); + ctrl->SetBitmap(reinterpret_cast<ScalableBitmap*>(ctrl->GetClientData())->bmp()); }; vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 0e0e0ad5e..ae13cb4b5 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -36,8 +36,8 @@ namespace Slic3r { namespace GUI { -typedef std::pair</*wxBitmap*/PrusaBitmap*, std::string> t_icon_description; -typedef std::vector<std::pair</*wxBitmap*/PrusaBitmap*, std::string>> t_icon_descriptions; +typedef std::pair<ScalableBitmap*, std::string> t_icon_description; +typedef std::vector<std::pair<ScalableBitmap*, std::string>> t_icon_descriptions; // Single Tab page containing a{ vsizer } of{ optgroups } // package Slic3r::GUI::Tab::Page; @@ -50,7 +50,7 @@ class Page : public wxScrolledWindow wxBoxSizer* m_vsizer; bool m_show = true; public: - Page(wxWindow* parent, const wxString title, const int iconID, const std::vector<PrusaBitmap>& mode_bmp_cache) : + Page(wxWindow* parent, const wxString title, const int iconID, const std::vector<ScalableBitmap>& mode_bmp_cache) : m_parent(parent), m_title(title), m_iconID(iconID), @@ -68,7 +68,7 @@ public: // Delayed layout after resizing the main window. bool layout_valid = false; - const std::vector<PrusaBitmap>& m_mode_bitmap_cache; + const std::vector<ScalableBitmap>& m_mode_bitmap_cache; public: std::vector <ConfigOptionsGroupShp> m_optgroups; @@ -81,7 +81,7 @@ public: void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } void reload_config(); void update_visibility(ConfigOptionMode mode); - void rescale(); + void msw_rescale(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1); @@ -122,20 +122,20 @@ protected: std::string m_name; const wxString m_title; wxBitmapComboBox* m_presets_choice; - /*wxBitmap*/PrusaButton* m_btn_save_preset; - /*wxBitmap*/PrusaButton* m_btn_delete_preset; - /*wxBitmap*/PrusaButton* m_btn_hide_incompatible_presets; + ScalableButton* m_btn_save_preset; + ScalableButton* m_btn_delete_preset; + ScalableButton* m_btn_hide_incompatible_presets; wxBoxSizer* m_hsizer; wxBoxSizer* m_left_sizer; wxTreeCtrl* m_treectrl; wxImageList* m_icons; - PrusaModeSizer* m_mode_sizer; + ModeSizer* m_mode_sizer; struct PresetDependencies { Preset::Type type = Preset::TYPE_INVALID; wxCheckBox *checkbox = nullptr; - /*wxButton*/PrusaButton *btn = nullptr; + ScalableButton *btn = nullptr; std::string key_list; // "compatible_printers" std::string key_condition; std::string dialog_title; @@ -144,27 +144,27 @@ protected: PresetDependencies m_compatible_printers; PresetDependencies m_compatible_prints; - /*wxButton*/PrusaButton* m_undo_btn; - /*wxButton*/PrusaButton* m_undo_to_sys_btn; - /*wxButton*/PrusaButton* m_question_btn; + ScalableButton* m_undo_btn; + ScalableButton* m_undo_to_sys_btn; + ScalableButton* m_question_btn; // Cached bitmaps. // A "flag" icon to be displayned next to the preset name in the Tab's combo box. - /*wxBitmap*/PrusaBitmap m_bmp_show_incompatible_presets; - /*wxBitmap*/PrusaBitmap m_bmp_hide_incompatible_presets; + ScalableBitmap m_bmp_show_incompatible_presets; + ScalableBitmap m_bmp_hide_incompatible_presets; // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - /*wxBitmap*/PrusaBitmap m_bmp_value_lock; - /*wxBitmap*/PrusaBitmap m_bmp_value_unlock; - /*wxBitmap*/PrusaBitmap m_bmp_white_bullet; + ScalableBitmap m_bmp_value_lock; + ScalableBitmap m_bmp_value_unlock; + ScalableBitmap m_bmp_white_bullet; // The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset. - /*wxBitmap*/PrusaBitmap *m_bmp_non_system; + ScalableBitmap *m_bmp_non_system; // Bitmaps to be shown on the "Undo user changes" button next to each input field. - /*wxBitmap*/PrusaBitmap m_bmp_value_revert; + ScalableBitmap m_bmp_value_revert; - std::vector<PrusaButton*> m_scaled_buttons = {}; - std::vector<PrusaBitmap*> m_scaled_bitmaps = {}; - std::vector<PrusaBitmap> m_scaled_icons_list = {}; - std::vector<PrusaBitmap> m_mode_bitmap_cache = {}; + std::vector<ScalableButton*> m_scaled_buttons = {}; + std::vector<ScalableBitmap*> m_scaled_bitmaps = {}; + std::vector<ScalableBitmap> m_scaled_icons_list = {}; + std::vector<ScalableBitmap> m_mode_bitmap_cache = {}; // Colors for ui "decoration" wxColour m_sys_label_clr; @@ -241,10 +241,10 @@ public: virtual bool supports_printer_technology(const PrinterTechnology tech) = 0; void create_preset_tab(); - void add_scaled_button(wxWindow* parent, PrusaButton** btn, const std::string& icon_name, + void add_scaled_button(wxWindow* parent, ScalableButton** btn, const std::string& icon_name, const wxString& label = wxEmptyString, long style = wxBU_EXACTFIT | wxNO_BORDER); - void add_scaled_bitmap(wxWindow* parent, PrusaBitmap& btn, const std::string& icon_name); + void add_scaled_bitmap(wxWindow* parent, ScalableBitmap& btn, const std::string& icon_name); void load_current_preset(); void rebuild_page_tree(); void update_page_tree_visibility(); @@ -283,7 +283,7 @@ public: virtual void reload_config(); void update_mode(); void update_visibility(); - void rescale(); + void msw_rescale(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText); @@ -355,8 +355,8 @@ class TabPrinter : public Tab void build_printhost(ConfigOptionsGroup *optgroup); public: wxButton* m_serial_test_btn = nullptr; - /*wxButton*/PrusaButton* m_print_host_test_btn = nullptr; - /*wxButton*/PrusaButton* m_printhost_browse_btn = nullptr; + ScalableButton* m_print_host_test_btn = nullptr; + ScalableButton* m_printhost_browse_btn = nullptr; size_t m_extruders_count; size_t m_extruders_count_old = 0; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 4dc6b6e2a..277494034 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -267,160 +267,6 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e cmb->SetText(selected); } -// ---------------------------------------------------------------------------- -// *** PrusaCollapsiblePane *** -// ---------------------------------------------------------------------------- -void PrusaCollapsiblePane::OnStateChange(const wxSize& sz) -{ -#ifdef __WXOSX__ - wxCollapsiblePane::OnStateChange(sz); -#else - SetSize(sz); - - if (this->HasFlag(wxCP_NO_TLW_RESIZE)) - { - // the user asked to explicitly handle the resizing itself... - return; - } - - auto top = GetParent(); //right_panel - if (!top) - return; - - wxSizer *sizer = top->GetSizer(); - if (!sizer) - return; - - const wxSize newBestSize = sizer->ComputeFittingClientSize(top); - top->SetMinClientSize(newBestSize); - - wxWindowUpdateLocker noUpdates_p(top->GetParent()); - // we shouldn't attempt to resize a maximized window, whatever happens - // if (!top->IsMaximized()) - // top->SetClientSize(newBestSize); - top->GetParent()->Layout(); - top->Refresh(); -#endif //__WXOSX__ -} - -// ---------------------------------------------------------------------------- -// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__ -// ---------------------------------------------------------------------------- -#ifdef __WXMSW__ -bool PrusaCollapsiblePaneMSW::Create(wxWindow *parent, wxWindowID id, const wxString& label, - const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name) -{ - if (!wxControl::Create(parent, id, pos, size, style, val, name)) - return false; - // m_pStaticLine = NULL; - m_strLabel = label; - - // sizer containing the expand button and possibly a static line - m_sz = new wxBoxSizer(wxHORIZONTAL); - - m_bmp_close.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_close.png")), wxBITMAP_TYPE_PNG); - m_bmp_open.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_open.png")), wxBITMAP_TYPE_PNG); - - m_pDisclosureTriangleButton = new wxButton(this, wxID_ANY, m_strLabel, wxPoint(0, 0), - wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - UpdateBtnBmp(); - m_pDisclosureTriangleButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) - { - if (event.GetEventObject() != m_pDisclosureTriangleButton) - { - event.Skip(); - return; - } - - Collapse(!IsCollapsed()); - - // this change was generated by the user - send the event - wxCollapsiblePaneEvent ev(this, GetId(), IsCollapsed()); - GetEventHandler()->ProcessEvent(ev); - }); - - m_sz->Add(m_pDisclosureTriangleButton, 0, wxLEFT | wxTOP | wxBOTTOM, GetBorder()); - - // do not set sz as our sizers since we handle the pane window without using sizers - m_pPane = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxTAB_TRAVERSAL | wxNO_BORDER, wxT("wxCollapsiblePanePane")); - - wxColour&& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_pDisclosureTriangleButton->SetBackgroundColour(clr); - this->SetBackgroundColour(clr); - m_pPane->SetBackgroundColour(clr); - - // start as collapsed: - m_pPane->Hide(); - - return true; -} - -void PrusaCollapsiblePaneMSW::UpdateBtnBmp() -{ - if (IsCollapsed()) - m_pDisclosureTriangleButton->SetBitmap(m_bmp_close); - else{ - m_pDisclosureTriangleButton->SetBitmap(m_bmp_open); - // To updating button bitmap it's needed to lost focus on this button, so - // we set focus to mainframe - //GetParent()->GetParent()->GetParent()->SetFocus(); - //or to pane - GetPane()->SetFocus(); - } - Layout(); -} - -void PrusaCollapsiblePaneMSW::SetLabel(const wxString &label) -{ - m_strLabel = label; - m_pDisclosureTriangleButton->SetLabel(m_strLabel); - Layout(); -} - -bool PrusaCollapsiblePaneMSW::Layout() -{ - if (!m_pDisclosureTriangleButton || !m_pPane || !m_sz) - return false; // we need to complete the creation first! - - wxSize oursz(GetSize()); - - // move & resize the button and the static line - m_sz->SetDimension(0, 0, oursz.GetWidth(), m_sz->GetMinSize().GetHeight()); - m_sz->Layout(); - - if (IsExpanded()) - { - // move & resize the container window - int yoffset = m_sz->GetSize().GetHeight() + GetBorder(); - m_pPane->SetSize(0, yoffset, - oursz.x, oursz.y - yoffset); - - // this is very important to make the pane window layout show correctly - m_pPane->Layout(); - } - - return true; -} - -void PrusaCollapsiblePaneMSW::Collapse(bool collapse) -{ - // optimization - if (IsCollapsed() == collapse) - return; - - InvalidateBestSize(); - - // update our state - m_pPane->Show(!collapse); - - // update button bitmap - UpdateBtnBmp(); - - OnStateChange(GetBestSize()); -} -#endif //__WXMSW__ - /* Function for getting of em_unit value from correct parent. * In most of cases it is m_em_unit value from GUI_App, * but for DPIDialogs it's its own value. @@ -474,17 +320,10 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, con // ***************************************************************************** // ---------------------------------------------------------------------------- -// PrusaObjectDataViewModelNode +// ObjectDataViewModelNode // ---------------------------------------------------------------------------- -/* -void PrusaObjectDataViewModelNode::set_object_action_icon() { - m_action_icon = create_scaled_bitmap(nullptr, "advanced_plus"); // FIXME: pass window ptr -} -void PrusaObjectDataViewModelNode::set_part_action_icon() { - m_action_icon = create_scaled_bitmap(nullptr, m_type == itVolume ? "cog" : "set_separate_obj"); // FIXME: pass window ptr -} -*/ -void PrusaObjectDataViewModelNode::set_action_icon() + +void ObjectDataViewModelNode::set_action_icon() { m_action_icon_name = m_type == itObject ? "advanced_plus" : m_type == itVolume ? "cog" : "set_separate_obj"; @@ -492,7 +331,7 @@ void PrusaObjectDataViewModelNode::set_action_icon() } Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; -void PrusaObjectDataViewModelNode::update_settings_digest_bitmaps() +void ObjectDataViewModelNode::update_settings_digest_bitmaps() { m_bmp = m_empty_bmp; @@ -513,40 +352,25 @@ void PrusaObjectDataViewModelNode::update_settings_digest_bitmaps() m_bmp = *bmp; } -bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std::string>& categories) +bool ObjectDataViewModelNode::update_settings_digest(const std::vector<std::string>& categories) { if (m_type != itSettings || m_opt_categories == categories) return false; m_opt_categories = categories; m_name = wxEmptyString; -// m_bmp = m_empty_bmp; - -// std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON; for (auto& cat : m_opt_categories) m_name += cat + "; "; if (!m_name.IsEmpty()) m_name.erase(m_name.Length()-2, 2); // Delete last "; " - /* - wxBitmap *bmp = m_bitmap_cache->find(m_name.ToUTF8().data()); - if (bmp == nullptr) { - std::vector<wxBitmap> bmps; - for (auto& cat : m_opt_categories) - bmps.emplace_back(categories_icon.find(cat) == categories_icon.end() ? - wxNullBitmap : categories_icon.at(cat)); - bmp = m_bitmap_cache->insert(m_name.ToUTF8().data(), bmps); - } - - m_bmp = *bmp; - */ update_settings_digest_bitmaps(); return true; } -void PrusaObjectDataViewModelNode::rescale() +void ObjectDataViewModelNode::msw_rescale() { if (!m_action_icon_name.empty()) m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); @@ -557,15 +381,15 @@ void PrusaObjectDataViewModelNode::rescale() // ***************************************************************************** // ---------------------------------------------------------------------------- -// PrusaObjectDataViewModel +// ObjectDataViewModel // ---------------------------------------------------------------------------- -PrusaObjectDataViewModel::PrusaObjectDataViewModel() +ObjectDataViewModel::ObjectDataViewModel() { m_bitmap_cache = new Slic3r::GUI::BitmapCache; } -PrusaObjectDataViewModel::~PrusaObjectDataViewModel() +ObjectDataViewModel::~ObjectDataViewModel() { for (auto object : m_objects) delete object; @@ -573,10 +397,10 @@ PrusaObjectDataViewModel::~PrusaObjectDataViewModel() m_bitmap_cache = nullptr; } -wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int extruder) +wxDataViewItem ObjectDataViewModel::Add(const wxString &name, const int extruder) { const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); - auto root = new PrusaObjectDataViewModelNode(name, extruder_str); + auto root = new ObjectDataViewModelNode(name, extruder_str); m_objects.push_back(root); // notify control wxDataViewItem child((void*)root); @@ -585,13 +409,13 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int ext return child; } -wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &parent_item, - const wxString &name, - const Slic3r::ModelVolumeType volume_type, - const int extruder/* = 0*/, - const bool create_frst_child/* = true*/) +wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item, + const wxString &name, + const Slic3r::ModelVolumeType volume_type, + const int extruder/* = 0*/, + const bool create_frst_child/* = true*/) { - PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + ObjectDataViewModelNode *root = (ObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); @@ -603,7 +427,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa if (create_frst_child && root->m_volumes_cnt == 0) { - const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, *m_volume_bmps[0], extruder_str, 0); + const auto node = new ObjectDataViewModelNode(root, root->m_name, *m_volume_bmps[0], extruder_str, 0); insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position); // notify control const wxDataViewItem child((void*)node); @@ -615,7 +439,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa node->m_volume_type = volume_type; } - const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[int(volume_type)], extruder_str, root->m_volumes_cnt); + const auto node = new ObjectDataViewModelNode(root, name, *m_volume_bmps[int(volume_type)], extruder_str, root->m_volumes_cnt); insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position); // notify control const wxDataViewItem child((void*)node); @@ -627,12 +451,12 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa return child; } -wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item) +wxDataViewItem ObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item) { - PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + ObjectDataViewModelNode *root = (ObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); - const auto node = new PrusaObjectDataViewModelNode(root, itSettings); + const auto node = new ObjectDataViewModelNode(root, itSettings); root->Insert(node, 0); // notify control const wxDataViewItem child((void*)node); @@ -640,27 +464,27 @@ wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem & return child; } -int get_istances_root_idx(PrusaObjectDataViewModelNode *parent_node) +int get_istances_root_idx(ObjectDataViewModelNode *parent_node) { // because of istance_root is a last item of the object const int inst_root_idx = parent_node->GetChildCount()-1; - if (inst_root_idx < 0 || parent_node->GetNthChild(inst_root_idx)->m_type == itInstanceRoot) + if (inst_root_idx < 0 || parent_node->GetNthChild(inst_root_idx)->GetType() == itInstanceRoot) return inst_root_idx; return -1; } -wxDataViewItem PrusaObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) +wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) { - PrusaObjectDataViewModelNode *parent_node = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); // Check and create/get instances root node const int inst_root_id = get_istances_root_idx(parent_node); - PrusaObjectDataViewModelNode *inst_root_node = inst_root_id < 0 ? - new PrusaObjectDataViewModelNode(parent_node, itInstanceRoot) : + ObjectDataViewModelNode *inst_root_node = inst_root_id < 0 ? + new ObjectDataViewModelNode(parent_node, itInstanceRoot) : parent_node->GetNthChild(inst_root_id); const wxDataViewItem inst_root_item((void*)inst_root_node); @@ -672,10 +496,10 @@ wxDataViewItem PrusaObjectDataViewModel::AddInstanceChild(const wxDataViewItem & } // Add instance nodes - PrusaObjectDataViewModelNode *instance_node = nullptr; + ObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; while (counter < num) { - instance_node = new PrusaObjectDataViewModelNode(inst_root_node, itInstance); + instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -686,10 +510,10 @@ wxDataViewItem PrusaObjectDataViewModel::AddInstanceChild(const wxDataViewItem & return wxDataViewItem((void*)instance_node); } -wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) +wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) { auto ret_item = wxDataViewItem(0); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return ret_item; @@ -737,12 +561,12 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) delete node; ItemDeleted(parent, item); - PrusaObjectDataViewModelNode *last_instance_node = node_parent->GetNthChild(0); + ObjectDataViewModelNode *last_instance_node = node_parent->GetNthChild(0); node_parent->GetChildren().Remove(last_instance_node); delete last_instance_node; ItemDeleted(parent, wxDataViewItem(last_instance_node)); - PrusaObjectDataViewModelNode *obj_node = node_parent->GetParent(); + ObjectDataViewModelNode *obj_node = node_parent->GetParent(); obj_node->GetChildren().Remove(node_parent); delete node_parent; ret_item = wxDataViewItem(obj_node); @@ -773,7 +597,7 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) delete node; ItemDeleted(parent, item); - PrusaObjectDataViewModelNode *last_child_node = node_parent->GetNthChild(vol_idx); + ObjectDataViewModelNode *last_child_node = node_parent->GetNthChild(vol_idx); DeleteSettings(wxDataViewItem(last_child_node)); node_parent->GetChildren().Remove(last_child_node); node_parent->m_volumes_cnt = 0; @@ -832,17 +656,17 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) return ret_item; } -wxDataViewItem PrusaObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &parent_item, size_t num) +wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &parent_item, size_t num) { auto ret_item = wxDataViewItem(0); - PrusaObjectDataViewModelNode *parent_node = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return ret_item; const int inst_root_id = get_istances_root_idx(parent_node); if (inst_root_id < 0) return ret_item; wxDataViewItemArray items; - PrusaObjectDataViewModelNode *inst_root_node = parent_node->GetNthChild(inst_root_id); + ObjectDataViewModelNode *inst_root_node = parent_node->GetNthChild(inst_root_id); const wxDataViewItem inst_root_item((void*)inst_root_node); const int inst_cnt = inst_root_node->GetChildCount(); @@ -850,7 +674,7 @@ wxDataViewItem PrusaObjectDataViewModel::DeleteLastInstance(const wxDataViewItem int stop = delete_inst_root_item ? 0 : inst_cnt - num; for (int i = inst_cnt - 1; i >= stop;--i) { - PrusaObjectDataViewModelNode *last_instance_node = inst_root_node->GetNthChild(i); + ObjectDataViewModelNode *last_instance_node = inst_root_node->GetNthChild(i); inst_root_node->GetChildren().Remove(last_instance_node); delete last_instance_node; ItemDeleted(inst_root_item, wxDataViewItem(last_instance_node)); @@ -869,7 +693,7 @@ wxDataViewItem PrusaObjectDataViewModel::DeleteLastInstance(const wxDataViewItem return ret_item; } -void PrusaObjectDataViewModel::DeleteAll() +void ObjectDataViewModel::DeleteAll() { while (!m_objects.empty()) { @@ -879,9 +703,9 @@ void PrusaObjectDataViewModel::DeleteAll() } } -void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) +void ObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) { - PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *root = (ObjectDataViewModelNode*)parent.GetID(); if (!root) // happens if item.IsOk()==false return; @@ -911,9 +735,9 @@ void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) #endif //__WXGTK__ } -void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) +void ObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) { - PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *root = (ObjectDataViewModelNode*)parent.GetID(); if (!root) // happens if item.IsOk()==false return; @@ -945,9 +769,9 @@ void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) #endif //__WXGTK__ } -void PrusaObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) +void ObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) { - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)parent.GetID(); if (!node) return; // if volume has a "settings"item, than delete it before volume deleting @@ -960,7 +784,7 @@ void PrusaObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) } } -wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) +wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx) { if (obj_idx >= m_objects.size()) { @@ -971,7 +795,7 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) } -wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx) +wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx) { if (obj_idx >= m_objects.size() || obj_idx < 0) { printf("Error! Out of objects range.\n"); @@ -995,7 +819,7 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volu return wxDataViewItem(0); } -wxDataViewItem PrusaObjectDataViewModel::GetItemByInstanceId(int obj_idx, int inst_idx) +wxDataViewItem ObjectDataViewModel::GetItemByInstanceId(int obj_idx, int inst_idx) { if (obj_idx >= m_objects.size() || obj_idx < 0) { printf("Error! Out of objects range.\n"); @@ -1006,7 +830,7 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByInstanceId(int obj_idx, int in if (!instances_item) return wxDataViewItem(0); - auto parent = (PrusaObjectDataViewModelNode*)instances_item.GetID();; + auto parent = (ObjectDataViewModelNode*)instances_item.GetID();; for (size_t i = 0; i < parent->GetChildCount(); i++) if (parent->GetNthChild(i)->m_idx == inst_idx) return wxDataViewItem(parent->GetNthChild(i)); @@ -1014,11 +838,11 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByInstanceId(int obj_idx, int in return wxDataViewItem(0); } -int PrusaObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const +int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const { wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); auto it = find(m_objects.begin(), m_objects.end(), node); if (it == m_objects.end()) return -1; @@ -1026,44 +850,44 @@ int PrusaObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const return it - m_objects.begin(); } -int PrusaObjectDataViewModel::GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const +int ObjectDataViewModel::GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const { wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (!node || node->m_type != type) return -1; return node->GetIdx(); } -int PrusaObjectDataViewModel::GetObjectIdByItem(const wxDataViewItem& item) const +int ObjectDataViewModel::GetObjectIdByItem(const wxDataViewItem& item) const { return GetIdByItem(GetTopParent(item)); } -int PrusaObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item) const +int ObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item) const { return GetIdByItemAndType(item, itVolume); } -int PrusaObjectDataViewModel::GetInstanceIdByItem(const wxDataViewItem& item) const +int ObjectDataViewModel::GetInstanceIdByItem(const wxDataViewItem& item) const { return GetIdByItemAndType(item, itInstance); } -void PrusaObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx) +void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx) { wxASSERT(item.IsOk()); type = itUndef; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (!node || node->GetIdx() <-1 || node->GetIdx() ==-1 && !(node->GetType() & (itObject | itSettings | itInstanceRoot))) return; idx = node->GetIdx(); type = node->GetType(); - PrusaObjectDataViewModelNode *parent_node = node->GetParent(); + ObjectDataViewModelNode *parent_node = node->GetParent(); if (!parent_node) return; if (type == itInstance) parent_node = node->GetParent()->GetParent(); @@ -1076,7 +900,7 @@ void PrusaObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type = itUndef; } -int PrusaObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const +int ObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const { if (m_objects.empty()) return -1; @@ -1092,7 +916,7 @@ int PrusaObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const for (int j = 0; j < m_objects[i]->GetChildCount(); j++) { row_num++; - PrusaObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j); + ObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j); if (item == wxDataViewItem(cur_node)) return row_num; @@ -1114,30 +938,30 @@ int PrusaObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const return -1; } -wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const +wxString ObjectDataViewModel::GetName(const wxDataViewItem &item) const { - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return wxEmptyString; return node->m_name; } -wxBitmap& PrusaObjectDataViewModel::GetBitmap(const wxDataViewItem &item) const +wxBitmap& ObjectDataViewModel::GetBitmap(const wxDataViewItem &item) const { - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); return node->m_bmp; } -void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const +void ObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); switch (col) { case 0: - variant << PrusaDataViewBitmapText(node->m_name, node->m_bmp); + variant << DataViewBitmapText(node->m_name, node->m_bmp); break; case 1: variant = node->m_extruder; @@ -1150,83 +974,37 @@ void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem } } -bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) +bool ObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) { wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); return node->SetValue(variant, col); } -bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) +bool ObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) { if (item_idx < 0 || item_idx >= m_objects.size()) return false; return m_objects[item_idx]->SetValue(variant, col); } -/* -wxDataViewItem PrusaObjectDataViewModel::MoveChildUp(const wxDataViewItem &item) -{ - auto ret_item = wxDataViewItem(0); - wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return ret_item; - auto node_parent = node->GetParent(); - if (!node_parent) // If isn't part, but object - return ret_item; - - auto volume_id = node->GetVolumeId(); - if (0 < volume_id && volume_id < node_parent->GetChildCount()) { - node_parent->SwapChildrens(volume_id - 1, volume_id); - ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1)); - ItemChanged(item); - ItemChanged(ret_item); - } - else - ret_item = wxDataViewItem(node_parent->GetNthChild(0)); - return ret_item; -} - -wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &item) -{ - auto ret_item = wxDataViewItem(0); - wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return ret_item; - - auto node_parent = node->GetParent(); - if (!node_parent) // If isn't part, but object - return ret_item; - - auto volume_id = node->GetVolumeId(); - if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()) { - node_parent->SwapChildrens(volume_id + 1, volume_id); - ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1)); - ItemChanged(item); - ItemChanged(ret_item); - } - else - ret_item = wxDataViewItem(node_parent->GetNthChild(node_parent->GetChildCount()-1)); - return ret_item; -} -*/ -wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_id, int new_volume_id, const wxDataViewItem &parent) +wxDataViewItem ObjectDataViewModel::ReorganizeChildren( const int current_volume_id, + const int new_volume_id, + const wxDataViewItem &parent) { auto ret_item = wxDataViewItem(0); if (current_volume_id == new_volume_id) return ret_item; wxASSERT(parent.IsOk()); - PrusaObjectDataViewModelNode *node_parent = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *node_parent = (ObjectDataViewModelNode*)parent.GetID(); if (!node_parent) // happens if item.IsOk()==false return ret_item; const size_t shift = node_parent->GetChildren().Item(0)->m_type == itSettings ? 1 : 0; - PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id+shift); + ObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id+shift); node_parent->GetChildren().Remove(deleted_node); ItemDeleted(parent, wxDataViewItem(deleted_node)); node_parent->Insert(deleted_node, new_volume_id+shift); @@ -1245,22 +1023,22 @@ wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_i return wxDataViewItem(node_parent->GetNthChild(new_volume_id+shift)); } -bool PrusaObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const +bool ObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); // disable extruder selection for the non "itObject|itVolume" item return !(col == 1 && node->m_extruder.IsEmpty()); } -wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) const +wxDataViewItem ObjectDataViewModel::GetParent(const wxDataViewItem &item) const { // the invisible root node has no parent if (!item.IsOk()) return wxDataViewItem(0); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); // objects nodes has no parent too if (node->m_type == itObject) @@ -1269,17 +1047,17 @@ wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) c return wxDataViewItem((void*)node->GetParent()); } -wxDataViewItem PrusaObjectDataViewModel::GetTopParent(const wxDataViewItem &item) const +wxDataViewItem ObjectDataViewModel::GetTopParent(const wxDataViewItem &item) const { // the invisible root node has no parent if (!item.IsOk()) return wxDataViewItem(0); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (node->m_type == itObject) return item; - PrusaObjectDataViewModelNode *parent_node = node->GetParent(); + ObjectDataViewModelNode *parent_node = node->GetParent(); while (parent_node->m_type != itObject) { node = parent_node; @@ -1289,19 +1067,19 @@ wxDataViewItem PrusaObjectDataViewModel::GetTopParent(const wxDataViewItem &item return wxDataViewItem((void*)parent_node); } -bool PrusaObjectDataViewModel::IsContainer(const wxDataViewItem &item) const +bool ObjectDataViewModel::IsContainer(const wxDataViewItem &item) const { // the invisible root node can have children if (!item.IsOk()) return true; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); return node->IsContainer(); } -unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +unsigned int ObjectDataViewModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const { - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)parent.GetID(); if (!node) { for (auto object : m_objects) @@ -1317,16 +1095,16 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, unsigned int count = node->GetChildren().GetCount(); for (unsigned int pos = 0; pos < count; pos++) { - PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos); + ObjectDataViewModelNode *child = node->GetChildren().Item(pos); array.Add(wxDataViewItem((void*)child)); } return count; } -void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +void ObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const { - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)parent.GetID(); if (!node) { for (auto object : m_objects) array.Add(wxDataViewItem((void*)object)); @@ -1336,7 +1114,7 @@ void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDa else { const size_t count = node->GetChildren().GetCount(); for (size_t pos = 0; pos < count; pos++) { - PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos); + ObjectDataViewModelNode *child = node->GetChildren().Item(pos); array.Add(wxDataViewItem((void*)child)); } } @@ -1350,20 +1128,20 @@ void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDa } } -ItemType PrusaObjectDataViewModel::GetItemType(const wxDataViewItem &item) const +ItemType ObjectDataViewModel::GetItemType(const wxDataViewItem &item) const { if (!item.IsOk()) return itUndef; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); return node->m_type; } -wxDataViewItem PrusaObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_item, ItemType type) const +wxDataViewItem ObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_item, ItemType type) const { if (!parent_item.IsOk()) return wxDataViewItem(0); - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)parent_item.GetID(); if (node->GetChildCount() == 0) return wxDataViewItem(0); @@ -1375,45 +1153,45 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByType(const wxDataViewItem &par return wxDataViewItem(0); } -wxDataViewItem PrusaObjectDataViewModel::GetSettingsItem(const wxDataViewItem &item) const +wxDataViewItem ObjectDataViewModel::GetSettingsItem(const wxDataViewItem &item) const { return GetItemByType(item, itSettings); } -wxDataViewItem PrusaObjectDataViewModel::GetInstanceRootItem(const wxDataViewItem &item) const +wxDataViewItem ObjectDataViewModel::GetInstanceRootItem(const wxDataViewItem &item) const { return GetItemByType(item, itInstanceRoot); } -bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const +bool ObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const { if (!item.IsOk()) return false; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); return node->m_type == itSettings; } -void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, +void ObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories) { if (!item.IsOk()) return; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); if (!node->update_settings_digest(categories)) return; ItemChanged(item); } -void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type) +void ObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type) { if (!item.IsOk() || GetItemType(item) != itVolume) return; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); node->SetBitmap(*m_volume_bmps[int(type)]); ItemChanged(item); } -void PrusaObjectDataViewModel::Rescale() +void ObjectDataViewModel::Rescale() { wxDataViewItemArray all_items; GetAllChildren(wxDataViewItem(0), all_items); @@ -1423,8 +1201,8 @@ void PrusaObjectDataViewModel::Rescale() if (!item.IsOk()) continue; - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); - node->rescale(); + ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); + node->msw_rescale(); if (node->m_type & itVolume) node->m_bmp = *m_volume_bmps[node->volume_type()]; @@ -1440,16 +1218,16 @@ void PrusaObjectDataViewModel::Rescale() // PrusaDataViewBitmapText //----------------------------------------------------------------------------- -wxIMPLEMENT_DYNAMIC_CLASS(PrusaDataViewBitmapText, wxObject) +wxIMPLEMENT_DYNAMIC_CLASS(DataViewBitmapText, wxObject) -IMPLEMENT_VARIANT_OBJECT(PrusaDataViewBitmapText) +IMPLEMENT_VARIANT_OBJECT(DataViewBitmapText) // --------------------------------------------------------- -// PrusaIconTextRenderer +// BitmapTextRenderer // --------------------------------------------------------- #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING -PrusaBitmapTextRenderer::PrusaBitmapTextRenderer(wxDataViewCellMode mode /*= wxDATAVIEW_CELL_EDITABLE*/, +BitmapTextRenderer::BitmapTextRenderer(wxDataViewCellMode mode /*= wxDATAVIEW_CELL_EDITABLE*/, int align /*= wxDVR_DEFAULT_ALIGNMENT*/): wxDataViewRenderer(wxT("PrusaDataViewBitmapText"), mode, align) { @@ -1458,25 +1236,25 @@ wxDataViewRenderer(wxT("PrusaDataViewBitmapText"), mode, align) } #endif // ENABLE_NONCUSTOM_DATA_VIEW_RENDERING -bool PrusaBitmapTextRenderer::SetValue(const wxVariant &value) +bool BitmapTextRenderer::SetValue(const wxVariant &value) { m_value << value; return true; } -bool PrusaBitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const +bool BitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const { return false; } #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING && wxUSE_ACCESSIBILITY -wxString PrusaBitmapTextRenderer::GetAccessibleDescription() const +wxString BitmapTextRenderer::GetAccessibleDescription() const { return m_value.GetText(); } #endif // wxUSE_ACCESSIBILITY && ENABLE_NONCUSTOM_DATA_VIEW_RENDERING -bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state) +bool BitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state) { int xoffset = 0; @@ -1492,7 +1270,7 @@ bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state) return true; } -wxSize PrusaBitmapTextRenderer::GetSize() const +wxSize BitmapTextRenderer::GetSize() const { if (!m_value.GetText().empty()) { @@ -1506,15 +1284,15 @@ wxSize PrusaBitmapTextRenderer::GetSize() const } -wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelRect, const wxVariant& value) +wxWindow* BitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelRect, const wxVariant& value) { wxDataViewCtrl* const dv_ctrl = GetOwner()->GetOwner(); - PrusaObjectDataViewModel* const model = dynamic_cast<PrusaObjectDataViewModel*>(dv_ctrl->GetModel()); + ObjectDataViewModel* const model = dynamic_cast<ObjectDataViewModel*>(dv_ctrl->GetModel()); if ( !(model->GetItemType(dv_ctrl->GetSelection()) & (itVolume | itObject)) ) return nullptr; - PrusaDataViewBitmapText data; + DataViewBitmapText data; data << value; m_was_unusable_symbol = false; @@ -1534,7 +1312,7 @@ wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect lab return text_editor; } -bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) +bool BitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) { wxTextCtrl* text_editor = wxDynamicCast(ctrl, wxTextCtrl); if (!text_editor || text_editor->GetValue().IsEmpty()) @@ -1553,7 +1331,7 @@ bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& wxVariant valueOld; GetView()->GetModel()->GetValue(valueOld, m_item, 0); - PrusaDataViewBitmapText bmpText; + DataViewBitmapText bmpText; bmpText << valueOld; // But replace the text with the value entered by user. @@ -1564,19 +1342,19 @@ bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& } // ---------------------------------------------------------------------------- -// PrusaDoubleSlider +// DoubleSlider // ---------------------------------------------------------------------------- -PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, - wxWindowID id, - int lowerValue, - int higherValue, - int minValue, - int maxValue, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& val, - const wxString& name) : +DoubleSlider::DoubleSlider( wxWindow *parent, + wxWindowID id, + int lowerValue, + int higherValue, + int minValue, + int maxValue, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& val, + const wxString& name) : wxControl(parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE), m_lower_value(lowerValue), m_higher_value (higherValue), m_min_value(minValue), m_max_value(maxValue), @@ -1588,36 +1366,36 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX - m_bmp_thumb_higher = /*wxBitmap*/(style == wxSL_HORIZONTAL ? /*create_scaled_bitmap*/PrusaBitmap(this, "right_half_circle.png") : /*create_scaled_bitmap*/PrusaBitmap(this, "up_half_circle.png", 16, true)); - m_bmp_thumb_lower = /*wxBitmap*/(style == wxSL_HORIZONTAL ? /*create_scaled_bitmap*/PrusaBitmap(this, "left_half_circle.png" ) : /*create_scaled_bitmap*/PrusaBitmap(this, "down_half_circle.png", 16, true)); + m_bmp_thumb_higher = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "right_half_circle.png") : ScalableBitmap(this, "up_half_circle.png", 16, true)); + m_bmp_thumb_lower = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "left_half_circle.png" ) : ScalableBitmap(this, "down_half_circle.png", 16, true)); m_thumb_size = m_bmp_thumb_lower.bmp().GetSize(); - m_bmp_add_tick_on = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_add_on.png"); - m_bmp_add_tick_off = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_add_off.png"); - m_bmp_del_tick_on = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_delete_on.png"); - m_bmp_del_tick_off = /*create_scaled_bitmap*/PrusaBitmap(this, "colorchange_delete_off.png"); + m_bmp_add_tick_on = ScalableBitmap(this, "colorchange_add_on.png"); + m_bmp_add_tick_off = ScalableBitmap(this, "colorchange_add_off.png"); + m_bmp_del_tick_on = ScalableBitmap(this, "colorchange_delete_on.png"); + m_bmp_del_tick_off = ScalableBitmap(this, "colorchange_delete_off.png"); m_tick_icon_dim = m_bmp_add_tick_on.bmp().GetSize().x; - m_bmp_one_layer_lock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_on.png"); - m_bmp_one_layer_lock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_off.png"); - m_bmp_one_layer_unlock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_on.png"); - m_bmp_one_layer_unlock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_off.png"); + m_bmp_one_layer_lock_on = ScalableBitmap(this, "one_layer_lock_on.png"); + m_bmp_one_layer_lock_off = ScalableBitmap(this, "one_layer_lock_off.png"); + m_bmp_one_layer_unlock_on = ScalableBitmap(this, "one_layer_unlock_on.png"); + m_bmp_one_layer_unlock_off = ScalableBitmap(this, "one_layer_unlock_off.png"); m_lock_icon_dim = m_bmp_one_layer_lock_on.bmp().GetSize().x; m_selection = ssUndef; // slider events - Bind(wxEVT_PAINT, &PrusaDoubleSlider::OnPaint, this); - Bind(wxEVT_LEFT_DOWN, &PrusaDoubleSlider::OnLeftDown, this); - Bind(wxEVT_MOTION, &PrusaDoubleSlider::OnMotion, this); - Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this); - Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this); - Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); - Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); - Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); - Bind(wxEVT_KEY_UP, &PrusaDoubleSlider::OnKeyUp, this); - Bind(wxEVT_RIGHT_DOWN, &PrusaDoubleSlider::OnRightDown,this); - Bind(wxEVT_RIGHT_UP, &PrusaDoubleSlider::OnRightUp, this); + Bind(wxEVT_PAINT, &DoubleSlider::OnPaint, this); + Bind(wxEVT_LEFT_DOWN, &DoubleSlider::OnLeftDown, this); + Bind(wxEVT_MOTION, &DoubleSlider::OnMotion, this); + Bind(wxEVT_LEFT_UP, &DoubleSlider::OnLeftUp, this); + Bind(wxEVT_MOUSEWHEEL, &DoubleSlider::OnWheel, this); + Bind(wxEVT_ENTER_WINDOW,&DoubleSlider::OnEnterWin, this); + Bind(wxEVT_LEAVE_WINDOW,&DoubleSlider::OnLeaveWin, this); + Bind(wxEVT_KEY_DOWN, &DoubleSlider::OnKeyDown, this); + Bind(wxEVT_KEY_UP, &DoubleSlider::OnKeyUp, this); + Bind(wxEVT_RIGHT_DOWN, &DoubleSlider::OnRightDown,this); + Bind(wxEVT_RIGHT_UP, &DoubleSlider::OnRightUp, this); // control's view variables SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); @@ -1630,32 +1408,32 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, GREY_PEN = wxPen(wxColour(164, 164, 164)); LIGHT_GREY_PEN = wxPen(wxColour(204, 204, 204)); - line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN }; - segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN }; + m_line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN }; + m_segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN }; const wxFont& font = GetFont(); m_font = is_osx ? font.Smaller().Smaller() : font.Smaller(); } -void PrusaDoubleSlider::rescale() +void DoubleSlider::msw_rescale() { const wxFont& font = Slic3r::GUI::wxGetApp().normal_font(); m_font = is_osx ? font.Smaller().Smaller() : font.Smaller(); - m_bmp_thumb_higher.rescale(); - m_bmp_thumb_lower .rescale(); + m_bmp_thumb_higher.msw_rescale(); + m_bmp_thumb_lower .msw_rescale(); m_thumb_size = m_bmp_thumb_lower.bmp().GetSize(); - m_bmp_add_tick_on .rescale(); - m_bmp_add_tick_off.rescale(); - m_bmp_del_tick_on .rescale(); - m_bmp_del_tick_off.rescale(); + m_bmp_add_tick_on .msw_rescale(); + m_bmp_add_tick_off.msw_rescale(); + m_bmp_del_tick_on .msw_rescale(); + m_bmp_del_tick_off.msw_rescale(); m_tick_icon_dim = m_bmp_add_tick_on.bmp().GetSize().x; - m_bmp_one_layer_lock_on .rescale(); - m_bmp_one_layer_lock_off .rescale(); - m_bmp_one_layer_unlock_on .rescale(); - m_bmp_one_layer_unlock_off.rescale(); + m_bmp_one_layer_lock_on .msw_rescale(); + m_bmp_one_layer_lock_off .msw_rescale(); + m_bmp_one_layer_unlock_on .msw_rescale(); + m_bmp_one_layer_unlock_off.msw_rescale(); m_lock_icon_dim = m_bmp_one_layer_lock_on.bmp().GetSize().x; SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); @@ -1664,14 +1442,14 @@ void PrusaDoubleSlider::rescale() GetParent()->Layout(); } -int PrusaDoubleSlider::GetActiveValue() const +int DoubleSlider::GetActiveValue() const { return m_selection == ssLower ? m_lower_value : m_selection == ssHigher ? m_higher_value : -1; } -wxSize PrusaDoubleSlider::get_min_size() const +wxSize DoubleSlider::get_min_size() const { const int min_side = is_horizontal() ? (is_osx ? 8 : 6) * Slic3r::GUI::wxGetApp().em_unit() : @@ -1680,7 +1458,7 @@ wxSize PrusaDoubleSlider::get_min_size() const return wxSize(min_side, min_side); } -wxSize PrusaDoubleSlider::DoGetBestSize() const +wxSize DoubleSlider::DoGetBestSize() const { const wxSize size = wxControl::DoGetBestSize(); if (size.x > 1 && size.y > 1) @@ -1688,7 +1466,7 @@ wxSize PrusaDoubleSlider::DoGetBestSize() const return get_min_size(); } -void PrusaDoubleSlider::SetLowerValue(const int lower_val) +void DoubleSlider::SetLowerValue(const int lower_val) { m_selection = ssLower; m_lower_value = lower_val; @@ -1701,7 +1479,7 @@ void PrusaDoubleSlider::SetLowerValue(const int lower_val) ProcessWindowEvent(e); } -void PrusaDoubleSlider::SetHigherValue(const int higher_val) +void DoubleSlider::SetHigherValue(const int higher_val) { m_selection = ssHigher; m_higher_value = higher_val; @@ -1714,7 +1492,7 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val) ProcessWindowEvent(e); } -void PrusaDoubleSlider::SetSelectionSpan(const int lower_val, const int higher_val) +void DoubleSlider::SetSelectionSpan(const int lower_val, const int higher_val) { m_lower_value = std::max(lower_val, m_min_value); m_higher_value = std::max(std::min(higher_val, m_max_value), m_lower_value); @@ -1729,14 +1507,14 @@ void PrusaDoubleSlider::SetSelectionSpan(const int lower_val, const int higher_v ProcessWindowEvent(e); } -void PrusaDoubleSlider::SetMaxValue(const int max_value) +void DoubleSlider::SetMaxValue(const int max_value) { m_max_value = max_value; Refresh(); Update(); } -void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos) +void DoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos) { int width; int height; @@ -1752,11 +1530,11 @@ void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const in wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1; wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1; - for (int id = 0; id < line_pens.size(); id++) + for (int id = 0; id < m_line_pens.size(); id++) { - dc.SetPen(*line_pens[id]); + dc.SetPen(*m_line_pens[id]); dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y); - dc.SetPen(*segm_pens[id]); + dc.SetPen(*m_segm_pens[id]); dc.DrawLine(segm_beg_x, segm_beg_y, segm_end_x, segm_end_y); if (is_horizontal()) line_beg_y = line_end_y = segm_beg_y = segm_end_y += 1; @@ -1765,7 +1543,7 @@ void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const in } } -double PrusaDoubleSlider::get_scroll_step() +double DoubleSlider::get_scroll_step() { const wxSize sz = get_size(); const int& slider_len = m_style == wxSL_HORIZONTAL ? sz.x : sz.y; @@ -1773,27 +1551,27 @@ double PrusaDoubleSlider::get_scroll_step() } // get position on the slider line from entered value -wxCoord PrusaDoubleSlider::get_position_from_value(const int value) +wxCoord DoubleSlider::get_position_from_value(const int value) { const double step = get_scroll_step(); const int val = is_horizontal() ? value : m_max_value - value; return wxCoord(SLIDER_MARGIN + int(val*step + 0.5)); } -wxSize PrusaDoubleSlider::get_size() +wxSize DoubleSlider::get_size() { int w, h; get_size(&w, &h); return wxSize(w, h); } -void PrusaDoubleSlider::get_size(int *w, int *h) +void DoubleSlider::get_size(int *w, int *h) { GetSize(w, h); is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim; } -double PrusaDoubleSlider::get_double_value(const SelectedSlider& selection) +double DoubleSlider::get_double_value(const SelectedSlider& selection) { if (m_values.empty() || m_lower_value<0) return 0.0; @@ -1804,7 +1582,7 @@ double PrusaDoubleSlider::get_double_value(const SelectedSlider& selection) return m_values[selection == ssLower ? m_lower_value : m_higher_value].second; } -std::vector<double> PrusaDoubleSlider::GetTicksValues() const +std::vector<double> DoubleSlider::GetTicksValues() const { std::vector<double> values; @@ -1818,7 +1596,7 @@ std::vector<double> PrusaDoubleSlider::GetTicksValues() const return values; } -void PrusaDoubleSlider::SetTicksValues(const std::vector<double>& heights) +void DoubleSlider::SetTicksValues(const std::vector<double>& heights) { if (m_values.empty()) return; @@ -1840,7 +1618,7 @@ void PrusaDoubleSlider::SetTicksValues(const std::vector<double>& heights) wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } -void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) +void DoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) { const double step = get_scroll_step(); if (is_horizontal()) { @@ -1853,7 +1631,7 @@ void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& highe } } -void PrusaDoubleSlider::draw_focus_rect() +void DoubleSlider::draw_focus_rect() { if (!m_is_focused) return; @@ -1865,7 +1643,7 @@ void PrusaDoubleSlider::draw_focus_rect() dc.DrawRectangle(1, 1, sz.x - 2, sz.y - 2); } -void PrusaDoubleSlider::render() +void DoubleSlider::render() { SetBackgroundColour(GetParent()->GetBackgroundColour()); draw_focus_rect(); @@ -1898,12 +1676,10 @@ void PrusaDoubleSlider::render() draw_one_layer_icon(dc); } -void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) +void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; -// wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off : &m_bmp_add_tick_on; -// if (m_ticks.find(tick) != m_ticks.end()) -// icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off : &m_bmp_del_tick_on; + wxBitmap& icon = m_is_action_icon_focesed ? m_bmp_add_tick_off.bmp() : m_bmp_add_tick_on.bmp(); if (m_ticks.find(tick) != m_ticks.end()) icon = m_is_action_icon_focesed ? m_bmp_del_tick_off.bmp() : m_bmp_del_tick_on.bmp(); @@ -1915,13 +1691,13 @@ void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const w else is_horizontal() ? y_draw = pt_beg.y - m_tick_icon_dim-2 : x_draw = pt_end.x + 3; - dc.DrawBitmap(/***/icon, x_draw, y_draw); + dc.DrawBitmap(icon, x_draw, y_draw); //update rect of the tick action icon m_rect_tick_action = wxRect(x_draw, y_draw, m_tick_icon_dim, m_tick_icon_dim); } -void PrusaDoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) +void DoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) { if (m_selection == selection) { //draw info line @@ -1936,7 +1712,7 @@ void PrusaDoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, c } } -wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const +wxString DoubleSlider::get_label(const SelectedSlider& selection) const { const int value = selection == ssLower ? m_lower_value : m_higher_value; @@ -1951,7 +1727,7 @@ wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const return wxString::Format("%s\n(%d)", str, m_values.empty() ? value : m_values[value].first); } -void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const +void DoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const { if ((m_is_one_layer || m_higher_value==m_lower_value) && selection != m_selection || !selection) return; @@ -1968,7 +1744,7 @@ void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const Sele dc.DrawText(label, text_pos); } -void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) +void DoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) { wxCoord x_draw, y_draw; if (selection == ssLower) { @@ -1997,7 +1773,7 @@ void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const Sele update_thumb_rect(x_draw, y_draw, selection); } -void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection) +void DoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection) { //calculate thumb position on slider line int width, height; @@ -2014,7 +1790,7 @@ void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const Sel draw_thumb_text(dc, pos, selection); } -void PrusaDoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos) +void DoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos) { //calculate thumb position on slider line int width, height; @@ -2038,7 +1814,7 @@ void PrusaDoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wx draw_thumb_text(dc, pos_l, ssLower); } -void PrusaDoubleSlider::draw_ticks(wxDC& dc) +void DoubleSlider::draw_ticks(wxDC& dc) { dc.SetPen(m_is_enabled_tick_manipulation ? DARK_GREY_PEN : LIGHT_GREY_PEN ); int height, width; @@ -2055,7 +1831,7 @@ void PrusaDoubleSlider::draw_ticks(wxDC& dc) } } -void PrusaDoubleSlider::draw_colored_band(wxDC& dc) +void DoubleSlider::draw_colored_band(wxDC& dc) { int height, width; get_size(&width, &height); @@ -2105,11 +1881,8 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc) } } -void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc) +void DoubleSlider::draw_one_layer_icon(wxDC& dc) { -// wxBitmap* icon = m_is_one_layer ? -// m_is_one_layer_icon_focesed ? &m_bmp_one_layer_lock_off : &m_bmp_one_layer_lock_on : -// m_is_one_layer_icon_focesed ? &m_bmp_one_layer_unlock_off : &m_bmp_one_layer_unlock_on; const wxBitmap& icon = m_is_one_layer ? m_is_one_layer_icon_focesed ? m_bmp_one_layer_lock_off.bmp() : m_bmp_one_layer_lock_on.bmp() : m_is_one_layer_icon_focesed ? m_bmp_one_layer_unlock_off.bmp() : m_bmp_one_layer_unlock_on.bmp(); @@ -2121,13 +1894,13 @@ void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc) is_horizontal() ? x_draw = width-2 : x_draw = 0.5*width - 0.5*m_lock_icon_dim; is_horizontal() ? y_draw = 0.5*height - 0.5*m_lock_icon_dim : y_draw = height-2; - dc.DrawBitmap(/***/icon, x_draw, y_draw); + dc.DrawBitmap(icon, x_draw, y_draw); //update rect of the lock/unlock icon m_rect_one_layer_icon = wxRect(x_draw, y_draw, m_lock_icon_dim, m_lock_icon_dim); } -void PrusaDoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) +void DoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) { const wxRect& rect = wxRect(begin_x, begin_y, m_thumb_size.x, m_thumb_size.y); if (selection == ssLower) @@ -2136,7 +1909,7 @@ void PrusaDoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& m_rect_higher_thumb = rect; } -int PrusaDoubleSlider::get_value_from_position(const wxCoord x, const wxCoord y) +int DoubleSlider::get_value_from_position(const wxCoord x, const wxCoord y) { const int height = get_size().y; const double step = get_scroll_step(); @@ -2147,13 +1920,13 @@ int PrusaDoubleSlider::get_value_from_position(const wxCoord x, const wxCoord y) return int(m_min_value + double(height - SLIDER_MARGIN - y) / step + 0.5); } -void PrusaDoubleSlider::detect_selected_slider(const wxPoint& pt) +void DoubleSlider::detect_selected_slider(const wxPoint& pt) { m_selection = is_point_in_rect(pt, m_rect_lower_thumb) ? ssLower : is_point_in_rect(pt, m_rect_higher_thumb) ? ssHigher : ssUndef; } -bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) +bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) { if (rect.GetLeft() <= pt.x && pt.x <= rect.GetRight() && rect.GetTop() <= pt.y && pt.y <= rect.GetBottom()) @@ -2161,7 +1934,7 @@ bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) return false; } -int PrusaDoubleSlider::is_point_near_tick(const wxPoint& pt) +int DoubleSlider::is_point_near_tick(const wxPoint& pt) { for (auto tick : m_ticks) { const wxCoord pos = get_position_from_value(tick); @@ -2178,7 +1951,7 @@ int PrusaDoubleSlider::is_point_near_tick(const wxPoint& pt) return -1; } -void PrusaDoubleSlider::ChangeOneLayerLock() +void DoubleSlider::ChangeOneLayerLock() { m_is_one_layer = !m_is_one_layer; m_selection == ssLower ? correct_lower_value() : correct_higher_value(); @@ -2192,7 +1965,7 @@ void PrusaDoubleSlider::ChangeOneLayerLock() ProcessWindowEvent(e); } -void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) +void DoubleSlider::OnLeftDown(wxMouseEvent& event) { this->CaptureMouse(); wxClientDC dc(this); @@ -2237,7 +2010,7 @@ void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) event.Skip(); } -void PrusaDoubleSlider::correct_lower_value() +void DoubleSlider::correct_lower_value() { if (m_lower_value < m_min_value) m_lower_value = m_min_value; @@ -2248,7 +2021,7 @@ void PrusaDoubleSlider::correct_lower_value() m_higher_value = m_lower_value; } -void PrusaDoubleSlider::correct_higher_value() +void DoubleSlider::correct_higher_value() { if (m_higher_value > m_max_value) m_higher_value = m_max_value; @@ -2259,7 +2032,7 @@ void PrusaDoubleSlider::correct_higher_value() m_lower_value = m_higher_value; } -void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) +void DoubleSlider::OnMotion(wxMouseEvent& event) { bool action = false; @@ -2293,7 +2066,7 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) } } -void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) +void DoubleSlider::OnLeftUp(wxMouseEvent& event) { if (!HasCapture()) return; @@ -2308,7 +2081,7 @@ void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) ProcessWindowEvent(e); } -void PrusaDoubleSlider::enter_window(wxMouseEvent& event, const bool enter) +void DoubleSlider::enter_window(wxMouseEvent& event, const bool enter) { m_is_focused = enter; Refresh(); @@ -2319,7 +2092,7 @@ void PrusaDoubleSlider::enter_window(wxMouseEvent& event, const bool enter) // "condition" have to be true for: // - value increase (if wxSL_VERTICAL) // - value decrease (if wxSL_HORIZONTAL) -void PrusaDoubleSlider::move_current_thumb(const bool condition) +void DoubleSlider::move_current_thumb(const bool condition) { // m_is_one_layer = wxGetKeyState(WXK_CONTROL); int delta = condition ? -1 : 1; @@ -2342,7 +2115,7 @@ void PrusaDoubleSlider::move_current_thumb(const bool condition) ProcessWindowEvent(e); } -void PrusaDoubleSlider::action_tick(const TicksAction action) +void DoubleSlider::action_tick(const TicksAction action) { if (m_selection == ssUndef) return; @@ -2366,7 +2139,7 @@ void PrusaDoubleSlider::action_tick(const TicksAction action) Update(); } -void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +void DoubleSlider::OnWheel(wxMouseEvent& event) { // Set nearest to the mouse thumb as a selected, if there is not selected thumb if (m_selection == ssUndef) @@ -2386,7 +2159,7 @@ void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) move_current_thumb(event.GetWheelRotation() > 0); } -void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) +void DoubleSlider::OnKeyDown(wxKeyEvent &event) { const int key = event.GetKeyCode(); if (key == '+' || key == WXK_NUMPAD_ADD) @@ -2412,7 +2185,7 @@ void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) } } -void PrusaDoubleSlider::OnKeyUp(wxKeyEvent &event) +void DoubleSlider::OnKeyUp(wxKeyEvent &event) { if (event.GetKeyCode() == WXK_CONTROL) m_is_one_layer = false; @@ -2421,7 +2194,7 @@ void PrusaDoubleSlider::OnKeyUp(wxKeyEvent &event) event.Skip(); } -void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) +void DoubleSlider::OnRightDown(wxMouseEvent& event) { this->CaptureMouse(); const wxClientDC dc(this); @@ -2441,7 +2214,7 @@ void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) event.Skip(); } -void PrusaDoubleSlider::OnRightUp(wxMouseEvent& event) +void DoubleSlider::OnRightUp(wxMouseEvent& event) { if (!HasCapture()) return; @@ -2455,20 +2228,19 @@ void PrusaDoubleSlider::OnRightUp(wxMouseEvent& event) // ---------------------------------------------------------------------------- -// PrusaLockButton +// LockButton // ---------------------------------------------------------------------------- -PrusaLockButton::PrusaLockButton( wxWindow *parent, - wxWindowID id, - const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/): - wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER) +LockButton::LockButton( wxWindow *parent, + wxWindowID id, + const wxPoint& pos /*= wxDefaultPosition*/, + const wxSize& size /*= wxDefaultSize*/): + wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER) { - m_bmp_lock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_on.png"); - m_bmp_lock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_lock_off.png"); - m_bmp_unlock_on = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_on.png"); - m_bmp_unlock_off = /*create_scaled_bitmap*/PrusaBitmap(this, "one_layer_unlock_off.png"); - + m_bmp_lock_on = ScalableBitmap(this, "one_layer_lock_on.png"); + m_bmp_lock_off = ScalableBitmap(this, "one_layer_lock_off.png"); + m_bmp_unlock_on = ScalableBitmap(this, "one_layer_unlock_on.png"); + m_bmp_unlock_off = ScalableBitmap(this, "one_layer_unlock_off.png"); #ifdef __WXMSW__ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -2477,12 +2249,12 @@ PrusaLockButton::PrusaLockButton( wxWindow *parent, SetBitmapDisabled(m_bmp_lock_on.bmp()); //button events - Bind(wxEVT_BUTTON, &PrusaLockButton::OnButton, this); - Bind(wxEVT_ENTER_WINDOW, &PrusaLockButton::OnEnterBtn, this); - Bind(wxEVT_LEAVE_WINDOW, &PrusaLockButton::OnLeaveBtn, this); + Bind(wxEVT_BUTTON, &LockButton::OnButton, this); + Bind(wxEVT_ENTER_WINDOW, &LockButton::OnEnterBtn, this); + Bind(wxEVT_LEAVE_WINDOW, &LockButton::OnLeaveBtn, this); } -void PrusaLockButton::OnButton(wxCommandEvent& event) +void LockButton::OnButton(wxCommandEvent& event) { m_is_pushed = !m_is_pushed; enter_button(true); @@ -2490,27 +2262,22 @@ void PrusaLockButton::OnButton(wxCommandEvent& event) event.Skip(); } -void PrusaLockButton::SetLock(bool lock) +void LockButton::SetLock(bool lock) { m_is_pushed = lock; enter_button(true); } -void PrusaLockButton::rescale() +void LockButton::msw_rescale() { - m_bmp_lock_on .rescale(); - m_bmp_lock_off .rescale(); - m_bmp_unlock_on .rescale(); - m_bmp_unlock_off.rescale(); + m_bmp_lock_on .msw_rescale(); + m_bmp_lock_off .msw_rescale(); + m_bmp_unlock_on .msw_rescale(); + m_bmp_unlock_off.msw_rescale(); } -void PrusaLockButton::enter_button(const bool enter) +void LockButton::enter_button(const bool enter) { -// wxBitmap* icon = m_is_pushed ? -// enter ? &m_bmp_lock_off : &m_bmp_lock_on : -// enter ? &m_bmp_unlock_off : &m_bmp_unlock_on; -// SetBitmap(*icon); - const wxBitmap& icon = m_is_pushed ? enter ? m_bmp_lock_off.bmp() : m_bmp_lock_on.bmp() : enter ? m_bmp_unlock_off.bmp() : m_bmp_unlock_on.bmp(); @@ -2523,36 +2290,28 @@ void PrusaLockButton::enter_button(const bool enter) // ---------------------------------------------------------------------------- -// PrusaModeButton +// ModeButton // ---------------------------------------------------------------------------- -PrusaModeButton::PrusaModeButton( wxWindow *parent, - wxWindowID id, - const std::string& icon_name/* = ""*/, - const wxString& mode/* = wxEmptyString*/, - const wxSize& size/* = wxDefaultSize*/, - const wxPoint& pos/* = wxDefaultPosition*/) : +ModeButton::ModeButton( wxWindow * parent, + wxWindowID id, + const std::string& icon_name /* = ""*/, + const wxString& mode /* = wxEmptyString*/, + const wxSize& size /* = wxDefaultSize*/, + const wxPoint& pos /* = wxDefaultPosition*/) : // wxButton(parent, id, mode, pos, wxDefaultSize/*size*/, wxBU_EXACTFIT | wxNO_BORDER), - PrusaButton(parent, id, icon_name, mode, size, pos) -// m_bmp_on(bmp_on) + ScalableButton(parent, id, icon_name, mode, size, pos) { -// #ifdef __WXMSW__ -// SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); -// #endif // __WXMSW__ -// m_bmp_off = create_scaled_bitmap(this, "mode_off_sq.png"); - m_tt_focused = wxString::Format(_(L("Switch to the %s mode")), mode); m_tt_selected = wxString::Format(_(L("Current mode is %s")), mode); -// SetBitmap(m_bmp_on); - //button events - Bind(wxEVT_BUTTON, &PrusaModeButton::OnButton, this); - Bind(wxEVT_ENTER_WINDOW, &PrusaModeButton::OnEnterBtn, this); - Bind(wxEVT_LEAVE_WINDOW, &PrusaModeButton::OnLeaveBtn, this); + Bind(wxEVT_BUTTON, &ModeButton::OnButton, this); + Bind(wxEVT_ENTER_WINDOW, &ModeButton::OnEnterBtn, this); + Bind(wxEVT_LEAVE_WINDOW, &ModeButton::OnLeaveBtn, this); } -void PrusaModeButton::OnButton(wxCommandEvent& event) +void ModeButton::OnButton(wxCommandEvent& event) { m_is_selected = true; focus_button(m_is_selected); @@ -2560,14 +2319,14 @@ void PrusaModeButton::OnButton(wxCommandEvent& event) event.Skip(); } -void PrusaModeButton::SetState(const bool state) +void ModeButton::SetState(const bool state) { m_is_selected = state; focus_button(m_is_selected); SetToolTip(state ? m_tt_selected : m_tt_focused); } -void PrusaModeButton::focus_button(const bool focus) +void ModeButton::focus_button(const bool focus) { wxFont font = GetFont(); const wxFont& new_font = focus ? font.Bold() : font.GetBaseFont(); @@ -2580,35 +2339,35 @@ void PrusaModeButton::focus_button(const bool focus) // ---------------------------------------------------------------------------- -// PrusaModeSizer +// ModeSizer // ---------------------------------------------------------------------------- -PrusaModeSizer::PrusaModeSizer(wxWindow *parent, int hgap/* = 10*/) : +ModeSizer::ModeSizer(wxWindow *parent, int hgap/* = 10*/) : wxFlexGridSizer(3, 0, hgap) { SetFlexibleDirection(wxHORIZONTAL); std::vector < std::pair < wxString, std::string >> buttons = { - {_(L("Simple")), /*create_scaled_bitmap(parent, */"mode_simple_sq.png"/*)*/}, - {_(L("Advanced")), /*create_scaled_bitmap(parent, */"mode_middle_sq.png"/*)*/}, - {_(L("Expert")), /*create_scaled_bitmap(parent, */"mode_expert_sq.png"/*)*/} + {_(L("Simple")), "mode_simple_sq.png"}, + {_(L("Advanced")), "mode_middle_sq.png"}, + {_(L("Expert")), "mode_expert_sq.png"} }; - mode_btns.reserve(3); + m_mode_btns.reserve(3); for (const auto& button : buttons) { // int x, y; // parent->GetTextExtent(button.first, &x, &y, nullptr, nullptr, &Slic3r::GUI::wxGetApp().bold_font()); // const wxSize size = wxSize(x + button.second.GetWidth() + Slic3r::GUI::wxGetApp().em_unit(), // y + Slic3r::GUI::wxGetApp().em_unit()); - mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, button.second, button.first/*, size*/)); + m_mode_btns.push_back(new ModeButton(parent, wxID_ANY, button.second, button.first/*, size*/)); } - for (auto btn : mode_btns) + for (auto btn : m_mode_btns) { btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event) { event.Skip(); int mode_id = 0; - for (auto cur_btn : mode_btns) { + for (auto cur_btn : m_mode_btns) { if (cur_btn == btn) break; else @@ -2622,24 +2381,24 @@ PrusaModeSizer::PrusaModeSizer(wxWindow *parent, int hgap/* = 10*/) : } -void PrusaModeSizer::SetMode(const int mode) +void ModeSizer::SetMode(const int mode) { - for (int m = 0; m < mode_btns.size(); m++) - mode_btns[m]->SetState(m == mode); + for (int m = 0; m < m_mode_btns.size(); m++) + m_mode_btns[m]->SetState(m == mode); } -void PrusaModeSizer::rescale() +void ModeSizer::msw_rescale() { - for (int m = 0; m < mode_btns.size(); m++) - mode_btns[m]->rescale(); + for (int m = 0; m < m_mode_btns.size(); m++) + m_mode_btns[m]->msw_rescale(); } // ---------------------------------------------------------------------------- -// PrusaMenu +// MenuWithSeparators // ---------------------------------------------------------------------------- -void PrusaMenu::DestroySeparators() +void MenuWithSeparators::DestroySeparators() { if (m_separator_frst) { Destroy(m_separator_frst); @@ -2652,22 +2411,31 @@ void PrusaMenu::DestroySeparators() } } +void MenuWithSeparators::SetFirstSeparator() +{ + m_separator_frst = this->AppendSeparator(); +} + +void MenuWithSeparators::SetSecondSeparator() +{ + m_separator_scnd = this->AppendSeparator(); +} // ---------------------------------------------------------------------------- // PrusaBitmap // ---------------------------------------------------------------------------- -PrusaBitmap::PrusaBitmap(wxWindow *parent, - const std::string& icon_name/* = ""*/, - const int px_cnt/* = 16*/, - const bool is_horizontal/* = false*/): - m_parent(parent), m_icon_name(icon_name), - m_px_cnt(px_cnt), m_is_horizontal(is_horizontal) +ScalableBitmap::ScalableBitmap( wxWindow *parent, + const std::string& icon_name/* = ""*/, + const int px_cnt/* = 16*/, + const bool is_horizontal/* = false*/): + m_parent(parent), m_icon_name(icon_name), + m_px_cnt(px_cnt), m_is_horizontal(is_horizontal) { m_bmp = create_scaled_bitmap(parent, icon_name, px_cnt, is_horizontal); } -void PrusaBitmap::rescale() +void ScalableBitmap::msw_rescale() { m_bmp = create_scaled_bitmap(m_parent, m_icon_name, m_px_cnt, m_is_horizontal); } @@ -2676,13 +2444,13 @@ void PrusaBitmap::rescale() // PrusaButton // ---------------------------------------------------------------------------- -PrusaButton::PrusaButton(wxWindow *parent, - wxWindowID id, - const std::string& icon_name/*= ""*/, - const wxString& label /* = wxEmptyString*/, - const wxSize& size /* = wxDefaultSize*/, - const wxPoint& pos /* = wxDefaultPosition*/, - long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : +ScalableButton::ScalableButton( wxWindow * parent, + wxWindowID id, + const std::string& icon_name /*= ""*/, + const wxString& label /* = wxEmptyString*/, + const wxSize& size /* = wxDefaultSize*/, + const wxPoint& pos /* = wxDefaultPosition*/, + long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : m_current_icon_name(icon_name), m_parent(parent) { @@ -2696,11 +2464,11 @@ PrusaButton::PrusaButton(wxWindow *parent, } -PrusaButton::PrusaButton(wxWindow *parent, - wxWindowID id, - const PrusaBitmap& bitmap, - const wxString& label /*= wxEmptyString*/, - long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : +ScalableButton::ScalableButton( wxWindow * parent, + wxWindowID id, + const ScalableBitmap& bitmap, + const wxString& label /*= wxEmptyString*/, + long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : m_current_icon_name(bitmap.name()), m_parent(parent) { @@ -2713,13 +2481,13 @@ PrusaButton::PrusaButton(wxWindow *parent, SetBitmap(bitmap.bmp()); } -void PrusaButton::SetBitmap_(const PrusaBitmap& bmp) +void ScalableButton::SetBitmap_(const ScalableBitmap& bmp) { SetBitmap(bmp.bmp()); m_current_icon_name = bmp.name(); } -void PrusaButton::rescale() +void ScalableButton::msw_rescale() { const wxBitmap bmp = create_scaled_bitmap(m_parent, m_current_icon_name); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 574712849..7d63438c0 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -96,91 +96,20 @@ public: }; - -// *** PrusaCollapsiblePane *** // ---------------------------------------------------------------------------- -class PrusaCollapsiblePane : public wxCollapsiblePane +// DataViewBitmapText: helper class used by PrusaBitmapTextRenderer +// ---------------------------------------------------------------------------- + +class DataViewBitmapText : public wxObject { public: - PrusaCollapsiblePane() {} - PrusaCollapsiblePane(wxWindow *parent, - wxWindowID winid, - const wxString& label, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxCP_DEFAULT_STYLE, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxCollapsiblePaneNameStr) - { - Create(parent, winid, label, pos, size, style, val, name); - } - ~PrusaCollapsiblePane() {} - - void OnStateChange(const wxSize& sz); //override/hide of OnStateChange from wxCollapsiblePane - virtual bool Show(bool show = true) override { - wxCollapsiblePane::Show(show); - OnStateChange(GetBestSize()); - return true; - } -}; - - -// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__ -// ---------------------------------------------------------------------------- -#ifdef __WXMSW__ -class PrusaCollapsiblePaneMSW : public PrusaCollapsiblePane//wxCollapsiblePane -{ - wxButton* m_pDisclosureTriangleButton = nullptr; - wxBitmap m_bmp_close; - wxBitmap m_bmp_open; - wxString m_strLabel; -public: - PrusaCollapsiblePaneMSW() {} - PrusaCollapsiblePaneMSW( wxWindow *parent, - wxWindowID winid, - const wxString& label, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxCP_DEFAULT_STYLE, - const wxValidator& val = wxDefaultValidator, - const wxString& name = wxCollapsiblePaneNameStr) - { - Create(parent, winid, label, pos, size, style, val, name); - } - - ~PrusaCollapsiblePaneMSW() {} - - bool Create(wxWindow *parent, - wxWindowID id, - const wxString& label, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& val, - const wxString& name); - - void UpdateBtnBmp(); - void SetLabel(const wxString &label) override; - bool Layout() override; - void Collapse(bool collapse) override; -}; -#endif //__WXMSW__ - -// ***************************************************************************** - -// ---------------------------------------------------------------------------- -// PrusaDataViewBitmapText: helper class used by PrusaBitmapTextRenderer -// ---------------------------------------------------------------------------- - -class PrusaDataViewBitmapText : public wxObject -{ -public: - PrusaDataViewBitmapText(const wxString &text = wxEmptyString, - const wxBitmap& bmp = wxNullBitmap) : - m_text(text), m_bmp(bmp) + DataViewBitmapText( const wxString &text = wxEmptyString, + const wxBitmap& bmp = wxNullBitmap) : + m_text(text), + m_bmp(bmp) { } - PrusaDataViewBitmapText(const PrusaDataViewBitmapText &other) + DataViewBitmapText(const DataViewBitmapText &other) : wxObject(), m_text(other.m_text), m_bmp(other.m_bmp) @@ -188,18 +117,18 @@ public: void SetText(const wxString &text) { m_text = text; } wxString GetText() const { return m_text; } - void SetBitmap(const wxBitmap &bmp) { m_bmp = bmp; } + void SetBitmap(const wxBitmap &bmp) { m_bmp = bmp; } const wxBitmap &GetBitmap() const { return m_bmp; } - bool IsSameAs(const PrusaDataViewBitmapText& other) const { + bool IsSameAs(const DataViewBitmapText& other) const { return m_text == other.m_text && m_bmp.IsSameAs(other.m_bmp); } - bool operator==(const PrusaDataViewBitmapText& other) const { + bool operator==(const DataViewBitmapText& other) const { return IsSameAs(other); } - bool operator!=(const PrusaDataViewBitmapText& other) const { + bool operator!=(const DataViewBitmapText& other) const { return !IsSameAs(other); } @@ -207,13 +136,13 @@ private: wxString m_text; wxBitmap m_bmp; - wxDECLARE_DYNAMIC_CLASS(PrusaDataViewBitmapText); + wxDECLARE_DYNAMIC_CLASS(DataViewBitmapText); }; -DECLARE_VARIANT_OBJECT(PrusaDataViewBitmapText) +DECLARE_VARIANT_OBJECT(DataViewBitmapText) // ---------------------------------------------------------------------------- -// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel +// ObjectDataViewModelNode: a node inside PrusaObjectDataViewModel // ---------------------------------------------------------------------------- enum ItemType { @@ -225,49 +154,58 @@ enum ItemType { itSettings = 16 }; -class PrusaObjectDataViewModelNode; -WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); +class ObjectDataViewModelNode; +WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); -class PrusaObjectDataViewModelNode +class ObjectDataViewModelNode { - PrusaObjectDataViewModelNode* m_parent; + ObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; wxBitmap m_empty_bmp; size_t m_volumes_cnt = 0; std::vector< std::string > m_opt_categories; + wxString m_name; + wxBitmap& m_bmp = m_empty_bmp; + ItemType m_type; + int m_idx = -1; + bool m_container = false; + wxString m_extruder = "default"; + wxBitmap m_action_icon; + std::string m_action_icon_name = ""; Slic3r::ModelVolumeType m_volume_type; public: - PrusaObjectDataViewModelNode(const wxString &name, - const wxString& extruder) { - m_parent = NULL; - m_name = name; - m_type = itObject; + ObjectDataViewModelNode(const wxString &name, + const wxString& extruder): + m_parent(NULL), + m_name(name), + m_type(itObject), + m_extruder(extruder) + { #ifdef __WXGTK__ // it's necessary on GTK because of control have to know if this item will be container // in another case you couldn't to add subitem for this item // it will be produce "segmentation fault" m_container = true; #endif //__WXGTK__ - m_extruder = extruder; -// set_object_action_icon(); set_action_icon(); } - PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, - const wxString& sub_obj_name, - const wxBitmap& bmp, - const wxString& extruder, - const int idx = -1 ) { - m_parent = parent; - m_name = sub_obj_name; - m_bmp = bmp; - m_type = itVolume; - m_idx = idx; - m_extruder = extruder; + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const wxString& sub_obj_name, + const wxBitmap& bmp, + const wxString& extruder, + const int idx = -1 ) : + m_parent (parent), + m_name (sub_obj_name), + m_type (itVolume), + m_idx (idx), + m_extruder (extruder) + { + m_bmp = bmp; #ifdef __WXGTK__ // it's necessary on GTK because of control have to know if this item will be container // in another case you couldn't to add subitem for this item @@ -275,14 +213,14 @@ public: m_container = true; #endif //__WXGTK__ -// set_part_action_icon(); set_action_icon(); } - PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const ItemType type) : - m_parent(parent), - m_type(type), - m_extruder(wxEmptyString) + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const ItemType type) : + m_parent(parent), + m_type(type), + m_extruder(wxEmptyString) { if (type == itSettings) { m_name = "Settings to modified"; @@ -296,36 +234,28 @@ public: else if (type == itInstance) { m_idx = parent->GetChildCount(); m_name = wxString::Format("Instance_%d", m_idx+1); -// set_part_action_icon(); + set_action_icon(); } } - ~PrusaObjectDataViewModelNode() + ~ObjectDataViewModelNode() { // free all our children nodes size_t count = m_children.GetCount(); for (size_t i = 0; i < count; i++) { - PrusaObjectDataViewModelNode *child = m_children[i]; + ObjectDataViewModelNode *child = m_children[i]; delete child; } } - - wxString m_name; - wxBitmap& m_bmp = m_empty_bmp; - ItemType m_type; - int m_idx = -1; - bool m_container = false; - wxString m_extruder = "default"; - wxBitmap m_action_icon; bool IsContainer() const { return m_container; } - PrusaObjectDataViewModelNode* GetParent() + ObjectDataViewModelNode* GetParent() { return m_parent; } @@ -333,17 +263,17 @@ public: { return m_children; } - PrusaObjectDataViewModelNode* GetNthChild(unsigned int n) + ObjectDataViewModelNode* GetNthChild(unsigned int n) { return m_children.Item(n); } - void Insert(PrusaObjectDataViewModelNode* child, unsigned int n) + void Insert(ObjectDataViewModelNode* child, unsigned int n) { if (!m_container) m_container = true; m_children.Insert(child, n); } - void Append(PrusaObjectDataViewModelNode* child) + void Append(ObjectDataViewModelNode* child) { if (!m_container) m_container = true; @@ -373,7 +303,7 @@ public: switch (col) { case 0:{ - PrusaDataViewBitmapText data; + DataViewBitmapText data; data << variant; m_bmp = data.GetBitmap(); m_name = data.GetText(); @@ -411,7 +341,7 @@ public: } // use this function only for childrens - void AssignAllVal(PrusaObjectDataViewModelNode& from_node) + void AssignAllVal(ObjectDataViewModelNode& from_node) { // ! Don't overwrite other values because of equality of this values for all children -- m_name = from_node.m_name; @@ -427,8 +357,8 @@ public: scnd_id < 0 || scnd_id >= GetChildCount()) return false; - PrusaObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); - PrusaObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); + ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); + ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); new_scnd.m_idx = m_children.Item(scnd_id)->m_idx; new_frst.m_idx = m_children.Item(frst_id)->m_idx; @@ -439,42 +369,40 @@ public: } // Set action icons for node -// void set_object_action_icon(); -// void set_part_action_icon(); void set_action_icon(); void update_settings_digest_bitmaps(); bool update_settings_digest(const std::vector<std::string>& categories); int volume_type() const { return int(m_volume_type); } - void rescale(); + void msw_rescale(); private: - friend class PrusaObjectDataViewModel; + friend class ObjectDataViewModel; }; // ---------------------------------------------------------------------------- -// PrusaObjectDataViewModel +// ObjectDataViewModel // ---------------------------------------------------------------------------- // custom message the model sends to associated control to notify a last volume deleted from the object: wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); -class PrusaObjectDataViewModel :public wxDataViewModel +class ObjectDataViewModel :public wxDataViewModel { - std::vector<PrusaObjectDataViewModelNode*> m_objects; + std::vector<ObjectDataViewModelNode*> m_objects; std::vector<wxBitmap*> m_volume_bmps; wxDataViewCtrl* m_ctrl{ nullptr }; public: - PrusaObjectDataViewModel(); - ~PrusaObjectDataViewModel(); + ObjectDataViewModel(); + ~ObjectDataViewModel(); wxDataViewItem Add(const wxString &name, const int extruder); - wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item, - const wxString &name, - const Slic3r::ModelVolumeType volume_type, - const int extruder = 0, - const bool create_frst_child = true); + wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item, + const wxString &name, + const Slic3r::ModelVolumeType volume_type, + const int extruder = 0, + const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem Delete(const wxDataViewItem &item); @@ -486,58 +414,62 @@ public: wxDataViewItem GetItemById(int obj_idx); wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); - int GetIdByItem(const wxDataViewItem& item) const; - int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; - int GetObjectIdByItem(const wxDataViewItem& item) const; - int GetVolumeIdByItem(const wxDataViewItem& item) const; - int GetInstanceIdByItem(const wxDataViewItem& item) const; + int GetIdByItem(const wxDataViewItem& item) const; + int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; + int GetObjectIdByItem(const wxDataViewItem& item) const; + int GetVolumeIdByItem(const wxDataViewItem& item) const; + int GetInstanceIdByItem(const wxDataViewItem& item) const; void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx); - int GetRowByItem(const wxDataViewItem& item) const; + int GetRowByItem(const wxDataViewItem& item) const; bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog - wxString GetName(const wxDataViewItem &item) const; - wxBitmap& GetBitmap(const wxDataViewItem &item) const; + wxString GetName(const wxDataViewItem &item) const; + wxBitmap& GetBitmap(const wxDataViewItem &item) const; // helper methods to change the model - virtual unsigned int GetColumnCount() const override { return 3;} - virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } + virtual unsigned int GetColumnCount() const override { return 3;} + virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } - virtual void GetValue(wxVariant &variant, - const wxDataViewItem &item, unsigned int col) const override; - virtual bool SetValue(const wxVariant &variant, - const wxDataViewItem &item, unsigned int col) override; - bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col); + virtual void GetValue( wxVariant &variant, + const wxDataViewItem &item, + unsigned int col) const override; + virtual bool SetValue( const wxVariant &variant, + const wxDataViewItem &item, + unsigned int col) override; + bool SetValue( const wxVariant &variant, + const int item_idx, + unsigned int col); -// wxDataViewItem MoveChildUp(const wxDataViewItem &item); -// wxDataViewItem MoveChildDown(const wxDataViewItem &item); // For parent move child from cur_volume_id place to new_volume_id // Remaining items will moved up/down accordingly - wxDataViewItem ReorganizeChildren(int cur_volume_id, - int new_volume_id, - const wxDataViewItem &parent); + wxDataViewItem ReorganizeChildren( const int cur_volume_id, + const int new_volume_id, + const wxDataViewItem &parent); - virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; + virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; - virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; + virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; // get object item - wxDataViewItem GetTopParent(const wxDataViewItem &item) const; - virtual bool IsContainer(const wxDataViewItem &item) const override; - virtual unsigned int GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const override; + wxDataViewItem GetTopParent(const wxDataViewItem &item) const; + virtual bool IsContainer(const wxDataViewItem &item) const override; + virtual unsigned int GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const override; void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; // Is the container just a header or an item with all columns // In our case it is an item with all columns - virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } + virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } - ItemType GetItemType(const wxDataViewItem &item) const ; - wxDataViewItem GetItemByType(const wxDataViewItem &parent_item, ItemType type) const; - wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; - wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; + ItemType GetItemType(const wxDataViewItem &item) const ; + wxDataViewItem GetItemByType( const wxDataViewItem &parent_item, + ItemType type) const; + wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; + wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const; - void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories); + void UpdateSettingsDigest( const wxDataViewItem &item, + const std::vector<std::string>& categories); void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; } void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); @@ -548,16 +480,16 @@ public: }; // ---------------------------------------------------------------------------- -// PrusaBitmapTextRenderer +// BitmapTextRenderer // ---------------------------------------------------------------------------- #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING -class PrusaBitmapTextRenderer : public wxDataViewRenderer +class BitmapTextRenderer : public wxDataViewRenderer #else -class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer +class BitmapTextRenderer : public wxDataViewCustomRenderer #endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING { public: - PrusaBitmapTextRenderer(wxDataViewCellMode mode = + BitmapTextRenderer(wxDataViewCellMode mode = #ifdef __WXOSX__ wxDATAVIEW_CELL_INERT #else @@ -568,7 +500,7 @@ public: #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING ); #else - ) : wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {} + ) : wxDataViewCustomRenderer(wxT("DataViewBitmapText"), mode, align) {} #endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING bool SetValue(const wxVariant &value); @@ -596,7 +528,7 @@ public: bool WasCanceled() const { return m_was_unusable_symbol; } private: - PrusaDataViewBitmapText m_value; + DataViewBitmapText m_value; bool m_was_unusable_symbol {false}; }; @@ -694,21 +626,21 @@ private: // ---------------------------------------------------------------------------- -// PrusaBitmap +// ScalableBitmap // ---------------------------------------------------------------------------- -class PrusaBitmap +class ScalableBitmap { public: - PrusaBitmap() {}; - PrusaBitmap(wxWindow *parent, - const std::string& icon_name = "", - const int px_cnt = 16, - const bool is_horizontal = false); + ScalableBitmap() {}; + ScalableBitmap( wxWindow *parent, + const std::string& icon_name = "", + const int px_cnt = 16, + const bool is_horizontal = false); - ~PrusaBitmap() {} + ~ScalableBitmap() {} - void rescale(); + void msw_rescale(); const wxBitmap& bmp() const { return m_bmp; } wxBitmap& bmp() { return m_bmp; } @@ -724,7 +656,7 @@ private: // ---------------------------------------------------------------------------- -// PrusaDoubleSlider +// DoubleSlider // ---------------------------------------------------------------------------- // custom message the slider sends to its parent to notify a tick-change: @@ -741,10 +673,10 @@ enum TicksAction{ taDel }; -class PrusaDoubleSlider : public wxControl +class DoubleSlider : public wxControl { public: - PrusaDoubleSlider( + DoubleSlider( wxWindow *parent, wxWindowID id, int lowerValue, @@ -756,9 +688,9 @@ public: long style = wxSL_VERTICAL, const wxValidator& val = wxDefaultValidator, const wxString& name = wxEmptyString); - ~PrusaDoubleSlider() {} + ~DoubleSlider() {} - void rescale(); + void msw_rescale(); int GetMinValue() const { return m_min_value; } int GetMaxValue() const { return m_max_value; } @@ -852,16 +784,16 @@ private: int m_max_value; int m_lower_value; int m_higher_value; - /*wxBitmap*/PrusaBitmap m_bmp_thumb_higher; - /*wxBitmap*/PrusaBitmap m_bmp_thumb_lower; - /*wxBitmap*/PrusaBitmap m_bmp_add_tick_on; - /*wxBitmap*/PrusaBitmap m_bmp_add_tick_off; - /*wxBitmap*/PrusaBitmap m_bmp_del_tick_on; - /*wxBitmap*/PrusaBitmap m_bmp_del_tick_off; - /*wxBitmap*/PrusaBitmap m_bmp_one_layer_lock_on; - /*wxBitmap*/PrusaBitmap m_bmp_one_layer_lock_off; - /*wxBitmap*/PrusaBitmap m_bmp_one_layer_unlock_on; - /*wxBitmap*/PrusaBitmap m_bmp_one_layer_unlock_off; + ScalableBitmap m_bmp_thumb_higher; + ScalableBitmap m_bmp_thumb_lower; + ScalableBitmap m_bmp_add_tick_on; + ScalableBitmap m_bmp_add_tick_off; + ScalableBitmap m_bmp_del_tick_on; + ScalableBitmap m_bmp_del_tick_off; + ScalableBitmap m_bmp_one_layer_lock_on; + ScalableBitmap m_bmp_one_layer_lock_off; + ScalableBitmap m_bmp_one_layer_unlock_on; + ScalableBitmap m_bmp_one_layer_unlock_off; SelectedSlider m_selection; bool m_is_left_down = false; bool m_is_right_down = false; @@ -892,26 +824,26 @@ private: wxPen GREY_PEN; wxPen LIGHT_GREY_PEN; - std::vector<wxPen*> line_pens; - std::vector<wxPen*> segm_pens; + std::vector<wxPen*> m_line_pens; + std::vector<wxPen*> m_segm_pens; std::set<int> m_ticks; std::vector<std::pair<int,double>> m_values; }; // ---------------------------------------------------------------------------- -// PrusaLockButton +// LockButton // ---------------------------------------------------------------------------- -class PrusaLockButton : public wxButton +class LockButton : public wxButton { public: - PrusaLockButton( + LockButton( wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); - ~PrusaLockButton() {} + ~LockButton() {} void OnButton(wxCommandEvent& event); void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); } @@ -920,7 +852,7 @@ public: bool IsLocked() const { return m_is_pushed; } void SetLock(bool lock); - void rescale(); + void msw_rescale(); protected: void enter_button(const bool enter); @@ -928,42 +860,42 @@ protected: private: bool m_is_pushed = false; - /*wxBitmap*/PrusaBitmap m_bmp_lock_on; - /*wxBitmap*/PrusaBitmap m_bmp_lock_off; - /*wxBitmap*/PrusaBitmap m_bmp_unlock_on; - /*wxBitmap*/PrusaBitmap m_bmp_unlock_off; + ScalableBitmap m_bmp_lock_on; + ScalableBitmap m_bmp_lock_off; + ScalableBitmap m_bmp_unlock_on; + ScalableBitmap m_bmp_unlock_off; }; // ---------------------------------------------------------------------------- -// PrusaButton +// ScalableButton // ---------------------------------------------------------------------------- -class PrusaButton : public wxButton +class ScalableButton : public wxButton { public: - PrusaButton(){} - PrusaButton( - wxWindow *parent, - wxWindowID id, - const std::string& icon_name = "", - const wxString& label = wxEmptyString, - const wxSize& size = wxDefaultSize, - const wxPoint& pos = wxDefaultPosition, - long style = wxBU_EXACTFIT | wxNO_BORDER); + ScalableButton(){} + ScalableButton( + wxWindow * parent, + wxWindowID id, + const std::string& icon_name = "", + const wxString& label = wxEmptyString, + const wxSize& size = wxDefaultSize, + const wxPoint& pos = wxDefaultPosition, + long style = wxBU_EXACTFIT | wxNO_BORDER); - PrusaButton( - wxWindow *parent, - wxWindowID id, - const PrusaBitmap& bitmap, - const wxString& label = wxEmptyString, - long style = wxBU_EXACTFIT | wxNO_BORDER); + ScalableButton( + wxWindow * parent, + wxWindowID id, + const ScalableBitmap& bitmap, + const wxString& label = wxEmptyString, + long style = wxBU_EXACTFIT | wxNO_BORDER); - ~PrusaButton() {} + ~ScalableButton() {} - void SetBitmap_(const PrusaBitmap& bmp); + void SetBitmap_(const ScalableBitmap& bmp); - void rescale(); + void msw_rescale(); private: wxWindow* m_parent; @@ -972,20 +904,20 @@ private: // ---------------------------------------------------------------------------- -// PrusaModeButton +// ModeButton // ---------------------------------------------------------------------------- -class PrusaModeButton : public PrusaButton/*wxButton*/ +class ModeButton : public ScalableButton { public: - PrusaModeButton( - wxWindow *parent, - wxWindowID id, - const std::string& icon_name = "", - const wxString& mode = wxEmptyString, - const wxSize& size = wxDefaultSize, - const wxPoint& pos = wxDefaultPosition); - ~PrusaModeButton() {} + ModeButton( + wxWindow* parent, + wxWindowID id, + const std::string& icon_name = "", + const wxString& mode = wxEmptyString, + const wxSize& size = wxDefaultSize, + const wxPoint& pos = wxDefaultPosition); + ~ModeButton() {} void OnButton(wxCommandEvent& event); void OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); } @@ -999,8 +931,6 @@ protected: private: bool m_is_selected = false; -// wxBitmap m_bmp_on; -// wxBitmap m_bmp_off; wxString m_tt_selected; wxString m_tt_focused; }; @@ -1008,42 +938,45 @@ private: // ---------------------------------------------------------------------------- -// PrusaModeSizer +// ModeSizer // ---------------------------------------------------------------------------- -class PrusaModeSizer : public wxFlexGridSizer +class ModeSizer : public wxFlexGridSizer { public: - PrusaModeSizer( wxWindow *parent, int hgap = 10); - ~PrusaModeSizer() {} + ModeSizer( wxWindow *parent, int hgap = 10); + ~ModeSizer() {} void SetMode(const /*ConfigOptionMode*/int mode); - void rescale(); + void msw_rescale(); private: - std::vector<PrusaModeButton*> mode_btns; + std::vector<ModeButton*> m_mode_btns; }; // ---------------------------------------------------------------------------- -// PrusaMenu +// MenuWithSeparators // ---------------------------------------------------------------------------- -class PrusaMenu : public wxMenu +class MenuWithSeparators : public wxMenu { public: - PrusaMenu(const wxString& title, long style = 0) + MenuWithSeparators(const wxString& title, long style = 0) : wxMenu(title, style) {} - PrusaMenu(long style = 0) + MenuWithSeparators(long style = 0) : wxMenu(style) {} - ~PrusaMenu() {} + ~MenuWithSeparators() {} void DestroySeparators(); + void SetFirstSeparator(); + void SetSecondSeparator(); +private: wxMenuItem* m_separator_frst { nullptr }; // use like separator before settings item wxMenuItem* m_separator_scnd { nullptr }; // use like separator between settings items }; From ea7cfce286fcc8b84c08b3ffac2922f401190033 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 25 Apr 2019 09:16:18 +0200 Subject: [PATCH 25/28] Restored French localization files (Fix of #2158) --- resources/localization/Slic3rPE.pot | 14 +- resources/localization/fr_FR/Slic3rPE.mo | Bin 176879 -> 125865 bytes resources/localization/fr_FR/Slic3rPE_fr.po | 5738 +++++++++---------- 3 files changed, 2874 insertions(+), 2878 deletions(-) diff --git a/resources/localization/Slic3rPE.pot b/resources/localization/Slic3rPE.pot index c65ea69d4..89a8f7bb2 100644 --- a/resources/localization/Slic3rPE.pot +++ b/resources/localization/Slic3rPE.pot @@ -2016,7 +2016,12 @@ msgstr "" msgid "Iso View" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:450 src/libslic3r/PrintConfig.cpp:2041 +#: src/slic3r/GUI/MainFrame.cpp:450 +msgid "Top" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2041 +msgctxt "Layers" msgid "Top" msgstr "" @@ -2024,7 +2029,12 @@ msgstr "" msgid "Top View" msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:451 src/libslic3r/PrintConfig.cpp:148 +#: src/slic3r/GUI/MainFrame.cpp:451 +msgid "Bottom" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:148 +msgctxt "Layers" msgid "Bottom" msgstr "" diff --git a/resources/localization/fr_FR/Slic3rPE.mo b/resources/localization/fr_FR/Slic3rPE.mo index ba1966d28c7f4bbe7f875c1d3e51eb47c4cbcd7c..0a2409281d680db867f53af3d019c310597b2fa5 100644 GIT binary patch literal 125865 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уt#_waR9KZx)V&|0Au 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 literal 176879 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 diff --git a/resources/localization/fr_FR/Slic3rPE_fr.po b/resources/localization/fr_FR/Slic3rPE_fr.po index 9e5335586..af9255cf5 100644 --- a/resources/localization/fr_FR/Slic3rPE_fr.po +++ b/resources/localization/fr_FR/Slic3rPE_fr.po @@ -1,25 +1,22 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-04-09 14:34+0200\n" -"PO-Revision-Date: 2019-04-09 15:04+0200\n" -"Language: en\n" +"POT-Creation-Date: 2019-04-18 10:07+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Oleksandra Iushchenko <yusanka@gmail.com>\n" +"Language-Team: \n" +"Language: fr_FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Oleksandra Iushchenko <yusanka@gmail.com>\n" -"Language-Team: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 2.0.8\n" #: src/slic3r/GUI/AboutDialog.cpp:35 -msgid "About Slic3r" -msgstr "About Slic3r" +#, c-format +msgid "About %s" +msgstr "A propos de %s" #: src/slic3r/GUI/AboutDialog.cpp:64 src/slic3r/GUI/MainFrame.cpp:52 msgid "Version" @@ -27,40 +24,40 @@ msgstr "Version" #: src/slic3r/GUI/BedShapeDialog.cpp:43 msgid "Shape" -msgstr "Shape" +msgstr "Forme" #: src/slic3r/GUI/BedShapeDialog.cpp:51 msgid "Rectangular" -msgstr "Rectangular" +msgstr "Rectangle" #: src/slic3r/GUI/BedShapeDialog.cpp:55 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:118 src/slic3r/GUI/Plater.cpp:136 -#: src/slic3r/GUI/Tab.cpp:2185 +#: src/slic3r/GUI/Tab.cpp:2186 msgid "Size" -msgstr "Size" +msgstr "Taille" #: src/slic3r/GUI/BedShapeDialog.cpp:56 msgid "Size in X and Y of the rectangular plate." -msgstr "Size in X and Y of the rectangular plate." +msgstr "Taille en X et Y du plateau rectangulaire." #: src/slic3r/GUI/BedShapeDialog.cpp:62 msgid "Origin" -msgstr "Origin" +msgstr "Origine" #: src/slic3r/GUI/BedShapeDialog.cpp:63 msgid "" "Distance of the 0,0 G-code coordinate from the front left corner of the " "rectangle." msgstr "" -"Distance of the 0,0 G-code coordinate from the front left corner of the " +"Distance des coordonnées 0,0 du G-code depuis le coin avant gauche du " "rectangle." #: src/slic3r/GUI/BedShapeDialog.cpp:67 msgid "Circular" -msgstr "Circular" +msgstr "Circulaire" #: src/slic3r/GUI/BedShapeDialog.cpp:70 src/slic3r/GUI/ConfigWizard.cpp:111 -#: src/slic3r/GUI/ConfigWizard.cpp:544 src/slic3r/GUI/ConfigWizard.cpp:558 +#: src/slic3r/GUI/ConfigWizard.cpp:547 src/slic3r/GUI/ConfigWizard.cpp:561 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:115 #: src/slic3r/GUI/RammingChart.cpp:81 src/slic3r/GUI/WipeTowerDialog.cpp:84 #: src/libslic3r/PrintConfig.cpp:59 src/libslic3r/PrintConfig.cpp:66 @@ -80,151 +77,154 @@ msgstr "Circular" #: src/libslic3r/PrintConfig.cpp:1931 src/libslic3r/PrintConfig.cpp:2123 #: src/libslic3r/PrintConfig.cpp:2130 src/libslic3r/PrintConfig.cpp:2137 #: src/libslic3r/PrintConfig.cpp:2167 src/libslic3r/PrintConfig.cpp:2177 -#: src/libslic3r/PrintConfig.cpp:2187 src/libslic3r/PrintConfig.cpp:2293 -#: src/libslic3r/PrintConfig.cpp:2368 src/libslic3r/PrintConfig.cpp:2377 -#: src/libslic3r/PrintConfig.cpp:2386 src/libslic3r/PrintConfig.cpp:2396 -#: src/libslic3r/PrintConfig.cpp:2440 src/libslic3r/PrintConfig.cpp:2450 -#: src/libslic3r/PrintConfig.cpp:2469 src/libslic3r/PrintConfig.cpp:2479 -#: src/libslic3r/PrintConfig.cpp:2488 src/libslic3r/PrintConfig.cpp:2506 -#: src/libslic3r/PrintConfig.cpp:2521 src/libslic3r/PrintConfig.cpp:2532 -#: src/libslic3r/PrintConfig.cpp:2545 src/libslic3r/PrintConfig.cpp:2555 +#: src/libslic3r/PrintConfig.cpp:2187 src/libslic3r/PrintConfig.cpp:2295 +#: src/libslic3r/PrintConfig.cpp:2370 src/libslic3r/PrintConfig.cpp:2379 +#: src/libslic3r/PrintConfig.cpp:2388 src/libslic3r/PrintConfig.cpp:2398 +#: src/libslic3r/PrintConfig.cpp:2442 src/libslic3r/PrintConfig.cpp:2452 +#: src/libslic3r/PrintConfig.cpp:2471 src/libslic3r/PrintConfig.cpp:2481 +#: src/libslic3r/PrintConfig.cpp:2490 src/libslic3r/PrintConfig.cpp:2508 +#: src/libslic3r/PrintConfig.cpp:2523 src/libslic3r/PrintConfig.cpp:2537 +#: src/libslic3r/PrintConfig.cpp:2550 src/libslic3r/PrintConfig.cpp:2560 msgid "mm" msgstr "mm" #: src/slic3r/GUI/BedShapeDialog.cpp:71 src/libslic3r/PrintConfig.cpp:676 msgid "Diameter" -msgstr "Diameter" +msgstr "Diamètre" #: src/slic3r/GUI/BedShapeDialog.cpp:72 msgid "" "Diameter of the print bed. It is assumed that origin (0,0) is located in the " "center." msgstr "" -"Diameter of the print bed. It is assumed that origin (0,0) is located in the " -"center." +"Diamètre du plateau d'impression. Il est supposé que l'origine (0,0) est " +"située au centre." #: src/slic3r/GUI/BedShapeDialog.cpp:76 src/slic3r/GUI/GUI_Preview.cpp:239 #: src/libslic3r/GCode/PreviewData.cpp:175 msgid "Custom" -msgstr "Custom" +msgstr "Personnalisé" #: src/slic3r/GUI/BedShapeDialog.cpp:80 msgid "Load shape from STL..." -msgstr "Load shape from STL..." +msgstr "Charger une forme depuis un STL..." #: src/slic3r/GUI/BedShapeDialog.cpp:126 msgid "Settings" -msgstr "Settings" +msgstr "Réglages" #: src/slic3r/GUI/BedShapeDialog.cpp:299 msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "" +"Choisir un fichier à partir duquel importer la forme du plateau (STL/OBJ/" +"AMF/3MF/PRUSA) :" -#: src/slic3r/GUI/BedShapeDialog.cpp:316 src/slic3r/GUI/GUI_ObjectList.cpp:1252 +#: src/slic3r/GUI/BedShapeDialog.cpp:316 src/slic3r/GUI/GUI_ObjectList.cpp:1320 msgid "Error! " -msgstr "Error! " +msgstr "Erreur ! " #: src/slic3r/GUI/BedShapeDialog.cpp:325 msgid "The selected file contains no geometry." -msgstr "The selected file contains no geometry." +msgstr "Le fichier sélectionné ne contient aucune géométrie." #: src/slic3r/GUI/BedShapeDialog.cpp:329 msgid "" "The selected file contains several disjoint areas. This is not supported." msgstr "" -"The selected file contains several disjoint areas. This is not supported." +"Le fichier sélectionné contient plusieurs zones disjointes. Cela n'est pas " +"utilisable." -#: src/slic3r/GUI/BedShapeDialog.hpp:44 src/slic3r/GUI/ConfigWizard.cpp:507 +#: src/slic3r/GUI/BedShapeDialog.hpp:44 src/slic3r/GUI/ConfigWizard.cpp:510 msgid "Bed Shape" -msgstr "Bed Shape" +msgstr "Forme du plateau" #: src/slic3r/GUI/BonjourDialog.cpp:55 msgid "Network lookup" -msgstr "Network lookup" +msgstr "Recherche réseau" #: src/slic3r/GUI/BonjourDialog.cpp:72 msgid "Address" -msgstr "Address" +msgstr "Adresse" #: src/slic3r/GUI/BonjourDialog.cpp:73 msgid "Hostname" -msgstr "Hostname" +msgstr "Nom d'hôte" #: src/slic3r/GUI/BonjourDialog.cpp:74 msgid "Service name" -msgstr "Service name" +msgstr "Nom du service" #: src/slic3r/GUI/BonjourDialog.cpp:76 msgid "OctoPrint version" -msgstr "OctoPrint version" +msgstr "Version d'OctoPrint" #: src/slic3r/GUI/BonjourDialog.cpp:218 msgid "Searching for devices" -msgstr "Searching for devices" +msgstr "Recherche des dispositifs" #: src/slic3r/GUI/BonjourDialog.cpp:225 msgid "Finished" -msgstr "Finished" +msgstr "Terminé" #: src/slic3r/GUI/ButtonsDescription.cpp:15 msgid "Buttons And Text Colors Description" -msgstr "Buttons And Text Colors Description" +msgstr "Description des Boutons et des Couleurs de Texte" #: src/slic3r/GUI/ButtonsDescription.cpp:40 msgid "Value is the same as the system value" -msgstr "Value is the same as the system value" +msgstr "La valeur est identique à la valeur du système" #: src/slic3r/GUI/ButtonsDescription.cpp:57 msgid "" "Value was changed and is not equal to the system value or the last saved " "preset" msgstr "" -"Value was changed and is not equal to the system value or the last saved " -"preset" +"La valeur a été changée et n'est pas égale à la valeur du système ou au " +"dernier préréglage sauvegardé" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:17 msgid "Upgrade" -msgstr "Upgrade" +msgstr "Mise à jour" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:19 msgid "Downgrade" -msgstr "Downgrade" +msgstr "Rétrograder" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:21 msgid "Before roll back" -msgstr "Before roll back" +msgstr "Avant le retour en arrière" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:23 msgid "User" -msgstr "User" +msgstr "Utilisateur" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:26 msgid "Unknown" -msgstr "Unknown" +msgstr "Inconnu" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:38 msgid "Active: " -msgstr "Active: " +msgstr "Actif : " #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:44 msgid "slic3r version" -msgstr "slic3r version" +msgstr "version de slic3r" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:45 src/slic3r/GUI/Preset.cpp:1250 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:45 src/slic3r/GUI/Preset.cpp:1252 msgid "print" -msgstr "print" +msgstr "imprimer" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:46 msgid "filaments" msgstr "filaments" -#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:47 src/slic3r/GUI/Preset.cpp:1254 +#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:47 src/slic3r/GUI/Preset.cpp:1256 msgid "printer" -msgstr "printer" +msgstr "imprimer" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:51 src/slic3r/GUI/Tab.cpp:872 msgid "vendor" -msgstr "vendor" +msgstr "fabriquant" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:51 msgid "version" @@ -232,63 +232,63 @@ msgstr "version" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:52 msgid "min slic3r version" -msgstr "min slic3r version" +msgstr "version minimale de slic3r" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:54 msgid "max slic3r version" -msgstr "max slic3r version" +msgstr "version maximale de slic3r" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:57 msgid "model" -msgstr "model" +msgstr "modèle" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:57 msgid "variants" -msgstr "variants" +msgstr "variantes" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:69 msgid "Incompatible with this Slic3r" -msgstr "Incompatible with this Slic3r" +msgstr "Incompatible avec ce Slic3r" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:72 msgid "Activate" -msgstr "Activate" +msgstr "Activer" #: src/slic3r/GUI/ConfigSnapshotDialog.cpp:98 msgid "Configuration Snapshots" -msgstr "Configuration Snapshots" +msgstr "Instantanés de Configuration" #: src/slic3r/GUI/ConfigWizard.cpp:111 msgid "nozzle" -msgstr "nozzle" +msgstr "buse" #: src/slic3r/GUI/ConfigWizard.cpp:115 msgid "Alternate nozzles:" -msgstr "Alternate nozzles:" +msgstr "" #: src/slic3r/GUI/ConfigWizard.cpp:181 msgid "All standard" -msgstr "All standard" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:182 src/slic3r/GUI/Tab.cpp:2909 +#: src/slic3r/GUI/ConfigWizard.cpp:182 src/slic3r/GUI/Tab.cpp:2910 msgid "All" -msgstr "All" +msgstr "Tous" -#: src/slic3r/GUI/ConfigWizard.cpp:183 src/slic3r/GUI/Plater.cpp:414 +#: src/slic3r/GUI/ConfigWizard.cpp:183 src/slic3r/GUI/Plater.cpp:413 #: src/libslic3r/GCode/PreviewData.cpp:162 msgid "None" -msgstr "None" +msgstr "Aucun" #: src/slic3r/GUI/ConfigWizard.cpp:284 #, c-format -msgid "Welcome to the Slic3r %s" -msgstr "Welcome to the Slic3r %s" +msgid "Welcome to the %s %s" +msgstr "" #: src/slic3r/GUI/ConfigWizard.cpp:284 msgid "Welcome" -msgstr "Welcome" +msgstr "Bienvenue" -#: src/slic3r/GUI/ConfigWizard.cpp:288 src/slic3r/GUI/GUI_App.cpp:600 +#: src/slic3r/GUI/ConfigWizard.cpp:288 src/slic3r/GUI/GUI_App.cpp:632 #, c-format msgid "Run %s" msgstr "Run %s" @@ -296,306 +296,304 @@ msgstr "Run %s" #: src/slic3r/GUI/ConfigWizard.cpp:290 #, c-format msgid "" -"Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial " -"configuration; just a few settings and you will be ready to print." +"Hello, welcome to %s! This %s helps you with the initial configuration; just " +"a few settings and you will be ready to print." msgstr "" -"Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial " -"configuration; just a few settings and you will be ready to print." -#: src/slic3r/GUI/ConfigWizard.cpp:294 +#: src/slic3r/GUI/ConfigWizard.cpp:295 msgid "" "Remove user profiles - install from scratch (a snapshot will be taken " "beforehand)" msgstr "" -"Remove user profiles - install from scratch (a snapshot will be taken " -"beforehand)" +"Supprimer les profils d'utilisateur - installation à partir de zéro (un " +"snapshot sera fait avant)" -#: src/slic3r/GUI/ConfigWizard.cpp:325 +#: src/slic3r/GUI/ConfigWizard.cpp:326 #, c-format msgid "%s Family" -msgstr "%s Family" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:362 +#: src/slic3r/GUI/ConfigWizard.cpp:363 msgid "Custom Printer Setup" -msgstr "Custom Printer Setup" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:362 +#: src/slic3r/GUI/ConfigWizard.cpp:363 msgid "Custom Printer" -msgstr "Custom Printer" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:364 +#: src/slic3r/GUI/ConfigWizard.cpp:365 msgid "Define a custom printer profile" -msgstr "Define a custom printer profile" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:366 +#: src/slic3r/GUI/ConfigWizard.cpp:367 msgid "Custom profile name:" -msgstr "Custom profile name:" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:390 +#: src/slic3r/GUI/ConfigWizard.cpp:391 msgid "Automatic updates" -msgstr "Automatic updates" +msgstr "Mises à jour automatiques" -#: src/slic3r/GUI/ConfigWizard.cpp:390 +#: src/slic3r/GUI/ConfigWizard.cpp:391 msgid "Updates" -msgstr "Updates" +msgstr "Mises à jour" -#: src/slic3r/GUI/ConfigWizard.cpp:398 src/slic3r/GUI/Preferences.cpp:59 +#: src/slic3r/GUI/ConfigWizard.cpp:399 src/slic3r/GUI/Preferences.cpp:59 msgid "Check for application updates" -msgstr "Check for application updates" +msgstr "Vérifier les mises à jour de l'application" -#: src/slic3r/GUI/ConfigWizard.cpp:401 src/slic3r/GUI/Preferences.cpp:61 +#: src/slic3r/GUI/ConfigWizard.cpp:402 +#, c-format msgid "" -"If enabled, Slic3r checks for new versions of Slic3r PE online. When a new " -"version becomes available a notification is displayed at the next " -"application startup (never during program usage). This is only a " -"notification mechanisms, no automatic installation is done." +"If enabled, Slic3r checks for new versions of %s online. When a new version " +"becomes available, a notification is displayed at the next application " +"startup (never during program usage). This is only a notification " +"mechanisms, no automatic installation is done." msgstr "" -"If enabled, Slic3r checks for new versions of Slic3r PE online. When a new " -"version becomes available a notification is displayed at the next " -"application startup (never during program usage). This is only a " -"notification mechanisms, no automatic installation is done." -#: src/slic3r/GUI/ConfigWizard.cpp:405 src/slic3r/GUI/Preferences.cpp:67 +#: src/slic3r/GUI/ConfigWizard.cpp:408 src/slic3r/GUI/Preferences.cpp:67 msgid "Update built-in Presets automatically" -msgstr "Update built-in Presets automatically" +msgstr "Mettre à jour automatiquement les Préréglages intégrés" -#: src/slic3r/GUI/ConfigWizard.cpp:408 src/slic3r/GUI/Preferences.cpp:69 +#: src/slic3r/GUI/ConfigWizard.cpp:411 src/slic3r/GUI/Preferences.cpp:69 msgid "" "If enabled, Slic3r downloads updates of built-in system presets in the " "background. These updates are downloaded into a separate temporary location. " "When a new preset version becomes available it is offered at application " "startup." msgstr "" -"If enabled, Slic3r downloads updates of built-in system presets in the " -"background. These updates are downloaded into a separate temporary location. " -"When a new preset version becomes available it is offered at application " -"startup." +"Si activé, Slic3r télécharge les mises à jours des préréglages système " +"intégrés en arrière-plan. Ces mises à jour sont téléchargées dans un " +"répertoire temporaire séparé. Lorsqu'une nouvelle version de préréglages est " +"disponible, elle est proposée au démarrage de l'application." -#: src/slic3r/GUI/ConfigWizard.cpp:409 +#: src/slic3r/GUI/ConfigWizard.cpp:412 msgid "" "Updates are never applied without user's consent and never overwrite user's " "customized settings." msgstr "" -"Updates are never applied without user's consent and never overwrite user's " -"customized settings." +"Les mises à jour ne sont jamais appliquées sans l'accord de l'utilisateur et " +"n'annulent jamais les réglages personnalisés de l'utilisateur." -#: src/slic3r/GUI/ConfigWizard.cpp:414 +#: src/slic3r/GUI/ConfigWizard.cpp:417 msgid "" "Additionally a backup snapshot of the whole configuration is created before " "an update is applied." msgstr "" -"Additionally a backup snapshot of the whole configuration is created before " -"an update is applied." +"De plus, un instantané de sauvegarde de l'ensemble de la configuration est " +"créé avant qu'une mise à jour ne soit appliquée." -#: src/slic3r/GUI/ConfigWizard.cpp:421 +#: src/slic3r/GUI/ConfigWizard.cpp:424 msgid "Other Vendors" -msgstr "Other Vendors" +msgstr "Autres Fabriquants" -#: src/slic3r/GUI/ConfigWizard.cpp:423 -msgid "Pick another vendor supported by Slic3r PE:" -msgstr "Pick another vendor supported by Slic3r PE:" +#: src/slic3r/GUI/ConfigWizard.cpp:426 +#, c-format +msgid "Pick another vendor supported by %s:" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:469 +#: src/slic3r/GUI/ConfigWizard.cpp:472 msgid "Firmware Type" -msgstr "Firmware Type" +msgstr "Type de Firmware" -#: src/slic3r/GUI/ConfigWizard.cpp:469 src/slic3r/GUI/Tab.cpp:1870 +#: src/slic3r/GUI/ConfigWizard.cpp:472 src/slic3r/GUI/Tab.cpp:1870 msgid "Firmware" msgstr "Firmware" -#: src/slic3r/GUI/ConfigWizard.cpp:473 +#: src/slic3r/GUI/ConfigWizard.cpp:476 msgid "Choose the type of firmware used by your printer." -msgstr "Choose the type of firmware used by your printer." - -#: src/slic3r/GUI/ConfigWizard.cpp:507 -msgid "Bed Shape and Size" -msgstr "Bed Shape and Size" +msgstr "Choisissez le type de firmware utilisé par votre imprimante." #: src/slic3r/GUI/ConfigWizard.cpp:510 +msgid "Bed Shape and Size" +msgstr "Forme du Plateau et Taille" + +#: src/slic3r/GUI/ConfigWizard.cpp:513 msgid "Set the shape of your printer's bed." -msgstr "Set the shape of your printer's bed." +msgstr "Réglez la forme du plateau de votre imprimante." -#: src/slic3r/GUI/ConfigWizard.cpp:524 +#: src/slic3r/GUI/ConfigWizard.cpp:527 msgid "Filament and Nozzle Diameters" -msgstr "Filament and Nozzle Diameters" +msgstr "Diamètres du Filament et de la Buse" -#: src/slic3r/GUI/ConfigWizard.cpp:524 +#: src/slic3r/GUI/ConfigWizard.cpp:527 msgid "Print Diameters" -msgstr "Print Diameters" - -#: src/slic3r/GUI/ConfigWizard.cpp:540 -msgid "Enter the diameter of your printer's hot end nozzle." -msgstr "Enter the diameter of your printer's hot end nozzle." +msgstr "Diamètres d'Impression" #: src/slic3r/GUI/ConfigWizard.cpp:543 +msgid "Enter the diameter of your printer's hot end nozzle." +msgstr "" +"Entrez le diamètre de la buse de la tête d'impression de votre imprimante." + +#: src/slic3r/GUI/ConfigWizard.cpp:546 msgid "Nozzle Diameter:" -msgstr "Nozzle Diameter:" +msgstr "Diamètre de la Buse :" -#: src/slic3r/GUI/ConfigWizard.cpp:553 +#: src/slic3r/GUI/ConfigWizard.cpp:556 msgid "Enter the diameter of your filament." -msgstr "Enter the diameter of your filament." +msgstr "Entrez le diamètre de votre filament." -#: src/slic3r/GUI/ConfigWizard.cpp:554 +#: src/slic3r/GUI/ConfigWizard.cpp:557 msgid "" "Good precision is required, so use a caliper and do multiple measurements " "along the filament, then compute the average." msgstr "" -"Good precision is required, so use a caliper and do multiple measurements " -"along the filament, then compute the average." +"Une bonne précision est requise, utilisez un pied à coulisse et calculez la " +"moyenne de plusieurs mesures le long du filament." -#: src/slic3r/GUI/ConfigWizard.cpp:557 +#: src/slic3r/GUI/ConfigWizard.cpp:560 msgid "Filament Diameter:" -msgstr "Filament Diameter:" +msgstr "Diamètre du Filament :" -#: src/slic3r/GUI/ConfigWizard.cpp:575 +#: src/slic3r/GUI/ConfigWizard.cpp:578 msgid "Extruder and Bed Temperatures" -msgstr "Extruder and Bed Temperatures" +msgstr "Températures de l'Extrudeur et du Lit" -#: src/slic3r/GUI/ConfigWizard.cpp:575 +#: src/slic3r/GUI/ConfigWizard.cpp:578 msgid "Temperatures" -msgstr "Temperatures" +msgstr "Températures" -#: src/slic3r/GUI/ConfigWizard.cpp:591 +#: src/slic3r/GUI/ConfigWizard.cpp:594 msgid "Enter the temperature needed for extruding your filament." -msgstr "Enter the temperature needed for extruding your filament." - -#: src/slic3r/GUI/ConfigWizard.cpp:592 -msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." -msgstr "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." +msgstr "Entrez la température nécessaire pour extruder votre filament." #: src/slic3r/GUI/ConfigWizard.cpp:595 -msgid "Extrusion Temperature:" -msgstr "Extrusion Temperature:" +msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." +msgstr "" +"La règle générale est 160 à 230 °C pour le PLA et 215 à 250 °C pour l'ABS." -#: src/slic3r/GUI/ConfigWizard.cpp:596 src/slic3r/GUI/ConfigWizard.cpp:610 +#: src/slic3r/GUI/ConfigWizard.cpp:598 +msgid "Extrusion Temperature:" +msgstr "Température d'Extrusion :" + +#: src/slic3r/GUI/ConfigWizard.cpp:599 src/slic3r/GUI/ConfigWizard.cpp:613 msgid "°C" msgstr "°C" -#: src/slic3r/GUI/ConfigWizard.cpp:605 +#: src/slic3r/GUI/ConfigWizard.cpp:608 msgid "" "Enter the bed temperature needed for getting your filament to stick to your " "heated bed." msgstr "" -"Enter the bed temperature needed for getting your filament to stick to your " -"heated bed." - -#: src/slic3r/GUI/ConfigWizard.cpp:606 -msgid "" -"A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have " -"no heated bed." -msgstr "" -"A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have " -"no heated bed." +"Entrez la température du lit nécessaire pour que votre filament colle à " +"votre lit chauffant." #: src/slic3r/GUI/ConfigWizard.cpp:609 +msgid "" +"A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have " +"no heated bed." +msgstr "" +"La règle générale est 60 °C pour le PLA et 110 °C pour l'ABS. Laissez à zéro " +"si vous n'avez pas de lit chauffant." + +#: src/slic3r/GUI/ConfigWizard.cpp:612 msgid "Bed Temperature:" -msgstr "Bed Temperature:" +msgstr "Température du Plateau :" -#: src/slic3r/GUI/ConfigWizard.cpp:1001 +#: src/slic3r/GUI/ConfigWizard.cpp:1017 msgid "Select all standard printers" -msgstr "Select all standard printers" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1004 +#: src/slic3r/GUI/ConfigWizard.cpp:1020 msgid "< &Back" -msgstr "< &Back" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1005 +#: src/slic3r/GUI/ConfigWizard.cpp:1021 msgid "&Next >" -msgstr "&Next >" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1006 +#: src/slic3r/GUI/ConfigWizard.cpp:1022 msgid "&Finish" -msgstr "&Finish" +msgstr "&Fin" -#: src/slic3r/GUI/ConfigWizard.cpp:1007 src/slic3r/GUI/FirmwareDialog.cpp:142 +#: src/slic3r/GUI/ConfigWizard.cpp:1023 src/slic3r/GUI/FirmwareDialog.cpp:142 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:37 #: src/slic3r/GUI/ProgressStatusBar.cpp:28 msgid "Cancel" -msgstr "Cancel" +msgstr "Annuler" -#: src/slic3r/GUI/ConfigWizard.cpp:1021 +#: src/slic3r/GUI/ConfigWizard.cpp:1037 msgid "Prusa FFF Technology Printers" -msgstr "Prusa FFF Technology Printers" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1024 +#: src/slic3r/GUI/ConfigWizard.cpp:1040 msgid "Prusa MSLA Technology Printers" -msgstr "Prusa MSLA Technology Printers" +msgstr "" -#: src/slic3r/GUI/ConfigWizard.cpp:1111 +#: src/slic3r/GUI/ConfigWizard.cpp:1127 msgid "Configuration Wizard" -msgstr "Configuration Wizard" +msgstr "Assistant de Configuration" -#: src/slic3r/GUI/ConfigWizard.cpp:1112 +#: src/slic3r/GUI/ConfigWizard.cpp:1128 msgid "Configuration &Wizard" -msgstr "Configuration &Wizard" +msgstr "&Assistant de Configuration" -#: src/slic3r/GUI/ConfigWizard.cpp:1114 +#: src/slic3r/GUI/ConfigWizard.cpp:1130 msgid "Configuration Assistant" -msgstr "Configuration Assistant" +msgstr "Assistant de Configuration" -#: src/slic3r/GUI/ConfigWizard.cpp:1115 +#: src/slic3r/GUI/ConfigWizard.cpp:1131 msgid "Configuration &Assistant" -msgstr "Configuration &Assistant" +msgstr "&Assistant de Configuration" -#: src/slic3r/GUI/Field.cpp:112 +#: src/slic3r/GUI/Field.cpp:111 msgid "default value" -msgstr "default value" +msgstr "" -#: src/slic3r/GUI/Field.cpp:115 +#: src/slic3r/GUI/Field.cpp:114 msgid "parameter name" -msgstr "parameter name" +msgstr "" -#: src/slic3r/GUI/Field.cpp:143 +#: src/slic3r/GUI/Field.cpp:142 #, c-format msgid "%s doesn't support percentage" -msgstr "%s doesn't support percentage" +msgstr "%s ne supporte pas un pourcentage" -#: src/slic3r/GUI/Field.cpp:157 src/slic3r/GUI/Field.cpp:180 +#: src/slic3r/GUI/Field.cpp:156 src/slic3r/GUI/Field.cpp:179 msgid "Invalid numeric input." -msgstr "Invalid numeric input." +msgstr "" -#: src/slic3r/GUI/Field.cpp:162 +#: src/slic3r/GUI/Field.cpp:161 msgid "Input value is out of range" -msgstr "Input value is out of range" +msgstr "La valeur entrée est hors plage" -#: src/slic3r/GUI/Field.cpp:188 +#: src/slic3r/GUI/Field.cpp:187 #, c-format msgid "" "Do you mean %d%% instead of %d %s?\n" "Select YES if you want to change this value to %d%%, \n" "or NO if you are sure that %d %s is a correct value." msgstr "" -"Do you mean %d%% instead of %d %s?\n" -"Select YES if you want to change this value to %d%%, \n" -"or NO if you are sure that %d %s is a correct value." -#: src/slic3r/GUI/Field.cpp:191 +#: src/slic3r/GUI/Field.cpp:190 msgid "Parameter validation" -msgstr "Parameter validation" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:141 msgid "Flash!" -msgstr "Flash!" +msgstr "Flash !" #: src/slic3r/GUI/FirmwareDialog.cpp:143 msgid "Flashing in progress. Please do not disconnect the printer!" -msgstr "Flashing in progress. Please do not disconnect the printer!" +msgstr "" +"Processus de flash en cours. Veuillez ne pas déconnecter l'imprimante !" #: src/slic3r/GUI/FirmwareDialog.cpp:187 msgid "Flashing failed: " -msgstr "Flashing failed: " +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:268 msgid "Flashing succeeded!" -msgstr "Flashing succeeded!" +msgstr "Flash effectué avec succès !" #: src/slic3r/GUI/FirmwareDialog.cpp:269 msgid "Flashing failed. Please see the avrdude log below." -msgstr "Flashing failed. Please see the avrdude log below." +msgstr "" +"Le processus de flash a échoué. Veuillez consulter le journal avrdude ci-" +"dessous." #: src/slic3r/GUI/FirmwareDialog.cpp:270 msgid "Flashing cancelled." -msgstr "Flashing cancelled." +msgstr "Processus de flash annulé." #: src/slic3r/GUI/FirmwareDialog.cpp:308 #, c-format @@ -607,19 +605,12 @@ msgid "" "Do you want to continue and flash this hex file anyway?\n" "Please only continue if you are sure this is the right thing to do." msgstr "" -"This firmware hex file does not match the printer model.\n" -"The hex file is intended for: %s\n" -"Printer reported: %s\n" -"\n" -"Do you want to continue and flash this hex file anyway?\n" -"Please only continue if you are sure this is the right thing to do." #: src/slic3r/GUI/FirmwareDialog.cpp:395 src/slic3r/GUI/FirmwareDialog.cpp:431 #, c-format msgid "" "Multiple %s devices found. Please only connect one at a time for flashing." msgstr "" -"Multiple %s devices found. Please only connect one at a time for flashing." #: src/slic3r/GUI/FirmwareDialog.cpp:412 #, c-format @@ -628,73 +619,70 @@ msgid "" "If the device is connected, please press the Reset button next to the USB " "connector ..." msgstr "" -"The %s device was not found.\n" -"If the device is connected, please press the Reset button next to the USB " -"connector ..." #: src/slic3r/GUI/FirmwareDialog.cpp:525 #, c-format msgid "The %s device could not have been found" -msgstr "The %s device could not have been found" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:603 #, c-format msgid "Error accessing port at %s: %s" -msgstr "Error accessing port at %s: %s" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:605 #, c-format msgid "Error: %s" -msgstr "Error: %s" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:735 msgid "Firmware flasher" -msgstr "Firmware flasher" +msgstr "Outil de flash du firmware" #: src/slic3r/GUI/FirmwareDialog.cpp:762 msgid "Firmware image:" -msgstr "Firmware image:" +msgstr "Image du firmware :" #: src/slic3r/GUI/FirmwareDialog.cpp:766 msgid "Serial port:" -msgstr "Serial port:" +msgstr "Port série :" #: src/slic3r/GUI/FirmwareDialog.cpp:768 msgid "Autodetected" -msgstr "Autodetected" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:769 msgid "Rescan" -msgstr "Rescan" +msgstr "Scanner à nouveau" #: src/slic3r/GUI/FirmwareDialog.cpp:776 msgid "Progress:" -msgstr "Progress:" +msgstr "Progression :" #: src/slic3r/GUI/FirmwareDialog.cpp:779 msgid "Status:" -msgstr "Status:" +msgstr "État :" #: src/slic3r/GUI/FirmwareDialog.cpp:780 msgid "Ready" -msgstr "Ready" +msgstr "Prêt" #: src/slic3r/GUI/FirmwareDialog.cpp:800 msgid "Advanced: Output log" -msgstr "Advanced: Output log" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:811 #: src/slic3r/GUI/PrintHostDialogs.cpp:161 msgid "Close" -msgstr "Close" +msgstr "" #: src/slic3r/GUI/FirmwareDialog.cpp:859 msgid "" "Are you sure you want to cancel firmware flashing?\n" "This could leave your printer in an unusable state!" msgstr "" -"Are you sure you want to cancel firmware flashing?\n" -"This could leave your printer in an unusable state!" +"Êtes-vous certain de vouloir annuler le processus de flash du firmware ?\n" +"Cela pourrait rendre votre imprimante inutilisable !" #: src/slic3r/GUI/FirmwareDialog.cpp:860 msgid "Confirmation" @@ -702,340 +690,357 @@ msgstr "Confirmation" #: src/slic3r/GUI/FirmwareDialog.cpp:863 msgid "Cancelling..." -msgstr "Cancelling..." +msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:709 +#: src/slic3r/GUI/GLCanvas3D.cpp:714 msgid "Detected object outside print volume" -msgstr "Detected object outside print volume" +msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:710 +#: src/slic3r/GUI/GLCanvas3D.cpp:715 msgid "Detected toolpath outside print volume" -msgstr "Detected toolpath outside print volume" +msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:711 +#: src/slic3r/GUI/GLCanvas3D.cpp:716 msgid "Some objects are not visible when editing supports" -msgstr "Some objects are not visible when editing supports" +msgstr "" -#: src/slic3r/GUI/GLCanvas3D.cpp:713 +#: src/slic3r/GUI/GLCanvas3D.cpp:718 msgid "" "Detected object outside print volume\n" "Resolve a clash to continue slicing/export process correctly" msgstr "" -"Detected object outside print volume\n" -"Resolve a clash to continue slicing/export process correctly" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:35 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:195 msgid "Rotate lower part upwards" -msgstr "Rotate lower part upwards" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:36 #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:198 msgid "Perform cut" -msgstr "Perform cut" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:43 msgid "Cut object:" -msgstr "Cut object:" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:88 msgid "Cut [C]" -msgstr "Cut [C]" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:188 src/libslic3r/PrintConfig.cpp:3006 +#: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:188 src/libslic3r/PrintConfig.cpp:3011 msgid "Cut" -msgstr "Cut" +msgstr "Couper" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:193 msgid "Keep upper part" -msgstr "Keep upper part" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoCut.cpp:194 msgid "Keep lower part" -msgstr "Keep lower part" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp:32 msgid "Place on face [F]" -msgstr "Place on face [F]" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:51 msgid "Move [M]" -msgstr "Move [M]" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:176 +#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:177 msgid "Position (mm)" -msgstr "Position (mm)" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:176 +#: src/slic3r/GUI/Gizmos/GLGizmoMove.cpp:177 msgid "Displacement (mm)" -msgstr "Displacement (mm)" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:458 msgid "Rotate [R]" -msgstr "Rotate [R]" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:491 msgid "Rotation (deg)" -msgstr "Rotation (deg)" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:51 msgid "Scale [S]" -msgstr "Scale [S]" +msgstr "" #: src/slic3r/GUI/Gizmos/GLGizmoScale.cpp:276 msgid "Scale (%)" -msgstr "Scale (%)" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:597 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:882 msgid "Left mouse click - add point" -msgstr "Left mouse click - add point" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:598 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:883 msgid "Right mouse click - remove point" -msgstr "Right mouse click - remove point" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:599 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:884 msgid "Shift + Left (+ drag) - select point(s)" -msgstr "Shift + Left (+ drag) - select point(s)" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:606 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:891 msgid "Head diameter: " -msgstr "Head diameter: " +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:618 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:903 msgid "Lock supports under new islands" -msgstr "Lock supports under new islands" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:622 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:907 msgid "Remove selected points" -msgstr "Remove selected points" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:626 -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:679 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:911 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:964 msgid "Remove all points" -msgstr "Remove all points" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:631 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:916 msgid "Apply changes" -msgstr "Apply changes" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:636 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:921 msgid "Discard changes" -msgstr "Discard changes" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:644 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:929 msgid "Minimal points distance: " -msgstr "Minimal points distance: " +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:655 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:940 msgid "Support points density: " -msgstr "Support points density: " +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:669 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:954 msgid "Auto-generate points [A]" -msgstr "Auto-generate points [A]" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:675 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:960 msgid "Manual editing [M]" -msgstr "Manual editing [M]" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:738 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:969 +msgid "No points (will be autogenerated)" +msgstr "" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:970 +msgid "Autogenerated points (no modifications)" +msgstr "" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:971 +msgid "User-modified points" +msgstr "" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:972 +msgid "Generation in progress..." +msgstr "" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:980 +msgid "Reset direction [R] " +msgstr "" + +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1039 msgid "SLA Support Points [L]" -msgstr "SLA Support Points [L]" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:767 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1066 msgid "Do you want to save your manually edited support points ?\n" -msgstr "Do you want to save your manually edited support points ?\n" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:768 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1067 msgid "Save changes?" -msgstr "Save changes?" +msgstr "" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:897 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1210 msgid "" "Autogeneration will erase all manually edited points.\n" "\n" "Are you sure you want to do it?\n" msgstr "" -"Autogeneration will erase all manually edited points.\n" -"\n" -"Are you sure you want to do it?\n" -#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:899 src/slic3r/GUI/GUI.cpp:288 +#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1212 src/slic3r/GUI/GUI.cpp:288 #: src/slic3r/GUI/WipeTowerDialog.cpp:44 src/slic3r/GUI/WipeTowerDialog.cpp:328 msgid "Warning" -msgstr "Warning" +msgstr "Alerte" -#: src/slic3r/GUI/GUI.cpp:147 src/slic3r/GUI/Tab.cpp:2720 +#: src/slic3r/GUI/GUI.cpp:147 src/slic3r/GUI/Tab.cpp:2721 msgid "It's impossible to print multi-part object(s) with SLA technology." -msgstr "It's impossible to print multi-part object(s) with SLA technology." +msgstr "" #: src/slic3r/GUI/GUI.cpp:148 msgid "Please check and fix your object list." -msgstr "Please check and fix your object list." +msgstr "" -#: src/slic3r/GUI/GUI.cpp:149 src/slic3r/GUI/GUI_App.cpp:679 -#: src/slic3r/GUI/Tab.cpp:2722 +#: src/slic3r/GUI/GUI.cpp:149 src/slic3r/GUI/GUI_App.cpp:711 +#: src/slic3r/GUI/Tab.cpp:2723 msgid "Attention!" -msgstr "Attention!" +msgstr "Attention !" #: src/slic3r/GUI/GUI.cpp:282 msgid "Notice" -msgstr "Notice" +msgstr "Remarque" -#: src/slic3r/GUI/GUI_App.cpp:318 +#: src/slic3r/GUI/GUI_App.cpp:352 msgid "Changing of an application language" -msgstr "Changing of an application language" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:326 src/slic3r/GUI/GUI_App.cpp:335 +#: src/slic3r/GUI/GUI_App.cpp:360 src/slic3r/GUI/GUI_App.cpp:369 msgid "Recreating" -msgstr "Recreating" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:339 -msgid "Loading of a current presets" -msgstr "Loading of a current presets" +#: src/slic3r/GUI/GUI_App.cpp:373 +msgid "Loading of current presets" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:347 +#: src/slic3r/GUI/GUI_App.cpp:381 msgid "Loading of a mode view" -msgstr "Loading of a mode view" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:429 +#: src/slic3r/GUI/GUI_App.cpp:463 msgid "Choose one file (3MF):" -msgstr "Choose one file (3MF):" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:441 +#: src/slic3r/GUI/GUI_App.cpp:475 msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "Choisir un ou plusieurs fichiers (STL/OBJ/AMF/3MF/PRUSA) :" -#: src/slic3r/GUI/GUI_App.cpp:454 +#: src/slic3r/GUI/GUI_App.cpp:488 msgid "Array of language names and identifiers should have the same size." -msgstr "Array of language names and identifiers should have the same size." +msgstr "" +"Les tableaux de noms et d'identifiants de langue doivent avoir la même " +"taille." -#: src/slic3r/GUI/GUI_App.cpp:464 +#: src/slic3r/GUI/GUI_App.cpp:498 msgid "Select the language" -msgstr "Select the language" +msgstr "Sélectionner la langue" -#: src/slic3r/GUI/GUI_App.cpp:464 +#: src/slic3r/GUI/GUI_App.cpp:498 msgid "Language" -msgstr "Language" +msgstr "Langue" -#: src/slic3r/GUI/GUI_App.cpp:534 src/slic3r/GUI/GUI_ObjectList.cpp:1067 +#: src/slic3r/GUI/GUI_App.cpp:568 src/slic3r/GUI/GUI_ObjectList.cpp:1135 #: src/libslic3r/PrintConfig.cpp:298 msgid "Default" -msgstr "Default" +msgstr "Défaut" -#: src/slic3r/GUI/GUI_App.cpp:603 +#: src/slic3r/GUI/GUI_App.cpp:635 msgid "&Configuration Snapshots" -msgstr "&Configuration Snapshots" +msgstr "Instantanés de &Configuration" -#: src/slic3r/GUI/GUI_App.cpp:603 +#: src/slic3r/GUI/GUI_App.cpp:635 msgid "Inspect / activate configuration snapshots" -msgstr "Inspect / activate configuration snapshots" +msgstr "Inspecter / activer les instantanés de configuration" -#: src/slic3r/GUI/GUI_App.cpp:604 +#: src/slic3r/GUI/GUI_App.cpp:636 msgid "Take Configuration &Snapshot" -msgstr "Take Configuration &Snapshot" +msgstr "Prendre un &snapshot de la configuration" -#: src/slic3r/GUI/GUI_App.cpp:604 +#: src/slic3r/GUI/GUI_App.cpp:636 msgid "Capture a configuration snapshot" -msgstr "Capture a configuration snapshot" +msgstr "Capturer un instantané de la configuration" -#: src/slic3r/GUI/GUI_App.cpp:607 +#: src/slic3r/GUI/GUI_App.cpp:639 msgid "&Preferences" -msgstr "&Preferences" +msgstr "&Préférences" -#: src/slic3r/GUI/GUI_App.cpp:613 +#: src/slic3r/GUI/GUI_App.cpp:645 msgid "Application preferences" -msgstr "Application preferences" +msgstr "Préférences de l'application" -#: src/slic3r/GUI/GUI_App.cpp:616 src/slic3r/GUI/wxExtensions.cpp:2446 +#: src/slic3r/GUI/GUI_App.cpp:648 src/slic3r/GUI/wxExtensions.cpp:2457 msgid "Simple" -msgstr "Simple" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:616 +#: src/slic3r/GUI/GUI_App.cpp:648 msgid "Simple View Mode" -msgstr "Simple View Mode" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:617 src/slic3r/GUI/GUI_ObjectList.cpp:73 +#: src/slic3r/GUI/GUI_App.cpp:649 src/slic3r/GUI/GUI_ObjectList.cpp:76 #: src/slic3r/GUI/Tab.cpp:977 src/slic3r/GUI/Tab.cpp:992 #: src/slic3r/GUI/Tab.cpp:1090 src/slic3r/GUI/Tab.cpp:1093 #: src/slic3r/GUI/Tab.cpp:1466 src/slic3r/GUI/Tab.cpp:1890 -#: src/slic3r/GUI/Tab.cpp:3347 src/slic3r/GUI/wxExtensions.cpp:2447 +#: src/slic3r/GUI/Tab.cpp:3349 src/slic3r/GUI/wxExtensions.cpp:2458 #: src/libslic3r/PrintConfig.cpp:72 src/libslic3r/PrintConfig.cpp:186 #: src/libslic3r/PrintConfig.cpp:349 src/libslic3r/PrintConfig.cpp:987 #: src/libslic3r/PrintConfig.cpp:2173 msgid "Advanced" -msgstr "Advanced" +msgstr "Avancé" -#: src/slic3r/GUI/GUI_App.cpp:617 +#: src/slic3r/GUI/GUI_App.cpp:649 msgid "Advanced View Mode" -msgstr "Advanced View Mode" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:618 src/slic3r/GUI/wxExtensions.cpp:2448 +#: src/slic3r/GUI/GUI_App.cpp:650 src/slic3r/GUI/wxExtensions.cpp:2459 msgid "Expert" -msgstr "Expert" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:618 +#: src/slic3r/GUI/GUI_App.cpp:650 msgid "Expert View Mode" -msgstr "Expert View Mode" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:623 +#: src/slic3r/GUI/GUI_App.cpp:655 msgid "Mode" -msgstr "Mode" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:623 +#: src/slic3r/GUI/GUI_App.cpp:655 msgid "Slic3r View Mode" -msgstr "Slic3r View Mode" +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:625 +#: src/slic3r/GUI/GUI_App.cpp:657 msgid "Change Application &Language" -msgstr "Change Application &Language" +msgstr "Changer la &langue de l'application" -#: src/slic3r/GUI/GUI_App.cpp:627 +#: src/slic3r/GUI/GUI_App.cpp:659 msgid "Flash printer &firmware" -msgstr "Flash printer &firmware" +msgstr "Flasher le &firmware de l'imprimante" -#: src/slic3r/GUI/GUI_App.cpp:627 +#: src/slic3r/GUI/GUI_App.cpp:659 msgid "Upload a firmware image into an Arduino based printer" -msgstr "Upload a firmware image into an Arduino based printer" +msgstr "Charger un firmware dans une imprimante basée sur un Arduino" -#: src/slic3r/GUI/GUI_App.cpp:639 +#: src/slic3r/GUI/GUI_App.cpp:671 msgid "Taking configuration snapshot" -msgstr "Taking configuration snapshot" +msgstr "Snapshot de la configuration en cours" -#: src/slic3r/GUI/GUI_App.cpp:639 +#: src/slic3r/GUI/GUI_App.cpp:671 msgid "Snapshot name" -msgstr "Snapshot name" +msgstr "Nom du snapshot" -#: src/slic3r/GUI/GUI_App.cpp:676 +#: src/slic3r/GUI/GUI_App.cpp:708 msgid "Application will be restarted after language change." -msgstr "Application will be restarted after language change." +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:677 +#: src/slic3r/GUI/GUI_App.cpp:709 msgid "3D-Scene will be cleaned." -msgstr "3D-Scene will be cleaned." +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:678 +#: src/slic3r/GUI/GUI_App.cpp:710 msgid "Please, check your changes before." -msgstr "Please, check your changes before." +msgstr "" -#: src/slic3r/GUI/GUI_App.cpp:706 +#: src/slic3r/GUI/GUI_App.cpp:738 msgid "&Configuration" msgstr "&Configuration" -#: src/slic3r/GUI/GUI_App.cpp:726 +#: src/slic3r/GUI/GUI_App.cpp:758 msgid "You have unsaved changes " -msgstr "You have unsaved changes " +msgstr "Les modifications n'ont pas été sauvegardées " -#: src/slic3r/GUI/GUI_App.cpp:726 +#: src/slic3r/GUI/GUI_App.cpp:758 msgid ". Discard changes and continue anyway?" -msgstr ". Discard changes and continue anyway?" +msgstr ". Annuler les changements et continuer malgré tout ?" -#: src/slic3r/GUI/GUI_App.cpp:727 +#: src/slic3r/GUI/GUI_App.cpp:759 msgid "Unsaved Presets" -msgstr "Unsaved Presets" +msgstr "Préréglages Non Sauvegardés" -#: src/slic3r/GUI/GUI_ObjectList.cpp:28 src/slic3r/GUI/GUI_ObjectList.cpp:65 +#: src/slic3r/GUI/GUI_ObjectList.cpp:28 src/slic3r/GUI/GUI_ObjectList.cpp:68 #: src/libslic3r/PrintConfig.cpp:56 src/libslic3r/PrintConfig.cpp:149 #: src/libslic3r/PrintConfig.cpp:380 src/libslic3r/PrintConfig.cpp:437 #: src/libslic3r/PrintConfig.cpp:445 src/libslic3r/PrintConfig.cpp:841 @@ -1043,10 +1048,10 @@ msgstr "Unsaved Presets" #: src/libslic3r/PrintConfig.cpp:1370 src/libslic3r/PrintConfig.cpp:1551 #: src/libslic3r/PrintConfig.cpp:1986 src/libslic3r/PrintConfig.cpp:2042 msgid "Layers and Perimeters" -msgstr "Layers and Perimeters" +msgstr "Couches et Périmètres" -#: src/slic3r/GUI/GUI_ObjectList.cpp:29 src/slic3r/GUI/GUI_ObjectList.cpp:66 -#: src/slic3r/GUI/Plater.cpp:431 src/slic3r/GUI/Tab.cpp:981 +#: src/slic3r/GUI/GUI_ObjectList.cpp:29 src/slic3r/GUI/GUI_ObjectList.cpp:69 +#: src/slic3r/GUI/Plater.cpp:430 src/slic3r/GUI/Tab.cpp:981 #: src/slic3r/GUI/Tab.cpp:982 src/slic3r/GUI/Tab.cpp:1311 #: src/libslic3r/PrintConfig.cpp:166 src/libslic3r/PrintConfig.cpp:388 #: src/libslic3r/PrintConfig.cpp:728 src/libslic3r/PrintConfig.cpp:742 @@ -1055,9 +1060,9 @@ msgstr "Layers and Perimeters" #: src/libslic3r/PrintConfig.cpp:978 src/libslic3r/PrintConfig.cpp:997 #: src/libslic3r/PrintConfig.cpp:1658 src/libslic3r/PrintConfig.cpp:1675 msgid "Infill" -msgstr "Infill" +msgstr "Remplissage" -#: src/slic3r/GUI/GUI_ObjectList.cpp:30 src/slic3r/GUI/GUI_ObjectList.cpp:67 +#: src/slic3r/GUI/GUI_ObjectList.cpp:30 src/slic3r/GUI/GUI_ObjectList.cpp:70 #: src/slic3r/GUI/GUI_Preview.cpp:236 src/slic3r/GUI/Tab.cpp:1010 #: src/slic3r/GUI/Tab.cpp:1011 src/libslic3r/PrintConfig.cpp:333 #: src/libslic3r/PrintConfig.cpp:1431 src/libslic3r/PrintConfig.cpp:1779 @@ -1072,1209 +1077,1233 @@ msgstr "Infill" #: src/libslic3r/PrintConfig.cpp:1955 src/libslic3r/PrintConfig.cpp:1969 #: src/libslic3r/GCode/PreviewData.cpp:172 msgid "Support material" -msgstr "Support material" +msgstr "Support" -#: src/slic3r/GUI/GUI_ObjectList.cpp:33 src/slic3r/GUI/GUI_ObjectList.cpp:69 +#: src/slic3r/GUI/GUI_ObjectList.cpp:33 src/slic3r/GUI/GUI_ObjectList.cpp:72 #: src/slic3r/GUI/Tab.cpp:1070 src/slic3r/GUI/Tab.cpp:1794 #: src/libslic3r/PrintConfig.cpp:455 src/libslic3r/PrintConfig.cpp:953 #: src/libslic3r/PrintConfig.cpp:1339 src/libslic3r/PrintConfig.cpp:1667 #: src/libslic3r/PrintConfig.cpp:1851 src/libslic3r/PrintConfig.cpp:1877 #: src/libslic3r/PrintConfig.cpp:2149 src/libslic3r/PrintConfig.cpp:2157 msgid "Extruders" -msgstr "Extruders" +msgstr "Extrudeurs" #: src/slic3r/GUI/GUI_ObjectList.cpp:39 msgid "Pad and Support" -msgstr "Pad and Support" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:68 src/slic3r/GUI/GUI_Preview.cpp:215 +#: src/slic3r/GUI/GUI_ObjectList.cpp:71 src/slic3r/GUI/GUI_Preview.cpp:215 #: src/slic3r/GUI/Tab.cpp:1035 src/libslic3r/PrintConfig.cpp:198 #: src/libslic3r/PrintConfig.cpp:425 src/libslic3r/PrintConfig.cpp:870 #: src/libslic3r/PrintConfig.cpp:998 src/libslic3r/PrintConfig.cpp:1360 #: src/libslic3r/PrintConfig.cpp:1597 src/libslic3r/PrintConfig.cpp:1646 #: src/libslic3r/PrintConfig.cpp:1697 src/libslic3r/PrintConfig.cpp:2028 msgid "Speed" -msgstr "Speed" +msgstr "Vitesse" -#: src/slic3r/GUI/GUI_ObjectList.cpp:70 src/libslic3r/PrintConfig.cpp:415 +#: src/slic3r/GUI/GUI_ObjectList.cpp:73 src/libslic3r/PrintConfig.cpp:415 #: src/libslic3r/PrintConfig.cpp:522 src/libslic3r/PrintConfig.cpp:829 #: src/libslic3r/PrintConfig.cpp:961 src/libslic3r/PrintConfig.cpp:1348 #: src/libslic3r/PrintConfig.cpp:1687 src/libslic3r/PrintConfig.cpp:1860 #: src/libslic3r/PrintConfig.cpp:2017 msgid "Extrusion Width" -msgstr "Extrusion Width" +msgstr "Largeur d'Extrusion" -#: src/slic3r/GUI/GUI_ObjectList.cpp:75 src/slic3r/GUI/Plater.cpp:410 -#: src/slic3r/GUI/Tab.cpp:3309 src/slic3r/GUI/Tab.cpp:3310 -#: src/libslic3r/PrintConfig.cpp:2359 src/libslic3r/PrintConfig.cpp:2366 -#: src/libslic3r/PrintConfig.cpp:2375 src/libslic3r/PrintConfig.cpp:2384 -#: src/libslic3r/PrintConfig.cpp:2394 src/libslic3r/PrintConfig.cpp:2420 -#: src/libslic3r/PrintConfig.cpp:2427 src/libslic3r/PrintConfig.cpp:2438 -#: src/libslic3r/PrintConfig.cpp:2448 src/libslic3r/PrintConfig.cpp:2457 -#: src/libslic3r/PrintConfig.cpp:2467 src/libslic3r/PrintConfig.cpp:2476 -#: src/libslic3r/PrintConfig.cpp:2486 src/libslic3r/PrintConfig.cpp:2496 -#: src/libslic3r/PrintConfig.cpp:2504 +#: src/slic3r/GUI/GUI_ObjectList.cpp:78 src/slic3r/GUI/Plater.cpp:409 +#: src/slic3r/GUI/Tab.cpp:3311 src/slic3r/GUI/Tab.cpp:3312 +#: src/libslic3r/PrintConfig.cpp:2361 src/libslic3r/PrintConfig.cpp:2368 +#: src/libslic3r/PrintConfig.cpp:2377 src/libslic3r/PrintConfig.cpp:2386 +#: src/libslic3r/PrintConfig.cpp:2396 src/libslic3r/PrintConfig.cpp:2422 +#: src/libslic3r/PrintConfig.cpp:2429 src/libslic3r/PrintConfig.cpp:2440 +#: src/libslic3r/PrintConfig.cpp:2450 src/libslic3r/PrintConfig.cpp:2459 +#: src/libslic3r/PrintConfig.cpp:2469 src/libslic3r/PrintConfig.cpp:2478 +#: src/libslic3r/PrintConfig.cpp:2488 src/libslic3r/PrintConfig.cpp:2498 +#: src/libslic3r/PrintConfig.cpp:2506 msgid "Supports" -msgstr "Supports" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:76 src/slic3r/GUI/Tab.cpp:3337 -#: src/slic3r/GUI/Tab.cpp:3338 src/libslic3r/PrintConfig.cpp:2512 -#: src/libslic3r/PrintConfig.cpp:2519 src/libslic3r/PrintConfig.cpp:2530 -#: src/libslic3r/PrintConfig.cpp:2540 src/libslic3r/PrintConfig.cpp:2553 -#: src/libslic3r/PrintConfig.cpp:2562 +#: src/slic3r/GUI/GUI_ObjectList.cpp:79 src/slic3r/GUI/Tab.cpp:3339 +#: src/slic3r/GUI/Tab.cpp:3340 src/libslic3r/PrintConfig.cpp:2514 +#: src/libslic3r/PrintConfig.cpp:2521 src/libslic3r/PrintConfig.cpp:2535 +#: src/libslic3r/PrintConfig.cpp:2545 src/libslic3r/PrintConfig.cpp:2558 +#: src/libslic3r/PrintConfig.cpp:2567 msgid "Pad" -msgstr "Pad" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:173 +#: src/slic3r/GUI/GUI_ObjectList.cpp:176 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:45 msgid "Name" -msgstr "Name" +msgstr "Nom" -#: src/slic3r/GUI/GUI_ObjectList.cpp:201 +#: src/slic3r/GUI/GUI_ObjectList.cpp:204 msgid "Right button click the icon to change the object settings" -msgstr "Right button click the icon to change the object settings" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:209 -#, c-format -msgid "Auto-repaired (%d errors):\n" -msgstr "Auto-repaired (%d errors):\n" +msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:212 -msgid "degenerate facets" -msgstr "degenerate facets" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:213 -msgid "edges fixed" -msgstr "edges fixed" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:214 -msgid "facets removed" -msgstr "facets removed" +#, c-format +msgid "Auto-repaired (%d errors):\n" +msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:215 -msgid "facets added" -msgstr "facets added" +msgid "degenerate facets" +msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:216 -msgid "facets reversed" -msgstr "facets reversed" +msgid "edges fixed" +msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:217 +msgid "facets removed" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:218 +msgid "facets added" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:219 +msgid "facets reversed" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:220 msgid "backwards edges" -msgstr "backwards edges" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:231 +#: src/slic3r/GUI/GUI_ObjectList.cpp:234 msgid "Right button click the icon to fix STL through Netfabb" -msgstr "Right button click the icon to fix STL through Netfabb" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:278 src/slic3r/GUI/Tab.cpp:1430 +#: src/slic3r/GUI/GUI_ObjectList.cpp:281 src/slic3r/GUI/Tab.cpp:1430 #: src/libslic3r/PrintConfig.cpp:454 msgid "Extruder" -msgstr "Extruder" +msgstr "Extrudeur" -#: src/slic3r/GUI/GUI_ObjectList.cpp:683 src/slic3r/GUI/GUI_ObjectList.cpp:963 -#: src/slic3r/GUI/GUI_ObjectList.cpp:969 src/slic3r/GUI/GUI_ObjectList.cpp:1199 +#: src/slic3r/GUI/GUI_ObjectList.cpp:751 src/slic3r/GUI/GUI_ObjectList.cpp:1031 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1037 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1267 #, c-format msgid "Quick Add Settings (%s)" -msgstr "Quick Add Settings (%s)" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:746 +#: src/slic3r/GUI/GUI_ObjectList.cpp:814 msgid "Select showing settings" -msgstr "Select showing settings" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:874 -msgid "Load" -msgstr "Load" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 src/slic3r/GUI/GUI_ObjectList.cpp:911 -#: src/slic3r/GUI/GUI_ObjectList.cpp:914 -msgid "Box" -msgstr "Box" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Cylinder" -msgstr "Cylinder" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Sphere" -msgstr "Sphere" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:879 -msgid "Slab" -msgstr "Slab" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:890 src/slic3r/GUI/GUI_ObjectList.cpp:906 -msgid "Add part" -msgstr "Add part" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:891 -msgid "Add modifier" -msgstr "Add modifier" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:892 src/slic3r/GUI/GUI_ObjectList.cpp:910 -msgid "Add support enforcer" -msgstr "Add support enforcer" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:893 src/slic3r/GUI/GUI_ObjectList.cpp:913 -msgid "Add support blocker" -msgstr "Add support blocker" - -#: src/slic3r/GUI/GUI_ObjectList.cpp:934 -msgid "Split to parts" -msgstr "Split to parts" +msgstr "" #: src/slic3r/GUI/GUI_ObjectList.cpp:942 +msgid "Load" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:947 src/slic3r/GUI/GUI_ObjectList.cpp:979 +#: src/slic3r/GUI/GUI_ObjectList.cpp:982 +msgid "Box" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:947 +msgid "Cylinder" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:947 +msgid "Sphere" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:947 +msgid "Slab" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:958 src/slic3r/GUI/GUI_ObjectList.cpp:974 +msgid "Add part" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:959 +msgid "Add modifier" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:960 src/slic3r/GUI/GUI_ObjectList.cpp:978 +msgid "Add support enforcer" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:961 src/slic3r/GUI/GUI_ObjectList.cpp:981 +msgid "Add support blocker" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1002 +msgid "Split to parts" +msgstr "" + +#: src/slic3r/GUI/GUI_ObjectList.cpp:1010 msgid "Add settings" -msgstr "Add settings" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1009 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1077 msgid "Change type" -msgstr "Change type" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1016 -#: src/slic3r/GUI/GUI_ObjectList.cpp:1153 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1084 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1221 msgid "Set as a Separated Object" -msgstr "Set as a Separated Object" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1024 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1092 msgid "Rename" -msgstr "Rename" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1034 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1102 msgid "Fix through the Netfabb" -msgstr "Fix through the Netfabb" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1041 src/slic3r/GUI/Plater.cpp:2861 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1109 src/slic3r/GUI/Plater.cpp:2883 msgid "Export as STL" -msgstr "Export as STL" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1048 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1116 msgid "Change extruder" -msgstr "Change extruder" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1073 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1141 msgid "Select new extruder for the object/part" -msgstr "Select new extruder for the object/part" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1079 src/slic3r/GUI/Plater.cpp:2825 -#: src/slic3r/GUI/Plater.cpp:2843 src/slic3r/GUI/Tab.cpp:2860 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1147 src/slic3r/GUI/Plater.cpp:2847 +#: src/slic3r/GUI/Plater.cpp:2865 src/slic3r/GUI/Tab.cpp:2861 msgid "Delete" -msgstr "Delete" +msgstr "Supprimer" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1153 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1221 msgid "Set as a Separated Objects" -msgstr "Set as a Separated Objects" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1374 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1442 msgid "Generic" -msgstr "Generic" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1516 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1582 msgid "You can't delete the last solid part from object." -msgstr "You can't delete the last solid part from object." +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1533 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1599 msgid "You can't delete the last intance from object." -msgstr "You can't delete the last intance from object." +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1560 src/slic3r/GUI/Plater.cpp:2219 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1626 src/slic3r/GUI/Plater.cpp:2235 msgid "" "The selected object couldn't be split because it contains only one part." msgstr "" -"The selected object couldn't be split because it contains only one part." +"L'objet sélectionné n'a pu être scindé car il ne contient qu'une seule pièce." -#: src/slic3r/GUI/GUI_ObjectList.cpp:1676 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1742 msgid "Group manipulation" -msgstr "Group manipulation" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1688 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1754 msgid "Object manipulation" -msgstr "Object manipulation" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1698 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1764 msgid "Object Settings to modify" -msgstr "Object Settings to modify" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1702 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1768 msgid "Part Settings to modify" -msgstr "Part Settings to modify" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1711 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1777 msgid "Part manipulation" -msgstr "Part manipulation" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:1717 +#: src/slic3r/GUI/GUI_ObjectList.cpp:1783 msgid "Instance manipulation" -msgstr "Instance manipulation" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2240 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2307 msgid "Object or Instance" -msgstr "Object or Instance" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2240 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2307 msgid "Part" -msgstr "Part" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2242 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2309 msgid "Unsupported selection" -msgstr "Unsupported selection" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2243 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2310 #, c-format msgid "You started your selection with %s Item." -msgstr "You started your selection with %s Item." +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2244 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2311 #, c-format msgid "In this mode you can select only other %s Items%s" -msgstr "In this mode you can select only other %s Items%s" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2247 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2314 msgid "of a current Object" -msgstr "of a current Object" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2252 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2325 src/slic3r/GUI/Plater.cpp:117 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2319 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2392 src/slic3r/GUI/Plater.cpp:117 msgid "Info" msgstr "Info" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2366 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2433 msgid "You can't change a type of the last solid part of the object." -msgstr "You can't change a type of the last solid part of the object." +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2373 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2440 msgid "Select type of part" -msgstr "Select type of part" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2538 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2605 msgid "Enter new name" -msgstr "Enter new name" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2538 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2605 msgid "Renaming" -msgstr "Renaming" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2554 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2632 src/slic3r/GUI/Tab.cpp:3191 -#: src/slic3r/GUI/Tab.cpp:3195 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2621 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2699 src/slic3r/GUI/Tab.cpp:3192 +#: src/slic3r/GUI/Tab.cpp:3196 msgid "The supplied name is not valid;" msgstr "The supplied name is not valid;" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2555 -#: src/slic3r/GUI/GUI_ObjectList.cpp:2633 src/slic3r/GUI/Tab.cpp:3192 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2622 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2700 src/slic3r/GUI/Tab.cpp:3193 msgid "the following characters are not allowed:" msgstr "the following characters are not allowed:" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2653 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2720 msgid "Set extruder for selected items" -msgstr "Set extruder for selected items" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2654 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2721 msgid "Select extruder number for selected objects and/or parts" -msgstr "Select extruder number for selected objects and/or parts" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2667 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2734 msgid "Select extruder number:" -msgstr "Select extruder number:" +msgstr "" -#: src/slic3r/GUI/GUI_ObjectList.cpp:2668 +#: src/slic3r/GUI/GUI_ObjectList.cpp:2735 msgid "This extruder will be set for selected items" -msgstr "This extruder will be set for selected items" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:25 msgid "Object Manipulation" -msgstr "Object Manipulation" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:47 msgid "Object name" -msgstr "Object name" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:115 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:160 msgid "Position" -msgstr "Position" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:116 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:161 msgid "Rotation" -msgstr "Rotation" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:117 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:201 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:221 -#: src/libslic3r/PrintConfig.cpp:3070 +#: src/libslic3r/PrintConfig.cpp:3075 msgid "Scale" -msgstr "Scale" +msgstr "Redimensionner" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:162 msgid "Scale factors" -msgstr "Scale factors" +msgstr "" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:200 #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:220 -#: src/libslic3r/PrintConfig.cpp:3055 +#: src/libslic3r/PrintConfig.cpp:3060 msgid "Rotate" -msgstr "Rotate" +msgstr "Pivoter" #: src/slic3r/GUI/GUI_ObjectManipulation.cpp:219 msgid "Translate" -msgstr "Translate" +msgstr "" #: src/slic3r/GUI/GUI_ObjectSettings.cpp:58 msgid "Additional Settings" -msgstr "Additional Settings" +msgstr "" #: src/slic3r/GUI/GUI_Preview.cpp:209 msgid "View" -msgstr "View" +msgstr "Vue" #: src/slic3r/GUI/GUI_Preview.cpp:212 src/slic3r/GUI/GUI_Preview.cpp:525 #: src/libslic3r/GCode/PreviewData.cpp:394 msgid "Feature type" -msgstr "Feature type" +msgstr "Type de fonctionnalité" #: src/slic3r/GUI/GUI_Preview.cpp:213 src/libslic3r/PrintConfig.cpp:467 msgid "Height" -msgstr "Height" +msgstr "Hauteur" #: src/slic3r/GUI/GUI_Preview.cpp:214 src/libslic3r/PrintConfig.cpp:2135 msgid "Width" -msgstr "Width" +msgstr "Largeur" #: src/slic3r/GUI/GUI_Preview.cpp:216 msgid "Volumetric flow rate" -msgstr "Volumetric flow rate" +msgstr "Débit volumétrique" #: src/slic3r/GUI/GUI_Preview.cpp:217 src/slic3r/GUI/GUI_Preview.cpp:315 #: src/slic3r/GUI/GUI_Preview.cpp:469 src/slic3r/GUI/GUI_Preview.cpp:525 #: src/slic3r/GUI/GUI_Preview.cpp:701 src/libslic3r/GCode/PreviewData.cpp:404 msgid "Tool" -msgstr "Tool" +msgstr "Outil" #: src/slic3r/GUI/GUI_Preview.cpp:218 src/slic3r/GUI/GUI_Preview.cpp:523 #: src/libslic3r/GCode/PreviewData.cpp:406 msgid "Color Print" -msgstr "Color Print" +msgstr "" #: src/slic3r/GUI/GUI_Preview.cpp:221 msgid "Show" -msgstr "Show" +msgstr "Afficher" #: src/slic3r/GUI/GUI_Preview.cpp:224 src/slic3r/GUI/GUI_Preview.cpp:225 msgid "Feature types" -msgstr "Feature types" +msgstr "Types de fonctionnalité" #: src/slic3r/GUI/GUI_Preview.cpp:227 src/libslic3r/GCode/PreviewData.cpp:163 msgid "Perimeter" -msgstr "Perimeter" +msgstr "Périmètre" #: src/slic3r/GUI/GUI_Preview.cpp:228 src/libslic3r/GCode/PreviewData.cpp:164 msgid "External perimeter" -msgstr "External perimeter" +msgstr "Périmètre externe" #: src/slic3r/GUI/GUI_Preview.cpp:229 src/libslic3r/GCode/PreviewData.cpp:165 msgid "Overhang perimeter" -msgstr "Overhang perimeter" +msgstr "Périmètre en surplomb" #: src/slic3r/GUI/GUI_Preview.cpp:230 src/libslic3r/GCode/PreviewData.cpp:166 msgid "Internal infill" -msgstr "Internal infill" +msgstr "Remplissage interne" #: src/slic3r/GUI/GUI_Preview.cpp:231 src/libslic3r/PrintConfig.cpp:1686 #: src/libslic3r/PrintConfig.cpp:1696 src/libslic3r/GCode/PreviewData.cpp:167 msgid "Solid infill" -msgstr "Solid infill" +msgstr "Remplissage solide" #: src/slic3r/GUI/GUI_Preview.cpp:232 src/libslic3r/PrintConfig.cpp:2016 #: src/libslic3r/PrintConfig.cpp:2027 src/libslic3r/GCode/PreviewData.cpp:168 msgid "Top solid infill" -msgstr "Top solid infill" +msgstr "Remplissage solide supérieur" #: src/slic3r/GUI/GUI_Preview.cpp:233 src/libslic3r/GCode/PreviewData.cpp:169 msgid "Bridge infill" -msgstr "Bridge infill" +msgstr "Remplissage du pont" #: src/slic3r/GUI/GUI_Preview.cpp:234 src/libslic3r/PrintConfig.cpp:869 #: src/libslic3r/GCode/PreviewData.cpp:170 msgid "Gap fill" -msgstr "Gap fill" +msgstr "Remplissage des trous" #: src/slic3r/GUI/GUI_Preview.cpp:235 src/slic3r/GUI/Tab.cpp:1001 #: src/libslic3r/GCode/PreviewData.cpp:171 msgid "Skirt" -msgstr "Skirt" +msgstr "Jupe" #: src/slic3r/GUI/GUI_Preview.cpp:237 src/libslic3r/PrintConfig.cpp:1903 #: src/libslic3r/GCode/PreviewData.cpp:173 msgid "Support material interface" -msgstr "Support material interface" +msgstr "Interface des supports" #: src/slic3r/GUI/GUI_Preview.cpp:238 src/slic3r/GUI/Tab.cpp:1081 #: src/libslic3r/GCode/PreviewData.cpp:174 msgid "Wipe tower" -msgstr "Wipe tower" +msgstr "Tour de nettoyage" #: src/slic3r/GUI/GUI_Preview.cpp:243 src/libslic3r/PrintConfig.cpp:2049 msgid "Travel" -msgstr "Travel" +msgstr "Déplacement" #: src/slic3r/GUI/GUI_Preview.cpp:244 msgid "Retractions" -msgstr "Retractions" +msgstr "Rétractations" #: src/slic3r/GUI/GUI_Preview.cpp:245 msgid "Unretractions" -msgstr "Unretractions" +msgstr "Dérétractation" #: src/slic3r/GUI/GUI_Preview.cpp:246 msgid "Shells" -msgstr "Shells" +msgstr "Coques" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:13 -msgid "Slic3r Prusa Edition - Keyboard Shortcuts" -msgstr "Slic3r Prusa Edition - Keyboard Shortcuts" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:13 src/slic3r/GUI/MainFrame.cpp:491 +msgid "Keyboard Shortcuts" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:100 msgid "Open project STL/OBJ/AMF/3MF with config, delete bed" -msgstr "Open project STL/OBJ/AMF/3MF with config, delete bed" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:101 msgid "Import STL/OBJ/AMF/3MF without config, keep bed" -msgstr "Import STL/OBJ/AMF/3MF without config, keep bed" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:102 msgid "Load Config from .ini/amf/3mf/gcode" -msgstr "Load Config from .ini/amf/3mf/gcode" +msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:103 src/slic3r/GUI/Plater.cpp:725 -#: src/slic3r/GUI/Plater.cpp:3673 src/libslic3r/PrintConfig.cpp:2957 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:103 src/slic3r/GUI/Plater.cpp:724 +#: src/slic3r/GUI/Plater.cpp:3704 src/libslic3r/PrintConfig.cpp:2962 msgid "Export G-code" -msgstr "Export G-code" +msgstr "Exporter le G-code" #: src/slic3r/GUI/KBShortcutsDialog.cpp:104 msgid "Save project (3MF)" -msgstr "Save project (3MF)" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:105 msgid "Load Config from .ini/amf/3mf/gcode and merge" -msgstr "Load Config from .ini/amf/3mf/gcode and merge" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:106 msgid "(Re)slice" -msgstr "(Re)slice" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:107 msgid "Quick slice" -msgstr "Quick slice" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:108 src/slic3r/GUI/MainFrame.cpp:326 msgid "Repeat last quick slice" -msgstr "Repeat last quick slice" +msgstr "Répéter le dernier découpage rapide" #: src/slic3r/GUI/KBShortcutsDialog.cpp:109 msgid "Select Plater Tab" -msgstr "Select Plater Tab" +msgstr "Sélectionner l'Onglet du Plateau" #: src/slic3r/GUI/KBShortcutsDialog.cpp:110 msgid "Quick slice and Save as" -msgstr "Quick slice and Save as" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:111 msgid "Select Print Settings Tab" -msgstr "Select Print Settings Tab" +msgstr "Sélectionner l'Onglet des Réglages d'Impression" #: src/slic3r/GUI/KBShortcutsDialog.cpp:112 msgid "Select Filament Settings Tab" -msgstr "Select Filament Settings Tab" +msgstr "Sélectionner l'Onglet des Réglages du Filament" #: src/slic3r/GUI/KBShortcutsDialog.cpp:113 msgid "Select Printer Settings Tab" -msgstr "Select Printer Settings Tab" +msgstr "Sélectionner l'Onglet des Réglages de l'Imprimante" #: src/slic3r/GUI/KBShortcutsDialog.cpp:114 msgid "Switch to 3D" -msgstr "Switch to 3D" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:115 msgid "Switch to Preview" -msgstr "Switch to Preview" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:116 src/slic3r/GUI/Preferences.cpp:10 msgid "Preferences" -msgstr "Preferences" +msgstr "Préférences" #: src/slic3r/GUI/KBShortcutsDialog.cpp:117 #: src/slic3r/GUI/PrintHostDialogs.cpp:134 msgid "Print host upload queue" -msgstr "Print host upload queue" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:118 msgid "Camera view " -msgstr "Camera view " +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:119 msgid "Add Instance to selected object " -msgstr "Add Instance to selected object " +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:120 msgid "Remove Instance from selected object" -msgstr "Remove Instance from selected object" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:121 msgid "Show keyboard shortcuts list" -msgstr "Show keyboard shortcuts list" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:122 msgid "Select multiple object/Move multiple object" -msgstr "Select multiple object/Move multiple object" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:124 msgid "Main Shortcuts" -msgstr "Main Shortcuts" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:130 msgid "Arrange" -msgstr "Arrange" +msgstr "Agencer" #: src/slic3r/GUI/KBShortcutsDialog.cpp:131 msgid "Select All objects" -msgstr "Select All objects" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:132 msgid "Delete selected" -msgstr "Delete selected" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:133 msgid "Delete All" -msgstr "Delete All" +msgstr "Tout Supprimer" #: src/slic3r/GUI/KBShortcutsDialog.cpp:134 -msgid "Gizmo move" -msgstr "Gizmo move" +msgid "Copy to clipboard" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:135 -msgid "Gizmo scale" -msgstr "Gizmo scale" +msgid "Paste from clipboard" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:136 -msgid "Gizmo rotate" -msgstr "Gizmo rotate" +msgid "Gizmo move" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:137 -msgid "Gizmo cut" -msgstr "Gizmo cut" +msgid "Gizmo scale" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:138 -msgid "Gizmo Place face on bed" -msgstr "Gizmo Place face on bed" +msgid "Gizmo rotate" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:139 -msgid "Gizmo SLA support points" -msgstr "Gizmo SLA support points" +msgid "Gizmo cut" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:140 -#, no-c-format -msgid "" -"Press to snap by 5% in Gizmo scale\n" -"or by 1mm in Gizmo move" +msgid "Gizmo Place face on bed" msgstr "" -"Press to snap by 5% in Gizmo scale\n" -"or by 1mm in Gizmo move" #: src/slic3r/GUI/KBShortcutsDialog.cpp:141 +msgid "Gizmo SLA support points" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:142 +#, c-format +msgid "" +"Press to snap by 5% in Gizmo scale\n" +"or by 1mm in Gizmo move" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:143 msgid "" "Press to scale or rotate selected objects\n" "around their own center" msgstr "" -"Press to scale or rotate selected objects\n" -"around their own center" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:142 -msgid "Zoom to Bed" -msgstr "Zoom to Bed" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:143 -msgid "Zoom to all objects in scene, if none selected" -msgstr "Zoom to all objects in scene, if none selected" #: src/slic3r/GUI/KBShortcutsDialog.cpp:144 -msgid "Zoom to selected object" -msgstr "Zoom to selected object" +msgid "Zoom to Bed" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:145 -msgid "Zoom in" -msgstr "Zoom in" +msgid "Zoom to all objects in scene, if none selected" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:146 -msgid "Zoom out" -msgstr "Zoom out" +msgid "Zoom to selected object" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:147 -msgid "Unselect gizmo, keep object selection" -msgstr "Unselect gizmo, keep object selection" +msgid "Zoom in" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:148 +msgid "Zoom out" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:149 +msgid "Unselect gizmo, keep object selection" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:151 msgid "Plater Shortcuts" -msgstr "Plater Shortcuts" +msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:164 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:175 -msgid "Arrow Up" -msgstr "Arrow Up" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:164 #: src/slic3r/GUI/KBShortcutsDialog.cpp:166 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:177 +msgid "Arrow Up" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:166 +#: src/slic3r/GUI/KBShortcutsDialog.cpp:168 msgid "Upper Layer" -msgstr "Upper Layer" +msgstr "" -#: src/slic3r/GUI/KBShortcutsDialog.cpp:165 -#: src/slic3r/GUI/KBShortcutsDialog.cpp:176 -msgid "Arrow Down" -msgstr "Arrow Down" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:165 #: src/slic3r/GUI/KBShortcutsDialog.cpp:167 -msgid "Lower Layer" -msgstr "Lower Layer" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:178 +msgid "Arrow Down" +msgstr "" +#: src/slic3r/GUI/KBShortcutsDialog.cpp:167 #: src/slic3r/GUI/KBShortcutsDialog.cpp:169 +msgid "Lower Layer" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:171 msgid "Preview Shortcuts" -msgstr "Preview Shortcuts" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:175 -msgid "Move current slider thump Up" -msgstr "Move current slider thump Up" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:176 -msgid "Move current slider thump Down" -msgstr "Move current slider thump Down" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:177 -msgid "Arrow Left" -msgstr "Arrow Left" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:177 -msgid "Set upper thumb to current slider thumb" -msgstr "Set upper thumb to current slider thumb" +msgid "Move current slider thumb Up" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:178 -msgid "Arrow Right" -msgstr "Arrow Right" - -#: src/slic3r/GUI/KBShortcutsDialog.cpp:178 -msgid "Set lower thumb to current slider thumb" -msgstr "Set lower thumb to current slider thumb" +msgid "Move current slider thumb Down" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:179 -msgid "Add color change marker for current layer" -msgstr "Add color change marker for current layer" +msgid "Arrow Left" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:179 +msgid "Set upper thumb to current slider thumb" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:180 -msgid "Delete color change marker for current layer" -msgstr "Delete color change marker for current layer" +msgid "Arrow Right" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:180 +msgid "Set lower thumb to current slider thumb" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:181 +msgid "Add color change marker for current layer" +msgstr "" #: src/slic3r/GUI/KBShortcutsDialog.cpp:182 +msgid "Delete color change marker for current layer" +msgstr "" + +#: src/slic3r/GUI/KBShortcutsDialog.cpp:184 msgid "Layers Slider Shortcuts" -msgstr "Layers Slider Shortcuts" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:54 msgid "" " - Remember to check for updates at http://github.com/prusa3d/slic3r/releases" msgstr "" -" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases" +" - Pensez à vérifier les mises à jours sur http://github.com/prusa3d/slic3r/" +"releases" #: src/slic3r/GUI/MainFrame.cpp:160 msgid "Plater" -msgstr "Plater" +msgstr "Plateau" #: src/slic3r/GUI/MainFrame.cpp:273 msgid "&Open Project" -msgstr "&Open Project" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:273 msgid "Open a project file" -msgstr "Open a project file" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:275 msgid "&Save Project" -msgstr "&Save Project" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:275 msgid "Save current project file" -msgstr "Save current project file" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:277 msgid "Save Project &as" -msgstr "Save Project &as" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:277 msgid "Save current project file as" -msgstr "Save current project file as" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:283 msgid "Import STL/OBJ/AM&F/3MF" -msgstr "Import STL/OBJ/AM&F/3MF" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:283 msgid "Load a model" -msgstr "Load a model" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:286 msgid "Import &Config" -msgstr "Import &Config" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:286 msgid "Load exported configuration file" -msgstr "Load exported configuration file" +msgstr "Charger le fichier de configuration exporté" #: src/slic3r/GUI/MainFrame.cpp:288 msgid "Import Config from &project" -msgstr "Import Config from &project" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:288 msgid "Load configuration from project file" -msgstr "Load configuration from project file" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:291 msgid "Import Config &Bundle" -msgstr "Import Config &Bundle" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:291 msgid "Load presets from a bundle" -msgstr "Load presets from a bundle" +msgstr "Charger les préréglages à partir d'un lot" #: src/slic3r/GUI/MainFrame.cpp:293 msgid "&Import" -msgstr "&Import" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:296 msgid "Export &G-code" -msgstr "Export &G-code" +msgstr "Exporter le &G-code" #: src/slic3r/GUI/MainFrame.cpp:296 msgid "Export current plate as G-code" -msgstr "Export current plate as G-code" +msgstr "Exporter le plateau courant en G-code" #: src/slic3r/GUI/MainFrame.cpp:299 msgid "Export plate as &STL" -msgstr "Export plate as &STL" +msgstr "Exporter le plateau en &STL" #: src/slic3r/GUI/MainFrame.cpp:299 msgid "Export current plate as STL" -msgstr "Export current plate as STL" +msgstr "Exporter le plateau courant en STL" #: src/slic3r/GUI/MainFrame.cpp:301 msgid "Export plate as &AMF" -msgstr "Export plate as &AMF" +msgstr "Exporter le plateau en &AMF" #: src/slic3r/GUI/MainFrame.cpp:301 msgid "Export current plate as AMF" -msgstr "Export current plate as AMF" +msgstr "Exporter le plateau courant en AMF" #: src/slic3r/GUI/MainFrame.cpp:304 msgid "Export &Config" -msgstr "Export &Config" +msgstr "Exporter la &configuration" #: src/slic3r/GUI/MainFrame.cpp:304 msgid "Export current configuration to file" -msgstr "Export current configuration to file" +msgstr "Exporter la configuration actuelle vers un fichier" #: src/slic3r/GUI/MainFrame.cpp:306 msgid "Export Config &Bundle" -msgstr "Export Config &Bundle" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:306 msgid "Export all presets to file" -msgstr "Export all presets to file" +msgstr "Exporter tous les préréglage vers un fichier" #: src/slic3r/GUI/MainFrame.cpp:308 msgid "&Export" -msgstr "&Export" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:314 msgid "Quick Slice" -msgstr "Quick Slice" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:314 msgid "Slice a file into a G-code" -msgstr "Slice a file into a G-code" +msgstr "Découper un fichier en G-code" #: src/slic3r/GUI/MainFrame.cpp:320 msgid "Quick Slice and Save As" -msgstr "Quick Slice and Save As" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:320 msgid "Slice a file into a G-code, save as" -msgstr "Slice a file into a G-code, save as" +msgstr "Découper un fichier en G-code, enregistrer sous" #: src/slic3r/GUI/MainFrame.cpp:326 msgid "Repeat Last Quick Slice" -msgstr "Repeat Last Quick Slice" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:334 msgid "(Re)Slice &Now" -msgstr "(Re)Slice &Now" +msgstr "(Re)Découper mai&ntenant" #: src/slic3r/GUI/MainFrame.cpp:334 msgid "Start new slicing process" -msgstr "Start new slicing process" +msgstr "Démarrer un nouveau processus de découpe" #: src/slic3r/GUI/MainFrame.cpp:337 msgid "&Repair STL file" -msgstr "&Repair STL file" +msgstr "&Réparer le fichier STL" #: src/slic3r/GUI/MainFrame.cpp:337 msgid "Automatically repair an STL file" -msgstr "Automatically repair an STL file" +msgstr "Réparer automatiquement un fichier STL" #: src/slic3r/GUI/MainFrame.cpp:340 msgid "&Quit" -msgstr "&Quit" +msgstr "&Quitter" #: src/slic3r/GUI/MainFrame.cpp:340 msgid "Quit Slic3r" -msgstr "Quit Slic3r" +msgstr "Quitter Slic3r" #: src/slic3r/GUI/MainFrame.cpp:374 msgid "&Select all" -msgstr "&Select all" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:374 msgid "Selects all objects" -msgstr "Selects all objects" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:377 msgid "&Delete selected" -msgstr "&Delete selected" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:377 msgid "Deletes the current selection" -msgstr "Deletes the current selection" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:379 msgid "Delete &all" -msgstr "Delete &all" +msgstr "" #: src/slic3r/GUI/MainFrame.cpp:379 msgid "Deletes all objects" -msgstr "Deletes all objects" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:392 +#: src/slic3r/GUI/MainFrame.cpp:384 +msgid "&Copy" +msgstr "" + +#: src/slic3r/GUI/MainFrame.cpp:384 +msgid "Copy selection to clipboard" +msgstr "" + +#: src/slic3r/GUI/MainFrame.cpp:386 +msgid "&Paste" +msgstr "" + +#: src/slic3r/GUI/MainFrame.cpp:386 +msgid "Paste clipboard" +msgstr "" + +#: src/slic3r/GUI/MainFrame.cpp:401 msgid "&Plater Tab" -msgstr "&Plater Tab" +msgstr "L'Onglet du &Plateau" -#: src/slic3r/GUI/MainFrame.cpp:392 +#: src/slic3r/GUI/MainFrame.cpp:401 msgid "Show the plater" -msgstr "Show the plater" +msgstr "Afficher le plateau" -#: src/slic3r/GUI/MainFrame.cpp:399 +#: src/slic3r/GUI/MainFrame.cpp:408 msgid "P&rint Settings Tab" -msgstr "P&rint Settings Tab" +msgstr "L'Onglet des Réglages d'&Impression" -#: src/slic3r/GUI/MainFrame.cpp:399 +#: src/slic3r/GUI/MainFrame.cpp:408 msgid "Show the print settings" -msgstr "Show the print settings" +msgstr "Afficher les réglages d'impression" -#: src/slic3r/GUI/MainFrame.cpp:401 +#: src/slic3r/GUI/MainFrame.cpp:410 msgid "&Filament Settings Tab" -msgstr "&Filament Settings Tab" +msgstr "L'Onglet des Réglages du &Filament" -#: src/slic3r/GUI/MainFrame.cpp:401 +#: src/slic3r/GUI/MainFrame.cpp:410 msgid "Show the filament settings" -msgstr "Show the filament settings" +msgstr "Afficher les réglages de filament" -#: src/slic3r/GUI/MainFrame.cpp:403 +#: src/slic3r/GUI/MainFrame.cpp:412 msgid "Print&er Settings Tab" -msgstr "Print&er Settings Tab" +msgstr "L'Onglet des Réglages de l'Impri&mante" -#: src/slic3r/GUI/MainFrame.cpp:403 +#: src/slic3r/GUI/MainFrame.cpp:412 msgid "Show the printer settings" -msgstr "Show the printer settings" +msgstr "Afficher les réglages de l'imprimante" -#: src/slic3r/GUI/MainFrame.cpp:407 +#: src/slic3r/GUI/MainFrame.cpp:416 msgid "3&D" -msgstr "3&D" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:407 +#: src/slic3r/GUI/MainFrame.cpp:416 msgid "Show the 3D editing view" -msgstr "Show the 3D editing view" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:409 +#: src/slic3r/GUI/MainFrame.cpp:418 msgid "Pre&view" -msgstr "Pre&view" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:409 +#: src/slic3r/GUI/MainFrame.cpp:418 msgid "Show the 3D slices preview" -msgstr "Show the 3D slices preview" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:430 +#: src/slic3r/GUI/MainFrame.cpp:439 msgid "Print &Host Upload Queue" -msgstr "Print &Host Upload Queue" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:430 +#: src/slic3r/GUI/MainFrame.cpp:439 msgid "Display the Print Host Upload Queue window" -msgstr "Display the Print Host Upload Queue window" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:439 +#: src/slic3r/GUI/MainFrame.cpp:448 msgid "Iso" -msgstr "Iso" +msgstr "Isométrique" -#: src/slic3r/GUI/MainFrame.cpp:439 +#: src/slic3r/GUI/MainFrame.cpp:448 msgid "Iso View" -msgstr "Iso View" +msgstr "Vue Isométrique" -#: src/slic3r/GUI/MainFrame.cpp:441 +#: src/slic3r/GUI/MainFrame.cpp:450 msgid "Top" -msgstr "Top" +msgstr "du Dessus" #: src/libslic3r/PrintConfig.cpp:2041 msgctxt "Layers" msgid "Top" -msgstr "Top" +msgstr "Haut" -#: src/slic3r/GUI/MainFrame.cpp:441 +#: src/slic3r/GUI/MainFrame.cpp:450 msgid "Top View" -msgstr "Top View" +msgstr "Vue du Dessus" -#: src/slic3r/GUI/MainFrame.cpp:442 +#: src/slic3r/GUI/MainFrame.cpp:451 msgid "Bottom" -msgstr "Bottom" +msgstr "du Dessous" #: src/libslic3r/PrintConfig.cpp:148 msgctxt "Layers" msgid "Bottom" -msgstr "Bottom" +msgstr "Dessous" -#: src/slic3r/GUI/MainFrame.cpp:442 +#: src/slic3r/GUI/MainFrame.cpp:451 msgid "Bottom View" -msgstr "Bottom View" +msgstr "Vue du Dessous" -#: src/slic3r/GUI/MainFrame.cpp:443 +#: src/slic3r/GUI/MainFrame.cpp:452 msgid "Front" -msgstr "Front" +msgstr "Avant" -#: src/slic3r/GUI/MainFrame.cpp:443 +#: src/slic3r/GUI/MainFrame.cpp:452 msgid "Front View" -msgstr "Front View" +msgstr "Vue Avant" -#: src/slic3r/GUI/MainFrame.cpp:444 src/libslic3r/PrintConfig.cpp:1561 +#: src/slic3r/GUI/MainFrame.cpp:453 src/libslic3r/PrintConfig.cpp:1561 msgid "Rear" -msgstr "Rear" +msgstr "Arrière" -#: src/slic3r/GUI/MainFrame.cpp:444 +#: src/slic3r/GUI/MainFrame.cpp:453 msgid "Rear View" -msgstr "Rear View" +msgstr "Vue Arrière" -#: src/slic3r/GUI/MainFrame.cpp:445 +#: src/slic3r/GUI/MainFrame.cpp:454 msgid "Left" -msgstr "Left" +msgstr "Gauche" -#: src/slic3r/GUI/MainFrame.cpp:445 +#: src/slic3r/GUI/MainFrame.cpp:454 msgid "Left View" -msgstr "Left View" +msgstr "Vue Gauche" -#: src/slic3r/GUI/MainFrame.cpp:446 +#: src/slic3r/GUI/MainFrame.cpp:455 msgid "Right" -msgstr "Right" +msgstr "Droite" -#: src/slic3r/GUI/MainFrame.cpp:446 +#: src/slic3r/GUI/MainFrame.cpp:455 msgid "Right View" -msgstr "Right View" +msgstr "Vue Droite" -#: src/slic3r/GUI/MainFrame.cpp:460 +#: src/slic3r/GUI/MainFrame.cpp:469 msgid "Prusa 3D &Drivers" -msgstr "Prusa 3D &Drivers" +msgstr "&Drivers Prusa 3D" -#: src/slic3r/GUI/MainFrame.cpp:460 +#: src/slic3r/GUI/MainFrame.cpp:469 msgid "Open the Prusa3D drivers download page in your browser" -msgstr "Open the Prusa3D drivers download page in your browser" +msgstr "" +"Ouvrir la page de téléchargement des drivers Prusa3D dans votre navigateur" -#: src/slic3r/GUI/MainFrame.cpp:462 +#: src/slic3r/GUI/MainFrame.cpp:471 msgid "Prusa Edition &Releases" -msgstr "Prusa Edition &Releases" +msgstr "&Publication de la Prusa Edition" -#: src/slic3r/GUI/MainFrame.cpp:462 +#: src/slic3r/GUI/MainFrame.cpp:471 msgid "Open the Prusa Edition releases page in your browser" -msgstr "Open the Prusa Edition releases page in your browser" +msgstr "" +"Ouvrir la page des publications de la Prusa Edition dans votre navigateur" -#: src/slic3r/GUI/MainFrame.cpp:468 +#: src/slic3r/GUI/MainFrame.cpp:477 msgid "Slic3r &Website" -msgstr "Slic3r &Website" +msgstr "Site &Web de Slic3r" -#: src/slic3r/GUI/MainFrame.cpp:468 +#: src/slic3r/GUI/MainFrame.cpp:477 msgid "Open the Slic3r website in your browser" -msgstr "Open the Slic3r website in your browser" +msgstr "Ouvrir le site web de Slic3r dans votre navigateur" -#: src/slic3r/GUI/MainFrame.cpp:470 +#: src/slic3r/GUI/MainFrame.cpp:479 msgid "Slic3r &Manual" -msgstr "Slic3r &Manual" +msgstr "&Manuel de Slic3r" -#: src/slic3r/GUI/MainFrame.cpp:470 +#: src/slic3r/GUI/MainFrame.cpp:479 msgid "Open the Slic3r manual in your browser" -msgstr "Open the Slic3r manual in your browser" +msgstr "Ouvrir la manuel de Slic3r dans votre navigateur" -#: src/slic3r/GUI/MainFrame.cpp:473 +#: src/slic3r/GUI/MainFrame.cpp:482 msgid "System &Info" -msgstr "System &Info" +msgstr "&Informations sur le Système" -#: src/slic3r/GUI/MainFrame.cpp:473 +#: src/slic3r/GUI/MainFrame.cpp:482 msgid "Show system information" -msgstr "Show system information" +msgstr "Afficher les informations système" -#: src/slic3r/GUI/MainFrame.cpp:475 +#: src/slic3r/GUI/MainFrame.cpp:484 msgid "Show &Configuration Folder" -msgstr "Show &Configuration Folder" +msgstr "Afficher le Répertoire de &Configuration" -#: src/slic3r/GUI/MainFrame.cpp:475 +#: src/slic3r/GUI/MainFrame.cpp:484 msgid "Show user configuration folder (datadir)" -msgstr "Show user configuration folder (datadir)" +msgstr "Afficher le répertoire de configuration utilisateur (datadir)" -#: src/slic3r/GUI/MainFrame.cpp:477 +#: src/slic3r/GUI/MainFrame.cpp:486 msgid "Report an I&ssue" -msgstr "Report an I&ssue" +msgstr "Signaler un p&roblème" -#: src/slic3r/GUI/MainFrame.cpp:477 -msgid "Report an issue on the Slic3r Prusa Edition" -msgstr "Report an issue on the Slic3r Prusa Edition" +#: src/slic3r/GUI/MainFrame.cpp:486 +#, c-format +msgid "Report an issue on %s" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:479 -msgid "&About Slic3r" -msgstr "&About Slic3r" +#: src/slic3r/GUI/MainFrame.cpp:488 +#, c-format +msgid "&About %s" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:479 +#: src/slic3r/GUI/MainFrame.cpp:488 msgid "Show about dialog" -msgstr "Show about dialog" - -#: src/slic3r/GUI/MainFrame.cpp:482 -msgid "Keyboard Shortcuts" -msgstr "Keyboard Shortcuts" - -#: src/slic3r/GUI/MainFrame.cpp:482 -msgid "Show the list of the keyboard shortcuts" -msgstr "Show the list of the keyboard shortcuts" - -#: src/slic3r/GUI/MainFrame.cpp:490 -msgid "&File" -msgstr "&File" +msgstr "Afficher la boîte de dialogue à propos" #: src/slic3r/GUI/MainFrame.cpp:491 +msgid "Show the list of the keyboard shortcuts" +msgstr "" + +#: src/slic3r/GUI/MainFrame.cpp:499 +msgid "&File" +msgstr "&Fichier" + +#: src/slic3r/GUI/MainFrame.cpp:500 msgid "&Edit" -msgstr "&Edit" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:492 +#: src/slic3r/GUI/MainFrame.cpp:501 msgid "&Window" -msgstr "&Window" +msgstr "Fe&nêtre" -#: src/slic3r/GUI/MainFrame.cpp:493 +#: src/slic3r/GUI/MainFrame.cpp:502 msgid "&View" -msgstr "&View" +msgstr "&Vue" -#: src/slic3r/GUI/MainFrame.cpp:496 +#: src/slic3r/GUI/MainFrame.cpp:505 msgid "&Help" -msgstr "&Help" +msgstr "&Aide" -#: src/slic3r/GUI/MainFrame.cpp:524 +#: src/slic3r/GUI/MainFrame.cpp:533 msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):" -msgstr "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):" +msgstr "Choisir un fichier à découper (STL/OBJ/AMF/3MF/PRUSA) :" -#: src/slic3r/GUI/MainFrame.cpp:538 +#: src/slic3r/GUI/MainFrame.cpp:547 msgid "No previously sliced file." -msgstr "No previously sliced file." +msgstr "Aucun fichier précédemment découpé." -#: src/slic3r/GUI/MainFrame.cpp:539 src/slic3r/GUI/PrintHostDialogs.cpp:219 +#: src/slic3r/GUI/MainFrame.cpp:548 src/slic3r/GUI/PrintHostDialogs.cpp:219 msgid "Error" -msgstr "Error" +msgstr "Erreur" -#: src/slic3r/GUI/MainFrame.cpp:544 +#: src/slic3r/GUI/MainFrame.cpp:553 msgid "Previously sliced file (" -msgstr "Previously sliced file (" +msgstr "Fichier précédemment découpé (" -#: src/slic3r/GUI/MainFrame.cpp:544 +#: src/slic3r/GUI/MainFrame.cpp:553 msgid ") not found." -msgstr ") not found." +msgstr ") non trouvé." -#: src/slic3r/GUI/MainFrame.cpp:545 +#: src/slic3r/GUI/MainFrame.cpp:554 msgid "File Not Found" -msgstr "File Not Found" +msgstr "Fichier non trouvé" -#: src/slic3r/GUI/MainFrame.cpp:580 src/slic3r/GUI/Tab.cpp:3152 +#: src/slic3r/GUI/MainFrame.cpp:589 src/slic3r/GUI/Tab.cpp:3153 msgid "Save " -msgstr "Save " +msgstr "Enregistrer " -#: src/slic3r/GUI/MainFrame.cpp:580 +#: src/slic3r/GUI/MainFrame.cpp:589 msgid "SVG" msgstr "SVG" -#: src/slic3r/GUI/MainFrame.cpp:580 +#: src/slic3r/GUI/MainFrame.cpp:589 msgid "G-code" msgstr "G-code" -#: src/slic3r/GUI/MainFrame.cpp:580 +#: src/slic3r/GUI/MainFrame.cpp:589 msgid " file as:" -msgstr " file as:" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:595 +#: src/slic3r/GUI/MainFrame.cpp:604 msgid "Save zip file as:" -msgstr "Save zip file as:" +msgstr "" -#: src/slic3r/GUI/MainFrame.cpp:607 src/slic3r/GUI/Plater.cpp:2352 -#: src/slic3r/GUI/Plater.cpp:3467 src/slic3r/GUI/Tab.cpp:1110 -#: src/slic3r/GUI/Tab.cpp:3348 +#: src/slic3r/GUI/MainFrame.cpp:616 src/slic3r/GUI/Plater.cpp:2368 +#: src/slic3r/GUI/Plater.cpp:3498 src/slic3r/GUI/Tab.cpp:1110 +#: src/slic3r/GUI/Tab.cpp:3350 msgid "Slicing" -msgstr "Slicing" +msgstr "Découpe en cours" -#: src/slic3r/GUI/MainFrame.cpp:607 +#: src/slic3r/GUI/MainFrame.cpp:616 msgid "Processing " -msgstr "Processing " +msgstr "Traitement " -#: src/slic3r/GUI/MainFrame.cpp:630 +#: src/slic3r/GUI/MainFrame.cpp:639 msgid " was successfully sliced." -msgstr " was successfully sliced." +msgstr " a été découpé avec succès." -#: src/slic3r/GUI/MainFrame.cpp:632 +#: src/slic3r/GUI/MainFrame.cpp:641 msgid "Slicing Done!" -msgstr "Slicing Done!" +msgstr "Découpe Effectuée !" -#: src/slic3r/GUI/MainFrame.cpp:647 +#: src/slic3r/GUI/MainFrame.cpp:656 msgid "Select the STL file to repair:" -msgstr "Select the STL file to repair:" +msgstr "Sélectionner le fichier STL à réparer :" -#: src/slic3r/GUI/MainFrame.cpp:661 +#: src/slic3r/GUI/MainFrame.cpp:669 msgid "Save OBJ file (less prone to coordinate errors than STL) as:" -msgstr "Save OBJ file (less prone to coordinate errors than STL) as:" +msgstr "" +"Enregistrer le fichier OBJ (moins enclin aux erreurs de coordonnées que le " +"STL) sous :" -#: src/slic3r/GUI/MainFrame.cpp:676 +#: src/slic3r/GUI/MainFrame.cpp:684 msgid "Your file was repaired." -msgstr "Your file was repaired." +msgstr "Votre fichier a été réparé." -#: src/slic3r/GUI/MainFrame.cpp:676 src/libslic3r/PrintConfig.cpp:3051 +#: src/slic3r/GUI/MainFrame.cpp:684 src/libslic3r/PrintConfig.cpp:3056 msgid "Repair" -msgstr "Repair" +msgstr "Réparer" -#: src/slic3r/GUI/MainFrame.cpp:690 +#: src/slic3r/GUI/MainFrame.cpp:698 msgid "Save configuration as:" -msgstr "Save configuration as:" +msgstr "Enregistrer la configuration sous :" -#: src/slic3r/GUI/MainFrame.cpp:710 src/slic3r/GUI/MainFrame.cpp:774 +#: src/slic3r/GUI/MainFrame.cpp:718 src/slic3r/GUI/MainFrame.cpp:782 msgid "Select configuration to load:" -msgstr "Select configuration to load:" +msgstr "Sélectionner la configuration à charger :" -#: src/slic3r/GUI/MainFrame.cpp:747 +#: src/slic3r/GUI/MainFrame.cpp:755 msgid "Save presets bundle as:" -msgstr "Save presets bundle as:" +msgstr "Enregistrer le lot de préréglages sous :" -#: src/slic3r/GUI/MainFrame.cpp:798 +#: src/slic3r/GUI/MainFrame.cpp:806 #, c-format msgid "%d presets successfully imported." -msgstr "%d presets successfully imported." +msgstr "%d préréglages importés avec succès." #: src/slic3r/GUI/MsgDialog.cpp:71 msgid "Slic3r error" -msgstr "Slic3r error" +msgstr "Erreur de Slic3r" #: src/slic3r/GUI/MsgDialog.cpp:71 msgid "Slic3r has encountered an error" -msgstr "Slic3r has encountered an error" +msgstr "Slic3r a rencontré une erreur" #: src/slic3r/GUI/Plater.cpp:137 msgid "Volume" @@ -2282,126 +2311,126 @@ msgstr "Volume" #: src/slic3r/GUI/Plater.cpp:138 msgid "Facets" -msgstr "Facets" +msgstr "Faces" #: src/slic3r/GUI/Plater.cpp:139 msgid "Materials" -msgstr "Materials" +msgstr "Matériaux" #: src/slic3r/GUI/Plater.cpp:142 msgid "Manifold" -msgstr "Manifold" +msgstr "Variété" -#: src/slic3r/GUI/Plater.cpp:188 +#: src/slic3r/GUI/Plater.cpp:187 msgid "Sliced Info" -msgstr "Sliced Info" +msgstr "Informations de découpage" -#: src/slic3r/GUI/Plater.cpp:207 src/slic3r/GUI/Plater.cpp:998 +#: src/slic3r/GUI/Plater.cpp:206 src/slic3r/GUI/Plater.cpp:998 msgid "Used Filament (m)" -msgstr "Used Filament (m)" +msgstr "Filament Utilisé (m)" + +#: src/slic3r/GUI/Plater.cpp:207 +msgid "Used Filament (mm³)" +msgstr "Filament Utilisé (mm³)" #: src/slic3r/GUI/Plater.cpp:208 -msgid "Used Filament (mm³)" -msgstr "Used Filament (mm³)" +msgid "Used Filament (g)" +msgstr "Filament Utilisé (g)" #: src/slic3r/GUI/Plater.cpp:209 -msgid "Used Filament (g)" -msgstr "Used Filament (g)" - -#: src/slic3r/GUI/Plater.cpp:210 msgid "Used Material (unit)" -msgstr "Used Material (unit)" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:211 src/slic3r/GUI/Plater.cpp:1013 +#: src/slic3r/GUI/Plater.cpp:210 src/slic3r/GUI/Plater.cpp:1013 #: src/libslic3r/PrintConfig.cpp:716 msgid "Cost" -msgstr "Cost" +msgstr "Coût" -#: src/slic3r/GUI/Plater.cpp:212 src/slic3r/GUI/Plater.cpp:985 +#: src/slic3r/GUI/Plater.cpp:211 src/slic3r/GUI/Plater.cpp:985 #: src/slic3r/GUI/Plater.cpp:1027 msgid "Estimated printing time" -msgstr "Estimated printing time" +msgstr "Temps d'impression estimé" -#: src/slic3r/GUI/Plater.cpp:213 +#: src/slic3r/GUI/Plater.cpp:212 msgid "Number of tool changes" -msgstr "Number of tool changes" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:290 +#: src/slic3r/GUI/Plater.cpp:289 msgid "Click to edit preset" -msgstr "Click to edit preset" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:413 +#: src/slic3r/GUI/Plater.cpp:412 msgid "Select what kind of support do you need" -msgstr "Select what kind of support do you need" +msgstr "Choisissez le type de support dont vous avez besoin" -#: src/slic3r/GUI/Plater.cpp:415 src/libslic3r/PrintConfig.cpp:1814 -#: src/libslic3r/PrintConfig.cpp:2419 +#: src/slic3r/GUI/Plater.cpp:414 src/libslic3r/PrintConfig.cpp:1814 +#: src/libslic3r/PrintConfig.cpp:2421 msgid "Support on build plate only" -msgstr "Support on build plate only" +msgstr "Support sur le plateau uniquement" -#: src/slic3r/GUI/Plater.cpp:416 +#: src/slic3r/GUI/Plater.cpp:415 msgid "Everywhere" -msgstr "Everywhere" +msgstr "Partout" -#: src/slic3r/GUI/Plater.cpp:438 src/slic3r/GUI/Tab.cpp:1007 +#: src/slic3r/GUI/Plater.cpp:437 src/slic3r/GUI/Tab.cpp:1007 msgid "Brim" -msgstr "Brim" +msgstr "Bordure" -#: src/slic3r/GUI/Plater.cpp:440 +#: src/slic3r/GUI/Plater.cpp:439 msgid "" "This flag enables the brim that will be printed around each object on the " "first layer." msgstr "" -"This flag enables the brim that will be printed around each object on the " -"first layer." +"Cette option permet l'impression de la bordure qui entoure chaque objet lors " +"de la première couche." -#: src/slic3r/GUI/Plater.cpp:448 +#: src/slic3r/GUI/Plater.cpp:447 msgid "Purging volumes" -msgstr "Purging volumes" +msgstr "Volumes de purge" -#: src/slic3r/GUI/Plater.cpp:673 +#: src/slic3r/GUI/Plater.cpp:672 msgid "Print settings" -msgstr "Print settings" +msgstr "Réglages d'impression" -#: src/slic3r/GUI/Plater.cpp:674 src/slic3r/GUI/Tab.cpp:1421 +#: src/slic3r/GUI/Plater.cpp:673 src/slic3r/GUI/Tab.cpp:1421 #: src/slic3r/GUI/Tab.cpp:1422 msgid "Filament" msgstr "Filament" -#: src/slic3r/GUI/Plater.cpp:675 src/slic3r/GUI/Preset.cpp:1252 +#: src/slic3r/GUI/Plater.cpp:674 src/slic3r/GUI/Preset.cpp:1254 msgid "SLA print" -msgstr "SLA print" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:676 src/slic3r/GUI/Preset.cpp:1253 +#: src/slic3r/GUI/Plater.cpp:675 src/slic3r/GUI/Preset.cpp:1255 msgid "SLA material" -msgstr "SLA material" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:677 +#: src/slic3r/GUI/Plater.cpp:676 msgid "Printer" -msgstr "Printer" +msgstr "Imprimante" -#: src/slic3r/GUI/Plater.cpp:707 src/slic3r/GUI/Plater.cpp:3674 +#: src/slic3r/GUI/Plater.cpp:706 src/slic3r/GUI/Plater.cpp:3705 msgid "Send to printer" -msgstr "Send to printer" +msgstr "Envoyer à l'imprimante" -#: src/slic3r/GUI/Plater.cpp:727 src/slic3r/GUI/Plater.cpp:2352 -#: src/slic3r/GUI/Plater.cpp:3470 +#: src/slic3r/GUI/Plater.cpp:726 src/slic3r/GUI/Plater.cpp:2368 +#: src/slic3r/GUI/Plater.cpp:3501 msgid "Slice now" -msgstr "Slice now" +msgstr "Découper maintenant" #: src/slic3r/GUI/Plater.cpp:860 msgid "Hold Shift to Slice & Export G-code" -msgstr "Hold Shift to Slice & Export G-code" +msgstr "" #: src/slic3r/GUI/Plater.cpp:931 #, c-format msgid "%d (%d shells)" -msgstr "%d (%d shells)" +msgstr "%d (%d coques)" #: src/slic3r/GUI/Plater.cpp:936 #, c-format msgid "Auto-repaired (%d errors)" -msgstr "Auto-repaired (%d errors)" +msgstr "Réparé automatiquement (%d erreurs)" #: src/slic3r/GUI/Plater.cpp:939 #, c-format @@ -2409,398 +2438,401 @@ msgid "" "%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d " "facets reversed, %d backwards edges" msgstr "" -"%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d " -"facets reversed, %d backwards edges" +"%d faces invalides, %d arrêtes corrigées, %d faces retirées, %d faces " +"ajoutées, %d faces inversées, %d arrêtes à l'envers" #: src/slic3r/GUI/Plater.cpp:949 msgid "Yes" -msgstr "Yes" +msgstr "Oui" #: src/slic3r/GUI/Plater.cpp:972 msgid "Used Material (ml)" -msgstr "Used Material (ml)" +msgstr "" #: src/slic3r/GUI/Plater.cpp:975 msgid "object(s)" -msgstr "object(s)" +msgstr "" #: src/slic3r/GUI/Plater.cpp:975 msgid "supports and pad" -msgstr "supports and pad" +msgstr "" #: src/slic3r/GUI/Plater.cpp:1000 src/slic3r/GUI/Plater.cpp:1015 msgid "objects" -msgstr "objects" +msgstr "" #: src/slic3r/GUI/Plater.cpp:1000 src/slic3r/GUI/Plater.cpp:1015 msgid "wipe tower" -msgstr "wipe tower" +msgstr "" #: src/slic3r/GUI/Plater.cpp:1030 msgid "normal mode" -msgstr "normal mode" +msgstr "" #: src/slic3r/GUI/Plater.cpp:1034 msgid "silent mode" -msgstr "silent mode" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:1544 +#: src/slic3r/GUI/Plater.cpp:1546 msgid "Loading" -msgstr "Loading" +msgstr "Chargement" -#: src/slic3r/GUI/Plater.cpp:1554 +#: src/slic3r/GUI/Plater.cpp:1556 #, c-format msgid "Processing input file %s\n" -msgstr "Processing input file %s\n" +msgstr "Traitement du fichier d'entrée %s\n" -#: src/slic3r/GUI/Plater.cpp:1612 +#: src/slic3r/GUI/Plater.cpp:1614 msgid "" "This file contains several objects positioned at multiple heights. Instead " "of considering them as multiple objects, should I consider\n" "this file as a single object having multiple parts?\n" msgstr "" -"This file contains several objects positioned at multiple heights. Instead " -"of considering them as multiple objects, should I consider\n" -"this file as a single object having multiple parts?\n" +"Ce fichier contient plusieurs objets positionnés à différentes hauteurs. Au " +"lieu de les considérer comme des objets distincts, voulez-vous que je " +"considère\n" +"ce fichier comme un seul objet en plusieurs parties?\n" -#: src/slic3r/GUI/Plater.cpp:1615 src/slic3r/GUI/Plater.cpp:1707 +#: src/slic3r/GUI/Plater.cpp:1617 src/slic3r/GUI/Plater.cpp:1725 msgid "Multi-part object detected" -msgstr "Multi-part object detected" +msgstr "Objet multi-pièces détecté" -#: src/slic3r/GUI/Plater.cpp:1650 +#: src/slic3r/GUI/Plater.cpp:1668 msgid "" -"This file cannot be loaded in simple mode. Do you want to switch to expert " -"mode?\n" +"This file cannot be loaded in a simple mode. Do you want to switch to an " +"advanced mode?\n" msgstr "" -"This file cannot be loaded in simple mode. Do you want to switch to expert " -"mode?\n" -#: src/slic3r/GUI/Plater.cpp:1651 +#: src/slic3r/GUI/Plater.cpp:1669 msgid "Detected advanced data" -msgstr "Detected advanced data" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:1684 +#: src/slic3r/GUI/Plater.cpp:1702 #, c-format msgid "" "You can't to add the object(s) from %s because of one or some of them " "is(are) multi-part" msgstr "" -"You can't to add the object(s) from %s because of one or some of them " -"is(are) multi-part" -#: src/slic3r/GUI/Plater.cpp:1704 +#: src/slic3r/GUI/Plater.cpp:1722 msgid "" "Multiple objects were loaded for a multi-material printer.\n" "Instead of considering them as multiple objects, should I consider\n" "these files to represent a single object having multiple parts?\n" msgstr "" -"Multiple objects were loaded for a multi-material printer.\n" -"Instead of considering them as multiple objects, should I consider\n" -"these files to represent a single object having multiple parts?\n" +"Plusieurs objets ont été chargés pour une imprimante multi-matériaux.\n" +"Au lieu de les considérer comme plusieurs objets, dois-je considérer\n" +"ces fichiers comment représentant un objets ayant plusieurs pièces ?\n" -#: src/slic3r/GUI/Plater.cpp:1720 +#: src/slic3r/GUI/Plater.cpp:1738 msgid "Loaded" -msgstr "Loaded" +msgstr "Chargé" -#: src/slic3r/GUI/Plater.cpp:1812 +#: src/slic3r/GUI/Plater.cpp:1830 msgid "" "Your object appears to be too large, so it was automatically scaled down to " "fit your print bed." msgstr "" -"Your object appears to be too large, so it was automatically scaled down to " -"fit your print bed." +"Votre objet semble être trop grand, il a donc été automatiquement réduit " +"afin de l'adapter à votre plateau d'impression." -#: src/slic3r/GUI/Plater.cpp:1813 +#: src/slic3r/GUI/Plater.cpp:1831 msgid "Object too large?" -msgstr "Object too large?" +msgstr "Objet trop grand ?" -#: src/slic3r/GUI/Plater.cpp:1863 +#: src/slic3r/GUI/Plater.cpp:1881 msgid "Export STL file:" -msgstr "Export STL file:" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:1870 +#: src/slic3r/GUI/Plater.cpp:1888 msgid "Export AMF file:" -msgstr "Export AMF file:" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:1876 +#: src/slic3r/GUI/Plater.cpp:1894 msgid "Save file as:" -msgstr "Save file as:" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2042 +#: src/slic3r/GUI/Plater.cpp:2059 msgid "Arranging canceled" -msgstr "Arranging canceled" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2045 +#: src/slic3r/GUI/Plater.cpp:2062 msgid "Arranging" -msgstr "Arranging" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2079 +#: src/slic3r/GUI/Plater.cpp:2096 msgid "Could not arrange model objects! Some geometries may be invalid." -msgstr "Could not arrange model objects! Some geometries may be invalid." +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2083 +#: src/slic3r/GUI/Plater.cpp:2100 msgid "Arranging done." -msgstr "Arranging done." +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2124 +#: src/slic3r/GUI/Plater.cpp:2141 msgid "Orientation search canceled" -msgstr "Orientation search canceled" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2129 +#: src/slic3r/GUI/Plater.cpp:2146 msgid "Searching for optimal orientation" -msgstr "Searching for optimal orientation" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2190 +#: src/slic3r/GUI/Plater.cpp:2207 msgid "Orientation found." -msgstr "Orientation found." +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2211 +#: src/slic3r/GUI/Plater.cpp:2227 msgid "" "The selected object can't be split because it contains more than one volume/" "material." msgstr "" -"The selected object can't be split because it contains more than one volume/" -"material." +"L'objet sélectionné ne peut être scindé car il contient plus d'un volume/" +"matériau." -#: src/slic3r/GUI/Plater.cpp:2337 +#: src/slic3r/GUI/Plater.cpp:2353 msgid "Invalid data" -msgstr "Invalid data" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2346 +#: src/slic3r/GUI/Plater.cpp:2362 msgid "Ready to slice" -msgstr "Ready to slice" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2379 src/slic3r/GUI/PrintHostDialogs.cpp:220 +#: src/slic3r/GUI/Plater.cpp:2400 src/slic3r/GUI/PrintHostDialogs.cpp:220 msgid "Cancelling" -msgstr "Cancelling" +msgstr "Annulation" -#: src/slic3r/GUI/Plater.cpp:2396 +#: src/slic3r/GUI/Plater.cpp:2417 msgid "Another export job is currently running." -msgstr "Another export job is currently running." +msgstr "Une autre tâche d'export est actuellement en cours." -#: src/slic3r/GUI/Plater.cpp:2656 +#: src/slic3r/GUI/Plater.cpp:2678 msgid "Export failed" -msgstr "Export failed" +msgstr "L'export a échoué" -#: src/slic3r/GUI/Plater.cpp:2661 src/slic3r/GUI/PrintHostDialogs.cpp:221 +#: src/slic3r/GUI/Plater.cpp:2683 src/slic3r/GUI/PrintHostDialogs.cpp:221 msgid "Cancelled" -msgstr "Cancelled" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2747 src/slic3r/GUI/Plater.cpp:2759 -#: src/slic3r/GUI/Plater.cpp:2831 +#: src/slic3r/GUI/Plater.cpp:2769 src/slic3r/GUI/Plater.cpp:2781 +#: src/slic3r/GUI/Plater.cpp:2853 msgid "Increase copies" -msgstr "Increase copies" +msgstr "Augmenter les copies" -#: src/slic3r/GUI/Plater.cpp:2825 src/slic3r/GUI/Plater.cpp:2843 +#: src/slic3r/GUI/Plater.cpp:2847 src/slic3r/GUI/Plater.cpp:2865 msgid "Remove the selected object" -msgstr "Remove the selected object" +msgstr "Retirer l'objet sélectionné" -#: src/slic3r/GUI/Plater.cpp:2831 +#: src/slic3r/GUI/Plater.cpp:2853 msgid "Place one more copy of the selected object" -msgstr "Place one more copy of the selected object" +msgstr "Placer une copie supplémentaire de l'objet sélectionné" -#: src/slic3r/GUI/Plater.cpp:2833 +#: src/slic3r/GUI/Plater.cpp:2855 msgid "Decrease copies" -msgstr "Decrease copies" +msgstr "Réduire les copies" -#: src/slic3r/GUI/Plater.cpp:2833 +#: src/slic3r/GUI/Plater.cpp:2855 msgid "Remove one copy of the selected object" -msgstr "Remove one copy of the selected object" +msgstr "Retirer une copie de l'objet sélectionné" -#: src/slic3r/GUI/Plater.cpp:2835 +#: src/slic3r/GUI/Plater.cpp:2857 msgid "Set number of copies" -msgstr "Set number of copies" +msgstr "Choisir le nombre de copies" -#: src/slic3r/GUI/Plater.cpp:2835 +#: src/slic3r/GUI/Plater.cpp:2857 msgid "Change the number of copies of the selected object" -msgstr "Change the number of copies of the selected object" +msgstr "Changer le nombre de copies de l'objet sélectionné" -#: src/slic3r/GUI/Plater.cpp:2858 +#: src/slic3r/GUI/Plater.cpp:2880 msgid "Reload from Disk" -msgstr "Reload from Disk" +msgstr "Recharger depuis le Disque" -#: src/slic3r/GUI/Plater.cpp:2858 +#: src/slic3r/GUI/Plater.cpp:2880 msgid "Reload the selected file from Disk" -msgstr "Reload the selected file from Disk" +msgstr "Recharger le fichier sélectionné depuis le Disque" -#: src/slic3r/GUI/Plater.cpp:2861 +#: src/slic3r/GUI/Plater.cpp:2883 msgid "Export the selected object as STL file" -msgstr "Export the selected object as STL file" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2873 +#: src/slic3r/GUI/Plater.cpp:2895 msgid "Along X axis" -msgstr "Along X axis" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2873 +#: src/slic3r/GUI/Plater.cpp:2895 msgid "Mirror the selected object along the X axis" -msgstr "Mirror the selected object along the X axis" +msgstr "Symétriser l'objet sélectionné selon l'axe X" -#: src/slic3r/GUI/Plater.cpp:2875 +#: src/slic3r/GUI/Plater.cpp:2897 msgid "Along Y axis" -msgstr "Along Y axis" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2875 +#: src/slic3r/GUI/Plater.cpp:2897 msgid "Mirror the selected object along the Y axis" -msgstr "Mirror the selected object along the Y axis" +msgstr "Symétriser l'objet sélectionné selon l'axe Y" -#: src/slic3r/GUI/Plater.cpp:2877 +#: src/slic3r/GUI/Plater.cpp:2899 msgid "Along Z axis" -msgstr "Along Z axis" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2877 +#: src/slic3r/GUI/Plater.cpp:2899 msgid "Mirror the selected object along the Z axis" -msgstr "Mirror the selected object along the Z axis" +msgstr "Symétriser l'objet sélectionné selon l'axe Z" -#: src/slic3r/GUI/Plater.cpp:2880 +#: src/slic3r/GUI/Plater.cpp:2902 msgid "Mirror" -msgstr "Mirror" +msgstr "Symétrie" -#: src/slic3r/GUI/Plater.cpp:2880 +#: src/slic3r/GUI/Plater.cpp:2902 msgid "Mirror the selected object" -msgstr "Mirror the selected object" +msgstr "Symétriser l'objet sélectionné" -#: src/slic3r/GUI/Plater.cpp:2898 +#: src/slic3r/GUI/Plater.cpp:2920 msgid "To objects" -msgstr "To objects" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2898 src/slic3r/GUI/Plater.cpp:2920 +#: src/slic3r/GUI/Plater.cpp:2920 src/slic3r/GUI/Plater.cpp:2942 msgid "Split the selected object into individual objects" -msgstr "Split the selected object into individual objects" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2900 +#: src/slic3r/GUI/Plater.cpp:2922 msgid "To parts" -msgstr "To parts" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2900 src/slic3r/GUI/Plater.cpp:2940 +#: src/slic3r/GUI/Plater.cpp:2922 src/slic3r/GUI/Plater.cpp:2962 msgid "Split the selected object into individual sub-parts" -msgstr "Split the selected object into individual sub-parts" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2903 src/slic3r/GUI/Plater.cpp:2920 -#: src/slic3r/GUI/Plater.cpp:2940 src/libslic3r/PrintConfig.cpp:3075 +#: src/slic3r/GUI/Plater.cpp:2925 src/slic3r/GUI/Plater.cpp:2942 +#: src/slic3r/GUI/Plater.cpp:2962 src/libslic3r/PrintConfig.cpp:3080 msgid "Split" -msgstr "Split" +msgstr "Scinder" -#: src/slic3r/GUI/Plater.cpp:2903 +#: src/slic3r/GUI/Plater.cpp:2925 msgid "Split the selected object" -msgstr "Split the selected object" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2926 +#: src/slic3r/GUI/Plater.cpp:2948 msgid "Optimize orientation" -msgstr "Optimize orientation" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:2926 +#: src/slic3r/GUI/Plater.cpp:2948 msgid "Optimize the rotation of the object for better print results." -msgstr "Optimize the rotation of the object for better print results." +msgstr "" -#: src/slic3r/GUI/Plater.cpp:3342 +#: src/slic3r/GUI/Plater.cpp:3373 msgid "Save G-code file as:" -msgstr "Save G-code file as:" +msgstr "Sauvegarder le fichier G-code en tant que :" -#: src/slic3r/GUI/Plater.cpp:3342 +#: src/slic3r/GUI/Plater.cpp:3373 msgid "Save SL1 file as:" -msgstr "Save SL1 file as:" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:3397 +#: src/slic3r/GUI/Plater.cpp:3428 #, c-format msgid "STL file exported to %s" -msgstr "STL file exported to %s" +msgstr "Fichier STL exporté vers %s" -#: src/slic3r/GUI/Plater.cpp:3413 +#: src/slic3r/GUI/Plater.cpp:3444 #, c-format msgid "AMF file exported to %s" -msgstr "AMF file exported to %s" +msgstr "Fichier AMF exporté vers %s" -#: src/slic3r/GUI/Plater.cpp:3416 +#: src/slic3r/GUI/Plater.cpp:3447 #, c-format msgid "Error exporting AMF file %s" -msgstr "Error exporting AMF file %s" +msgstr "Erreur d'export du fichier AMF %s" -#: src/slic3r/GUI/Plater.cpp:3442 +#: src/slic3r/GUI/Plater.cpp:3473 #, c-format msgid "3MF file exported to %s" -msgstr "3MF file exported to %s" +msgstr "Fichier 3MF exporté vers %s" -#: src/slic3r/GUI/Plater.cpp:3445 +#: src/slic3r/GUI/Plater.cpp:3476 #, c-format msgid "Error exporting 3MF file %s" -msgstr "Error exporting 3MF file %s" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:3673 +#: src/slic3r/GUI/Plater.cpp:3704 msgid "Export" -msgstr "Export" +msgstr "" -#: src/slic3r/GUI/Plater.cpp:3674 +#: src/slic3r/GUI/Plater.cpp:3705 msgid "Send G-code" -msgstr "Send G-code" +msgstr "" #: src/slic3r/GUI/Preferences.cpp:17 src/slic3r/GUI/Tab.cpp:1762 #: src/slic3r/GUI/Tab.cpp:1963 msgid "General" -msgstr "General" +msgstr "Général" #: src/slic3r/GUI/Preferences.cpp:34 msgid "Remember output directory" -msgstr "Remember output directory" +msgstr "Se souvenir du répertoire de sortie" #: src/slic3r/GUI/Preferences.cpp:36 msgid "" "If this is enabled, Slic3r will prompt the last output directory instead of " "the one containing the input files." msgstr "" -"If this is enabled, Slic3r will prompt the last output directory instead of " -"the one containing the input files." +"Si ceci est activé, Slic3r affichera le dernier répertoire de sortie au lieu " +"de celui contenant les fichiers d'entrée." #: src/slic3r/GUI/Preferences.cpp:42 msgid "Auto-center parts" -msgstr "Auto-center parts" +msgstr "Centrer automatiquement les pièces" #: src/slic3r/GUI/Preferences.cpp:44 msgid "" "If this is enabled, Slic3r will auto-center objects around the print bed " "center." msgstr "" -"If this is enabled, Slic3r will auto-center objects around the print bed " -"center." +"Si ceci est activé, Slic3r centrera automatique les objets autour du centre " +"du plateau d'impression." #: src/slic3r/GUI/Preferences.cpp:50 msgid "Background processing" -msgstr "Background processing" +msgstr "Tâche en arrière plan" #: src/slic3r/GUI/Preferences.cpp:52 msgid "" "If this is enabled, Slic3r will pre-process objects as soon as they're " "loaded in order to save time when exporting G-code." msgstr "" -"If this is enabled, Slic3r will pre-process objects as soon as they're " -"loaded in order to save time when exporting G-code." +"Si ceci est activé, Slic3r va pré-calculer les objets dès qu'ils sont " +"chargés pour gagner du temps lors de l'export du G-code." + +#: src/slic3r/GUI/Preferences.cpp:61 +msgid "If enabled, Slic3r checks for new versions of " +msgstr "" #: src/slic3r/GUI/Preferences.cpp:74 msgid "Suppress \" - default - \" presets" -msgstr "Suppress \" - default - \" presets" +msgstr "Supprimer les préréglages \" - par défaut - \"" #: src/slic3r/GUI/Preferences.cpp:76 msgid "" "Suppress \" - default - \" presets in the Print / Filament / Printer " "selections once there are any other valid presets available." msgstr "" -"Suppress \" - default - \" presets in the Print / Filament / Printer " -"selections once there are any other valid presets available." +"Supprimer les préréglages \" - par défaut - \" dans les choix Impression / " +"Filament / Imprimante une fois qu'il y a d'autres préréglages valides " +"disponibles." #: src/slic3r/GUI/Preferences.cpp:82 msgid "Show incompatible print and filament presets" -msgstr "Show incompatible print and filament presets" +msgstr "Afficher les préréglages d'impression et de filament incompatibles" #: src/slic3r/GUI/Preferences.cpp:84 msgid "" "When checked, the print and filament presets are shown in the preset editor " "even if they are marked as incompatible with the active printer" msgstr "" -"When checked, the print and filament presets are shown in the preset editor " -"even if they are marked as incompatible with the active printer" +"Lorsqu'ils sont sélectionnés, les préréglages de l'imprimante et du filament " +"sont visibles dans l'éditeur de préréglage même s'ils sont désignés comme " +"incompatibles avec l'imprimante en cours d'utilisation" #: src/slic3r/GUI/Preferences.cpp:91 msgid "Use legacy OpenGL 1.1 rendering" -msgstr "Use legacy OpenGL 1.1 rendering" +msgstr "Utiliser le rendu de legacy OpenGL 1.1" #: src/slic3r/GUI/Preferences.cpp:93 msgid "" @@ -2808,48 +2840,48 @@ msgid "" "try to check this checkbox. This will disable the layer height editing and " "anti aliasing, so it is likely better to upgrade your graphics driver." msgstr "" -"If you have rendering issues caused by a buggy OpenGL 2.0 driver, you may " -"try to check this checkbox. This will disable the layer height editing and " -"anti aliasing, so it is likely better to upgrade your graphics driver." +"Si vous avez des soucis de rendu causés par un driver OpenGL 2.0 bogué, vous " +"pouvez essayer de cocher cette case. Ceci désactivera l'édition de la " +"hauteur de couche et l'anti-aliasing, vous avez donc intérêt à mettre à jour " +"vos drivers graphiques." #: src/slic3r/GUI/Preferences.cpp:101 msgid "Use Retina resolution for the 3D scene" -msgstr "Use Retina resolution for the 3D scene" +msgstr "" #: src/slic3r/GUI/Preferences.cpp:103 msgid "" "If enabled, the 3D scene will be rendered in Retina resolution. If you are " "experiencing 3D performance problems, disabling this option may help." msgstr "" -"If enabled, the 3D scene will be rendered in Retina resolution. If you are " -"experiencing 3D performance problems, disabling this option may help." #: src/slic3r/GUI/Preferences.cpp:126 msgid "You need to restart Slic3r to make the changes effective." -msgstr "You need to restart Slic3r to make the changes effective." +msgstr "" +"Vous devez redémarrer Slic3r afin que les modifications soient appliquées." #: src/slic3r/GUI/Preset.cpp:207 msgid "modified" -msgstr "modified" +msgstr "" -#: src/slic3r/GUI/Preset.cpp:918 src/slic3r/GUI/Preset.cpp:958 -#: src/slic3r/GUI/Preset.cpp:1011 src/slic3r/GUI/Preset.cpp:1043 -#: src/slic3r/GUI/PresetBundle.cpp:1484 src/slic3r/GUI/PresetBundle.cpp:1537 +#: src/slic3r/GUI/Preset.cpp:920 src/slic3r/GUI/Preset.cpp:960 +#: src/slic3r/GUI/Preset.cpp:1013 src/slic3r/GUI/Preset.cpp:1045 +#: src/slic3r/GUI/PresetBundle.cpp:1470 src/slic3r/GUI/PresetBundle.cpp:1523 msgid "System presets" -msgstr "System presets" +msgstr "Préréglages système" -#: src/slic3r/GUI/Preset.cpp:962 src/slic3r/GUI/Preset.cpp:1047 -#: src/slic3r/GUI/PresetBundle.cpp:1542 +#: src/slic3r/GUI/Preset.cpp:964 src/slic3r/GUI/Preset.cpp:1049 +#: src/slic3r/GUI/PresetBundle.cpp:1528 msgid "User presets" -msgstr "User presets" +msgstr "Préréglages utilisateur" -#: src/slic3r/GUI/Preset.cpp:991 src/slic3r/GUI/Tab.cpp:247 +#: src/slic3r/GUI/Preset.cpp:993 src/slic3r/GUI/Tab.cpp:247 msgid "Add a new printer" -msgstr "Add a new printer" +msgstr "" -#: src/slic3r/GUI/Preset.cpp:1251 +#: src/slic3r/GUI/Preset.cpp:1253 msgid "filament" -msgstr "filament" +msgstr "" #: src/slic3r/GUI/PresetHints.cpp:28 #, c-format @@ -2858,9 +2890,10 @@ msgid "" "will be reduced so that no less than %ds are spent on that layer (however, " "speed will never be reduced below %dmm/s)." msgstr "" -"If estimated layer time is below ~%ds, fan will run at %d%% and print speed " -"will be reduced so that no less than %ds are spent on that layer (however, " -"speed will never be reduced below %dmm/s)." +"Si le temps de couche estimé est inférieur à ~%d s, le ventilateur tournera " +"à %d%% et la vitesse d'impression sera réduite pour qu'au moins %d s soient " +"passées sur cette couche (cependant, la vitesse ne sera jamais réduite en-" +"dessous de %d mm/s)." #: src/slic3r/GUI/PresetHints.cpp:32 #, c-format @@ -2870,8 +2903,9 @@ msgid "" "proportionally decreasing speed between %d%% and %d%%." msgstr "" "\n" -"If estimated layer time is greater, but still below ~%ds, fan will run at a " -"proportionally decreasing speed between %d%% and %d%%." +"Si le temps estimé pour la couche est supérieur, mais cependant inférieur à ~" +"%ds, le ventilateur tournera à une vitesse proportionnellement décroissante " +"entre %d%% et %d%%." #: src/slic3r/GUI/PresetHints.cpp:36 msgid "" @@ -2879,49 +2913,49 @@ msgid "" "During the other layers, fan " msgstr "" "\n" -"During the other layers, fan " +"Pendant les autres couches, le ventilateur " #: src/slic3r/GUI/PresetHints.cpp:38 msgid "Fan " -msgstr "Fan " +msgstr "Ventilateur " #: src/slic3r/GUI/PresetHints.cpp:43 #, c-format msgid "will always run at %d%% " -msgstr "will always run at %d%% " +msgstr "fonctionnera toujours à %d%% " #: src/slic3r/GUI/PresetHints.cpp:46 #, c-format msgid "except for the first %d layers" -msgstr "except for the first %d layers" +msgstr "sauf pour les %d première couches" #: src/slic3r/GUI/PresetHints.cpp:50 msgid "except for the first layer" -msgstr "except for the first layer" +msgstr "sauf pour la première couche" #: src/slic3r/GUI/PresetHints.cpp:52 msgid "will be turned off." -msgstr "will be turned off." +msgstr "sera désactivé." #: src/slic3r/GUI/PresetHints.cpp:153 msgid "external perimeters" -msgstr "external perimeters" +msgstr "périmètres externes" #: src/slic3r/GUI/PresetHints.cpp:162 msgid "perimeters" -msgstr "perimeters" +msgstr "périmètres" #: src/slic3r/GUI/PresetHints.cpp:171 msgid "infill" -msgstr "infill" +msgstr "remplissage" #: src/slic3r/GUI/PresetHints.cpp:181 msgid "solid infill" -msgstr "solid infill" +msgstr "remplissage solide" #: src/slic3r/GUI/PresetHints.cpp:189 msgid "top solid infill" -msgstr "top solid infill" +msgstr "remplissage solide supérieur" #: src/slic3r/GUI/PresetHints.cpp:200 msgid "support" @@ -2929,35 +2963,35 @@ msgstr "support" #: src/slic3r/GUI/PresetHints.cpp:210 msgid "support interface" -msgstr "support interface" +msgstr "interface du support" #: src/slic3r/GUI/PresetHints.cpp:216 msgid "First layer volumetric" -msgstr "First layer volumetric" +msgstr "Volume de la première couche" #: src/slic3r/GUI/PresetHints.cpp:216 msgid "Bridging volumetric" -msgstr "Bridging volumetric" +msgstr "Volumétrie des ponts" #: src/slic3r/GUI/PresetHints.cpp:216 msgid "Volumetric" -msgstr "Volumetric" +msgstr "Volumétrique" #: src/slic3r/GUI/PresetHints.cpp:217 msgid " flow rate is maximized " -msgstr " flow rate is maximized " +msgstr " le débit est maximisé " #: src/slic3r/GUI/PresetHints.cpp:220 msgid "by the print profile maximum" -msgstr "by the print profile maximum" +msgstr "par le maximum du profil de l'imprimante" #: src/slic3r/GUI/PresetHints.cpp:221 msgid "when printing " -msgstr "when printing " +msgstr "pendant l'impression des " #: src/slic3r/GUI/PresetHints.cpp:222 msgid " with a volumetric rate " -msgstr " with a volumetric rate " +msgstr " avec un débit volumétrique " #: src/slic3r/GUI/PresetHints.cpp:226 #, c-format @@ -2967,299 +3001,302 @@ msgstr "%3.2f mm³/s" #: src/slic3r/GUI/PresetHints.cpp:228 #, c-format msgid " at filament speed %3.2f mm/s." -msgstr " at filament speed %3.2f mm/s." +msgstr " à une vitesse de filament de %3.2f mm/s." #: src/slic3r/GUI/PresetHints.cpp:247 msgid "" "Recommended object thin wall thickness: Not available due to invalid layer " "height." msgstr "" -"Recommended object thin wall thickness: Not available due to invalid layer " -"height." +"Épaisseur des parois fines de l'objet recommandée : Non disponible car la " +"hauteur de couche est invalide." #: src/slic3r/GUI/PresetHints.cpp:264 #, c-format msgid "Recommended object thin wall thickness for layer height %.2f and " -msgstr "Recommended object thin wall thickness for layer height %.2f and " +msgstr "" +"Épaisseur des parois fines de l'objet recommandée pour la hauteur de couche " +"%.2f et " #: src/slic3r/GUI/PresetHints.cpp:271 #, c-format msgid "%d lines: %.2lf mm" -msgstr "%d lines: %.2lf mm" +msgstr "%d lignes : %.2lf mm" #: src/slic3r/GUI/PrintHostDialogs.cpp:32 msgid "Send G-Code to printer host" -msgstr "Send G-Code to printer host" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:32 msgid "Upload to Printer Host with the following filename:" -msgstr "Upload to Printer Host with the following filename:" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:34 msgid "Start printing after upload" -msgstr "Start printing after upload" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:41 msgid "Use forward slashes ( / ) as a directory separator if needed." -msgstr "Use forward slashes ( / ) as a directory separator if needed." +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:157 msgid "Cancel selected" -msgstr "Cancel selected" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:159 msgid "Show error message" -msgstr "Show error message" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:198 #: src/slic3r/GUI/PrintHostDialogs.cpp:217 msgid "Enqueued" -msgstr "Enqueued" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:218 msgid "Uploading" -msgstr "Uploading" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:222 msgid "Completed" -msgstr "Completed" +msgstr "" #: src/slic3r/GUI/PrintHostDialogs.cpp:260 msgid "Error uploading to print host:" -msgstr "Error uploading to print host:" +msgstr "" #: src/slic3r/GUI/RammingChart.cpp:23 msgid "NO RAMMING AT ALL" -msgstr "NO RAMMING AT ALL" +msgstr "PAS D'EXPULSION DU TOUT" #: src/slic3r/GUI/RammingChart.cpp:76 msgid "Time" -msgstr "Time" +msgstr "Durée" #: src/slic3r/GUI/RammingChart.cpp:76 src/slic3r/GUI/RammingChart.cpp:81 #: src/slic3r/GUI/WipeTowerDialog.cpp:82 src/libslic3r/PrintConfig.cpp:611 #: src/libslic3r/PrintConfig.cpp:655 src/libslic3r/PrintConfig.cpp:670 #: src/libslic3r/PrintConfig.cpp:2241 src/libslic3r/PrintConfig.cpp:2250 -#: src/libslic3r/PrintConfig.cpp:2308 src/libslic3r/PrintConfig.cpp:2315 +#: src/libslic3r/PrintConfig.cpp:2310 src/libslic3r/PrintConfig.cpp:2317 msgid "s" msgstr "s" #: src/slic3r/GUI/RammingChart.cpp:81 msgid "Volumetric speed" -msgstr "Volumetric speed" +msgstr "Vitesse volumétrique" #: src/slic3r/GUI/SysInfoDialog.cpp:44 -msgid "Slic3r Prusa Edition - System Information" -msgstr "Slic3r Prusa Edition - System Information" +msgid "System Information" +msgstr "" #: src/slic3r/GUI/Tab.cpp:50 src/libslic3r/PrintConfig.cpp:228 msgid "Compatible printers" -msgstr "Compatible printers" +msgstr "Imprimantes compatibles" #: src/slic3r/GUI/Tab.cpp:51 msgid "Select the printers this profile is compatible with." -msgstr "Select the printers this profile is compatible with." +msgstr "Sélectionner les imprimantes avec lesquelles ce profil est compatible." #: src/slic3r/GUI/Tab.cpp:56 src/libslic3r/PrintConfig.cpp:243 msgid "Compatible print profiles" -msgstr "Compatible print profiles" +msgstr "" #: src/slic3r/GUI/Tab.cpp:57 msgid "Select the print profiles this profile is compatible with." -msgstr "Select the print profiles this profile is compatible with." +msgstr "" #: src/slic3r/GUI/Tab.cpp:132 msgid "Save current " -msgstr "Save current " +msgstr "Enregistrer l'état actuel " #: src/slic3r/GUI/Tab.cpp:133 msgid "Delete this preset" -msgstr "Delete this preset" +msgstr "Supprimer ce préréglage" #: src/slic3r/GUI/Tab.cpp:145 msgid "" "Hover the cursor over buttons to find more information \n" "or click this button." msgstr "" -"Hover the cursor over buttons to find more information \n" -"or click this button." +"Passez le curseur au dessus des boutons pour obtenir plus d'informations\n" +"ou cliquez sur ce bouton." #: src/slic3r/GUI/Tab.cpp:858 msgid "It's a default preset." -msgstr "It's a default preset." +msgstr "C'est un préréglage par défaut." #: src/slic3r/GUI/Tab.cpp:859 msgid "It's a system preset." -msgstr "It's a system preset." +msgstr "C'est un préréglage système." #: src/slic3r/GUI/Tab.cpp:860 msgid "Current preset is inherited from " -msgstr "Current preset is inherited from " +msgstr "Le préréglage en cours a hérité de " #: src/slic3r/GUI/Tab.cpp:865 msgid "It can't be deleted or modified. " -msgstr "It can't be deleted or modified. " +msgstr "Il ne peut être supprimé ou modifié. " #: src/slic3r/GUI/Tab.cpp:866 msgid "" "Any modifications should be saved as a new preset inherited from this one. " msgstr "" -"Any modifications should be saved as a new preset inherited from this one. " +"Toute modification doit être enregistrée comme un nouveau préréglage hérité " +"de celui-ci. " #: src/slic3r/GUI/Tab.cpp:867 msgid "To do that please specify a new name for the preset." -msgstr "To do that please specify a new name for the preset." +msgstr "Pour faire cela veuillez spécifier un nouveau nom pour le préréglage." #: src/slic3r/GUI/Tab.cpp:871 msgid "Additional information:" -msgstr "Additional information:" +msgstr "Informations complémentaires :" #: src/slic3r/GUI/Tab.cpp:877 msgid "printer model" -msgstr "printer model" +msgstr "modèle de l'imprimante" #: src/slic3r/GUI/Tab.cpp:885 msgid "default print profile" -msgstr "default print profile" +msgstr "profil d'impression par défaut" #: src/slic3r/GUI/Tab.cpp:888 msgid "default filament profile" -msgstr "default filament profile" +msgstr "profil du filament par défaut" #: src/slic3r/GUI/Tab.cpp:902 msgid "default SLA material profile" -msgstr "default SLA material profile" +msgstr "" #: src/slic3r/GUI/Tab.cpp:906 msgid "default SLA print profile" -msgstr "default SLA print profile" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:948 src/slic3r/GUI/Tab.cpp:3303 +#: src/slic3r/GUI/Tab.cpp:948 src/slic3r/GUI/Tab.cpp:3305 msgid "Layers and perimeters" -msgstr "Layers and perimeters" +msgstr "Couches et périmètres" #: src/slic3r/GUI/Tab.cpp:949 src/libslic3r/PrintConfig.cpp:55 msgid "Layer height" -msgstr "Layer height" +msgstr "Hauteur de couche" #: src/slic3r/GUI/Tab.cpp:953 msgid "Vertical shells" -msgstr "Vertical shells" +msgstr "Parois verticales" #: src/slic3r/GUI/Tab.cpp:964 msgid "Horizontal shells" -msgstr "Horizontal shells" +msgstr "Coques horizontales" #: src/slic3r/GUI/Tab.cpp:965 src/libslic3r/PrintConfig.cpp:1709 msgid "Solid layers" -msgstr "Solid layers" +msgstr "Couches solides" #: src/slic3r/GUI/Tab.cpp:970 msgid "Quality (slower slicing)" -msgstr "Quality (slower slicing)" +msgstr "Qualité (découpage plus lent)" #: src/slic3r/GUI/Tab.cpp:988 msgid "Reducing printing time" -msgstr "Reducing printing time" +msgstr "Réduction du temps d'impression" #: src/slic3r/GUI/Tab.cpp:1000 msgid "Skirt and brim" -msgstr "Skirt and brim" +msgstr "Jupe et bordure" #: src/slic3r/GUI/Tab.cpp:1017 msgid "Raft" -msgstr "Raft" +msgstr "Radeau" #: src/slic3r/GUI/Tab.cpp:1021 msgid "Options for support material and raft" -msgstr "Options for support material and raft" +msgstr "Options pour le matériau de support et le radeau" #: src/slic3r/GUI/Tab.cpp:1036 msgid "Speed for print moves" -msgstr "Speed for print moves" +msgstr "Vitesse pour les déplacements d'impression" #: src/slic3r/GUI/Tab.cpp:1048 msgid "Speed for non-print moves" -msgstr "Speed for non-print moves" +msgstr "Vitesse pour les déplacements sans impression" #: src/slic3r/GUI/Tab.cpp:1051 msgid "Modifiers" -msgstr "Modifiers" +msgstr "Modificateurs" #: src/slic3r/GUI/Tab.cpp:1054 msgid "Acceleration control (advanced)" -msgstr "Acceleration control (advanced)" +msgstr "Contrôle de l'accélération (avancé)" #: src/slic3r/GUI/Tab.cpp:1061 msgid "Autospeed (advanced)" -msgstr "Autospeed (advanced)" +msgstr "Vitesse automatique (avancé)" #: src/slic3r/GUI/Tab.cpp:1069 msgid "Multiple Extruders" -msgstr "Multiple Extruders" +msgstr "Extrudeurs Multiples" #: src/slic3r/GUI/Tab.cpp:1077 msgid "Ooze prevention" -msgstr "Ooze prevention" +msgstr "Prévention des coulures" #: src/slic3r/GUI/Tab.cpp:1094 msgid "Extrusion width" -msgstr "Extrusion width" +msgstr "Largeur d'extrusion" #: src/slic3r/GUI/Tab.cpp:1104 msgid "Overlap" -msgstr "Overlap" +msgstr "Chevauchement" #: src/slic3r/GUI/Tab.cpp:1107 msgid "Flow" -msgstr "Flow" +msgstr "Flux" #: src/slic3r/GUI/Tab.cpp:1116 msgid "Other" -msgstr "Other" +msgstr "Autre" -#: src/slic3r/GUI/Tab.cpp:1119 src/slic3r/GUI/Tab.cpp:3351 +#: src/slic3r/GUI/Tab.cpp:1119 src/slic3r/GUI/Tab.cpp:3353 msgid "Output options" -msgstr "Output options" +msgstr "Options de sortie" #: src/slic3r/GUI/Tab.cpp:1120 msgid "Sequential printing" -msgstr "Sequential printing" +msgstr "Impression séquentielle" #: src/slic3r/GUI/Tab.cpp:1122 msgid "Extruder clearance (mm)" -msgstr "Extruder clearance (mm)" +msgstr "Dégagement de l'extrudeur (mm)" -#: src/slic3r/GUI/Tab.cpp:1131 src/slic3r/GUI/Tab.cpp:3352 +#: src/slic3r/GUI/Tab.cpp:1131 src/slic3r/GUI/Tab.cpp:3354 msgid "Output file" -msgstr "Output file" +msgstr "Fichier de sortie" #: src/slic3r/GUI/Tab.cpp:1138 src/libslic3r/PrintConfig.cpp:1382 msgid "Post-processing scripts" -msgstr "Post-processing scripts" +msgstr "Scripts de post-traitement" #: src/slic3r/GUI/Tab.cpp:1144 src/slic3r/GUI/Tab.cpp:1145 #: src/slic3r/GUI/Tab.cpp:1527 src/slic3r/GUI/Tab.cpp:1528 #: src/slic3r/GUI/Tab.cpp:1935 src/slic3r/GUI/Tab.cpp:1936 -#: src/slic3r/GUI/Tab.cpp:2027 src/slic3r/GUI/Tab.cpp:2028 -#: src/slic3r/GUI/Tab.cpp:3240 src/slic3r/GUI/Tab.cpp:3241 +#: src/slic3r/GUI/Tab.cpp:2028 src/slic3r/GUI/Tab.cpp:2029 +#: src/slic3r/GUI/Tab.cpp:3242 src/slic3r/GUI/Tab.cpp:3243 msgid "Notes" msgstr "Notes" #: src/slic3r/GUI/Tab.cpp:1151 src/slic3r/GUI/Tab.cpp:1535 -#: src/slic3r/GUI/Tab.cpp:1942 src/slic3r/GUI/Tab.cpp:2034 -#: src/slic3r/GUI/Tab.cpp:3248 src/slic3r/GUI/Tab.cpp:3357 +#: src/slic3r/GUI/Tab.cpp:1942 src/slic3r/GUI/Tab.cpp:2035 +#: src/slic3r/GUI/Tab.cpp:3250 src/slic3r/GUI/Tab.cpp:3359 msgid "Dependencies" -msgstr "Dependencies" +msgstr "Dépendances" #: src/slic3r/GUI/Tab.cpp:1152 src/slic3r/GUI/Tab.cpp:1536 -#: src/slic3r/GUI/Tab.cpp:1943 src/slic3r/GUI/Tab.cpp:2035 -#: src/slic3r/GUI/Tab.cpp:3249 src/slic3r/GUI/Tab.cpp:3358 +#: src/slic3r/GUI/Tab.cpp:1943 src/slic3r/GUI/Tab.cpp:2036 +#: src/slic3r/GUI/Tab.cpp:3251 src/slic3r/GUI/Tab.cpp:3360 msgid "Profile dependencies" -msgstr "Profile dependencies" +msgstr "Dépendances du profil" #: src/slic3r/GUI/Tab.cpp:1198 -#, no-c-format +#, fuzzy, c-format msgid "" "The Spiral Vase mode requires:\n" "- one perimeter\n" @@ -3270,18 +3307,18 @@ msgid "" "\n" "Shall I adjust those settings in order to enable Spiral Vase?" msgstr "" -"The Spiral Vase mode requires:\n" -"- one perimeter\n" -"- no top solid layers\n" -"- 0% fill density\n" -"- no support material\n" -"- no ensure_vertical_shell_thickness\n" +"Le mode Vase Spiral requiert :\n" +"-Un périmètre\n" +"-Pas de couches solides supérieures\n" +"-Une densité de remplissage de 0%\n" +"-Pas de supports\n" +"-Pas de ensure_vertical_shell_thickness\n" "\n" -"Shall I adjust those settings in order to enable Spiral Vase?" +"Voulez-vous que je modifie ces réglages afin d'activer le Vase Spirale?" #: src/slic3r/GUI/Tab.cpp:1205 msgid "Spiral Vase" -msgstr "Spiral Vase" +msgstr "Vase Spiral" #: src/slic3r/GUI/Tab.cpp:1228 msgid "" @@ -3293,17 +3330,18 @@ msgid "" "\n" "Shall I adjust those settings in order to enable the Wipe Tower?" msgstr "" -"The Wipe Tower currently supports the non-soluble supports only\n" -"if they are printed with the current extruder without triggering a tool " -"change.\n" -"(both support_material_extruder and support_material_interface_extruder need " -"to be set to 0).\n" +"A l'heure actuelle la Tour de Nettoyage ne tolère les supports non-" +"solubles \n" +"que s'ils sont imprimés avec l'extrudeur en cours d'utilisation sans " +"déclencher un changement d'outil.\n" +"(support_material_extruder de même que support_material_interface_extruder " +"doivent être réglés sur 0).\n" "\n" -"Shall I adjust those settings in order to enable the Wipe Tower?" +"Voulez-vous que je modifie ces réglages pour activer la Tour de Nettoyage ?" #: src/slic3r/GUI/Tab.cpp:1232 src/slic3r/GUI/Tab.cpp:1249 msgid "Wipe Tower" -msgstr "Wipe Tower" +msgstr "Tour de Nettoyage" #: src/slic3r/GUI/Tab.cpp:1246 msgid "" @@ -3312,10 +3350,12 @@ msgid "" "\n" "Shall I synchronize support layers in order to enable the Wipe Tower?" msgstr "" -"For the Wipe Tower to work with the soluble supports, the support layers\n" -"need to be synchronized with the object layers.\n" +"Pour que la tour de nettoyage fonctionne avec des supports solubles, les " +"couches de support\n" +"doivent être synchronisées avec les couches de l'objet.\n" "\n" -"Shall I synchronize support layers in order to enable the Wipe Tower?" +"Dois-je synchroniser les couches de support pour pouvoir activer la tour de " +"nettoyage ?" #: src/slic3r/GUI/Tab.cpp:1264 msgid "" @@ -3324,92 +3364,97 @@ msgid "" "\n" "Shall I adjust those settings for supports?" msgstr "" -"Supports work better, if the following feature is enabled:\n" -"- Detect bridging perimeters\n" +"Les supports sont plus efficaces, si la fonctionnalité suivante est " +"activée :\n" +"-Détection des périmètres de pont\n" "\n" -"Shall I adjust those settings for supports?" +"Voulez-vous que que je modifie les réglages des supports ?" #: src/slic3r/GUI/Tab.cpp:1267 msgid "Support Generator" -msgstr "Support Generator" +msgstr "Générateur de Support" +# Used in context: _("The ") + str_fill_pattern + _(" infill pattern is not supposed to work at 100% density.\n") #: src/slic3r/GUI/Tab.cpp:1309 msgid "The " -msgstr "The " +msgstr "" #: src/slic3r/GUI/Tab.cpp:1309 -#, no-c-format +#, fuzzy, c-format msgid "" " infill pattern is not supposed to work at 100% density.\n" "\n" "Shall I switch to rectilinear fill pattern?" msgstr "" -" infill pattern is not supposed to work at 100% density.\n" +" le motif de remplissage n'est pas supposé fonctionner à une densité de " +"100%.\n" "\n" -"Shall I switch to rectilinear fill pattern?" +"Dois-je passer au motif de remplissage rectiligne ?" #: src/slic3r/GUI/Tab.cpp:1429 msgid "Temperature " -msgstr "Temperature " +msgstr "Température " #: src/slic3r/GUI/Tab.cpp:1435 msgid "Bed" -msgstr "Bed" +msgstr "Plateau" #: src/slic3r/GUI/Tab.cpp:1440 msgid "Cooling" -msgstr "Cooling" +msgstr "Refroidissement" #: src/slic3r/GUI/Tab.cpp:1441 src/libslic3r/PrintConfig.cpp:1285 #: src/libslic3r/PrintConfig.cpp:2097 msgid "Enable" -msgstr "Enable" +msgstr "Activer" #: src/slic3r/GUI/Tab.cpp:1452 msgid "Fan settings" -msgstr "Fan settings" +msgstr "Réglages du ventilateur" #: src/slic3r/GUI/Tab.cpp:1453 msgid "Fan speed" -msgstr "Fan speed" +msgstr "Vitesse du ventilateur" #: src/slic3r/GUI/Tab.cpp:1461 msgid "Cooling thresholds" -msgstr "Cooling thresholds" +msgstr "Seuils de refroidissement" #: src/slic3r/GUI/Tab.cpp:1467 msgid "Filament properties" -msgstr "Filament properties" +msgstr "Propriétés du filament" #: src/slic3r/GUI/Tab.cpp:1471 msgid "Print speed override" -msgstr "Print speed override" +msgstr "Contournement de la vitesse d'impression" #: src/slic3r/GUI/Tab.cpp:1481 msgid "Toolchange parameters with single extruder MM printers" -msgstr "Toolchange parameters with single extruder MM printers" +msgstr "" +"Paramètres de changement d'outil pour les imprimantes multi-matériaux mono-" +"extrudeur" #: src/slic3r/GUI/Tab.cpp:1496 msgid "Ramming settings" -msgstr "Ramming settings" +msgstr "Réglages de l'expulsion" #: src/slic3r/GUI/Tab.cpp:1514 src/slic3r/GUI/Tab.cpp:1898 msgid "Custom G-code" -msgstr "Custom G-code" +msgstr "G-code personnalisé" #: src/slic3r/GUI/Tab.cpp:1515 src/slic3r/GUI/Tab.cpp:1899 #: src/libslic3r/PrintConfig.cpp:1735 src/libslic3r/PrintConfig.cpp:1750 msgid "Start G-code" -msgstr "Start G-code" +msgstr "G-code de début" #: src/slic3r/GUI/Tab.cpp:1521 src/slic3r/GUI/Tab.cpp:1905 #: src/libslic3r/PrintConfig.cpp:358 src/libslic3r/PrintConfig.cpp:368 msgid "End G-code" -msgstr "End G-code" +msgstr "G-code de fin" #: src/slic3r/GUI/Tab.cpp:1632 src/slic3r/GUI/Tab.cpp:1689 msgid " Browse " -msgstr " Browse " +msgstr " Parcourir " #: src/slic3r/GUI/Tab.cpp:1651 src/slic3r/GUI/Tab.cpp:1838 msgid "Test" @@ -3417,27 +3462,28 @@ msgstr "Test" #: src/slic3r/GUI/Tab.cpp:1662 msgid "Could not get a valid Printer Host reference" -msgstr "Could not get a valid Printer Host reference" +msgstr "" #: src/slic3r/GUI/Tab.cpp:1668 src/slic3r/GUI/Tab.cpp:1851 msgid "Success!" -msgstr "Success!" +msgstr "Réussi !" #: src/slic3r/GUI/Tab.cpp:1683 msgid "" "HTTPS CA file is optional. It is only needed if you use HTTPS with a self-" "signed certificate." msgstr "" -"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-" -"signed certificate." +"Le fichier HTTPS CA est optionnel. Il est uniquement requis si vous utilisez " +"le HTTPS avec un certificat auto-signé." #: src/slic3r/GUI/Tab.cpp:1696 msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*" -msgstr "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*" +msgstr "" +"Fichiers de certificat (*.crt, *.pem)|*.crt;*.pem|Tous les fichiers|*.*" #: src/slic3r/GUI/Tab.cpp:1697 msgid "Open CA certificate file" -msgstr "Open CA certificate file" +msgstr "Ouvrir le fichier de certificat CA" #: src/slic3r/GUI/Tab.cpp:1725 msgid "" @@ -3447,547 +3493,543 @@ msgid "" "\tTo use a custom CA file, please import your CA file into Certificate " "Store / Keychain." msgstr "" -"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." #: src/slic3r/GUI/Tab.cpp:1763 src/slic3r/GUI/Tab.cpp:1964 msgid "Size and coordinates" -msgstr "Size and coordinates" +msgstr "Taille et coordonnées" #: src/slic3r/GUI/Tab.cpp:1767 src/slic3r/GUI/Tab.cpp:1968 -#: src/slic3r/GUI/Tab.cpp:2911 +#: src/slic3r/GUI/Tab.cpp:2912 msgid " Set " -msgstr " Set " +msgstr " Appliquer " #: src/slic3r/GUI/Tab.cpp:1790 msgid "Capabilities" -msgstr "Capabilities" +msgstr "Fonctionnalités" #: src/slic3r/GUI/Tab.cpp:1795 msgid "Number of extruders of the printer." -msgstr "Number of extruders of the printer." +msgstr "Nombre d'extrudeurs de l'imprimante." #: src/slic3r/GUI/Tab.cpp:1823 msgid "USB/Serial connection" -msgstr "USB/Serial connection" +msgstr "Port USB/Série" #: src/slic3r/GUI/Tab.cpp:1824 src/libslic3r/PrintConfig.cpp:1590 msgid "Serial port" -msgstr "Serial port" +msgstr "Port série" #: src/slic3r/GUI/Tab.cpp:1829 msgid "Rescan serial ports" -msgstr "Rescan serial ports" +msgstr "Rescanner les ports série" #: src/slic3r/GUI/Tab.cpp:1851 msgid "Connection to printer works correctly." -msgstr "Connection to printer works correctly." +msgstr "La connexion avec l'imprimante fonctionne correctement." #: src/slic3r/GUI/Tab.cpp:1854 msgid "Connection failed." -msgstr "Connection failed." +msgstr "La connexion a échoué." -#: src/slic3r/GUI/Tab.cpp:1867 src/slic3r/GUI/Tab.cpp:2022 +#: src/slic3r/GUI/Tab.cpp:1867 src/slic3r/GUI/Tab.cpp:2023 msgid "Print Host upload" -msgstr "Print Host upload" +msgstr "" #: src/slic3r/GUI/Tab.cpp:1911 src/libslic3r/PrintConfig.cpp:128 msgid "Before layer change G-code" -msgstr "Before layer change G-code" +msgstr "G-Code avant changement de couche" #: src/slic3r/GUI/Tab.cpp:1917 src/libslic3r/PrintConfig.cpp:1030 msgid "After layer change G-code" -msgstr "After layer change G-code" +msgstr "G-Code après changement de couche" #: src/slic3r/GUI/Tab.cpp:1923 src/libslic3r/PrintConfig.cpp:2005 msgid "Tool change G-code" -msgstr "Tool change G-code" +msgstr "G-code de changement d'outil" #: src/slic3r/GUI/Tab.cpp:1929 msgid "Between objects G-code (for sequential printing)" -msgstr "Between objects G-code (for sequential printing)" +msgstr "Entre le G-code des objets (pour une impression séquentielle)" #: src/slic3r/GUI/Tab.cpp:1990 msgid "Display" -msgstr "Display" +msgstr "" #: src/slic3r/GUI/Tab.cpp:2001 msgid "Tilt" -msgstr "Tilt" +msgstr "" #: src/slic3r/GUI/Tab.cpp:2002 msgid "Tilt time" -msgstr "Tilt time" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2008 src/slic3r/GUI/Tab.cpp:3223 +#: src/slic3r/GUI/Tab.cpp:2008 src/slic3r/GUI/Tab.cpp:3224 msgid "Corrections" -msgstr "Corrections" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2074 src/slic3r/GUI/Tab.cpp:2136 +#: src/slic3r/GUI/Tab.cpp:2075 src/slic3r/GUI/Tab.cpp:2137 #: src/libslic3r/PrintConfig.cpp:1076 src/libslic3r/PrintConfig.cpp:1086 #: src/libslic3r/PrintConfig.cpp:1096 src/libslic3r/PrintConfig.cpp:1109 #: src/libslic3r/PrintConfig.cpp:1120 src/libslic3r/PrintConfig.cpp:1131 #: src/libslic3r/PrintConfig.cpp:1142 msgid "Machine limits" -msgstr "Machine limits" - -#: src/slic3r/GUI/Tab.cpp:2088 -msgid "Values in this column are for Full Power mode" -msgstr "Values in this column are for Full Power mode" +msgstr "" #: src/slic3r/GUI/Tab.cpp:2089 -msgid "Full Power" -msgstr "Full Power" +msgid "Values in this column are for Full Power mode" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2094 -msgid "Values in this column are for Silent mode" -msgstr "Values in this column are for Silent mode" +#: src/slic3r/GUI/Tab.cpp:2090 +msgid "Full Power" +msgstr "" #: src/slic3r/GUI/Tab.cpp:2095 +msgid "Values in this column are for Silent mode" +msgstr "" + +#: src/slic3r/GUI/Tab.cpp:2096 msgid "Silent" -msgstr "Silent" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2103 +#: src/slic3r/GUI/Tab.cpp:2104 msgid "Maximum feedrates" -msgstr "Maximum feedrates" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2108 +#: src/slic3r/GUI/Tab.cpp:2109 msgid "Maximum accelerations" -msgstr "Maximum accelerations" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2115 +#: src/slic3r/GUI/Tab.cpp:2116 msgid "Jerk limits" -msgstr "Jerk limits" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2120 +#: src/slic3r/GUI/Tab.cpp:2121 msgid "Minimum feedrates" -msgstr "Minimum feedrates" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2158 src/slic3r/GUI/Tab.cpp:2166 +#: src/slic3r/GUI/Tab.cpp:2159 src/slic3r/GUI/Tab.cpp:2167 msgid "Single extruder MM setup" -msgstr "Single extruder MM setup" +msgstr "Réglage MM pour extrudeur unique" -#: src/slic3r/GUI/Tab.cpp:2167 +#: src/slic3r/GUI/Tab.cpp:2168 msgid "Single extruder multimaterial parameters" -msgstr "Single extruder multimaterial parameters" +msgstr "Paramètres multimatériaux pour extrudeur unique" -#: src/slic3r/GUI/Tab.cpp:2181 src/libslic3r/GCode/PreviewData.cpp:475 +#: src/slic3r/GUI/Tab.cpp:2182 src/libslic3r/GCode/PreviewData.cpp:475 #, c-format msgid "Extruder %d" -msgstr "Extruder %d" +msgstr "Extrudeur %d" -#: src/slic3r/GUI/Tab.cpp:2188 +#: src/slic3r/GUI/Tab.cpp:2189 msgid "Layer height limits" -msgstr "Layer height limits" +msgstr "Limites de hauteur de couche" -#: src/slic3r/GUI/Tab.cpp:2193 +#: src/slic3r/GUI/Tab.cpp:2194 msgid "Position (for multi-extruder printers)" -msgstr "Position (for multi-extruder printers)" +msgstr "Position (pour les imprimantes multi-extrudeurs)" -#: src/slic3r/GUI/Tab.cpp:2196 +#: src/slic3r/GUI/Tab.cpp:2197 msgid "Retraction" -msgstr "Retraction" +msgstr "Rétraction" -#: src/slic3r/GUI/Tab.cpp:2199 +#: src/slic3r/GUI/Tab.cpp:2200 msgid "Only lift Z" -msgstr "Only lift Z" +msgstr "Lever Z seulement" -#: src/slic3r/GUI/Tab.cpp:2212 +#: src/slic3r/GUI/Tab.cpp:2213 msgid "" "Retraction when tool is disabled (advanced settings for multi-extruder " "setups)" msgstr "" -"Retraction when tool is disabled (advanced settings for multi-extruder " -"setups)" +"Rétractation lorsque l'outil est désactivé (réglages avancés pour les " +"configurations multi-extrudeurs)" -#: src/slic3r/GUI/Tab.cpp:2216 +#: src/slic3r/GUI/Tab.cpp:2217 msgid "Preview" -msgstr "Preview" +msgstr "Aperçu" -#: src/slic3r/GUI/Tab.cpp:2352 +#: src/slic3r/GUI/Tab.cpp:2353 msgid "" "The Wipe option is not available when using the Firmware Retraction mode.\n" "\n" "Shall I disable it in order to enable Firmware Retraction?" msgstr "" -"The Wipe option is not available when using the Firmware Retraction mode.\n" +"L'option Nettoyage n'est pas disponible lorsque vous utilisez le mode " +"Rétractation du Firmware.\n" "\n" -"Shall I disable it in order to enable Firmware Retraction?" +"Voulez-vous que je la désactive pour permettre la Rétractation du Firmware ?" -#: src/slic3r/GUI/Tab.cpp:2354 +#: src/slic3r/GUI/Tab.cpp:2355 msgid "Firmware Retraction" -msgstr "Firmware Retraction" - -#: src/slic3r/GUI/Tab.cpp:2681 -#, c-format -msgid "Default preset (%s)" -msgstr "Default preset (%s)" +msgstr "Rétraction du Firmware" #: src/slic3r/GUI/Tab.cpp:2682 #, c-format +msgid "Default preset (%s)" +msgstr "Préréglages par défaut (%s)" + +#: src/slic3r/GUI/Tab.cpp:2683 +#, c-format msgid "Preset (%s)" -msgstr "Preset (%s)" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2699 +#: src/slic3r/GUI/Tab.cpp:2700 msgid "has the following unsaved changes:" -msgstr "has the following unsaved changes:" - -#: src/slic3r/GUI/Tab.cpp:2702 -msgid "is not compatible with printer" -msgstr "is not compatible with printer" +msgstr "a les changements suivants non-enregistrés :" #: src/slic3r/GUI/Tab.cpp:2703 +msgid "is not compatible with printer" +msgstr "n'est pas compatible avec l'imprimante" + +#: src/slic3r/GUI/Tab.cpp:2704 msgid "is not compatible with print profile" -msgstr "is not compatible with print profile" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2705 +#: src/slic3r/GUI/Tab.cpp:2706 msgid "and it has the following unsaved changes:" -msgstr "and it has the following unsaved changes:" - -#: src/slic3r/GUI/Tab.cpp:2708 -msgid "Discard changes and continue anyway?" -msgstr "Discard changes and continue anyway?" +msgstr "et il y a les changements non sauvegardés suivants :" #: src/slic3r/GUI/Tab.cpp:2709 +msgid "Discard changes and continue anyway?" +msgstr "Annuler les changements et continuer malgré tout ?" + +#: src/slic3r/GUI/Tab.cpp:2710 msgid "Unsaved Changes" -msgstr "Unsaved Changes" +msgstr "Changements Non Sauvegardés" -#: src/slic3r/GUI/Tab.cpp:2721 +#: src/slic3r/GUI/Tab.cpp:2722 msgid "Please check your object list before preset changing." -msgstr "Please check your object list before preset changing." +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2801 +#: src/slic3r/GUI/Tab.cpp:2802 msgid "Copy" -msgstr "Copy" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:2823 +#: src/slic3r/GUI/Tab.cpp:2824 msgid "The supplied name is empty. It can't be saved." -msgstr "The supplied name is empty. It can't be saved." +msgstr "Le nom proposé est vide. Sauvegarde impossible." -#: src/slic3r/GUI/Tab.cpp:2828 +#: src/slic3r/GUI/Tab.cpp:2829 msgid "Cannot overwrite a system profile." -msgstr "Cannot overwrite a system profile." +msgstr "Impossible d'écraser un profil système." -#: src/slic3r/GUI/Tab.cpp:2832 +#: src/slic3r/GUI/Tab.cpp:2833 msgid "Cannot overwrite an external profile." -msgstr "Cannot overwrite an external profile." +msgstr "Impossible d'écraser un profil externe." -#: src/slic3r/GUI/Tab.cpp:2858 +#: src/slic3r/GUI/Tab.cpp:2859 msgid "remove" -msgstr "remove" +msgstr "retirer" -#: src/slic3r/GUI/Tab.cpp:2858 +#: src/slic3r/GUI/Tab.cpp:2859 msgid "delete" -msgstr "delete" - -#: src/slic3r/GUI/Tab.cpp:2859 -msgid "Are you sure you want to " -msgstr "Are you sure you want to " - -#: src/slic3r/GUI/Tab.cpp:2859 -msgid " the selected preset?" -msgstr " the selected preset?" +msgstr "supprimer" #: src/slic3r/GUI/Tab.cpp:2860 -msgid "Remove" -msgstr "Remove" +msgid "Are you sure you want to " +msgstr "Êtes-vous sûr de vouloir " + +#: src/slic3r/GUI/Tab.cpp:2860 +msgid " the selected preset?" +msgstr " le préréglage sélectionné ?" #: src/slic3r/GUI/Tab.cpp:2861 +msgid "Remove" +msgstr "Retirer" + +#: src/slic3r/GUI/Tab.cpp:2862 msgid " Preset" -msgstr " Preset" +msgstr " Préréglage" -#: src/slic3r/GUI/Tab.cpp:2989 +#: src/slic3r/GUI/Tab.cpp:2990 msgid "" "LOCKED LOCK;indicates that the settings are the same as the system values " "for the current option group" msgstr "" -"LOCKED LOCK;indicates that the settings are the same as the system values " -"for the current option group" +"VERROU VERROUILLE;indique que les paramètres sont les mêmes que les valeurs " +"système pour le groupe d'options en cours" -#: src/slic3r/GUI/Tab.cpp:2992 +#: src/slic3r/GUI/Tab.cpp:2993 msgid "" "UNLOCKED LOCK;indicates that some settings were changed and are not equal to " "the system values for the current option group.\n" "Click the UNLOCKED LOCK icon to reset all settings for current option group " "to the system values." msgstr "" -"UNLOCKED LOCK;indicates that some settings were changed and are not equal to " -"the system values for the current option group.\n" -"Click the UNLOCKED LOCK icon to reset all settings for current option group " -"to the system values." +"CADENAS OUVERT;indique que certains paramètres ont été modifiés et ne sont " +"pas égaux aux valeurs du système pour le groupe d'options actuel.\n" +"Cliquez sur l'icône CADENAS OUVERT pour régler tous les paramètres pour le " +"groupe d'options actuel sur les valeurs du système." -#: src/slic3r/GUI/Tab.cpp:2998 +#: src/slic3r/GUI/Tab.cpp:2999 msgid "" "WHITE BULLET;for the left button: \tindicates a non-system preset,\n" "for the right button: \tindicates that the settings hasn't been modified." msgstr "" -"WHITE BULLET;for the left button: \tindicates a non-system preset,\n" -"for the right button: \tindicates that the settings hasn't been modified." +"PUCE BLANCHE;pour le bouton gauche : indique un préréglage non-système, pour " +"le bouton droit : indique que le réglage n'a pas été modifié." -#: src/slic3r/GUI/Tab.cpp:3002 +#: src/slic3r/GUI/Tab.cpp:3003 msgid "" "BACK ARROW;indicates that the settings were changed and are not equal to the " "last saved preset for the current option group.\n" "Click the BACK ARROW icon to reset all settings for the current option group " "to the last saved preset." msgstr "" -"BACK ARROW;indicates that the settings were changed and are not equal to the " -"last saved preset for the current option group.\n" -"Click the BACK ARROW icon to reset all settings for the current option group " -"to the last saved preset." +"FLÈCHE ARRIÈRE;indique que les paramètres ont été changés et qu'ils ne sont " +"pas identiques au dernier préréglage enregistré du groupe d'options en " +"cours.\n" +"Cliquez sur l'icône FLÈCHE ARRIÈRE pour restaurer tous les paramètres du " +"groupe d'options en cours avec les valeurs du dernier préréglage enregistré." -#: src/slic3r/GUI/Tab.cpp:3028 +#: src/slic3r/GUI/Tab.cpp:3029 msgid "" "LOCKED LOCK icon indicates that the settings are the same as the system " "values for the current option group" msgstr "" -"LOCKED LOCK icon indicates that the settings are the same as the system " -"values for the current option group" +"L'icône VERROU VERROUILLE indique que les paramètres sont les mêmes que les " +"valeurs système pour le groupe d'options en cours" -#: src/slic3r/GUI/Tab.cpp:3030 +#: src/slic3r/GUI/Tab.cpp:3031 msgid "" "UNLOCKED LOCK icon indicates that some settings were changed and are not " "equal to the system values for the current option group.\n" "Click to reset all settings for current option group to the system values." msgstr "" -"UNLOCKED LOCK icon indicates that some settings were changed and are not " -"equal to the system values for the current option group.\n" -"Click to reset all settings for current option group to the system values." +"L'icône CADENAS OUVERT indique que certains paramètres ont été modifiés et " +"ne sont pas égaux aux valeurs du système pour le groupe d'options actuel.\n" +"Cliquez pour régler tous les paramètres pour le groupe d'options actuel sur " +"les valeurs du système." -#: src/slic3r/GUI/Tab.cpp:3033 +#: src/slic3r/GUI/Tab.cpp:3034 msgid "WHITE BULLET icon indicates a non system preset." -msgstr "WHITE BULLET icon indicates a non system preset." +msgstr "L'icône en forme de PUCE BLANCHE indique un préréglage non-système." -#: src/slic3r/GUI/Tab.cpp:3036 +#: src/slic3r/GUI/Tab.cpp:3037 msgid "" "WHITE BULLET icon indicates that the settings are the same as in the last " "saved preset for the current option group." msgstr "" -"WHITE BULLET icon indicates that the settings are the same as in the last " -"saved preset for the current option group." +"L'icône en forme de PUCE BLANCHE indique que les réglages sont identiques au " +"dernier préréglage sauvegardé pour le groupe d'options actuel." -#: src/slic3r/GUI/Tab.cpp:3038 +#: src/slic3r/GUI/Tab.cpp:3039 msgid "" "BACK ARROW icon indicates that the settings were changed and are not equal " "to the last saved preset for the current option group.\n" "Click to reset all settings for the current option group to the last saved " "preset." msgstr "" -"BACK ARROW icon indicates that the settings were changed and are not equal " -"to the last saved preset for the current option group.\n" -"Click to reset all settings for the current option group to the last saved " -"preset." - -#: src/slic3r/GUI/Tab.cpp:3044 -msgid "" -"LOCKED LOCK icon indicates that the value is the same as the system value." -msgstr "" -"LOCKED LOCK icon indicates that the value is the same as the system value." +"L'icône FLÈCHE ARRIÈRE indique que les paramètres ont été changés et qu'ils " +"ne sont pas identiques au dernier préréglage enregistré du groupe d'options " +"en cours.\n" +"Cliquez pour restaurer tous les paramètres du groupe d'options en cours avec " +"les valeurs du dernier préréglage enregistré." #: src/slic3r/GUI/Tab.cpp:3045 msgid "" -"UNLOCKED LOCK icon indicates that the value was changed and is not equal to " -"the system value.\n" -"Click to reset current value to the system value." +"LOCKED LOCK icon indicates that the value is the same as the system value." msgstr "" -"UNLOCKED LOCK icon indicates that the value was changed and is not equal to " -"the system value.\n" -"Click to reset current value to the system value." +"L'icône VERROU VERROUILLE indique que la valeur est la même que la valeur " +"système." -#: src/slic3r/GUI/Tab.cpp:3051 +#: src/slic3r/GUI/Tab.cpp:3046 msgid "" -"WHITE BULLET icon indicates that the value is the same as in the last saved " -"preset." +"UNLOCKED LOCK icon indicates that the value was changed and is not equal to " +"the system value.\n" +"Click to reset current value to the system value." msgstr "" -"WHITE BULLET icon indicates that the value is the same as in the last saved " -"preset." +"L'icône CADENAS OUVERT indique que la valeur a été changée et n'est pas " +"égale à la valeur du système.\n" +"Cliquez pour régler la valeur actuelle sur les valeurs du système." #: src/slic3r/GUI/Tab.cpp:3052 msgid "" +"WHITE BULLET icon indicates that the value is the same as in the last saved " +"preset." +msgstr "" +"L'icône PUCE BLANCHE indique que la valeur est la même que pour le dernier " +"préréglage sauvegardé." + +#: src/slic3r/GUI/Tab.cpp:3053 +msgid "" "BACK ARROW icon indicates that the value was changed and is not equal to the " "last saved preset.\n" "Click to reset current value to the last saved preset." msgstr "" -"BACK ARROW icon indicates that the value was changed and is not equal to the " -"last saved preset.\n" -"Click to reset current value to the last saved preset." +"L'icône FLÈCHE ARRIÈRE indique que la valeur a été changée et qu'elle n'est " +"pas identique au dernier préréglage enregistré.\n" +"Cliquez pour restaurer la valeur à celle du dernier préréglage enregistré." -#: src/slic3r/GUI/Tab.cpp:3152 +# Used in this context: _("Save ") + title + _(" as:") +#: src/slic3r/GUI/Tab.cpp:3153 msgid " as:" -msgstr " as:" +msgstr " sous :" -#: src/slic3r/GUI/Tab.cpp:3196 +#: src/slic3r/GUI/Tab.cpp:3197 msgid "the following postfix are not allowed:" -msgstr "the following postfix are not allowed:" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3200 +#: src/slic3r/GUI/Tab.cpp:3201 msgid "The supplied name is not available." -msgstr "The supplied name is not available." +msgstr "Le nom proposé n'est pas disponible." -#: src/slic3r/GUI/Tab.cpp:3213 +#: src/slic3r/GUI/Tab.cpp:3214 msgid "Material" -msgstr "Material" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3215 src/slic3r/GUI/Tab.cpp:3305 +#: src/slic3r/GUI/Tab.cpp:3216 src/slic3r/GUI/Tab.cpp:3307 msgid "Layers" -msgstr "Layers" +msgstr "Couches" -#: src/slic3r/GUI/Tab.cpp:3219 +#: src/slic3r/GUI/Tab.cpp:3220 msgid "Exposure" -msgstr "Exposure" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3313 +#: src/slic3r/GUI/Tab.cpp:3315 msgid "Support head" -msgstr "Support head" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3318 +#: src/slic3r/GUI/Tab.cpp:3320 msgid "Support pillar" -msgstr "Support pillar" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3328 +#: src/slic3r/GUI/Tab.cpp:3330 msgid "Connection of the support sticks and junctions" -msgstr "Connection of the support sticks and junctions" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3333 +#: src/slic3r/GUI/Tab.cpp:3335 msgid "Automatic generation" -msgstr "Automatic generation" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3395 +#: src/slic3r/GUI/Tab.cpp:3397 msgid "Head penetration should not be greater than the head width." -msgstr "Head penetration should not be greater than the head width." +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3396 +#: src/slic3r/GUI/Tab.cpp:3398 msgid "Invalid Head penetration" -msgstr "Invalid Head penetration" +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3408 +#: src/slic3r/GUI/Tab.cpp:3410 msgid "Pinhead diameter should be smaller than the pillar diameter." -msgstr "Pinhead diameter should be smaller than the pillar diameter." +msgstr "" -#: src/slic3r/GUI/Tab.cpp:3409 +#: src/slic3r/GUI/Tab.cpp:3411 msgid "Invalid pinhead diameter" -msgstr "Invalid pinhead diameter" +msgstr "" #: src/slic3r/GUI/Tab.hpp:307 src/slic3r/GUI/Tab.hpp:395 msgid "Print Settings" -msgstr "Print Settings" +msgstr "Réglages d'Impression" #: src/slic3r/GUI/Tab.hpp:325 msgid "Filament Settings" -msgstr "Filament Settings" +msgstr "Réglages du filament" #: src/slic3r/GUI/Tab.hpp:358 msgid "Printer Settings" -msgstr "Printer Settings" +msgstr "Réglages de l'Imprimante" #: src/slic3r/GUI/Tab.hpp:381 msgid "Material Settings" -msgstr "Material Settings" +msgstr "" #: src/slic3r/GUI/Tab.hpp:407 msgid "Save preset" -msgstr "Save preset" +msgstr "Enregistrer le préréglage" -#: src/slic3r/GUI/UpdateDialogs.cpp:29 +#: src/slic3r/GUI/UpdateDialogs.cpp:30 msgid "Update available" -msgstr "Update available" +msgstr "Mise à jour disponible" -#: src/slic3r/GUI/UpdateDialogs.cpp:29 -msgid "New version of Slic3r PE is available" -msgstr "New version of Slic3r PE is available" - -#: src/slic3r/GUI/UpdateDialogs.cpp:36 -msgid "To download, follow the link below." -msgstr "To download, follow the link below." - -#: src/slic3r/GUI/UpdateDialogs.cpp:44 -msgid "Current version:" -msgstr "Current version:" - -#: src/slic3r/GUI/UpdateDialogs.cpp:46 -msgid "New version:" -msgstr "New version:" - -#: src/slic3r/GUI/UpdateDialogs.cpp:54 -msgid "Don't notify about new releases any more" -msgstr "Don't notify about new releases any more" - -#: src/slic3r/GUI/UpdateDialogs.cpp:72 src/slic3r/GUI/UpdateDialogs.cpp:164 -msgid "Configuration update" -msgstr "Configuration update" - -#: src/slic3r/GUI/UpdateDialogs.cpp:72 -msgid "Configuration update is available" -msgstr "Configuration update is available" - -#: src/slic3r/GUI/UpdateDialogs.cpp:75 -msgid "" -"Would you like to install it?\n" -"\n" -"Note that a full configuration snapshot will be created first. It can then " -"be restored at any time should there be a problem with the new version.\n" -"\n" -"Updated configuration bundles:" -msgstr "" -"Would you like to install it?\n" -"\n" -"Note that a full configuration snapshot will be created first. It can then " -"be restored at any time should there be a problem with the new version.\n" -"\n" -"Updated configuration bundles:" - -#: src/slic3r/GUI/UpdateDialogs.cpp:111 -msgid "Slic3r incompatibility" -msgstr "Slic3r incompatibility" - -#: src/slic3r/GUI/UpdateDialogs.cpp:111 -msgid "Slic3r configuration is incompatible" -msgstr "Slic3r configuration is incompatible" - -#: src/slic3r/GUI/UpdateDialogs.cpp:114 -msgid "" -"This version of Slic3r PE is not compatible with currently installed " -"configuration bundles.\n" -"This probably happened as a result of running an older Slic3r PE 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" -msgstr "" -"This version of Slic3r PE is not compatible with currently installed " -"configuration bundles.\n" -"This probably happened as a result of running an older Slic3r PE 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" - -#: src/slic3r/GUI/UpdateDialogs.cpp:123 +#: src/slic3r/GUI/UpdateDialogs.cpp:30 #, c-format -msgid "This Slic3r PE version: %s" -msgstr "This Slic3r PE version: %s" +msgid "New version of %s is available" +msgstr "" -#: src/slic3r/GUI/UpdateDialogs.cpp:128 +#: src/slic3r/GUI/UpdateDialogs.cpp:37 +msgid "To download, follow the link below." +msgstr "Pour télécharger, suivez le lien ci-dessous." + +#: src/slic3r/GUI/UpdateDialogs.cpp:45 +msgid "Current version:" +msgstr "Version actuelle :" + +#: src/slic3r/GUI/UpdateDialogs.cpp:47 +msgid "New version:" +msgstr "Nouvelle version :" + +#: src/slic3r/GUI/UpdateDialogs.cpp:55 +msgid "Don't notify about new releases any more" +msgstr "Ne plus me notifier au sujet des nouvelles publications" + +#: src/slic3r/GUI/UpdateDialogs.cpp:73 src/slic3r/GUI/UpdateDialogs.cpp:167 +msgid "Configuration update" +msgstr "Mise à jour de la configuration" + +#: src/slic3r/GUI/UpdateDialogs.cpp:73 +msgid "Configuration update is available" +msgstr "Une mise à jour de la configuration est disponible" + +#: src/slic3r/GUI/UpdateDialogs.cpp:76 +msgid "" +"Would you like to install it?\n" +"\n" +"Note that a full configuration snapshot will be created first. It can then " +"be restored at any time should there be a problem with the new version.\n" +"\n" +"Updated configuration bundles:" +msgstr "" +"Voulez-vous l'installer ?\n" +"\n" +"Notez qu'un snapshot complet de la configuration sera sauvegardé d'abord. " +"Elle peut être restaurée à tout moment si vous rencontrez un problème avec " +"la nouvelle version.\n" +"\n" +"Ensembles de configuration mis à jour :" + +#: src/slic3r/GUI/UpdateDialogs.cpp:112 +msgid "Slic3r incompatibility" +msgstr "Incompatibilité avec Slic3r" + +#: src/slic3r/GUI/UpdateDialogs.cpp:112 +msgid "Slic3r configuration is incompatible" +msgstr "La configuration de Slic3r n'est pas compatible" + +#: src/slic3r/GUI/UpdateDialogs.cpp:117 +#, c-format +msgid "" +"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" +msgstr "" + +#: src/slic3r/GUI/UpdateDialogs.cpp:126 +#, c-format +msgid "This %s version: %s" +msgstr "" + +#: src/slic3r/GUI/UpdateDialogs.cpp:131 msgid "Incompatible bundles:" -msgstr "Incompatible bundles:" - -#: src/slic3r/GUI/UpdateDialogs.cpp:144 -msgid "Exit Slic3r" -msgstr "Exit Slic3r" +msgstr "Lots incompatibles :" #: src/slic3r/GUI/UpdateDialogs.cpp:147 -msgid "Re-configure" -msgstr "Re-configure" +msgid "Exit Slic3r" +msgstr "Quitter Slic3r" -#: src/slic3r/GUI/UpdateDialogs.cpp:168 +#: src/slic3r/GUI/UpdateDialogs.cpp:150 +msgid "Re-configure" +msgstr "Reconfigurer" + +#: src/slic3r/GUI/UpdateDialogs.cpp:171 #, c-format msgid "" -"Slic3r PE now uses an updated configuration structure.\n" +"%s now uses an updated configuration structure.\n" "\n" "So called 'System presets' have been introduced, which hold the built-in " "default settings for various printers. These System presets cannot be " @@ -3999,25 +4041,14 @@ msgid "" "Please proceed with the %s that follows to set up the new presets and to " "choose whether to enable automatic preset updates." msgstr "" -"Slic3r PE now uses an updated configuration structure.\n" -"\n" -"So called 'System presets' have been introduced, which hold the built-in " -"default settings for various printers. These System presets cannot be " -"modified, instead, users now may create their own presets inheriting " -"settings from one of the System presets.\n" -"An inheriting preset may either inherit a particular value from its parent " -"or override it with a customized value.\n" -"\n" -"Please proceed with the %s that follows to set up the new presets and to " -"choose whether to enable automatic preset updates." -#: src/slic3r/GUI/UpdateDialogs.cpp:184 +#: src/slic3r/GUI/UpdateDialogs.cpp:187 msgid "For more information please visit our wiki page:" -msgstr "For more information please visit our wiki page:" +msgstr "Pour plus d'informations, merci de visiter notre page wiki :" #: src/slic3r/GUI/WipeTowerDialog.cpp:14 msgid "Ramming customization" -msgstr "Ramming customization" +msgstr "Personnalisation de l'expulsion" #: src/slic3r/GUI/WipeTowerDialog.cpp:40 msgid "" @@ -4031,75 +4062,77 @@ msgid "" "This is an expert-level setting, incorrect adjustment will likely lead to " "jams, extruder wheel grinding into filament etc." msgstr "" -"Ramming denotes the rapid extrusion just before a tool change in a single-" -"extruder MM printer. Its purpose is to properly shape the end of the " -"unloaded filament so it does not prevent insertion of the new filament and " -"can itself be reinserted later. This phase is important and different " -"materials can require different extrusion speeds to get the good shape. For " -"this reason, the extrusion rates during ramming are adjustable.\n" +"L'Expulsion décrit l'extrusion rapide qui a lieu juste avant un changement " +"d'outil sur une imprimante MM à extrudeur unique. Le but est de donner une " +"forme correcte au filament déchargé afin qu'il n'empêche pas l'insertion du " +"nouveau filament et puisse être réinséré lui-même plus tard. Cette phase est " +"importante et des matériaux différents peuvent nécessiter des vitesses " +"d'extrusion différentes pour obtenir la bonne forme. De ce fait, les débits " +"d'extrusion pendant l'expulsion sont ajustables.\n" "\n" -"This is an expert-level setting, incorrect adjustment will likely lead to " -"jams, extruder wheel grinding into filament etc." +"Ceci est un paramétrage de niveau expert, et un mauvais ajustement " +"provoquera probablement des blocages, des accrochages de la roue de " +"l'extrudeur sur le filament , etc ..." #: src/slic3r/GUI/WipeTowerDialog.cpp:82 msgid "Total ramming time" -msgstr "Total ramming time" +msgstr "Durée totale de l'expulsion" #: src/slic3r/GUI/WipeTowerDialog.cpp:84 msgid "Total rammed volume" -msgstr "Total rammed volume" +msgstr "Volume total expulsé" #: src/slic3r/GUI/WipeTowerDialog.cpp:88 msgid "Ramming line width" -msgstr "Ramming line width" +msgstr "Largeur de la ligne d'expulsion" #: src/slic3r/GUI/WipeTowerDialog.cpp:90 msgid "Ramming line spacing" -msgstr "Ramming line spacing" +msgstr "Espacement de la ligne de ramming" #: src/slic3r/GUI/WipeTowerDialog.cpp:141 msgid "Wipe tower - Purging volume adjustment" -msgstr "Wipe tower - Purging volume adjustment" +msgstr "Tour de nettoyage - Ajustement du volume de purge" #: src/slic3r/GUI/WipeTowerDialog.cpp:225 msgid "" "Here you can adjust required purging volume (mm³) for any given pair of " "tools." msgstr "" -"Here you can adjust required purging volume (mm³) for any given pair of " -"tools." +"Ici vous pouvez ajuster le volume de purge nécessaire (mm³) pour une paire " +"d'outils donnée." #: src/slic3r/GUI/WipeTowerDialog.cpp:226 msgid "Extruder changed to" -msgstr "Extruder changed to" +msgstr "Extrudeur changé à" #: src/slic3r/GUI/WipeTowerDialog.cpp:234 msgid "unloaded" -msgstr "unloaded" +msgstr "déchargé" #: src/slic3r/GUI/WipeTowerDialog.cpp:235 msgid "loaded" -msgstr "loaded" +msgstr "chargé" #: src/slic3r/GUI/WipeTowerDialog.cpp:240 msgid "Tool #" -msgstr "Tool #" +msgstr "Outil #" #: src/slic3r/GUI/WipeTowerDialog.cpp:247 msgid "" "Total purging volume is calculated by summing two values below, depending on " "which tools are loaded/unloaded." msgstr "" -"Total purging volume is calculated by summing two values below, depending on " -"which tools are loaded/unloaded." +"Le volume de purge total est calculé en additionnant les deux valeurs ci-" +"dessous, en fonction des outils qui sont chargés/déchargés." #: src/slic3r/GUI/WipeTowerDialog.cpp:248 msgid "Volume to purge (mm³) when the filament is being" -msgstr "Volume to purge (mm³) when the filament is being" +msgstr "Volume à purger (mm³) lorsque le filament est" #: src/slic3r/GUI/WipeTowerDialog.cpp:262 msgid "From" -msgstr "From" +msgstr "De" #: src/slic3r/GUI/WipeTowerDialog.cpp:327 msgid "" @@ -4108,570 +4141,501 @@ msgid "" "\n" "Do you want to proceed?" msgstr "" -"Switching to simple settings will discard changes done in the advanced " -"mode!\n" +"Basculer vers les réglages simples annulera les changements effectués en " +"mode avancé !\n" "\n" -"Do you want to proceed?" +"Voulez-vous continuer ?" #: src/slic3r/GUI/WipeTowerDialog.cpp:339 msgid "Show simplified settings" -msgstr "Show simplified settings" +msgstr "Afficher les réglages simplifiés" #: src/slic3r/GUI/WipeTowerDialog.cpp:339 msgid "Show advanced settings" -msgstr "Show advanced settings" +msgstr "Afficher les réglages avancés" -#: src/slic3r/GUI/wxExtensions.cpp:2398 +#: src/slic3r/GUI/wxExtensions.cpp:2409 #, c-format msgid "Switch to the %s mode" -msgstr "Switch to the %s mode" +msgstr "" -#: src/slic3r/GUI/wxExtensions.cpp:2399 +#: src/slic3r/GUI/wxExtensions.cpp:2410 #, c-format msgid "Current mode is %s" -msgstr "Current mode is %s" +msgstr "" #: src/slic3r/Utils/Duet.cpp:51 msgid "Connection to Duet works correctly." -msgstr "Connection to Duet works correctly." +msgstr "" #: src/slic3r/Utils/Duet.cpp:56 msgid "Could not connect to Duet" -msgstr "Could not connect to Duet" +msgstr "" #: src/slic3r/Utils/Duet.cpp:84 src/slic3r/Utils/Duet.cpp:154 msgid "Unknown error occured" -msgstr "Unknown error occured" +msgstr "" #: src/slic3r/Utils/Duet.cpp:148 msgid "Wrong password" -msgstr "Wrong password" +msgstr "" #: src/slic3r/Utils/Duet.cpp:151 msgid "Could not get resources to create a new connection" -msgstr "Could not get resources to create a new connection" +msgstr "" #: src/slic3r/Utils/OctoPrint.cpp:69 #, c-format msgid "Mismatched type of print host: %s" -msgstr "Mismatched type of print host: %s" +msgstr "" #: src/slic3r/Utils/OctoPrint.cpp:84 msgid "Connection to OctoPrint works correctly." -msgstr "Connection to OctoPrint works correctly." +msgstr "La connexion avec OctoPrint fonctionne correctement." #: src/slic3r/Utils/OctoPrint.cpp:90 msgid "Could not connect to OctoPrint" -msgstr "Could not connect to OctoPrint" +msgstr "Impossible de se connecter à OctoPrint" #: src/slic3r/Utils/OctoPrint.cpp:90 msgid "Note: OctoPrint version at least 1.1.0 is required." -msgstr "Note: OctoPrint version at least 1.1.0 is required." +msgstr "" +"Note : une version d'Octoprint supérieure ou égale à 1.1.0 est requise." #: src/slic3r/Utils/OctoPrint.cpp:195 msgid "Connection to Prusa SLA works correctly." -msgstr "Connection to Prusa SLA works correctly." +msgstr "" #: src/slic3r/Utils/OctoPrint.cpp:200 msgid "Could not connect to Prusa SLA" -msgstr "Could not connect to Prusa SLA" +msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:583 #, c-format msgid "requires min. %s and max. %s" -msgstr "requires min. %s and max. %s" +msgstr "nécessite min. %s et max. %s" #: src/slic3r/Utils/PresetUpdater.cpp:588 #, c-format msgid "requires min. %s" -msgstr "requires min. %s" +msgstr "" #: src/slic3r/Utils/PresetUpdater.cpp:590 #, c-format msgid "requires max. %s" -msgstr "requires max. %s" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:219 #: src/slic3r/Utils/FixModelByWin10.cpp:359 msgid "Exporting source model" -msgstr "Exporting source model" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:235 msgid "Failed loading the input model." -msgstr "Failed loading the input model." +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:242 msgid "Repairing model by the Netfabb service" -msgstr "Repairing model by the Netfabb service" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:248 msgid "Mesh repair failed." -msgstr "Mesh repair failed." +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:251 #: src/slic3r/Utils/FixModelByWin10.cpp:378 msgid "Loading repaired model" -msgstr "Loading repaired model" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:263 #: src/slic3r/Utils/FixModelByWin10.cpp:270 #: src/slic3r/Utils/FixModelByWin10.cpp:302 msgid "Saving mesh into the 3MF container failed." -msgstr "Saving mesh into the 3MF container failed." +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:340 msgid "Model fixing" -msgstr "Model fixing" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:341 msgid "Exporting model..." -msgstr "Exporting model..." +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:368 msgid "Export of a temporary 3mf file failed" -msgstr "Export of a temporary 3mf file failed" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:383 msgid "Import of the repaired 3mf file failed" -msgstr "Import of the repaired 3mf file failed" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:385 msgid "Repaired 3MF file does not contain any object" -msgstr "Repaired 3MF file does not contain any object" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:387 msgid "Repaired 3MF file contains more than one object" -msgstr "Repaired 3MF file contains more than one object" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:389 msgid "Repaired 3MF file does not contain any volume" -msgstr "Repaired 3MF file does not contain any volume" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:391 msgid "Repaired 3MF file contains more than one volume" -msgstr "Repaired 3MF file contains more than one volume" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:400 msgid "Model repair finished" -msgstr "Model repair finished" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:406 msgid "Model repair canceled" -msgstr "Model repair canceled" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:423 msgid "Model repaired successfully" -msgstr "Model repaired successfully" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:423 #: src/slic3r/Utils/FixModelByWin10.cpp:426 msgid "Model Repair by the Netfabb service" -msgstr "Model Repair by the Netfabb service" +msgstr "" #: src/slic3r/Utils/FixModelByWin10.cpp:426 msgid "Model repair failed: \n" -msgstr "Model repair failed: \n" +msgstr "" #: src/libslic3r/Zipper.cpp:35 msgid "undefined error" -msgstr "undefined error" +msgstr "" #: src/libslic3r/Zipper.cpp:37 msgid "too many files" -msgstr "too many files" +msgstr "" #: src/libslic3r/Zipper.cpp:39 msgid "file too large" -msgstr "file too large" +msgstr "" #: src/libslic3r/Zipper.cpp:41 msgid "unsupported method" -msgstr "unsupported method" +msgstr "" #: src/libslic3r/Zipper.cpp:43 msgid "unsupported encryption" -msgstr "unsupported encryption" +msgstr "" #: src/libslic3r/Zipper.cpp:45 msgid "unsupported feature" -msgstr "unsupported feature" +msgstr "" #: src/libslic3r/Zipper.cpp:47 msgid "failed finding central directory" -msgstr "failed finding central directory" +msgstr "" #: src/libslic3r/Zipper.cpp:49 msgid "not a ZIP archive" -msgstr "not a ZIP archive" +msgstr "" #: src/libslic3r/Zipper.cpp:51 msgid "invalid header or archive is corrupted" -msgstr "invalid header or archive is corrupted" +msgstr "" #: src/libslic3r/Zipper.cpp:53 msgid "unsupported multidisk archive" -msgstr "unsupported multidisk archive" +msgstr "" #: src/libslic3r/Zipper.cpp:55 msgid "decompression failed or archive is corrupted" -msgstr "decompression failed or archive is corrupted" +msgstr "" #: src/libslic3r/Zipper.cpp:57 msgid "compression failed" -msgstr "compression failed" +msgstr "" #: src/libslic3r/Zipper.cpp:59 msgid "unexpected decompressed size" -msgstr "unexpected decompressed size" +msgstr "" #: src/libslic3r/Zipper.cpp:61 msgid "CRC-32 check failed" -msgstr "CRC-32 check failed" +msgstr "" #: src/libslic3r/Zipper.cpp:63 msgid "unsupported central directory size" -msgstr "unsupported central directory size" +msgstr "" #: src/libslic3r/Zipper.cpp:65 msgid "allocation failed" -msgstr "allocation failed" +msgstr "" #: src/libslic3r/Zipper.cpp:67 msgid "file open failed" -msgstr "file open failed" +msgstr "" #: src/libslic3r/Zipper.cpp:69 msgid "file create failed" -msgstr "file create failed" +msgstr "" #: src/libslic3r/Zipper.cpp:71 msgid "file write failed" -msgstr "file write failed" +msgstr "" #: src/libslic3r/Zipper.cpp:73 msgid "file read failed" -msgstr "file read failed" +msgstr "" #: src/libslic3r/Zipper.cpp:75 msgid "file close failed" -msgstr "file close failed" +msgstr "" #: src/libslic3r/Zipper.cpp:77 msgid "file seek failed" -msgstr "file seek failed" +msgstr "" #: src/libslic3r/Zipper.cpp:79 msgid "file stat failed" -msgstr "file stat failed" +msgstr "" #: src/libslic3r/Zipper.cpp:81 msgid "invalid parameter" -msgstr "invalid parameter" +msgstr "" #: src/libslic3r/Zipper.cpp:83 msgid "invalid filename" -msgstr "invalid filename" +msgstr "" #: src/libslic3r/Zipper.cpp:85 msgid "buffer too small" -msgstr "buffer too small" +msgstr "" #: src/libslic3r/Zipper.cpp:87 msgid "internal error" -msgstr "internal error" +msgstr "" #: src/libslic3r/Zipper.cpp:89 msgid "file not found" -msgstr "file not found" +msgstr "" #: src/libslic3r/Zipper.cpp:91 msgid "archive is too large" -msgstr "archive is too large" +msgstr "" #: src/libslic3r/Zipper.cpp:93 msgid "validation failed" -msgstr "validation failed" +msgstr "" #: src/libslic3r/Zipper.cpp:95 msgid "write calledback failed" -msgstr "write calledback failed" +msgstr "" #: src/libslic3r/Zipper.cpp:105 msgid "Error with zip archive" -msgstr "Error with zip archive" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2153 -msgid "Starting" -msgstr "Starting" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2154 -msgid "Filtering" -msgstr "Filtering" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2155 -msgid "Generate pinheads" -msgstr "Generate pinheads" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2156 -msgid "Classification" -msgstr "Classification" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2157 -msgid "Routing to ground" -msgstr "Routing to ground" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2158 -msgid "Routing supports to model surface" -msgstr "Routing supports to model surface" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2159 -msgid "Cascading pillars" -msgstr "Cascading pillars" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2160 -msgid "Processing small holes" -msgstr "Processing small holes" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2161 -msgid "Done" -msgstr "Done" - -#: src/libslic3r/SLA/SLASupportTree.cpp:2162 -msgid "Abort" -msgstr "Abort" +msgstr "" #: src/libslic3r/Print.cpp:1136 msgid "All objects are outside of the print volume." -msgstr "All objects are outside of the print volume." +msgstr "" #: src/libslic3r/Print.cpp:1165 msgid "Some objects are too close; your extruder will collide with them." -msgstr "Some objects are too close; your extruder will collide with them." +msgstr "" #: src/libslic3r/Print.cpp:1180 msgid "" "Some objects are too tall and cannot be printed without extruder collisions." msgstr "" -"Some objects are too tall and cannot be printed without extruder collisions." #: src/libslic3r/Print.cpp:1190 msgid "The Spiral Vase option can only be used when printing a single object." -msgstr "The Spiral Vase option can only be used when printing a single object." +msgstr "" #: src/libslic3r/Print.cpp:1192 msgid "" "The Spiral Vase option can only be used when printing single material " "objects." msgstr "" -"The Spiral Vase option can only be used when printing single material " -"objects." #: src/libslic3r/Print.cpp:1198 msgid "" "All extruders must have the same diameter for single extruder multimaterial " "printer." msgstr "" -"All extruders must have the same diameter for single extruder multimaterial " -"printer." #: src/libslic3r/Print.cpp:1203 msgid "" "The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter " "and Repetier G-code flavors." msgstr "" -"The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter " -"and Repetier G-code flavors." #: src/libslic3r/Print.cpp:1205 msgid "" "The Wipe Tower is currently only supported with the relative extruder " "addressing (use_relative_e_distances=1)." msgstr "" -"The Wipe Tower is currently only supported with the relative extruder " -"addressing (use_relative_e_distances=1)." #: src/libslic3r/Print.cpp:1226 msgid "" "The Wipe Tower is only supported for multiple objects if they have equal " "layer heigths" msgstr "" -"The Wipe Tower is only supported for multiple objects if they have equal " -"layer heigths" #: src/libslic3r/Print.cpp:1228 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "over an equal number of raft layers" msgstr "" -"The Wipe Tower is only supported for multiple objects if they are printed " -"over an equal number of raft layers" #: src/libslic3r/Print.cpp:1230 msgid "" "The Wipe Tower is only supported for multiple objects if they are printed " "with the same support_material_contact_distance" msgstr "" -"The Wipe Tower is only supported for multiple objects if they are printed " -"with the same support_material_contact_distance" #: src/libslic3r/Print.cpp:1232 msgid "" "The Wipe Tower is only supported for multiple objects if they are sliced " "equally." msgstr "" -"The Wipe Tower is only supported for multiple objects if they are sliced " -"equally." #: src/libslic3r/Print.cpp:1261 msgid "" "The Wipe tower is only supported if all objects have the same layer height " "profile" msgstr "" -"The Wipe tower is only supported if all objects have the same layer height " -"profile" #: src/libslic3r/Print.cpp:1271 msgid "The supplied settings will cause an empty print." -msgstr "The supplied settings will cause an empty print." +msgstr "" #: src/libslic3r/Print.cpp:1288 msgid "" "One or more object were assigned an extruder that the printer does not have." msgstr "" -"One or more object were assigned an extruder that the printer does not have." -#: src/libslic3r/Print.cpp:1297 +#: src/libslic3r/Print.cpp:1298 msgid "" "Printing with multiple extruders of differing nozzle diameters. If support " "is to be printed with the current extruder (support_material_extruder == 0 " "or support_material_interface_extruder == 0), all nozzles have to be of the " "same diameter." msgstr "" -"Printing with multiple extruders of differing nozzle diameters. If support " -"is to be printed with the current extruder (support_material_extruder == 0 " -"or support_material_interface_extruder == 0), all nozzles have to be of the " -"same diameter." -#: src/libslic3r/Print.cpp:1305 +#: src/libslic3r/Print.cpp:1306 msgid "" "For the Wipe Tower to work with the soluble supports, the support layers " "need to be synchronized with the object layers." msgstr "" -"For the Wipe Tower to work with the soluble supports, the support layers " -"need to be synchronized with the object layers." -#: src/libslic3r/Print.cpp:1309 +#: src/libslic3r/Print.cpp:1310 msgid "" "The Wipe Tower currently supports the non-soluble supports only if they are " "printed with the current extruder without triggering a tool change. (both " "support_material_extruder and support_material_interface_extruder need to be " "set to 0)." msgstr "" -"The Wipe Tower currently supports the non-soluble supports only if they are " -"printed with the current extruder without triggering a tool change. (both " -"support_material_extruder and support_material_interface_extruder need to be " -"set to 0)." -#: src/libslic3r/Print.cpp:1316 +#: src/libslic3r/Print.cpp:1317 msgid "first_layer_height" -msgstr "first_layer_height" +msgstr "" -#: src/libslic3r/Print.cpp:1331 +#: src/libslic3r/Print.cpp:1332 msgid "First layer height can't be greater than nozzle diameter" -msgstr "First layer height can't be greater than nozzle diameter" +msgstr "" -#: src/libslic3r/Print.cpp:1335 +#: src/libslic3r/Print.cpp:1336 msgid "Layer height can't be greater than nozzle diameter" -msgstr "Layer height can't be greater than nozzle diameter" +msgstr "" #: src/libslic3r/SLAPrint.cpp:55 msgid "Slicing model" -msgstr "Slicing model" +msgstr "" -#: src/libslic3r/SLAPrint.cpp:56 src/libslic3r/SLAPrint.cpp:801 +#: src/libslic3r/SLAPrint.cpp:56 src/libslic3r/SLAPrint.cpp:804 msgid "Generating support points" -msgstr "Generating support points" +msgstr "" #: src/libslic3r/SLAPrint.cpp:57 msgid "Generating support tree" -msgstr "Generating support tree" +msgstr "" #: src/libslic3r/SLAPrint.cpp:58 msgid "Generating pad" -msgstr "Generating pad" +msgstr "" #: src/libslic3r/SLAPrint.cpp:59 msgid "Slicing supports" -msgstr "Slicing supports" +msgstr "" #: src/libslic3r/SLAPrint.cpp:71 msgid "Merging slices and calculating statistics" -msgstr "Merging slices and calculating statistics" +msgstr "" #: src/libslic3r/SLAPrint.cpp:72 msgid "Rasterizing layers" -msgstr "Rasterizing layers" +msgstr "" -#: src/libslic3r/SLAPrint.cpp:605 +#: src/libslic3r/SLAPrint.cpp:606 msgid "" "Cannot proceed without support points! Add support points or disable support " "generation." msgstr "" -"Cannot proceed without support points! Add support points or disable support " -"generation." -#: src/libslic3r/SLAPrint.cpp:617 +#: src/libslic3r/SLAPrint.cpp:618 msgid "Elevation is too low for object." -msgstr "Elevation is too low for object." +msgstr "" -#: src/libslic3r/SLAPrint.cpp:699 +#. TRN To be shown at the status bar on SLA slicing error. +#: src/libslic3r/SLAPrint.cpp:701 msgid "Slicing had to be stopped due to an internal error." -msgstr "Slicing had to be stopped due to an internal error." +msgstr "" -#: src/libslic3r/SLAPrint.cpp:849 src/libslic3r/SLAPrint.cpp:859 -#: src/libslic3r/SLAPrint.cpp:907 +#: src/libslic3r/SLAPrint.cpp:852 src/libslic3r/SLAPrint.cpp:862 +#: src/libslic3r/SLAPrint.cpp:910 msgid "Visualizing supports" -msgstr "Visualizing supports" +msgstr "" -#: src/libslic3r/SLAPrint.cpp:1449 +#: src/libslic3r/SLAPrint.cpp:1452 msgid "Slicing done" -msgstr "Slicing done" +msgstr "" #: src/libslic3r/PrintBase.cpp:65 msgid "Failed processing of the output_filename_format template." -msgstr "Failed processing of the output_filename_format template." +msgstr "" #: src/libslic3r/PrintConfig.cpp:42 src/libslic3r/PrintConfig.cpp:43 msgid "Printer technology" -msgstr "Printer technology" +msgstr "" #: src/libslic3r/PrintConfig.cpp:50 msgid "Bed shape" -msgstr "Bed shape" +msgstr "Forme du plateau" #: src/libslic3r/PrintConfig.cpp:57 msgid "" "This setting controls the height (and thus the total number) of the slices/" "layers. Thinner layers give better accuracy but take more time to print." msgstr "" -"This setting controls the height (and thus the total number) of the slices/" -"layers. Thinner layers give better accuracy but take more time to print." +"Cette option contrôle l'épaisseur (et donc le nombre total) des couches. Des " +"couches plus fines donneront une meilleure précision mais l'impression sera " +"plus longue." #: src/libslic3r/PrintConfig.cpp:64 msgid "Max print height" -msgstr "Max print height" +msgstr "Hauteur maximale d'impression" #: src/libslic3r/PrintConfig.cpp:65 msgid "" "Set this to the maximum height that can be reached by your extruder while " "printing." msgstr "" -"Set this to the maximum height that can be reached by your extruder while " -"printing." +"Réglez cette valeur sur la hauteur maximum que peut atteindre votre " +"extrudeur au cours de l'impression." #: src/libslic3r/PrintConfig.cpp:71 msgid "Slice gap closing radius" -msgstr "Slice gap closing radius" +msgstr "" #: src/libslic3r/PrintConfig.cpp:73 msgid "" @@ -4679,37 +4643,30 @@ msgid "" "triangle mesh slicing. The gap closing operation may reduce the final print " "resolution, therefore it is advisable to keep the value reasonably low." msgstr "" -"Cracks smaller than 2x gap closing radius are being filled during the " -"triangle mesh slicing. The gap closing operation may reduce the final print " -"resolution, therefore it is advisable to keep the value reasonably low." #: src/libslic3r/PrintConfig.cpp:81 msgid "Hostname, IP or URL" -msgstr "Hostname, IP or URL" +msgstr "Nom d'hôte, IP ou URL" #: src/libslic3r/PrintConfig.cpp:82 msgid "" "Slic3r can upload G-code files to a printer host. This field should contain " "the hostname, IP address or URL of the printer host instance." msgstr "" -"Slic3r can upload G-code files to a printer host. This field should contain " -"the hostname, IP address or URL of the printer host instance." #: src/libslic3r/PrintConfig.cpp:88 msgid "API Key / Password" -msgstr "API Key / Password" +msgstr "" #: src/libslic3r/PrintConfig.cpp:89 msgid "" "Slic3r can upload G-code files to a printer host. This field should contain " "the API Key or the password required for authentication." msgstr "" -"Slic3r can upload G-code files to a printer host. This field should contain " -"the API Key or the password required for authentication." #: src/libslic3r/PrintConfig.cpp:111 msgid "Avoid crossing perimeters" -msgstr "Avoid crossing perimeters" +msgstr "Éviter de traverser les périmètres" #: src/libslic3r/PrintConfig.cpp:112 msgid "" @@ -4717,25 +4674,27 @@ msgid "" "is mostly useful with Bowden extruders which suffer from oozing. This " "feature slows down both the print and the G-code generation." msgstr "" -"Optimize travel moves in order to minimize the crossing of perimeters. This " -"is mostly useful with Bowden extruders which suffer from oozing. This " -"feature slows down both the print and the G-code generation." +"Optimiser les déplacements afin de minimiser le franchissement de " +"périmètres. Ceci est surtout utile avec les extruder Bowden qui sont sujets " +"aux coulures. Cette fonctionnalité ralentit l'impression et la génération du " +"G-code." #: src/libslic3r/PrintConfig.cpp:119 src/libslic3r/PrintConfig.cpp:1976 msgid "Other layers" -msgstr "Other layers" +msgstr "Autres couches" #: src/libslic3r/PrintConfig.cpp:120 msgid "" "Bed temperature for layers after the first one. Set this to zero to disable " "bed temperature control commands in the output." msgstr "" -"Bed temperature for layers after the first one. Set this to zero to disable " -"bed temperature control commands in the output." +"Température du plateau pour les couches après la première. Mettez ceci à " +"zéro pour désactiver les commandes de contrôle de température du plateau " +"dans la sortie." #: src/libslic3r/PrintConfig.cpp:122 msgid "Bed temperature" -msgstr "Bed temperature" +msgstr "Température du plateau" #: src/libslic3r/PrintConfig.cpp:129 msgid "" @@ -4743,13 +4702,13 @@ msgid "" "Note that you can use placeholder variables for all Slic3r settings as well " "as [layer_num] and [layer_z]." msgstr "" -"This custom code is inserted at every layer change, right before the Z move. " -"Note that you can use placeholder variables for all Slic3r settings as well " -"as [layer_num] and [layer_z]." +"Ce code personnalisé est inséré à chaque changement de couche, juste avant " +"le mouvement en Z. Notez que vous pouvez utiliser des variables génériques " +"pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]." #: src/libslic3r/PrintConfig.cpp:139 msgid "Between objects G-code" -msgstr "Between objects G-code" +msgstr "Entre le G-code des objets" #: src/libslic3r/PrintConfig.cpp:140 msgid "" @@ -4760,32 +4719,34 @@ msgid "" "variables for all Slic3r settings, so you can put a \"M109 " "S[first_layer_temperature]\" command wherever you want." msgstr "" -"This code is inserted between objects when using sequential printing. By " -"default extruder and bed temperature are reset using non-wait command; " -"however if M104, M109, M140 or M190 are detected in this custom code, Slic3r " -"will not add temperature commands. Note that you can use placeholder " -"variables for all Slic3r settings, so you can put a \"M109 " -"S[first_layer_temperature]\" command wherever you want." +"Ce code est inséré entre des objets lorsque vous utilisez l'impression " +"séquentielle. Par défaut la température de l'extrudeur et du plateau est " +"réinitialisée et utilise la commande sans-attente ; toutefois si des " +"commandes M104, M109, M140 ou M190 sont détectées dans ce code personnalisé, " +"Slic3r n'ajoutera pas de commandes de température. Notez que vous pouvez " +"utiliser des variables génériques pour tous les réglages de Slic3r, donc " +"vous pouvez entrer une commande \"M109S[first_layer_temperature]\" où vous " +"le souhaitez." #: src/libslic3r/PrintConfig.cpp:150 msgid "Number of solid layers to generate on bottom surfaces." -msgstr "Number of solid layers to generate on bottom surfaces." +msgstr "Nombre de couches solides à générer sur les surfaces inférieures." #: src/libslic3r/PrintConfig.cpp:151 msgid "Bottom solid layers" -msgstr "Bottom solid layers" +msgstr "Couches solides inférieures" #: src/libslic3r/PrintConfig.cpp:156 msgid "Bridge" -msgstr "Bridge" +msgstr "Pont" #: src/libslic3r/PrintConfig.cpp:157 msgid "" "This is the acceleration your printer will use for bridges. Set zero to " "disable acceleration control for bridges." msgstr "" -"This is the acceleration your printer will use for bridges. Set zero to " -"disable acceleration control for bridges." +"L'accélération qui sera utilisée par votre imprimante pour les ponts. Régler " +"sur zéro pour désactiver l'accélération pour les ponts." #: src/libslic3r/PrintConfig.cpp:159 src/libslic3r/PrintConfig.cpp:302 #: src/libslic3r/PrintConfig.cpp:814 src/libslic3r/PrintConfig.cpp:935 @@ -4796,7 +4757,7 @@ msgstr "mm/s²" #: src/libslic3r/PrintConfig.cpp:165 msgid "Bridging angle" -msgstr "Bridging angle" +msgstr "Angle du pont" #: src/libslic3r/PrintConfig.cpp:167 msgid "" @@ -4804,35 +4765,36 @@ msgid "" "calculated automatically. Otherwise the provided angle will be used for all " "bridges. Use 180° for zero angle." msgstr "" -"Bridging angle override. If left to zero, the bridging angle will be " -"calculated automatically. Otherwise the provided angle will be used for all " -"bridges. Use 180° for zero angle." +"Contournement de l'angle du pont. Si laissé à zéro, l'angle du pont sera " +"calculé automatiquement. Sinon, l'angle fourni sera utilisé pour tous les " +"ponts. Utilisez 180° pour un angle nul." #: src/libslic3r/PrintConfig.cpp:170 src/libslic3r/PrintConfig.cpp:732 #: src/libslic3r/PrintConfig.cpp:1569 src/libslic3r/PrintConfig.cpp:1579 #: src/libslic3r/PrintConfig.cpp:1807 src/libslic3r/PrintConfig.cpp:1961 -#: src/libslic3r/PrintConfig.cpp:2459 +#: src/libslic3r/PrintConfig.cpp:2461 msgid "°" msgstr "°" #: src/libslic3r/PrintConfig.cpp:176 msgid "Bridges fan speed" -msgstr "Bridges fan speed" +msgstr "Vitesse du ventilateur pour les ponts" #: src/libslic3r/PrintConfig.cpp:177 msgid "This fan speed is enforced during all bridges and overhangs." -msgstr "This fan speed is enforced during all bridges and overhangs." +msgstr "" +"Cette vitesse de ventilateur sera utilisée pour les ponts et les surplombs." #: src/libslic3r/PrintConfig.cpp:178 src/libslic3r/PrintConfig.cpp:744 #: src/libslic3r/PrintConfig.cpp:1153 src/libslic3r/PrintConfig.cpp:1216 #: src/libslic3r/PrintConfig.cpp:1461 src/libslic3r/PrintConfig.cpp:2258 -#: src/libslic3r/PrintConfig.cpp:2498 +#: src/libslic3r/PrintConfig.cpp:2500 msgid "%" msgstr "%" #: src/libslic3r/PrintConfig.cpp:185 msgid "Bridge flow ratio" -msgstr "Bridge flow ratio" +msgstr "Ratio de flux pour les ponts" #: src/libslic3r/PrintConfig.cpp:187 msgid "" @@ -4841,18 +4803,18 @@ msgid "" "settings are usually good and you should experiment with cooling (use a fan) " "before tweaking this." msgstr "" -"This factor affects the amount of plastic for bridging. You can decrease it " -"slightly to pull the extrudates and prevent sagging, although default " -"settings are usually good and you should experiment with cooling (use a fan) " -"before tweaking this." +"Ce facteur affecte la quantité de plastique utilisée pour les ponts. Vous " +"pouvez le diminuer légèrement pour éviter l'affaissement. La valeur par " +"défaut est généralement suffisante et vous devriez expérimenter le " +"refroidissement (utiliser un ventilateur) avant de modifier ceci." #: src/libslic3r/PrintConfig.cpp:197 msgid "Bridges" -msgstr "Bridges" +msgstr "Ponts" #: src/libslic3r/PrintConfig.cpp:199 msgid "Speed for printing bridges." -msgstr "Speed for printing bridges." +msgstr "Vitesse d'impression des ponts." #: src/libslic3r/PrintConfig.cpp:200 src/libslic3r/PrintConfig.cpp:576 #: src/libslic3r/PrintConfig.cpp:584 src/libslic3r/PrintConfig.cpp:593 @@ -4869,19 +4831,19 @@ msgstr "mm/s" #: src/libslic3r/PrintConfig.cpp:207 msgid "Brim width" -msgstr "Brim width" +msgstr "Largeur de la bordure" #: src/libslic3r/PrintConfig.cpp:208 msgid "" "Horizontal width of the brim that will be printed around each object on the " "first layer." msgstr "" -"Horizontal width of the brim that will be printed around each object on the " -"first layer." +"Largeur horizontale de la bordure qui sera imprimée autour de chaque objet " +"sur la première couche." #: src/libslic3r/PrintConfig.cpp:215 msgid "Clip multi-part objects" -msgstr "Clip multi-part objects" +msgstr "Dissocier les objets multi-pièces" #: src/libslic3r/PrintConfig.cpp:216 msgid "" @@ -4889,21 +4851,22 @@ msgid "" "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)." msgstr "" -"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)." +"Lorsque vous imprimez des objets multi-matériaux, ce réglage fera en sorte " +"que Slic3r rattache ensemble les parties de l'objet qui se superposent (la " +"2e partie sera rattachée à la 1ere, la 3e partie sera rattachée à la 1ere et " +"la 2e, etc...)." #: src/libslic3r/PrintConfig.cpp:223 msgid "Colorprint height" -msgstr "Colorprint height" +msgstr "" #: src/libslic3r/PrintConfig.cpp:224 msgid "Heights at which a filament change is to occur. " -msgstr "Heights at which a filament change is to occur. " +msgstr "" #: src/libslic3r/PrintConfig.cpp:234 msgid "Compatible printers condition" -msgstr "Compatible printers condition" +msgstr "Condition de compatibilité des imprimantes" #: src/libslic3r/PrintConfig.cpp:235 msgid "" @@ -4911,13 +4874,13 @@ msgid "" "profile. If this expression evaluates to true, this profile is considered " "compatible with the active printer profile." msgstr "" -"A boolean expression using the configuration values of an active printer " -"profile. If this expression evaluates to true, this profile is considered " -"compatible with the active printer profile." +"Une expression booléenne utilisant les valeurs de configuration d'un profil " +"d'imprimante actif. Si cette expression est évaluée comme vraie, ce profil " +"est considéré comme compatible avec le profil d'imprimante actif." #: src/libslic3r/PrintConfig.cpp:249 msgid "Compatible print profiles condition" -msgstr "Compatible print profiles condition" +msgstr "" #: src/libslic3r/PrintConfig.cpp:250 msgid "" @@ -4925,13 +4888,10 @@ msgid "" "profile. If this expression evaluates to true, this profile is considered " "compatible with the active print profile." msgstr "" -"A boolean expression using the configuration values of an active print " -"profile. If this expression evaluates to true, this profile is considered " -"compatible with the active print profile." #: src/libslic3r/PrintConfig.cpp:267 msgid "Complete individual objects" -msgstr "Complete individual objects" +msgstr "Compléter les objets individuels" #: src/libslic3r/PrintConfig.cpp:268 msgid "" @@ -4940,39 +4900,44 @@ msgid "" "This feature is useful to avoid the risk of ruined prints. Slic3r should " "warn and prevent you from extruder collisions, but beware." msgstr "" -"When printing multiple objects or copies, this feature will complete each " -"object before moving onto next one (and starting it from its bottom layer). " -"This feature is useful to avoid the risk of ruined prints. Slic3r should " -"warn and prevent you from extruder collisions, but beware." +"Lorsque vous imprimez plusieurs objets ou copies, ce réglage permet de " +"terminer un objet avant de passer au suivant (en repartant de sa première " +"couche). Cette fonction est utile pour éviter les risques d'impressions " +"gâchées. Slic3r doit vous avertir et éviter les collisions entre les objets " +"et l'extrudeur, mais soyez vigilant." #: src/libslic3r/PrintConfig.cpp:276 msgid "Enable auto cooling" -msgstr "Enable auto cooling" +msgstr "Activer le refroidissement automatique" #: src/libslic3r/PrintConfig.cpp:277 msgid "" "This flag enables the automatic cooling logic that adjusts print speed and " "fan speed according to layer printing time." msgstr "" -"This flag enables the automatic cooling logic that adjusts print speed and " -"fan speed according to layer printing time." +"Cette option active la logique de refroidissement automatique, qui ajuste la " +"vitesse d'impression et celle du ventilateur en fonction du temps " +"d'impression de la couche." #: src/libslic3r/PrintConfig.cpp:282 msgid "Cooling tube position" -msgstr "Cooling tube position" +msgstr "Position du tube de refroidissement" #: src/libslic3r/PrintConfig.cpp:283 msgid "Distance of the center-point of the cooling tube from the extruder tip " msgstr "" -"Distance of the center-point of the cooling tube from the extruder tip " +"Distance entre le point central du tube de refroidissement et la pointe de " +"l'extrudeur. " #: src/libslic3r/PrintConfig.cpp:290 msgid "Cooling tube length" -msgstr "Cooling tube length" +msgstr "Longueur du tube de refroidissement" #: src/libslic3r/PrintConfig.cpp:291 msgid "Length of the cooling tube to limit space for cooling moves inside it " -msgstr "Length of the cooling tube to limit space for cooling moves inside it " +msgstr "" +"Longueur du tube de refroidissement pour limiter l'espace pour les " +"déplacements de refroidissement à l'intérieur de celui-ci " #: src/libslic3r/PrintConfig.cpp:299 msgid "" @@ -4980,13 +4945,13 @@ msgid "" "specific acceleration values are used (perimeter/infill). Set zero to " "prevent resetting acceleration at all." msgstr "" -"This is the acceleration your printer will be reset to after the role-" -"specific acceleration values are used (perimeter/infill). Set zero to " -"prevent resetting acceleration at all." +"Accélération à laquelle votre imprimante sera réinitialisée suite à une " +"modification de l'accélération des fonctions spécifiques (périmètre/" +"remplissage). Régler sur zéro pour ne pas réinitialiser l'accélération." #: src/libslic3r/PrintConfig.cpp:308 msgid "Default filament profile" -msgstr "Default filament profile" +msgstr "Profil de filament par défaut" #: src/libslic3r/PrintConfig.cpp:309 msgid "" @@ -4994,83 +4959,85 @@ msgid "" "selection of the current printer profile, this filament profile will be " "activated." msgstr "" -"Default filament profile associated with the current printer profile. On " -"selection of the current printer profile, this filament profile will be " -"activated." +"Profil de filament par défaut associé au profil d'imprimante courant. En " +"sélectionnant le profil d'imprimante courant, ce profil de filament sera " +"activé." #: src/libslic3r/PrintConfig.cpp:315 msgid "Default print profile" -msgstr "Default print profile" +msgstr "Profil de filament par défaut" -#: src/libslic3r/PrintConfig.cpp:316 src/libslic3r/PrintConfig.cpp:2337 -#: src/libslic3r/PrintConfig.cpp:2348 +#: src/libslic3r/PrintConfig.cpp:316 src/libslic3r/PrintConfig.cpp:2339 +#: src/libslic3r/PrintConfig.cpp:2350 msgid "" "Default print profile associated with the current printer profile. On " "selection of the current printer profile, this print profile will be " "activated." msgstr "" -"Default print profile associated with the current printer profile. On " -"selection of the current printer profile, this print profile will be " -"activated." +"Profil de filament par défaut associé au profil d'imprimante courant. En " +"sélectionnant le profil d'imprimante courant, ce profil de filament sera " +"activé." #: src/libslic3r/PrintConfig.cpp:322 msgid "Disable fan for the first" -msgstr "Disable fan for the first" +msgstr "Désactiver le ventilateur pour le(s) première(s)" #: src/libslic3r/PrintConfig.cpp:323 msgid "" "You can set this to a positive value to disable fan at all during the first " "layers, so that it does not make adhesion worse." msgstr "" -"You can set this to a positive value to disable fan at all during the first " -"layers, so that it does not make adhesion worse." +"Vous pouvez régler ce paramètre sur une valeur positive pour désactiver " +"complètement le ventilateur pendant les premières couches, afin de ne pas " +"rendre l'adhérence plus difficile." #: src/libslic3r/PrintConfig.cpp:325 src/libslic3r/PrintConfig.cpp:945 #: src/libslic3r/PrintConfig.cpp:1434 src/libslic3r/PrintConfig.cpp:1619 #: src/libslic3r/PrintConfig.cpp:1680 src/libslic3r/PrintConfig.cpp:1843 #: src/libslic3r/PrintConfig.cpp:1888 msgid "layers" -msgstr "layers" +msgstr "couches" #: src/libslic3r/PrintConfig.cpp:332 msgid "Don't support bridges" -msgstr "Don't support bridges" +msgstr "Ne pas supporter les ponts" #: src/libslic3r/PrintConfig.cpp:334 msgid "" "Experimental option for preventing support material from being generated " "under bridged areas." msgstr "" -"Experimental option for preventing support material from being generated " -"under bridged areas." +"Option expérimentale pour empêcher la génération de support sous les ponts." #: src/libslic3r/PrintConfig.cpp:340 msgid "Distance between copies" -msgstr "Distance between copies" +msgstr "Distance entre les copies" #: src/libslic3r/PrintConfig.cpp:341 msgid "Distance used for the auto-arrange feature of the plater." -msgstr "Distance used for the auto-arrange feature of the plater." +msgstr "Distance utilisée par la fonction d'agencement automatique du plateau." #: src/libslic3r/PrintConfig.cpp:348 msgid "Elephant foot compensation" -msgstr "Elephant foot compensation" +msgstr "Compensation de l'effet patte d'éléphant" #: src/libslic3r/PrintConfig.cpp:350 msgid "" "The first layer will be shrunk in the XY plane by the configured value to " "compensate for the 1st layer squish aka an Elephant Foot effect." msgstr "" -"The first layer will be shrunk in the XY plane by the configured value to " -"compensate for the 1st layer squish aka an Elephant Foot effect." +"La première couche sera réduite sur le plan XY selon la valeur configurée " +"afin de compenser l'écrasement de la première couche également connu sous le " +"nom d'effet Pied d'Éléphant." #: src/libslic3r/PrintConfig.cpp:359 msgid "" "This end procedure is inserted at the end of the output file. Note that you " "can use placeholder variables for all Slic3r settings." msgstr "" -"This end procedure is inserted at the end of the output file. Note that you " -"can use placeholder variables for all Slic3r settings." +"Cette procédure de fin est insérée à la fin du fichier de sortie. Notez que " +"vous pouvez utiliser des variables génériques pour tous les réglages de " +"Slic3r." #: src/libslic3r/PrintConfig.cpp:369 msgid "" @@ -5079,71 +5046,68 @@ msgid "" "Slic3r settings. If you have multiple extruders, the gcode is processed in " "extruder order." msgstr "" -"This end procedure is inserted at the end of the output file, before the " -"printer end gcode. Note that you can use placeholder variables for all " -"Slic3r settings. If you have multiple extruders, the gcode is processed in " -"extruder order." +"Cette procédure de fin est insérée à la fin du fichier de sortie, avant le " +"gcode de fin de l'imprimante. Notez que vous pouvez utiliser des variables " +"génériques pour tous les réglages de Slic3r. Si vous avez plusieurs " +"extrudeurs, le gcode sera traité suivant l'ordre des extrudeurs." #: src/libslic3r/PrintConfig.cpp:379 msgid "Ensure vertical shell thickness" -msgstr "Ensure vertical shell thickness" +msgstr "S'assurer de l'épaisseur de la coque verticale" #: src/libslic3r/PrintConfig.cpp:381 msgid "" "Add solid infill near sloping surfaces to guarantee the vertical shell " "thickness (top+bottom solid layers)." msgstr "" -"Add solid infill near sloping surfaces to guarantee the vertical shell " -"thickness (top+bottom solid layers)." +"Ajouter un remplissage plein à proximité des surfaces inclinées pour " +"garantir une épaisseur de coque verticale (couches solides supérieures" +"+inférieures)." #: src/libslic3r/PrintConfig.cpp:387 msgid "Top fill pattern" -msgstr "Top fill pattern" +msgstr "" #: src/libslic3r/PrintConfig.cpp:389 msgid "" "Fill pattern for top infill. This only affects the top visible layer, and " "not its adjacent solid shells." msgstr "" -"Fill pattern for top infill. This only affects the top visible layer, and " -"not its adjacent solid shells." #: src/libslic3r/PrintConfig.cpp:397 src/libslic3r/PrintConfig.cpp:795 #: src/libslic3r/PrintConfig.cpp:1921 msgid "Rectilinear" -msgstr "Rectilinear" +msgstr "" #: src/libslic3r/PrintConfig.cpp:398 src/libslic3r/PrintConfig.cpp:801 msgid "Concentric" -msgstr "Concentric" +msgstr "" #: src/libslic3r/PrintConfig.cpp:399 src/libslic3r/PrintConfig.cpp:805 msgid "Hilbert Curve" -msgstr "Hilbert Curve" +msgstr "" #: src/libslic3r/PrintConfig.cpp:400 src/libslic3r/PrintConfig.cpp:806 msgid "Archimedean Chords" -msgstr "Archimedean Chords" +msgstr "" #: src/libslic3r/PrintConfig.cpp:401 src/libslic3r/PrintConfig.cpp:807 msgid "Octagram Spiral" -msgstr "Octagram Spiral" +msgstr "" #: src/libslic3r/PrintConfig.cpp:408 msgid "Bottom fill pattern" -msgstr "Bottom fill pattern" +msgstr "" #: src/libslic3r/PrintConfig.cpp:409 msgid "" "Fill pattern for bottom infill. This only affects the bottom external " "visible layer, and not its adjacent solid shells." msgstr "" -"Fill pattern for bottom infill. This only affects the bottom external " -"visible layer, and not its adjacent solid shells." #: src/libslic3r/PrintConfig.cpp:414 src/libslic3r/PrintConfig.cpp:424 msgid "External perimeters" -msgstr "External perimeters" +msgstr "Périmètres externes" #: src/libslic3r/PrintConfig.cpp:416 msgid "" @@ -5152,17 +5116,19 @@ msgid "" "otherwise 1.125 x nozzle diameter will be used. If expressed as percentage " "(for example 200%), it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for external " -"perimeters. If left zero, default extrusion width will be used if set, " -"otherwise 1.125 x nozzle diameter will be used. If expressed as percentage " -"(for example 200%), it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour les périmètres extérieurs. Si la valeur reste sur " +"zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon la " +"valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est exprimée " +"en pourcentage (par exemple : 200%), elle sera calculée par rapport à la " +"hauteur de couche." #: src/libslic3r/PrintConfig.cpp:419 src/libslic3r/PrintConfig.cpp:834 #: src/libslic3r/PrintConfig.cpp:966 src/libslic3r/PrintConfig.cpp:1353 #: src/libslic3r/PrintConfig.cpp:1691 src/libslic3r/PrintConfig.cpp:1864 #: src/libslic3r/PrintConfig.cpp:2022 msgid "mm or % (leave 0 for default)" -msgstr "mm or % (leave 0 for default)" +msgstr "mm ou % (laissez à 0 pour la valeur par défaut)" #: src/libslic3r/PrintConfig.cpp:426 msgid "" @@ -5170,42 +5136,43 @@ msgid "" "visible ones). If expressed as percentage (for example: 80%) it will be " "calculated on the perimeters speed setting above. Set to zero for auto." msgstr "" -"This separate setting will affect the speed of external perimeters (the " -"visible ones). If expressed as percentage (for example: 80%) it will be " -"calculated on the perimeters speed setting above. Set to zero for auto." +"Ce réglage distinct affectera la vitesse des périmètres extérieurs (ceux qui " +"sont visibles). Si cette valeur est exprimée en pourcentage (par exemple: " +"80%) elle sera calculée d'après le réglage de la vitesse de périmètre " +"susmentionnée. Réglez sur zéro pour un ajustement automatique." #: src/libslic3r/PrintConfig.cpp:429 src/libslic3r/PrintConfig.cpp:855 #: src/libslic3r/PrintConfig.cpp:1650 src/libslic3r/PrintConfig.cpp:1701 #: src/libslic3r/PrintConfig.cpp:1907 src/libslic3r/PrintConfig.cpp:2034 msgid "mm/s or %" -msgstr "mm/s or %" +msgstr "mm/s ou %" #: src/libslic3r/PrintConfig.cpp:436 msgid "External perimeters first" -msgstr "External perimeters first" +msgstr "Périmètres externes en premier" #: src/libslic3r/PrintConfig.cpp:438 msgid "" "Print contour perimeters from the outermost one to the innermost one instead " "of the default inverse order." msgstr "" -"Print contour perimeters from the outermost one to the innermost one instead " -"of the default inverse order." +"Imprimer les périmètres de l'extérieur vers l'intérieur au lieu de l'ordre " +"par défaut qui est inversé." #: src/libslic3r/PrintConfig.cpp:444 msgid "Extra perimeters if needed" -msgstr "Extra perimeters if needed" +msgstr "Périmètres supplémentaires si nécessaire" #: src/libslic3r/PrintConfig.cpp:446 -#, no-c-format +#, fuzzy, c-format msgid "" "Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r " "keeps adding perimeters, until more than 70% of the loop immediately above " "is supported." msgstr "" -"Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r " -"keeps adding perimeters, until more than 70% of the loop immediately above " -"is supported." +"Ajouter plus de périmètres si nécessaire pour éviter des trous dans les " +"parois inclinées. Slic3r ajoute des périmètres, jusqu'à ce que plus de " +"70% de la boucle immédiatement au-dessus soit supportée." #: src/libslic3r/PrintConfig.cpp:456 msgid "" @@ -5213,9 +5180,9 @@ msgid "" "This value overrides perimeter and infill extruders, but not the support " "extruders." msgstr "" -"The extruder to use (unless more specific extruder settings are specified). " -"This value overrides perimeter and infill extruders, but not the support " -"extruders." +"L'extrudeur à utiliser (à moins que d'autres réglages d'extrudeur plus " +"spécifiques soient spécifiés). Cette valeur se substitue aux extrudeurs de " +"périmètre et de remplissage, mais pas aux extrudeurs de support." #: src/libslic3r/PrintConfig.cpp:468 msgid "" @@ -5224,14 +5191,15 @@ msgid "" "cylinder around your extruder, and it represents the maximum depth the " "extruder can peek before colliding with other printed objects." msgstr "" -"Set this to the vertical distance between your nozzle tip and (usually) the " -"X carriage rods. In other words, this is the height of the clearance " -"cylinder around your extruder, and it represents the maximum depth the " -"extruder can peek before colliding with other printed objects." +"Paramétrez ceci avec la distance verticale entre la pointe de la buse et " +"(habituellement) les tiges du chariot de l'axe X. En d'autres termes, il " +"s'agit de la hauteur du cylindre de dégagement autour de l'extrudeur, et " +"elle représente la profondeur maximum à laquelle peut descendre l'extrudeur " +"avant d'entrer en collision avec d'autres objets imprimés." #: src/libslic3r/PrintConfig.cpp:478 msgid "Radius" -msgstr "Radius" +msgstr "Rayon" #: src/libslic3r/PrintConfig.cpp:479 msgid "" @@ -5239,21 +5207,24 @@ msgid "" "not centered, choose the largest value for safety. This setting is used to " "check for collisions and to display the graphical preview in the plater." msgstr "" -"Set this to the clearance radius around your extruder. If the extruder is " -"not centered, choose the largest value for safety. This setting is used to " -"check for collisions and to display the graphical preview in the plater." +"Paramétrez ceci avec le rayon de dégagement autour de l'extrudeur. Si " +"l'extrudeur n'est pas centré, choisissez la plus grande valeur par sécurité. " +"Ce réglage est utilisé pour vérifier les collisions et afficher l'aperçu " +"graphique sur le plateau." #: src/libslic3r/PrintConfig.cpp:489 msgid "Extruder Color" -msgstr "Extruder Color" +msgstr "Couleur de l'extrudeur" #: src/libslic3r/PrintConfig.cpp:490 src/libslic3r/PrintConfig.cpp:550 msgid "This is only used in the Slic3r interface as a visual help." -msgstr "This is only used in the Slic3r interface as a visual help." +msgstr "" +"Ceci est uniquement utilisé dans l'interface de Slic3r comme indication " +"visuelle." #: src/libslic3r/PrintConfig.cpp:496 msgid "Extruder offset" -msgstr "Extruder offset" +msgstr "Décalage de l'extrudeur" #: src/libslic3r/PrintConfig.cpp:497 msgid "" @@ -5262,26 +5233,26 @@ msgid "" "of each extruder with respect to the first one. It expects positive " "coordinates (they will be subtracted from the XY coordinate)." msgstr "" -"If your firmware doesn't handle the extruder displacement you need the G-" -"code to take it into account. This option lets you specify the displacement " -"of each extruder with respect to the first one. It expects positive " -"coordinates (they will be subtracted from the XY coordinate)." +"Si le firmware de votre imprimante ne gère pas le décalage de l'extrudeur, " +"c'est au G-code d'en tenir compte. Cette option vous permet de spécifier le " +"décalage de chaque extrudeur par rapport au premier. Des valeurs positives " +"sont attendues (elles seront soustraites des coordonnées XY)." #: src/libslic3r/PrintConfig.cpp:506 msgid "Extrusion axis" -msgstr "Extrusion axis" +msgstr "Axe d'extrusion" #: src/libslic3r/PrintConfig.cpp:507 msgid "" "Use this option to set the axis letter associated to your printer's extruder " "(usually E but some printers use A)." msgstr "" -"Use this option to set the axis letter associated to your printer's extruder " -"(usually E but some printers use A)." +"Utiliser cette option pour indiquer la lettre utilisée par l'extrudeur de " +"votre imprimante (habituellement E, mais certaines imprimantes utilisent A)." #: src/libslic3r/PrintConfig.cpp:512 msgid "Extrusion multiplier" -msgstr "Extrusion multiplier" +msgstr "Multiplicateur d'extrusion" #: src/libslic3r/PrintConfig.cpp:513 msgid "" @@ -5290,14 +5261,15 @@ msgid "" "Usual values are between 0.9 and 1.1. If you think you need to change this " "more, check filament diameter and your firmware E steps." msgstr "" -"This factor changes the amount of flow proportionally. You may need to tweak " -"this setting to get nice surface finish and correct single wall widths. " -"Usual values are between 0.9 and 1.1. If you think you need to change this " -"more, check filament diameter and your firmware E steps." +"Ce facteur modifie proportionnellement le flux d'extrusion. Vous pouvez " +"avoir besoin de modifier ceci afin d'obtenir un rendu de surface net et une " +"largeur correcte pour les murs uniques. Les valeurs habituelles vont de 0.9 " +"à 1.1. Si vous pensez devoir changer davantage cette valeur, vérifiez le " +"diamètre de votre filament et les E Steps dans le firmware." #: src/libslic3r/PrintConfig.cpp:521 msgid "Default extrusion width" -msgstr "Default extrusion width" +msgstr "Largeur d'extrusion par défaut" #: src/libslic3r/PrintConfig.cpp:523 msgid "" @@ -5307,31 +5279,33 @@ msgid "" "expressed as percentage (for example: 230%), it will be computed over layer " "height." msgstr "" -"Set this to a non-zero value to allow a manual extrusion width. If left to " -"zero, Slic3r derives extrusion widths from the nozzle diameter (see the " -"tooltips for perimeter extrusion width, infill extrusion width etc). If " -"expressed as percentage (for example: 230%), it will be computed over layer " -"height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion. Si la valeur reste sur zéro, Slic3r calcule la largeur " +"d’extrusion en se basant sur le diamètre de la buse (voir l’info-bulle " +"concernant la largeur d’extrusion du périmètre, la largeur d’extrusion du " +"remplissage, etc…). Si la valeur est exprimée en pourcentage (par exemple : " +"230%), elle sera calculée par rapport à la hauteur de couche." #: src/libslic3r/PrintConfig.cpp:527 msgid "mm or % (leave 0 for auto)" -msgstr "mm or % (leave 0 for auto)" +msgstr "mm ou % (laissez à 0 pour le mode automatique)" #: src/libslic3r/PrintConfig.cpp:532 msgid "Keep fan always on" -msgstr "Keep fan always on" +msgstr "Garder le ventilateur toujours actif" #: src/libslic3r/PrintConfig.cpp:533 msgid "" "If this is enabled, fan will never be disabled and will be kept running at " "least at its minimum speed. Useful for PLA, harmful for ABS." msgstr "" -"If this is enabled, fan will never be disabled and will be kept running at " -"least at its minimum speed. Useful for PLA, harmful for ABS." +"Si ceci est activé, le ventilateur ne sera jamais désactivé et sera maintenu " +"au moins à sa vitesse minimum. Utile pour le PLA, mais risqué pour l'ABS." #: src/libslic3r/PrintConfig.cpp:538 msgid "Enable fan if layer print time is below" -msgstr "Enable fan if layer print time is below" +msgstr "" +"Activer le ventilateur si le temps d'impression de la couche est inférieur à" #: src/libslic3r/PrintConfig.cpp:539 msgid "" @@ -5339,29 +5313,29 @@ msgid "" "enabled and its speed will be calculated by interpolating the minimum and " "maximum speeds." msgstr "" -"If layer print time is estimated below this number of seconds, fan will be " -"enabled and its speed will be calculated by interpolating the minimum and " -"maximum speeds." +"Si le temps d'impression estimé de la couche est inférieur à ce nombre de " +"secondes, le ventilateur sera activé et sa vitesse calculée par " +"interpolation des vitesses minimum et maximum." #: src/libslic3r/PrintConfig.cpp:541 src/libslic3r/PrintConfig.cpp:1637 msgid "approximate seconds" -msgstr "approximate seconds" +msgstr "secondes approximatives" #: src/libslic3r/PrintConfig.cpp:549 msgid "Color" -msgstr "Color" +msgstr "Couleur" #: src/libslic3r/PrintConfig.cpp:555 msgid "Filament notes" -msgstr "Filament notes" +msgstr "Notes du filament" #: src/libslic3r/PrintConfig.cpp:556 msgid "You can put your notes regarding the filament here." -msgstr "You can put your notes regarding the filament here." +msgstr "Vous pouvez saisir vos remarques concernant le filament ici." #: src/libslic3r/PrintConfig.cpp:564 src/libslic3r/PrintConfig.cpp:1181 msgid "Max volumetric speed" -msgstr "Max volumetric speed" +msgstr "Vitesse volumétrique maximale" #: src/libslic3r/PrintConfig.cpp:565 msgid "" @@ -5369,9 +5343,9 @@ msgid "" "volumetric speed of a print to the minimum of print and filament volumetric " "speed. Set to zero for no limit." msgstr "" -"Maximum volumetric speed allowed for this filament. Limits the maximum " -"volumetric speed of a print to the minimum of print and filament volumetric " -"speed. Set to zero for no limit." +"Vitesse volumétrique maximale autorisée pour ce filament. Limite la vitesse " +"volumétrique d'une impression au minimum des vitesses volumétriques " +"d'impression et de filament. Mettez à zéro pour enlever la limite." #: src/libslic3r/PrintConfig.cpp:568 src/libslic3r/PrintConfig.cpp:1184 msgid "mm³/s" @@ -5379,45 +5353,44 @@ msgstr "mm³/s" #: src/libslic3r/PrintConfig.cpp:574 msgid "Loading speed" -msgstr "Loading speed" +msgstr "Vitesse de chargement" #: src/libslic3r/PrintConfig.cpp:575 msgid "Speed used for loading the filament on the wipe tower. " -msgstr "Speed used for loading the filament on the wipe tower. " +msgstr "Vitesse utilisée pour charger le filament sur la tour de nettoyage. " #: src/libslic3r/PrintConfig.cpp:582 msgid "Loading speed at the start" -msgstr "Loading speed at the start" +msgstr "" #: src/libslic3r/PrintConfig.cpp:583 msgid "Speed used at the very beginning of loading phase. " -msgstr "Speed used at the very beginning of loading phase. " +msgstr "" #: src/libslic3r/PrintConfig.cpp:590 msgid "Unloading speed" -msgstr "Unloading speed" +msgstr "Vitesse de déchargement" #: src/libslic3r/PrintConfig.cpp:591 msgid "" "Speed used for unloading the filament on the wipe tower (does not affect " "initial part of unloading just after ramming). " msgstr "" -"Speed used for unloading the filament on the wipe tower (does not affect " -"initial part of unloading just after ramming). " +"Vitesse utilisée pour décharger le filament sur la tour de nettoyage " +"(n'affecte pas l'étape initiale de déchargement juste après l'expulsion). " #: src/libslic3r/PrintConfig.cpp:599 msgid "Unloading speed at the start" -msgstr "Unloading speed at the start" +msgstr "" #: src/libslic3r/PrintConfig.cpp:600 msgid "" "Speed used for unloading the tip of the filament immediately after ramming. " msgstr "" -"Speed used for unloading the tip of the filament immediately after ramming. " #: src/libslic3r/PrintConfig.cpp:607 msgid "Delay after unloading" -msgstr "Delay after unloading" +msgstr "Délai après le déchargement" #: src/libslic3r/PrintConfig.cpp:608 msgid "" @@ -5425,33 +5398,31 @@ msgid "" "toolchanges with flexible materials that may need more time to shrink to " "original dimensions. " msgstr "" -"Time to wait after the filament is unloaded. May help to get reliable " -"toolchanges with flexible materials that may need more time to shrink to " -"original dimensions. " +"Temps d'attente nécessaire après que le filament ait été déchargé. Peut " +"aider à obtenir des changements d'outils fiables avec des matériaux flexible " +"qui ont besoin de plus de temps pour revenir à leurs dimensions originales. " #: src/libslic3r/PrintConfig.cpp:617 msgid "Number of cooling moves" -msgstr "Number of cooling moves" +msgstr "" #: src/libslic3r/PrintConfig.cpp:618 msgid "" "Filament is cooled by being moved back and forth in the cooling tubes. " "Specify desired number of these moves " msgstr "" -"Filament is cooled by being moved back and forth in the cooling tubes. " -"Specify desired number of these moves " #: src/libslic3r/PrintConfig.cpp:626 msgid "Speed of the first cooling move" -msgstr "Speed of the first cooling move" +msgstr "" #: src/libslic3r/PrintConfig.cpp:627 msgid "Cooling moves are gradually accelerating beginning at this speed. " -msgstr "Cooling moves are gradually accelerating beginning at this speed. " +msgstr "" #: src/libslic3r/PrintConfig.cpp:634 msgid "Minimal purge on wipe tower" -msgstr "Minimal purge on wipe tower" +msgstr "" #: src/libslic3r/PrintConfig.cpp:635 msgid "" @@ -5461,27 +5432,22 @@ msgid "" "object, Slic3r will always prime this amount of material into the wipe tower " "to produce successive infill or sacrificial object extrusions reliably." msgstr "" -"After a tool change, the exact position of the newly loaded filament inside " -"the nozzle may not be known, and the filament pressure is likely not yet " -"stable. Before purging the print head into an infill or a sacrificial " -"object, Slic3r will always prime this amount of material into the wipe tower " -"to produce successive infill or sacrificial object extrusions reliably." #: src/libslic3r/PrintConfig.cpp:639 msgid "mm³" -msgstr "mm³" +msgstr "" #: src/libslic3r/PrintConfig.cpp:645 msgid "Speed of the last cooling move" -msgstr "Speed of the last cooling move" +msgstr "" #: src/libslic3r/PrintConfig.cpp:646 msgid "Cooling moves are gradually accelerating towards this speed. " -msgstr "Cooling moves are gradually accelerating towards this speed. " +msgstr "" #: src/libslic3r/PrintConfig.cpp:653 msgid "Filament load time" -msgstr "Filament load time" +msgstr "" #: src/libslic3r/PrintConfig.cpp:654 msgid "" @@ -5489,25 +5455,22 @@ msgid "" "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" -"Time for the printer firmware (or the Multi Material Unit 2.0) to load a new " -"filament during a tool change (when executing the T code). This time is " -"added to the total print time by the G-code time estimator." #: src/libslic3r/PrintConfig.cpp:661 msgid "Ramming parameters" -msgstr "Ramming parameters" +msgstr "Paramètres de l'expulsion" #: src/libslic3r/PrintConfig.cpp:662 msgid "" "This string is edited by RammingDialog and contains ramming specific " "parameters " msgstr "" -"This string is edited by RammingDialog and contains ramming specific " -"parameters " +"Cette chaine est éditée par RammingDialog et contient les paramètres " +"spécifiques d'expulsion " #: src/libslic3r/PrintConfig.cpp:668 msgid "Filament unload time" -msgstr "Filament unload time" +msgstr "" #: src/libslic3r/PrintConfig.cpp:669 msgid "" @@ -5515,9 +5478,6 @@ msgid "" "filament during a tool change (when executing the T code). This time is " "added to the total print time by the G-code time estimator." msgstr "" -"Time for the printer firmware (or the Multi Material Unit 2.0) to unload a " -"filament during a tool change (when executing the T code). This time is " -"added to the total print time by the G-code time estimator." #: src/libslic3r/PrintConfig.cpp:677 msgid "" @@ -5525,13 +5485,13 @@ msgid "" "caliper and do multiple measurements along the filament, then compute the " "average." msgstr "" -"Enter your filament diameter here. Good precision is required, so use a " -"caliper and do multiple measurements along the filament, then compute the " -"average." +"Entrez le diamètre de votre filament ici. Une bonne précision est requise, " +"utilisez un pied à coulisse et calculez la moyenne de plusieurs mesures le " +"long du filament." #: src/libslic3r/PrintConfig.cpp:684 msgid "Density" -msgstr "Density" +msgstr "Densité" #: src/libslic3r/PrintConfig.cpp:685 msgid "" @@ -5540,10 +5500,11 @@ msgid "" "the length to volume. Better is to calculate the volume directly through " "displacement." msgstr "" -"Enter your filament density here. This is only for statistical information. " -"A decent way is to weigh a known length of filament and compute the ratio of " -"the length to volume. Better is to calculate the volume directly through " -"displacement." +"Entrez ici la densité de votre filament. Ceci est uniquement pour des " +"informations statistiques. Un bon moyen d'obtenir cette valeur est de peser " +"un morceau de filament d'une longueur connue et de calculer le rapport de sa " +"longueur par son poids. Le mieux est de calculer le volume directement par " +"déplacement." #: src/libslic3r/PrintConfig.cpp:688 msgid "g/cm³" @@ -5551,35 +5512,36 @@ msgstr "g/cm³" #: src/libslic3r/PrintConfig.cpp:693 msgid "Filament type" -msgstr "Filament type" +msgstr "Type de filament" #: src/libslic3r/PrintConfig.cpp:694 msgid "The filament material type for use in custom G-codes." -msgstr "The filament material type for use in custom G-codes." +msgstr "" #: src/libslic3r/PrintConfig.cpp:710 msgid "Soluble material" -msgstr "Soluble material" +msgstr "Matériau soluble" #: src/libslic3r/PrintConfig.cpp:711 msgid "Soluble material is most likely used for a soluble support." -msgstr "Soluble material is most likely used for a soluble support." +msgstr "" +"Il est probable qu'un matériau soluble soit utilisé pour un support soluble." #: src/libslic3r/PrintConfig.cpp:717 msgid "" "Enter your filament cost per kg here. This is only for statistical " "information." msgstr "" -"Enter your filament cost per kg here. This is only for statistical " -"information." +"Entrez le coût par Kg de votre filament. Ceci est uniquement pour " +"l'information statistique." #: src/libslic3r/PrintConfig.cpp:718 msgid "money/kg" -msgstr "money/kg" +msgstr "€/kg" #: src/libslic3r/PrintConfig.cpp:727 msgid "Fill angle" -msgstr "Fill angle" +msgstr "Angle du remplissage" #: src/libslic3r/PrintConfig.cpp:729 msgid "" @@ -5587,78 +5549,80 @@ msgid "" "this. Bridges will be infilled using the best direction Slic3r can detect, " "so this setting does not affect them." msgstr "" -"Default base angle for infill orientation. Cross-hatching will be applied to " -"this. Bridges will be infilled using the best direction Slic3r can detect, " -"so this setting does not affect them." +"Angle de base par défaut pour l'orientation du remplissage. Des croisements " +"seront appliqués à cette valeur. Les ponts seront remplis avec la meilleure " +"direction que Slic3r peut détecter, ce réglage ne les affecteront donc pas." #: src/libslic3r/PrintConfig.cpp:741 msgid "Fill density" -msgstr "Fill density" +msgstr "Densité du remplissage" #: src/libslic3r/PrintConfig.cpp:743 msgid "Density of internal infill, expressed in the range 0% - 100%." -msgstr "Density of internal infill, expressed in the range 0% - 100%." +msgstr "Densité du remplissage interne, exprimée en pourcentage de 0% à 100%." #: src/libslic3r/PrintConfig.cpp:778 msgid "Fill pattern" -msgstr "Fill pattern" +msgstr "Motif de remplissage" #: src/libslic3r/PrintConfig.cpp:780 msgid "Fill pattern for general low-density infill." -msgstr "Fill pattern for general low-density infill." +msgstr "Motif pour les remplissages de faible densité." #: src/libslic3r/PrintConfig.cpp:796 msgid "Grid" -msgstr "Grid" +msgstr "" #: src/libslic3r/PrintConfig.cpp:797 msgid "Triangles" -msgstr "Triangles" +msgstr "" #: src/libslic3r/PrintConfig.cpp:798 msgid "Stars" -msgstr "Stars" +msgstr "" #: src/libslic3r/PrintConfig.cpp:799 msgid "Cubic" -msgstr "Cubic" +msgstr "" #: src/libslic3r/PrintConfig.cpp:800 msgid "Line" -msgstr "Line" +msgstr "" #: src/libslic3r/PrintConfig.cpp:802 src/libslic3r/PrintConfig.cpp:1923 msgid "Honeycomb" -msgstr "Honeycomb" +msgstr "" #: src/libslic3r/PrintConfig.cpp:803 msgid "3D Honeycomb" -msgstr "3D Honeycomb" +msgstr "" #: src/libslic3r/PrintConfig.cpp:804 msgid "Gyroid" -msgstr "Gyroid" +msgstr "" #: src/libslic3r/PrintConfig.cpp:811 src/libslic3r/PrintConfig.cpp:820 #: src/libslic3r/PrintConfig.cpp:828 src/libslic3r/PrintConfig.cpp:861 msgid "First layer" -msgstr "First layer" +msgstr "Première couche" #: src/libslic3r/PrintConfig.cpp:812 msgid "" "This is the acceleration your printer will use for first layer. Set zero to " "disable acceleration control for first layer." msgstr "" -"This is the acceleration your printer will use for first layer. Set zero to " -"disable acceleration control for first layer." +"L'accélération que l'imprimante utilisera pour la première couche. Régler " +"sur zéro afin de désactiver le contrôle de l'accélération pour la première " +"couche." #: src/libslic3r/PrintConfig.cpp:821 msgid "" "Heated build plate temperature for the first layer. Set this to zero to " "disable bed temperature control commands in the output." msgstr "" -"Heated build plate temperature for the first layer. Set this to zero to " -"disable bed temperature control commands in the output." +"Température du plateau chauffant pour la première couche. Mettez ceci à zéro " +"pour désactiver les commandes de contrôle de température du plateau dans la " +"sortie." #: src/libslic3r/PrintConfig.cpp:830 msgid "" @@ -5667,14 +5631,16 @@ msgid "" "expressed as percentage (for example 120%) it will be computed over first " "layer height. If set to zero, it will use the default extrusion width." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for first " -"layer. You can use this to force fatter extrudates for better adhesion. If " -"expressed as percentage (for example 120%) it will be computed over first " -"layer height. If set to zero, it will use the default extrusion width." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour la première couche. Vous pouvez procéder ainsi pour " +"obtenir des extrudats plus épais afin d’avoir une meilleure adhérence. Si la " +"valeur est exprimée en pourcentage (par exemple : 120%), elle sera calculée " +"par rapport à la hauteur de la première couche. Si elle est réglée sur zéro, " +"elle utilisera la largeur d’extrusion par défaut." #: src/libslic3r/PrintConfig.cpp:840 msgid "First layer height" -msgstr "First layer height" +msgstr "Hauteur de la première couche" #: src/libslic3r/PrintConfig.cpp:842 msgid "" @@ -5683,19 +5649,20 @@ msgid "" "plates. This can be expressed as an absolute value or as a percentage (for " "example: 150%) over the default layer height." msgstr "" -"When printing with very low layer heights, you might still want to print a " -"thicker bottom layer to improve adhesion and tolerance for non perfect build " -"plates. This can be expressed as an absolute value or as a percentage (for " -"example: 150%) over the default layer height." +"Lors d'une impression avec de très faibles épaisseurs de couche, vous pouvez " +"choisir d'imprimer une première couche plus épaisse pour améliorer " +"l'adhérence et la tolérance aux plateaux imparfaits. Ce réglage peut être " +"exprimé comme une valeur absolue ou un pourcentage (par exemple 150%) par " +"rapport à l'épaisseur de couche par défaut." #: src/libslic3r/PrintConfig.cpp:846 src/libslic3r/PrintConfig.cpp:991 #: src/libslic3r/PrintConfig.cpp:1796 msgid "mm or %" -msgstr "mm or %" +msgstr "mm ou %" #: src/libslic3r/PrintConfig.cpp:851 msgid "First layer speed" -msgstr "First layer speed" +msgstr "Vitesse de la première couche" #: src/libslic3r/PrintConfig.cpp:852 msgid "" @@ -5703,9 +5670,10 @@ msgid "" "the print moves of the first layer, regardless of their type. If expressed " "as a percentage (for example: 40%) it will scale the default speeds." msgstr "" -"If expressed as absolute value in mm/s, this speed will be applied to all " -"the print moves of the first layer, regardless of their type. If expressed " -"as a percentage (for example: 40%) it will scale the default speeds." +"Si exprimée avec une valeur absolue en mm/s, cette vitesse sera appliquée à " +"tous les déplacements d'impression de la première couche, quel que soit leur " +"type. Si exprimée comme un pourcentage (par exemple 40%), cela modulera la " +"vitesse par défaut." #: src/libslic3r/PrintConfig.cpp:862 msgid "" @@ -5713,9 +5681,10 @@ msgid "" "manually during print, set this to zero to disable temperature control " "commands in the output file." msgstr "" -"Extruder temperature for first layer. If you want to control temperature " -"manually during print, set this to zero to disable temperature control " -"commands in the output file." +"Température de l’extrudeur pour la première couche. Si vous voulez contrôler " +"manuellement la température au cours de l’impression, mettez à zéro pour " +"désactiver les commandes de contrôle de température dans le fichier de " +"sortie." #: src/libslic3r/PrintConfig.cpp:871 msgid "" @@ -5723,13 +5692,14 @@ msgid "" "low to avoid too much shaking and resonance issues. Set zero to disable gaps " "filling." msgstr "" -"Speed for filling small gaps using short zigzag moves. Keep this reasonably " -"low to avoid too much shaking and resonance issues. Set zero to disable gaps " -"filling." +"Vitesse pour combler de petits interstices avec de courts mouvements en " +"zigzag. Gardez un réglage relativement lent afin d'éviter les problèmes de " +"vibration et de résonance. Réglez sur zéro pour désactiver le remplissage " +"d'interstices." #: src/libslic3r/PrintConfig.cpp:879 msgid "Verbose G-code" -msgstr "Verbose G-code" +msgstr "G-code commenté" #: src/libslic3r/PrintConfig.cpp:880 msgid "" @@ -5737,13 +5707,14 @@ msgid "" "descriptive text. If you print from SD card, the additional weight of the " "file could make your firmware slow down." msgstr "" -"Enable this to get a commented G-code file, with each line explained by a " -"descriptive text. If you print from SD card, the additional weight of the " -"file could make your firmware slow down." +"Activez ceci pour obtenir un fichier G-code commenté, avec chaque ligne " +"expliquée par un texte descriptif. Si vous imprimez depuis une carte SD, le " +"poids supplémentaire du fichier pourrait ralentir le firmware de votre " +"imprimante." #: src/libslic3r/PrintConfig.cpp:887 msgid "G-code flavor" -msgstr "G-code flavor" +msgstr "Version du G-code" #: src/libslic3r/PrintConfig.cpp:888 msgid "" @@ -5752,18 +5723,18 @@ msgid "" "output. The \"No extrusion\" flavor prevents Slic3r from exporting any " "extrusion value at all." msgstr "" -"Some G/M-code commands, including temperature control and others, are not " -"universal. Set this option to your printer's firmware to get a compatible " -"output. The \"No extrusion\" flavor prevents Slic3r from exporting any " -"extrusion value at all." +"Certaines commandes G/M-code, dont le contrôle de température et autres, ne " +"sont pas universelles. Paramétrez cette option avec le firmware de votre " +"imprimante pour obtenir une sortie compatible. La version \"sans extrusion\" " +"empêche Slic3r d'exporter toute valeur d'extrusion." #: src/libslic3r/PrintConfig.cpp:911 msgid "No extrusion" -msgstr "No extrusion" +msgstr "" #: src/libslic3r/PrintConfig.cpp:924 msgid "High extruder current on filament swap" -msgstr "High extruder current on filament swap" +msgstr "" #: src/libslic3r/PrintConfig.cpp:925 msgid "" @@ -5771,41 +5742,40 @@ msgid "" "filament exchange sequence to allow for rapid ramming feed rates and to " "overcome resistance when loading a filament with an ugly shaped tip." msgstr "" -"It may be beneficial to increase the extruder motor current during the " -"filament exchange sequence to allow for rapid ramming feed rates and to " -"overcome resistance when loading a filament with an ugly shaped tip." #: src/libslic3r/PrintConfig.cpp:933 msgid "" "This is the acceleration your printer will use for infill. Set zero to " "disable acceleration control for infill." msgstr "" -"This is the acceleration your printer will use for infill. Set zero to " -"disable acceleration control for infill." +"Il s'agit de l'accélération que votre imprimante utilisera pour le " +"remplissage. Régler sur zéro afin de désactiver le contrôle de " +"l'accélération pour le remplissage." #: src/libslic3r/PrintConfig.cpp:941 msgid "Combine infill every" -msgstr "Combine infill every" +msgstr "Combiner le remplissage toutes les" #: src/libslic3r/PrintConfig.cpp:943 msgid "" "This feature allows to combine infill and speed up your print by extruding " "thicker infill layers while preserving thin perimeters, thus accuracy." msgstr "" -"This feature allows to combine infill and speed up your print by extruding " -"thicker infill layers while preserving thin perimeters, thus accuracy." +"Cette fonction permet de combiner le remplissage afin d'accélérer " +"l'impression en extrudant des couches de remplissage plus épaisses tout en " +"conservant des périmètres fins, avec plus de précision." #: src/libslic3r/PrintConfig.cpp:946 msgid "Combine infill every n layers" -msgstr "Combine infill every n layers" +msgstr "Combiner le remplissage toutes les n couches" #: src/libslic3r/PrintConfig.cpp:952 msgid "Infill extruder" -msgstr "Infill extruder" +msgstr "Extrudeur pour le remplissage" #: src/libslic3r/PrintConfig.cpp:954 msgid "The extruder to use when printing infill." -msgstr "The extruder to use when printing infill." +msgstr "L'extrudeur à utiliser pour imprimer le remplissage." #: src/libslic3r/PrintConfig.cpp:962 msgid "" @@ -5815,27 +5785,29 @@ msgid "" "up the infill and make your parts stronger. If expressed as percentage (for " "example 90%) it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for infill. If " -"left zero, default extrusion width will be used if set, otherwise 1.125 x " -"nozzle diameter will be used. You may want to use fatter extrudates to speed " -"up the infill and make your parts stronger. If expressed as percentage (for " -"example 90%) it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour le remplissage. Si la valeur reste sur zéro, la " +"largeur d’extrusion par défaut sera utilisée si définie, sinon la valeur " +"1.125 x diamètre de la buse sera utilisée. Vous voudrez peut-être utiliser " +"des extrudats plus épais pour accélérer le remplissage et rendre vos pièces " +"plus solides. Si la valeur est exprimée en pourcentage (par exemple : 90%), " +"elle sera calculée par rapport à la hauteur de couche." #: src/libslic3r/PrintConfig.cpp:971 msgid "Infill before perimeters" -msgstr "Infill before perimeters" +msgstr "Remplissage avant les périmètres" #: src/libslic3r/PrintConfig.cpp:972 msgid "" "This option will switch the print order of perimeters and infill, making the " "latter first." msgstr "" -"This option will switch the print order of perimeters and infill, making the " -"latter first." +"Cette option inverse l'ordre d'impression des périmètres et du remplissage, " +"ce dernier étant alors imprimé en premier." #: src/libslic3r/PrintConfig.cpp:977 msgid "Only infill where needed" -msgstr "Only infill where needed" +msgstr "Remplissage seulement où cela est nécessaire" #: src/libslic3r/PrintConfig.cpp:979 msgid "" @@ -5843,13 +5815,14 @@ msgid "" "ceilings (it will act as internal support material). If enabled, slows down " "the G-code generation due to the multiple checks involved." msgstr "" -"This option will limit infill to the areas actually needed for supporting " -"ceilings (it will act as internal support material). If enabled, slows down " -"the G-code generation due to the multiple checks involved." +"Cette option limitera le remplissage aux zones nécessaires pour soutenir les " +"couches supérieures (cela agira comme un support interne). Si activé, la " +"génération du G-Code prendra plus de temps à cause des calculs " +"supplémentaires requis." #: src/libslic3r/PrintConfig.cpp:986 msgid "Infill/perimeters overlap" -msgstr "Infill/perimeters overlap" +msgstr "Chevauchement remplissage/périmètres" #: src/libslic3r/PrintConfig.cpp:988 msgid "" @@ -5858,26 +5831,29 @@ msgid "" "cause gaps. If expressed as percentage (example: 15%) it is calculated over " "perimeter extrusion width." msgstr "" -"This setting applies an additional overlap between infill and perimeters for " -"better bonding. Theoretically this shouldn't be needed, but backlash might " -"cause gaps. If expressed as percentage (example: 15%) it is calculated over " -"perimeter extrusion width." +"Cette option applique un chevauchement supplémentaire entre les périmètres " +"et le remplissage pour une meilleur fusion. En théorie, cela ne devrait pas " +"être nécessaire, mais le jeu mécanique peut générer des espacements. Si " +"exprimé en pourcentage (par exemple 15%), la valeur sera calculée en " +"fonction de la largeur d'extrusion du périmètre." #: src/libslic3r/PrintConfig.cpp:999 msgid "Speed for printing the internal fill. Set to zero for auto." -msgstr "Speed for printing the internal fill. Set to zero for auto." +msgstr "" +"Vitesse pour imprimer le remplissage interne. Réglez sur zéro pour un " +"ajustement automatique." #: src/libslic3r/PrintConfig.cpp:1007 msgid "Inherits profile" -msgstr "Inherits profile" +msgstr "Hérite du profil" #: src/libslic3r/PrintConfig.cpp:1008 msgid "Name of the profile, from which this profile inherits." -msgstr "Name of the profile, from which this profile inherits." +msgstr "Nom du profil, duquel hérite ce profil." #: src/libslic3r/PrintConfig.cpp:1021 msgid "Interface shells" -msgstr "Interface shells" +msgstr "Coques d'interface" #: src/libslic3r/PrintConfig.cpp:1022 msgid "" @@ -5885,9 +5861,9 @@ msgid "" "Useful for multi-extruder prints with translucent materials or manual " "soluble support material." msgstr "" -"Force the generation of solid shells between adjacent materials/volumes. " -"Useful for multi-extruder prints with translucent materials or manual " -"soluble support material." +"Force la génération de coques solides entre des volumes/matériaux adjacents. " +"Utile pour des impressions multi-extrudeurs avec des matériaux translucides " +"ou avec un support manuel soluble." #: src/libslic3r/PrintConfig.cpp:1031 msgid "" @@ -5896,14 +5872,14 @@ msgid "" "use placeholder variables for all Slic3r settings as well as [layer_num] and " "[layer_z]." msgstr "" -"This custom code is inserted at every layer change, right after the Z move " -"and before the extruder moves to the first layer point. Note that you can " -"use placeholder variables for all Slic3r settings as well as [layer_num] and " -"[layer_z]." +"Ce code personnalisé est inséré à chaque changement de couche, juste après " +"le mouvement Z et avant le déplacement de l'extrudeur au point de départ de " +"la couche suivante. Notez que vous pouvez utiliser des variables génériques " +"pour tous les réglages de Slic3r de même que [layer_num] et [layer_z]." #: src/libslic3r/PrintConfig.cpp:1042 msgid "Supports remaining times" -msgstr "Supports remaining times" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1043 msgid "" @@ -5912,83 +5888,80 @@ msgid "" "As of now only the Prusa i3 MK3 firmware recognizes M73. Also the i3 MK3 " "firmware supports M73 Qxx Sxx for the silent mode." msgstr "" -"Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute " -"intervals into the G-code to let the firmware show accurate remaining time. " -"As of now only the Prusa i3 MK3 firmware recognizes M73. Also the i3 MK3 " -"firmware supports M73 Qxx Sxx for the silent mode." #: src/libslic3r/PrintConfig.cpp:1051 msgid "Supports silent mode" -msgstr "Supports silent mode" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1052 msgid "Set silent mode for the G-code flavor" -msgstr "Set silent mode for the G-code flavor" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1075 msgid "Maximum feedrate %1%" -msgstr "Maximum feedrate %1%" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1077 msgid "Maximum feedrate of the %1% axis" -msgstr "Maximum feedrate of the %1% axis" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1085 msgid "Maximum acceleration %1%" -msgstr "Maximum acceleration %1%" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1087 msgid "Maximum acceleration of the %1% axis" -msgstr "Maximum acceleration of the %1% axis" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1095 msgid "Maximum jerk %1%" -msgstr "Maximum jerk %1%" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1097 msgid "Maximum jerk of the %1% axis" -msgstr "Maximum jerk of the %1% axis" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1108 src/libslic3r/PrintConfig.cpp:1110 msgid "Minimum feedrate when extruding" -msgstr "Minimum feedrate when extruding" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1119 src/libslic3r/PrintConfig.cpp:1121 msgid "Minimum travel feedrate" -msgstr "Minimum travel feedrate" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1130 src/libslic3r/PrintConfig.cpp:1132 msgid "Maximum acceleration when extruding" -msgstr "Maximum acceleration when extruding" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1141 src/libslic3r/PrintConfig.cpp:1143 msgid "Maximum acceleration when retracting" -msgstr "Maximum acceleration when retracting" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1151 src/libslic3r/PrintConfig.cpp:1160 msgid "Max" -msgstr "Max" +msgstr "Maximum" #: src/libslic3r/PrintConfig.cpp:1152 msgid "This setting represents the maximum speed of your fan." -msgstr "This setting represents the maximum speed of your fan." +msgstr "Cette option représente la vitesse maximum du ventilateur." #: src/libslic3r/PrintConfig.cpp:1161 -#, no-c-format +#, fuzzy, c-format msgid "" "This is the highest printable layer height for this extruder, used to cap " "the variable layer height and support layer height. Maximum recommended " "layer height is 75% of the extrusion width to achieve reasonable inter-layer " "adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter." msgstr "" -"This is the highest printable layer height for this extruder, used to cap " -"the variable layer height and support layer height. Maximum recommended " -"layer height is 75% of the extrusion width to achieve reasonable inter-layer " -"adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter." +"Ceci est la hauteur de couche imprimable maximum pour cet extrudeur, " +"utilisée pour plafonner la hauteur de couche variable et la hauteur de " +"couche des supports. La hauteur de couche maximum recommandée est 75% de la " +"largeur d'extrusion afin d'obtenir une adhésion inter-couches correcte. Si " +"réglée sur 0, la hauteur de couche est limitée à 75% du diamètre de la buse." #: src/libslic3r/PrintConfig.cpp:1171 msgid "Max print speed" -msgstr "Max print speed" +msgstr "Vitesse d'impression maximale" #: src/libslic3r/PrintConfig.cpp:1172 msgid "" @@ -5996,21 +5969,22 @@ msgid "" "speed in order to keep constant extruder pressure. This experimental setting " "is used to set the highest print speed you want to allow." msgstr "" -"When setting other speed settings to 0 Slic3r will autocalculate the optimal " -"speed in order to keep constant extruder pressure. This experimental setting " -"is used to set the highest print speed you want to allow." +"Lorsque vous réglez les autres vitesses à 0, Slic3r calculera " +"automatiquement la vitesse optimale de façon à garder une pression constante " +"dans l'extrudeur. Cette fonction expérimentale est utilisée pour régler la " +"plus haute vitesse que vous souhaitez autoriser." #: src/libslic3r/PrintConfig.cpp:1182 msgid "" "This experimental setting is used to set the maximum volumetric speed your " "extruder supports." msgstr "" -"This experimental setting is used to set the maximum volumetric speed your " -"extruder supports." +"Ce réglage expérimental est utilisé pour paramétrer la vitesse volumétrique " +"maximum tolérée par votre extrudeur." #: src/libslic3r/PrintConfig.cpp:1191 msgid "Max volumetric slope positive" -msgstr "Max volumetric slope positive" +msgstr "Pente volumétrique positive maximum" #: src/libslic3r/PrintConfig.cpp:1192 src/libslic3r/PrintConfig.cpp:1203 msgid "" @@ -6019,10 +5993,11 @@ msgid "" "of 1.8 mm³/s (0.45mm extrusion width, 0.2mm extrusion height, feedrate 20 mm/" "s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds." msgstr "" -"This experimental setting is used to limit the speed of change in extrusion " -"rate. A value of 1.8 mm³/s² ensures, that a change from the extrusion rate " -"of 1.8 mm³/s (0.45mm extrusion width, 0.2mm extrusion height, feedrate 20 mm/" -"s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds." +"Ce réglage expérimental sert à limiter la vitesse de changement dans le flux " +"d'extrusion. Une valeur de 1.8 mm³/s² garantit qu'un changement de flux " +"d'extrusion de 1.8 mm³/s (largeur d'extrusion 0.45mm, hauteur d'extrusion " +"0.2mm, alimentation 20 mm/s) à 5.4 mm³/s (alimentation 60 mm/s) prendra au " +"moins 2 secondes." #: src/libslic3r/PrintConfig.cpp:1196 src/libslic3r/PrintConfig.cpp:1207 msgid "mm³/s²" @@ -6030,15 +6005,17 @@ msgstr "mm³/s²" #: src/libslic3r/PrintConfig.cpp:1202 msgid "Max volumetric slope negative" -msgstr "Max volumetric slope negative" +msgstr "Pente volumétrique négative maximum" #: src/libslic3r/PrintConfig.cpp:1214 src/libslic3r/PrintConfig.cpp:1223 msgid "Min" -msgstr "Min" +msgstr "Minimum" #: src/libslic3r/PrintConfig.cpp:1215 msgid "This setting represents the minimum PWM your fan needs to work." -msgstr "This setting represents the minimum PWM your fan needs to work." +msgstr "" +"Cette option représente le PWM minimum dont votre ventilateur a besoin pour " +"tourner." #: src/libslic3r/PrintConfig.cpp:1224 msgid "" @@ -6046,21 +6023,21 @@ msgid "" "resolution for variable layer height. Typical values are between 0.05 mm and " "0.1 mm." msgstr "" -"This is the lowest printable layer height for this extruder and limits the " -"resolution for variable layer height. Typical values are between 0.05 mm and " -"0.1 mm." +"Cette valeur est la hauteur de couche imprimable minimum pour cet extrudeur " +"et elle limite la résolution pour la hauteur de couche variable. Les valeurs " +"type se situent entre 0.05 mm et 0.1 mm." #: src/libslic3r/PrintConfig.cpp:1232 msgid "Min print speed" -msgstr "Min print speed" +msgstr "Vitesse d'impression minimale" #: src/libslic3r/PrintConfig.cpp:1233 msgid "Slic3r will not scale speed down below this speed." -msgstr "Slic3r will not scale speed down below this speed." +msgstr "Slic3r ne descendra pas en-dessous de cette vitesse." #: src/libslic3r/PrintConfig.cpp:1240 msgid "Minimal filament extrusion length" -msgstr "Minimal filament extrusion length" +msgstr "Longueur minimale d'extrusion de filament" #: src/libslic3r/PrintConfig.cpp:1241 msgid "" @@ -6068,55 +6045,55 @@ msgid "" "specified amount of filament on the bottom layer. For multi-extruder " "machines, this minimum applies to each extruder." msgstr "" -"Generate no less than the number of skirt loops required to consume the " -"specified amount of filament on the bottom layer. For multi-extruder " -"machines, this minimum applies to each extruder." +"Nombre minimum de contours à générer afin de consommer la quantité de " +"filament spécifiée sur la couche inférieure. Pour les machines multi-" +"extrudeurs, ce minimum s'applique à chaque extrudeur." #: src/libslic3r/PrintConfig.cpp:1250 msgid "Configuration notes" -msgstr "Configuration notes" +msgstr "Notes de configuration" #: src/libslic3r/PrintConfig.cpp:1251 msgid "" "You can put here your personal notes. This text will be added to the G-code " "header comments." msgstr "" -"You can put here your personal notes. This text will be added to the G-code " -"header comments." +"Vous pouvez inscrire ici vos commentaires personnels. Ce texte sera ajouté " +"au commentaire en entête du G-Code." #: src/libslic3r/PrintConfig.cpp:1260 msgid "Nozzle diameter" -msgstr "Nozzle diameter" +msgstr "Diamètre de la buse" #: src/libslic3r/PrintConfig.cpp:1261 msgid "" "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)" msgstr "" -"This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)" +"Il s'agit du diamètre de la buse de votre extrudeur (par exemple: 0.5, 0.35, " +"etc.)" #: src/libslic3r/PrintConfig.cpp:1266 msgid "Host Type" -msgstr "Host Type" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1267 msgid "" "Slic3r can upload G-code files to a printer host. This field must contain " "the kind of the host." msgstr "" -"Slic3r can upload G-code files to a printer host. This field must contain " -"the kind of the host." #: src/libslic3r/PrintConfig.cpp:1278 msgid "Only retract when crossing perimeters" -msgstr "Only retract when crossing perimeters" +msgstr "Rétracter uniquement lors du franchissement de périmètres" #: src/libslic3r/PrintConfig.cpp:1279 msgid "" "Disables retraction when the travel path does not exceed the upper layer's " "perimeters (and thus any ooze will be probably invisible)." msgstr "" -"Disables retraction when the travel path does not exceed the upper layer's " -"perimeters (and thus any ooze will be probably invisible)." +"Désactiver la rétraction lorsque le chemin de déplacement ne franchit pas " +"les périmètres des couches supérieures (et donc les coulures seront " +"probablement invisibles)." #: src/libslic3r/PrintConfig.cpp:1286 msgid "" @@ -6124,13 +6101,14 @@ msgid "" "oozing. It will enable a tall skirt automatically and move extruders outside " "such skirt when changing temperatures." msgstr "" -"This option will drop the temperature of the inactive extruders to prevent " -"oozing. It will enable a tall skirt automatically and move extruders outside " -"such skirt when changing temperatures." +"Cette option abaissera la température des extrudeurs inutilisés pour " +"prévenir le oozing (suintement). Cela active automatiquement la génération " +"d'une grande jupe et le déplacement des extrudeurs hors de cette jupe lors " +"des changements de température." #: src/libslic3r/PrintConfig.cpp:1293 msgid "Output filename format" -msgstr "Output filename format" +msgstr "Format du nom de fichier de sortie" #: src/libslic3r/PrintConfig.cpp:1294 msgid "" @@ -6139,38 +6117,40 @@ msgid "" "[year], [month], [day], [hour], [minute], [second], [version], " "[input_filename], [input_filename_base]." msgstr "" -"You can use all configuration options as variables inside this template. For " -"example: [layer_height], [fill_density] etc. You can also use [timestamp], " -"[year], [month], [day], [hour], [minute], [second], [version], " -"[input_filename], [input_filename_base]." +"Vous pouvez utiliser toutes les options de configuration comme variables " +"dans ce modèle. Par exemple : [layer_height], [fill_density] etc. Vous " +"pouvez aussi utiliser [timestamp], [year], [month], [day], [hour], [minute], " +"[second], [version], [input_filename], [input_filename_base]." #: src/libslic3r/PrintConfig.cpp:1303 msgid "Detect bridging perimeters" -msgstr "Detect bridging perimeters" +msgstr "Détecter les périmètres faisant des ponts" #: src/libslic3r/PrintConfig.cpp:1305 msgid "" "Experimental option to adjust flow for overhangs (bridge flow will be used), " "to apply bridge speed to them and enable fan." msgstr "" -"Experimental option to adjust flow for overhangs (bridge flow will be used), " -"to apply bridge speed to them and enable fan." +"Option expérimentale qui ajuste le flux pour les surplombs (le flux pour les " +"ponts sera utilisé), leur applique la vitesse pour les ponts et active le " +"ventilateur." #: src/libslic3r/PrintConfig.cpp:1311 msgid "Filament parking position" -msgstr "Filament parking position" +msgstr "Position d'attente du filament" #: src/libslic3r/PrintConfig.cpp:1312 msgid "" "Distance of the extruder tip from the position where the filament is parked " "when unloaded. This should match the value in printer firmware. " msgstr "" -"Distance of the extruder tip from the position where the filament is parked " -"when unloaded. This should match the value in printer firmware. " +"Distance entre la pointe de l'extrudeur et la position où le filament est " +"positionné en attente lorsqu'il est déchargé. Cela doit correspondre à la " +"valeur dans le firmware de l'imprimante. " #: src/libslic3r/PrintConfig.cpp:1320 msgid "Extra loading distance" -msgstr "Extra loading distance" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1321 msgid "" @@ -6179,15 +6159,11 @@ msgid "" "positive, it is loaded further, if negative, the loading move is shorter " "than unloading. " msgstr "" -"When set to zero, the distance the filament is moved from parking position " -"during load is exactly the same as it was moved back during unload. When " -"positive, it is loaded further, if negative, the loading move is shorter " -"than unloading. " #: src/libslic3r/PrintConfig.cpp:1329 src/libslic3r/PrintConfig.cpp:1347 #: src/libslic3r/PrintConfig.cpp:1359 src/libslic3r/PrintConfig.cpp:1369 msgid "Perimeters" -msgstr "Perimeters" +msgstr "Périmètres" #: src/libslic3r/PrintConfig.cpp:1330 msgid "" @@ -6195,19 +6171,21 @@ msgid "" "like 9000 usually gives good results if your hardware is up to the job. Set " "zero to disable acceleration control for perimeters." msgstr "" -"This is the acceleration your printer will use for perimeters. A high value " -"like 9000 usually gives good results if your hardware is up to the job. Set " -"zero to disable acceleration control for perimeters." +"L'accélération que votre imprimante utilisera pour les périmètres. Une " +"valeur élevée comme 9000 donne généralement de bons résultats si votre " +"matériel le permet. Régler sur zéro afin de désactiver le contrôle de " +"l'accélération pour les périmètres." #: src/libslic3r/PrintConfig.cpp:1338 msgid "Perimeter extruder" -msgstr "Perimeter extruder" +msgstr "Extrudeur pour les périmètres" #: src/libslic3r/PrintConfig.cpp:1340 msgid "" "The extruder to use when printing perimeters and brim. First extruder is 1." msgstr "" -"The extruder to use when printing perimeters and brim. First extruder is 1." +"L'extrudeur à utiliser pour imprimer les périmètres et la bordure. Le " +"premier extrudeur a le numéro 1." #: src/libslic3r/PrintConfig.cpp:1349 msgid "" @@ -6217,17 +6195,20 @@ msgid "" "nozzle diameter will be used. If expressed as percentage (for example 200%) " "it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for perimeters. " -"You may want to use thinner extrudates to get more accurate surfaces. If " -"left zero, default extrusion width will be used if set, otherwise 1.125 x " -"nozzle diameter will be used. If expressed as percentage (for example 200%) " -"it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement une " +"largeur d’extrusion pour les périmètres. Vous voudrez peut-être utiliser des " +"extrudats plus fin pour obtenir des surfaces plus nettes. Si la valeur reste " +"sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon " +"la valeur 1.125 x diamètre de la buse sera utilisée. Si la valeur est " +"exprimée en pourcentage (par exemple : 200%), elle sera calculée par rapport " +"à la hauteur de couche." #: src/libslic3r/PrintConfig.cpp:1361 msgid "" "Speed for perimeters (contours, aka vertical shells). Set to zero for auto." msgstr "" -"Speed for perimeters (contours, aka vertical shells). Set to zero for auto." +"Vitesse pour les périmètres (contours, parois verticales). Réglez sur zéro " +"pour un ajustement automatique." #: src/libslic3r/PrintConfig.cpp:1371 msgid "" @@ -6236,10 +6217,10 @@ msgid "" "surfaces which benefit from a higher number of perimeters if the Extra " "Perimeters option is enabled." msgstr "" -"This option sets the number of perimeters to generate for each layer. Note " -"that Slic3r may increase this number automatically when it detects sloping " -"surfaces which benefit from a higher number of perimeters if the Extra " -"Perimeters option is enabled." +"Cette option définit le nombre de périmètres à générer pour chaque couche. " +"Notez que Slic3r peut augmenter cette valeur automatiquement si il détecte " +"une surface inclinée qui nécessite un plus grand nombre de périmètres, si " +"l'option \"Périmètres supplémentaires\" est sélectionnée." #: src/libslic3r/PrintConfig.cpp:1375 msgid "(minimum)" @@ -6253,63 +6234,63 @@ msgid "" "argument, and they can access the Slic3r config settings by reading " "environment variables." msgstr "" -"If you want to process the output G-code through custom scripts, just list " -"their absolute paths here. Separate multiple scripts with a semicolon. " -"Scripts will be passed the absolute path to the G-code file as the first " -"argument, and they can access the Slic3r config settings by reading " -"environment variables." +"Si vous voulez traiter le G-code de sortie à l'aide de scripts " +"personnalisés, listez simplement leurs chemins absolus ici. Séparez les " +"divers scripts avec un point virgule. Les scripts vont recevoir en premier " +"argument le chemin absolu du fichier G-code, et ils peuvent accéder aux " +"réglages de configuration de Slic3r en lisant des variables d'environnement." #: src/libslic3r/PrintConfig.cpp:1395 msgid "Printer type" -msgstr "Printer type" +msgstr "Type d'imprimante" #: src/libslic3r/PrintConfig.cpp:1396 msgid "Type of the printer." -msgstr "Type of the printer." +msgstr "Type d'imprimante." #: src/libslic3r/PrintConfig.cpp:1401 msgid "Printer notes" -msgstr "Printer notes" +msgstr "Notes de l'imprimante" #: src/libslic3r/PrintConfig.cpp:1402 msgid "You can put your notes regarding the printer here." -msgstr "You can put your notes regarding the printer here." +msgstr "Vous pouvez saisir ici vos observations concernant l'imprimante." #: src/libslic3r/PrintConfig.cpp:1410 msgid "Printer vendor" -msgstr "Printer vendor" +msgstr "Fabriquant de l'imprimante" #: src/libslic3r/PrintConfig.cpp:1411 msgid "Name of the printer vendor." -msgstr "Name of the printer vendor." +msgstr "Nom du fabriquant de l'imprimante." #: src/libslic3r/PrintConfig.cpp:1416 msgid "Printer variant" -msgstr "Printer variant" +msgstr "Variante d'imprimante" #: src/libslic3r/PrintConfig.cpp:1417 msgid "" "Name of the printer variant. For example, the printer variants may be " "differentiated by a nozzle diameter." msgstr "" -"Name of the printer variant. For example, the printer variants may be " -"differentiated by a nozzle diameter." +"Nom de la variante d'imprimante. Par exemple, la variante d'imprimante peut " +"être différenciée par un diamètre de buse." #: src/libslic3r/PrintConfig.cpp:1430 msgid "Raft layers" -msgstr "Raft layers" +msgstr "Couches du radeau" #: src/libslic3r/PrintConfig.cpp:1432 msgid "" "The object will be raised by this number of layers, and support material " "will be generated under it." msgstr "" -"The object will be raised by this number of layers, and support material " -"will be generated under it." +"L'objet sera surélevé de ce nombre de couches, et du support sera généré en " +"dessous." #: src/libslic3r/PrintConfig.cpp:1440 msgid "Resolution" -msgstr "Resolution" +msgstr "Résolution" #: src/libslic3r/PrintConfig.cpp:1441 msgid "" @@ -6318,48 +6299,50 @@ msgid "" "carry more detail than printers can render. Set to zero to disable any " "simplification and use full resolution from input." msgstr "" -"Minimum detail resolution, used to simplify the input file for speeding up " -"the slicing job and reducing memory usage. High-resolution models often " -"carry more detail than printers can render. Set to zero to disable any " -"simplification and use full resolution from input." +"Résolution minimale pour les détails, utilisée pour simplifier le fichier " +"d'entrée afin d'accélérer le découpage et de réduire l'utilisation de la " +"mémoire. Les modèles haute-résolution possèdent souvent plus de détails que " +"ce que les imprimantes peuvent produire. Mettez à zéro pour désactiver toute " +"simplification et utiliser la résolution complète de l'entrée." #: src/libslic3r/PrintConfig.cpp:1451 msgid "Minimum travel after retraction" -msgstr "Minimum travel after retraction" +msgstr "Trajet minimal après une rétraction" #: src/libslic3r/PrintConfig.cpp:1452 msgid "" "Retraction is not triggered when travel moves are shorter than this length." msgstr "" -"Retraction is not triggered when travel moves are shorter than this length." +"La rétraction n'est pas déclenchée lorsque les déplacements sont plus courts " +"que cette distance." #: src/libslic3r/PrintConfig.cpp:1458 msgid "Retract amount before wipe" -msgstr "Retract amount before wipe" +msgstr "Quantité de rétractation avant essuyage" #: src/libslic3r/PrintConfig.cpp:1459 msgid "" "With bowden extruders, it may be wise to do some amount of quick retract " "before doing the wipe movement." msgstr "" -"With bowden extruders, it may be wise to do some amount of quick retract " -"before doing the wipe movement." +"Avec les extrudeurs bowden, il est conseillé d'effectuer une rétractation " +"rapide avant de réaliser le mouvement de nettoyage." #: src/libslic3r/PrintConfig.cpp:1466 msgid "Retract on layer change" -msgstr "Retract on layer change" +msgstr "Rétracter lors des changements de couche" #: src/libslic3r/PrintConfig.cpp:1467 msgid "This flag enforces a retraction whenever a Z move is done." -msgstr "This flag enforces a retraction whenever a Z move is done." +msgstr "Cette option active la rétractation lors d'un déplacement sur l'axe Z." #: src/libslic3r/PrintConfig.cpp:1472 src/libslic3r/PrintConfig.cpp:1480 msgid "Length" -msgstr "Length" +msgstr "Longueur" #: src/libslic3r/PrintConfig.cpp:1473 msgid "Retraction Length" -msgstr "Retraction Length" +msgstr "Longueur de Rétractation" #: src/libslic3r/PrintConfig.cpp:1474 msgid "" @@ -6367,17 +6350,17 @@ msgid "" "amount (the length is measured on raw filament, before it enters the " "extruder)." msgstr "" -"When retraction is triggered, filament is pulled back by the specified " -"amount (the length is measured on raw filament, before it enters the " -"extruder)." +"Lorsque la rétractation est déclenchée, le filament est tiré en arrière de " +"la longueur indiquée (la longueur est mesurée sur le filament brut, avant " +"qu'il entre dans l'extrudeur)." #: src/libslic3r/PrintConfig.cpp:1476 src/libslic3r/PrintConfig.cpp:1485 msgid "mm (zero to disable)" -msgstr "mm (zero to disable)" +msgstr "mm (zéro pour désactiver)" #: src/libslic3r/PrintConfig.cpp:1481 msgid "Retraction Length (Toolchange)" -msgstr "Retraction Length (Toolchange)" +msgstr "Longueur de Rétractation (changement d'outil)" #: src/libslic3r/PrintConfig.cpp:1482 msgid "" @@ -6385,13 +6368,13 @@ msgid "" "by the specified amount (the length is measured on raw filament, before it " "enters the extruder)." msgstr "" -"When retraction is triggered before changing tool, filament is pulled back " -"by the specified amount (the length is measured on raw filament, before it " -"enters the extruder)." +"Lorsque la rétractation est déclenchée avant un changement d'outil, le " +"filament est retiré de la longueur indiquée (la longueur est mesurée sur le " +"filament brut, avant qu'il entre dans l'extrudeur)." #: src/libslic3r/PrintConfig.cpp:1490 msgid "Lift Z" -msgstr "Lift Z" +msgstr "Levage de l'axe Z" #: src/libslic3r/PrintConfig.cpp:1491 msgid "" @@ -6399,17 +6382,17 @@ msgid "" "retraction is triggered. When using multiple extruders, only the setting for " "the first extruder will be considered." msgstr "" -"If you set this to a positive value, Z is quickly raised every time a " -"retraction is triggered. When using multiple extruders, only the setting for " -"the first extruder will be considered." +"Si vous indiquez une valeur positive, l'axe Z est rapidement élevé à chaque " +"rétraction. Lorsque vous utilisez plusieurs extrudeurs, seul le réglage du " +"premier extrudeur sera pris en compte." #: src/libslic3r/PrintConfig.cpp:1498 msgid "Above Z" -msgstr "Above Z" +msgstr "Au-delà de Z" #: src/libslic3r/PrintConfig.cpp:1499 msgid "Only lift Z above" -msgstr "Only lift Z above" +msgstr "Lever Z seulement au-dessus de" #: src/libslic3r/PrintConfig.cpp:1500 msgid "" @@ -6417,17 +6400,17 @@ msgid "" "specified absolute Z. You can tune this setting for skipping lift on the " "first layers." msgstr "" -"If you set this to a positive value, Z lift will only take place above the " -"specified absolute Z. You can tune this setting for skipping lift on the " -"first layers." +"Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché " +"qu'à partir de la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier " +"ce réglage pour éviter le levage de l'axe Z sur les premières couches." #: src/libslic3r/PrintConfig.cpp:1507 msgid "Below Z" -msgstr "Below Z" +msgstr "En-deçà de Z" #: src/libslic3r/PrintConfig.cpp:1508 msgid "Only lift Z below" -msgstr "Only lift Z below" +msgstr "Lever Z seulement en-dessous de" #: src/libslic3r/PrintConfig.cpp:1509 msgid "" @@ -6435,41 +6418,43 @@ msgid "" "specified absolute Z. You can tune this setting for limiting lift to the " "first layers." msgstr "" -"If you set this to a positive value, Z lift will only take place below the " -"specified absolute Z. You can tune this setting for limiting lift to the " -"first layers." +"Si vous indiquez une valeur positive, le levage de l'axe Z ne sera déclenché " +"que jusqu'à la valeur absolue indiquée pour l'axe Z. Vous pouvez modifier ce " +"réglage pour limiter le levage de l'axe Z aux premières couches." #: src/libslic3r/PrintConfig.cpp:1517 src/libslic3r/PrintConfig.cpp:1525 msgid "Extra length on restart" -msgstr "Extra length on restart" +msgstr "Longueur supplémentaire à la reprise" #: src/libslic3r/PrintConfig.cpp:1518 msgid "" "When the retraction is compensated after the travel move, the extruder will " "push this additional amount of filament. This setting is rarely needed." msgstr "" -"When the retraction is compensated after the travel move, the extruder will " -"push this additional amount of filament. This setting is rarely needed." +"Lorsque la rétractation est compensée après un déplacement, l'extruder " +"exprimera cette quantité de filament en plus. Ce réglage est rarement " +"nécessaire." #: src/libslic3r/PrintConfig.cpp:1526 msgid "" "When the retraction is compensated after changing tool, the extruder will " "push this additional amount of filament." msgstr "" -"When the retraction is compensated after changing tool, the extruder will " -"push this additional amount of filament." +"Lorsque la rétractation est compensée après un changement d'outil, " +"l'extrudeur exprimera cette quantité de filament en plus." #: src/libslic3r/PrintConfig.cpp:1533 src/libslic3r/PrintConfig.cpp:1534 msgid "Retraction Speed" -msgstr "Retraction Speed" +msgstr "Vitesse de Rétractation" #: src/libslic3r/PrintConfig.cpp:1535 msgid "The speed for retractions (it only applies to the extruder motor)." -msgstr "The speed for retractions (it only applies to the extruder motor)." +msgstr "" +"La vitesse des rétractations (ne s'applique qu'au moteur de l'extrudeur)." #: src/libslic3r/PrintConfig.cpp:1541 src/libslic3r/PrintConfig.cpp:1542 msgid "Deretraction Speed" -msgstr "Deretraction Speed" +msgstr "Vitesse de Réinsertion" #: src/libslic3r/PrintConfig.cpp:1543 msgid "" @@ -6477,29 +6462,29 @@ msgid "" "applies to the extruder motor). If left to zero, the retraction speed is " "used." msgstr "" -"The speed for loading of a filament into extruder after retraction (it only " -"applies to the extruder motor). If left to zero, the retraction speed is " -"used." +"La vitesse de chargement d'un filament dans l'extrudeur après une " +"rétractation (ne s'applique qu'au moteur de l'extrudeur). Si cette valeur " +"reste sur zéro, la vitesse de rétraction est utilisée." #: src/libslic3r/PrintConfig.cpp:1550 msgid "Seam position" -msgstr "Seam position" +msgstr "Position de la jointure" #: src/libslic3r/PrintConfig.cpp:1552 msgid "Position of perimeters starting points." -msgstr "Position of perimeters starting points." +msgstr "Position des points de départ des périmètres." #: src/libslic3r/PrintConfig.cpp:1558 msgid "Random" -msgstr "Random" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1559 msgid "Nearest" -msgstr "Nearest" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1560 msgid "Aligned" -msgstr "Aligned" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1568 msgid "Direction" @@ -6507,67 +6492,67 @@ msgstr "Direction" #: src/libslic3r/PrintConfig.cpp:1570 msgid "Preferred direction of the seam" -msgstr "Preferred direction of the seam" +msgstr "Direction préférée de la jointure" #: src/libslic3r/PrintConfig.cpp:1571 msgid "Seam preferred direction" -msgstr "Seam preferred direction" +msgstr "Direction préférée de la jointure" #: src/libslic3r/PrintConfig.cpp:1578 msgid "Jitter" -msgstr "Jitter" +msgstr "Gigue" #: src/libslic3r/PrintConfig.cpp:1580 msgid "Seam preferred direction jitter" -msgstr "Seam preferred direction jitter" +msgstr "Gigue de la direction préférée de la jointure" #: src/libslic3r/PrintConfig.cpp:1581 msgid "Preferred direction of the seam - jitter" -msgstr "Preferred direction of the seam - jitter" +msgstr "Direction préférée de la jointure - gigue" #: src/libslic3r/PrintConfig.cpp:1591 msgid "USB/serial port for printer connection." -msgstr "USB/serial port for printer connection." +msgstr "Port USB/Série pour la connexion de l'imprimante." #: src/libslic3r/PrintConfig.cpp:1598 msgid "Serial port speed" -msgstr "Serial port speed" +msgstr "Vitesse du port série" #: src/libslic3r/PrintConfig.cpp:1599 msgid "Speed (baud) of USB/serial port for printer connection." -msgstr "Speed (baud) of USB/serial port for printer connection." +msgstr "Vitesse (baud) du port USB/série pour la connexion à l'imprimante." #: src/libslic3r/PrintConfig.cpp:1608 msgid "Distance from object" -msgstr "Distance from object" +msgstr "Distance de l'objet" #: src/libslic3r/PrintConfig.cpp:1609 msgid "" "Distance between skirt and object(s). Set this to zero to attach the skirt " "to the object(s) and get a brim for better adhesion." msgstr "" -"Distance between skirt and object(s). Set this to zero to attach the skirt " -"to the object(s) and get a brim for better adhesion." +"Distance entre le ou les objet(s) et la jupe. Mettez zéro pour attacher la " +"jupe a(ux) objet(s) et obtenir une bordure pour une meilleure adhésion." #: src/libslic3r/PrintConfig.cpp:1616 msgid "Skirt height" -msgstr "Skirt height" +msgstr "Hauteur de la jupe" #: src/libslic3r/PrintConfig.cpp:1617 msgid "" "Height of skirt expressed in layers. Set this to a tall value to use skirt " "as a shield against drafts." msgstr "" -"Height of skirt expressed in layers. Set this to a tall value to use skirt " -"as a shield against drafts." +"Hauteur de la jupe exprimée en couches. Mettez une valeur élevée pour " +"utiliser la jupe comme un bouclier contre les flux d'airs." #: src/libslic3r/PrintConfig.cpp:1624 msgid "Loops (minimum)" -msgstr "Loops (minimum)" +msgstr "Boucles (minimum)" #: src/libslic3r/PrintConfig.cpp:1625 msgid "Skirt Loops" -msgstr "Skirt Loops" +msgstr "Boucles de la Jupe" #: src/libslic3r/PrintConfig.cpp:1626 msgid "" @@ -6575,25 +6560,26 @@ msgid "" "set, the number of loops might be greater than the one configured here. Set " "this to zero to disable skirt completely." msgstr "" -"Number of loops for the skirt. If the Minimum Extrusion Length option is " -"set, the number of loops might be greater than the one configured here. Set " -"this to zero to disable skirt completely." +"Nombre de boucles pour la jupe. Si la Longueur Minimale d'Extrusion est " +"paramétrée, le nombre de boucles minimal sera plus grand que celui configuré " +"ici. Mettez à zéro pour désactiver complètement la jupe." #: src/libslic3r/PrintConfig.cpp:1634 msgid "Slow down if layer print time is below" -msgstr "Slow down if layer print time is below" +msgstr "Ralentir si le temps d'impression de la couche est inférieur à" #: src/libslic3r/PrintConfig.cpp:1635 msgid "" "If layer print time is estimated below this number of seconds, print moves " "speed will be scaled down to extend duration to this value." msgstr "" -"If layer print time is estimated below this number of seconds, print moves " -"speed will be scaled down to extend duration to this value." +"Si le temps d'impression estimé de la couche est inférieur à ce nombre de " +"secondes, la vitesse des déplacements d'impression sera réduite afin " +"d'atteindre cette valeur." #: src/libslic3r/PrintConfig.cpp:1645 msgid "Small perimeters" -msgstr "Small perimeters" +msgstr "Périmètres courts" #: src/libslic3r/PrintConfig.cpp:1647 msgid "" @@ -6601,21 +6587,23 @@ msgid "" "6.5mm (usually holes). If expressed as percentage (for example: 80%) it will " "be calculated on the perimeters speed setting above. Set to zero for auto." msgstr "" -"This separate setting will affect the speed of perimeters having radius <= " -"6.5mm (usually holes). If expressed as percentage (for example: 80%) it will " -"be calculated on the perimeters speed setting above. Set to zero for auto." +"Ce réglage distinct affectera la vitesse des périmètre ayant un rayon <= " +"6.5mm (les trous habituellement). Si cette valeur est exprimée en " +"pourcentage (par exemple: 80%) elle sera calculée d'après le réglage de la " +"vitesse de périmètre susmentionnée. Réglez sur zéro pour un ajustement " +"automatique." #: src/libslic3r/PrintConfig.cpp:1657 msgid "Solid infill threshold area" -msgstr "Solid infill threshold area" +msgstr "Surface de seuil pour le remplissage solide" #: src/libslic3r/PrintConfig.cpp:1659 msgid "" "Force solid infill for regions having a smaller area than the specified " "threshold." msgstr "" -"Force solid infill for regions having a smaller area than the specified " -"threshold." +"Forcer un remplissage solide pour les zones ayant une surface plus petite " +"que la valeur indiquée." #: src/libslic3r/PrintConfig.cpp:1660 msgid "mm²" @@ -6623,15 +6611,15 @@ msgstr "mm²" #: src/libslic3r/PrintConfig.cpp:1666 msgid "Solid infill extruder" -msgstr "Solid infill extruder" +msgstr "Extrudeur pour le remplissage solide" #: src/libslic3r/PrintConfig.cpp:1668 msgid "The extruder to use when printing solid infill." -msgstr "The extruder to use when printing solid infill." +msgstr "L'extrudeur à utiliser pour imprimer les remplissages solides." #: src/libslic3r/PrintConfig.cpp:1674 msgid "Solid infill every" -msgstr "Solid infill every" +msgstr "Remplissage solide toutes les" #: src/libslic3r/PrintConfig.cpp:1676 msgid "" @@ -6640,10 +6628,11 @@ msgid "" "will automatically choose the maximum possible number of layers to combine " "according to nozzle diameter and layer height." msgstr "" -"This feature allows to force a solid layer every given number of layers. " -"Zero to disable. You can set this to any value (for example 9999); Slic3r " -"will automatically choose the maximum possible number of layers to combine " -"according to nozzle diameter and layer height." +"Cette fonction permet de forcer l'impression d'une couche solide après le " +"nombre de couches indiqué. Réglez sur zéro pour la désactiver. Vous pouvez " +"indiquer n'importe quelle valeur (par exemple 9999); Slic3r choisira " +"automatiquement le nombre maximum de couches a combiner en fonction du " +"diamètre de la buse et de l'épaisseur des couches." #: src/libslic3r/PrintConfig.cpp:1688 msgid "" @@ -6652,10 +6641,12 @@ msgid "" "otherwise 1.125 x nozzle diameter will be used. If expressed as percentage " "(for example 90%) it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for infill for " -"solid surfaces. If left zero, default extrusion width will be used if set, " -"otherwise 1.125 x nozzle diameter will be used. If expressed as percentage " -"(for example 90%) it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour le remplissage ou les surfaces solides. Si la " +"valeur reste sur zéro, la largeur d’extrusion par défaut sera utilisée si " +"définie, sinon la valeur 1.125 x diamètre de la buse sera utilisée. Si la " +"valeur est exprimée en pourcentage (par exemple : 90%), elle sera calculée " +"par rapport à la hauteur de couche." #: src/libslic3r/PrintConfig.cpp:1698 msgid "" @@ -6663,17 +6654,20 @@ msgid "" "This can be expressed as a percentage (for example: 80%) over the default " "infill speed above. Set to zero for auto." msgstr "" -"Speed for printing solid regions (top/bottom/internal horizontal shells). " -"This can be expressed as a percentage (for example: 80%) over the default " -"infill speed above. Set to zero for auto." +"Vitesse pour imprimer des zones solides (supérieures/inférieures/parois " +"horizontales internes). Peut être exprimée en pourcentage (par exemple: 80%) " +"de la vitesse de remplissage par défaut susmentionnée. Réglez sur zéro pour " +"un ajustement automatique." #: src/libslic3r/PrintConfig.cpp:1710 msgid "Number of solid layers to generate on top and bottom surfaces." -msgstr "Number of solid layers to generate on top and bottom surfaces." +msgstr "" +"Nombre de couches solides à générer sur les surfaces supérieures et " +"inférieures." #: src/libslic3r/PrintConfig.cpp:1716 msgid "Spiral vase" -msgstr "Spiral vase" +msgstr "Vase spiral" #: src/libslic3r/PrintConfig.cpp:1717 msgid "" @@ -6683,15 +6677,16 @@ msgid "" "any number of bottom solid layers as well as skirt/brim loops. It won't work " "when printing more than an object." msgstr "" -"This feature will raise Z gradually while printing a single-walled object in " -"order to remove any visible seam. This option requires a single perimeter, " -"no infill, no top solid layers and no support material. You can still set " -"any number of bottom solid layers as well as skirt/brim loops. It won't work " -"when printing more than an object." +"Cette fonction élèvera le Z graduellement en cas d'impression d'un objet à " +"paroi unique, afin de rendre invisibles les jointures. Cette option " +"nécessite de n'avoir qu'un seul périmètre, de ne pas avoir de remplissage, " +"ni de surface solide supérieure, ni de support. Vous pouvez toujours choisir " +"le nombre de surface solides inférieures de même que les boucles des jupes " +"et des bordures. Cela ne fonctionnera pas si vous imprimez plus d'un objet." #: src/libslic3r/PrintConfig.cpp:1725 msgid "Temperature variation" -msgstr "Temperature variation" +msgstr "Variation de température" #: src/libslic3r/PrintConfig.cpp:1726 msgid "" @@ -6699,9 +6694,9 @@ msgid "" "a full-height \"sacrificial\" skirt on which the nozzles are periodically " "wiped." msgstr "" -"Temperature difference to be applied when an extruder is not active. Enables " -"a full-height \"sacrificial\" skirt on which the nozzles are periodically " -"wiped." +"Différence de température devant être appliquée quand un extrudeur n'est pas " +"actif. Permet la génération d'un contour complet \"sacrificiel\" sur lequel " +"les buses sont nettoyées régulièrement." #: src/libslic3r/PrintConfig.cpp:1736 msgid "" @@ -6713,13 +6708,15 @@ msgid "" "you can use placeholder variables for all Slic3r settings, so you can put a " "\"M109 S[first_layer_temperature]\" command wherever you want." msgstr "" -"This start procedure is inserted at the beginning, after bed has reached the " -"target temperature and extruder just started heating, and before extruder " -"has finished heating. If Slic3r detects M104 or M190 in your custom codes, " -"such commands will not be prepended automatically so you're free to " -"customize the order of heating commands and other custom actions. Note that " -"you can use placeholder variables for all Slic3r settings, so you can put a " -"\"M109 S[first_layer_temperature]\" command wherever you want." +"Cette procédure de démarrage est insérée au début, après que le plateau a " +"atteint la température ciblée et lorsque l'extrudeur vient juste de " +"commencer à chauffer, et avant que l'extrudeur ait terminé de chauffer. Si " +"Slic3r détecte des commandes M104 ou M190 dans vos codes personnalisés, ces " +"commandes ne seront pas ajoutées automatiquement ainsi vous serez libre de " +"personnaliser l'ordre des commandes de chauffe et autres actions " +"personnalisées. Notez que vous pouvez utiliser des variables génériques pour " +"tous les réglages de Slic3r, donc vous pouvez mettre une commande " +"\"M109S[first_layer_temperature]\" où vous le souhaitez." #: src/libslic3r/PrintConfig.cpp:1751 msgid "" @@ -6732,46 +6729,46 @@ msgid "" "S[first_layer_temperature]\" command wherever you want. If you have multiple " "extruders, the gcode is processed in extruder order." msgstr "" -"This start procedure is inserted at the beginning, after any printer start " -"gcode. This is used to override settings for a specific filament. If Slic3r " -"detects M104, M109, M140 or M190 in your custom codes, such commands will " -"not be prepended automatically so you're free to customize the order of " -"heating commands and other custom actions. Note that you can use placeholder " -"variables for all Slic3r settings, so you can put a \"M109 " -"S[first_layer_temperature]\" command wherever you want. If you have multiple " -"extruders, the gcode is processed in extruder order." +"Cette procédure de démarrage est insérée au début, après un gcode de " +"démarrage de l'imprimante. Elle est utilisée pour remplacer les réglages " +"pour un filament spécifique. Si Slic3r détecte des commandes M104, M109, " +"M140 ou M190 dans vos codes personnalisés ces commandes ne seront pas " +"ajoutées automatiquement, de cette manière vous pouvez personnaliser la " +"procédure de chauffe et autres actions. Notez que vous pouvez utiliser des " +"variables génériques pour tous les réglages de Slic3r, donc vous pouvez " +"saisir une commande \"M109 S[first_layer_temperature]\" où vous voulez. Si " +"vous avez plusieurs extrudeurs, le G-Code sera exécuté dans l'ordre des " +"extrudeurs." #: src/libslic3r/PrintConfig.cpp:1766 msgid "Single Extruder Multi Material" -msgstr "Single Extruder Multi Material" +msgstr "Extrudeur Unique Multi-Matériaux" #: src/libslic3r/PrintConfig.cpp:1767 msgid "The printer multiplexes filaments into a single hot end." -msgstr "The printer multiplexes filaments into a single hot end." +msgstr "L'imprimante multiplexe les filaments vers une seule tête d'extrusion." #: src/libslic3r/PrintConfig.cpp:1772 msgid "Prime all printing extruders" -msgstr "Prime all printing extruders" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1773 msgid "" "If enabled, all printing extruders will be primed at the front edge of the " "print bed at the start of the print." msgstr "" -"If enabled, all printing extruders will be primed at the front edge of the " -"print bed at the start of the print." #: src/libslic3r/PrintConfig.cpp:1778 msgid "Generate support material" -msgstr "Generate support material" +msgstr "Générer des supports" #: src/libslic3r/PrintConfig.cpp:1780 msgid "Enable support material generation." -msgstr "Enable support material generation." +msgstr "Activer la génération des supports." #: src/libslic3r/PrintConfig.cpp:1784 msgid "Auto generated supports" -msgstr "Auto generated supports" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1786 msgid "" @@ -6779,45 +6776,42 @@ msgid "" "threshold value. If unchecked, supports will be generated inside the " "\"Support Enforcer\" volumes only." msgstr "" -"If checked, supports will be generated automatically based on the overhang " -"threshold value. If unchecked, supports will be generated inside the " -"\"Support Enforcer\" volumes only." #: src/libslic3r/PrintConfig.cpp:1792 msgid "XY separation between an object and its support" -msgstr "XY separation between an object and its support" +msgstr "Séparation XY entre un objet et son support" #: src/libslic3r/PrintConfig.cpp:1794 msgid "" "XY separation between an object and its support. If expressed as percentage " "(for example 50%), it will be calculated over external perimeter width." msgstr "" -"XY separation between an object and its support. If expressed as percentage " -"(for example 50%), it will be calculated over external perimeter width." +"Séparation XY entre un objet et son support. Si la valeur est exprimée en " +"pourcentage (par exemple 50%), elle sera calculée à partir de la largeur du " +"périmètre extérieur." #: src/libslic3r/PrintConfig.cpp:1804 msgid "Pattern angle" -msgstr "Pattern angle" +msgstr "Angle du motif" #: src/libslic3r/PrintConfig.cpp:1806 msgid "" "Use this setting to rotate the support material pattern on the horizontal " "plane." msgstr "" -"Use this setting to rotate the support material pattern on the horizontal " -"plane." +"Utiliser ce réglage pour orienter le motif du support sur le plan horizontal." -#: src/libslic3r/PrintConfig.cpp:1816 src/libslic3r/PrintConfig.cpp:2421 +#: src/libslic3r/PrintConfig.cpp:1816 src/libslic3r/PrintConfig.cpp:2423 msgid "" "Only create support if it lies on a build plate. Don't create support on a " "print." msgstr "" -"Only create support if it lies on a build plate. Don't create support on a " -"print." +"Créer uniquement des supports reposant sur le plateau. Ne pas créer pas de " +"supports sur une impression." #: src/libslic3r/PrintConfig.cpp:1822 msgid "Contact Z distance" -msgstr "Contact Z distance" +msgstr "Distance de contact Z" #: src/libslic3r/PrintConfig.cpp:1824 msgid "" @@ -6825,21 +6819,21 @@ msgid "" "this to 0 will also prevent Slic3r from using bridge flow and speed for the " "first object layer." msgstr "" -"The vertical distance between object and support material interface. Setting " -"this to 0 will also prevent Slic3r from using bridge flow and speed for the " -"first object layer." +"Distance verticale entre l'objet et l'intercalaire du support. Régler cette " +"valeur sur zéro empêchera Slic3r d'utiliser la vitesse et le débit des ponts " +"pour la première couche de l'objet." #: src/libslic3r/PrintConfig.cpp:1831 msgid "soluble" -msgstr "soluble" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1832 msgid "detachable" -msgstr "detachable" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1837 msgid "Enforce support for the first" -msgstr "Enforce support for the first" +msgstr "Renforcer le support sur le(s) première(s)" #: src/libslic3r/PrintConfig.cpp:1839 msgid "" @@ -6848,26 +6842,26 @@ msgid "" "regardless of any angle threshold. This is useful for getting more adhesion " "of objects having a very thin or poor footprint on the build plate." msgstr "" -"Generate support material for the specified number of layers counting from " -"bottom, regardless of whether normal support material is enabled or not and " -"regardless of any angle threshold. This is useful for getting more adhesion " -"of objects having a very thin or poor footprint on the build plate." +"Générer des supports pour le nombre de couches spécifié à partir du bas, que " +"les supports normaux soient activés ou non et sans tenir compte de seuils " +"d'inclinaison. Ceci est utile pour obtenir une meilleure adhésion pour des " +"objets ayant une surface de contact très fine ou limitée sur le plateau." #: src/libslic3r/PrintConfig.cpp:1844 msgid "Enforce support for the first n layers" -msgstr "Enforce support for the first n layers" +msgstr "Renforcer le support pour les n premières couches" #: src/libslic3r/PrintConfig.cpp:1850 msgid "Support material/raft/skirt extruder" -msgstr "Support material/raft/skirt extruder" +msgstr "Extrudeur pour support/raft/jupe" #: src/libslic3r/PrintConfig.cpp:1852 msgid "" "The extruder to use when printing support material, raft and skirt (1+, 0 to " "use the current extruder to minimize tool changes)." msgstr "" -"The extruder to use when printing support material, raft and skirt (1+, 0 to " -"use the current extruder to minimize tool changes)." +"L'extrudeur à utiliser pour imprimer des supports, du raft ou des contours " +"(1+,0 pour utiliser l'extrudeur actuel et limiter les changements d'outil)." #: src/libslic3r/PrintConfig.cpp:1861 msgid "" @@ -6876,52 +6870,56 @@ msgid "" "otherwise nozzle diameter will be used. If expressed as percentage (for " "example 90%) it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for support " -"material. If left zero, default extrusion width will be used if set, " -"otherwise nozzle diameter will be used. If expressed as percentage (for " -"example 90%) it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour les supports. Si la valeur reste sur zéro, la " +"largeur d’extrusion par défaut sera utilisée si définie, sinon le diamètre " +"de la buse sera utilisée. Si la valeur est exprimée en pourcentage (par " +"exemple : 90%), elle sera calculée par rapport à la hauteur de couche." #: src/libslic3r/PrintConfig.cpp:1869 msgid "Interface loops" -msgstr "Interface loops" +msgstr "Boucles d'interface" #: src/libslic3r/PrintConfig.cpp:1871 msgid "" "Cover the top contact layer of the supports with loops. Disabled by default." msgstr "" -"Cover the top contact layer of the supports with loops. Disabled by default." +"Recouvrir la couche de contact supérieure des supports avec des boucles. " +"Désactivé par défaut." #: src/libslic3r/PrintConfig.cpp:1876 msgid "Support material/raft interface extruder" -msgstr "Support material/raft interface extruder" +msgstr "Extrudeur pour l'interface des supports/du radeau" #: src/libslic3r/PrintConfig.cpp:1878 msgid "" "The extruder to use when printing support material interface (1+, 0 to use " "the current extruder to minimize tool changes). This affects raft too." msgstr "" -"The extruder to use when printing support material interface (1+, 0 to use " -"the current extruder to minimize tool changes). This affects raft too." +"L'extrudeur à utiliser pour imprimer les intercalaires du support (1+,0 pour " +"utiliser l'extrudeur actuel et limiter les changements d'outil). Cela " +"affecte également le raft." #: src/libslic3r/PrintConfig.cpp:1885 msgid "Interface layers" -msgstr "Interface layers" +msgstr "Couches d'interface" #: src/libslic3r/PrintConfig.cpp:1887 msgid "" "Number of interface layers to insert between the object(s) and support " "material." msgstr "" -"Number of interface layers to insert between the object(s) and support " -"material." +"Nombre de couches d'interface à insérer entre le(s) objet(s) et les supports." #: src/libslic3r/PrintConfig.cpp:1894 msgid "Interface pattern spacing" -msgstr "Interface pattern spacing" +msgstr "Espacement du motif d'interface" #: src/libslic3r/PrintConfig.cpp:1896 msgid "Spacing between interface lines. Set zero to get a solid interface." -msgstr "Spacing between interface lines. Set zero to get a solid interface." +msgstr "" +"Espacement entre les lignes d'interface. Mettez à zéro pour obtenir une " +"interface solide." #: src/libslic3r/PrintConfig.cpp:1905 msgid "" @@ -6929,49 +6927,50 @@ msgid "" "percentage (for example 50%) it will be calculated over support material " "speed." msgstr "" -"Speed for printing support material interface layers. If expressed as " -"percentage (for example 50%) it will be calculated over support material " -"speed." +"Vitesse d'impression des couches d'interface des supports. Si exprimée en " +"pourcentage (par exemple 50%), elle sera calculée à partir de la vitesse " +"d'impression des supports." #: src/libslic3r/PrintConfig.cpp:1914 msgid "Pattern" -msgstr "Pattern" +msgstr "Motif" #: src/libslic3r/PrintConfig.cpp:1916 msgid "Pattern used to generate support material." -msgstr "Pattern used to generate support material." +msgstr "Motif utilisé pour générer les supports." #: src/libslic3r/PrintConfig.cpp:1922 msgid "Rectilinear grid" -msgstr "Rectilinear grid" +msgstr "" #: src/libslic3r/PrintConfig.cpp:1928 msgid "Pattern spacing" -msgstr "Pattern spacing" +msgstr "Espacement du motif" #: src/libslic3r/PrintConfig.cpp:1930 msgid "Spacing between support material lines." -msgstr "Spacing between support material lines." +msgstr "Espacement entre les lignes des supports." #: src/libslic3r/PrintConfig.cpp:1939 msgid "Speed for printing support material." -msgstr "Speed for printing support material." +msgstr "Vitesse d'impression du support." #: src/libslic3r/PrintConfig.cpp:1946 msgid "Synchronize with object layers" -msgstr "Synchronize with object layers" +msgstr "Synchroniser avec les couches de l'objet" #: src/libslic3r/PrintConfig.cpp:1948 msgid "" "Synchronize support layers with the object print layers. This is useful with " "multi-material printers, where the extruder switch is expensive." msgstr "" -"Synchronize support layers with the object print layers. This is useful with " -"multi-material printers, where the extruder switch is expensive." +"Synchroniser les couches du support avec les couches d'impression de " +"l'objet. Cela est utile pour les imprimantes multi-matériaux, pour " +"lesquelles le changement d'extrudeur est onéreux." #: src/libslic3r/PrintConfig.cpp:1954 msgid "Overhang threshold" -msgstr "Overhang threshold" +msgstr "Seuil de surplomb" #: src/libslic3r/PrintConfig.cpp:1956 msgid "" @@ -6981,47 +6980,49 @@ msgid "" "that you can print without support material. Set to zero for automatic " "detection (recommended)." msgstr "" -"Support material will not be generated for overhangs whose slope angle (90° " -"= vertical) is above the given threshold. In other words, this value " -"represent the most horizontal slope (measured from the horizontal plane) " -"that you can print without support material. Set to zero for automatic " -"detection (recommended)." +"Le support ne sera pas généré pour les surplombs dont l'inclinaison (90° = " +"vertical) dépasse le seuil défini. Autrement dit, cette valeur représente " +"l'inclinaison horizontale maximum (mesurée à partir du plan horizontal) que " +"vous pouvez imprimer sans support. Réglez sur zéro pour une détection " +"automatique (recommandé)." #: src/libslic3r/PrintConfig.cpp:1968 msgid "With sheath around the support" -msgstr "With sheath around the support" +msgstr "Avec une enveloppe autour du support" #: src/libslic3r/PrintConfig.cpp:1970 msgid "" "Add a sheath (a single perimeter line) around the base support. This makes " "the support more reliable, but also more difficult to remove." msgstr "" -"Add a sheath (a single perimeter line) around the base support. This makes " -"the support more reliable, but also more difficult to remove." +"Ajouter une enveloppe (une ligne unique de périmètre) autour de la base du " +"support. Ceci rend le support plus fiable, mais aussi plus difficile à " +"retirer." #: src/libslic3r/PrintConfig.cpp:1977 msgid "" "Extruder temperature for layers after the first one. Set this to zero to " "disable temperature control commands in the output." msgstr "" -"Extruder temperature for layers after the first one. Set this to zero to " -"disable temperature control commands in the output." +"Température de l'extrudeur pour les couches après la première. Mettez zéro " +"pour désactiver les commandes de contrôle de la température dans le fichier " +"de sortie." #: src/libslic3r/PrintConfig.cpp:1979 msgid "Temperature" -msgstr "Temperature" +msgstr "Température" #: src/libslic3r/PrintConfig.cpp:1985 msgid "Detect thin walls" -msgstr "Detect thin walls" +msgstr "Détecter les parois fines" #: src/libslic3r/PrintConfig.cpp:1987 msgid "" "Detect single-width walls (parts where two extrusions don't fit and we need " "to collapse them into a single trace)." msgstr "" -"Detect single-width walls (parts where two extrusions don't fit and we need " -"to collapse them into a single trace)." +"Détecter les parois de largeur unique (où deux extrusions côte à côte ne " +"rentrent pas et doivent êtres fusionnées en un seul trait)." #: src/libslic3r/PrintConfig.cpp:1993 msgid "Threads" @@ -7032,8 +7033,9 @@ msgid "" "Threads are used to parallelize long-running tasks. Optimal threads number " "is slightly above the number of available cores/processors." msgstr "" -"Threads are used to parallelize long-running tasks. Optimal threads number " -"is slightly above the number of available cores/processors." +"Les threads sont utilisés pour paralléliser les calculs longs. Le nombre " +"optimal de threads est légèrement supérieur au nombre de coeurs/processeurs " +"disponibles." #: src/libslic3r/PrintConfig.cpp:2006 msgid "" @@ -7041,9 +7043,9 @@ msgid "" "you can use placeholder variables for all Slic3r settings as well as " "[previous_extruder] and [next_extruder]." msgstr "" -"This custom code is inserted right before every extruder change. Note that " -"you can use placeholder variables for all Slic3r settings as well as " -"[previous_extruder] and [next_extruder]." +"Ce code personnalisé est inséré juste avant chaque changement d'extrudeur. " +"Notez que vous pouvez utiliser des variables génériques pour tous les " +"réglages de Slic3r de même que [previous_extruder] et [next_extruder]." #: src/libslic3r/PrintConfig.cpp:2018 msgid "" @@ -7053,11 +7055,14 @@ msgid "" "will be used if set, otherwise nozzle diameter will be used. If expressed as " "percentage (for example 90%) it will be computed over layer height." msgstr "" -"Set this to a non-zero value to set a manual extrusion width for infill for " -"top surfaces. You may want to use thinner extrudates to fill all narrow " -"regions and get a smoother finish. If left zero, default extrusion width " -"will be used if set, otherwise nozzle diameter will be used. If expressed as " -"percentage (for example 90%) it will be computed over layer height." +"Réglez ce paramètre sur une valeur non-nulle pour définir manuellement la " +"largeur d’extrusion pour le remplissage ou les surfaces supérieures. Vous " +"voudrez peut-être utiliser des extrudats plus fins pour remplir les zones " +"les plus étroites et obtenir des finitions plus lisses. Si la valeur reste " +"sur zéro, la largeur d’extrusion par défaut sera utilisée si définie, sinon " +"le diamètre de la buse sera utilisé. Si la valeur est exprimée en " +"pourcentage (par exemple : 90%), elle sera calculée par rapport à la hauteur " +"de couche." #: src/libslic3r/PrintConfig.cpp:2029 msgid "" @@ -7067,51 +7072,56 @@ msgid "" "percentage (for example: 80%) over the solid infill speed above. Set to zero " "for auto." msgstr "" -"Speed for printing top solid layers (it only applies to the uppermost " -"external layers and not to their internal solid layers). You may want to " -"slow down this to get a nicer surface finish. This can be expressed as a " -"percentage (for example: 80%) over the solid infill speed above. Set to zero " -"for auto." +"Vitesse pour imprimer les couches solides supérieures (ne s'applique qu'aux " +"couches externes les plus hautes et pas aux couches internes solides). Vous " +"voudrez peut-être abaisser cette vitesse afin d'avoir une finition de " +"surface plus nette. Peut être exprimé en pourcentage (par exemple: 80%) de " +"la vitesse de remplissage solide susmentionnée. Réglez sur zéro pour un " +"ajustement automatique." #: src/libslic3r/PrintConfig.cpp:2043 msgid "Number of solid layers to generate on top surfaces." -msgstr "Number of solid layers to generate on top surfaces." +msgstr "Nombre de couches solides à générer sur les surfaces supérieures." #: src/libslic3r/PrintConfig.cpp:2044 msgid "Top solid layers" -msgstr "Top solid layers" +msgstr "Couches supérieures solides" #: src/libslic3r/PrintConfig.cpp:2050 msgid "Speed for travel moves (jumps between distant extrusion points)." -msgstr "Speed for travel moves (jumps between distant extrusion points)." +msgstr "" +"Vitesse pour les déplacements (trajet entre deux points d'extrusion " +"distants)." #: src/libslic3r/PrintConfig.cpp:2058 msgid "Use firmware retraction" -msgstr "Use firmware retraction" +msgstr "Utiliser la rétractation du firmware" #: src/libslic3r/PrintConfig.cpp:2059 msgid "" "This experimental setting uses G10 and G11 commands to have the firmware " "handle the retraction. This is only supported in recent Marlin." msgstr "" -"This experimental setting uses G10 and G11 commands to have the firmware " -"handle the retraction. This is only supported in recent Marlin." +"Ce réglage expérimental utilise les commandes G10 et G11 pour laisser le " +"firmware gérer la rétractation. Utilisable seulement par les versions " +"récentes de Marlin." #: src/libslic3r/PrintConfig.cpp:2065 msgid "Use relative E distances" -msgstr "Use relative E distances" +msgstr "Utiliser des valeurs E relatives" #: src/libslic3r/PrintConfig.cpp:2066 msgid "" "If your firmware requires relative E values, check this, otherwise leave it " "unchecked. Most firmwares use absolute values." msgstr "" -"If your firmware requires relative E values, check this, otherwise leave it " -"unchecked. Most firmwares use absolute values." +"Si votre firmware requiert des valeurs relatives pour E, cochez cette case, " +"sinon laissez-la décochée. La plupart des firmwares utilisent des valeurs " +"absolues." #: src/libslic3r/PrintConfig.cpp:2072 msgid "Use volumetric E" -msgstr "Use volumetric E" +msgstr "E Volumétrique" #: src/libslic3r/PrintConfig.cpp:2073 msgid "" @@ -7122,48 +7132,51 @@ msgid "" "filament diameter associated to the filament selected in Slic3r. This is " "only supported in recent Marlin." msgstr "" -"This experimental setting uses outputs the E values in cubic millimeters " -"instead of linear millimeters. If your firmware doesn't already know " -"filament diameter(s), you can put commands like 'M200 D[filament_diameter_0] " -"T0' in your start G-code in order to turn volumetric mode on and use the " -"filament diameter associated to the filament selected in Slic3r. This is " -"only supported in recent Marlin." +"Cette fonction expérimentale génère des valeurs de E en millimètres cubiques " +"au lieu de millimètres linéaires. Si votre firmware ne connait pas déjà le " +"diamètre du filament, vous pouvez saisir une commande comme 'M200 " +"D[filament_diameter_0] T0' dans votre G-Code de début pour activer le mode " +"volumétrique, et utiliser le diamètre de filament associé au filament choisi " +"dans Slic3r. Cette fonction n'est utilisable que dans les versions récentes " +"de Marlin." #: src/libslic3r/PrintConfig.cpp:2083 msgid "Enable variable layer height feature" -msgstr "Enable variable layer height feature" +msgstr "Activer la fonction de hauteur de couche variable" #: src/libslic3r/PrintConfig.cpp:2084 msgid "" "Some printers or printer setups may have difficulties printing with a " "variable layer height. Enabled by default." msgstr "" -"Some printers or printer setups may have difficulties printing with a " -"variable layer height. Enabled by default." +"Certaines imprimantes ou certains réglages d'imprimante peuvent rencontrer " +"des difficultés pour imprimer avec une hauteur de couche variable. Activé " +"par défaut." #: src/libslic3r/PrintConfig.cpp:2090 msgid "Wipe while retracting" -msgstr "Wipe while retracting" +msgstr "Nettoyer lors des rétractations" #: src/libslic3r/PrintConfig.cpp:2091 msgid "" "This flag will move the nozzle while retracting to minimize the possible " "blob on leaky extruders." msgstr "" -"This flag will move the nozzle while retracting to minimize the possible " -"blob on leaky extruders." +"Cette option déplace la buse lors des rétractations, limitant ainsi " +"l'apparition d'amas sur les extrudeurs ayant tendance à couler." #: src/libslic3r/PrintConfig.cpp:2098 msgid "" "Multi material printers may need to prime or purge extruders on tool " "changes. Extrude the excess material into the wipe tower." msgstr "" -"Multi material printers may need to prime or purge extruders on tool " -"changes. Extrude the excess material into the wipe tower." +"Les imprimantes multi-matériaux peuvent avoir besoin de préparer ou de " +"purger leurs extrudeurs lors d'un changement d'outil. Extruder le matériau " +"en excès dans la tour de nettoyage." #: src/libslic3r/PrintConfig.cpp:2104 msgid "Purging volumes - load/unload volumes" -msgstr "Purging volumes - load/unload volumes" +msgstr "Volumes de purge - volumes de chargement/déchargement" #: src/libslic3r/PrintConfig.cpp:2105 msgid "" @@ -7171,21 +7184,22 @@ msgid "" "wipe tower. These values are used to simplify creation of the full purging " "volumes below. " msgstr "" -"This vector saves required volumes to change from/to each tool used on the " -"wipe tower. These values are used to simplify creation of the full purging " -"volumes below. " +"Ce vecteur enregistre les volumes requis pour changer l'outil utilisé pour " +"la tour de nettoyage. Ces valeurs sont utilisées pour simplifier la création " +"des volumes de purge complets ci-dessous. " #: src/libslic3r/PrintConfig.cpp:2111 msgid "Purging volumes - matrix" -msgstr "Purging volumes - matrix" +msgstr "Volumes de purge - matrice" #: src/libslic3r/PrintConfig.cpp:2112 msgid "" "This matrix describes volumes (in cubic milimetres) required to purge the " "new filament on the wipe tower for any given pair of tools. " msgstr "" -"This matrix describes volumes (in cubic milimetres) required to purge the " -"new filament on the wipe tower for any given pair of tools. " +"Cette matrice décrit les volumes (en millimètres cube) nécessaires pour " +"purger le nouveau filament dans la tour de nettoyage pour une paire d'outils " +"donnée. " #: src/libslic3r/PrintConfig.cpp:2121 msgid "Position X" @@ -7193,7 +7207,7 @@ msgstr "Position X" #: src/libslic3r/PrintConfig.cpp:2122 msgid "X coordinate of the left front corner of a wipe tower" -msgstr "X coordinate of the left front corner of a wipe tower" +msgstr "Coordonnée X du coin avant gauche d'une tour de nettoyage" #: src/libslic3r/PrintConfig.cpp:2128 msgid "Position Y" @@ -7201,27 +7215,27 @@ msgstr "Position Y" #: src/libslic3r/PrintConfig.cpp:2129 msgid "Y coordinate of the left front corner of a wipe tower" -msgstr "Y coordinate of the left front corner of a wipe tower" +msgstr "Coordonnée Y du coin avant gauche d'une tour de nettoyage" #: src/libslic3r/PrintConfig.cpp:2136 msgid "Width of a wipe tower" -msgstr "Width of a wipe tower" +msgstr "Largeur d'une tour de nettoyage" #: src/libslic3r/PrintConfig.cpp:2142 msgid "Wipe tower rotation angle" -msgstr "Wipe tower rotation angle" +msgstr "Angle de rotation de la tour de nettoyage" #: src/libslic3r/PrintConfig.cpp:2143 msgid "Wipe tower rotation angle with respect to x-axis " -msgstr "Wipe tower rotation angle with respect to x-axis " +msgstr "Angle de rotation de la tour de nettoyage par rapport à l'axe X " -#: src/libslic3r/PrintConfig.cpp:2144 src/libslic3r/PrintConfig.cpp:2565 +#: src/libslic3r/PrintConfig.cpp:2144 src/libslic3r/PrintConfig.cpp:2570 msgid "degrees" -msgstr "degrees" +msgstr "degrés" #: src/libslic3r/PrintConfig.cpp:2150 msgid "Wipe into this object's infill" -msgstr "Wipe into this object's infill" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2151 msgid "" @@ -7229,13 +7243,10 @@ msgid "" "the amount of waste but may result in longer print time due to additional " "travel moves." msgstr "" -"Purging after toolchange will done inside this object's infills. This lowers " -"the amount of waste but may result in longer print time due to additional " -"travel moves." #: src/libslic3r/PrintConfig.cpp:2158 msgid "Wipe into this object" -msgstr "Wipe into this object" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2159 msgid "" @@ -7243,21 +7254,19 @@ msgid "" "that would otherwise end up in the wipe tower and decrease print time. " "Colours of the objects will be mixed as a result." msgstr "" -"Object will be used to purge the nozzle after a toolchange to save material " -"that would otherwise end up in the wipe tower and decrease print time. " -"Colours of the objects will be mixed as a result." #: src/libslic3r/PrintConfig.cpp:2165 msgid "Maximal bridging distance" -msgstr "Maximal bridging distance" +msgstr "Distance maximale de pont" #: src/libslic3r/PrintConfig.cpp:2166 msgid "Maximal distance between supports on sparse infill sections. " -msgstr "Maximal distance between supports on sparse infill sections. " +msgstr "" +"Distance maximale entre les supports sur les sections de remplissage épars. " #: src/libslic3r/PrintConfig.cpp:2172 msgid "XY Size Compensation" -msgstr "XY Size Compensation" +msgstr "Compensation de Taille XY" #: src/libslic3r/PrintConfig.cpp:2174 msgid "" @@ -7265,13 +7274,13 @@ msgid "" "(negative = inwards, positive = outwards). This might be useful for fine-" "tuning hole sizes." msgstr "" -"The object will be grown/shrunk in the XY plane by the configured value " -"(negative = inwards, positive = outwards). This might be useful for fine-" -"tuning hole sizes." +"L'objet sera agrandi/réduit sur les plans XY selon la valeur indiquée " +"(négatif = réduit, positif = agrandi). Ce réglage peut être utile pour un " +"réglage fin des tailles de trous." #: src/libslic3r/PrintConfig.cpp:2182 msgid "Z offset" -msgstr "Z offset" +msgstr "Décalage Z" #: src/libslic3r/PrintConfig.cpp:2183 msgid "" @@ -7280,42 +7289,43 @@ msgid "" "example, if your endstop zero actually leaves the nozzle 0.3mm far from the " "print bed, set this to -0.3 (or fix your endstop)." msgstr "" -"This value will be added (or subtracted) from all the Z coordinates in the " -"output G-code. It is used to compensate for bad Z endstop position: for " -"example, if your endstop zero actually leaves the nozzle 0.3mm far from the " -"print bed, set this to -0.3 (or fix your endstop)." +"Cette valeur sera ajoutée (ou soustraite) de toutes les coordonnées Z dans " +"le G-Code de sortie. Elle est utilisée pour compenser une mauvaise position " +"de fin de course Z: par exemple si votre fin de course place votre buse à " +"0.3mm au dessus du plateau, réglez cette valeur sur -0.3 (ou corrigez votre " +"fin de course)." #: src/libslic3r/PrintConfig.cpp:2200 msgid "Display width" -msgstr "Display width" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2201 msgid "Width of the display" -msgstr "Width of the display" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2206 msgid "Display height" -msgstr "Display height" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2207 msgid "Height of the display" -msgstr "Height of the display" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2212 msgid "Number of pixels in" -msgstr "Number of pixels in" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2214 msgid "Number of pixels in X" -msgstr "Number of pixels in X" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2220 msgid "Number of pixels in Y" -msgstr "Number of pixels in Y" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2225 msgid "Display orientation" -msgstr "Display orientation" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2226 msgid "" @@ -7323,45 +7333,42 @@ msgid "" "will flip the meaning of display width and height parameters and the output " "images will be rotated by 90 degrees." msgstr "" -"Set the actual LCD display orientation inside the SLA printer. Portrait mode " -"will flip the meaning of display width and height parameters and the output " -"images will be rotated by 90 degrees." #: src/libslic3r/PrintConfig.cpp:2232 msgid "Landscape" -msgstr "Landscape" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2233 msgid "Portrait" -msgstr "Portrait" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2238 msgid "Fast" -msgstr "Fast" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2239 msgid "Fast tilt" -msgstr "Fast tilt" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2240 msgid "Time of the fast tilt" -msgstr "Time of the fast tilt" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2247 msgid "Slow" -msgstr "Slow" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2248 msgid "Slow tilt" -msgstr "Slow tilt" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2249 msgid "Time of the slow tilt" -msgstr "Time of the slow tilt" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2256 msgid "Area fill" -msgstr "Area fill" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2257 msgid "" @@ -7369,572 +7376,551 @@ msgid "" "If the print area exceeds the specified value, \n" "then a slow tilt will be used, otherwise - a fast tilt" msgstr "" -"The percentage of the bed area. \n" -"If the print area exceeds the specified value, \n" -"then a slow tilt will be used, otherwise - a fast tilt" #: src/libslic3r/PrintConfig.cpp:2264 src/libslic3r/PrintConfig.cpp:2265 #: src/libslic3r/PrintConfig.cpp:2266 msgid "Printer scaling correction" -msgstr "Printer scaling correction" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2272 src/libslic3r/PrintConfig.cpp:2273 msgid "Printer absolute correction" -msgstr "Printer absolute correction" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2274 msgid "" "Will inflate or deflate the sliced 2D polygons according to the sign of the " "correction." msgstr "" -"Will inflate or deflate the sliced 2D polygons according to the sign of the " -"correction." #: src/libslic3r/PrintConfig.cpp:2280 src/libslic3r/PrintConfig.cpp:2281 msgid "Printer gamma correction" -msgstr "Printer gamma correction" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2282 -msgid "This will apply a gamm correction to the rasterized 2D polygons." -msgstr "This will apply a gamm correction to the rasterized 2D polygons." +msgid "" +"This will apply a gamma correction to the rasterized 2D polygons. A gamma " +"value of zero means thresholding with the threshold in the middle. This " +"behaviour eliminates antialiasing without losing holes in polygons." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2291 src/libslic3r/PrintConfig.cpp:2292 +#: src/libslic3r/PrintConfig.cpp:2293 src/libslic3r/PrintConfig.cpp:2294 msgid "Initial layer height" -msgstr "Initial layer height" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2298 +#: src/libslic3r/PrintConfig.cpp:2300 msgid "Faded layers" -msgstr "Faded layers" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2299 +#: src/libslic3r/PrintConfig.cpp:2301 msgid "" "Number of the layers needed for the exposure time fade from initial exposure " "time to the exposure time" msgstr "" -"Number of the layers needed for the exposure time fade from initial exposure " -"time to the exposure time" -#: src/libslic3r/PrintConfig.cpp:2306 src/libslic3r/PrintConfig.cpp:2307 +#: src/libslic3r/PrintConfig.cpp:2308 src/libslic3r/PrintConfig.cpp:2309 msgid "Exposure time" -msgstr "Exposure time" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2313 src/libslic3r/PrintConfig.cpp:2314 +#: src/libslic3r/PrintConfig.cpp:2315 src/libslic3r/PrintConfig.cpp:2316 msgid "Initial exposure time" -msgstr "Initial exposure time" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2320 src/libslic3r/PrintConfig.cpp:2321 +#: src/libslic3r/PrintConfig.cpp:2322 src/libslic3r/PrintConfig.cpp:2323 msgid "Correction for expansion" -msgstr "Correction for expansion" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2327 +#: src/libslic3r/PrintConfig.cpp:2329 msgid "SLA print material notes" -msgstr "SLA print material notes" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2328 +#: src/libslic3r/PrintConfig.cpp:2330 msgid "You can put your notes regarding the SLA print material here." -msgstr "You can put your notes regarding the SLA print material here." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2336 src/libslic3r/PrintConfig.cpp:2347 +#: src/libslic3r/PrintConfig.cpp:2338 src/libslic3r/PrintConfig.cpp:2349 msgid "Default SLA material profile" -msgstr "Default SLA material profile" - -#: src/libslic3r/PrintConfig.cpp:2358 -msgid "Generate supports" -msgstr "Generate supports" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2360 -msgid "Generate supports for the models" -msgstr "Generate supports for the models" +msgid "Generate supports" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2365 -msgid "Support head front diameter" -msgstr "Support head front diameter" +#: src/libslic3r/PrintConfig.cpp:2362 +msgid "Generate supports for the models" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2367 -msgid "Diameter of the pointing side of the head" -msgstr "Diameter of the pointing side of the head" +msgid "Support head front diameter" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2374 -msgid "Support head penetration" -msgstr "Support head penetration" +#: src/libslic3r/PrintConfig.cpp:2369 +msgid "Diameter of the pointing side of the head" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2376 -msgid "How much the pinhead has to penetrate the model surface" -msgstr "How much the pinhead has to penetrate the model surface" +msgid "Support head penetration" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2383 -msgid "Support head width" -msgstr "Support head width" +#: src/libslic3r/PrintConfig.cpp:2378 +msgid "How much the pinhead has to penetrate the model surface" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2385 -msgid "Width from the back sphere center to the front sphere center" -msgstr "Width from the back sphere center to the front sphere center" +msgid "Support head width" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2393 -msgid "Support pillar diameter" -msgstr "Support pillar diameter" +#: src/libslic3r/PrintConfig.cpp:2387 +msgid "Width from the back sphere center to the front sphere center" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2395 +msgid "Support pillar diameter" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2397 msgid "Diameter in mm of the support pillars" -msgstr "Diameter in mm of the support pillars" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2403 +#: src/libslic3r/PrintConfig.cpp:2405 msgid "Support pillar connection mode" -msgstr "Support pillar connection mode" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2404 +#: src/libslic3r/PrintConfig.cpp:2406 msgid "" "Controls the bridge type between two neigboring pillars. Can be zig-zag, " "cross (double zig-zag) or dynamic which will automatically switch between " "the first two depending on the distance of the two pillars." msgstr "" -"Controls the bridge type between two neigboring pillars. Can be zig-zag, " -"cross (double zig-zag) or dynamic which will automatically switch between " -"the first two depending on the distance of the two pillars." - -#: src/libslic3r/PrintConfig.cpp:2412 -msgid "Zig-Zag" -msgstr "Zig-Zag" - -#: src/libslic3r/PrintConfig.cpp:2413 -msgid "Cross" -msgstr "Cross" #: src/libslic3r/PrintConfig.cpp:2414 -msgid "Dynamic" -msgstr "Dynamic" +msgid "Zig-Zag" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2426 -msgid "Pillar widening factor" -msgstr "Pillar widening factor" +#: src/libslic3r/PrintConfig.cpp:2415 +msgid "Cross" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2416 +msgid "Dynamic" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2428 +msgid "Pillar widening factor" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2430 msgid "" "Merging bridges or pillars into another pillars can increase the radius. " "Zero means no increase, one means full increase." msgstr "" -"Merging bridges or pillars into another pillars can increase the radius. " -"Zero means no increase, one means full increase." - -#: src/libslic3r/PrintConfig.cpp:2437 -msgid "Support base diameter" -msgstr "Support base diameter" #: src/libslic3r/PrintConfig.cpp:2439 -msgid "Diameter in mm of the pillar base" -msgstr "Diameter in mm of the pillar base" +msgid "Support base diameter" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2447 -msgid "Support base height" -msgstr "Support base height" +#: src/libslic3r/PrintConfig.cpp:2441 +msgid "Diameter in mm of the pillar base" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2449 -msgid "The height of the pillar base cone" -msgstr "The height of the pillar base cone" +msgid "Support base height" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2456 -msgid "Critical angle" -msgstr "Critical angle" +#: src/libslic3r/PrintConfig.cpp:2451 +msgid "The height of the pillar base cone" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2458 -msgid "The default angle for connecting support sticks and junctions." -msgstr "The default angle for connecting support sticks and junctions." +msgid "Critical angle" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2466 -msgid "Max bridge length" -msgstr "Max bridge length" +#: src/libslic3r/PrintConfig.cpp:2460 +msgid "The default angle for connecting support sticks and junctions." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2468 -msgid "The max length of a bridge" -msgstr "The max length of a bridge" +msgid "Max bridge length" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2475 -msgid "Max pillar linking distance" -msgstr "Max pillar linking distance" +#: src/libslic3r/PrintConfig.cpp:2470 +msgid "The max length of a bridge" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2477 +msgid "Max pillar linking distance" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2479 msgid "" "The max distance of two pillars to get linked with each other. A zero value " "will prohibit pillar cascading." msgstr "" -"The max distance of two pillars to get linked with each other. A zero value " -"will prohibit pillar cascading." - -#: src/libslic3r/PrintConfig.cpp:2485 -msgid "Object elevation" -msgstr "Object elevation" #: src/libslic3r/PrintConfig.cpp:2487 -msgid "How much the supports should lift up the supported object." -msgstr "How much the supports should lift up the supported object." +msgid "Object elevation" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2495 -msgid "Support points density" -msgstr "Support points density" +#: src/libslic3r/PrintConfig.cpp:2489 +msgid "How much the supports should lift up the supported object." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2497 -msgid "This is a relative measure of support points density." -msgstr "This is a relative measure of support points density." +msgid "Support points density" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2503 -msgid "Minimal distance of the support points" -msgstr "Minimal distance of the support points" +#: src/libslic3r/PrintConfig.cpp:2499 +msgid "This is a relative measure of support points density." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2505 -msgid "No support points will be placed closer than this threshold." -msgstr "No support points will be placed closer than this threshold." +msgid "Minimal distance of the support points" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2511 -msgid "Use pad" -msgstr "Use pad" +#: src/libslic3r/PrintConfig.cpp:2507 +msgid "No support points will be placed closer than this threshold." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2513 -msgid "Add a pad underneath the supported model" -msgstr "Add a pad underneath the supported model" +msgid "Use pad" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2518 -msgid "Pad wall thickness" -msgstr "Pad wall thickness" +#: src/libslic3r/PrintConfig.cpp:2515 +msgid "Add a pad underneath the supported model" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2520 +msgid "Pad wall thickness" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2522 msgid "The thickness of the pad and its optional cavity walls." -msgstr "The thickness of the pad and its optional cavity walls." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2528 +#: src/libslic3r/PrintConfig.cpp:2530 msgid "Pad wall height" -msgstr "Pad wall height" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2529 -msgid "Defines the cavity depth. Set to zero to disable the cavity." -msgstr "Defines the cavity depth. Set to zero to disable the cavity." +#: src/libslic3r/PrintConfig.cpp:2531 +msgid "" +"Defines the pad cavity depth. Set to zero to disable the cavity. Be careful " +"when enabling this feature, as some resins may produce an extreme suction " +"effect inside the cavity, which makes pealing the print off the vat foil " +"difficult." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2539 +#: src/libslic3r/PrintConfig.cpp:2544 msgid "Max merge distance" -msgstr "Max merge distance" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2541 +#: src/libslic3r/PrintConfig.cpp:2546 msgid "" "Some objects can get along with a few smaller pads instead of a single big " "one. This parameter defines how far the center of two smaller pads should " "be. If theyare closer, they will get merged into one pad." msgstr "" -"Some objects can get along with a few smaller pads instead of a single big " -"one. This parameter defines how far the center of two smaller pads should " -"be. If theyare closer, they will get merged into one pad." -#: src/libslic3r/PrintConfig.cpp:2552 +#: src/libslic3r/PrintConfig.cpp:2557 msgid "Pad edge radius" -msgstr "Pad edge radius" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2561 +#: src/libslic3r/PrintConfig.cpp:2566 msgid "Pad wall slope" -msgstr "Pad wall slope" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2563 +#: src/libslic3r/PrintConfig.cpp:2568 msgid "" "The slope of the pad wall relative to the bed plane. 90 degrees means " "straight walls." msgstr "" -"The slope of the pad wall relative to the bed plane. 90 degrees means " -"straight walls." -#: src/libslic3r/PrintConfig.cpp:2924 +#: src/libslic3r/PrintConfig.cpp:2929 msgid "Export SVG" -msgstr "Export SVG" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2925 +#: src/libslic3r/PrintConfig.cpp:2930 msgid "Export the model(s) as OBJ." -msgstr "Export the model(s) as OBJ." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2936 +#: src/libslic3r/PrintConfig.cpp:2941 msgid "Export SLA" -msgstr "Export SLA" - -#: src/libslic3r/PrintConfig.cpp:2937 -msgid "Slice the model and export SLA printing layers as PNG." -msgstr "Slice the model and export SLA printing layers as PNG." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2942 -msgid "Export 3MF" -msgstr "Export 3MF" - -#: src/libslic3r/PrintConfig.cpp:2943 -msgid "Export the model(s) as 3MF." -msgstr "Export the model(s) as 3MF." +msgid "Slice the model and export SLA printing layers as PNG." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2947 -msgid "Export AMF" -msgstr "Export AMF" +msgid "Export 3MF" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2948 -msgid "Export the model(s) as AMF." -msgstr "Export the model(s) as AMF." +msgid "Export the model(s) as 3MF." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2952 -msgid "Export STL" -msgstr "Export STL" +msgid "Export AMF" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2953 -msgid "Export the model(s) as STL." -msgstr "Export the model(s) as STL." +msgid "Export the model(s) as AMF." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2957 +msgid "Export STL" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2958 -msgid "Slice the model and export toolpaths as G-code." -msgstr "Slice the model and export toolpaths as G-code." +msgid "Export the model(s) as STL." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2963 -msgid "Slice" -msgstr "Slice" - -#: src/libslic3r/PrintConfig.cpp:2964 -msgid "" -"Slice the model as FFF or SLA based on the printer_technology configuration " -"value." +msgid "Slice the model and export toolpaths as G-code." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2968 +msgid "Slice" msgstr "" -"Slice the model as FFF or SLA based on the printer_technology configuration " -"value." #: src/libslic3r/PrintConfig.cpp:2969 -msgid "Help" -msgstr "Help" +msgid "" +"Slice the model as FFF or SLA based on the printer_technology configuration " +"value." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:2970 -msgid "Show this help." -msgstr "Show this help." +#: src/libslic3r/PrintConfig.cpp:2974 +msgid "Help" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2975 -msgid "Help (FFF options)" -msgstr "Help (FFF options)" - -#: src/libslic3r/PrintConfig.cpp:2976 -msgid "Show the full list of print/G-code configuration options." -msgstr "Show the full list of print/G-code configuration options." +msgid "Show this help." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2980 -msgid "Help (SLA options)" -msgstr "Help (SLA options)" +msgid "Help (FFF options)" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2981 -msgid "Show the full list of SLA print configuration options." -msgstr "Show the full list of SLA print configuration options." +msgid "Show the full list of print/G-code configuration options." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2985 -msgid "Output Model Info" -msgstr "Output Model Info" +msgid "Help (SLA options)" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2986 -msgid "Write information about the model to the console." -msgstr "Write information about the model to the console." +msgid "Show the full list of SLA print configuration options." +msgstr "" #: src/libslic3r/PrintConfig.cpp:2990 -msgid "Save config file" -msgstr "Save config file" +msgid "Output Model Info" +msgstr "" #: src/libslic3r/PrintConfig.cpp:2991 +msgid "Write information about the model to the console." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2995 +msgid "Save config file" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:2996 msgid "Save configuration to the specified file." -msgstr "Save configuration to the specified file." +msgstr "" -#: src/libslic3r/PrintConfig.cpp:3001 +#: src/libslic3r/PrintConfig.cpp:3006 msgid "Align XY" -msgstr "Align XY" - -#: src/libslic3r/PrintConfig.cpp:3002 -msgid "Align the model to the given point." -msgstr "Align the model to the given point." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3007 +msgid "Align the model to the given point." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3012 msgid "Cut model at the given Z." -msgstr "Cut model at the given Z." - -#: src/libslic3r/PrintConfig.cpp:3028 -msgid "Center" -msgstr "Center" - -#: src/libslic3r/PrintConfig.cpp:3029 -msgid "Center the print around the given center." -msgstr "Center the print around the given center." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3033 -msgid "Don't arrange" -msgstr "Don't arrange" +msgid "Center" +msgstr "" #: src/libslic3r/PrintConfig.cpp:3034 -msgid "" -"Do not rearrange the given models before merging and keep their original XY " -"coordinates." +msgid "Center the print around the given center." msgstr "" -"Do not rearrange the given models before merging and keep their original XY " -"coordinates." - -#: src/libslic3r/PrintConfig.cpp:3037 -msgid "Duplicate" -msgstr "Duplicate" #: src/libslic3r/PrintConfig.cpp:3038 -msgid "Multiply copies by this factor." -msgstr "Multiply copies by this factor." +msgid "Don't arrange" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3039 +msgid "" +"Do not rearrange the given models before merging and keep their original XY " +"coordinates." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3042 -msgid "Duplicate by grid" -msgstr "Duplicate by grid" +msgid "Duplicate" +msgstr "" #: src/libslic3r/PrintConfig.cpp:3043 -msgid "Multiply copies by creating a grid." -msgstr "Multiply copies by creating a grid." - -#: src/libslic3r/PrintConfig.cpp:3046 -msgid "Merge" -msgstr "Merge" +msgid "Multiply copies by this factor." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3047 -msgid "" -"Arrange the supplied models in a plate and merge them in a single model in " -"order to perform actions once." +msgid "Duplicate by grid" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3048 +msgid "Multiply copies by creating a grid." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3051 +msgid "Merge" msgstr "" -"Arrange the supplied models in a plate and merge them in a single model in " -"order to perform actions once." #: src/libslic3r/PrintConfig.cpp:3052 msgid "" +"Arrange the supplied models in a plate and merge them in a single model in " +"order to perform actions once." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3057 +msgid "" "Try to repair any non-manifold meshes (this option is implicitly added " "whenever we need to slice the model to perform the requested action)." msgstr "" -"Try to repair any non-manifold meshes (this option is implicitly added " -"whenever we need to slice the model to perform the requested action)." - -#: src/libslic3r/PrintConfig.cpp:3056 -msgid "Rotation angle around the Z axis in degrees." -msgstr "Rotation angle around the Z axis in degrees." - -#: src/libslic3r/PrintConfig.cpp:3060 -msgid "Rotate around X" -msgstr "Rotate around X" #: src/libslic3r/PrintConfig.cpp:3061 -msgid "Rotation angle around the X axis in degrees." -msgstr "Rotation angle around the X axis in degrees." +msgid "Rotation angle around the Z axis in degrees." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3065 -msgid "Rotate around Y" -msgstr "Rotate around Y" +msgid "Rotate around X" +msgstr "" #: src/libslic3r/PrintConfig.cpp:3066 -msgid "Rotation angle around the Y axis in degrees." -msgstr "Rotation angle around the Y axis in degrees." +msgid "Rotation angle around the X axis in degrees." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3070 +msgid "Rotate around Y" +msgstr "" #: src/libslic3r/PrintConfig.cpp:3071 -msgid "Scaling factor or percentage." -msgstr "Scaling factor or percentage." +msgid "Rotation angle around the Y axis in degrees." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3076 +msgid "Scaling factor or percentage." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3081 msgid "" "Detect unconnected parts in the given model(s) and split them into separate " "objects." msgstr "" -"Detect unconnected parts in the given model(s) and split them into separate " -"objects." -#: src/libslic3r/PrintConfig.cpp:3079 +#: src/libslic3r/PrintConfig.cpp:3084 msgid "Scale to Fit" -msgstr "Scale to Fit" +msgstr "" -#: src/libslic3r/PrintConfig.cpp:3080 +#: src/libslic3r/PrintConfig.cpp:3085 msgid "Scale to fit the given volume." -msgstr "Scale to fit the given volume." - -#: src/libslic3r/PrintConfig.cpp:3089 -msgid "Ignore non-existent config files" -msgstr "Ignore non-existent config files" - -#: src/libslic3r/PrintConfig.cpp:3090 -msgid "Do not fail if a file supplied to --load does not exist." -msgstr "Do not fail if a file supplied to --load does not exist." - -#: src/libslic3r/PrintConfig.cpp:3093 -msgid "Load config file" -msgstr "Load config file" +msgstr "" #: src/libslic3r/PrintConfig.cpp:3094 -msgid "" -"Load configuration from the specified file. It can be used more than once to " -"load options from multiple files." +msgid "Ignore non-existent config files" msgstr "" -"Load configuration from the specified file. It can be used more than once to " -"load options from multiple files." -#: src/libslic3r/PrintConfig.cpp:3097 -msgid "Output File" -msgstr "Output File" +#: src/libslic3r/PrintConfig.cpp:3095 +msgid "Do not fail if a file supplied to --load does not exist." +msgstr "" #: src/libslic3r/PrintConfig.cpp:3098 +msgid "Load config file" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3099 +msgid "" +"Load configuration from the specified file. It can be used more than once to " +"load options from multiple files." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3102 +msgid "Output File" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3103 msgid "" "The file where the output will be written (if not specified, it will be " "based on the input file)." msgstr "" -"The file where the output will be written (if not specified, it will be " -"based on the input file)." - -#: src/libslic3r/PrintConfig.cpp:3108 -msgid "Data directory" -msgstr "Data directory" - -#: src/libslic3r/PrintConfig.cpp:3109 -msgid "" -"Load and store settings at the given directory. This is useful for " -"maintaining different profiles or including configurations from a network " -"storage." -msgstr "" -"Load and store settings at the given directory. This is useful for " -"maintaining different profiles or including configurations from a network " -"storage." - -#: src/libslic3r/PrintConfig.cpp:3112 -msgid "Logging level" -msgstr "Logging level" #: src/libslic3r/PrintConfig.cpp:3113 +msgid "Data directory" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3114 +msgid "" +"Load and store settings at the given directory. This is useful for " +"maintaining different profiles or including configurations from a network " +"storage." +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3117 +msgid "Logging level" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3118 msgid "" "Messages with severity lower or eqal to the loglevel will be printed out. 0:" "trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal" msgstr "" -"Messages with severity lower or eqal to the loglevel will be printed out. 0:" -"trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal" + +#: src/libslic3r/PrintConfig.cpp:3123 +msgid "Render with a software renderer" +msgstr "" + +#: src/libslic3r/PrintConfig.cpp:3124 +msgid "" +"Render with a software renderer. The bundled MESA software renderer is " +"loaded instead of the default OpenGL driver." +msgstr "" #: src/libslic3r/GCode/PreviewData.cpp:176 msgid "Mixed" -msgstr "Mixed" +msgstr "" #: src/libslic3r/GCode/PreviewData.cpp:396 msgid "Height (mm)" -msgstr "Height (mm)" +msgstr "Hauteur (mm)" #: src/libslic3r/GCode/PreviewData.cpp:398 msgid "Width (mm)" -msgstr "Width (mm)" +msgstr "Largeur (mm)" #: src/libslic3r/GCode/PreviewData.cpp:400 msgid "Speed (mm/s)" -msgstr "Speed (mm/s)" +msgstr "Vitesse (mm/s)" #: src/libslic3r/GCode/PreviewData.cpp:402 msgid "Volumetric flow rate (mm3/s)" -msgstr "Volumetric flow rate (mm3/s)" +msgstr "Débit volumétrique (mm3/s)" #: src/libslic3r/GCode/PreviewData.cpp:491 msgid "Default print color" -msgstr "Default print color" +msgstr "" #: src/libslic3r/GCode/PreviewData.cpp:495 #, c-format msgid "up to %.2f mm" -msgstr "up to %.2f mm" +msgstr "" #: src/libslic3r/GCode/PreviewData.cpp:499 #, c-format msgid "above %.2f mm" -msgstr "above %.2f mm" +msgstr "" #: src/libslic3r/GCode/PreviewData.cpp:504 #, c-format msgid "%.2f - %.2f mm" -msgstr "%.2f - %.2f mm" +msgstr "" From 3f978f6afe95411ebe25fd8fcb38986b6d8ecbc4 Mon Sep 17 00:00:00 2001 From: Vojtech Kral <vojtech@kral.hk> Date: Thu, 25 Apr 2019 10:46:52 +0200 Subject: [PATCH 26/28] ConfigWizard: Fix app name interpolation --- src/slic3r/GUI/ConfigWizard.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 5e9327ffb..3d41285bb 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -406,16 +406,20 @@ PageUpdate::PageUpdate(ConfigWizard *parent) auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for application updates"))); box_slic3r->SetValue(app_config->get("version_check") == "1"); append(box_slic3r); - append_text(wxString::Format(_(L("If enabled, Slic3r checks for new versions of %s online. When a new version becomes available, " - "a notification is displayed at the next application startup (never during program usage). " - "This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME)); + append_text(wxString::Format(_(L( + "If enabled, %s checks for new application versions online. When a new version becomes available, " + "a notification is displayed at the next application startup (never during program usage). " + "This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME)); append_spacer(VERTICAL_SPACING); auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically"))); box_presets->SetValue(app_config->get("preset_update") == "1"); append(box_presets); - append_text(_(L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup."))); + append_text(wxString::Format(_(L( + "If enabled, %s downloads updates of built-in system presets in the background." + "These updates are downloaded into a separate temporary location." + "When a new preset version becomes available it is offered at application startup.")), SLIC3R_APP_NAME)); const auto text_bold = _(L("Updates are never applied without user's consent and never overwrite user's customized settings.")); auto *label_bold = new wxStaticText(this, wxID_ANY, text_bold); label_bold->SetFont(boldfont); From 708037158e78dfe0552b3ed5d9498da1832e031b Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 25 Apr 2019 15:06:44 +0200 Subject: [PATCH 27/28] Added msw_buttons_rescale() - Function for a scaling Dialog's buttons under MSW --- src/slic3r/GUI/AboutDialog.cpp | 4 ++- src/slic3r/GUI/ConfigSnapshotDialog.cpp | 7 ++-- src/slic3r/GUI/ConfigWizard.cpp | 23 ++++++++++-- src/slic3r/GUI/ConfigWizard_private.hpp | 4 +++ src/slic3r/GUI/Field.cpp | 18 +++++++--- src/slic3r/GUI/Field.hpp | 2 ++ src/slic3r/GUI/FirmwareDialog.cpp | 47 +++++++++++++++++-------- src/slic3r/GUI/FirmwareDialog.hpp | 10 +++++- src/slic3r/GUI/KBShortcutsDialog.cpp | 7 ++-- src/slic3r/GUI/OptionsGroup.cpp | 8 +++-- src/slic3r/GUI/Preferences.cpp | 11 +++--- src/slic3r/GUI/PrintHostDialogs.cpp | 15 ++++++-- src/slic3r/GUI/PrintHostDialogs.hpp | 4 ++- src/slic3r/GUI/SysInfoDialog.cpp | 11 +++--- src/slic3r/GUI/SysInfoDialog.hpp | 2 ++ src/slic3r/GUI/wxExtensions.cpp | 16 +++++++++ src/slic3r/GUI/wxExtensions.hpp | 3 +- 17 files changed, 149 insertions(+), 43 deletions(-) diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index fb1450ba1..b1a2556e7 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -133,13 +133,15 @@ void AboutDialog::on_dpi_changed(const wxRect &suggested_rect) const int& em = em_unit(); + msw_buttons_rescale(this, em, { wxID_CLOSE }); + m_html->SetMinSize(wxSize(-1, 16 * em)); m_html->Refresh(); const wxSize& size = wxSize(65 * em, 30 * em); SetMinSize(size); - SetSize(size); + Fit(); Refresh(); } diff --git a/src/slic3r/GUI/ConfigSnapshotDialog.cpp b/src/slic3r/GUI/ConfigSnapshotDialog.cpp index dd3e46229..b8634918b 100644 --- a/src/slic3r/GUI/ConfigSnapshotDialog.cpp +++ b/src/slic3r/GUI/ConfigSnapshotDialog.cpp @@ -6,6 +6,7 @@ #include "libslic3r/Utils.hpp" #include "GUI_App.hpp" +#include "wxExtensions.hpp" namespace Slic3r { namespace GUI { @@ -144,10 +145,12 @@ void ConfigSnapshotDialog::on_dpi_changed(const wxRect &suggested_rect) html->Refresh(); const int& em = em_unit(); - const wxSize& size = wxSize(45 * em, 40 * em); + msw_buttons_rescale(this, em, { wxID_CLOSE}); + + const wxSize& size = wxSize(45 * em, 40 * em); SetMinSize(size); - SetSize(size); + Fit(); Refresh(); } diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 3d41285bb..93cf1c73f 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -194,6 +194,9 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt title_sizer->Add(sel_all_std, 0, wxRIGHT, BTN_SPACING); title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING); title_sizer->Add(sel_none); + + // fill button indexes used later for buttons rescaling + m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() }; } sizer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, BTN_SPACING); @@ -1057,8 +1060,8 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) topsizer->AddSpacer(INDEX_MARGIN); topsizer->Add(p->hscroll, 1, wxEXPAND); - auto *btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all standard printers"))); - p->btnsizer->Add(btn_sel_all); + p->btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all standard printers"))); + p->btnsizer->Add(p->btn_sel_all); p->btn_prev = new wxButton(this, wxID_ANY, _(L("< &Back"))); p->btn_next = new wxButton(this, wxID_ANY, _(L("&Next >"))); @@ -1130,7 +1133,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->EndModal(wxID_OK); }); p->btn_finish->Hide(); - btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { + p->btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { p->page_fff->select_all(true, false); p->page_msla->select_all(true, false); p->index->go_to(p->page_update); @@ -1179,6 +1182,20 @@ const wxString& ConfigWizard::name(const bool from_menu/* = false*/) void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect) { p->index->msw_rescale(); + + const int& em = em_unit(); + + msw_buttons_rescale(this, em, { wxID_APPLY, + wxID_CANCEL, + p->btn_sel_all->GetId(), + p->btn_next->GetId(), + p->btn_prev->GetId() }); + + for (auto printer_picker: p->page_fff->printer_pickers) + msw_buttons_rescale(this, em, printer_picker->get_button_indexes()); + + // FIXME VK SetSize(???) + Refresh(); } diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index 31a990b60..95411e2aa 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -69,8 +69,11 @@ struct PrinterPicker: wxPanel void on_checkbox(const Checkbox *cbox, bool checked); int get_width() const { return width; } + const std::vector<int>& get_button_indexes() { return m_button_indexes; } private: int width; + + std::vector<int> m_button_indexes; }; struct ConfigWizardPage: wxPanel @@ -267,6 +270,7 @@ struct ConfigWizard::priv wxBoxSizer *btnsizer = nullptr; ConfigWizardPage *page_current = nullptr; ConfigWizardIndex *index = nullptr; + wxButton *btn_sel_all = nullptr; wxButton *btn_prev = nullptr; wxButton *btn_next = nullptr; wxButton *btn_finish = nullptr; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 822361c5d..738ec2e00 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -379,8 +379,8 @@ void TextCtrl::change_field_value(wxEvent& event) void CheckBox::BUILD() { auto size = wxSize(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height); - if (m_opt.width >= 0) size.SetWidth(m_opt.width); + if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); + if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); bool check_value = m_opt.type == coBool ? m_opt.default_value->getBool() : m_opt.type == coBools ? @@ -413,6 +413,14 @@ boost::any& CheckBox::get_value() return m_value; } +void CheckBox::msw_rescale() +{ + Field::msw_rescale(); + + wxCheckBox* field = dynamic_cast<wxCheckBox*>(window); + field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y +0.5f))); +} + int undef_spin_val = -9999; //! Probably, It's not necessary void SpinCtrl::BUILD() { @@ -849,9 +857,11 @@ void Choice::msw_rescale() */ field->Clear(); wxSize size(wxDefaultSize); - if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit); size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * m_em_unit); - + + // Set rescaled min height to correct layout + field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y + 0.5f))); + // Set rescaled size field->SetSize(size); size_t idx, counter = idx = 0; diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 516570ea8..88ea39036 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -319,6 +319,8 @@ public: } boost::any& get_value() override; + void msw_rescale() override; + void enable() override { dynamic_cast<wxCheckBox*>(window)->Enable(); } void disable() override { dynamic_cast<wxCheckBox*>(window)->Disable(); } wxWindow* getWindow() override { return window; } diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 4fdc57679..5de5626db 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -18,6 +18,7 @@ #include "MsgDialog.hpp" #include "../Utils/HexFile.hpp" #include "../Utils/Serial.hpp" +#include "wxExtensions.hpp" // wx includes need to come after asio because of the WinSock.h problem #include "FirmwareDialog.hpp" @@ -118,6 +119,10 @@ struct FirmwareDialog::priv wxTimer timer_pulse; + int min_width; + int min_height; + int min_height_expanded; + // Async modal dialog during flashing std::mutex mutex; int modal_response; @@ -735,18 +740,10 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : GUI::DPIDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), p(new priv(this)) { - enum { - DIALOG_MARGIN = 15, - SPACING = 10, - MIN_WIDTH = 50, - MIN_HEIGHT = 18, - MIN_HEIGHT_EXPANDED = 40, - }; - const int em = GUI::wxGetApp().em_unit(); - int min_width = MIN_WIDTH * em; - int min_height = MIN_HEIGHT * em; - int min_height_expanded = MIN_HEIGHT_EXPANDED * em; + p->min_width = MIN_WIDTH * em; + p->min_height = MIN_HEIGHT * em; + p->min_height_expanded = MIN_HEIGHT_EXPANDED * em; /* get current font from application, * because of wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) function @@ -825,10 +822,10 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : auto *topsizer = new wxBoxSizer(wxVERTICAL); topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN); - SetMinSize(wxSize(min_width, min_height)); + SetMinSize(wxSize(p->min_width, p->min_height)); SetSizerAndFit(topsizer); const auto size = GetSize(); - SetSize(std::max(size.GetWidth(), static_cast<int>(min_width)), std::max(size.GetHeight(), static_cast<int>(min_height))); + SetSize(std::max(size.GetWidth(), static_cast<int>(p->min_width)), std::max(size.GetHeight(), static_cast<int>(p->min_height))); Layout(); SetEscapeId(wxID_CLOSE); // To close the dialog using "Esc" button @@ -844,11 +841,11 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [=](wxCollapsiblePaneEvent &evt) { if (evt.GetCollapsed()) { - this->SetMinSize(wxSize(min_width, min_height)); + this->SetMinSize(wxSize(p->min_width, p->min_height)); const auto new_height = this->GetSize().GetHeight() - this->p->txt_stdout->GetSize().GetHeight(); this->SetSize(this->GetSize().GetWidth(), new_height); } else { - this->SetMinSize(wxSize(min_width, min_height_expanded)); + this->SetMinSize(wxSize(p->min_width, p->min_height_expanded)); } this->Layout(); @@ -903,5 +900,25 @@ void FirmwareDialog::run(wxWindow *parent) dialog.ShowModal(); } +void FirmwareDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + const int& em = em_unit(); + + msw_buttons_rescale(this, em, { p->btn_close->GetId(), + p->btn_rescan->GetId(), + p->btn_flash->GetId(), + p->hex_picker->GetPickerCtrl()->GetId() + }); + + p->min_width = MIN_WIDTH * em; + p->min_height = MIN_HEIGHT * em; + p->min_height_expanded = MIN_HEIGHT_EXPANDED * em; + + const int min_height = p->spoiler->IsExpanded() ? p->min_height_expanded : p->min_height; + SetMinSize(wxSize(p->min_width, min_height)); + Fit(); + + Refresh(); +} } diff --git a/src/slic3r/GUI/FirmwareDialog.hpp b/src/slic3r/GUI/FirmwareDialog.hpp index a1eac00de..7c688d379 100644 --- a/src/slic3r/GUI/FirmwareDialog.hpp +++ b/src/slic3r/GUI/FirmwareDialog.hpp @@ -12,6 +12,14 @@ namespace Slic3r { class FirmwareDialog: public GUI::DPIDialog { + enum { + DIALOG_MARGIN = 15, + SPACING = 10, + MIN_WIDTH = 50, + MIN_HEIGHT = /*18*/25, + MIN_HEIGHT_EXPANDED = 40, + }; + public: FirmwareDialog(wxWindow *parent); FirmwareDialog(FirmwareDialog &&) = delete; @@ -23,7 +31,7 @@ public: static void run(wxWindow *parent); protected: - void on_dpi_changed(const wxRect &suggested_rect) override{;} + void on_dpi_changed(const wxRect &suggested_rect) override; private: struct priv; std::unique_ptr<priv> p; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 7f77474f2..066bc54fa 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -196,11 +196,14 @@ void KBShortcutsDialog::on_dpi_changed(const wxRect &suggested_rect) for (wxStaticBitmap* bmp : m_head_bitmaps) bmp->SetBitmap(m_logo_bmp.bmp()); - const int& em = em_unit(); + const int em = em_unit(); + + msw_buttons_rescale(this, em, { wxID_OK }); + const wxSize& size = wxSize(85 * em, 75 * em); SetMinSize(size); - SetSize(size); + Fit(); Refresh(); } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index fdbe3b038..099ebc8ba 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -516,17 +516,19 @@ void ConfigOptionsGroup::msw_rescale() { auto label = dynamic_cast<wxStaticText*>(label_item->GetWindow()); if (label != nullptr) { - label->SetMinSize(wxSize(label_width*em, -1)); + const int label_height = int(1.5f*label->GetFont().GetPixelSize().y + 0.5f); + label->SetMinSize(wxSize(label_width*em, /*-1*/label_height)); } } - else if (label_item->IsSizer()) // case when we nave near_label_widget + else if (label_item->IsSizer()) // case when we have near_label_widget { const wxSizerItem* l_item = label_item->GetSizer()->GetItem(1); if (l_item->IsWindow()) { auto label = dynamic_cast<wxStaticText*>(l_item->GetWindow()); if (label != nullptr) { - label->SetMinSize(wxSize(label_width*em, -1)); + const int label_height = int(1.5f*label->GetFont().GetPixelSize().y + 0.5f); + label->SetMinSize(wxSize(label_width*em, /*-1*/label_height)); } } } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 69f4e3493..81d242d4f 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -8,7 +8,7 @@ namespace GUI { PreferencesDialog::PreferencesDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { build(); } @@ -146,11 +146,14 @@ void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect) { m_optgroup->msw_rescale(); - const int& em = em_unit(); - const wxSize& size = wxSize(50 * em, 29 * em); + const int em = em_unit(); + + msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL }); + + const wxSize& size = wxSize(47 * em, 28 * em); SetMinSize(size); - SetSize(size); + Fit(); Refresh(); } diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 4fb03594b..2b6e4f2a2 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -19,6 +19,7 @@ #include "MsgDialog.hpp" #include "I18N.hpp" #include "../Utils/PrintHost.hpp" +#include "wxExtensions.hpp" namespace fs = boost::filesystem; @@ -136,8 +137,6 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) , on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this) , on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this) { - enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 }; - const auto em = GetTextExtent("m").x; SetSize(wxSize(HEIGHT * em, WIDTH * em)); @@ -202,6 +201,18 @@ void PrintHostQueueDialog::append_job(const PrintHostJob &job) job_list->AppendItem(fields, static_cast<wxUIntPtr>(ST_NEW)); } +void PrintHostQueueDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + const int& em = em_unit(); + + msw_buttons_rescale(this, em, { wxID_DELETE, wxID_CANCEL, btn_error->GetId() }); + + SetMinSize(wxSize(HEIGHT * em, WIDTH * em)); + + Fit(); + Refresh(); +} + PrintHostQueueDialog::JobState PrintHostQueueDialog::get_state(int idx) { wxCHECK_MSG(idx >= 0 && idx < job_list->GetItemCount(), ST_ERROR, "Out of bounds access to job list"); diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp index e6c46aae6..427c4f6bf 100644 --- a/src/slic3r/GUI/PrintHostDialogs.hpp +++ b/src/slic3r/GUI/PrintHostDialogs.hpp @@ -64,7 +64,7 @@ public: void append_job(const PrintHostJob &job); protected: - void on_dpi_changed(const wxRect &suggested_rect) override { Refresh(); } + void on_dpi_changed(const wxRect &suggested_rect) override; private: enum Column { @@ -85,6 +85,8 @@ private: ST_COMPLETED, }; + enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 }; + wxButton *btn_cancel; wxButton *btn_error; wxDataViewListCtrl *job_list; diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 31f75a926..162a36c75 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -117,9 +117,10 @@ SysInfoDialog::SysInfoDialog() } wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); - auto btn_copy_to_clipboard = new wxButton(this, wxID_ANY, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize); - buttons->Insert(0, btn_copy_to_clipboard, 0, wxLEFT, 5); - btn_copy_to_clipboard->Bind(wxEVT_BUTTON, &SysInfoDialog::onCopyToClipboard, this); + m_btn_copy_to_clipboard = new wxButton(this, wxID_ANY, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize); + + buttons->Insert(0, m_btn_copy_to_clipboard, 0, wxLEFT, 5); + m_btn_copy_to_clipboard->Bind(wxEVT_BUTTON, &SysInfoDialog::onCopyToClipboard, this); this->SetEscapeId(wxID_OK); this->Bind(wxEVT_BUTTON, &SysInfoDialog::onCloseDialog, this, wxID_OK); @@ -146,6 +147,8 @@ void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect) const int& em = em_unit(); + msw_buttons_rescale(this, em, { wxID_OK, m_btn_copy_to_clipboard->GetId() }); + m_opengl_info_html->SetMinSize(wxSize(-1, 16 * em)); m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); m_opengl_info_html->Refresh(); @@ -153,7 +156,7 @@ void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect) const wxSize& size = wxSize(65 * em, 55 * em); SetMinSize(size); - SetSize(size); + Fit(); Refresh(); } diff --git a/src/slic3r/GUI/SysInfoDialog.hpp b/src/slic3r/GUI/SysInfoDialog.hpp index dec4b5635..3b1459648 100644 --- a/src/slic3r/GUI/SysInfoDialog.hpp +++ b/src/slic3r/GUI/SysInfoDialog.hpp @@ -17,6 +17,8 @@ class SysInfoDialog : public DPIDialog wxHtmlWindow* m_opengl_info_html; wxHtmlWindow* m_html; + wxButton* m_btn_copy_to_clipboard; + public: SysInfoDialog(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 277494034..573106ae7 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -267,6 +267,22 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e cmb->SetText(selected); } +/* Function for rescale of buttons in Dialog under MSW if dpi is changed. + * btn_ids - vector of buttons identifiers + */ +void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids) +{ + const wxSize& btn_size = wxSize(-1, int(2.5f * em_unit + 0.5f)); + + for (int btn_id : btn_ids) { + // There is a case [FirmwareDialog], when we have wxControl instead of wxButton + // so let casting everything to the wxControl + wxControl* btn = static_cast<wxControl*>(dlg->FindWindowById(btn_id, dlg)); + if (btn) + btn->SetMinSize(btn_size); + } +} + /* Function for getting of em_unit value from correct parent. * In most of cases it is m_em_unit value from GUI_App, * but for DPIDialogs it's its own value. diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 7d63438c0..69369b3ff 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,7 +31,8 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler); -int em_unit(wxWindow* win); +void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids); +int em_unit(wxWindow* win); wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false); From 545d9df3c0db94615d87a83b6872f6cf733c4ef9 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 25 Apr 2019 16:23:50 +0200 Subject: [PATCH 28/28] Added missed class declaration under OSX --- src/slic3r/GUI/wxExtensions.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 69369b3ff..e40306ea1 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,6 +31,7 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler); +class wxDialog; void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids); int em_unit(wxWindow* win);