/************************************************************************* Return the ListboxItem under the given window local pixel co-ordinate. *************************************************************************/ ListboxItem* Listbox::getItemAtPoint(const Point& pt) const { Rect renderArea(getListRenderArea()); // point must be within the rendering area of the Listbox. if (renderArea.isPointInRect(pt)) { float y = renderArea.d_top - getVertScrollbar()->getScrollPosition(); // test if point is above first item if (pt.d_y >= y) { for (size_t i = 0; i < getItemCount(); ++i) { y += d_listItems[i]->getPixelSize().d_height; if (pt.d_y < y) { return d_listItems[i]; } } } } return 0; }
void FalagardListbox::render() { Listbox* lb = (Listbox*)d_window; // render frame and stuff before we handle the items cacheListboxBaseImagery(); // // Render list items // Vector3 itemPos; Size itemSize; Rect itemClipper, itemRect; float widest = lb->getWidestItemWidth(); // calculate position of area we have to render into Rect itemsArea(getListRenderArea()); // set up some initial positional details for items itemPos.d_x = itemsArea.d_left - lb->getHorzScrollbar()->getScrollPosition(); itemPos.d_y = itemsArea.d_top - lb->getVertScrollbar()->getScrollPosition(); itemPos.d_z = System::getSingleton().getRenderer()->getZLayer(3) - System::getSingleton().getRenderer()->getCurrentZ(); float alpha = lb->getEffectiveAlpha(); // loop through the items size_t itemCount = lb->getItemCount(); for (size_t i = 0; i < itemCount; ++i) { ListboxItem* listItem = lb->getListboxItemFromIndex(i); itemSize.d_height = listItem->getPixelSize().d_height; // allow item to have full width of box if this is wider than items itemSize.d_width = ceguimax(itemsArea.getWidth(), widest); // calculate destination area for this item. itemRect.d_left = itemPos.d_x; itemRect.d_top = itemPos.d_y; itemRect.setSize(itemSize); itemClipper = itemRect.getIntersection(itemsArea); // skip this item if totally clipped if (itemClipper.getWidth() == 0) { itemPos.d_y += itemSize.d_height; continue; } // draw this item listItem->draw(lb->getRenderCache(), itemRect, itemPos.d_z, alpha, &itemClipper); // update position ready for next item itemPos.d_y += itemSize.d_height; } }
/************************************************************************* Perform the actual rendering for this Window. *************************************************************************/ void Listbox::populateRenderCache() { // get the derived class to render general stuff before we handle the items cacheListboxBaseImagery(); // // Render list items // Vector3 itemPos; Size itemSize; Rect itemClipper, itemRect; float widest = getWidestItemWidth(); // calculate position of area we have to render into Rect itemsArea(getListRenderArea()); // set up some initial positional details for items itemPos.d_x = itemsArea.d_left - d_horzScrollbar->getScrollPosition(); itemPos.d_y = itemsArea.d_top - d_vertScrollbar->getScrollPosition(); itemPos.d_z = System::getSingleton().getRenderer()->getZLayer(3) - System::getSingleton().getRenderer()->getCurrentZ(); float alpha = getEffectiveAlpha(); // loop through the items size_t itemCount = getItemCount(); for (size_t i = 0; i < itemCount; ++i) { itemSize.d_height = d_listItems[i]->getPixelSize().d_height; // allow item to have full width of box if this is wider than items itemSize.d_width = ceguimax(itemsArea.getWidth(), widest); // calculate destination area for this item. itemRect.d_left = itemPos.d_x; itemRect.d_top = itemPos.d_y; itemRect.setSize(itemSize); itemClipper = itemRect.getIntersection(itemsArea); // skip this item if totally clipped if (itemClipper.getWidth() == 0) { itemPos.d_y += itemSize.d_height; continue; } // draw this item d_listItems[i]->draw(d_renderCache, itemRect, itemPos.d_z, alpha, &itemClipper); // update position ready for next item itemPos.d_y += itemSize.d_height; } }
/************************************************************************* Ensure the item at the specified index is visible within the list box. *************************************************************************/ void Listbox::ensureItemIsVisible(size_t item_index) { Scrollbar* vertScrollbar = getVertScrollbar(); // handle simple "scroll to the bottom" case if (item_index >= getItemCount()) { vertScrollbar->setScrollPosition(vertScrollbar->getDocumentSize() - vertScrollbar->getPageSize()); } else { float bottom; float listHeight = getListRenderArea().getHeight(); float top = 0; // get height to top of item size_t i; for (i = 0; i < item_index; ++i) { top += d_listItems[i]->getPixelSize().d_height; } // calculate height to bottom of item 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. } }
void FalagardMultiColumnList::render() { MultiColumnList* w = (MultiColumnList*)d_window; const ListHeader* header = w->getListHeader(); const Scrollbar* vertScrollbar = w->getVertScrollbar(); const Scrollbar* horzScrollbar = w->getHorzScrollbar(); // render general stuff before we handle the items cacheListboxBaseImagery(); // // Render list items // Vector3f itemPos; Sizef itemSize; Rectf itemClipper, itemRect; // calculate position of area we have to render into Rectf itemsArea(getListRenderArea()); // set up initial positional details for items itemPos.d_y = itemsArea.top() - vertScrollbar->getScrollPosition(); itemPos.d_z = 0.0f; const float alpha = w->getEffectiveAlpha(); // loop through the items for (uint i = 0; i < w->getRowCount(); ++i) { // set initial x position for this row. itemPos.d_x = itemsArea.left() - horzScrollbar->getScrollPosition(); // calculate height for this row. itemSize.d_height = w->getHighestRowItemHeight(i); // loop through the columns in this row for (uint j = 0; j < w->getColumnCount(); ++j) { // allow item to use full width of the column itemSize.d_width = CoordConverter::asAbsolute(header->getColumnWidth(j), header->getPixelSize().d_width); ListboxItem* item = w->getItemAtGridReference(MCLGridRef(i,j)); // is the item for this column set? if (item) { // calculate destination area for this item. itemRect.left(itemPos.d_x); itemRect.top(itemPos.d_y); itemRect.setSize(itemSize); itemClipper = itemRect.getIntersection(itemsArea); // skip this item if totally clipped if (itemClipper.getWidth() == 0) { itemPos.d_x += itemSize.d_width; continue; } // draw this item item->draw(w->getGeometryBuffer(), itemRect, alpha, &itemClipper); } // update position for next column. itemPos.d_x += itemSize.d_width; } // update position ready for next row itemPos.d_y += itemSize.d_height; } }
/************************************************************************* display required integrated scroll bars according to current state of the list box and update their values. *************************************************************************/ void Listbox::configureScrollbars(void) { Scrollbar* vertScrollbar = getVertScrollbar(); Scrollbar* horzScrollbar = getHorzScrollbar(); float totalHeight = getTotalItemsHeight(); float widestItem = getWidestItemWidth(); // // First show or hide the scroll bars as needed (or requested) // // show or hide vertical scroll bar as required (or as specified by option) if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll) { vertScrollbar->show(); // show or hide horizontal scroll bar as required (or as specified by option) if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll) { horzScrollbar->show(); } else { horzScrollbar->hide(); } } else { // show or hide horizontal scroll bar as required (or as specified by option) if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll) { horzScrollbar->show(); // show or hide vertical scroll bar as required (or as specified by option) if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll) { vertScrollbar->show(); } else { vertScrollbar->hide(); } } else { vertScrollbar->hide(); horzScrollbar->hide(); } } // // Set up scroll bar values // Rect renderArea(getListRenderArea()); vertScrollbar->setDocumentSize(totalHeight); vertScrollbar->setPageSize(renderArea.getHeight()); vertScrollbar->setStepSize(ceguimax(1.0f, renderArea.getHeight() / 10.0f)); vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition()); horzScrollbar->setDocumentSize(widestItem); horzScrollbar->setPageSize(renderArea.getWidth()); horzScrollbar->setStepSize(ceguimax(1.0f, renderArea.getWidth() / 10.0f)); horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition()); }
/************************************************************************* display required integrated scroll bars according to current state of the list box and update their values. *************************************************************************/ void Listbox::configureScrollbars(void) { Scrollbar* vertScrollbar; Scrollbar* horzScrollbar; try { vertScrollbar = static_cast<Scrollbar*>(WindowManager::getSingleton().getWindow(getName() + "__auto_vscrollbar__")); horzScrollbar = static_cast<Scrollbar*>(WindowManager::getSingleton().getWindow(getName() + "__auto_hscrollbar__")); } catch (UnknownObjectException) { // no scrollbars? Can't configure then! return; } float totalHeight = getTotalItemsHeight(); float widestItem = getWidestItemWidth(); // // First show or hide the scroll bars as needed (or requested) // // show or hide vertical scroll bar as required (or as specified by option) if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll) { vertScrollbar->show(); // show or hide horizontal scroll bar as required (or as specified by option) if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll) { horzScrollbar->show(); } else { horzScrollbar->hide(); } } else { // show or hide horizontal scroll bar as required (or as specified by option) if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll) { horzScrollbar->show(); // show or hide vertical scroll bar as required (or as specified by option) if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll) { vertScrollbar->show(); } else { vertScrollbar->hide(); } } else { vertScrollbar->hide(); horzScrollbar->hide(); } } // // Set up scroll bar values // Rect renderArea(getListRenderArea()); vertScrollbar->setDocumentSize(totalHeight); vertScrollbar->setPageSize(renderArea.getHeight()); vertScrollbar->setStepSize(ceguimax(1.0f, renderArea.getHeight() / 10.0f)); vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition()); horzScrollbar->setDocumentSize(widestItem); horzScrollbar->setPageSize(renderArea.getWidth()); horzScrollbar->setStepSize(ceguimax(1.0f, renderArea.getWidth() / 10.0f)); horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition()); }