00001
00032 #include "linden_common.h"
00033
00034 #include "llresizebar.h"
00035
00036 #include "llmath.h"
00037 #include "llui.h"
00038 #include "llmenugl.h"
00039 #include "llfocusmgr.h"
00040 #include "llwindow.h"
00041
00042 LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
00043 :
00044 LLView( name, rect, TRUE ),
00045 mDragLastScreenX( 0 ),
00046 mDragLastScreenY( 0 ),
00047 mLastMouseScreenX( 0 ),
00048 mLastMouseScreenY( 0 ),
00049 mMinSize( min_size ),
00050 mMaxSize( max_size ),
00051 mSide( side ),
00052 mSnappingEnabled(TRUE),
00053 mAllowDoubleClickSnapping(TRUE),
00054 mResizingView(resizing_view)
00055 {
00056
00057 switch( side )
00058 {
00059 case LEFT:
00060 setFollowsLeft();
00061 setFollowsTop();
00062 setFollowsBottom();
00063 break;
00064 case TOP:
00065 setFollowsTop();
00066 setFollowsLeft();
00067 setFollowsRight();
00068 break;
00069 case RIGHT:
00070 setFollowsRight();
00071 setFollowsTop();
00072 setFollowsBottom();
00073 break;
00074 case BOTTOM:
00075 setFollowsBottom();
00076 setFollowsLeft();
00077 setFollowsRight();
00078 break;
00079 default:
00080 break;
00081 }
00082
00083 setSaveToXML(FALSE);
00084 }
00085
00086
00087 BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
00088 {
00089
00090
00091 gFocusMgr.setMouseCapture( this );
00092
00093 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
00094 mLastMouseScreenX = mDragLastScreenX;
00095 mLastMouseScreenY = mDragLastScreenY;
00096
00097 return TRUE;
00098 }
00099
00100
00101 BOOL LLResizeBar::handleMouseUp(S32 x, S32 y, MASK mask)
00102 {
00103 BOOL handled = FALSE;
00104
00105 if( hasMouseCapture() )
00106 {
00107
00108 gFocusMgr.setMouseCapture( NULL );
00109 handled = TRUE;
00110 }
00111 else
00112 {
00113 handled = TRUE;
00114 }
00115 return handled;
00116 }
00117
00118
00119 BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
00120 {
00121 BOOL handled = FALSE;
00122
00123
00124 if( hasMouseCapture() )
00125 {
00126 S32 screen_x;
00127 S32 screen_y;
00128 localPointToScreen(x, y, &screen_x, &screen_y);
00129
00130 S32 delta_x = screen_x - mDragLastScreenX;
00131 S32 delta_y = screen_y - mDragLastScreenY;
00132
00133 LLCoordGL mouse_dir;
00134
00135 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
00136 mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
00137 mLastMouseDir = mouse_dir;
00138 mLastMouseScreenX = screen_x;
00139 mLastMouseScreenY = screen_y;
00140
00141
00142
00143 LLRect valid_rect = getRootView()->getRect();
00144
00145 if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
00146 {
00147
00148 LLRect orig_rect = mResizingView->getRect();
00149 LLRect scaled_rect = orig_rect;
00150
00151 S32 new_width = orig_rect.getWidth();
00152 S32 new_height = orig_rect.getHeight();
00153
00154 switch( mSide )
00155 {
00156 case LEFT:
00157 new_width = llclamp(orig_rect.getWidth() - delta_x, mMinSize, mMaxSize);
00158 delta_x = orig_rect.getWidth() - new_width;
00159 scaled_rect.translate(delta_x, 0);
00160 break;
00161
00162 case TOP:
00163 new_height = llclamp(orig_rect.getHeight() + delta_y, mMinSize, mMaxSize);
00164 delta_y = new_height - orig_rect.getHeight();
00165 break;
00166
00167 case RIGHT:
00168 new_width = llclamp(orig_rect.getWidth() + delta_x, mMinSize, mMaxSize);
00169 delta_x = new_width - orig_rect.getWidth();
00170 break;
00171
00172 case BOTTOM:
00173 new_height = llclamp(orig_rect.getHeight() - delta_y, mMinSize, mMaxSize);
00174 delta_y = orig_rect.getHeight() - new_height;
00175 scaled_rect.translate(0, delta_y);
00176 break;
00177 }
00178
00179 scaled_rect.mTop = scaled_rect.mBottom + new_height;
00180 scaled_rect.mRight = scaled_rect.mLeft + new_width;
00181 mResizingView->setRect(scaled_rect);
00182
00183 LLView* snap_view = NULL;
00184
00185 if (mSnappingEnabled)
00186 {
00187 switch( mSide )
00188 {
00189 case LEFT:
00190 snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00191 break;
00192 case TOP:
00193 snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00194 break;
00195 case RIGHT:
00196 snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00197 break;
00198 case BOTTOM:
00199 snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00200 break;
00201 }
00202 }
00203
00204
00205 mResizingView->snappedTo(snap_view);
00206
00207
00208 mResizingView->setRect(orig_rect);
00209
00210 mResizingView->userSetShape(scaled_rect);
00211
00212
00213 LLRect new_rect = mResizingView->getRect();
00214 switch(mSide)
00215 {
00216 case LEFT:
00217 mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
00218 break;
00219 case RIGHT:
00220 mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
00221 break;
00222 case TOP:
00223 mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
00224 break;
00225 case BOTTOM:
00226 mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
00227 break;
00228 default:
00229 break;
00230 }
00231 }
00232
00233 handled = TRUE;
00234 }
00235 else
00236 {
00237 handled = TRUE;
00238 }
00239
00240 if( handled )
00241 {
00242 switch( mSide )
00243 {
00244 case LEFT:
00245 case RIGHT:
00246 getWindow()->setCursor(UI_CURSOR_SIZEWE);
00247 break;
00248
00249 case TOP:
00250 case BOTTOM:
00251 getWindow()->setCursor(UI_CURSOR_SIZENS);
00252 break;
00253 }
00254 }
00255
00256 return handled;
00257 }
00258
00259 BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask)
00260 {
00261 LLRect orig_rect = mResizingView->getRect();
00262 LLRect scaled_rect = orig_rect;
00263
00264 if (mSnappingEnabled && mAllowDoubleClickSnapping)
00265 {
00266 switch( mSide )
00267 {
00268 case LEFT:
00269 mResizingView->findSnapEdge(scaled_rect.mLeft, LLCoordGL(0, 0), SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
00270 scaled_rect.mLeft = scaled_rect.mRight - llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize);
00271 break;
00272 case TOP:
00273 mResizingView->findSnapEdge(scaled_rect.mTop, LLCoordGL(0, 0), SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
00274 scaled_rect.mTop = scaled_rect.mBottom + llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize);
00275 break;
00276 case RIGHT:
00277 mResizingView->findSnapEdge(scaled_rect.mRight, LLCoordGL(0, 0), SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
00278 scaled_rect.mRight = scaled_rect.mLeft + llclamp(scaled_rect.getWidth(), mMinSize, mMaxSize);
00279 break;
00280 case BOTTOM:
00281 mResizingView->findSnapEdge(scaled_rect.mBottom, LLCoordGL(0, 0), SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, S32_MAX);
00282 scaled_rect.mBottom = scaled_rect.mTop - llclamp(scaled_rect.getHeight(), mMinSize, mMaxSize);
00283 break;
00284 }
00285
00286 mResizingView->userSetShape(scaled_rect);
00287 }
00288
00289 return TRUE;
00290 }
00291