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