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 }