diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 91b4ad790..a9b28cdee 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -147,11 +147,11 @@ void MainFrame::init_tabpanel() wxGetApp().obj_list()->create_popup_menus(); // The following event is emited by Tab implementation on config value change. - Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this); + Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this); // #ys_FIXME_to_delete // The following event is emited by Tab on preset selection, // or when the preset's "modified" status changes. - Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); + Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); // #ys_FIXME_to_delete create_preset_tabs(); @@ -833,6 +833,7 @@ void MainFrame::select_view(const std::string& direction) m_plater->select_view(direction); } +// #ys_FIXME_to_delete void MainFrame::on_presets_changed(SimpleEvent &event) { auto *tab = dynamic_cast(event.GetEventObject()); @@ -857,6 +858,7 @@ void MainFrame::on_presets_changed(SimpleEvent &event) } } +// #ys_FIXME_to_delete void MainFrame::on_value_changed(wxCommandEvent& event) { auto *tab = dynamic_cast(event.GetEventObject()); @@ -880,6 +882,20 @@ void MainFrame::on_value_changed(wxCommandEvent& event) } } +void MainFrame::on_config_changed(DynamicPrintConfig* config) const +{ + if (m_plater) { + m_plater->on_config_change(*config); // propagate config change events to the plater + } + + // Don't save while loading for the first time. + if (m_loaded) { + AppConfig &cfg = *wxGetApp().app_config; + if (cfg.get("autosave") == "1") + cfg.save(); + } +} + // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. void MainFrame::update_ui_from_settings() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 31ae5d1c7..b44c73f91 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -96,6 +96,8 @@ public: void load_config(const DynamicPrintConfig& config); void select_tab(size_t tab) const; void select_view(const std::string& direction); + // Propagate changed configuration from the Tab to the Platter and save changes to the AppConfig + void on_config_changed(DynamicPrintConfig* cfg) const ; PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7fcc81b44..28b3008fd 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -521,7 +521,7 @@ struct Sidebar::priv void Sidebar::priv::show_preset_comboboxes() { - const bool showSLA = plater->printer_technology() == ptSLA; + const bool showSLA = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; wxWindowUpdateLocker noUpdates_scrolled(scrolled->GetParent()); @@ -682,11 +682,12 @@ void Sidebar::remove_unused_filament_combos(const int current_extruder_count) void Sidebar::update_presets(Preset::Type preset_type) { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); switch (preset_type) { case Preset::TYPE_FILAMENT: { - const int extruder_cnt = p->plater->printer_technology() != ptFFF ? 1 : + const int extruder_cnt = print_tech != ptFFF ? 1 : dynamic_cast(preset_bundle.printers.get_edited_preset().config.option("nozzle_diameter"))->values.size(); const int filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size(); @@ -718,7 +719,7 @@ void Sidebar::update_presets(Preset::Type preset_type) case Preset::TYPE_PRINTER: { // Update the print choosers to only contain the compatible presets, update the dirty flags. - if (p->plater->printer_technology() == ptFFF) + 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); @@ -731,7 +732,7 @@ void Sidebar::update_presets(Preset::Type preset_type) p->combo_printer->check_selection(); // Update the filament choosers to only contain the compatible presets, update the color preview, // update the dirty flags. - if (p->plater->printer_technology() == ptFFF) { + 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]); } @@ -1991,6 +1992,7 @@ void Plater::priv::split_volume() void Plater::priv::schedule_background_process() { + delayed_error_message.clear(); // Trigger the timer event after 0.5s this->background_process_timer.Start(500, wxTIMER_ONE_SHOT); // Notify the Canvas3D that something has changed, so it may invalidate some of the layer editing stuff. diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 5f33fd00a..0ee7a5c6c 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1435,7 +1435,8 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui) { - if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA) + if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA || + this->filament_presets.size() <= idx_extruder ) return; unsigned char rgb[3]; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 52d7f8526..7e9a0c3a2 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -669,7 +669,6 @@ void Tab::load_config(const DynamicPrintConfig& config) bool modified = 0; for(auto opt_key : m_config->diff(config)) { m_config->set_key_value(opt_key, config.option(opt_key)->clone()); - m_dirty_options.emplace(opt_key); modified = 1; } if (modified) { @@ -752,8 +751,6 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { - m_dirty_options.erase(opt_key); - ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(supports_printer_technology(ptFFF)); if (opt_key == "fill_density" || opt_key == "supports_enable" || opt_key == "pad_enable") { @@ -778,22 +775,29 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "wipe_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) update_wiping_button_visibility(); + if (opt_key == "extruders_count") + wxGetApp().plater()->on_extruders_change(boost::any_cast(value)); + update(); + // #ys_FIXME_to_delete // Post event to the Plater after updating of the all dirty options // It helps to avoid needless schedule_background_processing - if (update_completed()) { - wxCommandEvent event(EVT_TAB_VALUE_CHANGED); - event.SetEventObject(this); - event.SetString(opt_key); - if (opt_key == "extruders_count") - { - const int val = boost::any_cast(value); - event.SetInt(val); - } - - wxPostEvent(this, event); - } +// if (update_completed()) +// if (m_update_stack.empty()) +// { +// // wxCommandEvent event(EVT_TAB_VALUE_CHANGED); +// // event.SetEventObject(this); +// // event.SetString(opt_key); +// // if (opt_key == "extruders_count") +// // { +// // const int val = boost::any_cast(value); +// // event.SetInt(val); +// // } +// // +// // wxPostEvent(this, event); +// wxGetApp().mainframe->on_value_changed(m_config); +// } } // Show/hide the 'purging volumes' button @@ -826,10 +830,18 @@ void Tab::on_presets_changed() // refresh the print or filament/sla_material tab page. wxGetApp().get_tab(t)->load_current_preset(); } + // clear m_dependent_tabs after first update from select_preset() + // to avoid needless preset loading from update() function + m_dependent_tabs.clear(); + + // #ys_FIXME_to_delete +// wxCommandEvent event(EVT_TAB_PRESETS_CHANGED); +// event.SetEventObject(this); +// wxPostEvent(this, event); + + // Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets + wxGetApp().plater()->sidebar().update_presets(m_type); - wxCommandEvent event(EVT_TAB_PRESETS_CHANGED); - event.SetEventObject(this); - wxPostEvent(this, event); update_preset_description_line(); } @@ -1166,6 +1178,7 @@ void TabPrint::update() if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA) return; // ys_FIXME + // #ys_FIXME_to_delete //! Temporary workaround for the correct updates of the SpinCtrl (like "perimeters"): // KillFocus() for the wxSpinCtrl use CallAfter function. So, // to except the duplicate call of the update() after dialog->ShowModal(), @@ -1173,6 +1186,7 @@ void TabPrint::update() // if (is_msg_dlg_already_exist) // ! It looks like a fixed problem after start to using of a m_dirty_options // return; // ! TODO Let delete this part of code after a common aplication testing + m_update_cnt++; Freeze(); double fill_density = m_config->option("fill_density")->value; @@ -1385,6 +1399,10 @@ void TabPrint::update() from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); Thaw(); + m_update_cnt--; + + if (m_update_cnt==0) + wxGetApp().mainframe->on_config_changed(m_config); } void TabPrint::OnActivate() @@ -1554,6 +1572,7 @@ void TabFilament::update() if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA) return; // ys_FIXME + m_update_cnt++; Freeze(); wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); m_cooling_description_line->SetText(text); @@ -1568,7 +1587,11 @@ void TabFilament::update() for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) get_field(el)->toggle(fan_always_on); - Thaw(); + Thaw(); + m_update_cnt--; + + if (m_update_cnt == 0) + wxGetApp().mainframe->on_config_changed(m_config); } void TabFilament::OnActivate() @@ -2242,7 +2265,12 @@ void TabPrinter::update_pages() void TabPrinter::update() { + m_update_cnt++; m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla(); + m_update_cnt--; + + if (m_update_cnt == 0) + wxGetApp().mainframe->on_config_changed(m_config); } void TabPrinter::update_fff() @@ -3207,6 +3235,14 @@ void TabSLAMaterial::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) return; // #ys_FIXME + +// #ys_FIXME +// m_update_cnt++; +// ! something to update +// m_update_cnt--; +// +// if (m_update_cnt == 0) + wxGetApp().mainframe->on_config_changed(m_config); } void TabSLAPrint::build() @@ -3291,6 +3327,14 @@ void TabSLAPrint::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) return; // #ys_FIXME + +// #ys_FIXME +// m_update_cnt++; +// ! something to update +// m_update_cnt--; +// +// if (m_update_cnt == 0) + wxGetApp().mainframe->on_config_changed(m_config); } } // GUI diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 430caaf0e..7ef066963 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -204,7 +204,6 @@ protected: void set_type(); int m_em_unit; - std::set m_dirty_options; public: PresetBundle* m_preset_bundle; @@ -213,6 +212,11 @@ public: DynamicPrintConfig* m_config; ogStaticText* m_parent_preset_description_line; wxStaticText* m_colored_Label = nullptr; + // Counter for the updating (because of an update() function can have a recursive behavior): + // 1. increase value from the very beginning of an update() function + // 2. decrease value at the end of an update() function + // 3. propagate changed configuration to the Platter when (m_update_cnt == 0) only + int m_update_cnt = 0; public: Tab(wxNotebook* parent, const wxString& title, const char* name); @@ -284,7 +288,6 @@ protected: void update_frequently_changed_parameters(); void fill_icon_descriptions(); void set_tooltips_text(); - bool update_completed() const { return m_dirty_options.empty(); } }; class TabPrint : public Tab