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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llresizebar.cpp
  3.  * @brief LLResizeBar base class
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-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 "llresizebar.h"
  34. #include "llmath.h"
  35. #include "llui.h"
  36. #include "llmenugl.h"
  37. #include "llfocusmgr.h"
  38. #include "llwindow.h"
  39. LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
  40. : LLView(p),
  41. mDragLastScreenX( 0 ),
  42. mDragLastScreenY( 0 ),
  43. mLastMouseScreenX( 0 ),
  44. mLastMouseScreenY( 0 ),
  45. mMinSize( p.min_size ),
  46. mMaxSize( p.max_size ),
  47. mSide( p.side ),
  48. mSnappingEnabled(p.snapping_enabled),
  49. mAllowDoubleClickSnapping(p.allow_double_click_snapping),
  50. mResizingView(p.resizing_view)
  51. {
  52. setFollowsNone();
  53. // set up some generically good follow code.
  54. switch( mSide )
  55. {
  56. case LEFT:
  57. setFollowsLeft();
  58. setFollowsTop();
  59. setFollowsBottom();
  60. break;
  61. case TOP:
  62. setFollowsTop();
  63. setFollowsLeft();
  64. setFollowsRight();
  65. break;
  66. case RIGHT:
  67. setFollowsRight();
  68. setFollowsTop();
  69. setFollowsBottom();
  70. break;
  71. case BOTTOM:
  72. setFollowsBottom();
  73. setFollowsLeft();
  74. setFollowsRight();
  75. break;
  76. default:
  77. break;
  78. }
  79. }
  80. BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
  81. {
  82. // Route future Mouse messages here preemptively.  (Release on mouse up.)
  83. // No handler needed for focus lost since this clas has no state that depends on it.
  84. gFocusMgr.setMouseCapture( this );
  85. localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
  86. mLastMouseScreenX = mDragLastScreenX;
  87. mLastMouseScreenY = mDragLastScreenY;
  88. return TRUE;
  89. }
  90. BOOL LLResizeBar::handleMouseUp(S32 x, S32 y, MASK mask)
  91. {
  92. BOOL handled = FALSE;
  93. if( hasMouseCapture() )
  94. {
  95. // Release the mouse
  96. gFocusMgr.setMouseCapture( NULL );
  97. handled = TRUE;
  98. }
  99. else
  100. {
  101. handled = TRUE;
  102. }
  103. return handled;
  104. }
  105. BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
  106. {
  107. BOOL handled = FALSE;
  108. // We only handle the click if the click both started and ended within us
  109. if( hasMouseCapture() )
  110. {
  111. S32 screen_x;
  112. S32 screen_y;
  113. localPointToScreen(x, y, &screen_x, &screen_y);
  114. S32 delta_x = screen_x - mDragLastScreenX;
  115. S32 delta_y = screen_y - mDragLastScreenY;
  116. LLCoordGL mouse_dir;
  117. // use hysteresis on mouse motion to preserve user intent when mouse stops moving
  118. mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
  119. mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
  120. mLastMouseDir = mouse_dir;
  121. mLastMouseScreenX = screen_x;
  122. mLastMouseScreenY = screen_y;
  123. // Make sure the mouse in still over the application.  We don't want to make the parent
  124. // so big that we can't see the resize handle any more.
  125. LLRect valid_rect = getRootView()->getRect();
  126. if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
  127. {
  128. // undock floater when user resize it
  129. LLFloater* parent = dynamic_cast<LLFloater*>( getParent());
  130. if (parent && parent->isDocked())
  131. {
  132. parent->setDocked( false, false);
  133. }
  134. // Resize the parent
  135. LLRect orig_rect = mResizingView->getRect();
  136. LLRect scaled_rect = orig_rect;
  137. S32 new_width = orig_rect.getWidth();
  138. S32 new_height = orig_rect.getHeight();
  139. switch( mSide )
  140. {
  141. case LEFT:
  142. new_width = llclamp(orig_rect.getWidth() - delta_x, mMinSize, mMaxSize);
  143. delta_x = orig_rect.getWidth() - new_width;
  144. scaled_rect.translate(delta_x, 0);
  145. break;
  146. case TOP:
  147. new_height = llclamp(orig_rect.getHeight() + delta_y, mMinSize, mMaxSize);
  148. delta_y = new_height - orig_rect.getHeight();
  149. break;
  150. case RIGHT:
  151. new_width = llclamp(orig_rect.getWidth() + delta_x, mMinSize, mMaxSize);
  152. delta_x = new_width - orig_rect.getWidth();
  153. break;
  154. case BOTTOM:
  155. new_height = llclamp(orig_rect.getHeight() - delta_y, mMinSize, mMaxSize);
  156. delta_y = orig_rect.getHeight() - new_height;
  157. scaled_rect.translate(0, delta_y);
  158. break;
  159. }
  160. scaled_rect.mTop = scaled_rect.mBottom + new_height;
  161. scaled_rect.mRight = scaled_rect.mLeft + new_width;
  162. mResizingView->setRect(scaled_rect);
  163. LLView* snap_view = NULL;
  164. if (mSnappingEnabled)
  165. {
  166. static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
  167. switch( mSide )
  168. {
  169. case LEFT:
  170. snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
  171. break;
  172. case TOP:
  173. snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, snap_margin);
  174. break;
  175. case RIGHT:
  176. snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
  177. break;
  178. case BOTTOM:
  179. snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, snap_margin);
  180. break;
  181. }
  182. }
  183. // register "snap" behavior with snapped view
  184. mResizingView->setSnappedTo(snap_view);
  185. // restore original rectangle so the appropriate changes are detected
  186. mResizingView->setRect(orig_rect);
  187. // change view shape as user operation
  188. mResizingView->setShape(scaled_rect, true);
  189. // update last valid mouse cursor position based on resized view's actual size
  190. LLRect new_rect = mResizingView->getRect();
  191. switch(mSide)
  192. {
  193. case LEFT:
  194. mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
  195. break;
  196. case RIGHT:
  197. mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
  198. break;
  199. case TOP:
  200. mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
  201. break;
  202. case BOTTOM:
  203. mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
  204. break;
  205. default:
  206. break;
  207. }
  208. }
  209. handled = TRUE;
  210. }
  211. else
  212. {
  213. handled = TRUE;
  214. }
  215. if( handled )
  216. {
  217. switch( mSide )
  218. {
  219. case LEFT:
  220. case RIGHT:
  221. getWindow()->setCursor(UI_CURSOR_SIZEWE);
  222. break;
  223. case TOP:
  224. case BOTTOM:
  225. getWindow()->setCursor(UI_CURSOR_SIZENS);
  226. break;
  227. }
  228. }
  229. return handled;
  230. } // end LLResizeBar::handleHover
  231. BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask)
  232. {
  233. LLRect orig_rect = mResizingView->getRect();
  234. LLRect scaled_rect = orig_rect;
  235. if (mSnappingEnabled && mAllowDoubleClickSnapping)
  236. {
  237. switch( mSide )
  238. {
  239. case LEFT:
  240. mResizingView->findSnapEdge(scaled_rect.mLeft, LLCoordGL(0, 0), SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
  241. scaled_rect.mLeft = scaled_rect.mRight - llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize);
  242. break;
  243. case TOP:
  244. mResizingView->findSnapEdge(scaled_rect.mTop, LLCoordGL(0, 0), SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
  245. scaled_rect.mTop = scaled_rect.mBottom + llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize);
  246. break;
  247. case RIGHT:
  248. mResizingView->findSnapEdge(scaled_rect.mRight, LLCoordGL(0, 0), SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
  249. scaled_rect.mRight = scaled_rect.mLeft + llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize);
  250. break;
  251. case BOTTOM:
  252. mResizingView->findSnapEdge(scaled_rect.mBottom, LLCoordGL(0, 0), SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
  253. scaled_rect.mBottom = scaled_rect.mTop - llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize);
  254. break;
  255. }
  256. mResizingView->setShape(scaled_rect, true);
  257. }
  258. return TRUE;
  259. }