/************************************************************************* Initialise the Window based object ready for use. *************************************************************************/ void ComboDropList::initialiseComponents(void) { Listbox::initialiseComponents(); // set-up scroll bars so they return capture to us. getVertScrollbar()->setRestoreOldCapture(true); getHorzScrollbar()->setRestoreOldCapture(true); // ban these properties from being written getVertScrollbar()->banPropertyFromXML("RestoreOldCapture"); getHorzScrollbar()->banPropertyFromXML("RestoreOldCapture"); }
/************************************************************************* Initialise the Window based object ready for use. *************************************************************************/ void ComboDropList::initialiseComponents(void) { ListWidget::initialiseComponents(); // set-up scroll bars so they return capture to us. getVertScrollbar()->setRestoreOldCapture(true); getHorzScrollbar()->setRestoreOldCapture(true); // ban these properties from being written getVertScrollbar()->banPropertyFromXMLRecursive(Window::RestoreOldCapturePropertyName); getHorzScrollbar()->banPropertyFromXMLRecursive(Window::RestoreOldCapturePropertyName); }
//----------------------------------------------------------------------------// bool ScrollablePane::handleContentAreaChange(const EventArgs&) { // get updated extents of the content const Rectf contentArea(getScrolledContainer()->getContentArea()); // calculate any change on the top and left edges. const float xChange = contentArea.d_min.d_x - d_contentRect.d_min.d_x; const float yChange = contentArea.d_min.d_y - d_contentRect.d_min.d_y; // store new content extents information d_contentRect = contentArea; configureScrollbars(); // update scrollbar positions (which causes container pane to be moved as needed). Scrollbar* const horzScrollbar = getHorzScrollbar(); horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition() - xChange); Scrollbar* const vertScrollbar = getVertScrollbar(); vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition() - yChange); // this call may already have been made if the scroll positions changed. The call // is required here for cases where the top/left 'bias' has changed; in which // case the scroll position notification may or may not have been fired. if (xChange || yChange) updateContainerPosition(); // fire event WindowEventArgs args(this); onContentPaneChanged(args); return true; }
/************************************************************************* Initialise the Window based object ready for use. *************************************************************************/ void ComboDropList::initialiseComponents(void) { Listbox::initialiseComponents(); // set-up scroll bars so they return capture to us. getVertScrollbar()->setRestoreCapture(true); getHorzScrollbar()->setRestoreCapture(true); }
/************************************************************************ Configure scroll bars ************************************************************************/ void ScrolledItemListBase::configureScrollbars(const Size& doc_size) { Scrollbar* v = getVertScrollbar(); Scrollbar* h = getHorzScrollbar(); Size render_area_size = getItemRenderArea().getSize(); // setup the pane size float pane_size_w = ceguimax(doc_size.d_width, render_area_size.d_width); UVector2 pane_size(cegui_absdim(pane_size_w), cegui_absdim(doc_size.d_height)); d_pane->setMinSize(pane_size); d_pane->setMaxSize(pane_size); //d_pane->setWindowSize(pane_size); // "fix" scrollbar visibility if (d_forceVScroll || doc_size.d_height > render_area_size.d_height) { v->show(); } else { v->hide(); } //render_area_size = getItemRenderArea().getSize(); if (d_forceHScroll || doc_size.d_width > render_area_size.d_width) { h->show(); } else { h->hide(); } // get a fresh item render area Rect render_area = getItemRenderArea(); render_area_size = render_area.getSize(); // update the pane clipper area static_cast<ClippedContainer*>(d_pane)->setClipArea(render_area); // setup vertical scrollbar v->setDocumentSize(doc_size.d_height); v->setPageSize(render_area_size.d_height); v->setStepSize(ceguimax(1.0f, render_area_size.d_height / 10.0f)); v->setScrollPosition(v->getScrollPosition()); // setup horizontal scrollbar h->setDocumentSize(doc_size.d_width); h->setPageSize(render_area_size.d_width); h->setStepSize(ceguimax(1.0f, render_area_size.d_width / 10.0f)); h->setScrollPosition(h->getScrollPosition()); }
/************************************************************************* Initialise the Window based object ready for use. *************************************************************************/ void Listbox::initialiseComponents(void) { // get the component sub-widgets Scrollbar* vertScrollbar = getVertScrollbar(); Scrollbar* horzScrollbar = getHorzScrollbar(); vertScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&Listbox::handle_scrollChange, this)); horzScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&Listbox::handle_scrollChange, this)); configureScrollbars(); performChildWindowLayout(); }
//----------------------------------------------------------------------------// void ScrollablePane::updateContainerPosition(void) { // basePos is the position represented by the scrollbars // (these are negated so pane is scrolled in the correct directions) UVector2 basePos(cegui_absdim(-getHorzScrollbar()->getScrollPosition()), cegui_absdim(-getVertScrollbar()->getScrollPosition())); // this bias is the absolute position that 0 on the scrollbars represent. // Allows the pane to function correctly with negatively positioned content. UVector2 bias(cegui_absdim(d_contentRect.d_min.d_x), cegui_absdim(d_contentRect.d_min.d_y)); // set the new container pane position to be what the scrollbars request // minus any bias generated by the location of the content. getScrolledContainer()->setPosition(basePos - bias); }
//----------------------------------------------------------------------------// void ScrolledItemListBase::ensureItemIsVisibleHorz(const ItemEntry& item) { const Rect render_area = getItemRenderArea(); Scrollbar* const h = getHorzScrollbar(); const float currPos = h->getScrollPosition(); const float left = item.getXPosition().asAbsolute(this->getPixelSize().d_width) - currPos; const float right = left + item.getItemPixelSize().d_width; // if left is left of the view area, or if item too big, scroll item to left if ((left < render_area.d_left) || ((right - left) > render_area.getWidth())) h->setScrollPosition(currPos + left); // if right is right of the view area, scroll item to right of list else if (right >= render_area.d_right) h->setScrollPosition(currPos + right - render_area.getWidth()); }
/************************************************************************ Initialise ************************************************************************/ void ScrolledItemListBase::initialiseComponents() { // Only process the content pane if it hasn't been done in the past // NOTE: This ensures that a duplicate content pane is not created. An example where // this would be possible would be when changing the Look'N'Feel of the widget // (for instance an ItemListBox), an operation which would reconstruct the child components // of the widget by destroying the previous ones and creating new ones with the // new Look'N'Feel. However, since the content pane is not defined in the // look and feel file and thus not associated with the look'N'Feel itself // but instead created here manually, the destruction would not contemplate the content // pane itself, so when the children would be rebuilt, a duplicate content pane // would be attempted (and an exception would be issued). if(!d_pane) { // IMPORTANT: // we must do this before the base class handling or we'll lose the onChildRemoved subscriber!!! d_pane = WindowManager::getSingletonPtr()->createWindow("ClippedContainer", d_name+ContentPaneNameSuffix); // set up clipping static_cast<ClippedContainer*>(d_pane)->setClipperWindow(this); addChildWindow(d_pane); } // base class handling ItemListBase::initialiseComponents(); // set default pane position Rect r = getItemRenderArea(); d_pane->setPosition(UVector2(cegui_absdim(r.d_left),cegui_absdim(r.d_top))); // init scrollbars Scrollbar* v = getVertScrollbar(); Scrollbar* h = getHorzScrollbar(); v->setAlwaysOnTop(true); h->setAlwaysOnTop(true); v->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&ScrolledItemListBase::handle_VScroll,this)); h->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&ScrolledItemListBase::handle_HScroll,this)); v->hide(); h->hide(); }
//----------------------------------------------------------------------------// void ScrollablePane::configureScrollbars(void) { // controls should all be valid by this stage Scrollbar* const vertScrollbar = getVertScrollbar(); Scrollbar* const horzScrollbar = getHorzScrollbar(); const bool horzScrollBarWasVisible = horzScrollbar->isVisible(); const bool vertScrollBarWasVisible = vertScrollbar->isVisible(); // enable required scrollbars vertScrollbar->setVisible(isVertScrollbarNeeded()); horzScrollbar->setVisible(isHorzScrollbarNeeded()); // Check if the addition of the horizontal scrollbar means we // now also need the vertical bar. if (horzScrollbar->isVisible()) vertScrollbar->setVisible(isVertScrollbarNeeded()); if (horzScrollBarWasVisible != horzScrollbar->isVisible() || vertScrollBarWasVisible != vertScrollbar->isVisible()) { ElementEventArgs args(this); onSized(args); } performChildWindowLayout(); // get viewable area const Rectf viewableArea(getViewableArea()); // set up vertical scroll bar values vertScrollbar->setDocumentSize(fabsf(d_contentRect.getHeight())); vertScrollbar->setPageSize(viewableArea.getHeight()); vertScrollbar->setStepSize(ceguimax(1.0f, viewableArea.getHeight() * d_vertStep)); vertScrollbar->setOverlapSize(ceguimax(1.0f, viewableArea.getHeight() * d_vertOverlap)); vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition()); // set up horizontal scroll bar values horzScrollbar->setDocumentSize(fabsf(d_contentRect.getWidth())); horzScrollbar->setPageSize(viewableArea.getWidth()); horzScrollbar->setStepSize(ceguimax(1.0f, viewableArea.getWidth() * d_horzStep)); horzScrollbar->setOverlapSize(ceguimax(1.0f, viewableArea.getWidth() * d_horzOverlap)); horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition()); }
/************************************************************************* Handler for mouse wheel changes *************************************************************************/ void Listbox::onMouseWheel(MouseEventArgs& e) { // base class processing. Window::onMouseWheel(e); Scrollbar* vertScrollbar = getVertScrollbar(); Scrollbar* horzScrollbar = getHorzScrollbar(); if (vertScrollbar->isVisible() && (vertScrollbar->getDocumentSize() > vertScrollbar->getPageSize())) { vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition() + vertScrollbar->getStepSize() * -e.wheelChange); } else if (horzScrollbar->isVisible() && (horzScrollbar->getDocumentSize() > horzScrollbar->getPageSize())) { horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition() + horzScrollbar->getStepSize() * -e.wheelChange); } ++e.handled; }
//----------------------------------------------------------------------------// void ScrollablePane::initialiseComponents(void) { // get horizontal scrollbar Scrollbar* horzScrollbar = getHorzScrollbar(); // get vertical scrollbar Scrollbar* vertScrollbar = getVertScrollbar(); // get scrolled container widget ScrolledContainer* container = getScrolledContainer(); // do a bit of initialisation horzScrollbar->setAlwaysOnTop(true); vertScrollbar->setAlwaysOnTop(true); // container pane is always same size as this parent pane, // scrolling is actually implemented via positioning and clipping tricks. container->setSize(USize(cegui_reldim(1.0f), cegui_reldim(1.0f))); // subscribe to events we need to hear about vertScrollbar->subscribeEvent( Scrollbar::EventScrollPositionChanged, Event::Subscriber(&ScrollablePane::handleScrollChange, this)); horzScrollbar->subscribeEvent( Scrollbar::EventScrollPositionChanged, Event::Subscriber(&ScrollablePane::handleScrollChange, this)); d_contentChangedConn = container->subscribeEvent( ScrolledContainer::EventContentChanged, Event::Subscriber(&ScrollablePane::handleContentAreaChange, this)); d_autoSizeChangedConn = container->subscribeEvent( ScrolledContainer::EventAutoSizeSettingChanged, Event::Subscriber(&ScrollablePane::handleAutoSizePaneChanged, this)); // finalise setup configureScrollbars(); }
//----------------------------------------------------------------------------// ModelIndex TreeView::indexAtRecursive(TreeViewItemRenderingState& item, float& cur_height, const glm::vec2& window_position, bool& handled, TreeViewItemAction action) { float next_height = cur_height + item.d_size.d_height; if (window_position.y >= cur_height && window_position.y <= next_height) { handled = true; float expander_width = getViewRenderer()->getSubtreeExpanderSize().d_width; float base_x = getViewRenderer()->getSubtreeExpanderXIndent(item.d_nestedLevel); base_x -= getHorzScrollbar()->getScrollPosition(); if (window_position.x >= base_x && window_position.x <= base_x + expander_width) { (this->*action)(item, true); return ModelIndex(); } (this->*action)(item, false); return ModelIndex(d_itemModel->makeIndex(item.d_childId, item.d_parentIndex)); } cur_height = next_height; for (size_t i = 0; i < item.d_renderedChildren.size(); ++i) { ModelIndex index = indexAtRecursive(*item.d_renderedChildren.at(i), cur_height, window_position, handled, action); if (handled) return index; } return ModelIndex(); }
void CPFRotatingText::renderRotatingText() { Font* font = d_window->getFont(); // can't render text without a font :) if( font==NULL){ return; } // get destination area for the text. Rect absarea(getTextRenderArea()); Rect clipper(absarea); float textHeight = font->getFormattedLineCount(d_window->getText(), absarea, (TextFormatting)d_horzFormatting) * font->getLineSpacing(); Scrollbar* vertScrollbar = getVertScrollbar(); Scrollbar* horzScrollbar = getHorzScrollbar(); // calculate X offset static float xOffset = horzScrollbar->getPageSize(); if( xOffset<-(horzScrollbar->getDocumentSize()+horzScrollbar->getPageSize()) ){ xOffset = horzScrollbar->getPageSize(); } static boost::system_time previous_time = boost::get_system_time(); boost::system_time time = boost::get_system_time(); boost::system_time::time_duration_type time_step = (time-previous_time); xOffset -= (static_cast<float>(time_step.total_milliseconds())*d_textSpeed); previous_time = time; absarea.offset(Point(xOffset, 0)); // see if we may need to adjust horizontal position if( horzScrollbar->isVisible() ){ switch(d_horzFormatting) { case LeftAligned: case WordWrapLeftAligned: case Justified: case WordWrapJustified: absarea.offset(Point(-horzScrollbar->getScrollPosition(), 0)); break; case Centred: case WordWrapCentred: absarea.setWidth(horzScrollbar->getDocumentSize()); absarea.offset(Point(-horzScrollbar->getScrollPosition(), 0)); break; case RightAligned: case WordWrapRightAligned: absarea.offset(Point(horzScrollbar->getScrollPosition(), 0)); break; } } // adjust y positioning according to formatting option switch(d_vertFormatting) { case TopAligned: absarea.d_top -= vertScrollbar->getScrollPosition(); break; case VertCentred: // if scroll bar is in use, act like TopAligned if( vertScrollbar->isVisible() ){ absarea.d_top -= vertScrollbar->getScrollPosition(); } // no scroll bar, so centre text instead. else{ absarea.d_top += PixelAligned((absarea.getHeight() - textHeight) * 0.5f); } break; case BottomAligned: absarea.d_top = absarea.d_bottom - textHeight; absarea.d_top += vertScrollbar->getScrollPosition(); break; } // offset the font little down so that it's centered within its own spacing absarea.d_top += (font->getLineSpacing() - font->getFontHeight()) * 0.5f; // calculate final colours ColourRect final_cols(d_textCols); final_cols.modulateAlpha(d_window->getEffectiveAlpha()); // cache the text for rendering. d_window->getRenderCache().cacheText(d_window->getText(), font, (TextFormatting)d_horzFormatting, absarea, 0, final_cols, &clipper); }
/************************************************************************* 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()); }
//----------------------------------------------------------------------------// float ScrollablePane::getHorizontalScrollPosition(void) const { Scrollbar* horzScrollbar = getHorzScrollbar(); float docSz = horzScrollbar->getDocumentSize(); return (docSz != 0) ? horzScrollbar->getScrollPosition() / docSz : 0.0f; }
//----------------------------------------------------------------------------// void ScrollablePane::setHorizontalScrollPosition(float position) { Scrollbar* horzScrollbar = getHorzScrollbar(); horzScrollbar->setScrollPosition( horzScrollbar->getDocumentSize() * position); }
//----------------------------------------------------------------------------// float ScrollablePane::getHorizontalScrollPosition(void) const { return getHorzScrollbar()->getUnitIntervalScrollPosition(); }
//----------------------------------------------------------------------------// void ScrollablePane::setHorizontalScrollPosition(float position) { getHorzScrollbar()->setUnitIntervalScrollPosition(position); }