00001 
00032 
00033 
00034 #include "linden_common.h"
00035 
00036 #include "lldraghandle.h"
00037 
00038 #include "llmath.h"
00039 
00040 
00041 #include "llui.h"
00042 #include "llmenugl.h"
00043 #include "lltextbox.h"
00044 #include "llcontrol.h"
00045 #include "llresmgr.h"
00046 #include "llfontgl.h"
00047 #include "llwindow.h"
00048 #include "llfocusmgr.h"
00049 
00050 const S32 LEADING_PAD = 5;
00051 const S32 TITLE_PAD = 8;
00052 const S32 BORDER_PAD = 1;
00053 const S32 LEFT_PAD = BORDER_PAD + TITLE_PAD + LEADING_PAD;
00054 const S32 RIGHT_PAD = BORDER_PAD + 32; 
00055 
00056 S32 LLDragHandle::sSnapMargin = 5;
00057 
00058 LLDragHandle::LLDragHandle( const LLString& name, const LLRect& rect, const LLString& title )
00059 :       LLView( name, rect, TRUE ),
00060         mDragLastScreenX( 0 ),
00061         mDragLastScreenY( 0 ),
00062         mLastMouseScreenX( 0 ),
00063         mLastMouseScreenY( 0 ),
00064         mDragHighlightColor(    LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
00065         mDragShadowColor(               LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ),
00066         mTitleBox( NULL ),
00067         mMaxTitleWidth( 0 ),
00068         mForeground( TRUE )
00069 {
00070         sSnapMargin = LLUI::sConfigGroup->getS32("SnapMargin");
00071 
00072         setSaveToXML(false);
00073 }
00074 
00075 void LLDragHandle::setTitleVisible(BOOL visible) 
00076 { 
00077         mTitleBox->setVisible(visible); 
00078 }
00079 
00080 LLDragHandleTop::LLDragHandleTop(const LLString& name, const LLRect &rect, const LLString& title)
00081 :       LLDragHandle(name, rect, title)
00082 {
00083         setFollowsAll();
00084         setTitle( title );
00085 }
00086 
00087 EWidgetType LLDragHandleTop::getWidgetType() const
00088 {
00089         return WIDGET_TYPE_DRAG_HANDLE_TOP;
00090 }
00091 
00092 LLString LLDragHandleTop::getWidgetTag() const
00093 {
00094         return LL_DRAG_HANDLE_TOP_TAG;
00095 }
00096 
00097 LLDragHandleLeft::LLDragHandleLeft(const LLString& name, const LLRect &rect, const LLString& title)
00098 :       LLDragHandle(name, rect, title)
00099 {
00100         setFollowsAll();
00101         setTitle( title );
00102 }
00103 
00104 EWidgetType LLDragHandleLeft::getWidgetType() const
00105 {
00106         return WIDGET_TYPE_DRAG_HANDLE_LEFT;
00107 }
00108 
00109 LLString LLDragHandleLeft::getWidgetTag() const
00110 {
00111         return LL_DRAG_HANDLE_LEFT_TAG;
00112 }
00113 
00114 void LLDragHandleTop::setTitle(const LLString& title)
00115 {
00116         if( mTitleBox )
00117         {
00118                 removeChild(mTitleBox);
00119                 delete mTitleBox;
00120         }
00121 
00122         LLString trimmed_title = title;
00123         LLString::trim(trimmed_title);
00124 
00125         const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
00126         mTitleBox = new LLTextBox( "Drag Handle Title", mRect, trimmed_title, font );
00127         mTitleBox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
00128         mTitleBox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
00129         reshapeTitleBox();
00130         
00131         
00132         if (trimmed_title.empty())
00133         {
00134                 mTitleBox->setText(LLString::null);
00135         }
00136         addChild( mTitleBox );
00137 }
00138 
00139 
00140 const LLString& LLDragHandleTop::getTitle() const
00141 {
00142         return mTitleBox->getText();
00143 }
00144 
00145 
00146 void LLDragHandleLeft::setTitle(const LLString& )
00147 {
00148         if( mTitleBox )
00149         {
00150                 removeChild(mTitleBox);
00151                 delete mTitleBox;
00152         }
00153 
00154         mTitleBox = NULL;
00155 
00156         
00157 }
00158 
00159 
00160 const LLString& LLDragHandleLeft::getTitle() const
00161 {
00162         return LLString::null;
00163 }
00164 
00165 
00166 void LLDragHandleTop::draw()
00167 {
00168         
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206         
00207         if (mTitleBox)
00208         {
00209                 mTitleBox->setEnabled(mForeground);
00210         }
00211 
00212         LLView::draw();
00213 }
00214 
00215 
00216 
00217 void LLDragHandleLeft::draw()
00218 {
00219         
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251         
00252         if (mTitleBox)
00253         {
00254                 mTitleBox->setEnabled(mForeground);
00255         }
00256 
00257         LLView::draw();
00258 }
00259 
00260 void LLDragHandleTop::reshapeTitleBox()
00261 {
00262         const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
00263         S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_PAD;
00264         if (mMaxTitleWidth > 0)
00265                 title_width = llmin(title_width, mMaxTitleWidth);
00266         S32 title_height = llround(font->getLineHeight());
00267         LLRect title_rect;
00268         title_rect.setLeftTopAndSize( 
00269                 LEFT_PAD, 
00270                 mRect.getHeight() - BORDER_PAD,
00271                 mRect.getWidth() - LEFT_PAD - RIGHT_PAD,
00272                 title_height);
00273 
00274         mTitleBox->setRect( title_rect );
00275 }
00276 
00277 void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)
00278 {
00279         LLView::reshape(width, height, called_from_parent);
00280         reshapeTitleBox();
00281 }
00282 
00283 void LLDragHandleLeft::reshape(S32 width, S32 height, BOOL called_from_parent)
00284 {
00285         LLView::reshape(width, height, called_from_parent);
00286 }
00287 
00288 
00289 
00290 
00291 
00292 BOOL LLDragHandle::handleMouseDown(S32 x, S32 y, MASK mask)
00293 {
00294         
00295         
00296         gFocusMgr.setMouseCapture(this);
00297 
00298         localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
00299         mLastMouseScreenX = mDragLastScreenX;
00300         mLastMouseScreenY = mDragLastScreenY;
00301 
00302         
00303         return TRUE;
00304 }
00305 
00306 
00307 BOOL LLDragHandle::handleMouseUp(S32 x, S32 y, MASK mask)
00308 {
00309         if( hasMouseCapture() )
00310         {
00311                 
00312                 gFocusMgr.setMouseCapture( NULL );
00313         }
00314 
00315         
00316         return TRUE;
00317 }
00318 
00319 
00320 BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
00321 {
00322         BOOL    handled = FALSE;
00323 
00324         
00325         if( hasMouseCapture() )
00326         {
00327                 S32 screen_x;
00328                 S32 screen_y;
00329                 localPointToScreen(x, y, &screen_x, &screen_y);
00330 
00331                 
00332                 S32 delta_x = screen_x - mDragLastScreenX;
00333                 S32 delta_y = screen_y - mDragLastScreenY;
00334 
00335                 LLRect original_rect = getParent()->getRect();
00336                 LLRect translated_rect = getParent()->getRect();
00337                 translated_rect.translate(delta_x, delta_y);
00338                 
00339                 getParent()->setRect(translated_rect);
00340                 S32 pre_snap_x = getParent()->getRect().mLeft;
00341                 S32 pre_snap_y = getParent()->getRect().mBottom;
00342                 mDragLastScreenX = screen_x;
00343                 mDragLastScreenY = screen_y;
00344 
00345                 LLRect new_rect;
00346                 LLCoordGL mouse_dir;
00347                 
00348                 mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
00349                 mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
00350                 mLastMouseDir = mouse_dir;
00351                 mLastMouseScreenX = screen_x;
00352                 mLastMouseScreenY = screen_y;
00353 
00354                 LLView* snap_view = getParent()->findSnapRect(new_rect, mouse_dir, SNAP_PARENT_AND_SIBLINGS, sSnapMargin);
00355 
00356                 getParent()->snappedTo(snap_view);
00357                 delta_x = new_rect.mLeft - pre_snap_x;
00358                 delta_y = new_rect.mBottom - pre_snap_y;
00359                 translated_rect.translate(delta_x, delta_y);
00360 
00361                 
00362                 getParent()->setRect(original_rect);
00363                 getParent()->userSetShape(translated_rect);
00364 
00365                 mDragLastScreenX += delta_x;
00366                 mDragLastScreenY += delta_y;
00367 
00368                 getWindow()->setCursor(UI_CURSOR_ARROW);
00369                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" <<llendl;                
00370                 handled = TRUE;
00371         }
00372         else if( getVisible() )
00373         {
00374                 getWindow()->setCursor(UI_CURSOR_ARROW);
00375                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;             
00376                 handled = TRUE;
00377         }
00378 
00379         
00380 
00381         return handled;
00382 }
00383 
00384 void LLDragHandle::setValue(const LLSD& value)
00385 {
00386         setTitle(value.asString());
00387 }