wxSizer doesn't free space when hidden Topic is solved

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
Viking
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jan 13, 2009 5:58 pm

wxSizer doesn't free space when hidden

Post by Viking »

Hi to everybody,

I've made an application which uses three wxFlexGridSizer (in one column and three rows). I want to be able to hide the middle one in order to reduce the window height. It works partially, as I can hide it, but the bottom one take the space the other sizer occupied (it is the only one growable).

This could be correct if I could resize this third sizer so the total height was smaller than it was in the beginning. However, I can't reduce it more than I could when the middle sizer was visible, so, in the end, the minimum size of the window is exactly the same as when all the sizers are visible.

Sorry for my english. Just to resume it a little, my problem is I can't reduce the window size, even if I hide one of the wxFlexGridSizer.

I've read I should use wxADJUST_MINSIZE, but didn't work. I've tried to manually change the control sizes with SetSize too, but didn't work, either. I'm not an expert, so, please, any orientation would be welcome.

Thanks in advance,
Vik.
User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch »

First of all, if you only have one column, consider using a vertical wxBoxSizer to simplify things.

Otherwise, modifying the sizer would not resize the window. If you want the window to shrink after removing/hiding an item, try calling Fit()
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

I've just been through this a few weeks ago. A simple sizerMain::Layout() does it ! (with sizerMain as the root sizer which contains the just-hidden control).
User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch »

I'm almost positive that Layout() does not resize the window, in which case he'd have the same problem he's having (the bottom cell grows to fill the gap rather than the whole window shrinking).
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

wxWidgets manual :
wxSizer::Layout
void Layout()
Call this to force layout of the children anew, e.g. after having added a child to or removed a child (window, other sizer or space) from the sizer while keeping the current dimension.
Viking
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jan 13, 2009 5:58 pm

Post by Viking »

First, thanks for your help.

Disch is right. Maybe I'm using it the wrong way, but Layout() only updates the sizers position, but without changing the window size.

I've made a quick example in case you want to see what is my problem. Basically, I have one wxBoxSizer (as suggested by Disch) which contains three wxFlexGridSizer (I'll have several rows and columns in my program). The first wxFlexGridSizer contains one checkbox that, when checked, hides the second one.

Then, after using Layout(), the third sizer takes up the space left by the second one, but the window size still remains the same. I can't resize the third sizer, neither, to make it smaller than that.

In order not to making you compile anything, I've taken two screenshots to show this effect. Note that I can make the window bigger in any of two, but no smaller.

So I guess I should go with the Fit() solution, but I have problems to get the parent window (sorry, I'm still learning wxWidgets!).

The important parts of the code:

Code: Select all

// This is where wxWidgets creates the window, but parent is NULL, because it is (?) the on top window (parent->Fit() would crash).
Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));

Code: Select all

void SizerExampleFrame::OnCheckBox1Click(wxCommandEvent& event)
{
    if (CheckBox1->GetValue())
        BoxSizer1->Hide(FlexGridSizer2);
    else
        BoxSizer1->Show(FlexGridSizer2);
    BoxSizer1->Layout();

    // Doing "this->Fit();" doesn't do anything.
    // Same result doing "BoxSizer1->Fit(this);".
    // However, doing this change the background color, so it is the correct parent or not?
    // wxColour mybgcolor;
    // mybgcolor.Set(wxT("#ffffff"));
    // this->SetBackgroundColour(mybgcolor);
}
So, is it my problem that I'm not doing the Fit() to the correct parent window, or is it in the sizer definition?

Thank you very much for your help!
Vik.
Attachments
SizerExample.zip
Source code.
(10.58 KiB) Downloaded 112 times
Sizer shown. Now the window can grow up (the text will grow too), but can't shrink.
Sizer shown. Now the window can grow up (the text will grow too), but can't shrink.
Sizer_shown.png (6.05 KiB) Viewed 4112 times
Sizer hidden. As before, the window can grow up, but it can't shrink.
Sizer hidden. As before, the window can grow up, but it can't shrink.
Sizer_hidden.png (5.03 KiB) Viewed 4112 times
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Hi,

it is perfectly normal that the text area grows if you marked it as growable; if you want it to retain the same dimensions, try using wxWindow methods setting min and max size. The sizers should honour them.

The main problem i see is that it's not clear whether you want the text to be growable or fixed-size
User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch »

Fit() resizes the window to be the supplied minimum size -- often set by SetMinSize(), but can also be set by SetSizeHints().

In your SizerExampleFrame ctor (SizerExampleMain.cpp : line 87) you're calling SetSizeHints on your supplied sizer, which is setting the minimum size for the frame to match the size of the sizer with the additional controls. This prevents the frame from becoming any smaller. Therefore when you remove the controls, the window cannot shrink because the min size is still the same as it was when the control were there.

To get around this problem, you can do one of the following:

A) don't call SetSizeHints() in your ctor. This will allow the frame to shrink when you call Fit().

or

B) call SetSizeHints() again when controls are hidden (or visible again). You can do this in your sample code by slipping the call to SetSizeHints() after the call to Layout() in OnCheckBox1Click.
Viking
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jan 13, 2009 5:58 pm

Post by Viking »

Hi, Auria,

In fact I want both. I want the text to be quite small, but leaving the option to the user to resize it (so, if the user resize the window only the text grows). If the user wants even more space, he can disable the middle part of the window, and so the windows will be smaller, but still resizable.

In the end, what I want is the "hidden sizer" screenshot I've posted, but with the textcontrol size the "shown sizer" has (resulting in a smaller window). The user could resize this window to be as big as it is now in the "hidden sizer" screenshot, but my problem is that now I can't reduce that size.

I've faked a screenshot of what i want. If I resize this window, the text would grow as desired. Right now I can't get to this window size.

Thanks again for your help,
Vik.
Attachments
I can't get to this size.
I can't get to this size.
What_I_Want.png (4.7 KiB) Viewed 4102 times
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

Ok, i hadn't really understood what you were looking for (nor than what Disch said). Layout() does not resize the window. And that's not what you want, it is ? You want the window to be resize ?
Viking
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jan 13, 2009 5:58 pm

Post by Viking »

Disch wrote:Fit() resizes the window to be the supplied minimum size -- often set by SetMinSize(), but can also be set by SetSizeHints().
Awesome, Disch! Works like a charm! Nice explanation, I didn't notice how wxSmith was implementing the sizer.

Thank you very much for your help,
Vik.
Viking
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jan 13, 2009 5:58 pm

Post by Viking »

TrV wrote:You want the window to be resize ?
Yes, TrV, I want something so the user can dinamically choose the size of the window (smaller window with less controls, bigger window with more options), but always leaving a way to grow a text control which shows the result of the calculations.

I've marked the post as solved. Thanks to everybody for your help!
Vik.
User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch »

No problem.

Just a correction I feel I should make:

I think Fit actually sets the window size to the best size... which isn't necessarily the minimum size -- I shouldnt've said that in my earlier post (see wxWindow::GetBestSize()). However the window can't be resized to be smaller than the minimum size.

So yeah, little correction there. But I'm glad you got it working :D
Post Reply