diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c9f5bd0af..ad7615f6d 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1370,11 +1370,6 @@ const std::vector& PhysicalPrinter::printer_options() return s_opts; } -const std::string& PhysicalPrinter::get_preset_name() const -{ - return config.opt_string("preset_name"); -} - const std::set& PhysicalPrinter::get_preset_names() const { return preset_names; @@ -1415,8 +1410,6 @@ void PhysicalPrinter::update_from_preset(const Preset& preset) // add preset names to the options list auto ret = preset_names.emplace(preset.name); update_preset_names_in_config(); - - update_full_name(); } void PhysicalPrinter::update_from_config(const DynamicPrintConfig& new_config) @@ -1431,8 +1424,6 @@ void PhysicalPrinter::update_from_config(const DynamicPrintConfig& new_config) preset_names.emplace(val); } preset_names = values; - - update_full_name(); } void PhysicalPrinter::reset_presets() @@ -1454,26 +1445,26 @@ PhysicalPrinter::PhysicalPrinter(const std::string& name, const Preset& preset) void PhysicalPrinter::set_name(const std::string& name) { this->name = name; - update_full_name(); } -void PhysicalPrinter::update_full_name() +std::string PhysicalPrinter::get_full_name(std::string preset_name) const { - full_name = name + separator() + get_preset_name(); + return name + separator() + preset_name; } std::string PhysicalPrinter::get_short_name(std::string full_name) { int pos = full_name.find(separator()); - boost::erase_tail(full_name, full_name.length() - pos); + if (pos > 0) + boost::erase_tail(full_name, full_name.length() - pos); return full_name; } -std::string PhysicalPrinter::get_preset_name(std::string full_name) +std::string PhysicalPrinter::get_preset_name(std::string name) { - int pos = full_name.find(separator()); - boost::erase_head(full_name, pos + 2); - return full_name; + int pos = name.find(separator()); + boost::erase_head(name, pos + 3); + return Preset::remove_suffix_modified(name); } @@ -1563,7 +1554,6 @@ void PhysicalPrinterCollection::save_printer(const PhysicalPrinter& edited_print it->config = std::move(edited_printer.config); it->name = edited_printer.name; it->preset_names = edited_printer.preset_names; - it->full_name = edited_printer.full_name; } else { // Creating a new printer. @@ -1615,17 +1605,43 @@ bool PhysicalPrinterCollection::delete_selected_printer() return true; } -PhysicalPrinter& PhysicalPrinterCollection::select_printer_by_name(std::string name) +std::string PhysicalPrinterCollection::get_selected_full_printer_name() const { - name = PhysicalPrinter::get_short_name(name); - auto it = this->find_printer_internal(name); + return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_printer().get_full_name(m_selected_preset); +} + +PhysicalPrinter& PhysicalPrinterCollection::select_printer_by_name(const std::string& full_name) +{ + std::string printer_name = PhysicalPrinter::get_short_name(full_name); + auto it = this->find_printer_internal(printer_name); assert(it != m_printers.end()); // update idx_selected - m_idx_selected = it - m_printers.begin(); + m_idx_selected = it - m_printers.begin(); + // update name of the currently selected preset + m_selected_preset = it->get_preset_name(full_name); + if (m_selected_preset.empty()) + m_selected_preset = *it->preset_names.begin(); return *it; } +bool PhysicalPrinterCollection::has_selection() const +{ + return m_idx_selected != size_t(-1); +} + +void PhysicalPrinterCollection::unselect_printer() +{ + m_idx_selected = size_t(-1); + m_selected_preset.clear(); +} + +bool PhysicalPrinterCollection::is_selected(PhysicalPrinterCollection::ConstIterator it, const std::string& preset_name) const +{ + return m_idx_selected == it - m_printers.begin() && + m_selected_preset == preset_name; +} + namespace PresetUtils { const VendorProfile::PrinterModel* system_printer_model(const Preset &preset) diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index d583bed20..d30ea7059 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -539,12 +539,9 @@ public: PhysicalPrinter(const std::string& name) : name(name){} PhysicalPrinter(const std::string& name, const Preset& preset); void set_name(const std::string &name); - void update_full_name(); // Name of the Physical Printer, usually derived form the file name. std::string name; - // Full name of the Physical Printer, included related preset name - std::string full_name; // File name of the Physical Printer. std::string file; // Configuration data, loaded from a file, or set from the defaults. @@ -558,8 +555,6 @@ public: bool loaded = false; static const std::vector& printer_options(); - const std::string& get_preset_name() const; - const std::set& get_preset_names() const; bool has_empty_config() const; @@ -588,6 +583,9 @@ public: // Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection. bool operator<(const PhysicalPrinter& other) const { return this->name < other.name; } + // get full printer name included a name of the preset + std::string get_full_name(std::string preset_name) const; + // get printer name from the full name uncluded preset name static std::string get_short_name(std::string full_name); @@ -641,22 +639,29 @@ public: bool delete_selected_printer(); // Return the selected preset, without the user modifications applied. - PhysicalPrinter& get_selected_printer() { return m_printers[m_idx_selected]; } - const PhysicalPrinter& get_selected_printer() const { return m_printers[m_idx_selected]; } - size_t get_selected_idx() const { return m_idx_selected; } + PhysicalPrinter& get_selected_printer() { return m_printers[m_idx_selected]; } + const PhysicalPrinter& get_selected_printer() const { return m_printers[m_idx_selected]; } + + size_t get_selected_idx() const { return m_idx_selected; } // Returns the name of the selected preset, or an empty string if no preset is selected. - std::string get_selected_printer_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_printer().name; } - // Returns the full name of the selected preset, or an empty string if no preset is selected. - std::string get_selected_full_printer_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_printer().full_name; } + std::string get_selected_printer_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_printer().name; } + // Returns the config of the selected printer, or nullptr if no printer is selected. + DynamicPrintConfig* get_selected_printer_config() { return (m_idx_selected == size_t(-1)) ? nullptr : &(this->get_selected_printer().config); } + // Returns the config of the selected printer, or nullptr if no printer is selected. + PrinterTechnology get_selected_printer_technology() { return (m_idx_selected == size_t(-1)) ? PrinterTechnology::ptAny : this->get_selected_printer().printer_technology(); } + + // Each physical printer can have a several related preset, + // so, use the next functions to get an exact names of selections in the list: + // Returns the full name of the selected printer, or an empty string if no preset is selected. + std::string get_selected_full_printer_name() const; // Returns the printer model of the selected preset, or an empty string if no preset is selected. - std::string get_selected_printer_preset_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_printer().get_preset_name(); } - // Returns the config of the selected preset, or nullptr if no preset is selected. - DynamicPrintConfig* get_selected_printer_config() { return (m_idx_selected == size_t(-1)) ? nullptr : &(this->get_selected_printer().config); } + std::string get_selected_printer_preset_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : m_selected_preset; } // select printer with name and return reference on it - PhysicalPrinter& select_printer_by_name(std::string name); - bool has_selection() const { return m_idx_selected != size_t(-1); } - void unselect_printer() { m_idx_selected = size_t(-1); } + PhysicalPrinter& select_printer_by_name(const std::string& full_name); + bool has_selection() const; + void unselect_printer() ; + bool is_selected(ConstIterator it, const std::string &preset_name) const; // Return a printer by an index. If the printer is active, a temporary copy is returned. PhysicalPrinter& printer(size_t idx) { return m_printers[idx]; } @@ -698,6 +703,8 @@ private: // Selected printer. size_t m_idx_selected = size_t(-1); + // The name of the preset which is currently select for this printer + std::string m_selected_preset; // Path to the directory to store the config files into. std::string m_dir_path; diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 7c4fa1cb2..7969966e5 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -458,7 +458,7 @@ void PresetBundle::export_selections(AppConfig &config) config.set("presets", "sla_material", sla_materials.get_selected_preset_name()); config.set("presets", "printer", printers.get_selected_preset_name()); - config.set("extras", "physical_printer", physical_printers.get_selected_printer_name()); + config.set("extras", "physical_printer", physical_printers.get_selected_full_printer_name()); } DynamicPrintConfig PresetBundle::full_config() const diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 048e17926..5673eece7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3208,24 +3208,21 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) if (preset_type == Preset::TYPE_FILAMENT) { wxGetApp().preset_bundle->set_filament_preset(idx, preset_name); } - - if (preset_type == Preset::TYPE_PRINTER) { - if(combo->is_selected_physical_printer()) { - // Select related printer preset on the Printer Settings Tab - const std::string printer_name = combo->GetString(selection).ToUTF8().data(); - PhysicalPrinter& printer = wxGetApp().preset_bundle->physical_printers.select_printer_by_name(printer_name); - preset_name = wxGetApp().preset_bundle->get_preset_name_by_alias(preset_type, printer.get_preset_name()); - } - else - wxGetApp().preset_bundle->physical_printers.unselect_printer(); - } + bool select_preset = !combo->selection_is_changed_according_to_physical_printers(); // TODO: ? if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) { // Only update the plater UI for the 2nd and other filaments. combo->update(); } - else { + else if (select_preset) { + if (preset_type == Preset::TYPE_PRINTER) { + PhysicalPrinterCollection& physical_printers = wxGetApp().preset_bundle->physical_printers; + if(combo->is_selected_physical_printer()) + preset_name = physical_printers.get_selected_printer_preset_name(); + else + physical_printers.unselect_printer(); + } wxWindowUpdateLocker noUpdates(sidebar->presets_panel()); wxGetApp().get_tab(preset_type)->select_preset(preset_name); } diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 1473bf6da..e08cf101d 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -63,8 +63,7 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const m_type(preset_type), m_last_selected(wxNOT_FOUND), m_em_unit(em_unit(this)), - m_preset_bundle(wxGetApp().preset_bundle), - m_bitmap_cache(new BitmapCache) + m_preset_bundle(wxGetApp().preset_bundle) { SetFont(wxGetApp().normal_font()); #ifdef _WIN32 @@ -105,17 +104,31 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const m_bitmapCompatible = ScalableBitmap(this, "flag_green"); m_bitmapIncompatible = ScalableBitmap(this, "flag_red"); - m_bitmapLock = ScalableBitmap(this, "lock_closed"); - m_bitmapLockDisabled = ScalableBitmap(this, "lock_closed", 16, true); // parameters for an icon's drawing fill_width_height(); + + Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { + // see https://github.com/prusa3d/PrusaSlicer/issues/3889 + // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender") + // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive. + // So, use GetSelection() from event parameter + auto selected_item = evt.GetSelection(); + + auto marker = reinterpret_cast(this->GetClientData(selected_item)); + if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) + this->SetSelection(this->m_last_selected); + else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) { + m_last_selected = selected_item; + on_selection_changed(selected_item); + evt.StopPropagation(); + } + evt.Skip(); + }); } PresetComboBox::~PresetComboBox() { - delete m_bitmap_cache; - m_bitmap_cache = nullptr; } void PresetComboBox::set_label_marker(int item, LabelItemType label_item_type) @@ -123,12 +136,96 @@ void PresetComboBox::set_label_marker(int item, LabelItemType label_item_type) this->SetClientData(item, (void*)label_item_type); } +void PresetComboBox::update(const std::string& select_preset_name) +{ + Freeze(); + Clear(); + size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected + + const std::deque& presets = m_collection->get_presets(); + + std::map> nonsys_presets; + wxString selected = ""; + if (!presets.front().is_visible) + set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + + for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) + { + const Preset& preset = presets[i]; + if (!preset.is_visible || !preset.is_compatible) + continue; + + // marker used for disable incompatible printer models for the selected physical printer + bool is_enabled = true; + + std::string bitmap_key = "tab"; + std::string main_icon_name = m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; + + if (m_type == Preset::TYPE_PRINTER) { + bitmap_key += "_printer"; + if (preset.printer_technology() == ptSLA) + bitmap_key += "_sla"; + if (!is_enabled) + bitmap_key += "_disabled"; + } + bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; + bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; + + wxBitmap* bmp = get_bmp(bitmap_key, main_icon_name, "lock_closed", is_enabled, preset.is_compatible, preset.is_system || preset.is_default); + assert(bmp); + + if (preset.is_default || preset.is_system) { + int item_id = Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); + if (!is_enabled) + set_label_marker(item_id, LABEL_ITEM_DISABLED); + if (preset.name == select_preset_name ||//i == idx_selected || + // just in case: mark selected_preset_item as a first added element + selected_preset_item == INT_MAX) + selected_preset_item = GetCount() - 1; + } + else + { + std::pair pair(bmp, is_enabled); + nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), std::pair(bmp, is_enabled)); + if (preset.name == select_preset_name) + selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()); + } + if (i + 1 == m_collection->num_default_presets()) + set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + } + if (!nonsys_presets.empty()) + { + set_label_marker(Append(separator(L("User presets")), wxNullBitmap)); + for (std::map>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { + int item_id = Append(it->first, *it->second.first); + bool is_enabled = it->second.second; + if (!is_enabled) + set_label_marker(item_id, LABEL_ITEM_DISABLED); + if (it->first == selected || + // just in case: mark selected_preset_item as a first added element + selected_preset_item == INT_MAX) + selected_preset_item = GetCount() - 1; + } + } + + /* But, if selected_preset_item is still equal to INT_MAX, it means that + * there is no presets added to the list. + * So, select last combobox item ("Add/Remove preset") + */ + if (selected_preset_item == INT_MAX) + selected_preset_item = GetCount() - 1; + + SetSelection(selected_preset_item); + SetToolTip(GetString(selected_preset_item)); + Thaw(); + + m_last_selected = selected_preset_item; +} + void PresetComboBox::msw_rescale() { m_em_unit = em_unit(this); - m_bitmapLock.msw_rescale(); - m_bitmapLockDisabled.msw_rescale(); m_bitmapIncompatible.msw_rescale(); m_bitmapCompatible.msw_rescale(); @@ -142,9 +239,9 @@ void PresetComboBox::msw_rescale() void PresetComboBox::fill_width_height() { // To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so - // set a bitmap's height to m_bitmapLock->GetHeight() and norm_icon_width to m_bitmapLock->GetWidth() - icon_height = m_bitmapLock.GetBmpHeight(); - norm_icon_width = m_bitmapLock.GetBmpWidth(); + // set a bitmap's height to m_bitmapCompatible->GetHeight() and norm_icon_width to m_bitmapCompatible->GetWidth() + icon_height = m_bitmapCompatible.GetBmpHeight(); + norm_icon_width = m_bitmapCompatible.GetBmpWidth(); /* 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 @@ -165,6 +262,110 @@ wxString PresetComboBox::separator(const std::string& label) return wxString::FromUTF8(separator_head()) + _(label) + wxString::FromUTF8(separator_tail()); } +wxBitmap* PresetComboBox::get_bmp( std::string bitmap_key, bool wide_icons, const std::string& main_icon_name, + bool is_compatible/* = true*/, bool is_system/* = false*/, bool is_single_bar/* = false*/, + std::string filament_rgb/* = ""*/, std::string extruder_rgb/* = ""*/) +{ + bitmap_key += ",h" + std::to_string(icon_height); + + wxBitmap* bmp = bitmap_cache().find(bitmap_key); + if (bmp == nullptr) { + // Create the bitmap with color bars. + std::vector bmps; + if (wide_icons) + // Paint a red flag for incompatible presets. + bmps.emplace_back(is_compatible ? bitmap_cache().mkclear(norm_icon_width, icon_height) : m_bitmapIncompatible.bmp()); + + if (m_type == Preset::TYPE_FILAMENT) + { + unsigned char rgb[3]; + // Paint the color bars. + bitmap_cache().parse_color(filament_rgb, rgb); + bmps.emplace_back(bitmap_cache().mksolid(is_single_bar ? wide_icon_width : norm_icon_width, icon_height, rgb)); + if (!is_single_bar) { + bitmap_cache().parse_color(extruder_rgb, rgb); + bmps.emplace_back(bitmap_cache().mksolid(thin_icon_width, icon_height, rgb)); + } + // Paint a lock at the system presets. + bmps.emplace_back(bitmap_cache().mkclear(space_icon_width, icon_height)); + } + else + { + // Paint the color bars. + bmps.emplace_back(bitmap_cache().mkclear(thin_space_icon_width, icon_height)); + bmps.emplace_back(create_scaled_bitmap(main_icon_name)); + // Paint a lock at the system presets. + bmps.emplace_back(bitmap_cache().mkclear(wide_space_icon_width, icon_height)); + } + bmps.emplace_back(is_system ? create_scaled_bitmap("lock_closed") : bitmap_cache().mkclear(norm_icon_width, icon_height)); + bmp = bitmap_cache().insert(bitmap_key, bmps); + } + + return bmp; +} + +wxBitmap* PresetComboBox::get_bmp( std::string bitmap_key, const std::string& main_icon_name, const std::string& next_icon_name, + bool is_enabled/* = true*/, bool is_compatible/* = true*/, bool is_system/* = false*/) +{ + bitmap_key += ",h" + std::to_string(icon_height); + + wxBitmap* bmp = bitmap_cache().find(bitmap_key); + if (bmp == nullptr) { + // Create the bitmap with color bars. + std::vector bmps; + bmps.emplace_back(m_type == Preset::TYPE_PRINTER ? create_scaled_bitmap(main_icon_name, this, 16, !is_enabled) : + is_compatible ? m_bitmapCompatible.bmp() : m_bitmapIncompatible.bmp()); + // Paint a lock at the system presets. + bmps.emplace_back(is_system ? create_scaled_bitmap(next_icon_name, this, 16, !is_enabled) : bitmap_cache().mkclear(norm_icon_width, icon_height)); + bmp = bitmap_cache().insert(bitmap_key, bmps); + } + + return bmp; +} + +bool PresetComboBox::is_selected_physical_printer() +{ + auto selected_item = this->GetSelection(); + auto marker = reinterpret_cast(this->GetClientData(selected_item)); + return marker == LABEL_ITEM_PHYSICAL_PRINTER; +} + +bool PresetComboBox::selection_is_changed_according_to_physical_printers() +{ + if (m_type != Preset::TYPE_PRINTER || !is_selected_physical_printer()) + return false; + + PhysicalPrinterCollection& physical_printers = m_preset_bundle->physical_printers; + + std::string selected_string = this->GetString(this->GetSelection()).ToUTF8().data(); + + std::string old_printer_full_name, old_printer_preset; + if (physical_printers.has_selection()) { + old_printer_full_name = physical_printers.get_selected_full_printer_name(); + old_printer_preset = physical_printers.get_selected_printer_preset_name(); + } + else + old_printer_preset = m_collection->get_edited_preset().name; + // Select related printer preset on the Printer Settings Tab + physical_printers.select_printer_by_name(selected_string); + std::string preset_name = physical_printers.get_selected_printer_preset_name(); + + // if new preset wasn't selected, there is no need to call update preset selection + if (old_printer_preset == preset_name) { + // we need just to update according Plater<->Tab PresetComboBox + if (dynamic_cast(this)!=nullptr) + wxGetApp().get_tab(m_type)->update_preset_choice(); + else if (dynamic_cast(this)!=nullptr) + wxGetApp().sidebar().update_presets(m_type); + return true; + } + + Tab* tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); + if (tab) + tab->select_preset(preset_name, false, old_printer_full_name); + return true; +} + #ifdef __APPLE__ bool PresetComboBox::OnAddBitmap(const wxBitmap& bitmap) { @@ -245,25 +446,6 @@ PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) { this->SetSelection(this->m_last_selected); evt.StopPropagation(); - /* - if (marker == LABEL_ITEM_PHYSICAL_PRINTERS) - { - PhysicalPrinterDialog dlg(wxEmptyString); - if (dlg.ShowModal() == wxID_OK) - this->update(); - return; - } - if (marker >= LABEL_ITEM_WIZARD_PRINTERS) { - ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME; - switch (marker) { - case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break; - case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break; - case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break; - default: break; - } - wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); }); - } - */ if (marker == LABEL_ITEM_WIZARD_PRINTERS) show_add_menu(); else @@ -372,13 +554,6 @@ PlaterPresetComboBox::~PlaterPresetComboBox() edit_btn->Destroy(); } -bool PlaterPresetComboBox::is_selected_physical_printer() -{ - auto selected_item = this->GetSelection(); - auto marker = reinterpret_cast(this->GetClientData(selected_item)); - return marker == LABEL_ITEM_PHYSICAL_PRINTER; -} - bool PlaterPresetComboBox::switch_to_tab() { Tab* tab = wxGetApp().get_tab(m_type); @@ -465,7 +640,7 @@ void PlaterPresetComboBox::update() { unsigned char rgb[3]; extruder_color = m_preset_bundle->printers.get_edited_preset().config.opt_string("extruder_colour", (unsigned int)m_extruder_idx); - if (!m_bitmap_cache->parse_color(extruder_color, rgb)) + if (!bitmap_cache().parse_color(extruder_color, rgb)) // Extruder color is not defined. extruder_color.clear(); selected_filament_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_extruder_idx]); @@ -499,64 +674,33 @@ void PlaterPresetComboBox::update() continue; std::string bitmap_key, filament_rgb, extruder_rgb; + std::string bitmap_type_name = bitmap_key = m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; + bool single_bar = false; - if (m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA) - bitmap_key = "sla_printer"; - else if (m_type == Preset::TYPE_FILAMENT) + if (m_type == Preset::TYPE_FILAMENT) { // Assign an extruder color to the selected item if the extruder color is defined. filament_rgb = preset.config.opt_string("filament_colour", 0); extruder_rgb = (selected && !extruder_color.empty()) ? extruder_color : filament_rgb; single_bar = filament_rgb == extruder_rgb; - bitmap_key = single_bar ? filament_rgb : filament_rgb + extruder_rgb; + bitmap_key += single_bar ? filament_rgb : filament_rgb + extruder_rgb; } - wxBitmap main_bmp = create_scaled_bitmap(m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name); // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left // to the filament color image. if (wide_icons) bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; - bitmap_key += "-h" + std::to_string(icon_height); - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(norm_icon_width, icon_height) : m_bitmapIncompatible.bmp()); - - if (m_type == Preset::TYPE_FILAMENT) - { - unsigned char rgb[3]; - // Paint the color bars. - m_bitmap_cache->parse_color(filament_rgb, rgb); - bmps.emplace_back(m_bitmap_cache->mksolid(single_bar ? wide_icon_width : norm_icon_width, icon_height, rgb)); - if (!single_bar) { - m_bitmap_cache->parse_color(extruder_rgb, rgb); - bmps.emplace_back(m_bitmap_cache->mksolid(thin_icon_width, icon_height, rgb)); - } - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(space_icon_width, icon_height)); - } - else - { - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(main_bmp); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); - } - bmps.emplace_back((preset.is_system || preset.is_default) ? m_bitmapLock.bmp() : m_bitmap_cache->mkclear(norm_icon_width, icon_height)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + wxBitmap* bmp = get_bmp(bitmap_key, wide_icons, bitmap_type_name, + preset.is_compatible, preset.is_system || preset.is_default, + single_bar, filament_rgb, extruder_rgb); + assert(bmp); const std::string name = preset.alias.empty() ? preset.name : preset.alias; if (preset.is_default || preset.is_system) { - Append(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), - !bmp ? main_bmp : *bmp); + Append(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); if (is_selected || // just in case: mark selected_preset_item as a first added element selected_preset_item == INT_MAX) { @@ -595,59 +739,26 @@ void PlaterPresetComboBox::update() const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers; for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { - std::string bitmap_key = it->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; - if (wide_icons) - bitmap_key += "wide,"; - bitmap_key += "-h" + std::to_string(icon_height); - - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; + for (const std::string preset_name : it->get_preset_names()) { + Preset* preset = m_collection->find_preset(preset_name); + if (!preset) + continue; + std::string main_icon_name, bitmap_key = main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(m_bitmap_cache->mkclear(norm_icon_width, icon_height)); - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(create_scaled_bitmap(it->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name)); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width+norm_icon_width, icon_height)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + bitmap_key += ",cmpt"; + bitmap_key += ",nsyst"; - set_label_marker(Append(wxString::FromUTF8((it->full_name).c_str()), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); - if (ph_printers.has_selection() && it->name == ph_printers.get_selected_printer_name() || - // just in case: mark selected_preset_item as a first added element - selected_preset_item == INT_MAX) - selected_preset_item = GetCount() - 1; + wxBitmap* bmp = get_bmp(bitmap_key, wide_icons, main_icon_name); + assert(bmp); + + set_label_marker(Append(wxString::FromUTF8((it->get_full_name(preset_name) + (preset->is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); + if (ph_printers.is_selected(it, preset_name) || + // just in case: mark selected_preset_item as a first added element + selected_preset_item == INT_MAX) + selected_preset_item = GetCount() - 1; + } } } - -/* - // add LABEL_ITEM_PHYSICAL_PRINTERS - std::string bitmap_key; - if (wide_icons) - bitmap_key += "wide,"; - bitmap_key += "edit_preset_list"; - bitmap_key += "-h" + std::to_string(icon_height); - - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(m_bitmap_cache->mkclear(norm_icon_width, icon_height)); - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(create_scaled_bitmap("printer")); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); - bmps.emplace_back(create_scaled_bitmap("edit_uni")); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } - set_label_marker(Append(separator(L("Add physical printer")), *bmp), LABEL_ITEM_PHYSICAL_PRINTERS); -*/ } if (m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_SLA_MATERIAL) { @@ -657,23 +768,10 @@ void PlaterPresetComboBox::update() if (wide_icons) bitmap_key += "wide,"; bitmap_key += "edit_preset_list"; - bitmap_key += "-h" + std::to_string(icon_height); - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars.update_plater_ui - std::vector bmps; - if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(m_bitmap_cache->mkclear(norm_icon_width, icon_height)); - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(create_scaled_bitmap(m_main_bitmap_name)); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); - bmps.emplace_back(create_scaled_bitmap("edit_uni")); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + wxBitmap* bmp = get_bmp(bitmap_key, wide_icons, "edit_uni"); + assert(bmp); + if (m_type == Preset::TYPE_SLA_MATERIAL) set_label_marker(Append(separator(L("Add/Remove materials")), *bmp), LABEL_ITEM_WIZARD_MATERIALS); else @@ -731,8 +829,10 @@ TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) update(); }); } - else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty()) ) + else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty()) ) { + m_last_selected = selected_item; on_selection_changed(selected_item); + } evt.StopPropagation(); }); @@ -754,7 +854,12 @@ void TabPresetComboBox::update() if (!presets.front().is_visible) set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); int idx_selected = m_collection->get_selected_idx(); - for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) { + + std::string sel_preset_name = m_preset_bundle->physical_printers.get_selected_printer_preset_name(); + PrinterTechnology proper_pt = (m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) ? + m_collection->find_preset(sel_preset_name)->printer_technology() : ptAny; + for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) + { const Preset& preset = presets[i]; if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected)) continue; @@ -762,14 +867,12 @@ void TabPresetComboBox::update() // marker used for disable incompatible printer models for the selected physical printer bool is_enabled = true; // check this value just for printer presets, when physical printer is selected - if (m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) { - is_enabled = m_enable_all ? true : - preset.name == m_preset_bundle->physical_printers.get_selected_printer_preset_name()/* || - preset.config.opt_string("printer_model") == m_preset_bundle->physical_printers.get_selected_printer_model()*/; - } + if (m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) + is_enabled = m_enable_all ? true : preset.printer_technology() == proper_pt;//m_preset_bundle->physical_printers.get_selected_printer_technology(); std::string bitmap_key = "tab"; - wxBitmap main_bmp = create_scaled_bitmap(m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name, this, 16, !is_enabled); + std::string main_icon_name = m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; + if (m_type == Preset::TYPE_PRINTER) { bitmap_key += "_printer"; if (preset.printer_technology() == ptSLA) @@ -779,20 +882,12 @@ void TabPresetComboBox::update() } bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; - bitmap_key += "-h" + std::to_string(icon_height); - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - bmps.emplace_back(m_type == Preset::TYPE_PRINTER ? main_bmp : preset.is_compatible ? m_bitmapCompatible.bmp() : m_bitmapIncompatible.bmp()); - // Paint a lock at the system presets. - bmps.emplace_back((preset.is_system || preset.is_default) ? (is_enabled ? m_bitmapLock.bmp() : m_bitmapLockDisabled.bmp()) : m_bitmap_cache->mkclear(norm_icon_width, icon_height)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + wxBitmap* bmp = get_bmp(bitmap_key, main_icon_name, "lock_closed", is_enabled, preset.is_compatible, preset.is_system || preset.is_default); + assert(bmp); if (preset.is_default || preset.is_system) { - int item_id = Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), !bmp ? main_bmp : *bmp); + int item_id = Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp); if (!is_enabled) set_label_marker(item_id, LABEL_ITEM_DISABLED); if (i == idx_selected || @@ -824,18 +919,38 @@ void TabPresetComboBox::update() selected_preset_item = GetCount() - 1; } } - if (m_type == Preset::TYPE_PRINTER) { - std::string bitmap_key = "edit_preset_list"; - bitmap_key += "-h" + std::to_string(icon_height); - wxBitmap* bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - bmps.emplace_back(create_scaled_bitmap(m_main_bitmap_name, this)); - bmps.emplace_back(create_scaled_bitmap("edit_uni", this)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); + if (m_type == Preset::TYPE_PRINTER) + { + // add Physical printers, if any exists + if (!m_preset_bundle->physical_printers.empty()) { + set_label_marker(Append(separator(L("Physical printers")), wxNullBitmap)); + const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers; + + for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) { + for (const std::string preset_name : it->get_preset_names()) { + Preset* preset = m_collection->find_preset(preset_name); + if (!preset) + continue; + std::string main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name; + std::string bitmap_key = main_icon_name + ",nsyst"; + + wxBitmap* bmp = get_bmp(bitmap_key, main_icon_name, "", true, true, false); + assert(bmp); + + set_label_marker(Append(wxString::FromUTF8((it->get_full_name(preset_name) + (preset->is_dirty ? Preset::suffix_modified() : "")).c_str()), *bmp), LABEL_ITEM_PHYSICAL_PRINTER); + if (ph_printers.is_selected(it, preset_name) || + // just in case: mark selected_preset_item as a first added element + selected_preset_item == INT_MAX) + selected_preset_item = GetCount() - 1; + } + } } + + // add "Add/Remove printers" item + wxBitmap* bmp = get_bmp("edit_preset_list", m_main_bitmap_name, "edit_uni", true, true, true); + assert(bmp); + set_label_marker(Append(separator(L("Add/Remove printers")), *bmp), LABEL_ITEM_WIZARD_PRINTERS); } @@ -869,11 +984,26 @@ void TabPresetComboBox::update_dirty() // 2) Update the labels. wxWindowUpdateLocker noUpdates(this); for (unsigned int ui_id = 0; ui_id < GetCount(); ++ui_id) { + auto marker = reinterpret_cast(this->GetClientData(ui_id)); + if (marker >= LABEL_ITEM_MARKER) + continue; + std::string old_label = GetString(ui_id).utf8_str().data(); std::string preset_name = Preset::remove_suffix_modified(old_label); + std::string ph_printer_name; + + if (marker == LABEL_ITEM_PHYSICAL_PRINTER) { + ph_printer_name = PhysicalPrinter::get_short_name(preset_name); + preset_name = PhysicalPrinter::get_preset_name(preset_name); + } + const Preset* preset = m_collection->find_preset(preset_name, false); if (preset) { std::string new_label = preset->is_dirty ? preset->name + Preset::suffix_modified() : preset->name; + + if (marker == LABEL_ITEM_PHYSICAL_PRINTER) + new_label = ph_printer_name + PhysicalPrinter::separator() + new_label; + if (old_label != new_label) SetString(ui_id, wxString::FromUTF8(new_label.c_str())); } @@ -885,6 +1015,12 @@ void TabPresetComboBox::update_dirty() #endif /* __APPLE __ */ } +void TabPresetComboBox::update_physical_printers( const std::string& preset_name) +{ + if (m_type == Preset::TYPE_PRINTER && update_ph_printers) + update_ph_printers(preset_name); +} + //------------------------------------------ // PresetForPrinter @@ -900,9 +1036,7 @@ PresetForPrinter::PresetForPrinter(PhysicalPrinterDialog* parent, const std::str m_delete_preset_btn->SetToolTip(_L("Delete this preset from this printer device")); m_delete_preset_btn->Bind(wxEVT_BUTTON, &PresetForPrinter::DeletePreset, this); - m_presets_list = new TabPresetComboBox(parent, Preset::TYPE_PRINTER); - if (preset_name.empty()) - m_presets_list->set_enable_all(); + m_presets_list = new PresetComboBox(parent, Preset::TYPE_PRINTER); m_presets_list->set_selection_changed_function([this](int selection) { std::string selected_string = Preset::remove_suffix_modified(m_presets_list->GetString(selection).ToUTF8().data()); @@ -922,8 +1056,7 @@ PresetForPrinter::PresetForPrinter(PhysicalPrinterDialog* parent, const std::str update_full_printer_name(); }); - m_presets_list->update(); - m_presets_list->SetStringSelection(from_u8(preset_name)); + m_presets_list->update(preset_name); m_info_line = new wxStaticText(parent, wxID_ANY, _L("This printer will be shown in the presets list as") + ":"); @@ -997,11 +1130,10 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) SetFont(wxGetApp().normal_font()); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - if (printer_name.IsEmpty()) { - printer_name = _L("My Printer Device"); - // if printer_name is empty it means that new printer is created, so enable all items in the preset list - m_presets.emplace_back(new PresetForPrinter(this, "")); - } + m_default_name = _L("My Printer Device"); + + if (printer_name.IsEmpty()) + printer_name = m_default_name; else { std::string full_name = into_u8(printer_name); printer_name = from_u8(PhysicalPrinter::get_short_name(full_name)); @@ -1022,6 +1154,8 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) if (!printer) { const Preset& preset = wxGetApp().preset_bundle->printers.get_edited_preset(); printer = new PhysicalPrinter(into_u8(printer_name), preset); + // if printer_name is empty it means that new printer is created, so enable all items in the preset list + m_presets.emplace_back(new PresetForPrinter(this, preset.name)); } else { @@ -1275,7 +1409,11 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event) { wxString printer_name = m_printer_name->GetValue(); if (printer_name.IsEmpty()) { - show_error(this, _L("The supplied name is empty. It can't be saved.")); + warning_catcher(this, _L("The supplied name is empty. It can't be saved.")); + return; + } + if (printer_name == m_default_name) { + warning_catcher(this, _L("You should to change a name of your printer device. It can't be saved.")); return; } @@ -1311,9 +1449,10 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event) repeatable_presets += "\n"; wxString msg_text = from_u8((boost::format(_u8L("Next printer preset(s) is(are) duplicated:%1%" - "It(they) will be added just once for the printer \"%2%\".")) % repeatable_presets % printer_name).str()); - wxMessageDialog dialog(nullptr, msg_text, _L("Infornation"), wxICON_INFORMATION | wxOK); - dialog.ShowModal(); + "Should I add it(they) just once for the printer \"%2%\" and close the Editing Dialog?")) % repeatable_presets % printer_name).str()); + wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxYES | wxNO); + if (dialog.ShowModal() == wxID_NO) + return; } std::string renamed_from; @@ -1344,8 +1483,7 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event) void PhysicalPrinterDialog::AddPreset(wxEvent& event) { - // if printer_name is empty it means that new printer is created, so enable all items in the preset list - m_presets.emplace_back(new PresetForPrinter(this, "")); + m_presets.emplace_back(new PresetForPrinter(this)); // enable DELETE button for the first preset, if was disabled m_presets.front()->EnableDeleteBtn(); diff --git a/src/slic3r/GUI/PresetComboBoxes.hpp b/src/slic3r/GUI/PresetComboBoxes.hpp index c818b6b91..1f5ef026d 100644 --- a/src/slic3r/GUI/PresetComboBoxes.hpp +++ b/src/slic3r/GUI/PresetComboBoxes.hpp @@ -10,6 +10,7 @@ #include "libslic3r/Preset.hpp" #include "wxExtensions.hpp" #include "GUI_Utils.hpp" +#include "BitmapCache.hpp" class wxString; class wxTextCtrl; @@ -21,8 +22,6 @@ namespace Slic3r { namespace GUI { -class BitmapCache; - // --------------------------------- // *** PresetComboBox *** @@ -49,11 +48,22 @@ public: void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER); - virtual void update() {}; + void set_selection_changed_function(std::function sel_changed) { on_selection_changed = sel_changed; } + + bool is_selected_physical_printer(); + + // Return true, if physical printer was selected + // and next internal selection was accomplished + bool selection_is_changed_according_to_physical_printers(); + + void update(const std::string& select_preset); + + virtual void update(){}; virtual void msw_rescale(); protected: typedef std::size_t Marker; + std::function on_selection_changed { nullptr }; Preset::Type m_type; std::string m_main_bitmap_name; @@ -61,16 +71,16 @@ protected: PresetBundle* m_preset_bundle {nullptr}; PresetCollection* m_collection {nullptr}; - // Caching color bitmaps for the filament combo box. - BitmapCache* m_bitmap_cache {nullptr}; + // Caching bitmaps for the all bitmaps, used in preset comboboxes + static BitmapCache& bitmap_cache() { + static BitmapCache bmps; + return bmps; + } + // Indicator, that the preset is compatible with the selected printer. ScalableBitmap m_bitmapCompatible; // Indicator, that the preset is NOT compatible with the selected printer. ScalableBitmap m_bitmapIncompatible; - // Indicator, that the preset is system and not modified. - ScalableBitmap m_bitmapLock; - // Disabled analogue of the m_bitmapLock . - ScalableBitmap m_bitmapLockDisabled; int m_last_selected; int m_em_unit; @@ -93,6 +103,13 @@ protected: #endif // __linux__ static wxString separator(const std::string& label); + wxBitmap* get_bmp( std::string bitmap_key, bool wide_icons, const std::string& main_icon_name, + bool is_compatible = true, bool is_system = false, bool is_single_bar = false, + std::string filament_rgb = "", std::string extruder_rgb = ""); + + wxBitmap* get_bmp( std::string bitmap_key, const std::string& main_icon_name, const std::string& next_icon_name, + bool is_enabled = true, bool is_compatible = true, bool is_system = false); + #ifdef __APPLE__ /* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina * (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean @@ -128,7 +145,6 @@ public: void set_extruder_idx(const int extr_idx) { m_extruder_idx = extr_idx; } int get_extruder_idx() const { return m_extruder_idx; } - bool is_selected_physical_printer(); bool switch_to_tab(); void show_add_menu(); void show_edit_menu(); @@ -149,7 +165,8 @@ class TabPresetComboBox : public PresetComboBox { bool show_incompatible {false}; bool m_enable_all {false}; - std::function on_selection_changed { nullptr }; + + std::function update_ph_printers { nullptr }; public: TabPresetComboBox(wxWindow *parent, Preset::Type preset_type); @@ -157,12 +174,15 @@ public: void set_show_incompatible_presets(bool show_incompatible_presets) { show_incompatible = show_incompatible_presets; } + void set_update_physical_printers_function(std::function update_fn) { + update_ph_printers = update_fn; + } void update() override; void update_dirty(); + void update_physical_printers(const std::string& preset_name); void msw_rescale() override; - void set_selection_changed_function(std::function sel_changed) { on_selection_changed = sel_changed; } void set_enable_all(bool enable=true) { m_enable_all = enable; } }; @@ -176,7 +196,7 @@ class PresetForPrinter { PhysicalPrinterDialog* m_parent { nullptr }; - TabPresetComboBox* m_presets_list { nullptr }; + PresetComboBox* m_presets_list { nullptr }; ScalableButton* m_delete_preset_btn { nullptr }; wxStaticText* m_info_line { nullptr }; wxStaticText* m_full_printer_name { nullptr }; @@ -186,7 +206,7 @@ class PresetForPrinter void DeletePreset(wxEvent& event); public: - PresetForPrinter(PhysicalPrinterDialog* parent, const std::string& preset_name); + PresetForPrinter(PhysicalPrinterDialog* parent, const std::string& preset_name = ""); ~PresetForPrinter(); wxBoxSizer* sizer() { return m_sizer; } @@ -208,6 +228,7 @@ class ConfigOptionsGroup; class PhysicalPrinterDialog : public DPIDialog { PhysicalPrinter m_printer; + wxString m_default_name; DynamicPrintConfig* m_config { nullptr }; wxTextCtrl* m_printer_name { nullptr }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 595283e98..dbea9b3f5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -162,10 +162,20 @@ void Tab::create_preset_tab() // preset chooser m_presets_choice = new TabPresetComboBox(panel, m_type); m_presets_choice->set_selection_changed_function([this](int selection) { - std::string selected_string = m_presets_choice->GetString(selection).ToUTF8().data(); - update_physical_printers(selected_string); - // select preset - select_preset(selected_string); + if (!m_presets_choice->selection_is_changed_according_to_physical_printers()) + { + // for the printer presets set callback for the updating of the physical printers + if (m_type == Preset::TYPE_PRINTER) + m_presets_choice->set_update_physical_printers_function([this](std::string preset_name) { update_physical_printers(preset_name);}); + + // select preset + select_preset(m_presets_choice->GetString(selection).ToUTF8().data()); + + // Disable callback for the updating of the physical printers to avoid a case, + // when select_preset is called from the others than this place + if (m_type == Preset::TYPE_PRINTER) + m_presets_choice->set_update_physical_printers_function(nullptr); + } }); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); @@ -764,9 +774,11 @@ void Tab::update_tab_ui() void Tab::update_physical_printers(std::string preset_name) { - if (m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) + PhysicalPrinterCollection& physical_printers = wxGetApp().preset_bundle->physical_printers; + if (physical_printers.has_selection() && + Preset::remove_suffix_modified(preset_name) != physical_printers.get_selected_printer_preset_name()) { - std::string printer_name = m_preset_bundle->physical_printers.get_selected_full_printer_name(); + std::string printer_name = physical_printers.get_selected_full_printer_name(); wxString msg_text = from_u8((boost::format(_u8L("You have selected physical printer \"%1%\".")) % printer_name).str()); msg_text += "\n\n" + _L("Would you like to change related preset for this printer?") + "\n\n" + _L("Select YES if you want to change related preset for this printer \n" @@ -780,12 +792,14 @@ void Tab::update_physical_printers(std::string preset_name) Preset& edited_preset = m_presets->get_edited_preset(); if (preset->name == edited_preset.name) preset = &edited_preset; - m_preset_bundle->physical_printers.get_selected_printer().update_from_preset(*preset); + physical_printers.get_selected_printer().update_from_preset(*preset); + physical_printers.select_printer_by_name(physical_printers.get_selected_printer().get_full_name(preset_name)); + return; } - else - // unselect physical printer, if it was selected - m_preset_bundle->physical_printers.unselect_printer(); } + + // unselect physical printer, if it was selected + m_preset_bundle->physical_printers.unselect_printer(); } // Load a provied DynamicConfig into the tab, modifying the active preset. @@ -2148,11 +2162,10 @@ void TabPrinter::build_fff() line.append_widget(serial_test); optgroup->append_line(line); } -#endif optgroup = page->new_optgroup(L("Print Host upload")); build_printhost(optgroup.get()); - +#endif optgroup = page->new_optgroup(L("Firmware")); optgroup->append_single_option_line("gcode_flavor"); optgroup->append_single_option_line("silent_mode"); @@ -2310,8 +2323,10 @@ void TabPrinter::build_sla() optgroup->append_single_option_line("min_initial_exposure_time"); optgroup->append_single_option_line("max_initial_exposure_time"); + /* optgroup = page->new_optgroup(L("Print Host upload")); build_printhost(optgroup.get()); + */ const int notes_field_height = 25; // 250 @@ -2699,11 +2714,13 @@ void TabPrinter::update_fff() m_serial_test_btn->Disable(); } + /* { std::unique_ptr host(PrintHost::get_print_host(m_config)); m_print_host_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test()); m_printhost_browse_btn->Enable(host->has_auto_discovery()); } + */ bool have_multiple_extruders = m_extruders_count > 1; get_field("toolchange_gcode")->toggle(have_multiple_extruders); @@ -2942,10 +2959,15 @@ void Tab::update_page_tree_visibility() } +void Tab::update_preset_choice() +{ + m_presets_choice->update(); +} + // Called by the UI combo box when the user switches profiles, and also to delete the current profile. // Select a preset by a name.If !defined(name), then the default preset is selected. // If the current profile is modified, user is asked to save the changes. -void Tab::select_preset(std::string preset_name, bool delete_current) +void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, const std::string& last_selected_ph_printer_name/* =""*/) { if (preset_name.empty()) { if (delete_current) { @@ -3054,9 +3076,22 @@ void Tab::select_preset(std::string preset_name, bool delete_current) if (canceled) { update_tab_ui(); + /* // unselect physical printer selection to the correct synchronization of the printer presets between Tab and Plater if (m_type == Preset::TYPE_PRINTER) m_preset_bundle->physical_printers.unselect_printer(); + */ + + + // Check if preset really was changed. + // If preset selection was canceled and previously was selected physical printer, we should select it back + if (m_type == Preset::TYPE_PRINTER && !last_selected_ph_printer_name.empty()) { + if (m_presets->get_edited_preset().name == PhysicalPrinter::get_preset_name(last_selected_ph_printer_name)) { + m_preset_bundle->physical_printers.select_printer_by_name(last_selected_ph_printer_name); + m_presets_choice->update(); + } + } + // Trigger the on_presets_changed event so that we also restore the previous value in the plater selector, // if this action was initiated from the plater. on_presets_changed(); @@ -3098,6 +3133,10 @@ void Tab::select_preset(std::string preset_name, bool delete_current) else if (printer_technology == ptSLA && m_dependent_tabs.front() != Preset::Type::TYPE_SLA_PRINT) m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; } + + //update physical printer's related printer preset if it's needed + m_presets_choice->update_physical_printers(preset_name); + load_current_preset(); } } @@ -3295,7 +3334,7 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) // If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible. m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never); //update physical printer's related printer preset if it's needed - update_physical_printers(name); + m_presets_choice->update_physical_printers(name); // Add the new item into the UI component, remove dirty flags and activate the saved item. update_tab_ui(); // Update the selection boxes at the plater. diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 69720ff65..82df31b59 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -275,8 +275,9 @@ public: void load_current_preset(); void rebuild_page_tree(); void update_page_tree_visibility(); - // Select a new preset, possibly delete the current one. - void select_preset(std::string preset_name = "", bool delete_current = false); + void update_preset_choice(); + // Select a new preset, possibly delete the current one. + void select_preset(std::string preset_name = "", bool delete_current = false, const std::string& last_selected_ph_printer_name = ""); bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = ""); bool may_switch_to_SLA_preset();