00001
00033 #include "linden_common.h"
00034
00035 #include "llgl.h"
00036 #include "llglimmediate.h"
00037
00038 #include "llscrollcontainer.h"
00039 #include "llscrollbar.h"
00040 #include "llui.h"
00041 #include "llkeyboard.h"
00042 #include "llviewborder.h"
00043 #include "llfocusmgr.h"
00044 #include "llframetimer.h"
00045 #include "lluictrlfactory.h"
00046 #include "llfontgl.h"
00047
00048 #include "llglheaders.h"
00049
00053
00054 static const S32 HORIZONTAL_MULTIPLE = 8;
00055 static const S32 VERTICAL_MULTIPLE = 16;
00056 static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
00057 static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
00058 static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
00059
00063
00064 static LLRegisterWidget<LLScrollableContainerView> r("scroll_container");
00065
00066
00067 LLScrollableContainerView::LLScrollableContainerView( const LLString& name,
00068 const LLRect& rect,
00069 LLView* scrolled_view,
00070 BOOL is_opaque,
00071 const LLColor4& bg_color ) :
00072 LLUICtrl( name, rect, FALSE, NULL, NULL ),
00073 mScrolledView( scrolled_view ),
00074 mIsOpaque( is_opaque ),
00075 mBackgroundColor( bg_color ),
00076 mReserveScrollCorner( FALSE ),
00077 mAutoScrolling( FALSE ),
00078 mAutoScrollRate( 0.f )
00079 {
00080 if( mScrolledView )
00081 {
00082 addChild( mScrolledView );
00083 }
00084
00085 init();
00086 }
00087
00088
00089 LLScrollableContainerView::LLScrollableContainerView( const LLString& name, const LLRect& rect,
00090 LLUICtrl* scrolled_ctrl, BOOL is_opaque,
00091 const LLColor4& bg_color) :
00092 LLUICtrl( name, rect, FALSE, NULL, NULL ),
00093 mScrolledView( scrolled_ctrl ),
00094 mIsOpaque( is_opaque ),
00095 mBackgroundColor( bg_color ),
00096 mReserveScrollCorner( FALSE ),
00097 mAutoScrolling( FALSE ),
00098 mAutoScrollRate( 0.f )
00099 {
00100 if( scrolled_ctrl )
00101 {
00102 addChild( scrolled_ctrl );
00103 }
00104
00105 init();
00106 }
00107
00108 void LLScrollableContainerView::init()
00109 {
00110 LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
00111 mBorder = new LLViewBorder( "scroll border", border_rect, LLViewBorder::BEVEL_IN );
00112 addChild( mBorder );
00113
00114 mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
00115 mInnerRect.stretch( -mBorder->getBorderWidth() );
00116
00117 LLRect vertical_scroll_rect = mInnerRect;
00118 vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE;
00119 mScrollbar[VERTICAL] = new LLScrollbar( "scrollable vertical",
00120 vertical_scroll_rect,
00121 LLScrollbar::VERTICAL,
00122 mInnerRect.getHeight(),
00123 0,
00124 mInnerRect.getHeight(),
00125 NULL, this,
00126 VERTICAL_MULTIPLE);
00127 addChild( mScrollbar[VERTICAL] );
00128 mScrollbar[VERTICAL]->setVisible( FALSE );
00129 mScrollbar[VERTICAL]->setFollowsRight();
00130 mScrollbar[VERTICAL]->setFollowsTop();
00131 mScrollbar[VERTICAL]->setFollowsBottom();
00132
00133 LLRect horizontal_scroll_rect = mInnerRect;
00134 horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE;
00135 mScrollbar[HORIZONTAL] = new LLScrollbar( "scrollable horizontal",
00136 horizontal_scroll_rect,
00137 LLScrollbar::HORIZONTAL,
00138 mInnerRect.getWidth(),
00139 0,
00140 mInnerRect.getWidth(),
00141 NULL, this,
00142 HORIZONTAL_MULTIPLE);
00143 addChild( mScrollbar[HORIZONTAL] );
00144 mScrollbar[HORIZONTAL]->setVisible( FALSE );
00145 mScrollbar[HORIZONTAL]->setFollowsLeft();
00146 mScrollbar[HORIZONTAL]->setFollowsRight();
00147
00148 setTabStop(FALSE);
00149 }
00150
00151
00152 LLScrollableContainerView::~LLScrollableContainerView( void )
00153 {
00154
00155
00156 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
00157 {
00158 mScrollbar[i] = NULL;
00159 }
00160 mScrolledView = NULL;
00161 }
00162
00163
00164
00165 void LLScrollableContainerView::scrollHorizontal( S32 new_pos )
00166 {
00167
00168 if( mScrolledView )
00169 {
00170 LLRect doc_rect = mScrolledView->getRect();
00171 S32 old_pos = -(doc_rect.mLeft - mInnerRect.mLeft);
00172 mScrolledView->translate( -(new_pos - old_pos), 0 );
00173 }
00174 }
00175
00176
00177 void LLScrollableContainerView::scrollVertical( S32 new_pos )
00178 {
00179
00180 if( mScrolledView )
00181 {
00182 LLRect doc_rect = mScrolledView->getRect();
00183 S32 old_pos = doc_rect.mTop - mInnerRect.mTop;
00184 mScrolledView->translate( 0, new_pos - old_pos );
00185 }
00186 }
00187
00188
00189 void LLScrollableContainerView::reshape(S32 width, S32 height,
00190 BOOL called_from_parent)
00191 {
00192 LLUICtrl::reshape( width, height, called_from_parent );
00193
00194 mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
00195 mInnerRect.stretch( -mBorder->getBorderWidth() );
00196
00197 if (mScrolledView)
00198 {
00199 const LLRect& scrolled_rect = mScrolledView->getRect();
00200
00201 S32 visible_width = 0;
00202 S32 visible_height = 0;
00203 BOOL show_v_scrollbar = FALSE;
00204 BOOL show_h_scrollbar = FALSE;
00205 calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
00206
00207 mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
00208 mScrollbar[VERTICAL]->setPageSize( visible_height );
00209
00210 mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
00211 mScrollbar[HORIZONTAL]->setPageSize( visible_width );
00212 }
00213 }
00214
00215 BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
00216 {
00217 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
00218 {
00219 if( mScrollbar[i]->handleKeyHere(key, mask) )
00220 {
00221 return TRUE;
00222 }
00223 }
00224
00225 return FALSE;
00226 }
00227
00228 BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
00229 {
00230 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
00231 {
00232
00233
00234
00235 if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
00236 {
00237 return TRUE;
00238 }
00239 }
00240
00241
00242 return TRUE;
00243 }
00244
00245 BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const
00246 {
00247 if(mScrollbar[axis]->getVisible())
00248 {
00249 LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
00250 const S32 AUTOSCROLL_SIZE = 10;
00251 if(mScrollbar[axis]->getVisible())
00252 {
00253 inner_rect_local.mRight -= SCROLLBAR_SIZE;
00254 inner_rect_local.mTop += AUTOSCROLL_SIZE;
00255 inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
00256 }
00257 if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
00258 {
00259 return TRUE;
00260 }
00261
00262 }
00263 return FALSE;
00264 }
00265
00266 BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
00267 BOOL drop,
00268 EDragAndDropType cargo_type,
00269 void* cargo_data,
00270 EAcceptance* accept,
00271 LLString& tooltip_msg)
00272 {
00273
00274 *accept = ACCEPT_NO;
00275 BOOL handled = FALSE;
00276 if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
00277 {
00278 const S32 AUTOSCROLL_SIZE = 10;
00279 S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
00280
00281 LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
00282 if( mScrollbar[HORIZONTAL]->getVisible() )
00283 {
00284 inner_rect_local.mBottom += SCROLLBAR_SIZE;
00285 }
00286 if( mScrollbar[VERTICAL]->getVisible() )
00287 {
00288 inner_rect_local.mRight -= SCROLLBAR_SIZE;
00289 }
00290
00291 if( mScrollbar[HORIZONTAL]->getVisible() )
00292 {
00293 LLRect left_scroll_rect = inner_rect_local;
00294 left_scroll_rect.mRight = AUTOSCROLL_SIZE;
00295 if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
00296 {
00297 mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
00298 mAutoScrolling = TRUE;
00299 handled = TRUE;
00300 }
00301
00302 LLRect right_scroll_rect = inner_rect_local;
00303 right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
00304 if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
00305 {
00306 mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
00307 mAutoScrolling = TRUE;
00308 handled = TRUE;
00309 }
00310 }
00311 if( mScrollbar[VERTICAL]->getVisible() )
00312 {
00313 LLRect bottom_scroll_rect = inner_rect_local;
00314 bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
00315 if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
00316 {
00317 mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
00318 mAutoScrolling = TRUE;
00319 handled = TRUE;
00320 }
00321
00322 LLRect top_scroll_rect = inner_rect_local;
00323 top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
00324 if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
00325 {
00326 mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
00327 mAutoScrolling = TRUE;
00328 handled = TRUE;
00329 }
00330 }
00331 }
00332
00333 if( !handled )
00334 {
00335 handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
00336 cargo_data, accept, tooltip_msg) != NULL;
00337 }
00338
00339 return TRUE;
00340 }
00341
00342
00343 BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect)
00344 {
00345 S32 local_x, local_y;
00346 for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
00347 {
00348 local_x = x - mScrollbar[i]->getRect().mLeft;
00349 local_y = y - mScrollbar[i]->getRect().mBottom;
00350 if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) )
00351 {
00352 return TRUE;
00353 }
00354 }
00355
00356 if( mScrolledView )
00357 {
00358 local_x = x - mScrolledView->getRect().mLeft;
00359 local_y = y - mScrolledView->getRect().mBottom;
00360 if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) )
00361 {
00362 return TRUE;
00363 }
00364 }
00365
00366
00367 return TRUE;
00368 }
00369
00370 void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
00371 {
00372 const LLRect& rect = mScrolledView->getRect();
00373 calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar);
00374 }
00375
00376 void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
00377 {
00378 S32 doc_width = doc_rect.getWidth();
00379 S32 doc_height = doc_rect.getHeight();
00380
00381 *visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth();
00382 *visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth();
00383
00384 *show_v_scrollbar = FALSE;
00385 if( *visible_height < doc_height )
00386 {
00387 *show_v_scrollbar = TRUE;
00388 *visible_width -= SCROLLBAR_SIZE;
00389 }
00390
00391 *show_h_scrollbar = FALSE;
00392 if( *visible_width < doc_width )
00393 {
00394 *show_h_scrollbar = TRUE;
00395 *visible_height -= SCROLLBAR_SIZE;
00396
00397
00398 if( !*show_v_scrollbar && (*visible_height < doc_height) )
00399 {
00400 *show_v_scrollbar = TRUE;
00401 *visible_width -= SCROLLBAR_SIZE;
00402 }
00403 }
00404 }
00405
00406 void LLScrollableContainerView::draw()
00407 {
00408 if (mAutoScrolling)
00409 {
00410
00411 mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
00412 }
00413 else
00414 {
00415
00416 mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
00417 }
00418
00419 mAutoScrolling = FALSE;
00420
00421
00422
00423 if (!gFocusMgr.childHasKeyboardFocus(this) &&
00424 (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
00425 {
00426 focusFirstItem();
00427 }
00428
00429
00430 if( mIsOpaque )
00431 {
00432 LLGLSNoTexture no_texture;
00433 gGL.color4fv( mBackgroundColor.mV );
00434 gl_rect_2d( mInnerRect );
00435 }
00436
00437
00438
00439
00440
00441 if( mScrolledView )
00442 {
00443 updateScroll();
00444
00445
00446 {
00447 S32 visible_width = 0;
00448 S32 visible_height = 0;
00449 BOOL show_v_scrollbar = FALSE;
00450 BOOL show_h_scrollbar = FALSE;
00451 calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
00452
00453 LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
00454 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
00455 visible_width,
00456 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
00457 ));
00458 drawChild(mScrolledView);
00459 }
00460 }
00461
00462
00463 if( mBorder->getVisible() )
00464 {
00465 mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
00466 }
00467
00468
00469
00470 for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
00471 child_iter != getChildList()->rend(); ++child_iter)
00472 {
00473 LLView *viewp = *child_iter;
00474 if( sDebugRects )
00475 {
00476 sDepth++;
00477 }
00478 if( (viewp != mScrolledView) && viewp->getVisible() )
00479 {
00480 drawChild(viewp);
00481 }
00482 if( sDebugRects )
00483 {
00484 sDepth--;
00485 }
00486 }
00487
00488 if (sDebugRects)
00489 {
00490 drawDebugRect();
00491 }
00492
00493 }
00494
00495 void LLScrollableContainerView::updateScroll()
00496 {
00497 LLRect doc_rect = mScrolledView->getRect();
00498 S32 doc_width = doc_rect.getWidth();
00499 S32 doc_height = doc_rect.getHeight();
00500 S32 visible_width = 0;
00501 S32 visible_height = 0;
00502 BOOL show_v_scrollbar = FALSE;
00503 BOOL show_h_scrollbar = FALSE;
00504 calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
00505
00506 S32 border_width = mBorder->getBorderWidth();
00507 if( show_v_scrollbar )
00508 {
00509 if( doc_rect.mTop < getRect().getHeight() - border_width )
00510 {
00511 mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop );
00512 }
00513
00514 scrollVertical( mScrollbar[VERTICAL]->getDocPos() );
00515 mScrollbar[VERTICAL]->setVisible( TRUE );
00516
00517 S32 v_scrollbar_height = visible_height;
00518 if( !show_h_scrollbar && mReserveScrollCorner )
00519 {
00520 v_scrollbar_height -= SCROLLBAR_SIZE;
00521 }
00522 mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE );
00523
00524
00525 S32 v_scrollbar_offset = 0;
00526 if( show_h_scrollbar || mReserveScrollCorner )
00527 {
00528 v_scrollbar_offset = SCROLLBAR_SIZE;
00529 }
00530 LLRect r = mScrollbar[VERTICAL]->getRect();
00531 r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset );
00532 mScrollbar[VERTICAL]->setRect( r );
00533 }
00534 else
00535 {
00536 mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop );
00537
00538 mScrollbar[VERTICAL]->setVisible( FALSE );
00539 mScrollbar[VERTICAL]->setDocPos( 0 );
00540 }
00541
00542 if( show_h_scrollbar )
00543 {
00544 if( doc_rect.mLeft > border_width )
00545 {
00546 mScrolledView->translate( border_width - doc_rect.mLeft, 0 );
00547 mScrollbar[HORIZONTAL]->setDocPos( 0 );
00548 }
00549 else
00550 {
00551 scrollHorizontal( mScrollbar[HORIZONTAL]->getDocPos() );
00552 }
00553
00554 mScrollbar[HORIZONTAL]->setVisible( TRUE );
00555 S32 h_scrollbar_width = visible_width;
00556 if( !show_v_scrollbar && mReserveScrollCorner )
00557 {
00558 h_scrollbar_width -= SCROLLBAR_SIZE;
00559 }
00560 mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE );
00561 }
00562 else
00563 {
00564 mScrolledView->translate( border_width - doc_rect.mLeft, 0 );
00565
00566 mScrollbar[HORIZONTAL]->setVisible( FALSE );
00567 mScrollbar[HORIZONTAL]->setDocPos( 0 );
00568 }
00569
00570 mScrollbar[HORIZONTAL]->setDocSize( doc_width );
00571 mScrollbar[HORIZONTAL]->setPageSize( visible_width );
00572
00573 mScrollbar[VERTICAL]->setDocSize( doc_height );
00574 mScrollbar[VERTICAL]->setPageSize( visible_height );
00575 }
00576
00577 void LLScrollableContainerView::setBorderVisible(BOOL b)
00578 {
00579 mBorder->setVisible( b );
00580 }
00581
00582
00583 void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset)
00584 {
00585 if (!mScrolledView)
00586 {
00587 llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl;
00588 return;
00589 }
00590
00591 S32 visible_width = 0;
00592 S32 visible_height = 0;
00593 BOOL show_v_scrollbar = FALSE;
00594 BOOL show_h_scrollbar = FALSE;
00595 const LLRect& scrolled_rect = mScrolledView->getRect();
00596 calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
00597
00598
00599 S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0);
00600
00601 S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight()));
00602
00603
00604
00605
00606 S32 vert_pos = mScrollbar[VERTICAL]->getDocPos();
00607
00608
00609 S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset;
00610
00611 S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset;
00612
00613 if( vert_pos >= top_offset || visible_height < rect.getHeight())
00614 {
00615 vert_pos = top_offset;
00616 }
00617
00618 else
00619 if( vert_pos <= bottom_offset )
00620 {
00621 vert_pos = bottom_offset;
00622 }
00623
00624 mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
00625 mScrollbar[VERTICAL]->setPageSize( visible_height );
00626 mScrollbar[VERTICAL]->setDocPos( vert_pos );
00627
00628
00629
00630
00631 S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos();
00632 S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset;
00633 S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset;
00634
00635 if( horiz_pos >= left_offset || visible_width < rect.getWidth() )
00636 {
00637 horiz_pos = left_offset;
00638 }
00639 else if( horiz_pos <= right_offset )
00640 {
00641 horiz_pos = right_offset;
00642 }
00643
00644 mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
00645 mScrollbar[HORIZONTAL]->setPageSize( visible_width );
00646 mScrollbar[HORIZONTAL]->setDocPos( horiz_pos );
00647
00648
00649 updateScroll();
00650 }
00651
00652 void LLScrollableContainerView::pageUp(S32 overlap)
00653 {
00654 mScrollbar[VERTICAL]->pageUp(overlap);
00655 }
00656
00657 void LLScrollableContainerView::pageDown(S32 overlap)
00658 {
00659 mScrollbar[VERTICAL]->pageDown(overlap);
00660 }
00661
00662 void LLScrollableContainerView::goToTop()
00663 {
00664 mScrollbar[VERTICAL]->setDocPos(0);
00665 }
00666
00667 void LLScrollableContainerView::goToBottom()
00668 {
00669 mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
00670 }
00671
00672 S32 LLScrollableContainerView::getBorderWidth() const
00673 {
00674 if (mBorder)
00675 {
00676 return mBorder->getBorderWidth();
00677 }
00678
00679 return 0;
00680 }
00681
00682
00683 LLXMLNodePtr LLScrollableContainerView::getXML(bool save_children) const
00684 {
00685 LLXMLNodePtr node = LLView::getXML();
00686
00687
00688
00689 node->createChild("opaque", TRUE)->setBoolValue(mIsOpaque);
00690
00691 if (mIsOpaque)
00692 {
00693 node->createChild("color", TRUE)->setFloatValue(4, mBackgroundColor.mV);
00694 }
00695
00696
00697
00698 LLXMLNodePtr child_node = mScrolledView->getXML();
00699
00700 node->addChild(child_node);
00701
00702 return node;
00703 }
00704
00705 LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
00706 {
00707 LLString name("scroll_container");
00708 node->getAttributeString("name", name);
00709
00710 LLRect rect;
00711 createRect(node, rect, parent, LLRect());
00712
00713 BOOL opaque = FALSE;
00714 node->getAttributeBOOL("opaque", opaque);
00715
00716 LLColor4 color(0,0,0,0);
00717 LLUICtrlFactory::getAttributeColor(node,"color", color);
00718
00719
00720 LLScrollableContainerView *ret = new LLScrollableContainerView(name, rect, (LLPanel*)NULL, opaque, color);
00721
00722 LLPanel* panelp = NULL;
00723
00724
00725 LLXMLNodePtr child;
00726 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
00727 {
00728 LLView *control = factory->createCtrlWidget(panelp, child);
00729 if (control && control->isPanel())
00730 {
00731 if (panelp)
00732 {
00733 llinfos << "Warning! Attempting to put multiple panels into a scrollable container view!" << llendl;
00734 delete control;
00735 }
00736 else
00737 {
00738 panelp = (LLPanel*)control;
00739 }
00740 }
00741 }
00742
00743 if (panelp == NULL)
00744 {
00745 panelp = new LLPanel("dummy", LLRect::null, FALSE);
00746 }
00747
00748 ret->mScrolledView = panelp;
00749
00750 return ret;
00751 }