Shows extruder's values on filament's Setting Overrides tab. (#6370)

# Description
The idea behind this PR is to make it easier for the users to tweak
filament setting overrides i.e. reduce number of times users have to
switch between the printer and filament settings to compare the values.

# Screenshots/Recordings/Graphs

![image](https://github.com/user-attachments/assets/7221883e-74cd-4322-847a-800880e59c4b)

![image](https://github.com/user-attachments/assets/6019a0f4-b824-4a76-82e2-00e54f282c12)


![image](https://github.com/user-attachments/assets/75589d5d-0ba5-4c8c-8cb5-e23e67cd9e52)

![image](https://github.com/user-attachments/assets/b38f5000-20e0-48eb-afef-49787c9fec3b)

## Tests
I've done some manual testing to confirm:
* Override setting with the same value as extruder is still shown as a
change.
* Resetting unsaved override setting back to original value still works
as expected.
* Override settings are shown correctly on the next load after a save.
* Extruder settings changes are reflected on Settings Overrides page.

## Other
I have discovered a strange behaviour between `Filament Settings` and
`Printer Settings` windows. On a fresh load of application opening
`Filament Settings` window, navigating to `Settings Overrides` tab and
then closing the window results in `Filament` tab being opened the next
time `Filament Settings` window is opened. But if you open `Printer
settings` window, navigate to `Extruder` or `Motion ability` tabs then
the application changes the behaviour to open the last visited tab by
the user for both of the windows. I'm mentioning this because when this
happens the flow of events in the application changes and causes my
change to break until the user changes a tab. As far as I can tell for
some reason ConfigOptionsGroup's `reload_config` method is starting to
get called (second time?) after TabFilament's
`update_filament_overrides_page` method which wipes out the values set
by me. I'm not sure which is the correct behaviour, so I left that for a
discussion here. If last visited tab is the correct behaviour, then I
would need help to figure out how to fix this problem.
This commit is contained in:
SoftFever 2024-10-07 21:42:11 +08:00 committed by GitHub
commit 8097becedd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 33 deletions

View File

@ -248,8 +248,6 @@ bool Field::is_matched(const std::string& string, const std::string& pattern)
return std::regex_match(string, regex_pattern);
}
static wxString na_value() { return _(L("N/A")); }
void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true*/)
{
switch (m_opt.type) {
@ -287,7 +285,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
}
double val;
bool is_na_value = m_opt.nullable && str == na_value();
bool is_na_value = m_opt.nullable && str == m_na_value;
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
@ -827,7 +825,6 @@ bool TextCtrl::value_was_changed()
void TextCtrl::propagate_value()
{
if (!is_defined_input_value<wxTextCtrl>(text_ctrl(), m_opt.type)) { // BBS
// on_kill_focus() cause a call of OptionsGroup::reload_config(),
// Thus, do it only when it's really needed (when undefined value was input)
@ -840,11 +837,10 @@ void TextCtrl::propagate_value()
void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) {
m_disable_change_event = !change_event;
if (m_opt.nullable) {
const bool m_is_na_val = boost::any_cast<wxString>(value) == na_value();
if (!m_is_na_val)
if (boost::any_cast<wxString>(value) != _(L("N/A")))
m_last_meaningful_value = value;
text_ctrl()->SetValue(m_is_na_val ? na_value() :
boost::any_cast<wxString>(value)); // BBS
text_ctrl()->SetValue(boost::any_cast<wxString>(value)); // BBS
}
else
text_ctrl()->SetValue(value.empty() ? "" : boost::any_cast<wxString>(value)); // BBS // BBS: null value
@ -866,9 +862,14 @@ void TextCtrl::set_last_meaningful_value()
propagate_value();
}
void TextCtrl::update_na_value(const boost::any& value)
{
m_na_value = boost::any_cast<wxString>(value);
}
void TextCtrl::set_na_value()
{
text_ctrl()->SetValue(na_value()); // BBS
text_ctrl()->SetValue(m_na_value); // BBS
propagate_value();
}
@ -978,10 +979,16 @@ void CheckBox::set_value(const boost::any& value, bool change_event)
{
m_disable_change_event = !change_event;
if (m_opt.nullable) {
m_is_na_val = boost::any_cast<unsigned char>(value) == ConfigOptionBoolsNullable::nil_value();
const bool is_value_unsigned_char = value.type() == typeid(unsigned char);
m_is_na_val = is_value_unsigned_char &&
boost::any_cast<unsigned char>(value) == ConfigOptionBoolsNullable::nil_value();
if (!m_is_na_val)
m_last_meaningful_value = value;
dynamic_cast<::CheckBox*>(window)->SetValue(m_is_na_val ? false : boost::any_cast<unsigned char>(value) != 0); // BBS
m_last_meaningful_value = is_value_unsigned_char ? value : static_cast<unsigned char>(boost::any_cast<bool>(value));
const auto bool_value = is_value_unsigned_char ?
boost::any_cast<unsigned char>(value) != 0 :
boost::any_cast<bool>(value);
dynamic_cast<::CheckBox*>(window)->SetValue(m_is_na_val ? false : bool_value); // BBS
}
else if (!value.empty()) // BBS: null value
dynamic_cast<::CheckBox*>(window)->SetValue(boost::any_cast<bool>(value)); // BBS

View File

@ -10,6 +10,7 @@
#include <cstdint>
#include <functional>
#include <boost/any.hpp>
#include "I18N.hpp"
#include <wx/colourdata.h>
#include <wx/spinctrl.h>
@ -225,6 +226,8 @@ public:
virtual void set_last_meaningful_value() {}
virtual void set_na_value() {}
virtual void update_na_value(const boost::any& value) {}
/// Gets a boost::any representing this control.
/// subclasses should overload with a specific version
virtual boost::any& get_value() = 0;
@ -283,6 +286,7 @@ protected:
bool bEnterPressed = false;
wxString m_na_value = _(L("N/A"));
friend class OptionsGroup;
};
@ -324,6 +328,8 @@ public:
void set_last_meaningful_value() override;
void set_na_value() override;
void update_na_value(const boost::any& value) override;
boost::any& get_value() override;
void msw_rescale() override;

View File

@ -3117,17 +3117,27 @@ void TabFilament::add_filament_overrides_page()
line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) {
wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, "");
check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) {
check_box->Bind(
wxEVT_CHECKBOX,
[this, optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) {
const bool is_checked = evt.IsChecked();
if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) {
if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) {
field->toggle(is_checked);
if (is_checked)
if (is_checked) {
field->update_na_value(_(L("N/A")));
field->set_last_meaningful_value();
else
}
else {
const std::string printer_opt_key = opt_key.substr(strlen("filament_"));
const auto printer_config = m_preset_bundle->printers.get_edited_preset().config;
const boost::any printer_config_value = optgroup_sh->get_config_value(printer_config, printer_opt_key, opt_index);
field->update_na_value(printer_config_value);
field->set_na_value();
}
}
}
}, check_box->GetId());
m_overrides_options[opt_key] = check_box;
@ -3162,7 +3172,7 @@ void TabFilament::add_filament_overrides_page()
append_single_option_line(opt_key, extruder_idx);
}
void TabFilament::update_filament_overrides_page()
void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* printers_config)
{
if (!m_active_page || m_active_page->title() != "Setting Overrides")
return;
@ -3213,21 +3223,29 @@ void TabFilament::update_filament_overrides_page()
m_overrides_options[opt_key]->SetValue(is_checked);
Field* field = optgroup->get_fieldc(opt_key, extruder_idx);
if (field != nullptr) {
if (field == nullptr) continue;
if (opt_key == "filament_long_retractions_when_cut") {
int machine_enabled_level = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionInt>("enable_long_retraction_when_cut")->value;
int machine_enabled_level = printers_config->option<ConfigOptionInt>(
"enable_long_retraction_when_cut")->value;
bool machine_enabled = machine_enabled_level == LongRectrationLevel::EnableFilament;
toggle_line(opt_key, machine_enabled);
field->toggle(is_checked && machine_enabled);
}
else if (opt_key == "filament_retraction_distances_when_cut") {
int machine_enabled_level = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionInt>("enable_long_retraction_when_cut")->value;
} else if (opt_key == "filament_retraction_distances_when_cut") {
int machine_enabled_level = printers_config->option<ConfigOptionInt>(
"enable_long_retraction_when_cut")->value;
bool machine_enabled = machine_enabled_level == LongRectrationLevel::EnableFilament;
bool filament_enabled = m_config->option<ConfigOptionBools>("filament_long_retractions_when_cut")->values[extruder_idx] == 1;
toggle_line(opt_key, filament_enabled && machine_enabled);
field->toggle(is_checked && filament_enabled && machine_enabled);
} else {
if (!is_checked) {
const std::string printer_opt_key = opt_key.substr(strlen("filament_"));
boost::any printer_config_value = optgroup->get_config_value(*printers_config, printer_opt_key, extruder_idx);
field->update_na_value(printer_config_value);
field->set_value(printer_config_value, false);
}
else
field->toggle(is_checked);
}
}
@ -3602,7 +3620,7 @@ void TabFilament::toggle_options()
toggle_line("filament_diameter", !is_pellet_printer);
}
if (m_active_page->title() == L("Setting Overrides"))
update_filament_overrides_page();
update_filament_overrides_page(&cfg);
if (m_active_page->title() == L("Multimaterial")) {
// Orca: hide specific settings for BBL printers

View File

@ -554,7 +554,7 @@ private:
ogStaticText* m_cooling_description_line {nullptr};
void add_filament_overrides_page();
void update_filament_overrides_page();
void update_filament_overrides_page(const DynamicPrintConfig* printers_config);
void update_volumetric_flow_preset_hints();
std::map<std::string, wxCheckBox*> m_overrides_options;