Add back control pool
This commit is contained in:
parent
0b9a6b5fe4
commit
1ff70be243
7 changed files with 162 additions and 27 deletions
|
@ -111,11 +111,6 @@ Field::~Field()
|
||||||
m_back_to_initial_value = nullptr;
|
m_back_to_initial_value = nullptr;
|
||||||
if (m_back_to_sys_value)
|
if (m_back_to_sys_value)
|
||||||
m_back_to_sys_value = nullptr;
|
m_back_to_sys_value = nullptr;
|
||||||
if (getWindow()) {
|
|
||||||
wxWindow* win = getWindow();
|
|
||||||
win->Destroy();
|
|
||||||
win = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Field::PostInitialize()
|
void Field::PostInitialize()
|
||||||
|
@ -181,7 +176,7 @@ void Field::PostInitialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
});
|
}, getWindow()->GetId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +546,105 @@ void Field::sys_color_changed()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::deque<wxWindow *>**> spools;
|
||||||
|
std::vector<std::deque<wxWindow *>*> spools2;
|
||||||
|
|
||||||
|
void switch_window_pools()
|
||||||
|
{
|
||||||
|
for (auto p : spools) {
|
||||||
|
spools2.push_back(*p);
|
||||||
|
*p = new std::deque<wxWindow*>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_window_pools()
|
||||||
|
{
|
||||||
|
for (auto p : spools2) {
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
spools2.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Builder
|
||||||
|
{
|
||||||
|
Builder()
|
||||||
|
{
|
||||||
|
pool_ = new std::deque<wxWindow*>;
|
||||||
|
spools.push_back(&pool_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
T *build(wxWindow * p, Args ...args)
|
||||||
|
{
|
||||||
|
if (pool_->empty()) {
|
||||||
|
auto t = new T(p, args...);
|
||||||
|
t->SetClientData(pool_);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
auto t = dynamic_cast<T*>(pool_->front());
|
||||||
|
pool_->pop_front();
|
||||||
|
t->Reparent(p);
|
||||||
|
t->Enable();
|
||||||
|
t->Show();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
std::deque<wxWindow*>* pool_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wxEventFunctorRef
|
||||||
|
{
|
||||||
|
wxEventFunctor * func;
|
||||||
|
};
|
||||||
|
|
||||||
|
wxEventFunctor & wxMakeEventFunctor(const int, wxEventFunctorRef func)
|
||||||
|
{
|
||||||
|
return *func.func;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct myEvtHandler : wxEvtHandler
|
||||||
|
{
|
||||||
|
void UnbindAll()
|
||||||
|
{
|
||||||
|
size_t cookie;
|
||||||
|
for (wxDynamicEventTableEntry *entry = GetFirstDynamicEntry(cookie);
|
||||||
|
entry;
|
||||||
|
entry = GetNextDynamicEntry(cookie)) {
|
||||||
|
// In Field, All Bind has id, but for TextInput, ComboBox, SpinInput, all not
|
||||||
|
if (entry->m_id != wxID_ANY && entry->m_lastId == wxID_ANY)
|
||||||
|
Unbind(entry->m_eventType,
|
||||||
|
wxEventFunctorRef{entry->m_fn},
|
||||||
|
entry->m_id,
|
||||||
|
entry->m_lastId,
|
||||||
|
entry->m_callbackUserData);
|
||||||
|
//DoUnbind(entry->m_id, entry->m_lastId, entry->m_eventType, *entry->m_fn, entry->m_callbackUserData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void unbind_events(wxEvtHandler *h)
|
||||||
|
{
|
||||||
|
static_cast<myEvtHandler *>(h)->UnbindAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_window(wxWindow *win)
|
||||||
|
{
|
||||||
|
#if !defined(__WXGTK__)
|
||||||
|
unbind_events(win);
|
||||||
|
for (auto c : win->GetChildren())
|
||||||
|
if (dynamic_cast<wxTextCtrl*>(c))
|
||||||
|
unbind_events(c);
|
||||||
|
win->Hide();
|
||||||
|
if (auto sizer = win->GetContainingSizer())
|
||||||
|
sizer->Clear();
|
||||||
|
win->Reparent(wxGetApp().mainframe);
|
||||||
|
if (win->GetClientData())
|
||||||
|
reinterpret_cast<std::deque<wxWindow *>*>(win->GetClientData())->push_back(win);
|
||||||
|
#else
|
||||||
|
delete win;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type)
|
bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type)
|
||||||
{
|
{
|
||||||
|
@ -615,10 +709,15 @@ void TextCtrl::BUILD() {
|
||||||
|
|
||||||
// BBS: new param ui style
|
// BBS: new param ui style
|
||||||
// const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
|
// const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
|
||||||
|
static Builder<wxTextCtrl> builder1;
|
||||||
|
static Builder<::TextInput> builder2;
|
||||||
auto temp = m_opt.multiline
|
auto temp = m_opt.multiline
|
||||||
? (wxWindow *) new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, wxTE_MULTILINE)
|
? (wxWindow*)builder1.build(m_parent, wxID_ANY, "", wxDefaultPosition, size, wxTE_MULTILINE)
|
||||||
: new ::TextInput(m_parent, text_value, _L(m_opt.sidetext), "", wxDefaultPosition, size, wxTE_PROCESS_ENTER);
|
: builder2.build(m_parent, "", "", "", wxDefaultPosition, size, wxTE_PROCESS_ENTER);
|
||||||
|
temp->SetLabel(_L(m_opt.sidetext));
|
||||||
auto text_ctrl = m_opt.multiline ? (wxTextCtrl *)temp : ((TextInput *) temp)->GetTextCtrl();
|
auto text_ctrl = m_opt.multiline ? (wxTextCtrl *)temp : ((TextInput *) temp)->GetTextCtrl();
|
||||||
|
text_ctrl->SetLabel(text_value);
|
||||||
|
temp->SetSize(size);
|
||||||
m_combine_side_text = !m_opt.multiline;
|
m_combine_side_text = !m_opt.multiline;
|
||||||
if (parent_is_custom_ctrl && m_opt.height < 0)
|
if (parent_is_custom_ctrl && m_opt.height < 0)
|
||||||
opt_height = (double) text_ctrl->GetSize().GetHeight() / m_em_unit;
|
opt_height = (double) text_ctrl->GetSize().GetHeight() / m_em_unit;
|
||||||
|
@ -850,7 +949,8 @@ void CheckBox::BUILD() {
|
||||||
m_last_meaningful_value = static_cast<unsigned char>(check_value);
|
m_last_meaningful_value = static_cast<unsigned char>(check_value);
|
||||||
|
|
||||||
// BBS: use ::CheckBox
|
// BBS: use ::CheckBox
|
||||||
auto temp = new ::CheckBox(m_parent);
|
static Builder<::CheckBox> builder;
|
||||||
|
auto temp = builder.build(m_parent);
|
||||||
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||||
//temp->SetBackgroundColour(*wxWHITE);
|
//temp->SetBackgroundColour(*wxWHITE);
|
||||||
temp->SetValue(check_value);
|
temp->SetValue(check_value);
|
||||||
|
@ -969,8 +1069,14 @@ void SpinCtrl::BUILD() {
|
||||||
? 0 : m_opt.min;
|
? 0 : m_opt.min;
|
||||||
const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647;
|
const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647;
|
||||||
|
|
||||||
auto temp = new SpinInput(m_parent, text_value, _L(m_opt.sidetext), wxDefaultPosition, size,
|
static Builder<SpinInput> builder;
|
||||||
wxSP_ARROW_KEYS, min_val, max_val, default_value);
|
auto temp = builder.build(m_parent, "", "", wxDefaultPosition, size,
|
||||||
|
wxSP_ARROW_KEYS);
|
||||||
|
temp->SetSize(size);
|
||||||
|
temp->SetLabel(_L(m_opt.sidetext));
|
||||||
|
temp->GetTextCtrl()->SetLabel(text_value);
|
||||||
|
temp->SetRange(min_val, max_val);
|
||||||
|
temp->SetValue(default_value);
|
||||||
m_combine_side_text = true;
|
m_combine_side_text = true;
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
wxSize best_sz = temp->GetBestSize();
|
wxSize best_sz = temp->GetBestSize();
|
||||||
|
@ -993,7 +1099,7 @@ void SpinCtrl::BUILD() {
|
||||||
}
|
}
|
||||||
|
|
||||||
propagate_value();
|
propagate_value();
|
||||||
}));
|
}), temp->GetId());
|
||||||
|
|
||||||
temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId());
|
temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId());
|
||||||
|
|
||||||
|
@ -1152,7 +1258,8 @@ void Choice::BUILD()
|
||||||
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open
|
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open
|
||||||
&& m_list == nullptr) {
|
&& m_list == nullptr) {
|
||||||
m_is_editable = true;
|
m_is_editable = true;
|
||||||
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
|
static Builder<choice_ctrl> builder1;
|
||||||
|
temp = builder1.build(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef UNDEIFNED__WXOSX__ // __WXOSX__ // BBS
|
#ifdef UNDEIFNED__WXOSX__ // __WXOSX__ // BBS
|
||||||
|
@ -1164,9 +1271,12 @@ void Choice::BUILD()
|
||||||
temp->SetTextCtrlStyle(wxTE_READONLY);
|
temp->SetTextCtrlStyle(wxTE_READONLY);
|
||||||
temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
|
temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
|
||||||
#else
|
#else
|
||||||
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
|
static Builder<choice_ctrl> builder2;
|
||||||
|
temp = builder2.build(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
|
||||||
#endif //__WXOSX__
|
#endif //__WXOSX__
|
||||||
}
|
}
|
||||||
|
// temp->SetSize(size);
|
||||||
|
temp->Clear();
|
||||||
temp->GetDropDown().SetUseContentWidth(true);
|
temp->GetDropDown().SetUseContentWidth(true);
|
||||||
if (parent_is_custom_ctrl && m_opt.height < 0)
|
if (parent_is_custom_ctrl && m_opt.height < 0)
|
||||||
opt_height = (double) temp->GetTextCtrl()->GetSize().GetHeight() / m_em_unit;
|
opt_height = (double) temp->GetTextCtrl()->GetSize().GetHeight() / m_em_unit;
|
||||||
|
@ -1219,9 +1329,9 @@ void Choice::BUILD()
|
||||||
e.StopPropagation();
|
e.StopPropagation();
|
||||||
else
|
else
|
||||||
e.Skip();
|
e.Skip();
|
||||||
});
|
}, temp->GetId());
|
||||||
temp->Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_is_dropped = true; });
|
temp->Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_is_dropped = true; }, temp->GetId());
|
||||||
temp->Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent&) { m_is_dropped = false; });
|
temp->Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent&) { m_is_dropped = false; }, temp->GetId());
|
||||||
|
|
||||||
temp->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { on_change_field(); }, temp->GetId());
|
temp->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { on_change_field(); }, temp->GetId());
|
||||||
|
|
||||||
|
@ -1230,12 +1340,12 @@ void Choice::BUILD()
|
||||||
e.Skip();
|
e.Skip();
|
||||||
if (!bEnterPressed)
|
if (!bEnterPressed)
|
||||||
propagate_value();
|
propagate_value();
|
||||||
} );
|
}, temp->GetId() );
|
||||||
|
|
||||||
temp->Bind(wxEVT_TEXT_ENTER, [this](wxEvent& e) {
|
temp->Bind(wxEVT_TEXT_ENTER, [this](wxEvent& e) {
|
||||||
EnterPressed enter(this);
|
EnterPressed enter(this);
|
||||||
propagate_value();
|
propagate_value();
|
||||||
} );
|
}, temp->GetId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
temp->SetToolTip(get_tooltip_text(temp->GetValue()));
|
temp->SetToolTip(get_tooltip_text(temp->GetValue()));
|
||||||
|
|
|
@ -3268,6 +3268,9 @@ void GUI_App::check_printer_presets()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void switch_window_pools();
|
||||||
|
void release_window_pools();
|
||||||
|
|
||||||
void GUI_App::recreate_GUI(const wxString &msg_name)
|
void GUI_App::recreate_GUI(const wxString &msg_name)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI enter";
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI enter";
|
||||||
|
@ -3276,12 +3279,18 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
|
||||||
update_http_extra_header();
|
update_http_extra_header();
|
||||||
|
|
||||||
mainframe->shutdown();
|
mainframe->shutdown();
|
||||||
|
|
||||||
ProgressDialog dlg(msg_name, msg_name, 100, nullptr, wxPD_AUTO_HIDE);
|
ProgressDialog dlg(msg_name, msg_name, 100, nullptr, wxPD_AUTO_HIDE);
|
||||||
dlg.Pulse();
|
dlg.Pulse();
|
||||||
dlg.Update(10, _L("Rebuild") + dots);
|
dlg.Update(10, _L("Rebuild") + dots);
|
||||||
|
|
||||||
MainFrame *old_main_frame = mainframe;
|
MainFrame *old_main_frame = mainframe;
|
||||||
|
struct ClientData : wxClientData
|
||||||
|
{
|
||||||
|
~ClientData() { release_window_pools(); }
|
||||||
|
};
|
||||||
|
old_main_frame->SetClientObject(new ClientData);
|
||||||
|
|
||||||
|
switch_window_pools();
|
||||||
mainframe = new MainFrame();
|
mainframe = new MainFrame();
|
||||||
if (is_editor())
|
if (is_editor())
|
||||||
// hide settings tabs after first Layout
|
// hide settings tabs after first Layout
|
||||||
|
|
|
@ -532,6 +532,9 @@ bool OptionsGroup::activate(std::function<void()> throw_if_canceled/* = [](){}*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_window(wxWindow *win);
|
||||||
|
|
||||||
// delete all controls from the option group
|
// delete all controls from the option group
|
||||||
void OptionsGroup::clear(bool destroy_custom_ctrl)
|
void OptionsGroup::clear(bool destroy_custom_ctrl)
|
||||||
{
|
{
|
||||||
|
@ -560,8 +563,10 @@ void OptionsGroup::clear(bool destroy_custom_ctrl)
|
||||||
if (custom_ctrl) {
|
if (custom_ctrl) {
|
||||||
for (auto const &item : m_fields) {
|
for (auto const &item : m_fields) {
|
||||||
wxWindow* win = item.second.get()->getWindow();
|
wxWindow* win = item.second.get()->getWindow();
|
||||||
if (win)
|
if (win) {
|
||||||
|
free_window(win);
|
||||||
win = nullptr;
|
win = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//BBS: custom_ctrl already destroyed from sizer->clear(), no need to destroy here anymore
|
//BBS: custom_ctrl already destroyed from sizer->clear(), no need to destroy here anymore
|
||||||
if (destroy_custom_ctrl)
|
if (destroy_custom_ctrl)
|
||||||
|
|
|
@ -5023,12 +5023,12 @@ void Tab::clear_pages()
|
||||||
{
|
{
|
||||||
// invalidated highlighter, if any exists
|
// invalidated highlighter, if any exists
|
||||||
m_highlighter.invalidate();
|
m_highlighter.invalidate();
|
||||||
//BBS: clear page in Parent
|
|
||||||
//m_page_sizer->Clear(true);
|
|
||||||
m_parent->clear_page();
|
|
||||||
// clear pages from the controlls
|
// clear pages from the controlls
|
||||||
for (auto p : m_pages)
|
for (auto p : m_pages)
|
||||||
p->clear();
|
p->clear();
|
||||||
|
//BBS: clear page in Parent
|
||||||
|
//m_page_sizer->Clear(true);
|
||||||
|
m_parent->clear_page();
|
||||||
|
|
||||||
// nulling pointers
|
// nulling pointers
|
||||||
m_parent_preset_description_line = nullptr;
|
m_parent_preset_description_line = nullptr;
|
||||||
|
|
|
@ -166,6 +166,7 @@ int ComboBox::Append(const wxString &item,
|
||||||
|
|
||||||
void ComboBox::DoClear()
|
void ComboBox::DoClear()
|
||||||
{
|
{
|
||||||
|
SetIcon("drop_down");
|
||||||
texts.clear();
|
texts.clear();
|
||||||
tips.clear();
|
tips.clear();
|
||||||
icons.clear();
|
icons.clear();
|
||||||
|
|
|
@ -102,6 +102,14 @@ void TextInput::SetIcon(const wxBitmap &icon)
|
||||||
Rescale();
|
Rescale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextInput::SetIcon(const wxString &icon)
|
||||||
|
{
|
||||||
|
if (this->icon.name() == icon.ToStdString())
|
||||||
|
return;
|
||||||
|
this->icon = ScalableBitmap(this, icon.ToStdString(), 16);
|
||||||
|
Rescale();
|
||||||
|
}
|
||||||
|
|
||||||
void TextInput::SetLabelColor(StateColor const &color)
|
void TextInput::SetLabelColor(StateColor const &color)
|
||||||
{
|
{
|
||||||
label_color = color;
|
label_color = color;
|
||||||
|
|
|
@ -42,6 +42,8 @@ public:
|
||||||
|
|
||||||
void SetIcon(const wxBitmap & icon);
|
void SetIcon(const wxBitmap & icon);
|
||||||
|
|
||||||
|
void SetIcon(const wxString & icon);
|
||||||
|
|
||||||
void SetLabelColor(StateColor const &color);
|
void SetLabelColor(StateColor const &color);
|
||||||
|
|
||||||
void SetTextColor(StateColor const &color);
|
void SetTextColor(StateColor const &color);
|
||||||
|
|
Loading…
Reference in a new issue