llresizebar.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llresizebar.h"
00035 
00036 //#include "llviewermenu.h"
00037 //#include "llviewerimagelist.h"
00038 #include "llmath.h"
00039 #include "llui.h"
00040 #include "llmenugl.h"
00041 #include "llfocusmgr.h"
00042 #include "llwindow.h"
00043 
00044 LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
00045         :
00046         LLView( name, rect, TRUE ),
00047         mDragLastScreenX( 0 ),
00048         mDragLastScreenY( 0 ),
00049         mLastMouseScreenX( 0 ),
00050         mLastMouseScreenY( 0 ),
00051         mMinSize( min_size ),
00052         mMaxSize( max_size ),
00053         mSide( side ),
00054         mSnappingEnabled(TRUE),
00055         mResizingView(resizing_view)
00056 {
00057         // set up some generically good follow code.
00058         switch( side )
00059         {
00060         case LEFT:
00061                 setFollowsLeft();
00062                 setFollowsTop();
00063                 setFollowsBottom();
00064                 break;
00065         case TOP:
00066                 setFollowsTop();
00067                 setFollowsLeft();
00068                 setFollowsRight();
00069                 break;
00070         case RIGHT:
00071                 setFollowsRight();
00072                 setFollowsTop();
00073                 setFollowsBottom();
00074                 break;
00075         case BOTTOM:
00076                 setFollowsBottom();
00077                 setFollowsLeft();
00078                 setFollowsRight();
00079                 break;
00080         default:
00081                 break;
00082         }
00083         // this is just a decorator
00084         setSaveToXML(FALSE);
00085 }
00086 
00087 
00088 BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
00089 {
00090         if( mEnabled )
00091         {
00092                 // Route future Mouse messages here preemptively.  (Release on mouse up.)
00093                 // No handler needed for focus lost since this clas has no state that depends on it.
00094                 gFocusMgr.setMouseCapture( this );
00095 
00096                 localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
00097                 mLastMouseScreenX = mDragLastScreenX;
00098                 mLastMouseScreenY = mDragLastScreenY;
00099         }
00100 
00101         return TRUE;
00102 }
00103 
00104 
00105 BOOL LLResizeBar::handleMouseUp(S32 x, S32 y, MASK mask)
00106 {
00107         BOOL    handled = FALSE;
00108 
00109         if( hasMouseCapture() )
00110         {
00111                 // Release the mouse
00112                 gFocusMgr.setMouseCapture( NULL );
00113                 handled = TRUE;
00114         }
00115         else
00116         {
00117                 handled = TRUE;
00118         }
00119         return handled;
00120 }
00121 
00122 EWidgetType LLResizeBar::getWidgetType() const
00123 {
00124         return WIDGET_TYPE_RESIZE_BAR;
00125 }
00126 
00127 LLString LLResizeBar::getWidgetTag() const
00128 {
00129         return LL_RESIZE_BAR_TAG;
00130 }
00131 
00132 BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
00133 {
00134         BOOL    handled = FALSE;
00135 
00136         // We only handle the click if the click both started and ended within us
00137         if( hasMouseCapture() )
00138         {
00139                 S32 screen_x;
00140                 S32 screen_y;
00141                 localPointToScreen(x, y, &screen_x, &screen_y);
00142                 
00143                 S32 delta_x = screen_x - mDragLastScreenX;
00144                 S32 delta_y = screen_y - mDragLastScreenY;
00145                                 
00146                 LLCoordGL mouse_dir;
00147                 // use hysteresis on mouse motion to preserve user intent when mouse stops moving
00148                 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
00149                 mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
00150                 mLastMouseDir = mouse_dir;
00151                 mLastMouseScreenX = screen_x;
00152                 mLastMouseScreenY = screen_y;
00153 
00154                 // Make sure the mouse in still over the application.  We don't want to make the parent
00155                 // so big that we can't see the resize handle any more.
00156                 LLRect valid_rect = getRootView()->getRect();
00157                 
00158                 if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
00159                 {
00160                         // Resize the parent
00161                         LLRect orig_rect = mResizingView->getRect();
00162                         LLRect scaled_rect = orig_rect;
00163                                 
00164                         S32 new_width = orig_rect.getWidth();
00165                         S32 new_height = orig_rect.getHeight();
00166 
00167                         switch( mSide )
00168                         {
00169                         case LEFT:
00170                                 new_width = llclamp(orig_rect.getWidth() - delta_x, mMinSize, mMaxSize);
00171                                 delta_x = orig_rect.getWidth() - new_width;
00172                                 scaled_rect.translate(delta_x, 0);
00173                                 break;
00174 
00175                         case TOP:
00176                                 new_height = llclamp(orig_rect.getHeight() + delta_y, mMinSize, mMaxSize);
00177                                 delta_y = new_height - orig_rect.getHeight();
00178                                 break;
00179                         
00180                         case RIGHT:
00181                                 new_width = llclamp(orig_rect.getWidth() + delta_x, mMinSize, mMaxSize);
00182                                 delta_x = new_width - orig_rect.getWidth();
00183                                 break;
00184                 
00185                         case BOTTOM:
00186                                 new_height = llclamp(orig_rect.getHeight() - delta_y, mMinSize, mMaxSize);
00187                                 delta_y = orig_rect.getHeight() - new_height;
00188                                 scaled_rect.translate(0, delta_y);
00189                                 break;
00190                         }
00191 
00192                         scaled_rect.mTop = scaled_rect.mBottom + new_height;
00193                         scaled_rect.mRight = scaled_rect.mLeft + new_width;
00194                         mResizingView->setRect(scaled_rect);
00195 
00196                         LLView* snap_view = NULL;
00197 
00198                         if (mSnappingEnabled)
00199                         {
00200                                 switch( mSide )
00201                                 {
00202                                 case LEFT:
00203                                         snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00204                                         break;
00205                                 case TOP:
00206                                         snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00207                                         break;
00208                                 case RIGHT:
00209                                         snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00210                                         break;
00211                                 case BOTTOM:
00212                                         snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
00213                                         break;
00214                                 }
00215                         }
00216 
00217                         // register "snap" behavior with snapped view
00218                         mResizingView->snappedTo(snap_view);
00219 
00220                         // restore original rectangle so the appropriate changes are detected
00221                         mResizingView->setRect(orig_rect);
00222                         // change view shape as user operation
00223                         mResizingView->userSetShape(scaled_rect);
00224 
00225                         // update last valid mouse cursor position based on resized view's actual size
00226                         LLRect new_rect = mResizingView->getRect();
00227                         switch(mSide)
00228                         {
00229                         case LEFT:
00230                                 mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
00231                                 break;
00232                         case RIGHT:
00233                                 mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
00234                                 break;
00235                         case TOP:
00236                                 mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
00237                                 break;
00238                         case BOTTOM:
00239                                 mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
00240                                 break;
00241                         default:
00242                                 break;
00243                         }
00244                 }
00245 
00246                 handled = TRUE;
00247         }
00248         else
00249         {
00250                 handled = TRUE;
00251         }
00252 
00253         if( handled )
00254         {
00255                 switch( mSide )
00256                 {
00257                 case LEFT:
00258                 case RIGHT:
00259                         getWindow()->setCursor(UI_CURSOR_SIZEWE);
00260                         break;
00261 
00262                 case TOP:
00263                 case BOTTOM:
00264                         getWindow()->setCursor(UI_CURSOR_SIZENS);
00265                         break;
00266                 }
00267         }
00268 
00269         return handled;
00270 }
00271 

Generated on Thu Jul 1 06:09:04 2010 for Second Life Viewer by  doxygen 1.4.7