//----------------------------------------------------------------------------// bool ScrollablePane::handleContentAreaChange(const EventArgs&) { Scrollbar* vertScrollbar = getVertScrollbar(); Scrollbar* horzScrollbar = getHorzScrollbar(); // get updated extents of the content Rect contentArea(getScrolledContainer()->getContentArea()); // calculate any change on the top and left edges. float xChange = contentArea.d_left - d_contentRect.d_left; float yChange = contentArea.d_top - d_contentRect.d_top; // store new content extents information d_contentRect = contentArea; configureScrollbars(); // update scrollbar positions (which causes container pane to be moved as needed). horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition() - xChange); 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; }
//----------------------------------------------------------------------------// 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 ScrollablePane::removeChild_impl(Element* element) { Window* wnd = static_cast<Window*>(element); if (wnd->isAutoWindow()) { // This is an internal widget, so should be removed normally. Window::removeChild_impl(wnd); } // this is a client window/widget, so should be removed from the pane // container. else { // container should always be valid by the time we're handling client // controls getScrolledContainer()->removeChild(wnd); } }
//----------------------------------------------------------------------------// void ScrollablePane::addChild_impl(Window* wnd) { // null is not a valid window pointer! assert(wnd != 0); // See if this is an internally generated window // (will have AutoWidgetNameSuffix in the name) if (wnd->getName().find(AutoWidgetNameSuffix) != String::npos) { // This is an internal widget, so should be added normally. Window::addChild_impl(wnd); } // this is a client window/widget, so should be added to the pane container. else { // container should always be valid by the time we're adding client // controls getScrolledContainer()->addChildWindow(wnd); } }
//----------------------------------------------------------------------------// 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(); }
//----------------------------------------------------------------------------// void ScrollablePane::addChild_impl(Element* element) { Window* wnd = dynamic_cast<Window*>(element); if (!wnd) CEGUI_THROW(InvalidRequestException( "ScrollablePane can only have Elements of " "type Window added as children (Window path: " + getNamePath() + ").")); if (wnd->isAutoWindow()) { // This is an internal widget, so should be added normally. Window::addChild_impl(wnd); } // this is a client window/widget, so should be added to the pane container. else { // container should always be valid by the time we're adding client // controls getScrolledContainer()->addChild(wnd); } }
//----------------------------------------------------------------------------// void ScrollablePane::setContentPaneArea(const Rectf& area) { getScrolledContainer()->setContentArea(area); }
//----------------------------------------------------------------------------// const Rectf& ScrollablePane::getContentPaneArea(void) const { return getScrolledContainer()->getContentArea(); }
//----------------------------------------------------------------------------// const ScrolledContainer* ScrollablePane::getContentPane(void) const { return getScrolledContainer(); }
//----------------------------------------------------------------------------// void ScrollablePane::setContentPaneAutoSized(bool setting) { getScrolledContainer()->setContentPaneAutoSized(setting); }
//----------------------------------------------------------------------------// bool ScrollablePane::isContentPaneAutoSized(void) const { return getScrolledContainer()->isContentPaneAutoSized(); }