please review: new wxBoxSizer algorithm

26 views
Skip to first unread message

Vadim Zeitlin

unread,
Mar 15, 2010, 6:53:36 PM3/15/10
to wx-dev
Hello,

It took me a long time but finally I think I have the correct version of
wxBoxSizer layout code which respects both the proportions and the minimal
sizes of the items, i.e. fixes #11311 (and also fixes the problems of
#10008 although this is actually an independent issue).

I've put the full diff (including changes to the generated files for ease
of testing) at http://trac.wxwidgets.org/attachment/ticket/11311/boxsizer.diff
Please review it if you can and test it with your code. It does result in
the same behaviour as in 2.8 for the minimal sample modified by Julian's
patch to the same ticket provided there is enough space and it also passes
all the unit tests which you can see in the new boxsizer.cpp file which is
part of the diff. So I'm rather confident that this patch indeed implements
the right behaviour -- but please let me know if you find anything wrong
with it!

The rest of this message deals with explaining how the new code works and
can be skipped if you're not interested in it.

I'll start by reminding you what we want to do: recall that the main
problem was that 2.8 code distributed the entire space allocated to the
sizer among its children using their proportions. So if you had a sizer
with 3 children with proportions 1, 2 and 3 and the total size was 600 (I'm
only speaking of the major direction here), then the sizes of the items
would be 100, 200 and 300 respectively. We want to preserve this behaviour
if possible but sometimes it isn't possible to have both the right
proportions and respect the items minimal sizes. For example, if the
minimal size of the first item is 100 then it's easy to see that the
proportions may be only respected if the total size is >= 600. If the total
size is just 300, 2.8 version would yield (50, 100, 150) thus truncating
the first item while possibly leaving too much space for the 2 other ones.
With my patch the first item will still have its min size and the remaining
space will be distributed among the other items according to their
proportions (and min sizes, of course). So in this case, assuming there are
no other min size constraints, the sizes will be (100, 80, 120). IOW, the
first item is treated as being fixed (i.e. proportion == 0) if we can't
respect both its proportion and min size. As an aside, notice that this
fixes a nice bug in 2.8 version in which an item with proportion 1 (or 100
for that matter) could be smaller than an item with proportion 0. With the
patch, increasing an item proportion will never decrease its size which
looks obvious but wasn't actually true before.

To summarize, we want to:

1. Respect all items minimal sizes.
2. Respect their proportions if possible.
3. Lay items out irrespectively of their order.


Let's turn to implementation now. First, it's clear that even (1) alone is
not always possible simply because we may not have enough space for the sum
of min sizes of all the items. This explains the bug #10008 and is actually
not related to the proportions at all (i.e. both 2.8 and 2.9 without this
patch behave equally wrongly here). So we need to handle specifically a
degenerate case when there is simply not enough space for all the items.
E.g. in the example above if the total space is 50 there is no way the
first item can have the size of 100 and forget about the proportions. So
the code deals with this case specifically and simply allocates min size to
fixed size items while it can, then, if anything still remains, to the
other items starting from the first one, and sets the size of the rest of
the items to 0. This is not ideal but we can't work miracles and if there
is not enough space, not everything will be visible and there is nothing we
can do about it. To finish with this case, notice that it's the only one
which breaks (3) as well because the first item(s) will get their min size
while the last one(s) will not. In all the other cases the algorithm does
respect (3).


In the normal case we actually implement a quadratic, i.e. O(N^2) where N
is the number of items in the sizer, algorithm. This is usually a bad idea
but I couldn't find anything better and, also, the number of items in a
(box) sizer will hopefully rarely be much more than a dozen or so, so it
shouldn't be that bad in practice. And the algorithm also reduces to a
linear one if there is enough space for everything and there are no items
with proportion 0 (it could be optimized to remain linear even in presence
of items with proportion 0 and I might do it later if this turns out to be
a real problem). What the algorithm does is basically to assign their final
size to all items with proportion 0 and also to all items with non-zero
proportion whose size computed according to their proportion would turn out
to be less than their min size. Such items are, as mentioned above, handled
as if they were fixed (proportion == 0) and I'll call them pseudo-fixed
below.

The quadratic part comes from the fact that once we subtract the space
needed by a fixed or pseudo-fixed item we need to recheck all the non-fixed
items again as there might not be enough space for them any more even if
there was enough initially. So we restart the loop each time we fix a size
of any item. Clearly, the loop is still going to terminate sooner or later
-- but it may take N iterations for it to do so in the worst case.

Anyhow, once it does terminate we distribute the remaining (after
subtracting the fixed and pseudo-fixed items) part among all the items
using their proportions as usual. It's easy to see that (2) is satisfied if
possible because if there is enough space, the loop above will never set
any non-fixed items sizes and so the sizes of all items will be determined
according to their proportions.


I think the algorithm is finally simple enough. It's also potentially
rather inefficient but, once again, I couldn't find any one-pass algorithm
and I am not sure if it's going to be a problem in practice. I also hope to
have implemented it correctly and tried to write a relatively exhaustive
unit test to prove it. If you can think of other cases to test, please send
patches adding them or ask me to do it. FWIW I'm horrified by the number of
bugs in the original sizer algorithm which could be found by even simplest
unit tests (e.g. even laying out _1_ element didn't work correctly!). If
any further reasons to absolutely require unit tests for any new code were
needed, this would have clenched it.

Any comments and especially test results welcome!
VZ

Robin Dunn

unread,
Mar 16, 2010, 1:54:58 AM3/16/10
to wx-...@googlegroups.com
On 3/15/10 3:53 PM, Vadim Zeitlin wrote:
> Hello,
>
> It took me a long time but finally I think I have the correct version of
> wxBoxSizer layout code which respects both the proportions and the minimal
> sizes of the items, i.e. fixes #11311 (and also fixes the problems of
> #10008 although this is actually an independent issue).
>
> I've put the full diff (including changes to the generated files for ease
> of testing) at http://trac.wxwidgets.org/attachment/ticket/11311/boxsizer.diff
> Please review it if you can and test it with your code. It does result in
> the same behaviour as in 2.8 for the minimal sample modified by Julian's
> patch to the same ticket provided there is enough space and it also passes
> all the unit tests which you can see in the new boxsizer.cpp file which is
> part of the diff. So I'm rather confident that this patch indeed implements
> the right behaviour -- but please let me know if you find anything wrong
> with it!

Everything I've tried so far seems to be working correctly and as
expected. Good job.


--
Robin Dunn
Software Craftsman
http://wxPython.org

Julian Smart

unread,
Mar 16, 2010, 2:48:24 AM3/16/10
to wx-...@googlegroups.com
Hi Vadim,

Many thanks, I'll compile DialogBlocks against 2.9 and do some testing.
Have to figure out how to work around 2.9 API changes first.

Regards,

Julian


--
Julian Smart, Anthemion Software Ltd.
28/5 Gillespie Crescent, Edinburgh, Midlothian, EH10 4HU
www.anthemion.co.uk | +44 (0)131 229 5306
Tools for writers: www.writerscafe.co.uk
wxWidgets RAD: www.dialogblocks.com
Blog: www.juliansmart.com

Ronny Krueger

unread,
Mar 16, 2010, 10:32:52 AM3/16/10
to wx-...@googlegroups.com
On 15.03.2010 23:53, Vadim Zeitlin wrote:
> Hello,
>
> It took me a long time but finally I think I have the correct version of
> wxBoxSizer layout code which respects both the proportions and the minimal
> sizes of the items, i.e. fixes #11311 (and also fixes the problems of
> #10008 although this is actually an independent issue).
>
> I've put the full diff (including changes to the generated files for ease
> of testing) at http://trac.wxwidgets.org/attachment/ticket/11311/boxsizer.diff
> Please review it if you can and test it with your code. It does result in
> the same behaviour as in 2.8 for the minimal sample modified by Julian's
> patch to the same ticket provided there is enough space and it also passes
> all the unit tests which you can see in the new boxsizer.cpp file which is
> part of the diff. So I'm rather confident that this patch indeed implements
> the right behaviour -- but please let me know if you find anything wrong
> with it!
>
Overall this patch fixes a couple of layout problems I was having, so it
definitely makes things better. But there is now a strange thing
happening with the wxChoice widgets that I use in my wxAuiToolBar. When
I start the application everything is fine. But when I undock the
toolbar and dock it again the height of the wxChoice window is reduced
to only a couple of pixels.
The combo sample also shows an unusual behaviour. When the main window
is resized the combo boxes get smaller as if they don't have any min
size at all. The same goes for the check box in the top right. I don't
know if these problems are just incorrect uses of sizers that were
masked by the buggy sizer algorithm or if this is a real bug introduced
with the patch. Or it could be a bug in wxChoice and wxCheckBox not
supplying correct min size values.

Ronny

Vadim Zeitlin

unread,
Mar 16, 2010, 10:54:40 AM3/16/10
to wx-...@googlegroups.com
On Tue, 16 Mar 2010 15:32:52 +0100 Ronny Krueger <r...@rkxs.de> wrote:

RK> Overall this patch fixes a couple of layout problems I was having, so it
RK> definitely makes things better.

Thanks for testing it!

RK> But there is now a strange thing
RK> happening with the wxChoice widgets that I use in my wxAuiToolBar. When
RK> I start the application everything is fine. But when I undock the
RK> toolbar and dock it again the height of the wxChoice window is reduced
RK> to only a couple of pixels.

Can this problem be reproduced with a simple patch to the auidemo sample?
Also, notice that wxAUI still uses the old 2.8 wxBoxSizer version for
layout as it copied it into its own code after the changes to wxBoxSizer in
2.9. I did remove wxAuiProportionalBoxSizer and replaced it with wxBoxSizer
locally already as I think there should be no reason to use the former any
more but it's not in the patch. So could you please also try if just
renaming wxAuiProportionalBoxSizer to wxBoxSizer globally in
src/aui/framemanager.cpp change anything?

RK> The combo sample also shows an unusual behaviour. When the main window
RK> is resized the combo boxes get smaller as if they don't have any min
RK> size at all. The same goes for the check box in the top right. I don't
RK> know if these problems are just incorrect uses of sizers that were
RK> masked by the buggy sizer algorithm or if this is a real bug introduced
RK> with the patch. Or it could be a bug in wxChoice and wxCheckBox not
RK> supplying correct min size values.

It's either this or a bug in the sample layout which might not set the min
window size correctly. In any case I don't see any significant difference
here compared with the current trunk version. The only difference is that
the controls were just truncated before while now the last visible control
is always resized to fit (which is intentional, see #10008). However the
window can still be resized to completely hide the checkbox even without
the patch. Or did I miss any change in the behaviour due to the patch?

Thanks,
VZ

Ronny Krueger

unread,
Mar 16, 2010, 12:19:02 PM3/16/10
to wx-...@googlegroups.com
On 16.03.2010 15:54, Vadim Zeitlin wrote:
> On Tue, 16 Mar 2010 15:32:52 +0100 Ronny Krueger<r...@rkxs.de> wrote:
>
> RK> Overall this patch fixes a couple of layout problems I was having, so it
> RK> definitely makes things better.
>
> Thanks for testing it!
>
> RK> But there is now a strange thing
> RK> happening with the wxChoice widgets that I use in my wxAuiToolBar. When
> RK> I start the application everything is fine. But when I undock the
> RK> toolbar and dock it again the height of the wxChoice window is reduced
> RK> to only a couple of pixels.
>
> Can this problem be reproduced with a simple patch to the auidemo sample?
> Also, notice that wxAUI still uses the old 2.8 wxBoxSizer version for
> layout as it copied it into its own code after the changes to wxBoxSizer in
> 2.9. I did remove wxAuiProportionalBoxSizer and replaced it with wxBoxSizer
> locally already as I think there should be no reason to use the former any
> more but it's not in the patch. So could you please also try if just
> renaming wxAuiProportionalBoxSizer to wxBoxSizer globally in
> src/aui/framemanager.cpp change anything?
wxAuiToolBar uses the normal wxBoxSizer to layout its items.
wxAuiProportionalBoxSizer is used for the layout of the pane windows.
But I will certainly try to use wxBoxSizer there to see, if this works
as expected.

And yes, I can provide a simple patch to the aui demo that shows the
problem.
I have currently no access to my development computer to create a real
patch, so I hope the following will suffice.

auidemo.cpp(849)
tb4->SetCustomOverflowItems(prepend_items, append_items);

wxChoice* choice = new wxChoice(tb4, ID_SampleItem+35);
choice->AppendString(wxT("Choice 1"));
tb4->AddControl(choice);

tb4->Realize();

Add the three lines between the SetCustomOverflowItems() and the
Realize() call and you get a choice box on one of the toolbars. Now
undock that toolbar and redock it again to see the very tiny combobox
afterwards.

>
> RK> The combo sample also shows an unusual behaviour. When the main window
> RK> is resized the combo boxes get smaller as if they don't have any min
> RK> size at all. The same goes for the check box in the top right. I don't
> RK> know if these problems are just incorrect uses of sizers that were
> RK> masked by the buggy sizer algorithm or if this is a real bug introduced
> RK> with the patch. Or it could be a bug in wxChoice and wxCheckBox not
> RK> supplying correct min size values.
>
> It's either this or a bug in the sample layout which might not set the min
> window size correctly. In any case I don't see any significant difference
> here compared with the current trunk version. The only difference is that
> the controls were just truncated before while now the last visible control
> is always resized to fit (which is intentional, see #10008). However the
> window can still be resized to completely hide the checkbox even without
> the patch. Or did I miss any change in the behaviour due to the patch?

I have to admit that I did not check the behaviour of the combo sample
before the patch. If it does the same now as it did before the patch
then the problem is somewhere else. Or I am totally wrong in believing
that shrinking a checkbox to one pixel is not a good layout behaviour. :)

Best regards,

Ronny


Vadim Zeitlin

unread,
Mar 16, 2010, 1:19:16 PM3/16/10
to wx-...@googlegroups.com
On Tue, 16 Mar 2010 17:19:02 +0100 Ronny Krueger <r...@rkxs.de> wrote:

RK> wxAuiToolBar uses the normal wxBoxSizer to layout its items.
RK> wxAuiProportionalBoxSizer is used for the layout of the pane windows.

Yes, indeed, sorry, I was wrong about this, I just remembered that
wxAuiProportionalBoxSizer was used somewhere in wxAUI but didn't realize it
wasn't used everywhere. Sorry again for the confusion.

RK> And yes, I can provide a simple patch to the aui demo that shows the
RK> problem.
RK> I have currently no access to my development computer to create a real
RK> patch, so I hope the following will suffice.
RK>
RK> auidemo.cpp(849)
RK> tb4->SetCustomOverflowItems(prepend_items, append_items);
RK>
RK> wxChoice* choice = new wxChoice(tb4, ID_SampleItem+35);
RK> choice->AppendString(wxT("Choice 1"));
RK> tb4->AddControl(choice);
RK>
RK> tb4->Realize();
RK>
RK> Add the three lines between the SetCustomOverflowItems() and the
RK> Realize() call and you get a choice box on one of the toolbars. Now
RK> undock that toolbar and redock it again to see the very tiny combobox
RK> afterwards.

Thanks, I do see the problem and this time it's definitely due to the
patch as it behaves correctly in master. I'll check it.

RK> I have to admit that I did not check the behaviour of the combo sample
RK> before the patch. If it does the same now as it did before the patch
RK> then the problem is somewhere else. Or I am totally wrong in believing
RK> that shrinking a checkbox to one pixel is not a good layout behaviour. :)

No, it isn't, but, again, I think it's just a bug in the sample which
doesn't set the min window size correctly. And, of course, if there is not
enough space there is not much else that you can do. Anyhow, it'd be nice
to fix this but as I don't know this sample code and it doesn't seem
related to my changes I won't do it right now.

Regards,
VZ

Ronny Krueger

unread,
Mar 16, 2010, 2:18:18 PM3/16/10
to wx-...@googlegroups.com
On 16.03.2010 18:19, Vadim Zeitlin wrote:
> On Tue, 16 Mar 2010 17:19:02 +0100 Ronny Krueger<r...@rkxs.de> wrote:
>
> RK> wxAuiToolBar uses the normal wxBoxSizer to layout its items.
> RK> wxAuiProportionalBoxSizer is used for the layout of the pane windows.
>
> Yes, indeed, sorry, I was wrong about this, I just remembered that
> wxAuiProportionalBoxSizer was used somewhere in wxAUI but didn't realize it
> wasn't used everywhere. Sorry again for the confusion.
No problem. wx is huge and even though you are probably one of a small
group of people who knows most of the code, I don't expect you to know
it all. :-)

>
> RK> And yes, I can provide a simple patch to the aui demo that shows the
> RK> problem.
> RK> I have currently no access to my development computer to create a real
> RK> patch, so I hope the following will suffice.
> RK>
> RK> auidemo.cpp(849)
> RK> tb4->SetCustomOverflowItems(prepend_items, append_items);
> RK>
> RK> wxChoice* choice = new wxChoice(tb4, ID_SampleItem+35);
> RK> choice->AppendString(wxT("Choice 1"));
> RK> tb4->AddControl(choice);
> RK>
> RK> tb4->Realize();
> RK>
> RK> Add the three lines between the SetCustomOverflowItems() and the
> RK> Realize() call and you get a choice box on one of the toolbars. Now
> RK> undock that toolbar and redock it again to see the very tiny combobox
> RK> afterwards.
>
> Thanks, I do see the problem and this time it's definitely due to the
> patch as it behaves correctly in master. I'll check it.
Good to hear. If you have another patch I'll be happy to test it.

>
> RK> I have to admit that I did not check the behaviour of the combo sample
> RK> before the patch. If it does the same now as it did before the patch
> RK> then the problem is somewhere else. Or I am totally wrong in believing
> RK> that shrinking a checkbox to one pixel is not a good layout behaviour. :)
>
> No, it isn't, but, again, I think it's just a bug in the sample which
> doesn't set the min window size correctly. And, of course, if there is not
> enough space there is not much else that you can do. Anyhow, it'd be nice
> to fix this but as I don't know this sample code and it doesn't seem
> related to my changes I won't do it right now.
That's ok. I only thought this was an indicator of a problem inside
those widgets. But if it can be 'fixed' by just using the sizer
mechanism correctly then there is really no problem.

Regards,

Ronny

Vadim Zeitlin

unread,
Mar 16, 2010, 4:28:42 PM3/16/10
to wx-...@googlegroups.com
On Tue, 16 Mar 2010 19:18:18 +0100 Ronny Krueger <r...@rkxs.de> wrote:

RK> > Thanks, I do see the problem and this time it's definitely due to the
RK> > patch as it behaves correctly in master. I'll check it.
RK> Good to hear. If you have another patch I'll be happy to test it.

The fix is below and changes wxChoice to avoid hysteresis which it has
now: if you call SetSize(-1, 10) and SetSize(-1, 23) on it (where 23 is the
default height on my system, yours may be different), it remains of height
10 and doesn't become 23 again. This is, of course, bad on its own and so I
fixed this and now the AUI sample behaves correctly.

However it was also very surprising (at least to me) that the wxChoice
size was reduced below its normal value in the first place. And the culprit
is the call to SetSize(1,1) in wxAuiManager::Update() which, according to
the comment there, "reduces flicker". To be honest I don't understand at
all why is this needed, it seems to me that it can only increase it because
of an extra layout. If it hid and then showed the window I could understand
it but reducing its size to 1 pixel...? Does anybody know if this call is
(still) needed? Under Win7 I don't see any flicker anyhow because of its
double buffering and I don't have time to test elsewhere right now but I
seriously doubt this resize could improve anything anywhere.

Anyhow, thanks again for reporting this bug!
VZ

P.S. The promised patch fixing wxChoice:

--- a/src/msw/choice.cpp
+++ b/src/msw/choice.cpp
@@ -553,8 +553,21 @@ void wxChoice::DoSetSize(int x, int y,
int width, int height,
int sizeFlags)
{
+ const int heightBest = GetBestSize().y;
+
// we need the real height below so get the current one if it's not given
- if ( height != wxDefaultCoord && height != GetBestSize().y )
+ if ( height == wxDefaultCoord )
+ {
+ // height not specified, use the same as before
+ DoGetSize(NULL, &height);
+ }
+ else if ( height == heightBest )
+ {
+ // we don't need to manually manage our height, let the system use the
+ // default one
+ m_heightOwn = wxDefaultCoord;
+ }
+ else // non-default height specified
{
// set our new own height but be careful not to make it too big: the
// native control apparently stores it as a single byte and so setting
@@ -568,10 +581,6 @@ void wxChoice::DoSetSize(int x, int y,
else if ( m_heightOwn < COMBO_HEIGHT_ADJ )
m_heightOwn = COMBO_HEIGHT_ADJ;
}
- else // height not specified
- {
- DoGetSize(NULL, &height);
- }


// the height which we must pass to Windows should be the total height of

Ronny Krueger

unread,
Mar 17, 2010, 6:34:11 AM3/17/10
to wx-...@googlegroups.com
On 16.03.2010 21:28, Vadim Zeitlin wrote:
> On Tue, 16 Mar 2010 19:18:18 +0100 Ronny Krueger<r...@rkxs.de> wrote:
>
> RK> > Thanks, I do see the problem and this time it's definitely due to the
> RK> > patch as it behaves correctly in master. I'll check it.
> RK> Good to hear. If you have another patch I'll be happy to test it.
>
> The fix is below and changes wxChoice to avoid hysteresis which it has
> now: if you call SetSize(-1, 10) and SetSize(-1, 23) on it (where 23 is the
> default height on my system, yours may be different), it remains of height
> 10 and doesn't become 23 again. This is, of course, bad on its own and so I
> fixed this and now the AUI sample behaves correctly.
>
> However it was also very surprising (at least to me) that the wxChoice
> size was reduced below its normal value in the first place. And the culprit
> is the call to SetSize(1,1) in wxAuiManager::Update() which, according to
> the comment there, "reduces flicker". To be honest I don't understand at
> all why is this needed, it seems to me that it can only increase it because
> of an extra layout. If it hid and then showed the window I could understand
> it but reducing its size to 1 pixel...? Does anybody know if this call is
> (still) needed? Under Win7 I don't see any flicker anyhow because of its
> double buffering and I don't have time to test elsewhere right now but I
> seriously doubt this resize could improve anything anywhere.
>
Your patch for wxChoice fixed the problem. Before, you could see the
wxChoice flickering from its correct size to this very small size when
moving the toolbar. But other than that I never saw flickering of these
widgets under WinXP. And after your patch there is no flickering either.
I also replaced wxAuiProportionalBoxSizer with wxBoxSizer in
framemanager.cpp and could not see any problems in my application. So I
consider this working now. I hope the patches make into trunk soon.

Regards,

Ronny

Message has been deleted

Michael Stratmann

unread,
May 10, 2010, 3:11:40 PM5/10/10
to wx-dev
Hello,

First I would like to thank you for your effort to improve the sizer
algorithm, with enough space it looks good now.

With regard to a too small or a default window size I might have found
an issue (I use WinXP, VS90, wx r64258):

I expect my app's frame (dialog, etc.) to have the needed size
(wxDefaultSize), so the proportions (given stretch factors) are
fulfilled (maybe my expectation is wrong?). At least sometimes the
boxsizers do not do that. They do not even ensure enough minimum size,
to display everything inside, they can shrink to 0x0 pixels.

Take Julian's minimum example (http://trac.wxwidgets.org/ticket/
11311), remove line 236, "SetClientSize(600, 200);", run again. The
resulting default frame size is too small, the lower right static box
does not display all the text. But box's border is displayed, how
should user guess there is more?

2.8. makes smallest layout as sizers and stretch factors require,
ignoring too small frame size. I liked that one more.

Regards, Michael

--
To unsubscribe, send email to wx-dev+un...@googlegroups.com
or visit http://groups.google.com/group/wx-dev

Vadim Zeitlin

unread,
May 10, 2010, 4:41:13 PM5/10/10
to wx-...@googlegroups.com
On Mon, 10 May 2010 12:11:40 -0700 (PDT) Michael Stratmann <Stra...@MicSt.de> wrote:

MS> I expect my app's frame (dialog, etc.) to have the needed size
MS> (wxDefaultSize), so the proportions (given stretch factors) are
MS> fulfilled (maybe my expectation is wrong?).

Difficult question. On one hand, if you have 2 windows with min size of
100 it seems logical that the min size of them together should be 200, not
1100 if their proportions are 1 and 10. OTOH I guess you could make an
argument for 1100 as well and apparently it's more compatible with 2.8.

I think/hope however that applications actually relying on this should be
relatively rare and if you really absolutely do need this, it would be
enough to set the size of the second window to its proportion times min
size of the first one.

So I don't think we're going to change this unless there is a great public
outcry.

Regards,
VZ

Julian Smart

unread,
May 11, 2010, 5:32:56 AM5/11/10
to wx-...@googlegroups.com
What I don't quite understand about this is, how can you get the
required layout using stretch factors if you don't know what the dialog
size should be? (Without manually kludging it, which is not easy to
understand and maintain, and is problematic to insert code manually when
the layout has been generated automatically).

So I guess it comes down to whether proportion takes priority over min
size, or vice versa. How about a flag wxPRIORITIZE_PROPORTION which
makes the total min size take proportion into account?

Or, automatically make this the behaviour if any min sizes are violated
by a lack of space?

Regards,

Julian

Vadim Zeitlin

unread,
May 11, 2010, 6:55:11 AM5/11/10
to wx-...@googlegroups.com
On Tue, 11 May 2010 10:32:56 +0100 Julian Smart <jul...@anthemion.co.uk> wrote:

JS> Vadim Zeitlin wrote:
JS> > On Mon, 10 May 2010 12:11:40 -0700 (PDT) Michael Stratmann <Stra...@MicSt.de> wrote:
JS> >
JS> > MS> I expect my app's frame (dialog, etc.) to have the needed size
JS> > MS> (wxDefaultSize), so the proportions (given stretch factors) are
JS> > MS> fulfilled (maybe my expectation is wrong?).
JS> >
JS> > Difficult question. On one hand, if you have 2 windows with min size of
JS> > 100 it seems logical that the min size of them together should be 200, not
JS> > 1100 if their proportions are 1 and 10. OTOH I guess you could make an
JS> > argument for 1100 as well and apparently it's more compatible with 2.8.
JS> >
JS> > I think/hope however that applications actually relying on this should be
JS> > relatively rare and if you really absolutely do need this, it would be
JS> > enough to set the size of the second window to its proportion times min
JS> > size of the first one.
JS> >
JS> > So I don't think we're going to change this unless there is a great public
JS> > outcry.
JS> >
JS> What I don't quite understand about this is, how can you get the
JS> required layout using stretch factors if you don't know what the dialog
JS> size should be?

Right now only by specifying the minimal sizes explicitly (which is what,
I guess, you mean by "kludging").

JS> So I guess it comes down to whether proportion takes priority over min
JS> size, or vice versa.

Not quite, min sizes must be always respected. It's rather the question of
whether the proportions are vital enough to make the window (possibly
significantly) bigger to accommodate them or not. Personally I really don't
know the right answer as I practically never use proportions other than 0
and 1 anyhow. In fact I'd be curious to know what people use any higher
proportions for.

JS> How about a flag wxPRIORITIZE_PROPORTION which makes the total min size
JS> take proportion into account?

Oh no, please not another flag. If you think/there is consensus that this
is the right behaviour let's just implement it like this. FWIW it shouldn't
be very difficult neither, wxBoxSizer::CalcMin() should just calculate the
least common multiple of proportions and then the min size would be easy to
compute. Which doesn't mean that I wouldn't appreciate if someone else than
me did it...

JS> Or, automatically make this the behaviour if any min sizes are violated
JS> by a lack of space?

Min sizes are never violated by a lack of space unless the available space
is less than the sum of min sizes in which case proportions are really the
last of your problems.

Just to be clear: we're not talking about the layout being wrong here. It
is correct now and this doesn't need to change. We're only talking about
the determination of the minimal (and so initial) size of the sizer.

Regards,
VZ

Michael Stratmann

unread,
May 11, 2010, 11:50:16 AM5/11/10
to wx-dev
Hello,

On 11 Mai, 12:55, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Tue, 11 May 2010 10:32:56 +0100 Julian Smart <jul...@anthemion.co.uk> wrote:

> JS> What I don't quite understand about this is, how can you get the
> JS> required layout using stretch factors if you don't know what the dialog
> JS> size should be?
>
>  Right now only by specifying the minimal sizes explicitly (which is what,
> I guess, you mean by "kludging").

That ruins a lot, when the app runs on a PC with bigger default font
size. E.g. I want two columns 1:1. Considering T10N I can not even say
for sure which column is bigger, or even which size is needed at all
(French usually needs more space ...).

As result I would have to code myself what the sizers did for me in
2.8.

>
> JS> So I guess it comes down to whether proportion takes priority over min
> JS> size, or vice versa.
>
>  Not quite, min sizes must be always respected. It's rather the question of
> whether the proportions are vital enough to make the window (possibly
> significantly) bigger to accommodate them or not. Personally I really don't
> know the right answer as I practically never use proportions other than 0
> and 1 anyhow. In fact I'd be curious to know what people use any higher
> proportions for.

Even proportions 1:1 are not guaranteed now, because min has prio.
Effectively proportions are ignored to determine window size. They are
only used when there is enough space. Unfortunately this applies
recursively to the "critical path" of sizers, which can vary (font,
T10N). So in most windows some sizers do not have the desired
proportions.

Of course there are generic workarounds, e.g. wxGridSizer.

For me the plain sizers were most intuitive. To use a wxGridBagSizer
just to enforce 1:2 looks like overkill to me. When I need to add or
remove a column it's close to painful, compared to just adding sth
with proportion 1 in the right sizer.

Btw I have a usecase with proportions 1:1:1:1:1:1:1 and 2:2:3 inside a
staticbox. And I had a dialog with three columns, but columns grouped
1:2 inside two static boxes. A technical app with about 30 dialogs
full of checkboxes and comboctrls (up to 80 in a notebook page) to
view or configure HW state and parameters.

>
> JS> How about a flag wxPRIORITIZE_PROPORTION which makes the total min size
> JS> take proportion into account?
>
>  Oh no, please not another flag. If you think/there is consensus that this
> is the right behaviour let's just implement it like this. FWIW it shouldn't
> be very difficult neither, wxBoxSizer::CalcMin() should just calculate the
> least common multiple of proportions and then the min size would be easy to
> compute. Which doesn't mean that I wouldn't appreciate if someone else than
> me did it...
>
> JS> Or, automatically make this the behaviour if any min sizes are violated
> JS> by a lack of space?
>
>  Min sizes are never violated by a lack of space unless the available space
> is less than the sum of min sizes in which case proportions are really the
> last of your problems.

For dialogs I agree, but frame size is not adjusted (neither in 2.8),
so min sizes are violated. Is that wanted?

>
>  Just to be clear: we're not talking about the layout being wrong here. It
> is correct now and this doesn't need to change. We're only talking about
> the determination of the minimal (and so initial) size of the sizer.

I think so, too.

Would appreciate more opinions on this, maybe my app's design is just
too uncommon and min window size is really preferred over proportions
by the majority.

Regards,
Michael

Vadim Zeitlin

unread,
May 11, 2010, 4:07:27 PM5/11/10
to wx-...@googlegroups.com
On Tue, 11 May 2010 08:50:16 -0700 (PDT) Michael Stratmann <Stra...@MicSt.de> wrote:

MS> That ruins a lot, when the app runs on a PC with bigger default font
MS> size. E.g. I want two columns 1:1. Considering T10N I can not even say
MS> for sure which column is bigger, or even which size is needed at all
MS> (French usually needs more space ...).

This is a very good point which I didn't at all think about. And it does
indeed prove that we should calculate the minimal sizer size taking the
proportions into account.

So fixing wxBoxSizer::CalcMin() becomes critical. I'll do it before 3.0
but, again, if anybody can help with this [sooner] it would certainly be
very welcome.

MS> >  Min sizes are never violated by a lack of space unless the available space
MS> > is less than the sum of min sizes in which case proportions are really the
MS> > last of your problems.
MS>
MS> For dialogs I agree, but frame size is not adjusted (neither in 2.8),
MS> so min sizes are violated. Is that wanted?

Sorry, I still don't see what do you mean by this, could you please
explain?

Thanks,
VZ

Michael Stratmann

unread,
May 11, 2010, 4:55:46 PM5/11/10
to wx-dev
Hello,

On 11 Mai, 22:07, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Tue, 11 May 2010 08:50:16 -0700 (PDT) Michael Stratmann <Stratm...@MicSt.de> wrote:
>
> MS> That ruins a lot, when the app runs on a PC with bigger default font
> MS> size. E.g. I want two columns 1:1. Considering T10N I can not even say
> MS> for sure which column is bigger, or even which size is needed at all
> MS> (French usually needs more space ...).
>
>  This is a very good point which I didn't at all think about. And it does
> indeed prove that we should calculate the minimal sizer size taking the
> proportions into account.
>
>  So fixing wxBoxSizer::CalcMin() becomes critical. I'll do it before 3.0

Thank you very much!

> but, again, if anybody can help with this [sooner] it would certainly be
> very welcome.

I do not feel qualified :-|

>
> MS> >  Min sizes are never violated by a lack of space unless the available space
> MS> > is less than the sum of min sizes in which case proportions are really the
> MS> > last of your problems.
> MS>
> MS> For dialogs I agree, but frame size is not adjusted (neither in 2.8),
> MS> so min sizes are violated. Is that wanted?
>
>  Sorry, I still don't see what do you mean by this, could you please
> explain?

At main panel size(-1, -1), a wxFrame always gets about 400x240 small.
Independent from its panel's content (e.g. 500x300 big). See Julian's
sample without the SetClientSize() line.

I do not need that, just that I am irritated and curious, why frame
size is not adjusted according to panel min size and thus sizers' min
sizes are violated.

Vadim Zeitlin

unread,
May 11, 2010, 5:55:18 PM5/11/10
to wx-...@googlegroups.com
On Tue, 11 May 2010 13:55:46 -0700 (PDT) Michael Stratmann <Stra...@MicSt.de> wrote:

MS> > but, again, if anybody can help with this [sooner] it would certainly be
MS> > very welcome.
MS>
MS> I do not feel qualified :-|

It really shouldn't be difficult, this is just plain C++ code, no GUI
involved. It just needs time to do and test it properly.

MS> >  Sorry, I still don't see what do you mean by this, could you please
MS> > explain?
MS>
MS> At main panel size(-1, -1), a wxFrame always gets about 400x240 small.
MS> Independent from its panel's content (e.g. 500x300 big). See Julian's
MS> sample without the SetClientSize() line.
MS>
MS> I do not need that, just that I am irritated and curious, why frame
MS> size is not adjusted according to panel min size and thus sizers' min
MS> sizes are violated.

Sorry, still not clear what exactly is wrong here. If you use a sizer and
call SetSizerAndFit() the frame does adjust to the sizer min size. I don't
know what is Julian's sample but maybe you could make a tiny patch (please
see http://trac.wxwidgets.org/wiki/HowToSubmitPatches) to the minimal
sample showing what you mean?

Regards,
VZ

Reply all
Reply to author
Forward
0 new messages