How to force a wxGridBagSizer to grow and center its cell contents

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Gabriele Giuseppini
Experienced Solver
Experienced Solver
Posts: 56
Joined: Fri Oct 12, 2018 6:12 pm
Location: Amsterdam, the Netherlands

How to force a wxGridBagSizer to grow and center its cell contents

Post by Gabriele Giuseppini »

Dear wx gurus, I'm having troubles getting a wxGridBagSizer to do what I want it to do - may be I'm just asking too much :-)

I'm basically adding panels to a wxNotebook, and each panel uses a wxGridBagSizer to layout its elements - which are mostly static boxes. Being a notebook, all panels will be resized to be as wide as the widest of them all, while their content doesn't necessarily occupy the entire width. So I would like the content of narrower panels to be spread out evenly (horizontally) in the panel.

Here's what I'm getting now (forgive the red, that's to show that the panel does indeed get resized):
Image

But here's what I'd like to get instead (more or less, this has been hacked in Paint):
Image

In other words, I'd like the grid bag sizer to expand (horizontally) to occupy the entire space - together with its cells - and each of its cells to center its content horizontally.

This is the current code that I'm using to populate that panel above:

Code: Select all

void SettingsDialog::PopulateTODOTEST(wxPanel * panel)
{
    wxGridBagSizer * gridSizer = new wxGridBagSizer(0, 0);

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxVERTICAL, panel, _("Mechanics1"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO1");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(0, 0),
            wxGBSpan(1, 1),
            wxALL,
            CellBorderOuter);
    }

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxVERTICAL, panel, _("Mechanics2"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO2");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(0, 1),
            wxGBSpan(1, 1),
            wxALL,
            CellBorderOuter);
    }

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxHORIZONTAL, panel, _("Mechanics3"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO3a");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO3b");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(1, 0),
            wxGBSpan(1, 2),
            wxALL,
            CellBorderOuter);
    }


    // Finalize panel
    panel->SetBackgroundColour(*wxRED);
    panel->SetSizer(gridSizer);
}
Is it even possible to do what I'm trying to do, and if so, how? Thank you in advance for any pointers.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by doublemax »

Make columns growable with wxFlexGridSizer::AddGrowableCol
Use wxALIGN_CENTER_HORIZONTAL when adding items to cells.
Use the source, Luke!
Gabriele Giuseppini
Experienced Solver
Experienced Solver
Posts: 56
Joined: Fri Oct 12, 2018 6:12 pm
Location: Amsterdam, the Netherlands

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by Gabriele Giuseppini »

Thank you doublemax, as always you've been helpful. I'm getting close to it now, but not 100% there - what am I missing? Do I need to setup a flexible direction?

Code: Select all

{
    wxGridBagSizer * gridSizer = new wxGridBagSizer(0, 0);

    gridSizer->AddGrowableCol(0, 1);
    gridSizer->AddGrowableCol(1, 1);

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxVERTICAL, panel, _("Mechanics1"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO1");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(0, 0),
            wxGBSpan(1, 1),
            wxALL | wxALIGN_CENTER_HORIZONTAL,
            CellBorderOuter);
    }

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxVERTICAL, panel, _("Mechanics2"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO2");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(0, 1),
            wxGBSpan(1, 1),
            wxALL | wxALIGN_CENTER_HORIZONTAL,
            CellBorderOuter);
    }

    {
        wxStaticBoxSizer * mechanicsBoxSizer = new wxStaticBoxSizer(wxHORIZONTAL, panel, _("Mechanics3"));

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO3a");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        {
            wxButton * todo = new wxButton(mechanicsBoxSizer->GetStaticBox(), wxID_ANY, "FOO3b");
            mechanicsBoxSizer->Add(todo, 0, wxALL, StaticBoxInsetMargin);
        }

        gridSizer->Add(
            mechanicsBoxSizer,
            wxGBPosition(1, 0),
            wxGBSpan(1, 2),
            wxALL | wxALIGN_CENTER_HORIZONTAL,
            CellBorderOuter);
    }


    // Finalize panel
    panel->SetBackgroundColour(*wxRED);
    panel->SetSizer(gridSizer);
}
Image

I can tell that the second row - whose colspan is 2 - is indeed expanding and centering its content. The first row though - made up of two columns of colspan 1 each - doesn't seem to be doing what I'd hope it did...
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by doublemax »

Strange, that's pretty much exactly what i did for a test:

Code: Select all

wxPanel *panel = new wxPanel(this, wxID_ANY);

wxGridBagSizer *gbs = new wxGridBagSizer(0,0);

wxButton *button1 = new wxButton(panel, wxID_ANY, "1");
wxButton *button2 = new wxButton(panel, wxID_ANY, "2");
wxButton *button3 = new wxButton(panel, wxID_ANY, "3");

gbs->Add(button1, wxGBPosition(0,0), wxDefaultSpan, wxALIGN_CENTER_HORIZONTAL);
gbs->Add(button2, wxGBPosition(0,1), wxDefaultSpan, wxALIGN_CENTER_HORIZONTAL);
gbs->Add(button3, wxGBPosition(1,0), wxGBSpan(1,2), wxALIGN_CENTER_HORIZONTAL);

gbs->AddGrowableCol(0);
gbs->AddGrowableCol(1);

panel->SetSizer(gbs);
Which wxWidgets version are you using?
Use the source, Luke!
Gabriele Giuseppini
Experienced Solver
Experienced Solver
Posts: 56
Joined: Fri Oct 12, 2018 6:12 pm
Location: Amsterdam, the Netherlands

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by Gabriele Giuseppini »

Thanks doublemax, you pointed me to the right direction!

I'm on 3.1.4, but that was not the issue. Somehow, moving the `AddGrowableCol` calls at the end made it work.

But now I'm confused - why would the order matter here?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by doublemax »

Gabriele Giuseppini wrote: Sun Mar 21, 2021 3:25 pm I'm on 3.1.4, but that was not the issue. Somehow, moving the `AddGrowableCol` calls at the end made it work.
But now I'm confused - why would the order matter here?
Hm, i would understand if the AddGrowableCol() wouldn't do anything if the grid is still empty, because technically there are no columns yet. But it looks as if the call does "something", just not the same as when called at the end.

One might consider it a bug, i'd just take it as it is and move on ;)
Use the source, Luke!
Gabriele Giuseppini
Experienced Solver
Experienced Solver
Posts: 56
Joined: Fri Oct 12, 2018 6:12 pm
Location: Amsterdam, the Netherlands

Re: How to force a wxGridBagSizer to grow and center its cell contents

Post by Gabriele Giuseppini »

...and that's what I'm gonna do - take it as is and move on ;-)

Thank you as always for your help!
Post Reply