First visualization of system value changes

This commit is contained in:
YuSanka 2018-03-16 12:56:03 +01:00
parent d97a8f5740
commit 7f5bfe3ddc
13 changed files with 131 additions and 19 deletions

View file

@ -1942,6 +1942,7 @@ sub selection_changed {
$self->{object_info_manifold_warning_icon}->SetToolTipString($message); $self->{object_info_manifold_warning_icon}->SetToolTipString($message);
} else { } else {
$self->{object_info_manifold}->SetLabel(L("Yes")); $self->{object_info_manifold}->SetLabel(L("Yes"));
$self->{object_info_manifold_warning_icon}->Hide;
} }
} else { } else {
$self->{object_info_facets}->SetLabel($object->facets); $self->{object_info_facets}->SetLabel($object->facets);

View file

@ -206,6 +206,18 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const
return diff; return diff;
} }
t_config_option_keys ConfigBase::equal(const ConfigBase &other) const
{
t_config_option_keys equal;
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)
equal.emplace_back(opt_key);
}
return equal;
}
std::string ConfigBase::serialize(const t_config_option_key &opt_key) const std::string ConfigBase::serialize(const t_config_option_key &opt_key) const
{ {
const ConfigOption* opt = this->option(opt_key); const ConfigOption* opt = this->option(opt_key);

View file

@ -1046,6 +1046,7 @@ public:
void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false); 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(); } bool equals(const ConfigBase &other) const { return this->diff(other).empty(); }
t_config_option_keys diff(const ConfigBase &other) const; t_config_option_keys 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; 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() // Set a configuration value from a string, it will call an overridable handle_legacy()
// to resolve renamed and removed configuration keys. // to resolve renamed and removed configuration keys.

View file

@ -28,12 +28,15 @@ namespace Slic3r { namespace GUI {
} }
m_Undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); m_Undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG));
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(); }));
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){ /*on_back_to_sys_value()*/; }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ /*on_back_to_initial_value()*/; }));
BUILD(); BUILD();
} }
void Field::set_nonsys_btn_icon(const std::string& icon){
m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(icon)), wxBITMAP_TYPE_PNG));
}
void Field::on_kill_focus(wxEvent& event) { void Field::on_kill_focus(wxEvent& event) {
// Without this, there will be nasty focus bugs on Windows. // Without this, there will be nasty focus bugs on Windows.
// Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all

View file

@ -68,8 +68,8 @@ public:
// This is used to avoid recursive invocation of the field change/update by wxWidgets. // This is used to avoid recursive invocation of the field change/update by wxWidgets.
bool m_disable_change_event {false}; bool m_disable_change_event {false};
// This is used to avoid recursive invocation of the field change/update by wxWidgets.
bool m_is_modified_value {false}; bool m_is_modified_value {false};
bool m_is_nonsys_value;
/// Copy of ConfigOption for deduction purposes /// Copy of ConfigOption for deduction purposes
const ConfigOptionDef m_opt {ConfigOptionDef()}; const ConfigOptionDef m_opt {ConfigOptionDef()};
@ -96,6 +96,9 @@ public:
virtual wxString get_tooltip_text(const wxString& default_string); virtual wxString get_tooltip_text(const wxString& default_string);
// set icon to "UndoToSystemValue" button according to an inheritance of preset
void set_nonsys_btn_icon(const std::string& icon);
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {}; Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {};
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {}; Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {};

View file

@ -518,11 +518,14 @@ wxApp* get_app(){
return g_wxApp; return g_wxApp;
} }
wxColour* get_modified_label_clr() wxColour* get_modified_label_clr(){
{
return new wxColour(253, 88, 0); return new wxColour(253, 88, 0);
} }
wxColour* get_sys_label_clr(){
return new wxColour(26, 132, 57);
}
void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value)
{ {
if (comboCtrl == nullptr) if (comboCtrl == nullptr)

View file

@ -79,6 +79,7 @@ void set_preset_bundle(PresetBundle *preset_bundle);
AppConfig* get_app_config(); AppConfig* get_app_config();
wxApp* get_app(); wxApp* get_app();
wxColour* get_modified_label_clr(); wxColour* get_modified_label_clr();
wxColour* get_sys_label_clr();
void add_debug_menu(wxMenuBar *menu, int event_language_change); void add_debug_menu(wxMenuBar *menu, int event_language_change);

View file

@ -86,6 +86,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
field->m_Undo_btn->Hide(); field->m_Undo_btn->Hide();
field->m_Undo_to_sys_btn->Hide(); field->m_Undo_to_sys_btn->Hide();
} }
if (nonsys_btn_icon != "")
field->set_nonsys_btn_icon(nonsys_btn_icon);
// assign function objects for callbacks, etc. // assign function objects for callbacks, etc.
return field; return field;
@ -115,8 +117,10 @@ void OptionsGroup::append_line(const Line& line) {
const auto& option = option_set.front(); const auto& option = option_set.front();
const auto& field = build_field(option); const auto& field = build_field(option);
sizer->Add(field->m_Undo_to_sys_btn); auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(field->m_Undo_btn); btn_sizer->Add(field->m_Undo_to_sys_btn);
btn_sizer->Add(field->m_Undo_btn);
sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 0);
if (is_window_field(field)) if (is_window_field(field))
sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5); sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
if (is_sizer_field(field)) if (is_sizer_field(field))

View file

@ -83,6 +83,8 @@ public:
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
std::string nonsys_btn_icon = "";
/// Returns a copy of the pointer of the parent wxWindow. /// Returns a copy of the pointer of the parent wxWindow.
/// Accessor function is because users are not allowed to change the parent /// Accessor function is because users are not allowed to change the parent
/// but defining it as const means a lot of const_casts to deal with wx functions. /// but defining it as const means a lot of const_casts to deal with wx functions.

View file

@ -226,7 +226,8 @@ const std::vector<std::string>& Preset::printer_options()
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed", "bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
"octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", "octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "default_print_profile", "inherits", "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "max_print_height",
"default_print_profile", "inherits",
}; };
s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
} }
@ -411,7 +412,7 @@ const Preset* PresetCollection::get_selected_preset_parent() const
{ {
auto *inherits = dynamic_cast<const ConfigOptionString*>(this->get_edited_preset().config.option("inherits")); auto *inherits = dynamic_cast<const ConfigOptionString*>(this->get_edited_preset().config.option("inherits"));
if (inherits == nullptr || inherits->value.empty()) if (inherits == nullptr || inherits->value.empty())
return nullptr; return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; // nullptr;
const Preset* preset = this->find_preset(inherits->value, false); const Preset* preset = this->find_preset(inherits->value, false);
return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset; return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset;
} }
@ -576,6 +577,25 @@ std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, c
return changed; return changed;
} }
std::vector<std::string> PresetCollection::system_equal_options() const
{
const Preset *edited = &this->get_edited_preset();
const Preset *reference = this->get_selected_preset_parent();
std::vector<std::string> equal;
if (edited != nullptr && reference != nullptr) {
equal = reference->config.equal(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.
std::initializer_list<const char*> optional_keys{ "compatible_printers", "compatible_printers_condition" };
for (auto &opt_key : optional_keys) {
if (reference->config.has(opt_key) == edited->config.has(opt_key))
equal.emplace_back(opt_key);
}
}
return equal;
}
// Select a new preset. This resets all the edits done to the currently selected preset. // Select a new preset. This resets all the edits done to the currently selected preset.
// If the preset with index idx does not exist, a first visible preset is selected. // If the preset with index idx does not exist, a first visible preset is selected.
Preset& PresetCollection::select_preset(size_t idx) Preset& PresetCollection::select_preset(size_t idx)

View file

@ -250,6 +250,8 @@ public:
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
std::vector<std::string> current_different_from_parent_options() const std::vector<std::string> current_different_from_parent_options() const
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent()); } { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent()); }
// Compare the content of get_selected_preset() with get_selected_preset_parent() configs, return the list of keys where they equal.
std::vector<std::string> system_equal_options() const;
// Update the choice UI from the list of presets. // Update the choice UI from the list of presets.
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown. // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.

View file

@ -113,6 +113,14 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
update(); update();
} }
void Tab::load_initial_data()
{
m_config = &m_presets->get_edited_preset().config;
m_nonsys_btn_icon = m_presets->get_selected_preset_parent() == nullptr ?
"bullet_white.png" :
wxMSW ? "sys_unlock.png" : "lock_open.png";
}
PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/) PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/)
{ {
// Index of icon in an icon list $self->{icons}. // Index of icon in an icon list $self->{icons}.
@ -186,17 +194,19 @@ void Tab::update_changed_ui()
// Add new dirty options to m_dirty_options // Add new dirty options to m_dirty_options
for (auto opt_key : dirty_options){ for (auto opt_key : dirty_options){
Field* field = get_field(opt_key); Field* field = get_field(opt_key);
if (field != nullptr && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()){ if (field != nullptr &&
if (field->m_Label != nullptr){ find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()){
field->m_Label->SetForegroundColour(*get_modified_label_clr());
field->m_Label->Refresh(true);
}
// use bouth of temporary_icons till don't have "undo_icon" // use bouth of temporary_icons till don't have "undo_icon"
field->m_Undo_btn->SetBitmap(wxBitmap(from_u8(wxMSW ? var("action_undo.png") : var("arrow_undo.png")), wxBITMAP_TYPE_PNG)); field->m_Undo_btn->SetBitmap(wxBitmap(from_u8(wxMSW ? var("action_undo.png") : var("arrow_undo.png")), wxBITMAP_TYPE_PNG));
field->m_is_modified_value = true; field->m_is_modified_value = true;
m_dirty_options.push_back(opt_key); m_dirty_options.push_back(opt_key);
} }
if (field != nullptr && field->m_Label != nullptr){
field->m_Label->SetForegroundColour(*get_modified_label_clr());
field->m_Label->Refresh(true);
}
} }
// Delete clear options from m_dirty_options // Delete clear options from m_dirty_options
@ -219,6 +229,47 @@ void Tab::update_changed_ui()
} }
} }
} }
//update system options (colored in green)
auto sys_options = m_presets->system_equal_options();
// Add new system equal options to m_sys_options
for (auto opt_key : sys_options){
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));
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());
field->m_Label->Refresh(true);
}
}
// 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 (field != nullptr && find(sys_options.begin(), sys_options.end(), opt_key) == sys_options.end())
{
// 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;
}
}
}
} }
// Update the combo box label of the selected preset based on its "dirty" state, // Update the combo box label of the selected preset based on its "dirty" state,
@ -376,7 +427,7 @@ void Tab::reload_compatible_printers_widget()
void TabPrint::build() void TabPrint::build()
{ {
m_presets = &m_preset_bundle->prints; m_presets = &m_preset_bundle->prints;
m_config = &m_presets->get_edited_preset().config; load_initial_data();
auto page = add_options_page(_(L("Layers and perimeters")), "layers.png"); auto page = add_options_page(_(L("Layers and perimeters")), "layers.png");
auto optgroup = page->new_optgroup(_(L("Layer height"))); auto optgroup = page->new_optgroup(_(L("Layer height")));
@ -853,7 +904,7 @@ void TabPrint::OnActivate()
void TabFilament::build() void TabFilament::build()
{ {
m_presets = &m_preset_bundle->filaments; m_presets = &m_preset_bundle->filaments;
m_config = &m_preset_bundle->filaments.get_edited_preset().config; load_initial_data();
auto page = add_options_page(_(L("Filament")), "spool.png"); auto page = add_options_page(_(L("Filament")), "spool.png");
auto optgroup = page->new_optgroup(_(L("Filament"))); auto optgroup = page->new_optgroup(_(L("Filament")));
@ -1000,8 +1051,7 @@ bool Tab::current_preset_is_dirty()
void TabPrinter::build() void TabPrinter::build()
{ {
m_presets = &m_preset_bundle->printers; m_presets = &m_preset_bundle->printers;
m_config = &m_preset_bundle->printers.get_edited_preset().config; load_initial_data();
auto default_config = m_preset_bundle->full_config();
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter")); auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size();
@ -1414,6 +1464,9 @@ void TabPrinter::update(){
void Tab::load_current_preset() void Tab::load_current_preset()
{ {
auto preset = m_presets->get_edited_preset(); auto preset = m_presets->get_edited_preset();
m_nonsys_btn_icon = m_presets->get_selected_preset_parent() == nullptr ?
"bullet_white.png" :
wxMSW ? "sys_unlock.png" : "lock_open.png";
preset.is_default ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true); preset.is_default ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true);
update(); update();
// For the printer profile, generate the extruder pages. // For the printer profile, generate the extruder pages.
@ -1658,6 +1711,8 @@ void Tab::save_preset(std::string name /*= ""*/)
update_tab_ui(); update_tab_ui();
// Update the selection boxes at the platter. // Update the selection boxes at the platter.
on_presets_changed(); on_presets_changed();
update_changed_ui();
} }
// Called for a currently selected preset. // Called for a currently selected preset.
@ -1833,6 +1888,8 @@ ConfigOptionsGroupShp Page::new_optgroup(wxString title, int noncommon_label_wid
return config; return config;
}; };
optgroup->nonsys_btn_icon = static_cast<Tab*>(GetParent())->m_nonsys_btn_icon;
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
m_optgroups.push_back(optgroup); m_optgroups.push_back(optgroup);

View file

@ -100,6 +100,7 @@ protected:
std::vector<std::string> m_reload_dependent_tabs = {}; std::vector<std::string> m_reload_dependent_tabs = {};
std::vector<std::string> m_dirty_options = {}; std::vector<std::string> m_dirty_options = {};
std::vector<std::string> m_sys_options = {};
// The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType. // The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType.
wxEventType m_event_value_change = 0; wxEventType m_event_value_change = 0;
@ -110,6 +111,7 @@ public:
bool m_show_btn_incompatible_presets = false; bool m_show_btn_incompatible_presets = false;
PresetCollection* m_presets; PresetCollection* m_presets;
DynamicPrintConfig* m_config; DynamicPrintConfig* m_config;
std::string m_nonsys_btn_icon;
public: public:
Tab() {} Tab() {}
@ -154,6 +156,7 @@ public:
virtual void on_preset_loaded(){} virtual void on_preset_loaded(){}
virtual void build() = 0; virtual void build() = 0;
virtual void update() = 0; virtual void update() = 0;
void load_initial_data();
void update_dirty(); void update_dirty();
void update_tab_ui(); void update_tab_ui();
void load_config(DynamicPrintConfig config); void load_config(DynamicPrintConfig config);