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

Generated on Fri May 16 08:32:52 2008 for SecondLife by  doxygen 1.5.5