aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/lldraghandle.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llui/lldraghandle.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llui/lldraghandle.cpp')
-rw-r--r--linden/indra/llui/lldraghandle.cpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/linden/indra/llui/lldraghandle.cpp b/linden/indra/llui/lldraghandle.cpp
new file mode 100644
index 0000000..261d149
--- /dev/null
+++ b/linden/indra/llui/lldraghandle.cpp
@@ -0,0 +1,372 @@
1/**
2 * @file lldraghandle.cpp
3 * @brief LLDragHandle base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// A widget for dragging a view around the screen using the mouse.
29
30#include "linden_common.h"
31
32#include "lldraghandle.h"
33
34#include "llmath.h"
35
36//#include "llviewerwindow.h"
37#include "llui.h"
38#include "llmenugl.h"
39#include "lltextbox.h"
40#include "llcontrol.h"
41#include "llresmgr.h"
42#include "llfontgl.h"
43#include "llwindow.h"
44#include "llfocusmgr.h"
45
46const S32 LEADING_PAD = 5;
47const S32 TITLE_PAD = 8;
48const S32 BORDER_PAD = 1;
49const S32 LEFT_PAD = BORDER_PAD + TITLE_PAD + LEADING_PAD;
50const S32 RIGHT_PAD = BORDER_PAD + 32; // HACK: space for close btn and minimize btn
51
52S32 LLDragHandle::sSnapMargin = 5;
53
54LLDragHandle::LLDragHandle( const LLString& name, const LLRect& rect, const LLString& title )
55: LLView( name, rect, TRUE ),
56 mDragLastScreenX( 0 ),
57 mDragLastScreenY( 0 ),
58 mLastMouseScreenX( 0 ),
59 mLastMouseScreenY( 0 ),
60 mDragHighlightColor( LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
61 mDragShadowColor( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ),
62 mTitleBox( NULL ),
63 mMaxTitleWidth( 0 ),
64 mForeground( TRUE )
65{
66 sSnapMargin = LLUI::sConfigGroup->getS32("SnapMargin");
67
68 setSaveToXML(false);
69}
70
71void LLDragHandle::setTitleVisible(BOOL visible)
72{
73 mTitleBox->setVisible(visible);
74}
75
76LLDragHandleTop::LLDragHandleTop(const LLString& name, const LLRect &rect, const LLString& title)
77: LLDragHandle(name, rect, title)
78{
79 setFollowsAll();
80 setTitle( title );
81}
82
83EWidgetType LLDragHandleTop::getWidgetType() const
84{
85 return WIDGET_TYPE_DRAG_HANDLE_TOP;
86}
87
88LLString LLDragHandleTop::getWidgetTag() const
89{
90 return LL_DRAG_HANDLE_TOP_TAG;
91}
92
93LLDragHandleLeft::LLDragHandleLeft(const LLString& name, const LLRect &rect, const LLString& title)
94: LLDragHandle(name, rect, title)
95{
96 setFollowsAll();
97 setTitle( title );
98}
99
100EWidgetType LLDragHandleLeft::getWidgetType() const
101{
102 return WIDGET_TYPE_DRAG_HANDLE_LEFT;
103}
104
105LLString LLDragHandleLeft::getWidgetTag() const
106{
107 return LL_DRAG_HANDLE_LEFT_TAG;
108}
109
110void LLDragHandleTop::setTitle(const LLString& title)
111{
112 if( mTitleBox )
113 {
114 removeChild(mTitleBox);
115 delete mTitleBox;
116 }
117
118 LLString trimmed_title = title;
119 LLString::trim(trimmed_title);
120
121 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
122 mTitleBox = new LLTextBox( "Drag Handle Title", mRect, trimmed_title, font );
123 mTitleBox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
124 reshapeTitleBox();
125
126 // allow empty titles, as default behavior replaces them with title box name
127 if (trimmed_title.empty())
128 {
129 mTitleBox->setText(LLString::null);
130 }
131 addChild( mTitleBox );
132}
133
134
135const LLString& LLDragHandleTop::getTitle() const
136{
137 return mTitleBox->getText();
138}
139
140
141void LLDragHandleLeft::setTitle(const LLString& )
142{
143 if( mTitleBox )
144 {
145 removeChild(mTitleBox);
146 delete mTitleBox;
147 }
148
149 mTitleBox = NULL;
150
151 /* no title on left edge */
152}
153
154
155const LLString& LLDragHandleLeft::getTitle() const
156{
157 return LLString::null;
158}
159
160
161void LLDragHandleTop::draw()
162{
163 /* Disable lines. Can drag anywhere in most windows. JC
164 if( getVisible() && mEnabled && mForeground)
165 {
166 const S32 BORDER_PAD = 2;
167 const S32 HPAD = 2;
168 const S32 VPAD = 2;
169 S32 left = BORDER_PAD + HPAD;
170 S32 top = mRect.getHeight() - 2 * VPAD;
171 S32 right = mRect.getWidth() - HPAD;
172// S32 bottom = VPAD;
173
174 // draw lines for drag areas
175
176 const S32 LINE_SPACING = (DRAG_HANDLE_HEIGHT - 2 * VPAD) / 4;
177 S32 line = top - LINE_SPACING;
178
179 LLRect title_rect = mTitleBox->getRect();
180 S32 title_right = title_rect.mLeft + mTitleWidth;
181 BOOL show_right_side = title_right < mRect.getWidth();
182
183 for( S32 i=0; i<4; i++ )
184 {
185 gl_line_2d(left, line+1, title_rect.mLeft - LEADING_PAD, line+1, mDragHighlightColor);
186 if( show_right_side )
187 {
188 gl_line_2d(title_right, line+1, right, line+1, mDragHighlightColor);
189 }
190
191 gl_line_2d(left, line, title_rect.mLeft - LEADING_PAD, line, mDragShadowColor);
192 if( show_right_side )
193 {
194 gl_line_2d(title_right, line, right, line, mDragShadowColor);
195 }
196 line -= LINE_SPACING;
197 }
198 }
199 */
200
201 // Colorize the text to match the frontmost state
202 if (mTitleBox)
203 {
204 mTitleBox->setEnabled(mForeground);
205 }
206
207 LLView::draw();
208}
209
210
211// assumes GL state is set for 2D
212void LLDragHandleLeft::draw()
213{
214 /* Disable lines. Can drag anywhere in most windows. JC
215 if( getVisible() && mEnabled && mForeground )
216 {
217 const S32 BORDER_PAD = 2;
218// const S32 HPAD = 2;
219 const S32 VPAD = 2;
220 const S32 LINE_SPACING = 3;
221
222 S32 left = BORDER_PAD + LINE_SPACING;
223 S32 top = mRect.getHeight() - 2 * VPAD;
224// S32 right = mRect.getWidth() - HPAD;
225 S32 bottom = VPAD;
226
227 // draw lines for drag areas
228
229 // no titles yet
230 //LLRect title_rect = mTitleBox->getRect();
231 //S32 title_right = title_rect.mLeft + mTitleWidth;
232 //BOOL show_right_side = title_right < mRect.getWidth();
233
234 S32 line = left;
235 for( S32 i=0; i<4; i++ )
236 {
237 gl_line_2d(line, top, line, bottom, mDragHighlightColor);
238
239 gl_line_2d(line+1, top, line+1, bottom, mDragShadowColor);
240
241 line += LINE_SPACING;
242 }
243 }
244 */
245
246 // Colorize the text to match the frontmost state
247 if (mTitleBox)
248 {
249 mTitleBox->setEnabled(mForeground);
250 }
251
252 LLView::draw();
253}
254
255void LLDragHandleTop::reshapeTitleBox()
256{
257 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
258 S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_PAD;
259 if (mMaxTitleWidth > 0)
260 title_width = llmin(title_width, mMaxTitleWidth);
261 S32 title_height = llround(font->getLineHeight());
262 LLRect title_rect;
263 title_rect.setLeftTopAndSize(
264 LEFT_PAD,
265 mRect.getHeight() - BORDER_PAD,
266 mRect.getWidth() - LEFT_PAD - RIGHT_PAD,
267 title_height);
268
269 mTitleBox->setRect( title_rect );
270}
271
272void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)
273{
274 LLView::reshape(width, height, called_from_parent);
275 reshapeTitleBox();
276}
277
278void LLDragHandleLeft::reshape(S32 width, S32 height, BOOL called_from_parent)
279{
280 LLView::reshape(width, height, called_from_parent);
281}
282
283//-------------------------------------------------------------
284// UI event handling
285//-------------------------------------------------------------
286
287BOOL LLDragHandle::handleMouseDown(S32 x, S32 y, MASK mask)
288{
289 // Route future Mouse messages here preemptively. (Release on mouse up.)
290 // No handler needed for focus lost since this clas has no state that depends on it.
291 gFocusMgr.setMouseCapture(this, NULL );
292
293 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
294 mLastMouseScreenX = mDragLastScreenX;
295 mLastMouseScreenY = mDragLastScreenY;
296
297 // Note: don't pass on to children
298 return TRUE;
299}
300
301
302BOOL LLDragHandle::handleMouseUp(S32 x, S32 y, MASK mask)
303{
304 if( gFocusMgr.getMouseCapture() == this )
305 {
306 // Release the mouse
307 gFocusMgr.setMouseCapture( NULL, NULL );
308 }
309
310 // Note: don't pass on to children
311 return TRUE;
312}
313
314
315BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
316{
317 BOOL handled = FALSE;
318
319 // We only handle the click if the click both started and ended within us
320 if( gFocusMgr.getMouseCapture() == this )
321 {
322 S32 screen_x;
323 S32 screen_y;
324 localPointToScreen(x, y, &screen_x, &screen_y);
325
326 // Resize the parent
327 S32 delta_x = screen_x - mDragLastScreenX;
328 S32 delta_y = screen_y - mDragLastScreenY;
329 getParent()->translate(delta_x, delta_y);
330 S32 pre_snap_x = getParent()->getRect().mLeft;
331 S32 pre_snap_y = getParent()->getRect().mBottom;
332 mDragLastScreenX = screen_x;
333 mDragLastScreenY = screen_y;
334
335 LLRect new_rect;
336 LLCoordGL mouse_dir;
337 // use hysteresis on mouse motion to preserve user intent when mouse stops moving
338 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
339 mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
340 mLastMouseDir = mouse_dir;
341 mLastMouseScreenX = screen_x;
342 mLastMouseScreenY = screen_y;
343
344 LLView* snap_view = getParent()->findSnapRect(new_rect, mouse_dir, SNAP_PARENT_AND_SIBLINGS, sSnapMargin);
345
346 getParent()->snappedTo(snap_view);
347 delta_x = new_rect.mLeft - pre_snap_x;
348 delta_y = new_rect.mBottom - pre_snap_y;
349 getParent()->translate(delta_x, delta_y);
350 mDragLastScreenX += delta_x;
351 mDragLastScreenY += delta_y;
352
353 getWindow()->setCursor(UI_CURSOR_ARROW);
354 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" <<llendl;
355 handled = TRUE;
356 }
357 else if( getVisible() )
358 {
359 getWindow()->setCursor(UI_CURSOR_ARROW);
360 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
361 handled = TRUE;
362 }
363
364 // Note: don't pass on to children
365
366 return handled;
367}
368
369void LLDragHandle::setValue(const LLSD& value)
370{
371 setTitle(value.asString());
372}