Button-in-sizer problem

I fixed a sizer problem I was having with a button, but don't understand
why it didn't work in the first place.

If I add the button like so:
  sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL)
Then one row of pixels from the top and bottom each are missing. You can
see this here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-bad.png

But if I add like this:
  sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL|wxGROW)
Then I can see the whole button. See here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-good.png

Platform is wxPython 2407, Python 222, Mandrake 9. Code attached.

Why did I have to add wxGROW to make the whole button appear? (wxEXPAND
works as well)

I *think* the following should hold true:
  * sizers should respect the minimum size of a control
  * buttons should report a minimum size that includes their decorative
    outline, regardless of what flags were used to add to the sizer

So is this a bug, or am I missing something?

sizer-problem.py (851 Bytes)

···

--
Chuck
http://ChuckEsterbrook.com

Chuck Esterbrook wrote:

I fixed a sizer problem I was having with a button, but don't understand why it didn't work in the first place.

If I add the button like so:
  sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL)
Then one row of pixels from the top and bottom each are missing. You can see this here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-bad.png

But if I add like this:
  sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL|wxGROW)
Then I can see the whole button. See here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-good.png

Platform is wxPython 2407, Python 222, Mandrake 9. Code attached.

Why did I have to add wxGROW to make the whole button appear? (wxEXPAND works as well)

I *think* the following should hold true:
  * sizers should respect the minimum size of a control
  * buttons should report a minimum size that includes their decorative
    outline, regardless of what flags were used to add to the sizer

So is this a bug, or am I missing something?

Sort of, and yes.

First of all, the sizers don't clip the windows they contain, they only resize them. If you resized the button to be smaller than it's best size then it would just draw itself smaller. The true minimum size is a lot smaller than what you show in your screen shots.

Sizers use either the default size of a control, (the size it had when it was Add()ed to the sizer) or if the flag wxADJUST_MINSIZE is given then it calls the control's GetBestSize at every Layout() and uses that as the item's min size.

So in your example the problem is not that the sizer isn't allowing the button to draw itself, it's that the default size of the panel the button is on is (20,20) or something like that. So when topPanel is added to the outer sizer that sizer treats the min size of the topPanel as 20 pixels high and so it never makes it any bigger. So it is the topPanel that is clipping the button, (set its background color and it becomes obvious.) Adding a call to sizer.Fit(topPanel) enlarges the panel to be big enough for its sizer's min size, and then that will be the panel's min size in the sizer it is added too. (Lost yet? :wink: ) I'm not totally sure what about adding the wxGROW causes it to do the right thing, probably an extra iteration through the sizer algorithm or something.

The default DoGetBestSize for wxWindow will use the sizer if it has one to calculate the window's best size based on the min size of all the sizer items. So another way (and perhaps the best way) to solve this problem is to use the wxADJUST_MINSIZE flag when adding the panel to the outersizer, then the panel's sizer will get used to calculate the layout for all of the components.

The underlying issue here is that sizer calculations are normally only recursive if the item is a nested sizer, not if the item is a window. Adding the wxADJUST_MINSIZE flag for a window that has its own sizer allows the layout calc to cross that boundary and be recursive down through the sizer that belongs to the window item too.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

[snip]

I appreciate the explanation. After digesting it thoroughly, I'll
reconsider how I'm constructing my windows.

But for the record, I have to state:

   I hate sizers. Too much voo doo.

I welcome alternate proposals for managing windows (er, "views", not
frames!). Otherwise, I'll eventually propose something myself. :slight_smile:
But I don't have a strong handle on the situation yet.

Geez, if layout constraints were really harder to use than sizers I can
only imagine what that was like!

···

On Friday 11 April 2003 12:45 pm, Robin Dunn wrote:

Chuck Esterbrook wrote:
> I fixed a sizer problem I was having with a button, but don't
> understand why it didn't work in the first place.
>
> If I add the button like so:
> sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL)
> Then one row of pixels from the top and bottom each are missing.
> You can see this here:
> http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/
>button-bad.png
>
> But if I add like this:
> sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL|wxGROW)
> Then I can see the whole button. See here:
> http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/
>button-good.png
>
> Platform is wxPython 2407, Python 222, Mandrake 9. Code attached.
>
> Why did I have to add wxGROW to make the whole button appear?
> (wxEXPAND works as well)
>
> I *think* the following should hold true:
> * sizers should respect the minimum size of a control
> * buttons should report a minimum size that includes their
> decorative outline, regardless of what flags were used to add to
> the sizer
>
> So is this a bug, or am I missing something?

Sort of, and yes.

--
Chuck
http://ChuckEsterbrook.com

Sizers are your friend. They can even be fun. :slight_smile:

http://mindwrapper.org/prelim/pretutorial.html#controls

Cheers,

···

--- Chuck Esterbrook <ChuckEsterbrook@yahoo.com> wrote:

   I hate sizers. Too much voo doo.

=====
Donnal Walter
Arkansas Children's Hospital