From 82f4e16a27f85ec3c5e277b8fb4843d006ee7680 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 21 Mar 2018 22:21:37 +0100 Subject: [PATCH] "Decorated" UI for options groups. * Added prototype of undo-buttons for options groups; * Fixed bugs with "decoration" updating after preset changing; * Fixed wrong Ukrainian translation. --- resources/localization/uk/Slic3rPE.mo | Bin 140066 -> 140068 bytes resources/localization/uk/Slic3rPE_uk.po | 8 +- xs/src/slic3r/GUI/OptionsGroup.cpp | 8 +- xs/src/slic3r/GUI/OptionsGroup.hpp | 5 +- xs/src/slic3r/GUI/Tab.cpp | 251 ++++++++++++++++------- xs/src/slic3r/GUI/Tab.hpp | 12 +- 6 files changed, 196 insertions(+), 88 deletions(-) diff --git a/resources/localization/uk/Slic3rPE.mo b/resources/localization/uk/Slic3rPE.mo index c980ae64db8cc2f277ea38c8f12587076ef3626a..7ced15dc8c91acee358022d27d2d1abdf88c2313 100644 GIT binary patch delta 5917 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 BiDLi& delta 5915 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 tYZO&CzHy!St*Mvuf\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -3330,7 +3330,7 @@ msgstr "" #: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:137 msgid "None" -msgstr "Жадне" +msgstr "Жодне" #: c:\src\Slic3r\xs\src\libslic3r\GCode\PreviewData.cpp:138 #: c:\src\Slic3r\lib\Slic3r\GUI\Plater\3DPreview.pm:80 @@ -3718,11 +3718,11 @@ msgstr "Файл" #: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:419 msgid "&Plater" -msgstr "Платер" +msgstr "&Платер" #: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:420 msgid "&Object" -msgstr "Об'єкт" +msgstr "&Об'єкт" #: c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm:421 msgid "&Window" diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 37f3fea68d..3a97c98c7b 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -90,8 +90,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co field->m_Undo_btn->Hide(); field->m_Undo_to_sys_btn->Hide(); } - if (nonsys_btn_icon != "") - field->set_nonsys_btn_icon(nonsys_btn_icon); + if (nonsys_btn_icon != nullptr) + field->set_nonsys_btn_icon(nonsys_btn_icon()); // assign function objects for callbacks, etc. return field; @@ -335,7 +335,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, } void ConfigOptionsGroup::reload_config(){ - for (std::map< std::string, std::pair >::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { + for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { auto opt_id = it->first; std::string opt_key = m_opt_map.at(opt_id).first; int opt_index = m_opt_map.at(opt_id).second; @@ -455,7 +455,7 @@ Field* ConfigOptionsGroup::get_fieldc(t_config_option_key opt_key, int opt_index if (field != nullptr) return field; std::string opt_id = ""; - for (std::map< std::string, std::pair >::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { + 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; diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 3efa427304..7884271e1d 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -69,6 +69,7 @@ private: }; using t_optionfield_map = std::map; +using t_opt_map = std::map< std::string, std::pair >; class OptionsGroup { public: @@ -85,7 +86,7 @@ public: wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; - std::string nonsys_btn_icon = ""; + std::function nonsys_btn_icon{ nullptr }; /// Returns a copy of the pointer of the parent wxWindow. /// Accessor function is because users are not allowed to change the parent @@ -164,7 +165,7 @@ public: /// reference to libslic3r config, non-owning pointer (?). DynamicPrintConfig* m_config {nullptr}; bool m_full_labels {0}; - std::map< std::string, std::pair > m_opt_map; + t_opt_map m_opt_map; Option get_option(const std::string opt_key, int opt_index = -1); Line create_single_option_line(const std::string title, int idx = -1) /*const*/{ diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 464734f9c9..9266796645 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -55,6 +55,17 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->Disable(); + m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) { + m_undo_btn->SetBackgroundColour(color); + m_undo_to_sys_btn->SetBackgroundColour(color); + } + m_undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); + m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ })); + m_undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); + m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ })); + m_hsizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_hsizer, 0, wxBOTTOM, 3); m_hsizer->Add(m_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); @@ -64,6 +75,9 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(16); m_hsizer->Add(m_btn_hide_incompatible_presets, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->AddSpacer(64); + m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); //Horizontal sizer to hold the tree and the selected page. m_hsizer = new wxBoxSizer(wxHORIZONTAL); @@ -182,8 +196,6 @@ void Tab::update_changed_ui() { auto dirty_options = m_presets->current_dirty_options(); - auto sys_options = m_presets->system_equal_options(); - if (name() == "printer"){ // Update dirty_options in case changes of Extruder's options TabPrinter* tab = static_cast(this); @@ -201,38 +213,40 @@ void Tab::update_changed_ui() default: new_options.emplace_back(opt_key); break; } } - dirty_options.resize(0); dirty_options = new_options; if (tab->m_initial_extruders_count != tab->m_extruders_count) dirty_options.emplace_back("extruders_count"); - new_options.resize(0); - std::initializer_list optional_keys{"bed_shape", "compatible_printers", "compatible_printers_condition" }; - for (auto &opt_key : optional_keys) { - if (find(sys_options.begin(), sys_options.end(),opt_key) != sys_options.end()) - new_options.emplace_back(opt_key); - } - for (auto opt_key : m_config->keys()) - { - if (opt_key == "bed_shape") continue; - switch (m_config->option(opt_key)->type()) - { - case coInts: add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - case coBools: add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - case coFloats: add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - case coStrings: add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - case coPercents:add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - case coPoints: add_correct_opts_to_sys_options(opt_key, &new_options, tab); break; - default: new_options.emplace_back(opt_key); break; + m_sys_options.resize(0); + const auto sys_preset = m_presets->get_selected_preset_parent(); + if (sys_preset){ + std::initializer_list optional_keys{"compatible_printers", "compatible_printers_condition" }; + for (auto &opt_key : optional_keys) { + if (m_config->has(opt_key) == sys_preset->config.has(opt_key)) + m_sys_options.emplace_back(opt_key); + } + for (auto opt_key : m_config->keys()) + { + if (opt_key == "bed_shape"){ m_sys_options.emplace_back(opt_key); continue; } + switch (m_config->option(opt_key)->type()) + { + case coInts: add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + case coBools: add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + case coFloats: add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + case coStrings: add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + case coPercents:add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + case coPoints: add_correct_opts_to_sys_options(opt_key, &m_sys_options, tab); break; + default: m_sys_options.emplace_back(opt_key); break; + } } - } - sys_options.resize(0); - sys_options = new_options; - if (tab->m_sys_extruders_count == tab->m_extruders_count) - sys_options.emplace_back("extruders_count"); + if (tab->m_sys_extruders_count == tab->m_extruders_count) + m_sys_options.emplace_back("extruders_count"); + } } + else + m_sys_options = m_presets->system_equal_options(); // Add new dirty options to m_dirty_options for (auto opt_key : dirty_options){ @@ -272,62 +286,139 @@ void Tab::update_changed_ui() } } } - //update system options (colored in green) - // Add new system equal options to m_sys_options - for (auto opt_key : sys_options){ + for (const auto opt_key : m_full_options_list) + { Field* field = get_field(opt_key); - if (field != nullptr && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()){ - field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(wxMSW ? var("sys_lock.png") : var("lock.png")), wxBITMAP_TYPE_PNG)); + if (field == nullptr) continue; + std::string icon = wxMSW ? "sys_lock.png" : "lock.png"; + wxColor& color = *get_sys_label_clr(); + if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) != m_sys_options.end()) { field->m_is_nonsys_value = false; - - m_sys_options.push_back(opt_key); } - if (field != nullptr && field->m_Label != nullptr){ - field->m_Label->SetForegroundColour(*get_sys_label_clr()); + else { + field->m_is_nonsys_value = true; + icon = m_nonsys_btn_icon; + if(find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()) + color = wxSYS_COLOUR_WINDOWTEXT; + } + field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(icon)), wxBITMAP_TYPE_PNG)); + if (field->m_Label != nullptr){ + field->m_Label->SetForegroundColour(color); field->m_Label->Refresh(true); } } - if (sys_options.empty() && !m_sys_options.empty()){ - for (auto opt_key : m_config->keys()){ - Field* field = get_field(opt_key); - if (field != nullptr){ - field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(m_nonsys_btn_icon)), wxBITMAP_TYPE_PNG)); - field->m_is_nonsys_value = false; - if (field->m_Label != nullptr){ - field->m_Label->SetForegroundColour(wxSYS_COLOUR_WINDOWTEXT); - field->m_Label->Refresh(true); - } - } - } - m_sys_options.resize(0); - } - // Delete clear options from m_dirty_options - for (auto i = 0; i < m_sys_options.size(); ++i) - { - const std::string &opt_key = m_sys_options[i]; - Field* field = get_field(opt_key); - if (find(sys_options.begin(), sys_options.end(), opt_key) == sys_options.end()) - { - if (field != nullptr){ - // use bouth of temporary_icons till don't have "unlock_icon" - field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(m_nonsys_btn_icon)), wxBITMAP_TYPE_PNG)); - if (field->m_Label != nullptr && - find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()){ - field->m_Label->SetForegroundColour(wxSYS_COLOUR_WINDOWTEXT); - field->m_Label->Refresh(true); - } - field->m_is_nonsys_value = true; - } - std::vector::iterator itr = find(m_sys_options.begin(), m_sys_options.end(), opt_key); - if (itr != m_sys_options.end()){ - m_sys_options.erase(itr); - --i; - } - } + + wxTheApp->CallAfter([this]() { + update_changed_tree_ui(); + }); +} + +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"); + + std::initializer_list optional_keys{ "compatible_printers", "compatible_printers_condition" }; + for (auto &opt_key : optional_keys) { + if (m_config->has(opt_key)) + m_full_options_list.emplace_back(opt_key); + } +} + +void Tab::update_sys_ui_after_sel_preset() +{ + for (const auto opt_key : m_full_options_list){ + Field* field = get_field(opt_key); + if (field != nullptr){ + field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(m_nonsys_btn_icon)), wxBITMAP_TYPE_PNG)); + field->m_is_nonsys_value = true; + if (field->m_Label != nullptr){ + field->m_Label->SetForegroundColour(wxSYS_COLOUR_WINDOWTEXT); + field->m_Label->Refresh(true); + } + } + } + m_sys_options.resize(0); +} + +void Tab::update_changed_tree_ui() +{ + auto cur_item = m_treectrl->GetFirstVisibleItem(); + while (cur_item){ + auto title = m_treectrl->GetItemText(cur_item); + int i=0; + for (auto page : m_pages) + { + if (page->title() != title) + continue; + bool sys_page = true; + bool modified_page = false; + if (title == _("General")){ + if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), "extruders_count") == m_sys_options.end()) + sys_page = false; + if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), "extruders_count") != m_dirty_options.end()) + modified_page = true; + } + for (auto group : page->m_optgroups) + { + 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 (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; + } + if (!sys_page && modified_page) + break; + } + 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, wxSYS_COLOUR_WINDOWTEXT); + break; + } + auto next_item = m_treectrl->GetNextVisible(cur_item); + cur_item = next_item; + } } // Update the combo box label of the selected preset based on its "dirty" state, @@ -1116,7 +1207,9 @@ void TabPrinter::build() auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); - m_sys_extruders_count = static_cast(m_presets->get_selected_preset_parent()->config.option("nozzle_diameter"))->values.size(); + const Preset* parent_preset = m_presets->get_selected_preset_parent(); + m_sys_extruders_count = parent_preset == nullptr ? 0 : + static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); auto page = add_options_page(_(L("General")), "printer_empty.png"); auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); @@ -1550,8 +1643,14 @@ void Tab::load_current_preset() if (name() == "print") update_frequently_changed_parameters(); - if (m_name == "printer") + if (m_name == "printer"){ static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; + const Preset* parent_preset = m_presets->get_selected_preset_parent(); + 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_changed_ui(); }); } @@ -1962,7 +2061,9 @@ ConfigOptionsGroupShp Page::new_optgroup(wxString title, int noncommon_label_wid return static_cast(GetParent())->m_presets->get_selected_preset_parent() != nullptr; }; - optgroup->nonsys_btn_icon = static_cast(GetParent())->m_nonsys_btn_icon; + optgroup->nonsys_btn_icon = [this](){ + return static_cast(GetParent())->m_nonsys_btn_icon; + }; vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); m_optgroups.push_back(optgroup); diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index a2cf648e96..8dd667bd1d 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -90,10 +90,12 @@ protected: wxImageList* m_icons; wxCheckBox* m_compatible_printers_checkbox; wxButton* m_compatible_printers_btn; + wxButton* m_undo_btn; + wxButton* m_undo_to_sys_btn; int m_icon_count; - std::map m_icon_index; // Map from an icon file name to its index in $self->{icons}. - std::vector m_pages; // $self->{pages} = []; + std::map m_icon_index; // Map from an icon file name to its index + std::vector m_pages; bool m_disable_tree_sel_changed_event; bool m_show_incompatible_presets; bool m_no_controller; @@ -101,6 +103,7 @@ protected: std::vector m_reload_dependent_tabs = {}; std::vector m_dirty_options = {}; std::vector m_sys_options = {}; + std::vector m_full_options_list = {}; // The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType. wxEventType m_event_value_change = 0; @@ -149,7 +152,10 @@ 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_changed_tree_ui(); + PageShp add_options_page(wxString title, std::string icon, bool is_extruder_pages = false); virtual void OnActivate(){}