llslider.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:11k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llslider.cpp
  3.  * @brief LLSlider base class
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "llslider.h"
  34. #include "llui.h"
  35. #include "llgl.h"
  36. #include "llwindow.h"
  37. #include "llfocusmgr.h"
  38. #include "llkeyboard.h" // for the MASK constants
  39. #include "llcontrol.h"
  40. #include "lluictrlfactory.h"
  41. static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar");
  42. //FIXME: make this into an unregistered template so that code constructed sliders don't
  43. // have ambigious template lookup problem
  44. LLSlider::Params::Params()
  45. : orientation ("orientation", std::string ("horizontal")),
  46. track_color("track_color"),
  47. thumb_outline_color("thumb_outline_color"),
  48. thumb_center_color("thumb_center_color"),
  49. thumb_image("thumb_image"),
  50. thumb_image_pressed("thumb_image_pressed"),
  51. thumb_image_disabled("thumb_image_disabled"),
  52. track_image_horizontal("track_image_horizontal"),
  53. track_image_vertical("track_image_vertical"),
  54. track_highlight_horizontal_image("track_highlight_horizontal_image"),
  55. track_highlight_vertical_image("track_highlight_vertical_image"),
  56. mouse_down_callback("mouse_down_callback"),
  57. mouse_up_callback("mouse_up_callback")
  58. {
  59. follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
  60. }
  61. LLSlider::LLSlider(const LLSlider::Params& p)
  62. : LLF32UICtrl(p),
  63. mMouseOffset( 0 ),
  64. mOrientation ((p.orientation() == "horizontal") ? HORIZONTAL : VERTICAL),
  65. mTrackColor(p.track_color()),
  66. mThumbOutlineColor(p.thumb_outline_color()),
  67. mThumbCenterColor(p.thumb_center_color()),
  68. mThumbImage(p.thumb_image),
  69. mThumbImagePressed(p.thumb_image_pressed),
  70. mThumbImageDisabled(p.thumb_image_disabled),
  71. mTrackImageHorizontal(p.track_image_horizontal),
  72. mTrackImageVertical(p.track_image_vertical),
  73. mTrackHighlightHorizontalImage(p.track_highlight_horizontal_image),
  74. mTrackHighlightVerticalImage(p.track_highlight_vertical_image),
  75. mMouseDownSignal(NULL),
  76. mMouseUpSignal(NULL)
  77. {
  78.     mViewModel->setValue(p.initial_value);
  79. updateThumbRect();
  80. mDragStartThumbRect = mThumbRect;
  81. setControlName(p.control_name, NULL);
  82. setValue(getValueF32());
  83. if (p.mouse_down_callback.isProvided())
  84. {
  85. setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
  86. }
  87. if (p.mouse_up_callback.isProvided())
  88. {
  89. setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
  90. }
  91. }
  92. LLSlider::~LLSlider()
  93. {
  94. delete mMouseDownSignal;
  95. delete mMouseUpSignal;
  96. }
  97. void LLSlider::setValue(F32 value, BOOL from_event)
  98. {
  99. value = llclamp( value, mMinValue, mMaxValue );
  100. // Round to nearest increment (bias towards rounding down)
  101. value -= mMinValue;
  102. value += mIncrement/2.0001f;
  103. value -= fmod(value, mIncrement);
  104. value += mMinValue;
  105. if (!from_event && getValueF32() != value)
  106. {
  107. setControlValue(value);
  108. }
  109.     LLF32UICtrl::setValue(value);
  110. updateThumbRect();
  111. }
  112. void LLSlider::updateThumbRect()
  113. {
  114. const S32 DEFAULT_THUMB_SIZE = 16;
  115. F32 t = (getValueF32() - mMinValue) / (mMaxValue - mMinValue);
  116. S32 thumb_width = mThumbImage ? mThumbImage->getWidth() : DEFAULT_THUMB_SIZE;
  117. S32 thumb_height = mThumbImage ? mThumbImage->getHeight() : DEFAULT_THUMB_SIZE;
  118. if ( mOrientation == HORIZONTAL )
  119. {
  120. S32 left_edge = (thumb_width / 2);
  121. S32 right_edge = getRect().getWidth() - (thumb_width / 2);
  122. S32 x = left_edge + S32( t * (right_edge - left_edge) );
  123. mThumbRect.mLeft = x - (thumb_width / 2);
  124. mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
  125. mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2);
  126. mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
  127. }
  128. else
  129. {
  130. S32 top_edge = (thumb_height / 2);
  131. S32 bottom_edge = getRect().getHeight() - (thumb_height / 2);
  132. S32 y = top_edge + S32( t * (bottom_edge - top_edge) );
  133. mThumbRect.mLeft = getLocalRect().getCenterX() - (thumb_width / 2);
  134. mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
  135. mThumbRect.mBottom = y  - (thumb_height / 2);
  136. mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
  137. }
  138. }
  139. void LLSlider::setValueAndCommit(F32 value)
  140. {
  141. F32 old_value = getValueF32();
  142. setValue(value);
  143. if (getValueF32() != old_value)
  144. {
  145. onCommit();
  146. }
  147. }
  148. BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask)
  149. {
  150. if( hasMouseCapture() )
  151. {
  152. if ( mOrientation == HORIZONTAL )
  153. {
  154. S32 thumb_half_width = mThumbImage->getWidth()/2;
  155. S32 left_edge = thumb_half_width;
  156. S32 right_edge = getRect().getWidth() - (thumb_half_width);
  157. x += mMouseOffset;
  158. x = llclamp( x, left_edge, right_edge );
  159. F32 t = F32(x - left_edge) / (right_edge - left_edge);
  160. setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
  161. }
  162. else // mOrientation == VERTICAL
  163. {
  164. S32 thumb_half_height = mThumbImage->getHeight()/2;
  165. S32 top_edge = thumb_half_height;
  166. S32 bottom_edge = getRect().getHeight() - (thumb_half_height);
  167. y += mMouseOffset;
  168. y = llclamp(y, top_edge, bottom_edge);
  169. F32 t = F32(y - top_edge) / (bottom_edge - top_edge);
  170. setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
  171. }
  172. getWindow()->setCursor(UI_CURSOR_ARROW);
  173. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
  174. }
  175. else
  176. {
  177. getWindow()->setCursor(UI_CURSOR_ARROW);
  178. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
  179. }
  180. return TRUE;
  181. }
  182. BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
  183. {
  184. BOOL handled = FALSE;
  185. if( hasMouseCapture() )
  186. {
  187. gFocusMgr.setMouseCapture( NULL );
  188. if (mMouseUpSignal)
  189. (*mMouseUpSignal)( this, getValueF32() );
  190. handled = TRUE;
  191. make_ui_sound("UISndClickRelease");
  192. }
  193. else
  194. {
  195. handled = TRUE;
  196. }
  197. return handled;
  198. }
  199. BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
  200. {
  201. // only do sticky-focus on non-chrome widgets
  202. if (!getIsChrome())
  203. {
  204. setFocus(TRUE);
  205. }
  206. if (mMouseDownSignal)
  207. (*mMouseDownSignal)( this, getValueF32() );
  208. if (MASK_CONTROL & mask) // if CTRL is modifying
  209. {
  210. setValueAndCommit(mInitialValue);
  211. }
  212. else
  213. {
  214. // Find the offset of the actual mouse location from the center of the thumb.
  215. if (mThumbRect.pointInRect(x,y))
  216. {
  217. mMouseOffset = (mOrientation == HORIZONTAL)
  218. ? (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x
  219. : (mThumbRect.mBottom + mThumbImage->getHeight()/2) - y;
  220. }
  221. else
  222. {
  223. mMouseOffset = 0;
  224. }
  225. // Start dragging the thumb
  226. // No handler needed for focus lost since this class has no state that depends on it.
  227. gFocusMgr.setMouseCapture( this );  
  228. mDragStartThumbRect = mThumbRect;
  229. }
  230. make_ui_sound("UISndClick");
  231. return TRUE;
  232. }
  233. BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
  234. {
  235. BOOL handled = FALSE;
  236. switch(key)
  237. {
  238. case KEY_DOWN:
  239. case KEY_LEFT:
  240. setValueAndCommit(getValueF32() - getIncrement());
  241. handled = TRUE;
  242. break;
  243. case KEY_UP:
  244. case KEY_RIGHT:
  245. setValueAndCommit(getValueF32() + getIncrement());
  246. handled = TRUE;
  247. break;
  248. default:
  249. break;
  250. }
  251. return handled;
  252. }
  253. BOOL LLSlider::handleScrollWheel(S32 x, S32 y, S32 clicks)
  254. {
  255. if ( mOrientation == VERTICAL )
  256. {
  257. F32 new_val = getValueF32() - clicks * getIncrement();
  258. setValueAndCommit(new_val);
  259. return TRUE;
  260. }
  261. return LLF32UICtrl::handleScrollWheel(x,y,clicks);
  262. }
  263. void LLSlider::draw()
  264. {
  265. F32 alpha = getDrawContext().mAlpha;
  266. // since thumb image might still be decoding, need thumb to accomodate image size
  267. updateThumbRect();
  268. // Draw background and thumb.
  269. // drawing solids requires texturing be disabled
  270. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  271. // Track
  272. LLPointer<LLUIImage>& trackImage = ( mOrientation == HORIZONTAL )
  273. ? mTrackImageHorizontal
  274. : mTrackImageVertical;
  275. LLPointer<LLUIImage>& trackHighlightImage = ( mOrientation == HORIZONTAL )
  276. ? mTrackHighlightHorizontalImage
  277. : mTrackHighlightVerticalImage;
  278. LLRect track_rect;
  279. LLRect highlight_rect;
  280. if ( mOrientation == HORIZONTAL )
  281. {
  282. track_rect.set(mThumbImage->getWidth() / 2,
  283.    getLocalRect().getCenterY() + (trackImage->getHeight() / 2), 
  284.    getRect().getWidth() - mThumbImage->getWidth() / 2,
  285.    getLocalRect().getCenterY() - (trackImage->getHeight() / 2) );
  286. highlight_rect.set(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
  287. }
  288. else
  289. {
  290. track_rect.set(getLocalRect().getCenterX() - (trackImage->getWidth() / 2),
  291.    getRect().getHeight(),
  292.    getLocalRect().getCenterX() + (trackImage->getWidth() / 2),
  293.    0);
  294. highlight_rect.set(track_rect.mLeft, track_rect.mTop, track_rect.mRight, track_rect.mBottom);
  295. }
  296. trackImage->draw(track_rect, LLColor4::white % alpha);
  297. trackHighlightImage->draw(highlight_rect, LLColor4::white % alpha);
  298. // Thumb
  299. if (hasFocus())
  300. {
  301. // Draw focus highlighting.
  302. mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor() % alpha, gFocusMgr.getFocusFlashWidth());
  303. }
  304. if( hasMouseCapture() ) // currently clicking on slider
  305. {
  306. // Show ghost where thumb was before dragging began.
  307. if (mThumbImage.notNull())
  308. {
  309. mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % (0.3f * alpha));
  310. }
  311. if (mThumbImagePressed.notNull())
  312. {
  313. mThumbImagePressed->draw(mThumbRect, mThumbOutlineColor % alpha);
  314. }
  315. }
  316. else if (!isInEnabledChain())
  317. {
  318. if (mThumbImageDisabled.notNull())
  319. {
  320. mThumbImageDisabled->draw(mThumbRect, mThumbCenterColor % alpha);
  321. }
  322. }
  323. else
  324. {
  325. if (mThumbImage.notNull())
  326. {
  327. mThumbImage->draw(mThumbRect, mThumbCenterColor % alpha);
  328. }
  329. }
  330. LLUICtrl::draw();
  331. }
  332. boost::signals2::connection LLSlider::setMouseDownCallback( const commit_signal_t::slot_type& cb ) 
  333. if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
  334. return mMouseDownSignal->connect(cb); 
  335. }
  336. boost::signals2::connection LLSlider::setMouseUpCallback( const commit_signal_t::slot_type& cb )   
  337. if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
  338. return mMouseUpSignal->connect(cb); 
  339. }