/indra/llui/llscrollbar.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 644 lines · 477 code · 97 blank · 70 comment · 88 complexity · d1e7eaafd33f778726f9008779d55550 MD5 · raw file

  1. /**
  2. * @file llscrollbar.cpp
  3. * @brief Scrollbar UI widget
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llscrollbar.h"
  28. #include "llmath.h"
  29. #include "lltimer.h"
  30. #include "v3color.h"
  31. #include "llbutton.h"
  32. #include "llcriticaldamp.h"
  33. #include "llkeyboard.h"
  34. #include "llui.h"
  35. #include "llfocusmgr.h"
  36. #include "llwindow.h"
  37. #include "llcontrol.h"
  38. #include "llrender.h"
  39. #include "lluictrlfactory.h"
  40. static LLDefaultChildRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar");
  41. LLScrollbar::Params::Params()
  42. : orientation ("orientation", HORIZONTAL),
  43. doc_size ("doc_size", 0),
  44. doc_pos ("doc_pos", 0),
  45. page_size ("page_size", 0),
  46. step_size ("step_size", 1),
  47. thumb_image_vertical("thumb_image_vertical"),
  48. thumb_image_horizontal("thumb_image_horizontal"),
  49. track_image_vertical("track_image_vertical"),
  50. track_image_horizontal("track_image_horizontal"),
  51. track_color("track_color"),
  52. thumb_color("thumb_color"),
  53. thickness("thickness"),
  54. up_button("up_button"),
  55. down_button("down_button"),
  56. left_button("left_button"),
  57. right_button("right_button"),
  58. bg_visible("bg_visible", false),
  59. bg_color("bg_color", LLColor4::black)
  60. {}
  61. LLScrollbar::LLScrollbar(const Params & p)
  62. : LLUICtrl(p),
  63. mChangeCallback( p.change_callback() ),
  64. mOrientation( p.orientation ),
  65. mDocSize( p.doc_size ),
  66. mDocPos( p.doc_pos ),
  67. mPageSize( p.page_size ),
  68. mStepSize( p.step_size ),
  69. mDocChanged(FALSE),
  70. mDragStartX( 0 ),
  71. mDragStartY( 0 ),
  72. mHoverGlowStrength(0.15f),
  73. mCurGlowStrength(0.f),
  74. mTrackColor( p.track_color() ),
  75. mThumbColor ( p.thumb_color() ),
  76. mThumbImageV(p.thumb_image_vertical),
  77. mThumbImageH(p.thumb_image_horizontal),
  78. mTrackImageV(p.track_image_vertical),
  79. mTrackImageH(p.track_image_horizontal),
  80. mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")),
  81. mBGVisible(p.bg_visible),
  82. mBGColor(p.bg_color)
  83. {
  84. updateThumbRect();
  85. // Page up and page down buttons
  86. LLRect line_up_rect;
  87. LLRect line_down_rect;
  88. if( VERTICAL == mOrientation )
  89. {
  90. line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), mThickness, mThickness );
  91. line_down_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
  92. }
  93. else // HORIZONTAL
  94. {
  95. line_up_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
  96. line_down_rect.setOriginAndSize( getRect().getWidth() - mThickness, 0, mThickness, mThickness );
  97. }
  98. LLButton::Params up_btn(mOrientation == VERTICAL ? p.up_button : p.left_button);
  99. up_btn.name(std::string("Line Up"));
  100. up_btn.rect(line_up_rect);
  101. up_btn.click_callback.function(boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2));
  102. up_btn.mouse_held_callback.function(boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2));
  103. up_btn.tab_stop(false);
  104. up_btn.follows.flags = (mOrientation == VERTICAL ? (FOLLOWS_RIGHT | FOLLOWS_TOP) : (FOLLOWS_LEFT | FOLLOWS_BOTTOM));
  105. addChild(LLUICtrlFactory::create<LLButton>(up_btn));
  106. LLButton::Params down_btn(mOrientation == VERTICAL ? p.down_button : p.right_button);
  107. down_btn.name(std::string("Line Down"));
  108. down_btn.rect(line_down_rect);
  109. down_btn.follows.flags(FOLLOWS_RIGHT|FOLLOWS_BOTTOM);
  110. down_btn.click_callback.function(boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2));
  111. down_btn.mouse_held_callback.function(boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2));
  112. down_btn.tab_stop(false);
  113. addChild(LLUICtrlFactory::create<LLButton>(down_btn));
  114. }
  115. LLScrollbar::~LLScrollbar()
  116. {
  117. // Children buttons killed by parent class
  118. }
  119. void LLScrollbar::setDocParams( S32 size, S32 pos )
  120. {
  121. mDocSize = size;
  122. setDocPos(pos);
  123. mDocChanged = TRUE;
  124. updateThumbRect();
  125. }
  126. // returns true if document position really changed
  127. bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
  128. {
  129. pos = llclamp(pos, 0, getDocPosMax());
  130. if (pos != mDocPos)
  131. {
  132. mDocPos = pos;
  133. mDocChanged = TRUE;
  134. if( mChangeCallback )
  135. {
  136. mChangeCallback( mDocPos, this );
  137. }
  138. if( update_thumb )
  139. {
  140. updateThumbRect();
  141. }
  142. return true;
  143. }
  144. return false;
  145. }
  146. void LLScrollbar::setDocSize(S32 size)
  147. {
  148. if (size != mDocSize)
  149. {
  150. mDocSize = size;
  151. setDocPos(mDocPos);
  152. mDocChanged = TRUE;
  153. updateThumbRect();
  154. }
  155. }
  156. void LLScrollbar::setPageSize( S32 page_size )
  157. {
  158. if (page_size != mPageSize)
  159. {
  160. mPageSize = page_size;
  161. setDocPos(mDocPos);
  162. mDocChanged = TRUE;
  163. updateThumbRect();
  164. }
  165. }
  166. BOOL LLScrollbar::isAtBeginning()
  167. {
  168. return mDocPos == 0;
  169. }
  170. BOOL LLScrollbar::isAtEnd()
  171. {
  172. return mDocPos == getDocPosMax();
  173. }
  174. void LLScrollbar::updateThumbRect()
  175. {
  176. // llassert( 0 <= mDocSize );
  177. // llassert( 0 <= mDocPos && mDocPos <= getDocPosMax() );
  178. const S32 THUMB_MIN_LENGTH = 16;
  179. S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
  180. S32 thumb_bg_length = llmax(0, window_length - 2 * mThickness);
  181. S32 visible_lines = llmin( mDocSize, mPageSize );
  182. S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
  183. S32 variable_lines = mDocSize - visible_lines;
  184. if( mOrientation == LLScrollbar::VERTICAL )
  185. {
  186. S32 thumb_start_max = thumb_bg_length + mThickness;
  187. S32 thumb_start_min = mThickness + THUMB_MIN_LENGTH;
  188. S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
  189. mThumbRect.mLeft = 0;
  190. mThumbRect.mTop = thumb_start;
  191. mThumbRect.mRight = mThickness;
  192. mThumbRect.mBottom = thumb_start - thumb_length;
  193. }
  194. else
  195. {
  196. // Horizontal
  197. S32 thumb_start_max = thumb_bg_length + mThickness - thumb_length;
  198. S32 thumb_start_min = mThickness;
  199. S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
  200. mThumbRect.mLeft = thumb_start;
  201. mThumbRect.mTop = mThickness;
  202. mThumbRect.mRight = thumb_start + thumb_length;
  203. mThumbRect.mBottom = 0;
  204. }
  205. }
  206. BOOL LLScrollbar::handleMouseDown(S32 x, S32 y, MASK mask)
  207. {
  208. // Check children first
  209. BOOL handled_by_child = LLView::childrenHandleMouseDown(x, y, mask) != NULL;
  210. if( !handled_by_child )
  211. {
  212. if( mThumbRect.pointInRect(x,y) )
  213. {
  214. // Start dragging the thumb
  215. // No handler needed for focus lost since this clas has no state that depends on it.
  216. gFocusMgr.setMouseCapture( this );
  217. mDragStartX = x;
  218. mDragStartY = y;
  219. mOrigRect.mTop = mThumbRect.mTop;
  220. mOrigRect.mBottom = mThumbRect.mBottom;
  221. mOrigRect.mLeft = mThumbRect.mLeft;
  222. mOrigRect.mRight = mThumbRect.mRight;
  223. mLastDelta = 0;
  224. }
  225. else
  226. {
  227. if(
  228. ( (LLScrollbar::VERTICAL == mOrientation) && (mThumbRect.mTop < y) ) ||
  229. ( (LLScrollbar::HORIZONTAL == mOrientation) && (x < mThumbRect.mLeft) )
  230. )
  231. {
  232. // Page up
  233. pageUp(0);
  234. }
  235. else
  236. if(
  237. ( (LLScrollbar::VERTICAL == mOrientation) && (y < mThumbRect.mBottom) ) ||
  238. ( (LLScrollbar::HORIZONTAL == mOrientation) && (mThumbRect.mRight < x) )
  239. )
  240. {
  241. // Page down
  242. pageDown(0);
  243. }
  244. }
  245. }
  246. return TRUE;
  247. }
  248. BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
  249. {
  250. // Note: we don't bother sending the event to the children (the arrow buttons)
  251. // because they'll capture the mouse whenever they need hover events.
  252. BOOL handled = FALSE;
  253. if( hasMouseCapture() )
  254. {
  255. S32 height = getRect().getHeight();
  256. S32 width = getRect().getWidth();
  257. if( VERTICAL == mOrientation )
  258. {
  259. // S32 old_pos = mThumbRect.mTop;
  260. S32 delta_pixels = y - mDragStartY;
  261. if( mOrigRect.mBottom + delta_pixels < mThickness )
  262. {
  263. delta_pixels = mThickness - mOrigRect.mBottom - 1;
  264. }
  265. else
  266. if( mOrigRect.mTop + delta_pixels > height - mThickness )
  267. {
  268. delta_pixels = height - mThickness - mOrigRect.mTop + 1;
  269. }
  270. mThumbRect.mTop = mOrigRect.mTop + delta_pixels;
  271. mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels;
  272. S32 thumb_length = mThumbRect.getHeight();
  273. S32 thumb_track_length = height - 2 * mThickness;
  274. if( delta_pixels != mLastDelta || mDocChanged)
  275. {
  276. // Note: delta_pixels increases as you go up. mDocPos increases down (line 0 is at the top of the page).
  277. S32 usable_track_length = thumb_track_length - thumb_length;
  278. if( 0 < usable_track_length )
  279. {
  280. S32 variable_lines = getDocPosMax();
  281. S32 pos = mThumbRect.mTop;
  282. F32 ratio = F32(pos - mThickness - thumb_length) / usable_track_length;
  283. S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines );
  284. // Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
  285. // out of sync (less than a line's worth) to make the thumb feel responsive.
  286. changeLine( new_pos - mDocPos, FALSE );
  287. }
  288. }
  289. mLastDelta = delta_pixels;
  290. }
  291. else
  292. {
  293. // Horizontal
  294. // S32 old_pos = mThumbRect.mLeft;
  295. S32 delta_pixels = x - mDragStartX;
  296. if( mOrigRect.mLeft + delta_pixels < mThickness )
  297. {
  298. delta_pixels = mThickness - mOrigRect.mLeft - 1;
  299. }
  300. else
  301. if( mOrigRect.mRight + delta_pixels > width - mThickness )
  302. {
  303. delta_pixels = width - mThickness - mOrigRect.mRight + 1;
  304. }
  305. mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels;
  306. mThumbRect.mRight = mOrigRect.mRight + delta_pixels;
  307. S32 thumb_length = mThumbRect.getWidth();
  308. S32 thumb_track_length = width - 2 * mThickness;
  309. if( delta_pixels != mLastDelta || mDocChanged)
  310. {
  311. // Note: delta_pixels increases as you go up. mDocPos increases down (line 0 is at the top of the page).
  312. S32 usable_track_length = thumb_track_length - thumb_length;
  313. if( 0 < usable_track_length )
  314. {
  315. S32 variable_lines = getDocPosMax();
  316. S32 pos = mThumbRect.mLeft;
  317. F32 ratio = F32(pos - mThickness) / usable_track_length;
  318. S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines);
  319. // Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
  320. // out of sync (less than a line's worth) to make the thumb feel responsive.
  321. changeLine( new_pos - mDocPos, FALSE );
  322. }
  323. }
  324. mLastDelta = delta_pixels;
  325. }
  326. getWindow()->setCursor(UI_CURSOR_ARROW);
  327. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
  328. handled = TRUE;
  329. }
  330. else
  331. {
  332. handled = childrenHandleHover( x, y, mask ) != NULL;
  333. }
  334. // Opaque
  335. if( !handled )
  336. {
  337. getWindow()->setCursor(UI_CURSOR_ARROW);
  338. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
  339. handled = TRUE;
  340. }
  341. mDocChanged = FALSE;
  342. return handled;
  343. } // end handleHover
  344. BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
  345. {
  346. BOOL handled = changeLine( clicks * mStepSize, TRUE );
  347. return handled;
  348. }
  349. BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
  350. EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg)
  351. {
  352. // enable this to get drag and drop to control scrollbars
  353. //if (!drop)
  354. //{
  355. // //TODO: refactor this
  356. // S32 variable_lines = getDocPosMax();
  357. // S32 pos = (VERTICAL == mOrientation) ? y : x;
  358. // S32 thumb_length = (VERTICAL == mOrientation) ? mThumbRect.getHeight() : mThumbRect.getWidth();
  359. // S32 thumb_track_length = (VERTICAL == mOrientation) ? (getRect().getHeight() - 2 * SCROLLBAR_SIZE) : (getRect().getWidth() - 2 * SCROLLBAR_SIZE);
  360. // S32 usable_track_length = thumb_track_length - thumb_length;
  361. // F32 ratio = (VERTICAL == mOrientation) ? F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length
  362. // : F32(pos - SCROLLBAR_SIZE) / usable_track_length;
  363. // S32 new_pos = (VERTICAL == mOrientation) ? llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines )
  364. // : llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines );
  365. // changeLine( new_pos - mDocPos, TRUE );
  366. //}
  367. //return TRUE;
  368. return FALSE;
  369. }
  370. BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
  371. {
  372. BOOL handled = FALSE;
  373. if( hasMouseCapture() )
  374. {
  375. gFocusMgr.setMouseCapture( NULL );
  376. handled = TRUE;
  377. }
  378. else
  379. {
  380. // Opaque, so don't just check children
  381. handled = LLView::handleMouseUp( x, y, mask );
  382. }
  383. return handled;
  384. }
  385. BOOL LLScrollbar::handleDoubleClick(S32 x, S32 y, MASK mask)
  386. {
  387. // just treat a double click as a second click
  388. return handleMouseDown(x, y, mask);
  389. }
  390. void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
  391. {
  392. if (width == getRect().getWidth() && height == getRect().getHeight()) return;
  393. LLView::reshape( width, height, called_from_parent );
  394. LLButton* up_button = getChild<LLButton>("Line Up");
  395. LLButton* down_button = getChild<LLButton>("Line Down");
  396. if (mOrientation == VERTICAL)
  397. {
  398. up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
  399. down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
  400. up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
  401. }
  402. else
  403. {
  404. up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
  405. down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
  406. down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
  407. }
  408. updateThumbRect();
  409. }
  410. void LLScrollbar::draw()
  411. {
  412. if (!getRect().isValid()) return;
  413. if(mBGVisible)
  414. {
  415. gl_rect_2d(getLocalRect(), mBGColor.get(), TRUE);
  416. }
  417. S32 local_mouse_x;
  418. S32 local_mouse_y;
  419. LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
  420. BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this;
  421. BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
  422. if (hovered)
  423. {
  424. mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
  425. }
  426. else
  427. {
  428. mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
  429. }
  430. // Draw background and thumb.
  431. if ( ( mOrientation == VERTICAL&&(mThumbImageV.isNull() || mThumbImageH.isNull()) )
  432. || (mOrientation == HORIZONTAL&&(mTrackImageH.isNull() || mTrackImageV.isNull()) ))
  433. {
  434. gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,
  435. mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(),
  436. mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),
  437. mOrientation == VERTICAL ? mThickness : 0, mTrackColor.get(), TRUE);
  438. gl_rect_2d(mThumbRect, mThumbColor.get(), TRUE);
  439. }
  440. else
  441. {
  442. // Thumb
  443. LLRect outline_rect = mThumbRect;
  444. outline_rect.stretch(2);
  445. // Background
  446. if(mOrientation == HORIZONTAL)
  447. {
  448. mTrackImageH->drawSolid(mThickness //S32 x
  449. , 0 //S32 y
  450. , getRect().getWidth() - 2 * mThickness //S32 width
  451. , getRect().getHeight() //S32 height
  452. , mTrackColor.get()); //const LLColor4& color
  453. if (gFocusMgr.getKeyboardFocus() == this)
  454. {
  455. mTrackImageH->draw(outline_rect, gFocusMgr.getFocusColor());
  456. }
  457. mThumbImageH->draw(mThumbRect, mThumbColor.get());
  458. if (mCurGlowStrength > 0.01f)
  459. {
  460. gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
  461. mThumbImageH->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
  462. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  463. }
  464. }
  465. else if(mOrientation == VERTICAL)
  466. {
  467. mTrackImageV->drawSolid( 0 //S32 x
  468. , mThickness //S32 y
  469. , getRect().getWidth() //S32 width
  470. , getRect().getHeight() - 2 * mThickness //S32 height
  471. , mTrackColor.get()); //const LLColor4& color
  472. if (gFocusMgr.getKeyboardFocus() == this)
  473. {
  474. mTrackImageV->draw(outline_rect, gFocusMgr.getFocusColor());
  475. }
  476. mThumbImageV->draw(mThumbRect, mThumbColor.get());
  477. if (mCurGlowStrength > 0.01f)
  478. {
  479. gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
  480. mThumbImageV->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
  481. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  482. }
  483. }
  484. }
  485. // Draw children
  486. LLView::draw();
  487. } // end draw
  488. bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
  489. {
  490. return setDocPos(mDocPos + delta, update_thumb);
  491. }
  492. void LLScrollbar::setValue(const LLSD& value)
  493. {
  494. setDocPos((S32) value.asInteger());
  495. }
  496. BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask)
  497. {
  498. BOOL handled = FALSE;
  499. switch( key )
  500. {
  501. case KEY_HOME:
  502. setDocPos( 0 );
  503. handled = TRUE;
  504. break;
  505. case KEY_END:
  506. setDocPos( getDocPosMax() );
  507. handled = TRUE;
  508. break;
  509. case KEY_DOWN:
  510. setDocPos( getDocPos() + mStepSize );
  511. handled = TRUE;
  512. break;
  513. case KEY_UP:
  514. setDocPos( getDocPos() - mStepSize );
  515. handled = TRUE;
  516. break;
  517. case KEY_PAGE_DOWN:
  518. pageDown(1);
  519. break;
  520. case KEY_PAGE_UP:
  521. pageUp(1);
  522. break;
  523. }
  524. return handled;
  525. }
  526. void LLScrollbar::pageUp(S32 overlap)
  527. {
  528. if (mDocSize > mPageSize)
  529. {
  530. changeLine( -(mPageSize - overlap), TRUE );
  531. }
  532. }
  533. void LLScrollbar::pageDown(S32 overlap)
  534. {
  535. if (mDocSize > mPageSize)
  536. {
  537. changeLine( mPageSize - overlap, TRUE );
  538. }
  539. }
  540. void LLScrollbar::onLineUpBtnPressed( const LLSD& data )
  541. {
  542. changeLine( -mStepSize, TRUE );
  543. }
  544. void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
  545. {
  546. changeLine( mStepSize, TRUE );
  547. }