diff --git a/resources/localization/uk/Slic3rPE.mo b/resources/localization/uk/Slic3rPE.mo index c980ae64db..7ced15dc8c 100644 Binary files a/resources/localization/uk/Slic3rPE.mo and b/resources/localization/uk/Slic3rPE.mo differ diff --git a/resources/localization/uk/Slic3rPE_uk.po b/resources/localization/uk/Slic3rPE_uk.po index 60354fd614..24b12095d7 100644 --- a/resources/localization/uk/Slic3rPE_uk.po +++ b/resources/localization/uk/Slic3rPE_uk.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-28 13:53+0100\n" -"PO-Revision-Date: 2018-02-28 14:04+0100\n" +"PO-Revision-Date: 2018-03-21 16:01+0100\n" "Last-Translator: Oleksandra Iushchenko \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(){}