Fixed memory leaks on switch between parameter pages

This commit is contained in:
YuSanka 2022-12-07 16:52:52 +01:00
parent d2c8d628b9
commit 71a0b626a9
5 changed files with 78 additions and 66 deletions

View File

@ -1416,6 +1416,15 @@ void ColourPicker::sys_color_changed()
#endif #endif
} }
PointCtrl::~PointCtrl()
{
if (sizer) {
sizer->Clear();
delete sizer;
sizer = nullptr;
}
}
void PointCtrl::BUILD() void PointCtrl::BUILD()
{ {
auto temp = new wxBoxSizer(wxHORIZONTAL); auto temp = new wxBoxSizer(wxHORIZONTAL);

View File

@ -425,7 +425,7 @@ class PointCtrl : public Field {
public: public:
PointCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} PointCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
PointCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} PointCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~PointCtrl() {} ~PointCtrl();
wxSizer* sizer{ nullptr }; wxSizer* sizer{ nullptr };
wxTextCtrl* x_textctrl{ nullptr }; wxTextCtrl* x_textctrl{ nullptr };

View File

@ -118,6 +118,24 @@ OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title,
{ {
} }
void Line::clear()
{
if (near_label_widget_win)
near_label_widget_win = nullptr;
if (widget_sizer) {
widget_sizer->Clear(true);
delete widget_sizer;
widget_sizer = nullptr;
}
if (extra_widget_sizer) {
extra_widget_sizer->Clear(true);
delete extra_widget_sizer;
extra_widget_sizer = nullptr;
}
}
wxWindow* OptionsGroup::ctrl_parent() const wxWindow* OptionsGroup::ctrl_parent() const
{ {
return this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast<wxWindow*>(this->custom_ctrl) : (this->stb ? static_cast<wxWindow*>(this->stb) : this->parent()); return this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast<wxWindow*>(this->custom_ctrl) : (this->stb ? static_cast<wxWindow*>(this->stb) : this->parent());
@ -231,7 +249,7 @@ void OptionsGroup::activate_line(Line& line)
} }
} }
auto option_set = line.get_options(); const std::vector<Option>& option_set = line.get_options();
bool is_legend_line = option_set.front().opt.gui_type == ConfigOptionDef::GUIType::legend; bool is_legend_line = option_set.front().opt.gui_type == ConfigOptionDef::GUIType::legend;
if (!custom_ctrl && m_use_custom_ctrl) { if (!custom_ctrl && m_use_custom_ctrl) {
@ -263,15 +281,13 @@ void OptionsGroup::activate_line(Line& line)
return; return;
} }
auto grid_sizer = m_grid_sizer;
if (custom_ctrl) if (custom_ctrl)
m_use_custom_ctrl_as_parent = true; m_use_custom_ctrl_as_parent = true;
// if we have an extra column, build it // if we have an extra column, build it
if (extra_column) { if (extra_column) {
m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line)); m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line));
grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3); m_grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3);
} }
// Build a label if we have it // Build a label if we have it
@ -298,12 +314,12 @@ void OptionsGroup::activate_line(Line& line)
label->Wrap(label_width * wxGetApp().em_unit()); // avoid a Linux/GTK bug label->Wrap(label_width * wxGetApp().em_unit()); // avoid a Linux/GTK bug
} }
if (!line.near_label_widget) if (!line.near_label_widget)
grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); m_grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5);
else if (!line.label.IsEmpty()) { else if (!line.label.IsEmpty()) {
// If we're here, we have some widget near the label // If we're here, we have some widget near the label
// so we need a horizontal sizer to arrange these things // so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); m_grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
} }
if (label != nullptr && line.label_tooltip != "") if (label != nullptr && line.label_tooltip != "")
@ -317,15 +333,19 @@ void OptionsGroup::activate_line(Line& line)
if (custom_ctrl) if (custom_ctrl)
line.widget_sizer = wgt; line.widget_sizer = wgt;
else else
grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5); m_grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5);
return; return;
} }
// If we're here, we have more than one option or a single option with sidetext // If we're here, we have more than one option or a single option with sidetext
// so we need a horizontal sizer to arrange these things // so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* h_sizer{ nullptr };
if (!custom_ctrl) if (!custom_ctrl) {
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); // but this sizer is currently used just for NON-custom_ctrl cases
h_sizer = new wxBoxSizer(wxHORIZONTAL);
m_grid_sizer->Add(h_sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
}
// If we have a single option with no sidetext just add it directly to the grid sizer // If we have a single option with no sidetext just add it directly to the grid sizer
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) {
@ -334,42 +354,37 @@ void OptionsGroup::activate_line(Line& line)
if (!custom_ctrl) { if (!custom_ctrl) {
if (is_window_field(field)) if (is_window_field(field))
sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, h_sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0,
wxBOTTOM | wxTOP | (option.opt.full_width ? int(wxEXPAND) : int(wxALIGN_CENTER_VERTICAL)), (wxOSX || !staticbox) ? 0 : 2); wxBOTTOM | wxTOP | (option.opt.full_width ? int(wxEXPAND) : int(wxALIGN_CENTER_VERTICAL)), (wxOSX || !staticbox) ? 0 : 2);
if (is_sizer_field(field)) if (is_sizer_field(field))
sizer->Add(field->getSizer(), 1, (option.opt.full_width ? int(wxEXPAND) : int(wxALIGN_CENTER_VERTICAL)), 0); h_sizer->Add(field->getSizer(), 1, (option.opt.full_width ? int(wxEXPAND) : int(wxALIGN_CENTER_VERTICAL)), 0);
} else }
delete sizer;
return; return;
} }
bool sizer_is_used = false; for (const Option& opt : option_set) {
bool is_multioption_line = option_set.size() > 1; // add field
for (auto opt : option_set) { auto& field = build_field(opt);
ConfigOptionDef option = opt.opt;
wxSizer* sizer_tmp = sizer;
// add label if any
if ((is_multioption_line || line.label.IsEmpty()) && !option.label.empty() && !custom_ctrl) {
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ?
_CTX(option.label, "Layers") :
_(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);
wxSize(sublabel_width != -1 ? sublabel_width * wxGetApp().em_unit() : -1, -1), wxALIGN_RIGHT);
label->SetBackgroundStyle(wxBG_STYLE_PAINT);
label->SetFont(wxGetApp().normal_font());
sizer_tmp->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0);
sizer_is_used = true;
}
// add field
const Option& opt_ref = opt;
auto& field = build_field(opt_ref);
if (!custom_ctrl) { if (!custom_ctrl) {
ConfigOptionDef option = opt.opt;
// add label if any
if ((option_set.size() > 1 || line.label.IsEmpty()) && !option.label.empty()) {
// To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ?
_CTX(option.label, "Layers") :
_(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);
wxSize(sublabel_width != -1 ? sublabel_width * wxGetApp().em_unit() : -1, -1), wxALIGN_RIGHT);
label->SetBackgroundStyle(wxBG_STYLE_PAINT);
label->SetFont(wxGetApp().normal_font());
h_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0);
}
if (option_set.size() == 1 && option_set.front().opt.full_width) if (option_set.size() == 1 && option_set.front().opt.full_width)
{ {
const auto v_sizer = new wxBoxSizer(wxVERTICAL); const auto v_sizer = new wxBoxSizer(wxVERTICAL);
sizer_tmp->Add(v_sizer, 1, wxEXPAND); h_sizer->Add(v_sizer, 1, wxEXPAND);
is_sizer_field(field) ? is_sizer_field(field) ?
v_sizer->Add(field->getSizer(), 0, wxEXPAND) : v_sizer->Add(field->getSizer(), 0, wxEXPAND) :
v_sizer->Add(field->getWindow(), 0, wxEXPAND); v_sizer->Add(field->getWindow(), 0, wxEXPAND);
@ -377,8 +392,8 @@ void OptionsGroup::activate_line(Line& line)
} }
is_sizer_field(field) ? is_sizer_field(field) ?
sizer_tmp->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) : h_sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
sizer_tmp->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0); h_sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
// add sidetext if any // add sidetext if any
if (!option.sidetext.empty() || sidetext_width > 0) { if (!option.sidetext.empty() || sidetext_width > 0) {
@ -386,38 +401,35 @@ void OptionsGroup::activate_line(Line& line)
wxSize(sidetext_width != -1 ? sidetext_width * wxGetApp().em_unit() : -1, -1), wxALIGN_LEFT); wxSize(sidetext_width != -1 ? sidetext_width * wxGetApp().em_unit() : -1, -1), wxALIGN_LEFT);
sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT);
sidetext->SetFont(wxGetApp().normal_font()); sidetext->SetFont(wxGetApp().normal_font());
sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); h_sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
} }
// add side widget if any // add side widget if any
if (opt.side_widget != nullptr) { if (opt.side_widget != nullptr) {
sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification h_sizer->Add(opt.side_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
} }
if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back()) if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
sizer_tmp->AddSpacer(6); h_sizer->AddSpacer(6);
} }
} }
// add extra sizers if any // add extra sizers if any
for (auto extra_widget : line.get_extra_widgets()) for (auto extra_widget : line.get_extra_widgets())
{ {
if (line.get_extra_widgets().size() == 1 && !staticbox) if (line.get_extra_widgets().size() == 1 && !staticbox)
{ {
// extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT // extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT
const auto v_sizer = new wxBoxSizer(wxVERTICAL); const auto v_sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(v_sizer, option_set.size() == 1 ? 0 : 1, wxEXPAND); h_sizer->Add(v_sizer, option_set.size() == 1 ? 0 : 1, wxEXPAND);
v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT); v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT);
return; return;
} }
line.extra_widget_sizer = extra_widget(this->ctrl_parent()); line.extra_widget_sizer = extra_widget(this->ctrl_parent());
if (!custom_ctrl) if (!custom_ctrl)
sizer->Add(line.extra_widget_sizer, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification h_sizer->Add(line.extra_widget_sizer, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification
} }
if (custom_ctrl && !sizer_is_used)
delete sizer;
} }
// create all controls for the option group from the m_lines // create all controls for the option group from the m_lines
@ -484,20 +496,8 @@ void OptionsGroup::clear(bool destroy_custom_ctrl)
m_grid_sizer = nullptr; m_grid_sizer = nullptr;
sizer = nullptr; sizer = nullptr;
for (Line& line : m_lines) { for (Line& line : m_lines)
if (line.near_label_widget_win) line.clear();
line.near_label_widget_win = nullptr;
if (line.widget_sizer) {
line.widget_sizer->Clear(true);
line.widget_sizer = nullptr;
}
if (line.extra_widget_sizer) {
line.extra_widget_sizer->Clear(true);
line.extra_widget_sizer = nullptr;
}
}
if (custom_ctrl) { if (custom_ctrl) {
for (auto const &item : m_fields) { for (auto const &item : m_fields) {

View File

@ -86,6 +86,7 @@ public:
bool is_separator() const { return m_is_separator; } bool is_separator() const { return m_is_separator; }
bool has_only_option(const std::string& opt_key) const { return m_options.size() == 1 && m_options[0].opt_id == opt_key; } bool has_only_option(const std::string& opt_key) const { return m_options.size() == 1 && m_options[0].opt_id == opt_key; }
void clear();
const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;} const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;}
const std::vector<Option>& get_options() const { return m_options; } const std::vector<Option>& get_options() const { return m_options; }

View File

@ -1784,6 +1784,8 @@ void TabPrint::clear_pages()
m_recommended_thin_wall_thickness_description_line = nullptr; m_recommended_thin_wall_thickness_description_line = nullptr;
m_top_bottom_shell_thickness_explanation = nullptr; m_top_bottom_shell_thickness_explanation = nullptr;
m_post_process_explanation = nullptr; m_post_process_explanation = nullptr;
m_del_all_substitutions_btn = nullptr;
} }
bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode) bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode)