aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llresizehandle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llui/llresizehandle.cpp')
-rw-r--r--linden/indra/llui/llresizehandle.cpp118
1 files changed, 60 insertions, 58 deletions
diff --git a/linden/indra/llui/llresizehandle.cpp b/linden/indra/llui/llresizehandle.cpp
index fc15bcc..d9b8fac 100644
--- a/linden/indra/llui/llresizehandle.cpp
+++ b/linden/indra/llui/llresizehandle.cpp
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 6 *
7 * Second Life Viewer Source Code
7 * The source code in this file ("Source Code") is provided by Linden Lab 8 * 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 * 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 * ("GPL"), unless you have obtained a separate licensing agreement
@@ -42,8 +43,8 @@ const S32 RESIZE_BORDER_WIDTH = 3;
42LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner ) 43LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
43 : 44 :
44 LLView( name, rect, TRUE ), 45 LLView( name, rect, TRUE ),
45 mDragStartScreenX( 0 ), 46 mDragLastScreenX( 0 ),
46 mDragStartScreenY( 0 ), 47 mDragLastScreenY( 0 ),
47 mLastMouseScreenX( 0 ), 48 mLastMouseScreenX( 0 ),
48 mLastMouseScreenY( 0 ), 49 mLastMouseScreenY( 0 ),
49 mImage( NULL ), 50 mImage( NULL ),
@@ -66,6 +67,9 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi
66 case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break; 67 case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
67 case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break; 68 case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
68 } 69 }
70
71 // decorator object, don't serialize
72 setSaveToXML(FALSE);
69} 73}
70 74
71EWidgetType LLResizeHandle::getWidgetType() const 75EWidgetType LLResizeHandle::getWidgetType() const
@@ -88,11 +92,11 @@ BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask)
88 { 92 {
89 // Route future Mouse messages here preemptively. (Release on mouse up.) 93 // Route future Mouse messages here preemptively. (Release on mouse up.)
90 // No handler needed for focus lost since this clas has no state that depends on it. 94 // No handler needed for focus lost since this clas has no state that depends on it.
91 gFocusMgr.setMouseCapture( this, NULL ); 95 gFocusMgr.setMouseCapture( this );
92 96
93 localPointToScreen(x, y, &mDragStartScreenX, &mDragStartScreenY); 97 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
94 mLastMouseScreenX = mDragStartScreenX; 98 mLastMouseScreenX = mDragLastScreenX;
95 mLastMouseScreenY = mDragStartScreenY; 99 mLastMouseScreenY = mDragLastScreenY;
96 } 100 }
97 } 101 }
98 102
@@ -104,10 +108,10 @@ BOOL LLResizeHandle::handleMouseUp(S32 x, S32 y, MASK mask)
104{ 108{
105 BOOL handled = FALSE; 109 BOOL handled = FALSE;
106 110
107 if( gFocusMgr.getMouseCapture() == this ) 111 if( hasMouseCapture() )
108 { 112 {
109 // Release the mouse 113 // Release the mouse
110 gFocusMgr.setMouseCapture( NULL, NULL ); 114 gFocusMgr.setMouseCapture( NULL );
111 handled = TRUE; 115 handled = TRUE;
112 } 116 }
113 else 117 else
@@ -125,7 +129,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
125 BOOL handled = FALSE; 129 BOOL handled = FALSE;
126 130
127 // We only handle the click if the click both started and ended within us 131 // We only handle the click if the click both started and ended within us
128 if( gFocusMgr.getMouseCapture() == this ) 132 if( hasMouseCapture() )
129 { 133 {
130 // Make sure the mouse in still over the application. We don't want to make the parent 134 // Make sure the mouse in still over the application. We don't want to make the parent
131 // so big that we can't see the resize handle any more. 135 // so big that we can't see the resize handle any more.
@@ -133,18 +137,18 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
133 S32 screen_x; 137 S32 screen_x;
134 S32 screen_y; 138 S32 screen_y;
135 localPointToScreen(x, y, &screen_x, &screen_y); 139 localPointToScreen(x, y, &screen_x, &screen_y);
136 const LLRect& valid_rect = gFloaterView->getRect(); // Assumes that the parent is a floater. 140 const LLRect valid_rect = getRootView()->getRect();
137 screen_x = llclamp( screen_x, valid_rect.mLeft, valid_rect.mRight ); 141 screen_x = llclamp( screen_x, valid_rect.mLeft, valid_rect.mRight );
138 screen_y = llclamp( screen_y, valid_rect.mBottom, valid_rect.mTop ); 142 screen_y = llclamp( screen_y, valid_rect.mBottom, valid_rect.mTop );
139 143
140 LLView* parentView = getParent(); 144 LLView* resizing_view = getParent();
141 if( parentView ) 145 if( resizing_view )
142 { 146 {
143 // Resize the parent 147 // Resize the parent
144 LLRect parent_rect = parentView->getRect(); 148 LLRect orig_rect = resizing_view->getRect();
145 LLRect scaled_rect = parent_rect; 149 LLRect scaled_rect = orig_rect;
146 S32 delta_x = screen_x - mDragStartScreenX; 150 S32 delta_x = screen_x - mDragLastScreenX;
147 S32 delta_y = screen_y - mDragStartScreenY; 151 S32 delta_y = screen_y - mDragLastScreenY;
148 LLCoordGL mouse_dir; 152 LLCoordGL mouse_dir;
149 // use hysteresis on mouse motion to preserve user intent when mouse stops moving 153 // use hysteresis on mouse motion to preserve user intent when mouse stops moving
150 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX; 154 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
@@ -175,18 +179,18 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
175 break; 179 break;
176 } 180 }
177 181
178 S32 new_width = parent_rect.getWidth() + x_multiple * delta_x; 182 S32 new_width = orig_rect.getWidth() + x_multiple * delta_x;
179 if( new_width < mMinWidth ) 183 if( new_width < mMinWidth )
180 { 184 {
181 new_width = mMinWidth; 185 new_width = mMinWidth;
182 delta_x = x_multiple * (mMinWidth - parent_rect.getWidth()); 186 delta_x = x_multiple * (mMinWidth - orig_rect.getWidth());
183 } 187 }
184 188
185 S32 new_height = parent_rect.getHeight() + y_multiple * delta_y; 189 S32 new_height = orig_rect.getHeight() + y_multiple * delta_y;
186 if( new_height < mMinHeight ) 190 if( new_height < mMinHeight )
187 { 191 {
188 new_height = mMinHeight; 192 new_height = mMinHeight;
189 delta_y = y_multiple * (mMinHeight - parent_rect.getHeight()); 193 delta_y = y_multiple * (mMinHeight - orig_rect.getHeight());
190 } 194 }
191 195
192 switch( mCorner ) 196 switch( mCorner )
@@ -207,10 +211,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
207 // temporarily set new parent rect 211 // temporarily set new parent rect
208 scaled_rect.mRight = scaled_rect.mLeft + new_width; 212 scaled_rect.mRight = scaled_rect.mLeft + new_width;
209 scaled_rect.mTop = scaled_rect.mBottom + new_height; 213 scaled_rect.mTop = scaled_rect.mBottom + new_height;
210 parentView->setRect(scaled_rect); 214 resizing_view->setRect(scaled_rect);
211
212 S32 snap_delta_x = 0;
213 S32 snap_delta_y = 0;
214 215
215 LLView* snap_view = NULL; 216 LLView* snap_view = NULL;
216 LLView* test_view = NULL; 217 LLView* test_view = NULL;
@@ -219,77 +220,78 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
219 switch(mCorner) 220 switch(mCorner)
220 { 221 {
221 case LEFT_TOP: 222 case LEFT_TOP:
222 snap_view = parentView->findSnapEdge(snap_delta_x, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 223 snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
223 snap_delta_x -= scaled_rect.mLeft; 224 test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
224 test_view = parentView->findSnapEdge(snap_delta_y, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
225 snap_delta_y -= scaled_rect.mTop;
226 if (!snap_view) 225 if (!snap_view)
227 { 226 {
228 snap_view = test_view; 227 snap_view = test_view;
229 } 228 }
230 scaled_rect.mLeft += snap_delta_x;
231 scaled_rect.mTop += snap_delta_y;
232 break; 229 break;
233 case LEFT_BOTTOM: 230 case LEFT_BOTTOM:
234 snap_view = parentView->findSnapEdge(snap_delta_x, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 231 snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
235 snap_delta_x -= scaled_rect.mLeft; 232 test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
236 test_view = parentView->findSnapEdge(snap_delta_y, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
237 snap_delta_y -= scaled_rect.mBottom;
238 if (!snap_view) 233 if (!snap_view)
239 { 234 {
240 snap_view = test_view; 235 snap_view = test_view;
241 } 236 }
242 scaled_rect.mLeft += snap_delta_x;
243 scaled_rect.mBottom += snap_delta_y;
244 break; 237 break;
245 case RIGHT_TOP: 238 case RIGHT_TOP:
246 snap_view = parentView->findSnapEdge(snap_delta_x, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 239 snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
247 snap_delta_x -= scaled_rect.mRight; 240 test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
248 test_view = parentView->findSnapEdge(snap_delta_y, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
249 snap_delta_y -= scaled_rect.mTop;
250 if (!snap_view) 241 if (!snap_view)
251 { 242 {
252 snap_view = test_view; 243 snap_view = test_view;
253 } 244 }
254 scaled_rect.mRight += snap_delta_x;
255 scaled_rect.mTop += snap_delta_y;
256 break; 245 break;
257 case RIGHT_BOTTOM: 246 case RIGHT_BOTTOM:
258 snap_view = parentView->findSnapEdge(snap_delta_x, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 247 snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
259 snap_delta_x -= scaled_rect.mRight; 248 test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
260 test_view = parentView->findSnapEdge(snap_delta_y, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
261 snap_delta_y -= scaled_rect.mBottom;
262 if (!snap_view) 249 if (!snap_view)
263 { 250 {
264 snap_view = test_view; 251 snap_view = test_view;
265 } 252 }
266 scaled_rect.mRight += snap_delta_x;
267 scaled_rect.mBottom += snap_delta_y;
268 break; 253 break;
269 } 254 }
270 255
271 parentView->snappedTo(snap_view); 256 // register "snap" behavior with snapped view
257 resizing_view->snappedTo(snap_view);
272 258
273 // reset parent rect 259 // reset parent rect
274 parentView->setRect(parent_rect); 260 resizing_view->setRect(orig_rect);
275 261
276 // translate and scale to new shape 262 // translate and scale to new shape
277 parentView->reshape(scaled_rect.getWidth(), scaled_rect.getHeight(), FALSE); 263 resizing_view->userSetShape(scaled_rect);
278 parentView->translate(scaled_rect.mLeft - parentView->getRect().mLeft, scaled_rect.mBottom - parentView->getRect().mBottom);
279 264
280 screen_x = mDragStartScreenX + delta_x + snap_delta_x; 265 // update last valid mouse cursor position based on resized view's actual size
281 screen_y = mDragStartScreenY + delta_y + snap_delta_y; 266 LLRect new_rect = resizing_view->getRect();
282 mDragStartScreenX = screen_x; 267 switch(mCorner)
283 mDragStartScreenY = screen_y; 268 {
269 case LEFT_TOP:
270 mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
271 mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
272 break;
273 case LEFT_BOTTOM:
274 mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
275 mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
276 break;
277 case RIGHT_TOP:
278 mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
279 mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
280 break;
281 case RIGHT_BOTTOM:
282 mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
283 mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
284 break;
285 default:
286 break;
287 }
284 } 288 }
285 289
286 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active) " << llendl;
287 handled = TRUE; 290 handled = TRUE;
288 } 291 }
289 else 292 else
290 if( getVisible() && pointInHandle( x, y ) ) 293 if( getVisible() && pointInHandle( x, y ) )
291 { 294 {
292 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive) " << llendl;
293 handled = TRUE; 295 handled = TRUE;
294 } 296 }
295 297