"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.
This commit is contained in:
YuSanka 2018-03-21 22:21:37 +01:00
parent f72bb89521
commit 82f4e16a27
6 changed files with 196 additions and 88 deletions

View file

@ -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 <yusanka@gmail.com>\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"

View file

@ -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<std::string, int> >::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<std::string, int> >::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;

View file

@ -69,6 +69,7 @@ private:
};
using t_optionfield_map = std::map<t_config_option_key, t_field>;
using t_opt_map = std::map< std::string, std::pair<std::string, int> >;
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<std::string()> 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<std::string, int> > 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*/{

View file

@ -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<TabPrinter*>(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<const char*> 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<ConfigOptionInts >(opt_key, &new_options, tab); break;
case coBools: add_correct_opts_to_sys_options<ConfigOptionBools >(opt_key, &new_options, tab); break;
case coFloats: add_correct_opts_to_sys_options<ConfigOptionFloats >(opt_key, &new_options, tab); break;
case coStrings: add_correct_opts_to_sys_options<ConfigOptionStrings >(opt_key, &new_options, tab); break;
case coPercents:add_correct_opts_to_sys_options<ConfigOptionPercents>(opt_key, &new_options, tab); break;
case coPoints: add_correct_opts_to_sys_options<ConfigOptionPoints >(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<const char*> 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<ConfigOptionInts >(opt_key, &m_sys_options, tab); break;
case coBools: add_correct_opts_to_sys_options<ConfigOptionBools >(opt_key, &m_sys_options, tab); break;
case coFloats: add_correct_opts_to_sys_options<ConfigOptionFloats >(opt_key, &m_sys_options, tab); break;
case coStrings: add_correct_opts_to_sys_options<ConfigOptionStrings >(opt_key, &m_sys_options, tab); break;
case coPercents:add_correct_opts_to_sys_options<ConfigOptionPercents>(opt_key, &m_sys_options, tab); break;
case coPoints: add_correct_opts_to_sys_options<ConfigOptionPoints >(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<std::string>::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<class T>
void add_correct_opts_to_full_options_list(const std::string &opt_key, std::vector<std::string> *vec, TabPrinter *tab)
{
T *opt_cur = static_cast<T*>(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<TabPrinter*>(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<ConfigOptionInts >(opt_key, &m_full_options_list, tab); break;
case coBools: add_correct_opts_to_full_options_list<ConfigOptionBools >(opt_key, &m_full_options_list, tab); break;
case coFloats: add_correct_opts_to_full_options_list<ConfigOptionFloats >(opt_key, &m_full_options_list, tab); break;
case coStrings: add_correct_opts_to_full_options_list<ConfigOptionStrings >(opt_key, &m_full_options_list, tab); break;
case coPercents:add_correct_opts_to_full_options_list<ConfigOptionPercents >(opt_key, &m_full_options_list, tab); break;
case coPoints: add_correct_opts_to_full_options_list<ConfigOptionPoints >(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<const char*> 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<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size();
m_sys_extruders_count = static_cast<const ConfigOptionFloats*>(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<const ConfigOptionFloats*>(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<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
const Preset* parent_preset = m_presets->get_selected_preset_parent();
static_cast<TabPrinter*>(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 :
static_cast<const ConfigOptionFloats*>(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<Tab*>(GetParent())->m_presets->get_selected_preset_parent() != nullptr;
};
optgroup->nonsys_btn_icon = static_cast<Tab*>(GetParent())->m_nonsys_btn_icon;
optgroup->nonsys_btn_icon = [this](){
return static_cast<Tab*>(GetParent())->m_nonsys_btn_icon;
};
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
m_optgroups.push_back(optgroup);

View file

@ -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<std::string, size_t> m_icon_index; // Map from an icon file name to its index in $self->{icons}.
std::vector<PageShp> m_pages; // $self->{pages} = [];
std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index
std::vector<PageShp> 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<std::string> m_reload_dependent_tabs = {};
std::vector<std::string> m_dirty_options = {};
std::vector<std::string> m_sys_options = {};
std::vector<std::string> 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(){}