From 9ec432034dc3c45d7ce763eb02dae4cc7f6b8da8 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Sun, 21 Jun 2009 08:04:56 +0000 Subject: merge -r 122421-124917 viewer-2.0.0-2 -> viewer-2.0.0-3 ignore-dead-branch --- indra/llui/llscrollcontainer.cpp | 317 ++++++++++++++++++--------------------- 1 file changed, 143 insertions(+), 174 deletions(-) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index cf03259879..2a2e56a92c 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -1,6 +1,6 @@ /** * @file llscrollcontainer.cpp - * @brief LLScrollableContainerView base class + * @brief LLScrollContainer base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -33,8 +33,12 @@ #include "linden_common.h" -#include "llrender.h" #include "llscrollcontainer.h" + +#include "llrender.h" +#include "llcontainerview.h" +// #include "llfolderview.h" +#include "llscrollingpanellist.h" #include "llscrollbar.h" #include "llui.h" #include "llkeyboard.h" @@ -42,6 +46,7 @@ #include "llfocusmgr.h" #include "llframetimer.h" #include "lluictrlfactory.h" +#include "llpanel.h" #include "llfontgl.h" ///---------------------------------------------------------------------------- @@ -55,98 +60,79 @@ static const F32 MAX_AUTO_SCROLL_RATE = 500.f; static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; ///---------------------------------------------------------------------------- -/// Class LLScrollableContainerView +/// Class LLScrollContainer ///---------------------------------------------------------------------------- -static LLRegisterWidget r("scroll_container"); +static LLDefaultWidgetRegistry::Register r("scroll_container"); -// Default constructor -LLScrollableContainerView::LLScrollableContainerView( const std::string& name, - const LLRect& rect, - LLView* scrolled_view, - BOOL is_opaque, - const LLColor4& bg_color ) : - LLUICtrl( name, rect, FALSE, NULL, NULL ), - mScrolledView( scrolled_view ), - mIsOpaque( is_opaque ), - mBackgroundColor( bg_color ), - mReserveScrollCorner( FALSE ), - mAutoScrolling( FALSE ), - mAutoScrollRate( 0.f ) +LLScrollContainer::Params::Params() +: is_opaque("opaque"), + bg_color("color"), + reserve_scroll_corner("reserve_scroll_corner", false) { - if( mScrolledView ) - { - addChild( mScrolledView ); - } - - init(); + name = "scroll_container"; + mouse_opaque(true); + tab_stop(false); } -// LLUICtrl constructor -LLScrollableContainerView::LLScrollableContainerView( const std::string& name, const LLRect& rect, - LLUICtrl* scrolled_ctrl, BOOL is_opaque, - const LLColor4& bg_color) : - LLUICtrl( name, rect, FALSE, NULL, NULL ), - mScrolledView( scrolled_ctrl ), - mIsOpaque( is_opaque ), - mBackgroundColor( bg_color ), - mReserveScrollCorner( FALSE ), - mAutoScrolling( FALSE ), - mAutoScrollRate( 0.f ) -{ - if( scrolled_ctrl ) - { - addChild( scrolled_ctrl ); - } - - init(); -} -void LLScrollableContainerView::init() +// Default constructor +LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) +: LLUICtrl(p), + mAutoScrolling( FALSE ), + mAutoScrollRate( 0.f ), + mBackgroundColor(p.bg_color()), + mIsOpaque(p.is_opaque), + mReserveScrollCorner(p.reserve_scroll_corner), + mScrolledView(NULL) { + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); - mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN ); - addChild( mBorder ); + LLViewBorder::Params params; + params.name("scroll border"); + params.rect(border_rect); + params.bevel_type(LLViewBorder::BEVEL_IN); + mBorder = LLUICtrlFactory::create (params); + LLView::addChild( mBorder ); mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.stretch( -mBorder->getBorderWidth() ); LLRect vertical_scroll_rect = mInnerRect; - vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE; - mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"), - vertical_scroll_rect, - LLScrollbar::VERTICAL, - mInnerRect.getHeight(), - 0, - mInnerRect.getHeight(), - NULL, this, - VERTICAL_MULTIPLE); - addChild( mScrollbar[VERTICAL] ); + vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size; + LLScrollbar::Params sbparams; + sbparams.name("scrollable vertical"); + sbparams.rect(vertical_scroll_rect); + sbparams.orientation(LLScrollbar::VERTICAL); + sbparams.doc_size(mInnerRect.getHeight()); + sbparams.doc_pos(0); + sbparams.page_size(mInnerRect.getHeight()); + sbparams.step_size(VERTICAL_MULTIPLE); + mScrollbar[VERTICAL] = LLUICtrlFactory::create (sbparams); + LLView::addChild( mScrollbar[VERTICAL] ); mScrollbar[VERTICAL]->setVisible( FALSE ); mScrollbar[VERTICAL]->setFollowsRight(); mScrollbar[VERTICAL]->setFollowsTop(); mScrollbar[VERTICAL]->setFollowsBottom(); LLRect horizontal_scroll_rect = mInnerRect; - horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE; - mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"), - horizontal_scroll_rect, - LLScrollbar::HORIZONTAL, - mInnerRect.getWidth(), - 0, - mInnerRect.getWidth(), - NULL, this, - HORIZONTAL_MULTIPLE); - addChild( mScrollbar[HORIZONTAL] ); + horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size; + sbparams.name("scrollable horizontal"); + sbparams.rect(horizontal_scroll_rect); + sbparams.orientation(LLScrollbar::HORIZONTAL); + sbparams.doc_size(mInnerRect.getWidth()); + sbparams.doc_pos(0); + sbparams.page_size(mInnerRect.getWidth()); + sbparams.step_size(VERTICAL_MULTIPLE); + mScrollbar[HORIZONTAL] = LLUICtrlFactory::create (sbparams); + LLView::addChild( mScrollbar[HORIZONTAL] ); mScrollbar[HORIZONTAL]->setVisible( FALSE ); mScrollbar[HORIZONTAL]->setFollowsLeft(); mScrollbar[HORIZONTAL]->setFollowsRight(); - - setTabStop(FALSE); } // Destroys the object -LLScrollableContainerView::~LLScrollableContainerView( void ) +LLScrollContainer::~LLScrollContainer( void ) { // mScrolledView and mScrollbar are child views, so the LLView // destructor takes care of memory deallocation. @@ -159,9 +145,9 @@ LLScrollableContainerView::~LLScrollableContainerView( void ) // internal scrollbar handlers // virtual -void LLScrollableContainerView::scrollHorizontal( S32 new_pos ) +void LLScrollContainer::scrollHorizontal( S32 new_pos ) { - //llinfos << "LLScrollableContainerView::scrollHorizontal()" << llendl; + //llinfos << "LLScrollContainer::scrollHorizontal()" << llendl; if( mScrolledView ) { LLRect doc_rect = mScrolledView->getRect(); @@ -171,9 +157,9 @@ void LLScrollableContainerView::scrollHorizontal( S32 new_pos ) } // virtual -void LLScrollableContainerView::scrollVertical( S32 new_pos ) +void LLScrollContainer::scrollVertical( S32 new_pos ) { - // llinfos << "LLScrollableContainerView::scrollVertical() " << new_pos << llendl; + // llinfos << "LLScrollContainer::scrollVertical() " << new_pos << llendl; if( mScrolledView ) { LLRect doc_rect = mScrolledView->getRect(); @@ -183,7 +169,7 @@ void LLScrollableContainerView::scrollVertical( S32 new_pos ) } // LLView functionality -void LLScrollableContainerView::reshape(S32 width, S32 height, +void LLScrollContainer::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape( width, height, called_from_parent ); @@ -209,8 +195,17 @@ void LLScrollableContainerView::reshape(S32 width, S32 height, } } -BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask) +BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) { + // allow scrolled view to handle keystrokes in case it delegated keyboard focus + // to the scroll container. + // NOTE: this should not recurse indefinitely as handleKeyHere + // should not propagate to parent controls, so mScrolledView should *not* + // call LLScrollContainer::handleKeyHere in turn + if (mScrolledView->handleKeyHere(key, mask)) + { + return TRUE; + } for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) { if( mScrollbar[i]->handleKeyHere(key, mask) ) @@ -222,7 +217,7 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask) return FALSE; } -BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) +BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) { for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) { @@ -239,7 +234,7 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) return TRUE; } -BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const +BOOL LLScrollContainer::needsToScroll(S32 x, S32 y, LLScrollContainer::SCROLL_ORIENTATION axis) const { if(mScrollbar[axis]->getVisible()) { @@ -247,7 +242,8 @@ BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContaine const S32 AUTOSCROLL_SIZE = 10; if(mScrollbar[axis]->getVisible()) { - inner_rect_local.mRight -= SCROLLBAR_SIZE; + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + inner_rect_local.mRight -= scrollbar_size; inner_rect_local.mTop += AUTOSCROLL_SIZE; inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE; } @@ -260,13 +256,14 @@ BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContaine return FALSE; } -BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, +BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) { + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); // Scroll folder view if needed. Never accepts a drag or drop. *accept = ACCEPT_NO; BOOL handled = FALSE; @@ -278,11 +275,11 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); if( mScrollbar[HORIZONTAL]->getVisible() ) { - inner_rect_local.mBottom += SCROLLBAR_SIZE; + inner_rect_local.mBottom += scrollbar_size; } if( mScrollbar[VERTICAL]->getVisible() ) { - inner_rect_local.mRight -= SCROLLBAR_SIZE; + inner_rect_local.mRight -= scrollbar_size; } if( mScrollbar[HORIZONTAL]->getVisible() ) @@ -337,7 +334,7 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, } -BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) +BOOL LLScrollContainer::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) { S32 local_x, local_y; for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) @@ -364,14 +361,15 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LL return TRUE; } -void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const +void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); } -void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const +void LLScrollContainer::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); @@ -382,26 +380,28 @@ void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *vi if( *visible_height < doc_height ) { *show_v_scrollbar = TRUE; - *visible_width -= SCROLLBAR_SIZE; + *visible_width -= scrollbar_size; } *show_h_scrollbar = FALSE; if( *visible_width < doc_width ) { *show_h_scrollbar = TRUE; - *visible_height -= SCROLLBAR_SIZE; + *visible_height -= scrollbar_size; // Must retest now that visible_height has changed if( !*show_v_scrollbar && (*visible_height < doc_height) ) { *show_v_scrollbar = TRUE; - *visible_width -= SCROLLBAR_SIZE; + *visible_width -= scrollbar_size; } } } + -void LLScrollableContainerView::draw() +void LLScrollContainer::draw() { + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); if (mAutoScrolling) { // add acceleration to autoscroll @@ -427,7 +427,7 @@ void LLScrollableContainerView::draw() if( mIsOpaque ) { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4fv( mBackgroundColor.mV ); + gGL.color4fv( mBackgroundColor.get().mV ); gl_rect_2d( mInnerRect ); } @@ -448,9 +448,9 @@ void LLScrollableContainerView::draw() calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); LLLocalClipRect clip(LLRect(mInnerRect.mLeft, - mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height, + mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height, visible_width, - mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) )); drawChild(mScrolledView); } @@ -487,10 +487,49 @@ void LLScrollableContainerView::draw() drawDebugRect(); } + //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview) + //std::set::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); + //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights)) + //{ + // drawDebugRect(); + //} + } // end draw -void LLScrollableContainerView::updateScroll() +bool LLScrollContainer::addChild(LLView* view, S32 tab_group) +{ + if (!mScrolledView) + { + //*TODO: Move LLFolderView to llui and enable this check +// if (dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view)) + { + // Use the first panel or container as the scrollable view (bit of a hack) + mScrolledView = view; + } + } + + bool ret_val = LLView::addChild(view, tab_group); + + //bring the scrollbars to the front + sendChildToFront( mScrollbar[HORIZONTAL] ); + sendChildToFront( mScrollbar[VERTICAL] ); + + return ret_val; +} + +const widget_registry_t& LLScrollContainer::getChildRegistry() const { + // a scroll container can contain any default widget + return LLDefaultWidgetRegistry::instance(); +} + +void LLScrollContainer::updateScroll() +{ + if (!mScrolledView) + { + return; + } + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); LLRect doc_rect = mScrolledView->getRect(); S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); @@ -514,15 +553,15 @@ void LLScrollableContainerView::updateScroll() S32 v_scrollbar_height = visible_height; if( !show_h_scrollbar && mReserveScrollCorner ) { - v_scrollbar_height -= SCROLLBAR_SIZE; + v_scrollbar_height -= scrollbar_size; } - mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE ); + mScrollbar[VERTICAL]->reshape( scrollbar_size, v_scrollbar_height, TRUE ); // Make room for the horizontal scrollbar (or not) S32 v_scrollbar_offset = 0; if( show_h_scrollbar || mReserveScrollCorner ) { - v_scrollbar_offset = SCROLLBAR_SIZE; + v_scrollbar_offset = scrollbar_size; } LLRect r = mScrollbar[VERTICAL]->getRect(); r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset ); @@ -552,9 +591,9 @@ void LLScrollableContainerView::updateScroll() S32 h_scrollbar_width = visible_width; if( !show_v_scrollbar && mReserveScrollCorner ) { - h_scrollbar_width -= SCROLLBAR_SIZE; + h_scrollbar_width -= scrollbar_size; } - mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE ); + mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, scrollbar_size, TRUE ); } else { @@ -571,17 +610,17 @@ void LLScrollableContainerView::updateScroll() mScrollbar[VERTICAL]->setPageSize( visible_height ); } // end updateScroll -void LLScrollableContainerView::setBorderVisible(BOOL b) +void LLScrollContainer::setBorderVisible(BOOL b) { mBorder->setVisible( b ); } // Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled) -void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset) +void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset) { if (!mScrolledView) { - llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl; + llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; return; } @@ -646,27 +685,27 @@ void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoo updateScroll(); } -void LLScrollableContainerView::pageUp(S32 overlap) +void LLScrollContainer::pageUp(S32 overlap) { mScrollbar[VERTICAL]->pageUp(overlap); } -void LLScrollableContainerView::pageDown(S32 overlap) +void LLScrollContainer::pageDown(S32 overlap) { mScrollbar[VERTICAL]->pageDown(overlap); } -void LLScrollableContainerView::goToTop() +void LLScrollContainer::goToTop() { mScrollbar[VERTICAL]->setDocPos(0); } -void LLScrollableContainerView::goToBottom() +void LLScrollContainer::goToBottom() { mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); } -S32 LLScrollableContainerView::getBorderWidth() const +S32 LLScrollContainer::getBorderWidth() const { if (mBorder) { @@ -676,73 +715,3 @@ S32 LLScrollableContainerView::getBorderWidth() const return 0; } -// virtual -LLXMLNodePtr LLScrollableContainerView::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLView::getXML(); - - // Attributes - - node->createChild("opaque", TRUE)->setBoolValue(mIsOpaque); - - if (mIsOpaque) - { - node->createChild("color", TRUE)->setFloatValue(4, mBackgroundColor.mV); - } - - // Contents - - LLXMLNodePtr child_node = mScrolledView->getXML(); - - node->addChild(child_node); - - return node; -} - -LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - std::string name("scroll_container"); - node->getAttributeString("name", name); - - LLRect rect; - createRect(node, rect, parent, LLRect()); - - BOOL opaque = FALSE; - node->getAttributeBOOL("opaque", opaque); - - LLColor4 color(0,0,0,0); - LLUICtrlFactory::getAttributeColor(node,"color", color); - - // Create the scroll view - LLScrollableContainerView *ret = new LLScrollableContainerView(name, rect, (LLPanel*)NULL, opaque, color); - - LLPanel* panelp = NULL; - - // Find a child panel to add - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) - { - LLView *control = factory->createCtrlWidget(panelp, child); - if (control && control->isPanel()) - { - if (panelp) - { - llinfos << "Warning! Attempting to put multiple panels into a scrollable container view!" << llendl; - delete control; - } - else - { - panelp = (LLPanel*)control; - } - } - } - - if (panelp == NULL) - { - panelp = new LLPanel(std::string("dummy"), LLRect::null, FALSE); - } - - ret->mScrolledView = panelp; - - return ret; -} -- cgit v1.2.3 From 52aeaa32841e7d0b37abab0a2a2540c2be2f16b7 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 7 Jul 2009 00:53:05 +0000 Subject: Merge skinning-14 to viewer-2, including refactoring many floaters to register them with LLFloaterReg, support for introspection of ParamBlock based UI widgets to dump XML schema, splitting llfolderview.cpp into three separate files to unravel dependencies and skeleton for for LLListView widget. Resolved conflicts in these files: lldraghandle.h, lluictrl.h, llchiclet.cpp, llfolderview.h/cpp, lliinventorybridge.cpp, llpanelpicks.cpp, llviewermenu.cpp, floater_mute.xml, floater_preferences.xml, notifications.xml, panel_preferences_audio.xml, panel_preferences_graphics1.xml, panel_region_general.xml svn merge -r124961:126284 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-14 --- indra/llui/llscrollcontainer.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 2a2e56a92c..ea4bd2526e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -63,7 +63,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; /// Class LLScrollContainer ///---------------------------------------------------------------------------- -static LLDefaultWidgetRegistry::Register r("scroll_container"); +static LLDefaultChildRegistry::Register r("scroll_container"); LLScrollContainer::Params::Params() : is_opaque("opaque"), @@ -91,7 +91,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); - params.bevel_type(LLViewBorder::BEVEL_IN); + params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create (params); LLView::addChild( mBorder ); @@ -517,12 +517,6 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) return ret_val; } -const widget_registry_t& LLScrollContainer::getChildRegistry() const -{ - // a scroll container can contain any default widget - return LLDefaultWidgetRegistry::instance(); -} - void LLScrollContainer::updateScroll() { if (!mScrolledView) -- cgit v1.2.3 From 923d84d08f98b33657d6bd861c34b985125db757 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 10 Jul 2009 20:43:08 +0000 Subject: EXT-127: Tooltips don't disappear immediately after moving mouse out of object reviewed by Austin --- indra/llui/llscrollcontainer.cpp | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index ea4bd2526e..402c050d2e 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -333,34 +333,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, return TRUE; } - -BOOL LLScrollContainer::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) -{ - S32 local_x, local_y; - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) - { - local_x = x - mScrollbar[i]->getRect().mLeft; - local_y = y - mScrollbar[i]->getRect().mBottom; - if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - // Handle 'child' view. - if( mScrolledView ) - { - local_x = x - mScrolledView->getRect().mLeft; - local_y = y - mScrolledView->getRect().mBottom; - if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) ) - { - return TRUE; - } - } - - // Opaque - return TRUE; -} - void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); @@ -500,12 +472,8 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) { if (!mScrolledView) { - //*TODO: Move LLFolderView to llui and enable this check -// if (dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view) || dynamic_cast(view)) - { - // Use the first panel or container as the scrollable view (bit of a hack) - mScrolledView = view; - } + // Use the first panel or container as the scrollable view (bit of a hack) + mScrolledView = view; } bool ret_val = LLView::addChild(view, tab_group); -- cgit v1.2.3 From 1db494f58ad378b8028c1f071196be82af5fe964 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Fri, 14 Aug 2009 01:15:46 +0000 Subject: * Added a few safety checks to LLScrollContainer * Minor change to LLIMView so that IM windows don't get hidden after they are displayed * Changed default action for avatar list to be IM as per spec * Fixed merge of home tab from avatar code. --- indra/llui/llscrollcontainer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 402c050d2e..6f1572eda5 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -202,7 +202,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) // NOTE: this should not recurse indefinitely as handleKeyHere // should not propagate to parent controls, so mScrolledView should *not* // call LLScrollContainer::handleKeyHere in turn - if (mScrolledView->handleKeyHere(key, mask)) + if (mScrolledView && mScrolledView->handleKeyHere(key, mask)) { return TRUE; } @@ -335,7 +335,7 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { - const LLRect& rect = mScrolledView->getRect(); + const LLRect& rect = getScrolledViewRect(); calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); } -- cgit v1.2.3 From 6b31bc72294d72d14e9761c9c05815081517e23b Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Sat, 15 Aug 2009 00:45:43 +0000 Subject: EXT-490 Voice device settings unsaved EXT-466 Statistics window is empty EXT-488 Minimap does not open --- indra/llui/llscrollcontainer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 6f1572eda5..0b455f8e17 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -65,6 +65,13 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; static LLDefaultChildRegistry::Register r("scroll_container"); +#include "llscrollingpanellist.h" +#include "llcontainerview.h" +#include "llpanel.h" +static ScrollContainerRegistry::Register r1("scrolling_panel_list"); +static ScrollContainerRegistry::Register r2("container_view"); +static ScrollContainerRegistry::Register r3("panel", &LLPanel::fromXML); + LLScrollContainer::Params::Params() : is_opaque("opaque"), bg_color("color"), -- cgit v1.2.3 From 138bf1132262c479dbbd5c95195db46b1efd065f Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 24 Aug 2009 20:04:52 +0000 Subject: merge -r 130399-131510 skinning-21 -> viewer-2.0.0-3 DEV-11254 DEV-11254 DEV-2003: DEV-21567 DEV-37301 EXT-104 EXT-138 EXT-217 EXT-256 EXT-259 EXT-259 EXT-328 EXT-348 EXT-386 EXT-399 EXT-403 EXT-460 EXT-492 EXT-492 EXT-531 EXT-537 EXT-684 improved text editor (handles multiple fonts simultaneously as well as inline widgets) --- indra/llui/llscrollcontainer.cpp | 247 ++++++++++++++++++++------------------- 1 file changed, 124 insertions(+), 123 deletions(-) (limited to 'indra/llui/llscrollcontainer.cpp') diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 0b455f8e17..13f862f3af 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -55,8 +55,6 @@ static const S32 HORIZONTAL_MULTIPLE = 8; static const S32 VERTICAL_MULTIPLE = 16; -static const F32 MIN_AUTO_SCROLL_RATE = 120.f; -static const F32 MAX_AUTO_SCROLL_RATE = 500.f; static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; ///---------------------------------------------------------------------------- @@ -75,6 +73,9 @@ static ScrollContainerRegistry::Register r3("panel", &LLPanel::fromXML) LLScrollContainer::Params::Params() : is_opaque("opaque"), bg_color("color"), + border_visible("border_visible"), + min_auto_scroll_rate("min_auto_scroll_rate", 100), + max_auto_scroll_rate("max_auto_scroll_rate", 1000), reserve_scroll_corner("reserve_scroll_corner", false) { name = "scroll_container"; @@ -91,6 +92,8 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) mBackgroundColor(p.bg_color()), mIsOpaque(p.is_opaque), mReserveScrollCorner(p.reserve_scroll_corner), + mMinAutoScrollRate(p.min_auto_scroll_rate), + mMaxAutoScrollRate(p.max_auto_scroll_rate), mScrolledView(NULL) { static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); @@ -98,6 +101,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); + params.visible(p.border_visible); params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create (params); LLView::addChild( mBorder ); @@ -115,12 +119,11 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) sbparams.doc_pos(0); sbparams.page_size(mInnerRect.getHeight()); sbparams.step_size(VERTICAL_MULTIPLE); + sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + sbparams.visible(false); + sbparams.change_callback(p.scroll_callback); mScrollbar[VERTICAL] = LLUICtrlFactory::create (sbparams); LLView::addChild( mScrollbar[VERTICAL] ); - mScrollbar[VERTICAL]->setVisible( FALSE ); - mScrollbar[VERTICAL]->setFollowsRight(); - mScrollbar[VERTICAL]->setFollowsTop(); - mScrollbar[VERTICAL]->setFollowsBottom(); LLRect horizontal_scroll_rect = mInnerRect; horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size; @@ -131,11 +134,11 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) sbparams.doc_pos(0); sbparams.page_size(mInnerRect.getWidth()); sbparams.step_size(VERTICAL_MULTIPLE); + sbparams.visible(false); + sbparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT); + sbparams.change_callback(p.scroll_callback); mScrollbar[HORIZONTAL] = LLUICtrlFactory::create (sbparams); LLView::addChild( mScrollbar[HORIZONTAL] ); - mScrollbar[HORIZONTAL]->setVisible( FALSE ); - mScrollbar[HORIZONTAL]->setFollowsLeft(); - mScrollbar[HORIZONTAL]->setFollowsRight(); } // Destroys the object @@ -181,7 +184,7 @@ void LLScrollContainer::reshape(S32 width, S32 height, { LLUICtrl::reshape( width, height, called_from_parent ); - mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); + mInnerRect = getLocalRect(); mInnerRect.stretch( -mBorder->getBorderWidth() ); if (mScrolledView) @@ -192,13 +195,14 @@ void LLScrollContainer::reshape(S32 width, S32 height, S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); mScrollbar[VERTICAL]->setPageSize( visible_height ); mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); mScrollbar[HORIZONTAL]->setPageSize( visible_width ); + updateScroll(); } } @@ -217,6 +221,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) { if( mScrollbar[i]->handleKeyHere(key, mask) ) { + updateScroll(); return TRUE; } } @@ -233,6 +238,7 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) // Pretend the mouse is over the scrollbar if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) { + updateScroll(); return TRUE; } } @@ -241,28 +247,6 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) return TRUE; } -BOOL LLScrollContainer::needsToScroll(S32 x, S32 y, LLScrollContainer::SCROLL_ORIENTATION axis) const -{ - if(mScrollbar[axis]->getVisible()) - { - LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); - const S32 AUTOSCROLL_SIZE = 10; - if(mScrollbar[axis]->getVisible()) - { - static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); - inner_rect_local.mRight -= scrollbar_size; - inner_rect_local.mTop += AUTOSCROLL_SIZE; - inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE; - } - if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) ) - { - return TRUE; - } - - } - return FALSE; -} - BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -273,12 +257,27 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); // Scroll folder view if needed. Never accepts a drag or drop. *accept = ACCEPT_NO; - BOOL handled = FALSE; + BOOL handled = autoScroll(x, y); + + if( !handled ) + { + handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, + cargo_data, accept, tooltip_msg) != NULL; + } + + return TRUE; +} + +bool LLScrollContainer::autoScroll(S32 x, S32 y) +{ + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + + bool scrolling = false; if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() ) { - const S32 AUTOSCROLL_SIZE = 10; - S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32()); - + LLRect screen_local_extents; + screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents); + LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); if( mScrollbar[HORIZONTAL]->getVisible() ) { @@ -289,65 +288,61 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, inner_rect_local.mRight -= scrollbar_size; } + // clip rect against root view + inner_rect_local.intersectWith(screen_local_extents); + + S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32()); + // autoscroll region should take up no more than one third of visible scroller area + S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10); + S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10); + if( mScrollbar[HORIZONTAL]->getVisible() ) { - LLRect left_scroll_rect = inner_rect_local; - left_scroll_rect.mRight = AUTOSCROLL_SIZE; + LLRect left_scroll_rect = screen_local_extents; + left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width; if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) ) { mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } - LLRect right_scroll_rect = inner_rect_local; - right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE; + LLRect right_scroll_rect = screen_local_extents; + right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width; if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) ) { mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } } if( mScrollbar[VERTICAL]->getVisible() ) { - LLRect bottom_scroll_rect = inner_rect_local; - bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom; + LLRect bottom_scroll_rect = screen_local_extents; + bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height; if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) ) { mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } - LLRect top_scroll_rect = inner_rect_local; - top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE; + LLRect top_scroll_rect = screen_local_extents; + top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height; if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) ) { mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } } } - - if( !handled ) - { - handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, - cargo_data, accept, tooltip_msg) != NULL; - } - - return TRUE; + return scrolling; } void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { - const LLRect& rect = getScrolledViewRect(); - calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); -} - -void LLScrollContainer::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const -{ + const LLRect& doc_rect = getScrolledViewRect(); static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); @@ -384,20 +379,20 @@ void LLScrollContainer::draw() if (mAutoScrolling) { // add acceleration to autoscroll - mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE); + mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), mMaxAutoScrollRate); } else { - // reset to minimum - mAutoScrollRate = MIN_AUTO_SCROLL_RATE; + // reset to minimum for next time + mAutoScrollRate = mMinAutoScrollRate; } - // clear this flag to be set on next call to handleDragAndDrop + // clear this flag to be set on next call to autoScroll mAutoScrolling = FALSE; // auto-focus when scrollbar active // this allows us to capture user intent (i.e. stop automatically scrolling the view/etc) - if (!gFocusMgr.childHasKeyboardFocus(this) && - (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture())) + if (!hasFocus() + && (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture())) { focusFirstItem(); } @@ -424,7 +419,7 @@ void LLScrollContainer::draw() S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); LLLocalClipRect clip(LLRect(mInnerRect.mLeft, mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height, @@ -506,7 +501,7 @@ void LLScrollContainer::updateScroll() S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); S32 border_width = mBorder->getBorderWidth(); if( show_v_scrollbar ) @@ -584,71 +579,73 @@ void LLScrollContainer::setBorderVisible(BOOL b) mBorder->setVisible( b ); } -// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled) -void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset) +LLRect LLScrollContainer::getVisibleContentRect() { - if (!mScrolledView) - { - llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; - return; - } + updateScroll(); + LLRect visible_rect = getContentWindowRect(); + LLRect contents_rect = mScrolledView->getRect(); + visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom); + return visible_rect; +} +LLRect LLScrollContainer::getContentWindowRect() const +{ + LLRect scroller_view_rect; S32 visible_width = 0; S32 visible_height = 0; - BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - const LLRect& scrolled_rect = mScrolledView->getRect(); - calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); - - // can't be so far left that right side of rect goes off screen, or so far right that left side does - S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0); - // can't be so high that bottom of rect goes off screen, or so low that top does - S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight())); - - // Vertical - // 1. First make sure the top is visible - // 2. Then, if possible without hiding the top, make the bottom visible. - S32 vert_pos = mScrollbar[VERTICAL]->getDocPos(); - - // find scrollbar position to get top of rect on screen (scrolling up) - S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset; - // find scrollbar position to get bottom of rect on screen (scrolling down) - S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset; - // scroll up far enough to see top or scroll down just enough if item is bigger than visual area - if( vert_pos >= top_offset || visible_height < rect.getHeight()) - { - vert_pos = top_offset; - } - // else scroll down far enough to see bottom - else - if( vert_pos <= bottom_offset ) + BOOL show_v_scrollbar = FALSE; + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + S32 border_width = mBorder->getBorderWidth(); + scroller_view_rect.setOriginAndSize(border_width, + show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width, + visible_width, + visible_height); + return scroller_view_rect; +} + +// rect is in document coordinates, constraint is in display coordinates relative to content window rect +void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& constraint) +{ + if (!mScrolledView) { - vert_pos = bottom_offset; + llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; + return; } + LLRect content_window_rect = getContentWindowRect(); + // get document rect + LLRect scrolled_rect = mScrolledView->getRect(); + + // shrink target rect to fit within constraint region, biasing towards top left + LLRect rect_to_constrain = rect; + rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight()); + rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth()); + + // calculate allowable positions for scroller window in document coordinates + LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight, + rect_to_constrain.mBottom - constraint.mBottom, + rect_to_constrain.mLeft - constraint.mLeft, + rect_to_constrain.mTop - constraint.mTop); + + // translate from allowable region for lower left corner to upper left corner + allowable_scroll_rect.translate(0, content_window_rect.getHeight()); + + S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(), + mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll + mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll + mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); - mScrollbar[VERTICAL]->setPageSize( visible_height ); + mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() ); mScrollbar[VERTICAL]->setDocPos( vert_pos ); - // Horizontal - // 1. First make sure left side is visible - // 2. Then, if possible without hiding the left side, make the right side visible. - S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos(); - S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset; - S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset; + S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(), + allowable_scroll_rect.mLeft, + allowable_scroll_rect.mRight); - if( horiz_pos >= left_offset || visible_width < rect.getWidth() ) - { - horiz_pos = left_offset; - } - else if( horiz_pos <= right_offset ) - { - horiz_pos = right_offset; - } - mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); - mScrollbar[HORIZONTAL]->setPageSize( visible_width ); - mScrollbar[HORIZONTAL]->setDocPos( horiz_pos ); + mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() ); + mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos ); // propagate scroll to document updateScroll(); @@ -657,21 +654,25 @@ void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLCoordGL& de void LLScrollContainer::pageUp(S32 overlap) { mScrollbar[VERTICAL]->pageUp(overlap); + updateScroll(); } void LLScrollContainer::pageDown(S32 overlap) { mScrollbar[VERTICAL]->pageDown(overlap); + updateScroll(); } void LLScrollContainer::goToTop() { mScrollbar[VERTICAL]->setDocPos(0); + updateScroll(); } void LLScrollContainer::goToBottom() { mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); + updateScroll(); } S32 LLScrollContainer::getBorderWidth() const -- cgit v1.2.3