llfocusmgr.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llfocusmgr.h"
00035 #include "lluictrl.h"
00036 #include "v4color.h"
00037 
00038 const F32 FOCUS_FADE_TIME = 0.3f;
00039 
00040 LLFocusMgr gFocusMgr;
00041 
00042 LLFocusMgr::LLFocusMgr()
00043         :
00044         mLockedView( NULL ),
00045         mKeyboardLockedFocusLostCallback( NULL ),
00046         mMouseCaptor( NULL ),
00047         mKeyboardFocus( NULL ),
00048         mDefaultKeyboardFocus( NULL ),
00049         mKeyboardFocusLostCallback( NULL ),
00050         mTopCtrl( NULL ),
00051         mFocusWeight(0.f),
00052         mAppHasFocus(TRUE)   // Macs don't seem to notify us that we've gotten focus, so default to true
00053         #ifdef _DEBUG
00054                 , mMouseCaptorName("none")
00055                 , mKeyboardFocusName("none")
00056                 , mTopCtrlName("none")
00057         #endif
00058 {
00059 }
00060 
00061 LLFocusMgr::~LLFocusMgr()
00062 {
00063         mFocusHistory.clear();
00064 }
00065 
00066 void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
00067 {
00068         if( childHasMouseCapture( view ) )
00069         {
00070                 setMouseCapture( NULL );
00071         }
00072 
00073         if( childHasKeyboardFocus( view ))
00074         {
00075                 if (view == mLockedView)
00076                 {
00077                         mLockedView = NULL;
00078                         mKeyboardLockedFocusLostCallback = NULL;
00079                         setKeyboardFocus( NULL, NULL );
00080                 }
00081                 else
00082                 {
00083                         setKeyboardFocus( mLockedView, mKeyboardLockedFocusLostCallback );
00084                 }
00085         }
00086 
00087         if( childIsTopCtrl( view ) )
00088         {
00089                 setTopCtrl( NULL );
00090         }
00091 }
00092 
00093 
00094 void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focus_lost, BOOL lock)
00095 {
00096         if (mLockedView && 
00097                 (new_focus == NULL || 
00098                         (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView))))
00099         {
00100                 // don't allow focus to go to anything that is not the locked focus
00101                 // or one of its descendants
00102                 return;
00103         }
00104         FocusLostCallback old_callback = mKeyboardFocusLostCallback;
00105         mKeyboardFocusLostCallback = on_focus_lost;
00106 
00107         //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
00108 
00109         if( new_focus != mKeyboardFocus )
00110         {
00111                 LLUICtrl* old_focus = mKeyboardFocus;
00112                 mKeyboardFocus = new_focus;
00113 
00114                 // clear out any existing flash
00115                 if (new_focus)
00116                 {
00117                         mFocusWeight = 0.f;
00118                 }
00119                 mFocusTimer.reset();
00120 
00121                 if( old_callback )
00122                 {
00123                         old_callback( old_focus );
00124                 }
00125 
00126                 #ifdef _DEBUG
00127                         mKeyboardFocusName = new_focus ? new_focus->getName() : "none";
00128                 #endif
00129 
00130                 // If we've got a default keyboard focus, and the caller is
00131                 // releasing keyboard focus, move to the default.
00132                 if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL)
00133                 {
00134                         mDefaultKeyboardFocus->setFocus(TRUE);
00135                 }
00136 
00137                 LLView* focus_subtree = mKeyboardFocus;
00138                 LLView* viewp = mKeyboardFocus;
00139                 // find root-most focus root
00140                 while(viewp)
00141                 {
00142                         if (viewp->isFocusRoot())
00143                         {
00144                                 focus_subtree = viewp;
00145                         }
00146                         viewp = viewp->getParent();
00147                 }
00148 
00149                 
00150                 if (focus_subtree)
00151                 {
00152                         mFocusHistory[focus_subtree->mViewHandle] = mKeyboardFocus ? mKeyboardFocus->mViewHandle : LLViewHandle::sDeadHandle; 
00153                 }
00154         }
00155         
00156         if (lock)
00157         {
00158                 lockFocus();
00159         }
00160 }
00161 
00162 void LLFocusMgr::setDefaultKeyboardFocus(LLUICtrl* default_focus)
00163 {
00164         mDefaultKeyboardFocus = default_focus;
00165 }
00166 
00167 // Returns TRUE is parent or any descedent of parent has keyboard focus.
00168 BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
00169 {
00170         LLView* focus_view = mKeyboardFocus;
00171         while( focus_view )
00172         {
00173                 if( focus_view == parent )
00174                 {
00175                         return TRUE;
00176                 }
00177                 focus_view = focus_view->getParent();
00178         }
00179         return FALSE;
00180 }
00181 
00182 // Returns TRUE is parent or any descedent of parent is the mouse captor.
00183 BOOL LLFocusMgr::childHasMouseCapture( LLView* parent )
00184 {
00185         if( mMouseCaptor && mMouseCaptor->isView() )
00186         {
00187                 LLView* captor_view = (LLView*)mMouseCaptor;
00188                 while( captor_view )
00189                 {
00190                         if( captor_view == parent )
00191                         {
00192                                 return TRUE;
00193                         }
00194                         captor_view = captor_view->getParent();
00195                 }
00196         }
00197         return FALSE;
00198 }
00199 
00200 void LLFocusMgr::removeKeyboardFocusWithoutCallback( LLView* focus )
00201 {
00202         // should be ok to unlock here, as you have to know the locked view
00203         // in order to unlock it
00204         if (focus == mLockedView)
00205         {
00206                 mLockedView = NULL;
00207                 mKeyboardLockedFocusLostCallback = NULL;
00208         }
00209 
00210         if( mKeyboardFocus == focus )
00211         {
00212                 mKeyboardFocus = NULL;
00213                 mKeyboardFocusLostCallback = NULL;
00214                 #ifdef _DEBUG
00215                         mKeyboardFocusName = "none";
00216                 #endif
00217         }
00218 }
00219 
00220 
00221 void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
00222 {
00223         //if (mFocusLocked)
00224         //{
00225         //      return;
00226         //}
00227 
00228         if( new_captor != mMouseCaptor )
00229         {
00230                 LLMouseHandler* old_captor = mMouseCaptor;
00231                 mMouseCaptor = new_captor;
00232                 /*
00233                 if (new_captor)
00234                 {
00235                         if ( new_captor->getName() == "Stickto")
00236                         {
00237                                 llinfos << "New mouse captor: " << new_captor->getName() << llendl;
00238                         }
00239                         else
00240                         {
00241                                 llinfos << "New mouse captor: " << new_captor->getName() << llendl;
00242                         }
00243                 }
00244                 else
00245                 {
00246                         llinfos << "New mouse captor: NULL" << llendl;
00247                 }
00248                 */
00249 
00250                 if( old_captor )
00251                 {
00252                         old_captor->onMouseCaptureLost();
00253                 }
00254 
00255                 #ifdef _DEBUG
00256                         mMouseCaptorName = new_captor ? new_captor->getName() : "none";
00257                 #endif
00258         }
00259 }
00260 
00261 void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor )
00262 {
00263         //if (mFocusLocked)
00264         //{
00265         //      return;
00266         //}
00267         if( mMouseCaptor == captor )
00268         {
00269                 mMouseCaptor = NULL;
00270                 #ifdef _DEBUG
00271                         mMouseCaptorName = "none";
00272                 #endif
00273         }
00274 }
00275 
00276 
00277 BOOL LLFocusMgr::childIsTopCtrl( LLView* parent )
00278 {
00279         LLView* top_view = (LLView*)mTopCtrl;
00280         while( top_view )
00281         {
00282                 if( top_view == parent )
00283                 {
00284                         return TRUE;
00285                 }
00286                 top_view = top_view->getParent();
00287         }
00288         return FALSE;
00289 }
00290 
00291 
00292 
00293 // set new_top = NULL to release top_view.
00294 void LLFocusMgr::setTopCtrl( LLUICtrl* new_top  )
00295 {
00296         if( new_top != mTopCtrl )
00297         {
00298                 mTopCtrl = new_top;
00299 
00300                 #ifdef _DEBUG
00301                         mTopCtrlName = new_top ? new_top->getName() : "none";
00302                 #endif
00303         }
00304 }
00305 
00306 void LLFocusMgr::removeTopCtrlWithoutCallback( LLUICtrl* top_view )
00307 {
00308         if( mTopCtrl == top_view )
00309         {
00310                 mTopCtrl = NULL;
00311                 #ifdef _DEBUG
00312                         mTopCtrlName = "none";
00313                 #endif
00314         }
00315 }
00316 
00317 void LLFocusMgr::lockFocus()
00318 {
00319         mLockedView = mKeyboardFocus; 
00320         mKeyboardLockedFocusLostCallback = mKeyboardFocusLostCallback; 
00321 }
00322 
00323 void LLFocusMgr::unlockFocus()
00324 {
00325         mLockedView = NULL; 
00326         mKeyboardLockedFocusLostCallback = NULL;
00327 }
00328 
00329 F32 LLFocusMgr::getFocusFlashAmt()
00330 {
00331         return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f);
00332 }
00333 
00334 LLColor4 LLFocusMgr::getFocusColor()
00335 {
00336         LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt());
00337         // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem)
00338         if (!mAppHasFocus)
00339         {
00340                 focus_color.mV[VALPHA] *= 0.4f;
00341         }
00342         return focus_color;
00343 }
00344 
00345 void LLFocusMgr::triggerFocusFlash()
00346 {
00347         mFocusTimer.reset();
00348         mFocusWeight = 1.f;
00349 }
00350 
00351 void LLFocusMgr::setAppHasFocus(BOOL focus) 
00352 { 
00353         if (!mAppHasFocus && focus)
00354         {
00355                 triggerFocusFlash();
00356         }
00357         
00358         // release focus from "top ctrl"s, which generally hides them
00359         if (!focus && mTopCtrl && mTopCtrl->hasFocus())
00360         {
00361                 mTopCtrl->setFocus(FALSE);
00362         }
00363         mAppHasFocus = focus; 
00364 }
00365 
00366 LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root)
00367 {
00368         if (subtree_root)
00369         {
00370                 focus_history_map_t::iterator found_it = mFocusHistory.find(subtree_root->mViewHandle);
00371                 if (found_it != mFocusHistory.end())
00372                 {
00373                         // found last focus for this subtree
00374                         return static_cast<LLUICtrl*>(LLView::getViewByHandle(found_it->second));
00375                 }
00376         }
00377         return NULL;
00378 }
00379 
00380 void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)
00381 {
00382         if (subtree_root)
00383         {
00384                 mFocusHistory.erase(subtree_root->mViewHandle);
00385         }
00386 }

Generated on Thu Jul 1 06:08:37 2010 for Second Life Viewer by  doxygen 1.4.7