I have a little visual problem. As you can see in this minimal example, when one clicks the upper button on a wxSpinCtrl, the lower button under the cursor disappears and stays gone if one moves the mouse to the right afterwards. This is because I use SetDoubleBuffered(true) to avoid flickering when changing the wxNotebook pages.
Another tiny detail: the border lines around the spin buttons have a different color than the lines around the text control, but I could live with that.
Code: Select all
#pragma once
#include <wx/frame.h>
#include <wx/app.h>
#include <wx/notebook.h>
#include <wx/spinctrl.h>
enum class NBPageType : int {
WITH_BUTTON = 0,
WITH_SPIN
};
class nbPage {
public:
nbPage(NBPageType _type) : type(_type){}
NBPageType type = NBPageType::WITH_BUTTON;
};
class MyFrame1 : public wxFrame
{
public:
MyFrame1( wxWindow* parent = NULL,
wxWindowID id = wxID_ANY,
const wxString& title = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize( 300,500 ),
long style = wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL) :
wxFrame(parent, id, title, pos, size, style)
{
SetDoubleBuffered(true);
SetSizer(new wxBoxSizer(wxHORIZONTAL));
notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_FIXEDWIDTH | wxNB_NOPAGETHEME | wxCLIP_CHILDREN);
Bind(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &MyFrame1::onNotebookPageChanged, this);
GetSizer()->Add(notebook, 1, wxEXPAND);
pages.push_back(nbPage(NBPageType::WITH_SPIN));
pages.push_back(nbPage(NBPageType::WITH_SPIN));
//pages.push_back(nbPage(NBPageType::WITH_BUTTON));
for (auto page : pages) {
wxPanel* pan = new wxPanel(notebook);
pan->SetSizer(new wxBoxSizer(wxVERTICAL));
notebook->AddPage(pan, wxEmptyString);
wxBoxSizer* radioSiz = new wxBoxSizer(wxHORIZONTAL);
wxRadioButton* radioButton = new wxRadioButton(pan, wxID_ANY, wxT("with button"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
radioButton->SetValue(true);
radioButton->Bind(wxEVT_RADIOBUTTON, &MyFrame1::onTypeChoice, this);
radioSiz->Add(radioButton, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 1);
wxRadioButton* radioSpin = new wxRadioButton(pan, wxID_ANY, wxT("with spin"));
radioSpin->Bind(wxEVT_RADIOBUTTON, &MyFrame1::onTypeChoice, this);
radioSiz->Add(radioSpin, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 1);
pan->GetSizer()->Add(radioSiz);
for (int i = 0; i < 10; i++) {
pan->GetSizer()->Add(new wxButton(pan, wxID_ANY, wxT("button")));
pan->GetSizer()->AddSpacer(5);
pan->GetSizer()->Add(new wxStaticText(pan, wxID_ANY, wxT("text")));
wxSpinCtrl* spinCtrl = new wxSpinCtrl(pan, wxID_ANY/*, wxEmptyString, wxDefaultPosition, wxSize(60- -1), 1, 100*/);
spinCtrl->Bind(wxEVT_SPINCTRL, &MyFrame1::onSpin, this);
pan->GetSizer()->Add(spinCtrl);
}
}
notebook->SetSelection(0);
initControls();
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
this->Centre(wxBOTH);
}
~MyFrame1(){}
void onNotebookPageChanged(wxBookCtrlEvent& evt) {
initControls();
}
void onTypeChoice(wxCommandEvent& evt) {
int idx = notebook->GetSelection();
wxRadioButton* thisBtn = (wxRadioButton*)evt.GetEventObject();
NBPageType newType = thisBtn->GetLabel() == wxT("with button") ? NBPageType::WITH_BUTTON : NBPageType::WITH_SPIN;
pages.at(idx).type = newType;
initControls();
}
private:
wxNotebook* notebook = nullptr;
std::vector<nbPage>pages;
std::vector<wxButton*>buttons;
std::vector<wxSpinCtrl*>spins;
void initControls() {
int idx = notebook->GetSelection();
NBPageType curPageType = pages.at(idx).type;
wxWindow *curWin = notebook->GetCurrentPage();
wxWindow* win = nullptr;
for (unsigned int i = 0; i < curWin->GetChildren().GetCount(); i++) {
win = curWin->GetChildren().Item(i)->GetData();
if (win->IsKindOf(wxCLASSINFO(wxButton)) || win->IsKindOf(wxCLASSINFO(wxStaticText)))
win->Show(curPageType == NBPageType::WITH_BUTTON);
else if (win->IsKindOf(wxCLASSINFO(wxSpinCtrl)))
win->Show(curPageType == NBPageType::WITH_SPIN);
else if (win->IsKindOf(wxCLASSINFO(wxRadioButton)))
static_cast<wxRadioButton*>(win)->SetValue(curPageType == NBPageType::WITH_BUTTON && static_cast<wxRadioButton*>(win)->GetLabel() == wxT("with button") ||
curPageType == NBPageType::WITH_SPIN && static_cast<wxRadioButton*>(win)->GetLabel() == wxT("with spin"));
}
curWin->Layout();
curWin->Refresh();
}
void onSpin(wxSpinEvent& evt) {
OutputDebugString(wxT("onSpin\n"));
Update();
Refresh();
evt.Skip();
}
};
class MyApp : public wxApp {
virtual bool OnInit() {
MyFrame1* mainFrame = new MyFrame1();
mainFrame->Show();
SetTopWindow(mainFrame);
return TRUE;
}
};
wxIMPLEMENT_APP(MyApp);
Thank you!