ENH: param tab variant index & extruder switch

Change-Id: Icad6bce3b23ea98d5ef497ceabacc52f294af8f2
(cherry picked from commit 575572f184dc49eb763aa0b27f52f375dcb52f2d)
This commit is contained in:
chunmao.guo 2024-07-01 18:37:46 +08:00 committed by Noisyfox
parent fab6b21e4d
commit f5d2a1bc0c
7 changed files with 158 additions and 71 deletions

View file

@ -693,7 +693,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
auto itOption = it->second;
const std::string &opt_key = itOption.first;
int opt_index = get_extruder_idx(*m_config, itOption.first, itOption.second);
int opt_index = itOption.second;
this->change_opt_value(opt_key, value, opt_index == -1 ? 0 : opt_index);
}
@ -752,7 +752,6 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
auto opt_id = m_opt_map.find(opt_key)->first;
std::string opt_short_key = m_opt_map.at(opt_id).first;
int opt_index = m_opt_map.at(opt_id).second;
opt_index = get_extruder_idx(*m_config, opt_short_key, opt_index);
value = get_config_value(config, opt_short_key, opt_index);
}
@ -783,7 +782,7 @@ void ConfigOptionsGroup::reload_config()
// option key (may be scalar or vector)
const std::string &opt_key = kvp.second.first;
// index in the vector option, zero for scalars
int opt_index = get_extruder_idx(*m_config, kvp.second.first, kvp.second.second);
int opt_index = kvp.second.second;
const ConfigOptionDef &option = m_options.at(opt_id).opt;
this->set_value(opt_id, config_value(opt_key, opt_index, option.gui_flags == "serialized"));
}
@ -1279,9 +1278,6 @@ void ExtruderOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const
const std::string& opt_key = itOption.first;
int opt_index = itOption.second;
if (printer_extruder_options.find(opt_key) == printer_extruder_options.end()) {
opt_index = get_extruder_idx(*m_config, itOption.first, itOption.second);
}
this->change_opt_value(opt_key, value, opt_index == -1 ? 0 : opt_index);
}

View file

@ -13,7 +13,7 @@
#include "Field.hpp"
#include "I18N.hpp"
// Translate the ifdef
// Translate the ifdef
#ifdef __WXOSX__
#define wxOSX true
#else
@ -60,7 +60,7 @@ public:
bool undo_to_sys{false}; // BBS: object config
bool toggle_visible{true}; // BBS: hide some line
size_t full_width {0};
size_t full_width {0};
widget_t widget {nullptr};
std::function<wxWindow*(wxWindow*)> near_label_widget{ nullptr };
wxWindow* near_label_widget_win {nullptr};
@ -125,7 +125,7 @@ public:
std::function<void(wxWindow* win)> rescale_near_label_widget { nullptr };
std::function<void(const t_config_option_key& opt_key)> edit_custom_gcode { nullptr };
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
int sidetext_width{ -1 };
@ -153,7 +153,7 @@ public:
void append_single_option_line(const Option& option, const std::string& path = std::string()) { append_line(create_single_option_line(option, path)); }
void append_separator();
// return a non-owning pointer reference
// return a non-owning pointer reference
inline Field* get_field(const t_config_option_key& id) const{
if (m_fields.find(id) == m_fields.end()) return nullptr;
return m_fields.at(id).get();
@ -165,9 +165,9 @@ public:
return true;
}
boost::any get_value(const t_config_option_key& id) {
boost::any out;
boost::any out;
if (m_fields.find(id) == m_fields.end()) ;
else
else
out = m_fields.at(id)->get_value();
return out;
}
@ -188,14 +188,14 @@ public:
void hide_labels() { label_width = 0; }
OptionsGroup(wxWindow *_parent, const wxString &title, const wxString &icon, bool is_tab_opt = false,
OptionsGroup(wxWindow *_parent, const wxString &title, const wxString &icon, bool is_tab_opt = false,
column_t extra_clmn = nullptr);
~OptionsGroup() { clear(true); }
wxGridSizer* get_grid_sizer() { return m_grid_sizer; }
const std::vector<Line>& get_lines() { return m_lines; }
bool is_legend_line();
// if we have to set the same control alignment for different option groups,
// if we have to set the same control alignment for different option groups,
// we have to set same max contrtol width to all of them
void set_max_win_width(int max_win_width);
@ -210,7 +210,7 @@ protected:
std::vector<Line> m_lines;
/// Field list, contains unique_ptrs of the derived type.
/// using types that need to know what it is beyond the public interface
/// using types that need to know what it is beyond the public interface
/// need to cast based on the related ConfigOptionDef.
t_optionfield_map m_fields;
bool m_disabled {false};
@ -222,7 +222,7 @@ protected:
bool m_use_custom_ctrl_as_parent { false };
// This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox
// Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel
// Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel
// inside it before you insert the other controls.
#if 0//#ifdef__WXGTK__
wxPanel* m_panel {nullptr};
@ -247,13 +247,13 @@ public:
class ConfigOptionsGroup: public OptionsGroup {
public:
ConfigOptionsGroup( wxWindow* parent, const wxString& title, const wxString& icon, DynamicPrintConfig* config = nullptr,
ConfigOptionsGroup( wxWindow* parent, const wxString& title, const wxString& icon, DynamicPrintConfig* config = nullptr,
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
OptionsGroup(parent, title, icon, is_tab_opt, extra_clmn), m_config(config) {}
ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* config = nullptr,
ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* config = nullptr,
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
ConfigOptionsGroup(parent, title, wxEmptyString, config, is_tab_opt, extra_clmn) {}
ConfigOptionsGroup( wxWindow* parent, const wxString& title, ModelConfig* config,
ConfigOptionsGroup( wxWindow* parent, const wxString& title, ModelConfig* config,
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
OptionsGroup(parent, title, wxEmptyString, is_tab_opt, extra_clmn), m_config(&config->get()), m_modelconfig(config) {}
ConfigOptionsGroup( wxWindow* parent) :
@ -264,7 +264,7 @@ public:
const t_opt_map& opt_map() const throw() { return m_opt_map; }
void set_config_category_and_type(const wxString &category, int type) { m_config_category = category; m_config_type = type; }
void set_config(DynamicPrintConfig* config) {
void set_config(DynamicPrintConfig* config) {
m_config = config; m_modelconfig = nullptr; }
Option get_option(const std::string& opt_key, int opt_index = -1);
Line create_single_option_line(const std::string& title, const std::string& path = std::string(), int idx = -1) /*const*/{
@ -282,7 +282,7 @@ public:
Option option = get_option(title, idx);
append_single_option_line(option, path);
}
void on_change_OG(const t_config_option_key& opt_id, const boost::any& value) override;
void back_to_initial_value(const std::string& opt_key) override;
void back_to_sys_value(const std::string& opt_key) override;
@ -298,7 +298,7 @@ public:
void sys_color_changed();
void refresh();
boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
// return option value from config
// return option value from config
boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);
// BBS: restore all pages in preset
boost::any get_config_value2(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);

View file

@ -1620,6 +1620,8 @@ void Sidebar::msw_rescale()
//BBS
p->m_bed_type_list->Rescale();
p->m_bed_type_list->SetMinSize({-1, 3 * wxGetApp().em_unit()});
p->m_left_extruder_list->Rescale();
p->m_right_extruder_list->Rescale();
#if 0
if (p->mode_sizer)
p->mode_sizer->msw_rescale();
@ -1682,9 +1684,10 @@ void Sidebar::sys_color_changed()
// wxGetApp().UpdateDarkUI(btn, true);
p->m_printer_icon->msw_rescale();
p->m_printer_setting->msw_rescale();
p->m_printer_setting->msw_rescale();
p->m_filament_icon->msw_rescale();
p->m_bpButton_add_filament->msw_rescale();
p->m_bpButton_del_filament->msw_rescale();
//p->m_bpButton_del_filament->msw_rescale();
p->m_bpButton_ams_filament->msw_rescale();
p->m_bpButton_set_filament->msw_rescale();
p->m_flushing_volume_btn->Rescale();
@ -1958,7 +1961,7 @@ std::map<int, DynamicPrintConfig> Sidebar::build_filament_ams_list(MachineObject
int extruder = /*ams.nozzle ? 0 :*/ 0x10000;
for (auto tray : ams.second->trayList) {
char t = tray.first.front() - '0' + '1';
filament_ams_list.emplace(extruder + ((n - 'A') * 4 + t - '1'),
filament_ams_list.emplace(extruder + ((n - 'A') * 4 + t - '1'),
build_tray_config(*tray.second, std::string(1, n) + std::string(1, t)));
extruder = 0;
}

View file

@ -495,7 +495,19 @@ void Tab::create_preset_tab()
m_tabctrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
m_main_sizer->Add(m_tabctrl, 1, wxEXPAND | wxALL, 0 );
m_main_sizer->Add(m_tabctrl, 0, wxEXPAND | wxALL, 0 );
if (dynamic_cast<TabPrint *>(this)) {
m_extruder_switch = new SwitchButton(panel);
m_extruder_switch->SetMaxSize({em_unit(this) * 24, -1});
m_extruder_switch->SetLabels(_L("Left"), _L("Right"));
m_extruder_switch->Bind(wxEVT_TOGGLEBUTTON, [this] (auto & evt) {
evt.Skip();
dynamic_cast<TabPrint *>(this)->switch_excluder(evt.GetInt());
reload_config();
});
m_main_sizer->Add(m_extruder_switch, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 4);
}
this->SetSizer(m_main_sizer);
//this->Layout();
@ -859,44 +871,21 @@ void Tab::decorate()
m_active_page->refresh();
}
std::vector<std::string> Tab::filter_diff_option(const std::vector<std::string> &options)
void Tab::filter_diff_option(std::vector<std::string> &options)
{
auto get_name_and_index = [](const std::string& value) -> std::pair<std::string, int>{
size_t pos = value.find("#");
if (pos != std::string::npos) {
std::string param_name = value.substr(0, pos);
std::string number_str = value.substr(pos + 1);
int index = 0;
if (!number_str.empty()) {
index = std::stoi(number_str);
for (auto &opt : options) {
if (opt.find_last_of('#') == std::string::npos) continue;
bool found = false;
for (auto page : m_pages) {
if (auto iter = page->m_opt_id_map.find(opt); iter != page->m_opt_id_map.end()) {
opt = iter->second;
found = true;
break;
}
return std::make_pair(param_name, index);
}
return std::make_pair(value, -1);
};
std::vector<std::string> diff_options;
for (std::string option : options) {
auto name_to_index = get_name_and_index(option);
if (name_to_index.second == -1) {
diff_options.emplace_back(option);
continue;
}
size_t nozzle_nums = wxGetApp().preset_bundle->get_printer_extruder_count();
std::vector<int> support_indexes;
for (size_t i = 0; i < nozzle_nums; ++i) {
support_indexes.push_back(get_extruder_idx(*m_config, name_to_index.first, i));
}
auto iter = std::find(support_indexes.begin(), support_indexes.end(), name_to_index.second);
if (iter != support_indexes.end()) {
int extruder_id = std::distance(support_indexes.begin(), iter);
std::string name_to_extruder_id = name_to_index.first + "#" + std::to_string(extruder_id);
diff_options.emplace_back(name_to_extruder_id);
}
if (!found) opt.clear();
}
return diff_options;
options.erase(std::remove(options.begin(), options.end(), ""), options.end());
}
// Update UI according to changes
@ -919,8 +908,8 @@ void Tab::update_changed_ui()
for (auto& it : m_options_list)
it.second = m_opt_status_value;
dirty_options = filter_diff_option(dirty_options);
nonsys_options = filter_diff_option(nonsys_options);
filter_diff_option(dirty_options);
filter_diff_option(nonsys_options);
for (auto opt_key : dirty_options) {
m_options_list[opt_key] &= ~osInitValue;
@ -1091,7 +1080,7 @@ void Tab::update_changed_tree_ui()
if (!sys_page && modified_page)
break;
for (const auto &kvp : group->opt_map()) {
const std::string& opt_key = kvp.first;
const std::string &opt_key = kvp.first;
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
}
}
@ -1170,7 +1159,7 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
}
}
for (const auto &kvp : group->opt_map()) {
const std::string& opt_key = kvp.first;
const std::string &opt_key = kvp.first;
if ((m_options_list[opt_key] & os) == 0)
to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key);
}
@ -1779,6 +1768,18 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
m_config_manipulation.apply(m_config, &new_conf);
}
if (opt_key.find_first_of("nozzle_volume_type") != std::string::npos) {
int extruder_idx = std::atoi(opt_key.substr(opt_key.find_last_of('#') + 1).c_str());
for (auto tab : wxGetApp().tabs_list) {
tab->update_extruder_variants(extruder_idx);
tab->reload_config();
}
for (auto tab : wxGetApp().model_tabs_list) {
tab->update_extruder_variants(extruder_idx);
tab->reload_config();
}
}
if (m_postpone_update_ui) {
// It means that not all values are rolled to the system/last saved values jet.
// And call of the update() can causes a redundant check of the config values,
@ -2659,7 +2660,6 @@ void TabPrint::clear_pages()
m_top_bottom_shell_thickness_explanation = nullptr;
}
//BBS: GUI refactor
static std::vector<std::string> intersect(std::vector<std::string> const& l, std::vector<std::string> const& r)
@ -4514,6 +4514,7 @@ if (is_marlin_flavor)
load_config(new_conf);
}
}
update_dirty();
on_value_change(opt_key, value);
update();
@ -4889,6 +4890,7 @@ void Tab::load_current_preset()
}
// Reload preset pages with the new configuration values.
update_extruder_variants();
reload_config();
update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent());
@ -5630,6 +5632,8 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event)
return false;
m_active_page = page;
if (m_extruder_switch)
GetSizer()->Show(m_extruder_switch, !m_active_page->m_opt_id_map.empty());
auto throw_if_canceled = std::function<void()>([this](){
#ifdef WIN32
@ -6164,6 +6168,7 @@ void TabPrinter::set_extruder_volume_type(int extruder_id, NozzleVolumeType type
auto nozzle_volumes = m_config->option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
assert(nozzle_volumes->values.size() > (size_t)extruder_id);
nozzle_volumes->values[extruder_id] = type;
on_value_change((boost::format("nozzle_volume_type#%1%") % extruder_id).str(), int(type));
}
// Return a callback to create a TabPrinter widget to edit bed shape
@ -6272,6 +6277,88 @@ void Tab::set_just_edit(bool just_edit)
}
}
/// <summary>
/// Call from:
/// 1: on_value_change "nozzle_volume_type"
/// 2: on_preset_loaded (extruder_id = -1)
/// </summary>
/// <param name="extruder_id"></param>
void Tab::update_extruder_variants(int extruder_id)
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << extruder_id;
if (m_extruder_switch) {
Preset &printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
auto nozzle_volumes = printer_preset.config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
if (nozzle_volumes->size() == 2) {
auto nozzle_volumes_def = printer_preset.config.def()->get("nozzle_volume_type");
wxString left, right;
for (size_t i = 0; i < nozzle_volumes_def->enum_labels.size(); ++i) {
if (nozzle_volumes->values[0] == i) left = _L(nozzle_volumes_def->enum_labels[i]);
if (nozzle_volumes->values[1] == i) right = _L(nozzle_volumes_def->enum_labels[i]);
}
m_extruder_switch->SetLabels(wxString::Format(_L("Left: %s"), left), wxString::Format(_L("Right: %s"), right));
m_extruder_switch->SetValue(extruder_id == 1);
} else {
GetSizer()->Show(m_extruder_switch, false);
return;
}
}
switch_excluder(extruder_id);
if (m_extruder_switch)
GetSizer()->Show(m_extruder_switch, m_active_page && !m_active_page->m_opt_id_map.empty());
}
void Tab::switch_excluder(int extruder_id)
{
Preset & printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
auto nozzle_volumes = printer_preset.config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
auto extruders = printer_preset.config.option<ConfigOptionEnumsGeneric>("extruder_type");
std::pair<std::string, std::string> variant_keys[]{
{}, {"print_extruder_id", "print_extruder_variant"}, // Preset::TYPE_PRINT
{}, {"", "filament_extruder_variant"}, // Preset::TYPE_FILAMENT filament don't use id anymore
{}, {"printer_extruder_id", "printer_extruder_variant"}, // Preset::TYPE_PRINTER
};
if (m_extruder_switch) {
int current_extruder = m_extruder_switch->GetValue() ? 1 : 0;
if (extruder_id == -1)
extruder_id = current_extruder;
else if (extruder_id != current_extruder)
return;
}
auto get_index_for_extruder =
[this, &extruders, &nozzle_volumes, variant_keys = variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type]](int extruder_id) {
return m_config->get_index_for_extruder(extruder_id + 1, variant_keys.first,
ExtruderType(extruders->values[extruder_id]), NozzleVolumeType(nozzle_volumes->values[extruder_id]), variant_keys.second);
};
auto index = get_index_for_extruder(extruder_id == -1 ? 0 : extruder_id);
for (auto page : m_pages) {
bool is_extruder = false;
page->m_opt_id_map.clear();
if (m_extruder_switch == nullptr && page->title().StartsWith("Extruder ")) {
int extruder_id2 = std::atoi(page->title().Mid(9).ToUTF8()) - 1;
if (extruder_id >= 0 && extruder_id2 != extruder_id)
continue;
if (extruder_id2 > 0)
index = get_index_for_extruder(extruder_id2);
is_extruder = true;
}
for (auto group : page->m_optgroups) {
if (is_extruder && group->title == "Type") {
for (auto &opt : group->opt_map())
page->m_opt_id_map.insert({opt.first, opt.first});
continue;
}
for (auto &opt : group->opt_map()) {
if (opt.second.second >= 0) {
const_cast<int &>(opt.second.second) = index;
page->m_opt_id_map.insert({opt.second.first + "#" + std::to_string(index), opt.first});
}
}
}
}
}
void Tab::compatible_widget_reload(PresetDependencies &deps)
{
Field* field = this->get_field(deps.key_condition);

View file

@ -115,6 +115,8 @@ public:
}
bool get_show() const { return m_show; }
std::map<std::string, std::string> m_opt_id_map;
protected:
// Color of TreeCtrlItem. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
const wxColour* m_item_color;
@ -300,7 +302,8 @@ public:
// 3. propagate changed configuration to the Plater when (m_update_cnt == 0) only
int m_update_cnt = 0;
SwitchButton * m_mode_view = nullptr;
SwitchButton *m_mode_view = nullptr;
SwitchButton *m_extruder_switch = nullptr;
public:
// BBS
@ -420,6 +423,9 @@ public:
virtual const std::string& get_custom_gcode(const t_config_option_key& opt_key);
virtual void set_custom_gcode(const t_config_option_key& opt_key, const std::string& value);
void update_extruder_variants(int extruder_id = -1);
void switch_excluder(int extruder_id = -1);
protected:
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget);
wxSizer* compatible_widget_create(wxWindow* parent, PresetDependencies &deps);
@ -434,7 +440,7 @@ protected:
void update_preset_description_line();
void update_frequently_changed_parameters();
void set_tooltips_text();
std::vector<std::string> filter_diff_option(const std::vector<std::string> &options);
void filter_diff_option(std::vector<std::string> &options);
ConfigManipulation m_config_manipulation;
ConfigManipulation get_config_manipulation();

View file

@ -159,7 +159,6 @@ int ComboBox::Append(const wxString &item,
tips.push_back(wxString{});
icons.push_back(bitmap);
datas.push_back(clientData);
types.push_back(wxClientData_None);
SetClientDataType(wxClientData_Void);
drop.Invalidate();
return texts.size() - 1;
@ -172,7 +171,6 @@ void ComboBox::DoClear()
tips.clear();
icons.clear();
datas.clear();
types.clear();
drop.Invalidate(true);
}
@ -183,7 +181,6 @@ void ComboBox::DoDeleteOneItem(unsigned int pos)
tips.erase(tips.begin() + pos);
icons.erase(icons.begin() + pos);
datas.erase(datas.begin() + pos);
types.erase(types.begin() + pos);
drop.Invalidate(true);
}
@ -234,7 +231,6 @@ int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
tips.insert(tips.begin() + pos, wxString{});
icons.insert(icons.begin() + pos, wxNullBitmap);
datas.insert(datas.begin() + pos, clientData ? clientData[i] : NULL);
types.insert(types.begin() + pos, type);
++pos;
}
drop.Invalidate(true);

View file

@ -13,7 +13,6 @@ class ComboBox : public wxWindowWithItems<TextInput, wxItemContainer>
std::vector<wxString> tips;
std::vector<wxBitmap> icons;
std::vector<void *> datas;
std::vector<wxClientDataType> types;
DropDown drop;
bool drop_down = false;