I've adapted
void Listbox::ensureItemIsVisible(size_t item_index) and
void Listbox::ensureItemIsVisible(const ListboxItem* item) to a MultiColumnList object (and replaced the
i variable with a
row). It should be fairly easy to move this code within the MultiColumnList code.
What I'm unsure of (I have not looked enough at v0.5.0 yet) is whether the height is the same for every ListboxItem of a row, in which case the code below should be final, otherwise we'd have to iterate through each item on that row and find the highest.
Code: Select all
void ensureItemIsVisible(const CEGUI::MultiColumnList* multiColumnList, const CEGUI::ListboxItem* listboxItem)
{
ensureItemIsVisible(multiColumnList, multiColumnList->getItemRowIndex(listboxItem));
}
void ensureItemIsVisible(const CEGUI::MultiColumnList* multiColumnList, const CEGUI::uint& rowID)
{
using namespace CEGUI;
Scrollbar* vertScrollbar = multiColumnList->getVertScrollbar();
// handle simple "scroll to the bottom" case
if (rowID >= multiColumnList->getRowCount())
{
vertScrollbar->setScrollPosition(vertScrollbar->getDocumentSize() - vertScrollbar->getPageSize());
}
else
{
float bottom;
float listHeight = multiColumnList->getListRenderArea().getHeight();
float top = 0;
// get height to top of item
CEGUI::uint row;
for (row = 0; row < rowID; ++row)
{
MCLGridRef grid_ref(row, 0);
top += multiColumnList->getItemAtGridReference(grid_ref)->getPixelSize().d_height;
//top += d_listItems[i]->getPixelSize().d_height;
}
// calculate height to bottom of item
MCLGridRef grid_ref(row, 0);
bottom = top + multiColumnList->getItemAtGridReference(grid_ref)->getPixelSize().d_height;
//bottom = top + d_listItems[i]->getPixelSize().d_height;
// account for current scrollbar value
float currPos = vertScrollbar->getScrollPosition();
top -= currPos;
bottom -= currPos;
// if top is above the view area, or if item is too big to fit
if ((top < 0.0f) || ((bottom - top) > listHeight))
{
// scroll top of item to top of box.
vertScrollbar->setScrollPosition(currPos + top);
}
// if bottom is below the view area
else if (bottom >= listHeight)
{
// position bottom of item at the bottom of the list
vertScrollbar->setScrollPosition(currPos + bottom - listHeight);
}
// Item is already fully visible - nothing more to do.
}
}