diff options
Diffstat (limited to 'indra/llui/llscrollcontainer.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llui/llscrollcontainer.cpp | 268 |
1 files changed, 158 insertions, 110 deletions
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index d8606c6889..f70eebc594 100644..100755 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -2,31 +2,25 @@ * @file llscrollcontainer.cpp * @brief LLScrollContainer base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,7 +48,6 @@ /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -static const S32 HORIZONTAL_MULTIPLE = 8; static const S32 VERTICAL_MULTIPLE = 16; static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; @@ -79,12 +72,9 @@ LLScrollContainer::Params::Params() hide_scrollbar("hide_scrollbar"), 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"; - mouse_opaque(true); - tab_stop(false); -} + reserve_scroll_corner("reserve_scroll_corner", false), + size("size", -1) +{} // Default constructor @@ -98,9 +88,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) mReserveScrollCorner(p.reserve_scroll_corner), mMinAutoScrollRate(p.min_auto_scroll_rate), mMaxAutoScrollRate(p.max_auto_scroll_rate), - mScrolledView(NULL) + mScrolledView(NULL), + mSize(p.size) { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); + S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); + LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); LLViewBorder::Params params; params.name("scroll border"); @@ -111,7 +104,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLView::addChild( mBorder ); mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); - mInnerRect.stretch( -mBorder->getBorderWidth() ); + mInnerRect.stretch( -getBorderWidth() ); LLRect vertical_scroll_rect = mInnerRect; vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size; @@ -150,7 +143,7 @@ LLScrollContainer::~LLScrollContainer( void ) { // mScrolledView and mScrollbar are child views, so the LLView // destructor takes care of memory deallocation. - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) + for( S32 i = 0; i < ORIENTATION_COUNT; i++ ) { mScrollbar[i] = NULL; } @@ -161,7 +154,6 @@ LLScrollContainer::~LLScrollContainer( void ) // virtual void LLScrollContainer::scrollHorizontal( S32 new_pos ) { - //llinfos << "LLScrollContainer::scrollHorizontal()" << llendl; if( mScrolledView ) { LLRect doc_rect = mScrolledView->getRect(); @@ -173,7 +165,6 @@ void LLScrollContainer::scrollHorizontal( S32 new_pos ) // virtual void LLScrollContainer::scrollVertical( S32 new_pos ) { - // llinfos << "LLScrollContainer::scrollVertical() " << new_pos << llendl; if( mScrolledView ) { LLRect doc_rect = mScrolledView->getRect(); @@ -189,7 +180,7 @@ void LLScrollContainer::reshape(S32 width, S32 height, LLUICtrl::reshape( width, height, called_from_parent ); mInnerRect = getLocalRect(); - mInnerRect.stretch( -mBorder->getBorderWidth() ); + mInnerRect.stretch( -getBorderWidth() ); if (mScrolledView) { @@ -221,7 +212,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) { return TRUE; } - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) + for( S32 i = 0; i < ORIENTATION_COUNT; i++ ) { if( mScrollbar[i]->handleKeyHere(key, mask) ) { @@ -233,20 +224,48 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) return FALSE; } +BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char) +{ + if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char)) + { + return TRUE; + } + return FALSE; +} + BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - if(LLUICtrl::handleScrollWheel(x,y,clicks)) + // Give event to my child views - they may have scroll bars + // (Bad UI design, but technically possible.) + if (LLUICtrl::handleScrollWheel(x,y,clicks)) return TRUE; - for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) - { - // Note: tries vertical and then horizontal + // When the vertical scrollbar is visible, scroll wheel + // only affects vertical scrolling. It's confusing to have + // scroll wheel perform both vertical and horizontal in a + // single container. + LLScrollbar* vertical = mScrollbar[VERTICAL]; + if (vertical->getVisible() + && vertical->getEnabled()) + { // Pretend the mouse is over the scrollbar - if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) + if (vertical->handleScrollWheel( 0, 0, clicks ) ) { updateScroll(); - return TRUE; } + // Always eat the event + return TRUE; + } + + LLScrollbar* horizontal = mScrollbar[HORIZONTAL]; + // Test enablement and visibility for consistency with + // LLView::childrenHandleScrollWheel(). + if (horizontal->getVisible() + && horizontal->getEnabled() + && horizontal->handleScrollWheel( 0, 0, clicks ) ) + { + updateScroll(); + return TRUE; } return FALSE; } @@ -258,7 +277,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, EAcceptance* accept, std::string& tooltip_msg) { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); // Scroll folder view if needed. Never accepts a drag or drop. *accept = ACCEPT_NO; BOOL handled = autoScroll(x, y); @@ -274,7 +292,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, bool LLScrollContainer::autoScroll(S32 x, S32 y) { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); + S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); bool scrolling = false; if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() ) @@ -295,7 +314,7 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y) // clip rect against root view inner_rect_local.intersectWith(screen_local_extents); - S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32()); + S32 auto_scroll_speed = ll_round(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); @@ -347,32 +366,38 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y) void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& doc_rect = getScrolledViewRect(); - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); + S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); + S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); - S32 border_width = (mBorder->getVisible() ? 2 * mBorder->getBorderWidth() : 0); - *visible_width = getRect().getWidth() - border_width; - *visible_height = getRect().getHeight() - border_width; + S32 border_width = getBorderWidth(); + *visible_width = getRect().getWidth() - 2 * border_width; + *visible_height = getRect().getHeight() - 2 * border_width; *show_v_scrollbar = FALSE; *show_h_scrollbar = FALSE; if (!mHideScrollbar) { - if( *visible_height < doc_height ) + // Note: 1 pixel change can happen on final animation and should not trigger + // the display of sliders. + if ((doc_height - *visible_height) > 1) { *show_v_scrollbar = TRUE; *visible_width -= scrollbar_size; } - - if( *visible_width < doc_width ) + if ((doc_width - *visible_width) > 1) { *show_h_scrollbar = TRUE; *visible_height -= scrollbar_size; + // Note: Do *not* recompute *show_v_scrollbar here because with + // The view inside the scroll container should not be extended + // to container's full height to ensure the correct computation + // of *show_v_scrollbar after subtracting horizontal scrollbar_size. - // Must retest now that visible_height has changed - if( !*show_v_scrollbar && (*visible_height < doc_height) ) + if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) ) { *show_v_scrollbar = TRUE; *visible_width -= scrollbar_size; @@ -384,7 +409,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height void LLScrollContainer::draw() { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); + S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); + if (mAutoScrolling) { // add acceleration to autoscroll @@ -406,62 +433,66 @@ void LLScrollContainer::draw() focusFirstItem(); } - // Draw background - if( mIsOpaque ) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4fv( mBackgroundColor.get().mV ); - gl_rect_2d( mInnerRect ); - } - - // Draw mScrolledViews and update scroll bars. - // get a scissor region ready, and draw the scrolling view. The - // scissor region ensures that we don't draw outside of the bounds - // of the rectangle. - if( mScrolledView ) + if (getRect().isValid()) { - updateScroll(); - - // Draw the scrolled area. + // Draw background + if( mIsOpaque ) { - S32 visible_width = 0; - S32 visible_height = 0; - BOOL show_v_scrollbar = FALSE; - BOOL show_h_scrollbar = FALSE; - 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, - visible_width, - mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) - )); - drawChild(mScrolledView); - } - } + F32 alpha = getCurrentTransparency(); - // Highlight border if a child of this container has keyboard focus - if( mBorder->getVisible() ) - { - mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); - } - - // Draw all children except mScrolledView - // Note: scrollbars have been adjusted by above drawing code - for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin(); - child_iter != getChildList()->rend(); ++child_iter) - { - LLView *viewp = *child_iter; - if( sDebugRects ) + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha); + } + + // Draw mScrolledViews and update scroll bars. + // get a scissor region ready, and draw the scrolling view. The + // scissor region ensures that we don't draw outside of the bounds + // of the rectangle. + if( mScrolledView ) { - sDepth++; + updateScroll(); + + // Draw the scrolled area. + { + S32 visible_width = 0; + S32 visible_height = 0; + BOOL show_v_scrollbar = FALSE; + BOOL show_h_scrollbar = FALSE; + 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, + mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0), + mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + )); + drawChild(mScrolledView); + } } - if( (viewp != mScrolledView) && viewp->getVisible() ) + + // Highlight border if a child of this container has keyboard focus + if( mBorder->getVisible() ) { - drawChild(viewp); + mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); } - if( sDebugRects ) + + // Draw all children except mScrolledView + // Note: scrollbars have been adjusted by above drawing code + for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin(); + child_iter != getChildList()->rend(); ++child_iter) { - sDepth--; + LLView *viewp = *child_iter; + if( sDebugRects ) + { + sDepth++; + } + if( (viewp != mScrolledView) && viewp->getVisible() ) + { + drawChild(viewp); + } + if( sDebugRects ) + { + sDepth--; + } } } } // end draw @@ -485,11 +516,13 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) void LLScrollContainer::updateScroll() { - if (!mScrolledView) + if (!getVisible() || !mScrolledView) { return; } - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0); + S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize); + LLRect doc_rect = mScrolledView->getRect(); S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); @@ -499,7 +532,7 @@ void LLScrollContainer::updateScroll() BOOL show_h_scrollbar = FALSE; calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); - S32 border_width = mBorder->getBorderWidth(); + S32 border_width = getBorderWidth(); if( show_v_scrollbar ) { if( doc_rect.mTop < getRect().getHeight() - border_width ) @@ -573,6 +606,9 @@ void LLScrollContainer::updateScroll() void LLScrollContainer::setBorderVisible(BOOL b) { mBorder->setVisible( b ); + // Recompute inner rect, as border visibility changes it + mInnerRect = getLocalRect(); + mInnerRect.stretch( -getBorderWidth() ); } LLRect LLScrollContainer::getVisibleContentRect() @@ -584,15 +620,16 @@ LLRect LLScrollContainer::getVisibleContentRect() return visible_rect; } -LLRect LLScrollContainer::getContentWindowRect() const +LLRect LLScrollContainer::getContentWindowRect() { + updateScroll(); LLRect scroller_view_rect; S32 visible_width = 0; S32 visible_height = 0; BOOL show_h_scrollbar = FALSE; BOOL show_v_scrollbar = FALSE; calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); - S32 border_width = mBorder->getVisible() ? mBorder->getBorderWidth() : 0; + S32 border_width = getBorderWidth(); scroller_view_rect.setOriginAndSize(border_width, show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width, visible_width, @@ -605,7 +642,7 @@ void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& const { if (!mScrolledView) { - llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; + LL_WARNS() << "LLScrollContainer::scrollToShowRect with no view!" << LL_ENDL; return; } @@ -645,6 +682,11 @@ void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& const // propagate scroll to document updateScroll(); + + // In case we are in accordion tab notify parent to show selected rectangle + LLRect screen_rc; + localRectToScreen(rect_to_constrain, &screen_rc); + notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue())); } void LLScrollContainer::pageUp(S32 overlap) @@ -673,7 +715,7 @@ void LLScrollContainer::goToBottom() S32 LLScrollContainer::getBorderWidth() const { - if (mBorder) + if (mBorder->getVisible()) { return mBorder->getBorderWidth(); } @@ -681,3 +723,9 @@ S32 LLScrollContainer::getBorderWidth() const return 0; } +void LLScrollContainer::setSize(S32 size) +{ + mSize = size; + mScrollbar[VERTICAL]->setThickness(size); + mScrollbar[HORIZONTAL]->setThickness(size); +} |