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)   
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                 
00101                 
00102                 return;
00103         }
00104         FocusLostCallback old_callback = mKeyboardFocusLostCallback;
00105         mKeyboardFocusLostCallback = on_focus_lost;
00106 
00107         
00108 
00109         if( new_focus != mKeyboardFocus )
00110         {
00111                 LLUICtrl* old_focus = mKeyboardFocus;
00112                 mKeyboardFocus = new_focus;
00113 
00114                 
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                 
00131                 
00132                 if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL)
00133                 {
00134                         mDefaultKeyboardFocus->setFocus(TRUE);
00135                 }
00136 
00137                 LLView* focus_subtree = mKeyboardFocus;
00138                 LLView* viewp = mKeyboardFocus;
00139                 
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 
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 
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         
00203         
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         
00224         
00225         
00226         
00227 
00228         if( new_captor != mMouseCaptor )
00229         {
00230                 LLMouseHandler* old_captor = mMouseCaptor;
00231                 mMouseCaptor = new_captor;
00232                 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
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         
00264         
00265         
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 
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         
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         
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                         
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 }