wxGrid and wxSizer issue 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.
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

wxGrid and wxSizer issue

Post by Morat20 »

I seem to be making a simple mistake somewhere in my sizers dealing with a single grid. That grid, which may be one or more rows, is "wider" than the the vertical column it's embedded into, so it correctly creates a horizontal scrollbar.

The problem is that scrollbar promptly covers the last row of the grid, which may be the only row of the grid. If I add the grid to the sizer with the wxExpand flag, the grid sizer will expand vertically (it has plenty of room), adding a ton of absolutely useless white space between the last row of the grid and the horizontal scrollbar at the bottom.

I am clearly doing something stupid.

Here's the basic code:

myColumnSizer1 = new wxBoxSizer(wxVertical); //this is a vertical column with lots of controls

//lots of controls added to the column here that work properly

myGridSizer = new wxBoxSizer(wxHORIZONTAL); //this is needed, for reasons unrelated to the current problem.
myGridSizer->Add(ReallyWideGrid,0,wxALIGN_LEFT|wxEXPAND|wxALL,1);
myColumnSizer1->Add(myGridSizer,1,wxALIGN_LEFT|wxEXPAND|wxAll,1);

//add more controls below that also work properly

ListOfColumnSizer->Add(myColumnSizer1,1,wxEXPAND|wxALL,1);
mainSizer->Add(ListOfColumnSizer,1,wxBOTTOM|wxEXPAND|wxAll,1);
myPanel->SetSizer(mainSizer);
myPanel->Layout();
myPanel->Refresh();


That "ReallyWideGrid" will simply not display correctly. I have a choice between one row, covered by the horizontal scrollbar, or all that empty space between the grid and the scrollbar! If I cut the columns down so there's no need for a horizontal scrollbar, it works fine. Fits properly and everything.

As best I can tell, the sizer is simply not accounting for the height of the scrollbar at all when I make a layout() call. If I "stretch" the screen wide enough to eliminate the horizontal scrollbar the grid fits perfectly (when not using the wxEXPAND flag). I'm hestitant to define max and min sizes as the number of columns fluctuates, as does the number of rows.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxGrid and wxSizer issue

Post by ONEEYEMAN »

Hi,
Did you look at the grid sample?

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

Can you try to create a small, compilable sample or at least show a screenshot?

Probably unrelated, but still worth mentioning:
Flags like wxALIGN_LEFT or wxALIGN_RIGHT make no sense in a horizontal(!) boxsizer. In newer wxWidgets version this should have caused an assert. Which wxWidgets version are you using?
Use the source, Luke!
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

Re: wxGrid and wxSizer issue

Post by Morat20 »

doublemax wrote:Can you try to create a small, compilable sample or at least show a screenshot?

Probably unrelated, but still worth mentioning:
The wxALIGN_* flags and wxEXPAND are mutually exclusive. In newer wxWidgets version this should have caused an assert. Which wxWidgets version are you using?

Flags like wxALIGN_LEFT or wxALIGN_RIGHT make no sense in a horizontal(!) boxsizer. If you don't understand why, think about it for a while and it should become obvious.
2.9.5, which I cannot update at this point. (And yes, I know those particular flags don't make sense. Cleaning them out of the cut and paste job I'm dealing with is a task for after the crude layout work is done.)

I can try to put together a small version of this sufficient to release, but I'm working with...really old code that was half-done in sizers and half-done in static layouts, and I'm trying to make it all work dynamically.

I guess what I really don't get is that without the wxEXPAND flag, the grid height is off by exactly the height of the scrollbar. But if use the flag, the grid expands far taller than it needs to be to accommodate all the rows. And since there is a control directly beneath it, I can physically see there is plenty of vertical room.

So why isn't sizer properly adjusting for the height of the scrollbar?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

How about adding the wxALWAYS_SHOW_SB style flag as a workaround?
Use the source, Luke!
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

Re: wxGrid and wxSizer issue

Post by Morat20 »

doublemax wrote:How about adding the wxALWAYS_SHOW_SB style flag as a workaround?
If I add that to the grid, the grid then works perfectly -- all rows shown, even as I add rows. Of course, I can't get to half the columns now (the horizontal scrollbar should be there).

So at least that confirms the problem -- for some reason the containing sizer is not correctly adjusting for the scrollbar height. There is suffient room for the sizer to grow vertically (adding rows shows that), the problem is that overlap.

I have scoured the code looking for some sort of static resizing (as noted, this is me converting older code to work purely on sizers) that might be interfering and cannot find anything involving this grid.

It honestly seems like the scrollbar is being turned on without a Layout() and Refresh() call.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

How many items does the grid typically have? Maybe you can calculate and set a reasonable minimum height based on wxGrid::GetDefaultRowSize().
Use the source, Luke!
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

Re: wxGrid and wxSizer issue

Post by Morat20 »

doublemax wrote:How many items does the grid typically have? Maybe you can calculate and set a reasonable minimum height based on wxGrid::GetDefaultRowSize().
Between 1 and 4 rows, either of 7 or 16 columns.

Does GetDefaultRowSize() adjust for font size?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

Does GetDefaultRowSize() adjust for font size?
Probably not. But if you have so few rows, you can get each individual row height with wxGrid::GetRowSize ( row ).
Use the source, Luke!
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

Re: wxGrid and wxSizer issue

Post by Morat20 »

doublemax wrote:
Does GetDefaultRowSize() adjust for font size?
Probably not. But if you have so few rows, you can get each individual row height with wxGrid::GetRowSize ( row ).
Yeah, I can work around all that. I'll have to grab a cell, check it's height, check the height of the label, get the scrollbar height, figure out if the scrollbar is even there...

I simply don't understand why the sizer isn't taking into account the scrollbar height when it's being laid out. Disabling scrollbars makes it fit perfectly, everything working exactly as it should, the layout like you'd expect.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxGrid and wxSizer issue

Post by ONEEYEMAN »

Hi,
Probably because grid doesn't have a initial/best size.

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

I simply don't understand why the sizer isn't taking into account the scrollbar height when it's being laid out.
It's not the sizer's fault. wxGrid reports a "best size", that's the size needed to display everything without scrollbars. The problem in your case is that the content fits in one direction, but not the other.

I would calculate the minimum height as m_grid->GetBestSize().y + wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y).

In the worst case you'll have some extra space below the last line.
Use the source, Luke!
Morat20
Knows some wx things
Knows some wx things
Posts: 41
Joined: Tue Jan 07, 2014 8:43 pm

Re: wxGrid and wxSizer issue

Post by Morat20 »

doublemax wrote:
I simply don't understand why the sizer isn't taking into account the scrollbar height when it's being laid out.
It's not the sizer's fault. wxGrid reports a "best size", that's the size needed to display everything without scrollbars. The problem in your case is that the content fits in one direction, but not the other.

I would calculate the minimum height as m_grid->GetBestSize().y + wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y).

In the worst case you'll have some extra space below the last line.
I see. Unfortunately as I have a variable number of rows, I end up with a lot of extra space. I've got two functions, one which effectivly doubles the number of columns, and one which increases the number of rows (from 1 to 4, depending on what is selected) and that returns a size big enough to hold the all four plus some.

I think I see a way to do it that'll minimize white space, which will involve abusing min/max sizes (since I can calculate that very effectively whenever appending a column or changing the row count), and I suppose just guessing on whether a scrollbar is there.

Do you happen to have a link on how BestSize (and InitialSize) are used by wxWidgets when doing dynamic layouts? Or is this just "dig into the code and have fun" sort of thing?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

Do you happen to have a link on how BestSize (and InitialSize) are used by wxWidgets when doing dynamic layouts?
Not really, only this: http://docs.wxwidgets.org/trunk/overview_sizer.html

But there is not much to know anyway. All controls have 3 sizes that are used by the sizer algorithm: A "best" size, a minimum size and a maximum size. And a sizer will try to obey them all, but it's not always possible.

The only "hidden" feature is: If you pass a size to a control's constructor, this size will be also set as the minimum size.
Use the source, Luke!
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxSizer issue

Post by doublemax »

I see. Unfortunately as I have a variable number of rows, I end up with a lot of extra space.
Just recalculate the minimum size each time the number of rows changes and do a Layout().
Use the source, Luke!
Post Reply