Opened 5 years ago

Closed 4 years ago

#11311 closed enhancement (fixed)

Make wxBoxSizer proportion handling more compatible with 2.8.

Reported by: juliansmart Owned by:
Priority: high Milestone: 2.9.1
Component: GUI-all Version: stable-latest
Keywords: sizer proportion regression Cc:
Blocked By: Blocking:
Patch: no

Description

This patch allows applications to specify 2.8-compatible proportion behaviour for individual or all wxBoxSizers. The proportion identifier names could be improved.

You can use the code below code to test it (add to the end of the frame constructor in minimal.cpp).

wxBOX_PROPORTION_EVEN results in 100/75/75 pixels (2.8 behaviour) and for the default wxBOX_PROPORTION_USE_MINIMAL (2.9 behaviour) it's 100/100/50 pixels.

See also:

http://thread.gmane.org/gmane.comp.lib.wxwidgets.devel/81525

"Sizer proportion problems" in wx-dev (March 2009, from Benjamin Williams)

    //wxBoxSizer::SetDefaultProportionMode(wxBOX_PROPORTION_USE_MINIMAL);
    wxBoxSizer::SetDefaultProportionMode(wxBOX_PROPORTION_EVEN);

    wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
    sizer->Add(new wxStaticText(this, -1, _T("100 pixels fixed"),
                                wxDefaultPosition, wxSize(100, -1),
                                wxBORDER_SIMPLE));
    sizer->Add(new wxStaticText(this, -1, _T("100 pixels stretched"),
                                wxDefaultPosition, wxSize(100, -1),
                                wxBORDER_SIMPLE), wxSizerFlags(1));
    sizer->Add(new wxStaticText(this, -1, _T("50 pixels stretched"),
                                wxDefaultPosition, wxSize(50, -1),
                                wxBORDER_SIMPLE), wxSizerFlags(1));
    SetSizer(sizer);
    SetClientSize(wxSize(250, 100));

Attachments (4)

sizer.diff download (6.9 KB) - added by juliansmart 5 years ago.
Patch to add 2.8 box sizer compatibility
sizersample.diff download (4.0 KB) - added by juliansmart 5 years ago.
A patch to minimal.cpp (2.9 SVN) to demonstrate proportion issue.
patch_minimal_sizer_broken.patch download (16.5 KB) - added by pete_b 5 years ago.
A patch to minimal to demonstrate sizer porting issue. Adjust DoGetBestSize to fix.
boxsizer.diff download (36.4 KB) - added by vadz 4 years ago.
New wxBoxSizer layout algorithm and a unit test for it

Download all attachments as: .zip

Change History (12)

Changed 5 years ago by juliansmart

Patch to add 2.8 box sizer compatibility

comment:1 Changed 5 years ago by juliansmart

Here's an illustration of the problem.

A layout uses proportions to align the first item in each of two rows. The first row has 2 items and proportions of 1 and 2 respectively. The second row has 3 items, all with proportion 1. The result on 2.8 is that the first items in each row are the same size, which is quite intuitive if you're thinking of proportions in this way (i.e. more as overall proportions, less as stretch factors).

In 2.8 this gives:

http://www.anthemion.co.uk/wxwidgets/sizers/stretch-28.png

In 2.9 this gives:

http://www.anthemion.co.uk/wxwidgets/sizers/stretch-29.png

Changed 5 years ago by juliansmart

A patch to minimal.cpp (2.9 SVN) to demonstrate proportion issue.

comment:2 Changed 5 years ago by vadz

  • Keywords sizer proportion regression added
  • Patch unset
  • Priority changed from normal to high
  • Status changed from new to confirmed
  • Summary changed from wxBoxSizer compatibility in 2.9 to Make wxBoxSizer proportion handling more compatible with 2.8.

See this thread for more details, notably this message outlining the algorithm which we should probably use.

The goal is, in any case, to make the layout algorithm respect the minimal sizes while still making the sizes of the items (and not just the sizes of the part above the min size) proportional to the "proportion" specified when adding them to the sizer.

comment:3 follow-up: Changed 5 years ago by pete_b

Also seems that minimum sizes are sometimes broken by the new algorithm. I cant give specific details but so many layouts were broken in my app that I had to revert to 2.8.9 for the time being. There is just too much work to debug and fix them all.
In some cases, enlarging the containing dialog would allow increases in size of the contents, but shrinking the dialog would cause the contents to be clipped. This is probably indicative of a problem in my DoGetBestSize() code and minimum sizes or something but I'd rather just be able to use the old method, which worked absolutely fine.

Is there a possibility that you could put the new sizer algorithms into classes with new names and maybe deprecate the old sizers?

i.e. keep wxBoxSizer (et al) for 2.8 behaviour and add wxBoxLayout (or something) for the new version?

comment:4 in reply to: ↑ 3 ; follow-up: Changed 5 years ago by vadz

Replying to pete_b:

Also seems that minimum sizes are sometimes broken by the new algorithm.

This is definitely not supposed to happen. It would be great if you could make a simple patch showing the problem so that we could debug it even if you can't do it yourself.

Is there a possibility that you could put the new sizer algorithms into classes with new names and maybe deprecate the old sizers?

Hopefully this won't be necessary.

Changed 5 years ago by pete_b

A patch to minimal to demonstrate sizer porting issue. Adjust DoGetBestSize to fix.

comment:5 in reply to: ↑ 4 Changed 5 years ago by pete_b

Replying to vadz:

Replying to pete_b:

Also seems that minimum sizes are sometimes broken by the new algorithm.

This is definitely not supposed to happen. It would be great if you could make a simple patch showing the problem so that we could debug it even if you can't do it yourself.

Looks like this was probably due to me not implementing DoGetBestSize (see the patch). This is probably the same issue in a few other areas of my app.

Apologies if I've polluted this ticket.

comment:6 Changed 5 years ago by vadz

Sorry, this example is rather complicated and I don't have time to look at it now (can't it be simplified further, i.e. is all this extra stuff really needed to reproduce the problem?). However if the behaviour changes depending on whether DoGetBestSize() is implemented or not, then it's probably related to the changes of r62306 and not to the sizer layout changes at all.

comment:7 Changed 4 years ago by vadz

The attached patch should fix the original issue. Please see my post to wx-dev for more details.

Changed 4 years ago by vadz

New wxBoxSizer layout algorithm and a unit test for it

comment:8 Changed 4 years ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [63706]) Fix box sizer layout algorithm to respect both proportions and min sizes.

The new version of the algorithm tries to distribute the entire space
allocated to the sizer among its children, just as the version in 2.8 did,
while still respecting minimal children sizes first and foremost. This means
that the space allocated to the item will always be at least its minimal size
if the total space is at least equal to the sum of minimal sizes of the
children but that if there is enough space, the proportions will be respected
too.

Extended the unit test to check that laying out various combinations of three
elements results in the expected results.

Closes #11311.

Note: See TracTickets for help on using tickets.