Making a new reusable widget by combining existing widgets

From WxWiki
Jump to navigation Jump to search

Here is a minimal example of how you can construct a new type of widget by combining existing widgets :


#include <wx/wx.h>
#include <wx/choice.h>

class MySuperControl : public wxBoxSizer
{
public:
    MySuperControl(wxWindow* parent) : wxBoxSizer(wxHORIZONTAL)
    {
        wxChoice* choice = new wxChoice(parent, wxID_ANY);
        choice->Append( _("Pizza") );
        choice->Append( _("Pasta") );
        choice->Append( _("Chicken") );
        Add(choice ,0, wxALL, 5);
        
        wxChoice* choice2 = new wxChoice(parent, wxID_ANY);
        choice2->Append( _("Soda") );
        choice2->Append( _("Juice") );
        choice2->Append( _("Water") );
        choice2->Append( _("Coffee") );
        Add(choice2, 0, wxALL, 5);
        
        wxCheckBox* withFries = new wxCheckBox(parent, wxID_ANY, _("With fries"));
        withFries->SetValue(true);
        Add(withFries, 0, wxALL, 5);
    }
};

Note that here we derive from wxBoxSizer; you could also derive from wxPanel, but the advantage of using a sizer and not a panel is that tab-traversal into and out of your new widget is only possible if you make it a sizer, and will not be possible if you make it a panel.

You can then use this widget everywhere you like :

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(NULL, wxID_ANY,  wxT("Hello wxWidgets"), wxPoint(50,50), wxSize(800,600))
    {
        wxPanel* mainPane = new wxPanel(this);
        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        
        sizer->Add( new wxStaticText(mainPane, wxID_ANY, _("For you :")), 0, wxALL, 5);
        
        MySuperControl* control1 = new MySuperControl(mainPane);
        sizer->Add( control1,  0, wxALL, 5 );
        
        sizer->Add( new wxStaticText(mainPane, wxID_ANY, _("For your friend :")), 0, wxALL, 5);
        
        MySuperControl* control2 = new MySuperControl(mainPane);
        sizer->Add( control2, 0, wxALL, 5 );

        mainPane->SetSizer(sizer);
    }
};

class MyApp: public wxApp
{
    wxFrame* m_frame;
public:
    
    bool OnInit()
    {
        m_frame = new MyFrame();
        m_frame->Show();
        return true;
    } 
    
};

IMPLEMENT_APP(MyApp)