wxGrid with virtual storage and multirow or multicolumn cells
I’m working on a project that uses wxWidgets as a GUI library. In it, I have a grid (wxGrid class) that has some of the
cells that span multiple columns. Now, it’s very simple to make it
work when you have a regular wxGrid. But,
when you use virtual storage, you need to go through some steps to make
sure multi-column span is done right.
There is no documentation
on how to do this, so I first googled, and failing to find the explanation
like the one I’m about to write now, I experimented. Finally, when
some things just didn’t work right, I had to dig into the wxGrid
code to find out what is the correct way to do it.
If you ever
used virtual grid, you know that you need to have a class that derives
from wxGridTableBase. I have
it, and in my class I override the function GetAttr to get various
effects at runtime (saving both on memory and speed). In this function
you can set the cell attributes (color, font style, etc.) by reading
the info from your own virtual storage (this can be very useful if
you want, say, negative numbers to be red). Anyway, in this class
you use an object of class wxGridCellAttr, set its attributes
and return pointer to it. Make sure you use cellAttriM->IncRef(); before
exiting, since the caller will call DecRef() after using the info to
render the cell on screen.
Now, on to the cells that span
multiple columns or rows. To create a cell like that, you need to
set the attribute for that cell, but also for all cells
it ‘covers’. All this is done via SetSize() function on wxGridCellAttr
object.
Let’s take for example a cell that spans one
column and two rows: a cell at coordinates (3,5). This means that
cell at coordinate (3,6) would be covered by this. So, for the
cell at (3,5) you need to use:
cellAttr->SetSize(2, 1);
and for the cell at (3,6), you need to use:
cellAttr->SetSize(-1, 0);
This -1 and 0 is crucial for selection and cursor movement to work correctly. If your cell spans even more cells, you need to SetSize for all of them. For example, if the cell in above example would span 3 rows, the row at (3,7) would need to use:
cellAttr->SetSize(-2, 0);
Hopefully, something like this will be added to wx manual one day. Until that happens, read my blog ;)
Tweet to @mbabuskov Tweet Milan Babuškov, 2008-09-16