Search code examples
c++wxwidgets

Extendable wxSizer depending on window size


I want to make a layout which is containing some buttons and panels using wxWidgets. The issue is that I can't create an extendable wxSizer on the center of the other frames.

I tried using some of the wxWidgets components like wxBoxSizer,wxFlexGridSizer, and more. Is there any good advice for implementing this layout?

The simple representation of the window is like that: enter image description here


Solution

  • You need to look at this as multiple nested blocks.

    1. At the highest level, you have 3 blocks ordered horizontally: right rectangle, center rectangle, and left rectangle. In order to accomplish this you need a wxBoxSizer with horizontal orientation.
    2. At the second level, the center rectangle, you have 3 blocks ordered vertically: the top rectangle, the center rectangle, and the bottom rectangle. You will need a wxBoxSizer with vertical orientation.
    3. In order to get the center to expand to fill the space, you will need to use the proportion parameter.

    Here is a code snippet example:

    wxBoxSizer* rootsizer = new wxBoxSizer(wxHORIZONTAL);
    
    //TODO: the right side control is whatever you need it to be
    wxPanel* rightPanel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, rightPanelSize);
    //NOTE the use of 0 as the proportion; this means the right panel will NOT expand
    //horizontally; it is fixed in size.  The wxEXPAND flag means it will expand vertically
    //to fill
    rootsizer->Add(rightpanel, 0, wxEXPAND, 0);
    
    //Our center sizer to contain our center controls
    wxBoxSizer* centersizer = new wxBoxSizer(wxVERTICAL);
    //NOTE the use of 1 as the proportion; this means the center panel will expand HORIZONTALLY to fill all available space
    rootsizer->Add(centersizer, 1, wxEXPAND, 0);
    
    //TODO: whatever control goes on the left
    wxPanel* leftpanel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, leftPanelSize);
    //Proportion is again 0 to prevent expanding horizontally
    rootsizer->Add(leftpanel, 0, wxEXPAND, 0);
    
    //Now the second level
    
    //TODO: whatever control goes on the top
    wxPanel* toppanel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, topPanelSize);
    //Proportion is 0 to prevent expanding VERTICALLY (because we are now in the center sizer
    //which is a vertical sizer
    centersizer->Add(toppanel, 0, wxEXPAND, 0);
    
    //Our final depth, the centermost control, is set to a proportion of 1 to fill the space
    //vertically
    //TODO: whatever is your center control
    wxPanel* centerpanel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize);
    centersizer->Add(centerpanel, 1, wxEXPAND, 0);
    
    //And then the bottom control at proportion 0
    wxPanel* bottompanel= new wxPanel(parent, wxID_ANY, wxDefaultPosition, bottomPanelSize);
    centersizer->Add(bottompanel, 0, wxEXPAND, 0);
    
    

    By combining multiple levels of sizers, along with wxEXPAND and properly assigning proportion, you can get the right flexibility. You just have to learn to look at it in terms of groups of controls that expand and contract in just one direction.