From 3ca2dfbc1dc83d3b976573dba6aa065c6fed236c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 18 Apr 2018 13:32:21 +0200 Subject: [PATCH] Added some performance changes --- xs/src/libslic3r/Config.cpp | 38 +++ xs/src/libslic3r/Config.hpp | 3 + xs/src/slic3r/GUI/GUI.cpp | 6 + xs/src/slic3r/GUI/GUI.hpp | 1 + xs/src/slic3r/GUI/Preset.cpp | 8 +- xs/src/slic3r/GUI/Preset.hpp | 10 +- xs/src/slic3r/GUI/Tab.cpp | 529 ++++++++++++++++++++++++----------- xs/src/slic3r/GUI/Tab.hpp | 41 ++- 8 files changed, 455 insertions(+), 181 deletions(-) diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index a4eaf3072..8c1349e08 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -206,6 +206,44 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const return diff; } +template +void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase *this_c) +{ + const T* opt_init = static_cast(other.option(opt_key)); + const T* opt_cur = static_cast(this_c->option(opt_key)); + int opt_init_max_id = opt_init->values.size() - 1; + for (int i = 0; i < opt_cur->values.size(); i++) + { + int init_id = i <= opt_init_max_id ? i : 0; + if (opt_cur->values[i] != opt_init->values[init_id]) + vec.emplace_back(opt_key + "#" + std::to_string(i)); + } +} + +t_config_option_keys ConfigBase::deep_diff(const ConfigBase &other) const +{ + t_config_option_keys diff; + for (const t_config_option_key &opt_key : this->keys()) { + const ConfigOption *this_opt = this->option(opt_key); + const ConfigOption *other_opt = other.option(opt_key); + if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt) + { + if (opt_key == "bed_shape"){ diff.emplace_back(opt_key); continue; } + switch (other_opt->type()) + { + case coInts: add_correct_opts_to_diff(opt_key, diff, other, this); break; + case coBools: add_correct_opts_to_diff(opt_key, diff, other, this); break; + case coFloats: add_correct_opts_to_diff(opt_key, diff, other, this); break; + case coStrings: add_correct_opts_to_diff(opt_key, diff, other, this); break; + case coPercents:add_correct_opts_to_diff(opt_key, diff, other, this); break; + case coPoints: add_correct_opts_to_diff(opt_key, diff, other, this); break; + default: diff.emplace_back(opt_key); break; + } + } + } + return diff; +} + t_config_option_keys ConfigBase::equal(const ConfigBase &other) const { t_config_option_keys equal; diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index 6eb307c5c..24a887130 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -1046,6 +1046,9 @@ public: void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false); bool equals(const ConfigBase &other) const { return this->diff(other).empty(); } t_config_option_keys diff(const ConfigBase &other) const; + // Use deep_diff to correct return of changed options, + // considering individual options for each extruder + t_config_option_keys deep_diff(const ConfigBase &other) const; t_config_option_keys equal(const ConfigBase &other) const; std::string serialize(const t_config_option_key &opt_key) const; // Set a configuration value from a string, it will call an overridable handle_legacy() diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index cc135931a..c4f07935c 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -179,6 +179,7 @@ AppConfig *g_AppConfig = nullptr; PresetBundle *g_PresetBundle= nullptr; wxColour g_color_label_modified; wxColour g_color_label_sys; +wxColour g_color_label_default; std::vector g_tabs_list; @@ -198,6 +199,7 @@ static void init_label_colours() g_color_label_modified = wxColour(253, 111, 40); g_color_label_sys = wxColour(115, 220, 103); } + g_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); } void set_wxapp(wxApp *app) @@ -548,6 +550,10 @@ const wxColour& get_sys_label_clr() { return g_color_label_sys; } +const wxColour& get_default_label_clr() { + return g_color_label_default; +} + unsigned get_colour_approx_luma(const wxColour &colour) { double r = colour.Red(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 0b681f48f..75600a57b 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -83,6 +83,7 @@ wxApp* get_app(); const wxColour& get_modified_label_clr(); const wxColour& get_sys_label_clr(); +const wxColour& get_default_label_clr(); unsigned get_colour_approx_luma(const wxColour &colour); void add_debug_menu(wxMenuBar *menu, int event_language_change); diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index d48c9bf8f..30f49df08 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -629,11 +629,13 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui) return was_dirty != is_dirty; } -std::vector PresetCollection::dirty_options(const Preset *edited, const Preset *reference) +std::vector PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type /*= false*/) { std::vector changed; - if (edited != nullptr && reference != nullptr) { - changed = reference->config.diff(edited->config); + if (edited != nullptr && reference != nullptr) { + changed = is_printer_type ? + reference->config.deep_diff(edited->config) : + reference->config.diff(edited->config); // The "compatible_printers" option key is handled differently from the others: // It is not mandatory. If the key is missing, it means it is compatible with any printer. // If the key exists and it is empty, it means it is compatible with no printer. diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index c038160f4..e12f18b88 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -253,11 +253,11 @@ public: // Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ. bool current_is_dirty() const { return ! this->current_dirty_options().empty(); } // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. - std::vector current_dirty_options() const - { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset()); } + std::vector current_dirty_options(const bool is_printer_type = false) const + { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), is_printer_type); } // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. - std::vector current_different_from_parent_options() const - { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent()); } + std::vector current_different_from_parent_options(const bool is_printer_type = false) const + { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), is_printer_type); } // Compare the content of get_selected_preset() with get_selected_preset_parent() configs, return the list of keys where they equal. std::vector system_equal_options() const; @@ -299,7 +299,7 @@ private: std::deque::const_iterator find_preset_internal(const std::string &name) const { return const_cast(this)->find_preset_internal(name); } - static std::vector dirty_options(const Preset *edited, const Preset *reference); + static std::vector dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false); // Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER. Preset::Type m_type; diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 825243749..dcf61f574 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -25,6 +25,8 @@ #include "wxExtensions.hpp" #include +#include + namespace Slic3r { namespace GUI { @@ -112,14 +114,14 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) m_bmp_value_revert .LoadFile(from_u8(var("action_undo.png")), wxBITMAP_TYPE_PNG); m_bmp_white_bullet .LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); m_undo_btn->SetBitmap(m_bmp_white_bullet); - m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_initial_value(); })); + m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ /*on_back_to_initial_value*/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_back_to_sys_value(); })); + m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ /*on_back_to_sys_value*/on_roll_back_value(true); })); // Colors for ui "decoration" m_sys_label_clr = get_sys_label_clr(); m_modified_label_clr = get_modified_label_clr(); - m_default_text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + m_default_text_clr = get_default_label_clr(); m_hsizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_hsizer, 0, wxBOTTOM, 3); @@ -246,45 +248,108 @@ PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bo return page; } -template -void add_correct_opts_to_dirty_options(const std::string &opt_key, std::vector *vec, TabPrinter *tab) -{ - auto opt_init = static_cast(tab->m_presets->get_selected_preset().config.option(opt_key)); - auto opt_cur = static_cast(tab->m_config->option(opt_key)); - int opt_init_max_id = opt_init->values.size()-1; - for (int i = 0; i < opt_cur->values.size(); i++) - { - int init_id = i <= opt_init_max_id ? i : 0; - if (opt_cur->values[i] != opt_init->values[init_id]) - vec->emplace_back(opt_key + "#" + std::to_string(i)); - } -} - -template -void add_correct_opts_to_sys_options(const std::string &opt_key, std::vector *vec, TabPrinter *tab) -{ - const Preset* sys_preset = tab->m_presets->get_selected_preset_parent(); - if (sys_preset == nullptr) - return; - T *opt_cur = static_cast(tab->m_config->option(opt_key)); - const T *opt_sys = static_cast(sys_preset->config.option(opt_key)); - int opt_max_id = opt_sys->values.size()-1; - for (int i = 0; i < opt_cur->values.size(); i++) - { - int init_id = i <= opt_max_id ? i : 0; - if (opt_cur->values[i] == opt_sys->values[init_id]) - vec->emplace_back(opt_key + "#" + std::to_string(i)); - } -} +// template +// void add_correct_opts_to_dirty_options(const std::string &opt_key, std::vector *vec, TabPrinter *tab) +// { +// auto opt_init = static_cast(tab->m_presets->get_selected_preset().config.option(opt_key)); +// auto opt_cur = static_cast(tab->m_config->option(opt_key)); +// int opt_init_max_id = opt_init->values.size()-1; +// for (int i = 0; i < opt_cur->values.size(); i++) +// { +// int init_id = i <= opt_init_max_id ? i : 0; +// if (opt_cur->values[i] != opt_init->values[init_id]) +// vec->emplace_back(opt_key + "#" + std::to_string(i)); +// } +// } +// +// template +// void add_correct_opts_to_sys_options(const std::string &opt_key, std::vector *vec, TabPrinter *tab) +// { +// const Preset* sys_preset = tab->m_presets->get_selected_preset_parent(); +// if (sys_preset == nullptr) +// return; +// T *opt_cur = static_cast(tab->m_config->option(opt_key)); +// const T *opt_sys = static_cast(sys_preset->config.option(opt_key)); +// int opt_max_id = opt_sys->values.size()-1; +// for (int i = 0; i < opt_cur->values.size(); i++) +// { +// int init_id = i <= opt_max_id ? i : 0; +// if (opt_cur->values[i] == opt_sys->values[init_id]) +// vec->emplace_back(opt_key + "#" + std::to_string(i)); +// } +// } // Update UI according to changes void Tab::update_changed_ui() { if (m_postpone_update_ui) return; - auto dirty_options = m_presets->current_dirty_options(); - if (name() == "printer"){ + const bool is_printer_type = (name() == "printer"); + auto m_dirty_options = m_presets->current_dirty_options(is_printer_type); + auto m_nonsys_options = m_presets->current_different_from_parent_options(is_printer_type); + if (is_printer_type){ + TabPrinter* tab = static_cast(this); + if (tab->m_initial_extruders_count != tab->m_extruders_count) + m_dirty_options.emplace_back("extruders_count"); + if (tab->m_sys_extruders_count != tab->m_extruders_count) + m_nonsys_options.emplace_back("extruders_count"); + } + + for (auto& it : m_options_list) + it.second = m_opt_status_value; + +// auto m_options_list = m_options_list; + for (auto opt_key : m_dirty_options) m_options_list[opt_key] &= ~osInitValue; + for (auto opt_key : m_nonsys_options) m_options_list[opt_key] &= ~osSystemValue; + + Freeze(); + //update options "decoration" + for (const auto opt : m_options_list/*m_options_list*/) + { + 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 wxColour *color = &m_sys_label_clr; + + if ((opt.second & osSystemValue) == 0){ +// if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) { + is_nonsys_value = true; + sys_icon = m_bmp_non_system; + if ((opt.second & osInitValue) != 0) +// if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()) + color = &m_default_text_clr; + else + color = &m_modified_label_clr; + } + if ((opt.second & osInitValue) != 0) +// if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()) + { + is_modified_value = false; + icon = &m_bmp_white_bullet; + } + if (opt.first == "bed_shape" || opt.first == "compatible_printers") { + if (m_colored_Label != nullptr) { + m_colored_Label->SetForegroundColour(*color); + m_colored_Label->Refresh(true); + } + continue; + } + + Field* field = get_field(opt.first); + if (field == nullptr) continue; + field->m_is_nonsys_value = is_nonsys_value; + field->m_is_modified_value = is_modified_value; + field->set_undo_bitmap(icon); + field->set_undo_to_sys_bitmap(sys_icon); + field->set_label_colour(color); + } + Thaw(); +// m_options_list = m_options_list; +/* auto dirty_options = m_presets->current_dirty_options(); + + if (){ // Update dirty_options in case changes of Extruder's options TabPrinter* tab = static_cast(this); m_dirty_options.resize(0); @@ -381,71 +446,113 @@ void Tab::update_changed_ui() field->set_label_colour(color); } Thaw(); - +*/ wxTheApp->CallAfter([this]() { update_changed_tree_ui(); }); } +void Tab::init_options_list() +{ + if (!m_options_list.empty()) + m_options_list.clear(); + + for (const auto opt_key : m_config->keys()) + m_options_list.emplace(opt_key, m_opt_status_value); +} + template -void add_correct_opts_to_full_options_list(const std::string &opt_key, std::vector *vec, TabPrinter *tab) +void add_correct_opts_to_options_list(const std::string &opt_key, std::map& map, TabPrinter *tab, const int& value) { T *opt_cur = static_cast(tab->m_config->option(opt_key)); for (int i = 0; i < opt_cur->values.size(); i++) - vec->emplace_back(opt_key + "#" + std::to_string(i)); + map.emplace(opt_key + "#" + std::to_string(i), value); } -void Tab::update_full_options_list() +void TabPrinter::init_options_list() { - if (!m_full_options_list.empty()) - m_full_options_list.resize(0); + if (!m_options_list.empty()) + m_options_list.clear(); - if (m_name != "printer"){ - m_full_options_list = m_config->keys(); - return; - } - - TabPrinter* tab = static_cast(this); for (const auto opt_key : m_config->keys()) { if (opt_key == "bed_shape"){ - m_full_options_list.emplace_back(opt_key); + m_options_list.emplace(opt_key, m_opt_status_value); continue; } switch (m_config->option(opt_key)->type()) { - case coInts: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - case coBools: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - case coFloats: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - case coStrings: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - case coPercents:add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - case coPoints: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; - default: m_full_options_list.emplace_back(opt_key); break; + case coInts: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coBools: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coFloats: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coStrings: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coPercents:add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coPoints: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + default: m_options_list.emplace(opt_key, m_opt_status_value); break; } } - m_full_options_list.emplace_back("extruders_count"); + m_options_list.emplace("extruders_count", m_opt_status_value); } -void Tab::update_sys_ui_after_sel_preset() -{ - const wxColour* clr = &m_default_text_clr; - for (const auto opt_key : m_full_options_list){ - Field* field = get_field(opt_key); - if (field != nullptr){ - field->set_undo_to_sys_bitmap(m_bmp_non_system); - field->m_is_nonsys_value = true; - field->set_label_colour(clr); - } - } - m_sys_options.resize(0); -} + +// template +// void add_correct_opts_to_full_options_list(const std::string &opt_key, std::vector *vec, TabPrinter *tab) +// { +// T *opt_cur = static_cast(tab->m_config->option(opt_key)); +// for (int i = 0; i < opt_cur->values.size(); i++) +// vec->emplace_back(opt_key + "#" + std::to_string(i)); +// } + +// void Tab::update_full_options_list() +// { +// if (!m_full_options_list.empty()) +// m_full_options_list.resize(0); +// +// if (m_name != "printer"){ +// m_full_options_list = m_config->keys(); +// return; +// } +// +// TabPrinter* tab = static_cast(this); +// for (const auto opt_key : m_config->keys()) +// { +// if (opt_key == "bed_shape"){ +// m_full_options_list.emplace_back(opt_key); +// continue; +// } +// switch (m_config->option(opt_key)->type()) +// { +// case coInts: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// case coBools: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// case coFloats: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// case coStrings: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// case coPercents:add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// case coPoints: add_correct_opts_to_full_options_list(opt_key, &m_full_options_list, tab); break; +// default: m_full_options_list.emplace_back(opt_key); break; +// } +// } +// m_full_options_list.emplace_back("extruders_count"); +// } + +// void Tab::update_sys_ui_after_sel_preset() +// { +// const wxColour* clr = &m_default_text_clr; +// for (const auto opt_key : m_full_options_list){ +// Field* field = get_field(opt_key); +// if (field != nullptr){ +// field->set_undo_to_sys_bitmap(m_bmp_non_system); +// field->m_is_nonsys_value = true; +// field->set_label_colour(clr); +// } +// } +// m_sys_options.resize(0); +// } void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page) { - if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) - sys_page = false; - if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end()) - modified_page = true; + auto opt = m_options_list.find(opt_key); + if (sys_page) sys_page = (opt->second & osSystemValue) != 0; + if (!modified_page) modified_page = (opt->second & osInitValue) == 0; } void Tab::update_changed_tree_ui() @@ -466,7 +573,7 @@ void Tab::update_changed_tree_ui() get_sys_and_mod_flags(opt_key, sys_page, modified_page); } } - if (title == _("Dependencies")){ + if (title == _("Dependencies") && name() != "printer"){ get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); } for (auto group : page->m_optgroups) @@ -478,12 +585,13 @@ void Tab::update_changed_tree_ui() get_sys_and_mod_flags(opt_key, sys_page, modified_page); } } - if (sys_page) - m_treectrl->SetItemTextColour(cur_item, get_sys_label_clr()); - else if (modified_page) - m_treectrl->SetItemTextColour(cur_item, get_modified_label_clr()); - else - m_treectrl->SetItemTextColour(cur_item, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + + const wxColor *clr = sys_page ? &m_sys_label_clr : + modified_page ? &m_modified_label_clr : + &m_default_text_clr; + + if (page->set_item_colour(clr)) + m_treectrl->SetItemTextColour(cur_item, *clr); page->m_is_nonsys_values = !sys_page; page->m_is_modified_values = modified_page; @@ -506,9 +614,17 @@ void Tab::update_undo_buttons() m_undo_to_sys_btn->SetBitmap(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); } -void Tab::on_back_to_initial_value() +void Tab::on_roll_back_value(const bool to_sys /*= true*/) { - if (!m_is_modified_values) return; + int os; + if (to_sys) { + if (!m_is_nonsys_values) return; + os = osSystemValue; + } + else { + if (!m_is_modified_values) return; + os = osInitValue; + } m_postpone_update_ui = true; @@ -517,19 +633,19 @@ void Tab::on_back_to_initial_value() if (page->title() == selection) { for (auto group : page->m_optgroups){ if (group->title == _("Capabilities")){ - if (find(m_dirty_options.begin(), m_dirty_options.end(), "extruders_count") != m_dirty_options.end()) - group->back_to_initial_value("extruders_count"); + if ((m_options_list["extruders_count"] & os) == 0) + to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); } if (group->title == _("Size and coordinates")){ - if (find(m_dirty_options.begin(), m_dirty_options.end(), "bed_shape") != m_dirty_options.end()){ - group->back_to_initial_value("bed_shape"); + if ((m_options_list["bed_shape"] & os) == 0){ + to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); load_key_value("bed_shape", true/*some value*/, true); } } - if (group->title == _("Profile dependencies")){ - if (find(m_dirty_options.begin(), m_dirty_options.end(), "compatible_printers") != m_dirty_options.end()){ - group->back_to_initial_value("compatible_printers"); + if (group->title == _("Profile dependencies") && name() != "printer"){ + if ((m_options_list["compatible_printers"] & os) == 0){ + to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); load_key_value("compatible_printers", true/*some value*/, true); bool is_empty = m_config->option("compatible_printers")->values.empty(); @@ -539,8 +655,8 @@ void Tab::on_back_to_initial_value() } for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { const std::string& opt_key = it->first; - if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end()) - group->back_to_initial_value(opt_key); + if ((m_options_list[opt_key] & os) == 0) + to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key); } } break; @@ -550,48 +666,111 @@ void Tab::on_back_to_initial_value() update_changed_ui(); } -void Tab::on_back_to_sys_value() -{ - if (!m_is_nonsys_values) return; - - m_postpone_update_ui = true; - - auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); - for (auto page : m_pages) - if (page->title() == selection) { - for (auto group : page->m_optgroups) { - if (group->title == _("Capabilities")){ - if (find(m_sys_options.begin(), m_sys_options.end(), "extruders_count") == m_sys_options.end()) - group->back_to_sys_value("extruders_count"); - } - if (group->title == _("Size and coordinates")){ - if (find(m_sys_options.begin(), m_sys_options.end(), "bed_shape") == m_sys_options.end()){ - group->back_to_sys_value("bed_shape"); - load_key_value("bed_shape", true/*some value*/, true); - } - } - if (group->title == _("Profile dependencies")){ - if (find(m_sys_options.begin(), m_sys_options.end(), "compatible_printers") == m_sys_options.end()){ - group->back_to_sys_value("compatible_printers"); - load_key_value("compatible_printers", true/*some value*/, true); - - bool is_empty = m_config->option("compatible_printers")->values.empty(); - m_compatible_printers_checkbox->SetValue(is_empty); - is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); - } - } - for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { - const std::string& opt_key = it->first; - if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) - group->back_to_sys_value(opt_key); - } - } - break; - } - - m_postpone_update_ui = false; - update_changed_ui(); -} +// void Tab::on_back_to_initial_value() +// { +// if (!m_is_modified_values) return; +// std::chrono::milliseconds ms1 = std::chrono::duration_cast( +// std::chrono::system_clock::now().time_since_epoch() +// ); +// +// m_postpone_update_ui = true; +// +// auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); +// for (auto page : m_pages) +// if (page->title() == selection) { +// for (auto group : page->m_optgroups){ +// if (group->title == _("Capabilities")){ +// if (find(m_dirty_options.begin(), m_dirty_options.end(), "extruders_count") != m_dirty_options.end()) +// group->back_to_initial_value("extruders_count"); +// } +// if (group->title == _("Size and coordinates")){ +// if (find(m_dirty_options.begin(), m_dirty_options.end(), "bed_shape") != m_dirty_options.end()){ +// group->back_to_initial_value("bed_shape"); +// load_key_value("bed_shape", true/*some value*/, true); +// } +// +// } +// if (group->title == _("Profile dependencies")){ +// if (find(m_dirty_options.begin(), m_dirty_options.end(), "compatible_printers") != m_dirty_options.end()){ +// group->back_to_initial_value("compatible_printers"); +// load_key_value("compatible_printers", true/*some value*/, true); +// +// bool is_empty = m_config->option("compatible_printers")->values.empty(); +// m_compatible_printers_checkbox->SetValue(is_empty); +// is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); +// } +// } +// for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { +// const std::string& opt_key = it->first; +// if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end()) +// group->back_to_initial_value(opt_key); +// } +// } +// break; +// } +// +// std::chrono::milliseconds ms2 = std::chrono::duration_cast( +// std::chrono::system_clock::now().time_since_epoch() +// ); +// +// m_postpone_update_ui = false; +// update_changed_ui(); +// +// std::chrono::milliseconds ms3 = std::chrono::duration_cast( +// std::chrono::system_clock::now().time_since_epoch() +// ); +// +// auto roll_back_duration = std::chrono::microseconds(ms2 - ms1).count(); +// auto update_ui_duration = std::chrono::microseconds(ms3 - ms2).count(); +// printf("back_to init_duration duration = %lld ms \n", roll_back_duration); +// printf("update_ui_duration duration = %lld ms \n", update_ui_duration); +// +// // m_postpone_update_ui = false; +// // update_changed_ui(); +// } +// +// void Tab::on_back_to_sys_value() +// { +// if (!m_is_nonsys_values) return; +// +// m_postpone_update_ui = true; +// +// auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); +// for (auto page : m_pages) +// if (page->title() == selection) { +// for (auto group : page->m_optgroups) { +// if (group->title == _("Capabilities")){ +// if (find(m_sys_options.begin(), m_sys_options.end(), "extruders_count") == m_sys_options.end()) +// group->back_to_sys_value("extruders_count"); +// } +// if (group->title == _("Size and coordinates")){ +// if (find(m_sys_options.begin(), m_sys_options.end(), "bed_shape") == m_sys_options.end()){ +// group->back_to_sys_value("bed_shape"); +// load_key_value("bed_shape", true/*some value*/, true); +// } +// } +// if (group->title == _("Profile dependencies")){ +// if (find(m_sys_options.begin(), m_sys_options.end(), "compatible_printers") == m_sys_options.end()){ +// group->back_to_sys_value("compatible_printers"); +// load_key_value("compatible_printers", true/*some value*/, true); +// +// bool is_empty = m_config->option("compatible_printers")->values.empty(); +// m_compatible_printers_checkbox->SetValue(is_empty); +// is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); +// } +// } +// for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { +// const std::string& opt_key = it->first; +// if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) +// group->back_to_sys_value(opt_key); +// } +// } +// break; +// } +// +// m_postpone_update_ui = false; +// update_changed_ui(); +// } // Update the combo box label of the selected preset based on its "dirty" state, // comparing the selected preset config with $self->{config}. @@ -1698,12 +1877,34 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ } void TabPrinter::build_extruder_pages(){ - for (auto extruder_idx = m_extruder_pages.size(); extruder_idx < m_extruders_count; ++extruder_idx){ + if (m_extruders_count_old == m_extruders_count) + { + // if we have a single extruder MM setup, add a page with configuration options: + for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already + if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { + m_pages.erase(m_pages.begin() + i); + break; + } + if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material")) { + // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves + auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png", true); + auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); + optgroup->append_single_option_line("cooling_tube_retraction"); + optgroup->append_single_option_line("cooling_tube_length"); + optgroup->append_single_option_line("parking_pos_retraction"); + m_pages.insert(m_pages.end()-2, page); + } + rebuild_page_tree(); + return; + } + + for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx){ //# build page char buf[MIN_BUF_LENGTH_FOR_L]; sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); auto page = add_options_page(from_u8(buf), "funnel.png", true); - m_extruder_pages.push_back(page); + m_pages.insert(m_pages.begin() + 2+extruder_idx, page); +// m_extruder_pages.push_back(page); auto optgroup = page->new_optgroup(_(L("Size"))); optgroup->append_single_option_line("nozzle_diameter", extruder_idx); @@ -1741,36 +1942,31 @@ void TabPrinter::build_extruder_pages(){ } // # remove extra pages - if (m_extruders_count <= m_extruder_pages.size()) { - m_extruder_pages.resize(m_extruders_count); - } +// if (m_extruders_count <= m_extruders_count_old) { +// m_extruder_pages.resize(m_extruders_count); +// } + + if (m_extruders_count < m_extruders_count_old) + m_pages.erase(m_pages.begin() + 2 + m_extruders_count, m_pages.begin() + 2 + m_extruders_count_old); + + m_extruders_count_old = m_extruders_count; // # rebuild page list - PageShp page_note = m_pages.back(); - m_pages.pop_back(); - while (m_pages.back()->title().find(_(L("Extruder"))) != std::string::npos) - m_pages.pop_back(); - for (auto page_extruder : m_extruder_pages) - m_pages.push_back(page_extruder); - m_pages.push_back(page_note); - - { - // if we have a single extruder MM setup, add a page with configuration options: - for (int i=0;ititle().find(_(L("Single extruder MM setup"))) != std::string::npos) { - m_pages.erase(m_pages.begin()+i); - break; - } - if ( m_extruder_pages.size()>1 && m_config->opt_bool("single_extruder_multi_material")) { - // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves - auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png",true); - auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); - optgroup->append_single_option_line("cooling_tube_retraction"); - optgroup->append_single_option_line("cooling_tube_length"); - optgroup->append_single_option_line("parking_pos_retraction"); - m_pages.insert(m_pages.begin()+1,page); - } - } +// PageShp page_note = m_pages.back(); +// m_pages.pop_back(); +// PageShp page_depend = m_pages.back(); +// m_pages.pop_back(); +// auto counter = m_extruders_count_old; +// while (counter > m_extruders_count/*m_pages.back()->title().find(_(L("Extruder"))) != std::string::npos*/){ +// m_pages.pop_back(); +// --counter; +// } +// // for (auto page_extruder : m_extruder_pages) +// // m_pages.push_back(page_extruder); +// for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) +// m_pages.push_back(m_extruder_pages[extruder_idx]); +// m_pages.push_back(page_note); +// m_pages.push_back(page_depend); rebuild_page_tree(); } @@ -1899,8 +2095,10 @@ void Tab::load_current_preset() static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); } - update_sys_ui_after_sel_preset(); - update_full_options_list(); +// update_sys_ui_after_sel_preset(); +// update_full_options_list(); + m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; + init_options_list(); update_changed_ui(); }); } @@ -1917,6 +2115,7 @@ void Tab::rebuild_page_tree() for (auto p : m_pages) { auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); + m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); if (p->title() == selected) { m_disable_tree_sel_changed_event = 1; m_treectrl->SelectItem(itemId); diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index 4668c1238..2ac1e969b 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -51,6 +51,7 @@ public: { Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); m_vsizer = new wxBoxSizer(wxVERTICAL); + m_item_color = &get_default_label_clr(); SetSizer(m_vsizer); } ~Page(){} @@ -71,6 +72,22 @@ public: 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); + + bool set_item_colour(const wxColour *clr) { + if (m_item_color != clr) { + m_item_color = clr; + return true; + } + return false; + } + + const wxColour get_item_colour() { + return *m_item_color; + } + +protected: + // Color of TreeCtrlItem. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one. + const wxColour* m_item_color; }; // Slic3r::GUI::Tab; @@ -125,9 +142,13 @@ protected: bool m_no_controller; std::vector m_reload_dependent_tabs = {}; - std::vector m_dirty_options = {}; - std::vector m_sys_options = {}; - std::vector m_full_options_list = {}; +// std::vector m_dirty_options = {}; +// std::vector m_nonsys_options = {}; +// std::vector m_sys_options = {}; +// std::vector m_full_options_list = {}; + enum OptStatus { osSystemValue = 1, osInitValue = 2 }; + std::map m_options_list; + int m_opt_status_value; // The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType. wxEventType m_event_value_change = 0; @@ -182,14 +203,15 @@ public: void update_show_hide_incompatible_button(); void update_ui_from_settings(); void update_changed_ui(); - void update_full_options_list(); - void update_sys_ui_after_sel_preset(); +// void update_full_options_list(); +// void update_sys_ui_after_sel_preset(); void get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page); void update_changed_tree_ui(); void update_undo_buttons(); - void on_back_to_initial_value(); - void on_back_to_sys_value(); + void on_roll_back_value(const bool to_sys = false); +// void on_back_to_initial_value(); +// void on_back_to_sys_value(); PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false); @@ -197,6 +219,7 @@ public: virtual void on_preset_loaded(){} virtual void build() = 0; virtual void update() = 0; + virtual void init_options_list(); void load_initial_data(); void update_dirty(); void update_tab_ui(); @@ -265,9 +288,10 @@ public: wxButton* m_octoprint_host_test_btn; size_t m_extruders_count; + size_t m_extruders_count_old = 0; size_t m_initial_extruders_count; size_t m_sys_extruders_count; - std::vector m_extruder_pages; +// std::vector m_extruder_pages; TabPrinter() {} TabPrinter(wxNotebook* parent, bool no_controller) : Tab(parent, _(L("Printer Settings")), "printer", no_controller) {} @@ -279,6 +303,7 @@ public: void extruders_count_changed(size_t extruders_count); void build_extruder_pages(); void on_preset_loaded() override; + void init_options_list() override; }; class SavePresetWindow :public wxDialog