diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 07c29e1e5..f56a0be60 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -40,14 +40,14 @@ void ConfigManipulation::toggle_field(const std::string &opt_key, const bool tog cb_toggle_field(opt_key, toggle, opt_index); } -void ConfigManipulation::toggle_line(const std::string& opt_key, const bool toggle) +void ConfigManipulation::toggle_line(const std::string& opt_key, const bool toggle, int opt_index) { if (local_config) { if (local_config->option(opt_key) == nullptr) return; } if (cb_toggle_line) - cb_toggle_line(opt_key, toggle); + cb_toggle_line(opt_key, toggle, opt_index); } void ConfigManipulation::check_nozzle_recommended_temperature_range(DynamicPrintConfig *config) { @@ -678,7 +678,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in // todo multi_extruders: bool has_overhang_speed = config->opt_bool("enable_overhang_speed", variant_index); for (auto el : { "overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed"}) - toggle_line(el, has_overhang_speed); + toggle_line(el, has_overhang_speed, variant_index); toggle_line("flush_into_objects", !is_global_config); diff --git a/src/slic3r/GUI/ConfigManipulation.hpp b/src/slic3r/GUI/ConfigManipulation.hpp index a302948c5..07faa747e 100644 --- a/src/slic3r/GUI/ConfigManipulation.hpp +++ b/src/slic3r/GUI/ConfigManipulation.hpp @@ -3,7 +3,7 @@ /* Class for validation config options * and update (enable/disable) IU components - * + * * Used for config validation for global config (Print Settings Tab) * and local config (overrides options on sidebar) * */ @@ -25,11 +25,11 @@ class ConfigManipulation bool m_support_material_overhangs_queried{ false }; bool is_BBL_Printer{false}; - // function to loading of changed configuration + // function to loading of changed configuration std::function load_config = nullptr; std::function cb_toggle_field = nullptr; - std::function cb_toggle_line = nullptr; - // callback to propagation of changed value, if needed + std::function cb_toggle_line = nullptr; + // callback to propagation of changed value, if needed std::function cb_value_change = nullptr; //BBS: change local config to const DynamicPrintConfig const DynamicPrintConfig* local_config = nullptr; @@ -41,7 +41,7 @@ class ConfigManipulation public: ConfigManipulation(std::function load_config, std::function cb_toggle_field, - std::function cb_toggle_line, + std::function cb_toggle_line, std::function cb_value_change, //BBS: change local config to DynamicPrintConfig const DynamicPrintConfig* local_config = nullptr, @@ -66,7 +66,7 @@ public: void apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config); t_config_option_keys const &applying_keys() const; void toggle_field(const std::string& field_key, const bool toggle, int opt_index = -1); - void toggle_line(const std::string& field_key, const bool toggle); + void toggle_line(const std::string& field_key, const bool toggle, int opt_index = -1); // FFF print void update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config = false, const bool is_plate_config = false); diff --git a/src/slic3r/GUI/GUI_ObjectTableSettings.cpp b/src/slic3r/GUI/GUI_ObjectTableSettings.cpp index 4ec42b54d..f94aaa150 100644 --- a/src/slic3r/GUI/GUI_ObjectTableSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectTableSettings.cpp @@ -290,7 +290,7 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_ if (field) field->toggle(toggle); }; - auto toggle_line = [this, optgroup](const t_config_option_key & opt_key, bool toggle) + auto toggle_line = [this, optgroup](const t_config_option_key &opt_key, bool toggle, int opt_index) { Line* line = optgroup->get_line(opt_key); if (line) line->toggle_visible = toggle; @@ -393,7 +393,7 @@ void ObjectTableSettings::update_config_values(bool is_object, ModelObject* obje if (field) field->toggle(toggle); }; - auto toggle_line = [this](const t_config_option_key &opt_key, bool toggle) { + auto toggle_line = [this](const t_config_option_key &opt_key, bool toggle, int opt_index) { for (auto og : m_og_settings) { Line *line = og->get_line(opt_key); if (line) { line->toggle_visible = toggle; break; } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index ae7855daa..4a87a5094 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1278,17 +1278,11 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index) { - Field* field = get_field(opt_key); + Field *field = get_field(opt_key); if (field != nullptr) return field; - std::string opt_id = ""; - for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { - if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second) { - opt_id = it->first; - break; - } - } - return opt_id.empty() ? nullptr : get_field(opt_id); + std::string opt_id = opt_key + '#' + std::to_string(opt_index); + return get_field(opt_id); } std::pair ConfigOptionsGroup::get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1baf60adf..cd184f558 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -500,14 +500,29 @@ void Tab::create_preset_tab() evt.Skip(); switch_excluder(evt.GetInt()); }); - m_main_sizer->Add(m_extruder_switch, 0, wxALIGN_CENTER | wxTOP, m_em_unit); + m_extruder_sync = new ScalableButton(panel, wxID_ANY, "ams_fila_sync"); + m_extruder_sync->SetToolTip(_L("Synchronize the modification of parameters to the corresponding parameters of another extruder.")); + m_extruder_sync->Bind(wxEVT_BUTTON, [this](auto &evt) { + evt.Skip(); + sync_excluder(); + }); + m_variant_sizer = new wxBoxSizer(wxHORIZONTAL); + auto right_sizer = new wxBoxSizer(wxHORIZONTAL); + m_variant_sizer->AddStretchSpacer(1); + m_variant_sizer->Add(m_extruder_switch, 0, wxALIGN_CENTER, 0); + m_variant_sizer->Add(right_sizer, 1, wxALIGN_CENTER); + right_sizer->AddStretchSpacer(1); + right_sizer->Add(m_extruder_sync, 0, wxALIGN_CENTER | wxRIGHT, m_em_unit); + m_main_sizer->Add(m_variant_sizer, 0, wxEXPAND | wxTOP, m_em_unit); } else if (dynamic_cast(this)) { m_variant_combo = new ComboBox(panel, wxID_ANY, "", wxDefaultPosition, {20 * m_em_unit, -1}, 0, {}, wxCB_READONLY); m_variant_combo->Bind(wxEVT_COMBOBOX, [this](auto &evt) { evt.Skip(); switch_excluder(evt.GetInt()); }); - m_main_sizer->Add(m_variant_combo, 0, wxLEFT | wxTOP, m_em_unit); + m_variant_sizer = new wxBoxSizer(wxHORIZONTAL); + m_variant_sizer->Add(m_variant_combo, 0, wxLEFT, m_em_unit); + m_main_sizer->Add(m_variant_sizer, 0, wxEXPAND | wxTOP, m_em_unit); } this->SetSizer(m_main_sizer); @@ -1331,10 +1346,10 @@ void Tab::toggle_option(const std::string& opt_key, bool toggle, int opt_index/* field->toggle(toggle); } -void Tab::toggle_line(const std::string &opt_key, bool toggle) +void Tab::toggle_line(const std::string &opt_key, bool toggle, int opt_index) { if (!m_active_page) return; - Line *line = m_active_page->get_line(opt_key); + Line *line = m_active_page->get_line(opt_key, opt_index); if (line) line->toggle_visible = toggle; }; @@ -5137,8 +5152,9 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event) // update_undo_buttons(); this->OnActivate(); m_parent->set_active_tab(this); - if (wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow*)m_extruder_switch : m_variant_combo) { - m_main_sizer->Show(variant_ctrl, variant_ctrl->IsEnabled() && !m_active_page->m_opt_id_map.empty()); + if (m_variant_sizer) { + wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; + m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty()); GetParent()->Layout(); } @@ -5151,8 +5167,9 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event) return false; m_active_page = page; - if (wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo) { - m_main_sizer->Show(variant_ctrl, variant_ctrl->IsEnabled() && !m_active_page->m_opt_id_map.empty()); + if (m_variant_sizer) { + wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; + m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty()); GetParent()->Layout(); } @@ -5806,7 +5823,8 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) } m_extruder_switch->SetLabels(wxString::Format(_L("Left: %s"), left), wxString::Format(_L("Right: %s"), right)); m_extruder_switch->SetValue(extruder_id == 1); - m_extruder_switch->Enable(); + m_extruder_switch->Enable(true); + assert(m_extruder_switch->IsEnabled()); } else { m_extruder_switch->Enable(false); } @@ -5821,8 +5839,9 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) m_variant_combo->SetSelection(n < 0 || n >= m_variant_combo->GetCount() ? 0 : n); } switch_excluder(extruder_id, reload); - if (wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo) { - m_main_sizer->Show(variant_ctrl, variant_ctrl->IsEnabled() && m_active_page && !m_active_page->m_opt_id_map.empty()); + if (m_variant_sizer) { + wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo; + m_main_sizer->Show(m_variant_sizer, variant_ctrl->IsThisEnabled() && m_active_page && !m_active_page->m_opt_id_map.empty()); GetParent()->Layout(); } } @@ -5894,6 +5913,59 @@ void Tab::switch_excluder(int extruder_id, bool reload) } } +void Tab::sync_excluder() +{ + Preset & printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset(); + auto nozzle_volumes = printer_preset.config.option("nozzle_volume_type"); + auto extruders = printer_preset.config.option("extruder_type"); + std::pair variant_keys[]{ + {}, {"print_extruder_id", "print_extruder_variant"}, // Preset::TYPE_PRINT + {}, {"", "filament_extruder_variant"}, // Preset::TYPE_FILAMENT filament don't use id anymore + {}, {"printer_extruder_id", "printer_extruder_variant"}, // Preset::TYPE_PRINTER + }; + auto get_index_for_extruder = + [this, &extruders, &nozzle_volumes, variant_keys = variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type]](int extruder_id) { + return m_config->get_index_for_extruder(extruder_id + 1, variant_keys.first, + ExtruderType(extruders->values[extruder_id]), NozzleVolumeType(nozzle_volumes->values[extruder_id]), variant_keys.second); + }; + int left_index = get_index_for_extruder(0); + int right_index = get_index_for_extruder(1); + int active_index = int(intptr_t(m_extruder_switch->GetClientData())); + auto left_str = std::to_string(left_index); + auto right_str = std::to_string(right_index); + auto dirty_options = m_presets->current_dirty_options(true); + for (int i = 0; i < dirty_options.size(); ++i) { + auto &opt = dirty_options[i]; + auto n= opt.find('#'); + if (n == std::string::npos) + continue; + auto field = m_active_page->get_field(opt.substr(0, n), active_index + 256); + if (field == nullptr) + continue; + ++n; + bool left = opt.substr(n) == left_str; + bool right = opt.substr(n) == right_str; + while (i + 1 < dirty_options.size() && dirty_options[i + 1].compare(0, n, opt, 0, n) == 0) { + left |= dirty_options[i + 1].substr(n) == left_str; + right |= dirty_options[i + 1].substr(n) == right_str; + ++i; + } + if (left == right) + continue; + auto option = dynamic_cast(m_config->option(opt.substr(0, n - 1))); + if (left) + option->set_at(option, right_index, left_index); + else + option->set_at(option, left_index, right_index); + } + reload_config(); + update_changed_ui(); + toggle_options(); + if (m_active_page) + m_active_page->update_visibility(m_mode, true); + m_page_view->GetParent()->Layout(); +} + void Tab::compatible_widget_reload(PresetDependencies &deps) { Field* field = this->get_field(deps.key_condition); @@ -6056,9 +6128,11 @@ Field *Page::get_field(const t_config_option_key &opt_key, int opt_index /*= -1* { Field *field = nullptr; auto opt_key2 = opt_key; - auto iter = m_opt_id_map.lower_bound(opt_key); - if (iter != m_opt_id_map.end() && iter->first.compare(0, opt_key.length(), opt_key) == 0) - opt_key2 = iter->second; + if (opt_index >= 256) { + auto iter = m_opt_id_map.find(opt_key + '#' + std::to_string(opt_index - 256)); + if (iter != m_opt_id_map.end()) + opt_key2 = iter->second; + } for (auto opt : m_optgroups) { field = opt->get_fieldc(opt_key2, opt_index); if (field != nullptr) return field; @@ -6066,13 +6140,15 @@ Field *Page::get_field(const t_config_option_key &opt_key, int opt_index /*= -1* return field; } -Line *Page::get_line(const t_config_option_key &opt_key) +Line *Page::get_line(const t_config_option_key &opt_key, int opt_index) { Line *line = nullptr; auto opt_key2 = opt_key; - auto iter = m_opt_id_map.lower_bound(opt_key); - if (iter != m_opt_id_map.end() && iter->first.compare(0, opt_key.length(), opt_key) == 0) - opt_key2 = iter->second; + if (opt_index >= 256) { + auto iter = m_opt_id_map.find(opt_key + '#' + std::to_string(opt_index - 256)); + if (iter != m_opt_id_map.end()) + opt_key2 = iter->second; + } for (auto opt : m_optgroups) { line = opt->get_line(opt_key2); if (line != nullptr) return line; @@ -6461,11 +6537,11 @@ ConfigManipulation Tab::get_config_manipulation() }; auto cb_toggle_field = [this](const t_config_option_key& opt_key, bool toggle, int opt_index) { - return toggle_option(opt_key, toggle, opt_index); + return toggle_option(opt_key, toggle, opt_index >= 0 ? opt_index + 256 : opt_index); }; - auto cb_toggle_line = [this](const t_config_option_key& opt_key, bool toggle) { - return toggle_line(opt_key, toggle); + auto cb_toggle_line = [this](const t_config_option_key &opt_key, bool toggle, int opt_index) { + return toggle_line(opt_key, toggle, opt_index >= 0 ? opt_index + 256 : opt_index); }; auto cb_value_change = [this](const std::string& opt_key, const boost::any& value) { diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 866b5e5e0..c95263051 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -96,7 +96,7 @@ public: void sys_color_changed(); void refresh(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; - Line * get_line(const t_config_option_key &opt_key); + Line * get_line(const t_config_option_key &opt_key, int opt_index = -1); bool set_value(const t_config_option_key& opt_key, const boost::any& value); // BBS. Add is_extruder_og parameter. ConfigOptionsGroupShp new_optgroup(const wxString& title, const wxString& icon = wxEmptyString, int noncommon_label_width = -1, bool is_extruder_og = false); @@ -300,8 +300,10 @@ public: int m_update_cnt = 0; SwitchButton *m_mode_view = nullptr; - SwitchButton *m_extruder_switch = nullptr; - ComboBox *m_variant_combo = nullptr; + wxSizer * m_variant_sizer = nullptr; + SwitchButton * m_extruder_switch = nullptr; + ScalableButton *m_extruder_sync = nullptr; + ComboBox * m_variant_combo = nullptr; public: // BBS @@ -383,7 +385,7 @@ public: Field* get_field(const t_config_option_key &opt_key, Page** selected_page, int opt_index = -1); void toggle_option(const std::string &opt_key, bool toggle, int opt_index = -1); - void toggle_line(const std::string &opt_key, bool toggle); // BBS: hide some line + void toggle_line(const std::string &opt_key, bool toggle, int opt_index = -1); // BBS: hide some line wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText, wxString text = wxEmptyString); bool current_preset_is_dirty() const; bool saved_preset_is_dirty() const; @@ -417,6 +419,7 @@ public: void update_extruder_variants(int extruder_id = -1, bool reload = true); void switch_excluder(int extruder_id = -1, bool reload = true); + void sync_excluder(); protected: void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget);