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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldraghandle.cpp
  3.  * @brief LLDragHandle 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. // A widget for dragging a view around the screen using the mouse.
  33. #include "linden_common.h"
  34. #include "lldraghandle.h"
  35. #include "llmath.h"
  36. //#include "llviewerwindow.h"
  37. #include "llui.h"
  38. #include "llmenugl.h"
  39. #include "lltextbox.h"
  40. #include "llcontrol.h"
  41. #include "llfontgl.h"
  42. #include "llwindow.h"
  43. #include "llfocusmgr.h"
  44. #include "lluictrlfactory.h"
  45. const S32 LEADING_PAD = 5;
  46. const S32 TITLE_HPAD = 8;
  47. const S32 BORDER_PAD = 1;
  48. const S32 LEFT_PAD = BORDER_PAD + TITLE_HPAD + LEADING_PAD;
  49. const S32 RIGHT_PAD = BORDER_PAD + 32; // HACK: space for close btn and minimize btn
  50. S32 LLDragHandle::sSnapMargin = 5;
  51. LLDragHandle::LLDragHandle(const LLDragHandle::Params& p)
  52. : LLView(p),
  53. mDragLastScreenX( 0 ),
  54. mDragLastScreenY( 0 ),
  55. mLastMouseScreenX( 0 ),
  56. mLastMouseScreenY( 0 ),
  57. mTitleBox( NULL ),
  58. mMaxTitleWidth( 0 ),
  59. mForeground( TRUE ),
  60. mDragHighlightColor(p.drag_highlight_color()),
  61. mDragShadowColor(p.drag_shadow_color())
  62. {
  63. static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
  64. sSnapMargin = snap_margin;
  65. }
  66. LLDragHandle::~LLDragHandle()
  67. {
  68. removeChild(mTitleBox);
  69. delete mTitleBox;
  70. }
  71. void LLDragHandle::initFromParams(const LLDragHandle::Params& p)
  72. {
  73. LLView::initFromParams(p);
  74. setTitle( p.label );
  75. }
  76. void LLDragHandle::setTitleVisible(BOOL visible) 
  77. if(mTitleBox)
  78. {
  79. mTitleBox->setVisible(visible); 
  80. }
  81. }
  82. void LLDragHandleTop::setTitle(const std::string& title)
  83. {
  84. std::string trimmed_title = title;
  85. LLStringUtil::trim(trimmed_title);
  86. if( mTitleBox )
  87. {
  88. mTitleBox->setText(trimmed_title);
  89. }
  90. else
  91. {
  92. const LLFontGL* font = LLFontGL::getFontSansSerif();
  93. LLTextBox::Params params;
  94. params.name("Drag Handle Title");
  95. params.rect(getRect());
  96. params.initial_value(trimmed_title);
  97. params.font(font);
  98. params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
  99. params.font_shadow(LLFontGL::DROP_SHADOW_SOFT);
  100. params.use_ellipses = true;
  101. params.allow_html = false; //cancel URL replacement in floater title
  102. mTitleBox = LLUICtrlFactory::create<LLTextBox> (params);
  103. addChild( mTitleBox );
  104. }
  105. reshapeTitleBox();
  106. }
  107. std::string LLDragHandleTop::getTitle() const
  108. {
  109. return mTitleBox == NULL ? LLStringUtil::null : mTitleBox->getText();
  110. }
  111. void LLDragHandleLeft::setTitle(const std::string& )
  112. {
  113. if( mTitleBox )
  114. {
  115. removeChild(mTitleBox);
  116. delete mTitleBox;
  117. mTitleBox = NULL;
  118. }
  119. /* no title on left edge */
  120. }
  121. std::string LLDragHandleLeft::getTitle() const
  122. {
  123. return LLStringUtil::null;
  124. }
  125. void LLDragHandleTop::draw()
  126. {
  127. /* Disable lines.  Can drag anywhere in most windows.  JC
  128. if( getVisible() && getEnabled() && mForeground) 
  129. {
  130. const S32 BORDER_PAD = 2;
  131. const S32 HPAD = 2;
  132. const S32 VPAD = 2;
  133. S32 left = BORDER_PAD + HPAD;
  134. S32 top = getRect().getHeight() - 2 * VPAD;
  135. S32 right = getRect().getWidth() - HPAD;
  136. // S32 bottom = VPAD;
  137. // draw lines for drag areas
  138. const S32 LINE_SPACING = (DRAG_HANDLE_HEIGHT - 2 * VPAD) / 4;
  139. S32 line = top - LINE_SPACING;
  140. LLRect title_rect = mTitleBox->getRect();
  141. S32 title_right = title_rect.mLeft + mTitleWidth;
  142. BOOL show_right_side = title_right < getRect().getWidth();
  143. for( S32 i=0; i<4; i++ )
  144. {
  145. gl_line_2d(left, line+1, title_rect.mLeft - LEADING_PAD, line+1, mDragHighlightColor);
  146. if( show_right_side )
  147. {
  148. gl_line_2d(title_right, line+1, right, line+1, mDragHighlightColor);
  149. }
  150. gl_line_2d(left, line, title_rect.mLeft - LEADING_PAD, line, mDragShadowColor);
  151. if( show_right_side )
  152. {
  153. gl_line_2d(title_right, line, right, line, mDragShadowColor);
  154. }
  155. line -= LINE_SPACING;
  156. }
  157. }
  158. */
  159. // Colorize the text to match the frontmost state
  160. if (mTitleBox)
  161. {
  162. mTitleBox->setEnabled(getForeground());
  163. }
  164. LLView::draw();
  165. }
  166. // assumes GL state is set for 2D
  167. void LLDragHandleLeft::draw()
  168. {
  169. /* Disable lines.  Can drag anywhere in most windows. JC
  170. if( getVisible() && getEnabled() && mForeground ) 
  171. {
  172. const S32 BORDER_PAD = 2;
  173. // const S32 HPAD = 2;
  174. const S32 VPAD = 2;
  175. const S32 LINE_SPACING = 3;
  176. S32 left = BORDER_PAD + LINE_SPACING;
  177. S32 top = getRect().getHeight() - 2 * VPAD;
  178. // S32 right = getRect().getWidth() - HPAD;
  179. S32 bottom = VPAD;
  180.  
  181. // draw lines for drag areas
  182. // no titles yet
  183. //LLRect title_rect = mTitleBox->getRect();
  184. //S32 title_right = title_rect.mLeft + mTitleWidth;
  185. //BOOL show_right_side = title_right < getRect().getWidth();
  186. S32 line = left;
  187. for( S32 i=0; i<4; i++ )
  188. {
  189. gl_line_2d(line, top, line, bottom, mDragHighlightColor);
  190. gl_line_2d(line+1, top, line+1, bottom, mDragShadowColor);
  191. line += LINE_SPACING;
  192. }
  193. }
  194. */
  195. // Colorize the text to match the frontmost state
  196. if (mTitleBox)
  197. {
  198. mTitleBox->setEnabled(getForeground());
  199. }
  200. LLView::draw();
  201. }
  202. void LLDragHandleTop::reshapeTitleBox()
  203. {
  204. static LLUICachedControl<S32> title_vpad("UIFloaterTitleVPad", 0);
  205. if( ! mTitleBox)
  206. {
  207. return;
  208. }
  209. const LLFontGL* font = LLFontGL::getFontSansSerif();
  210. S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_HPAD;
  211. if (getMaxTitleWidth() > 0)
  212. title_width = llmin(title_width, getMaxTitleWidth());
  213. S32 title_height = llround(font->getLineHeight());
  214. LLRect title_rect;
  215. title_rect.setLeftTopAndSize( 
  216. LEFT_PAD, 
  217. getRect().getHeight() - title_vpad,
  218. getRect().getWidth() - LEFT_PAD - RIGHT_PAD,
  219. title_height);
  220. // calls reshape on mTitleBox
  221. mTitleBox->setShape( title_rect );
  222. }
  223. void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)
  224. {
  225. LLView::reshape(width, height, called_from_parent);
  226. reshapeTitleBox();
  227. }
  228. void LLDragHandleLeft::reshape(S32 width, S32 height, BOOL called_from_parent)
  229. {
  230. LLView::reshape(width, height, called_from_parent);
  231. }
  232. //-------------------------------------------------------------
  233. // UI event handling
  234. //-------------------------------------------------------------
  235. BOOL LLDragHandle::handleMouseDown(S32 x, S32 y, MASK mask)
  236. {
  237. // Route future Mouse messages here preemptively.  (Release on mouse up.)
  238. // No handler needed for focus lost since this clas has no state that depends on it.
  239. gFocusMgr.setMouseCapture(this);
  240. localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
  241. mLastMouseScreenX = mDragLastScreenX;
  242. mLastMouseScreenY = mDragLastScreenY;
  243. // Note: don't pass on to children
  244. return TRUE;
  245. }
  246. BOOL LLDragHandle::handleMouseUp(S32 x, S32 y, MASK mask)
  247. {
  248. if( hasMouseCapture() )
  249. {
  250. // Release the mouse
  251. gFocusMgr.setMouseCapture( NULL );
  252. }
  253. // Note: don't pass on to children
  254. return TRUE;
  255. }
  256. BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
  257. {
  258. BOOL handled = FALSE;
  259. // We only handle the click if the click both started and ended within us
  260. if( hasMouseCapture() )
  261. {
  262. S32 screen_x;
  263. S32 screen_y;
  264. localPointToScreen(x, y, &screen_x, &screen_y);
  265. // Resize the parent
  266. S32 delta_x = screen_x - mDragLastScreenX;
  267. S32 delta_y = screen_y - mDragLastScreenY;
  268. // if dragging a docked floater we want to undock
  269. if (((LLFloater*)getParent())->isDocked())
  270. {
  271. const S32 SLOP = 12;
  272. if (delta_y <= -SLOP || 
  273. delta_y >= SLOP)
  274. {
  275. ((LLFloater*)getParent())->setDocked(false, false);
  276. return TRUE;
  277. }
  278. else
  279. {
  280. return FALSE;
  281. }
  282. }
  283. LLRect original_rect = getParent()->getRect();
  284. LLRect translated_rect = getParent()->getRect();
  285. translated_rect.translate(delta_x, delta_y);
  286. // temporarily slam dragged window to new position
  287. getParent()->setRect(translated_rect);
  288. S32 pre_snap_x = getParent()->getRect().mLeft;
  289. S32 pre_snap_y = getParent()->getRect().mBottom;
  290. mDragLastScreenX = screen_x;
  291. mDragLastScreenY = screen_y;
  292. LLRect new_rect;
  293. LLCoordGL mouse_dir;
  294. // use hysteresis on mouse motion to preserve user intent when mouse stops moving
  295. mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
  296. mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
  297. mLastMouseDir = mouse_dir;
  298. mLastMouseScreenX = screen_x;
  299. mLastMouseScreenY = screen_y;
  300. LLView* snap_view = getParent()->findSnapRect(new_rect, mouse_dir, SNAP_PARENT_AND_SIBLINGS, sSnapMargin);
  301. getParent()->setSnappedTo(snap_view);
  302. delta_x = new_rect.mLeft - pre_snap_x;
  303. delta_y = new_rect.mBottom - pre_snap_y;
  304. translated_rect.translate(delta_x, delta_y);
  305. // restore original rect so delta are detected, then call user reshape method to handle snapped floaters, etc
  306. getParent()->setRect(original_rect);
  307. getParent()->setShape(translated_rect, true);
  308. mDragLastScreenX += delta_x;
  309. mDragLastScreenY += delta_y;
  310. getWindow()->setCursor(UI_CURSOR_ARROW);
  311. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" <<llendl;
  312. handled = TRUE;
  313. }
  314. else
  315. {
  316. getWindow()->setCursor(UI_CURSOR_ARROW);
  317. lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
  318. handled = TRUE;
  319. }
  320. // Note: don't pass on to children
  321. return handled;
  322. }
  323. void LLDragHandle::setValue(const LLSD& value)
  324. {
  325. setTitle(value.asString());
  326. }