wxGrid and wxSizer issue Topic is solved
wxGrid and wxSizer issue
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.
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.
Re: wxGrid and wxSizer issue
Hi,
Did you look at the grid sample?
Thank you.
Did you look at the grid sample?
Thank you.
Re: wxGrid and wxSizer issue
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?
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!
Re: wxGrid and wxSizer issue
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.)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.
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?
Re: wxGrid and wxSizer issue
How about adding the wxALWAYS_SHOW_SB style flag as a workaround?
Use the source, Luke!
Re: wxGrid and wxSizer issue
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).doublemax wrote:How about adding the wxALWAYS_SHOW_SB style flag as a workaround?
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.
Re: wxGrid and wxSizer issue
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!
Re: wxGrid and wxSizer issue
Between 1 and 4 rows, either of 7 or 16 columns.doublemax wrote:How many items does the grid typically have? Maybe you can calculate and set a reasonable minimum height based on wxGrid::GetDefaultRowSize().
Does GetDefaultRowSize() adjust for font size?
Re: wxGrid and wxSizer issue
Probably not. But if you have so few rows, you can get each individual row height with wxGrid::GetRowSize ( row ).Does GetDefaultRowSize() adjust for font size?
Use the source, Luke!
Re: wxGrid and wxSizer issue
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...doublemax wrote:Probably not. But if you have so few rows, you can get each individual row height with wxGrid::GetRowSize ( row ).Does GetDefaultRowSize() adjust for font size?
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.
Re: wxGrid and wxSizer issue
Hi,
Probably because grid doesn't have a initial/best size.
Thank you.
Probably because grid doesn't have a initial/best size.
Thank you.
Re: wxGrid and wxSizer issue
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 simply don't understand why the sizer isn't taking into account the scrollbar height when it's being laid out.
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!
Re: wxGrid and wxSizer issue
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.doublemax wrote: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 simply don't understand why the sizer isn't taking into account the scrollbar height when it's being laid out.
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 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?
Re: wxGrid and wxSizer issue
Not really, only this: http://docs.wxwidgets.org/trunk/overview_sizer.htmlDo you happen to have a link on how BestSize (and InitialSize) are used by wxWidgets when doing dynamic layouts?
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!
Re: wxGrid and wxSizer issue
Just recalculate the minimum size each time the number of rows changes and do a Layout().I see. Unfortunately as I have a variable number of rows, I end up with a lot of extra space.
Use the source, Luke!