void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) { // notes if keyboard focus is changed again (by onFocusLost/onFocusReceived) // making the rest of our processing unnecessary since it will already be // handled by the recursive call static bool focus_dirty; focus_dirty = false; if (mLockedView && (new_focus == NULL || (new_focus != mLockedView && dynamic_cast<LLView*>(new_focus) && !dynamic_cast<LLView*>(new_focus)->hasAncestor(mLockedView)))) { // don't allow focus to go to anything that is not the locked focus // or one of its descendants return; } mKeystrokesOnly = keystrokes_only; if( new_focus != mKeyboardFocus ) { mLastKeyboardFocus = mKeyboardFocus; mKeyboardFocus = new_focus; // list of the focus and it's ancestors view_handle_list_t old_focus_list = mCachedKeyboardFocusList; view_handle_list_t new_focus_list; // walk up the tree to root and add all views to the new_focus_list for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent()) { new_focus_list.push_back(ctrl->getHandle()); } // remove all common ancestors since their focus is unchanged while (!new_focus_list.empty() && !old_focus_list.empty() && new_focus_list.back() == old_focus_list.back()) { new_focus_list.pop_back(); old_focus_list.pop_back(); } // walk up the old focus branch calling onFocusLost // we bubble up the tree to release focus, and back down to add for (view_handle_list_t::iterator old_focus_iter = old_focus_list.begin(); old_focus_iter != old_focus_list.end() && !focus_dirty; old_focus_iter++) { LLView* old_focus_view = old_focus_iter->get(); if (old_focus_view) { mCachedKeyboardFocusList.pop_front(); old_focus_view->onFocusLost(); } } // walk down the new focus branch calling onFocusReceived for (view_handle_list_t::reverse_iterator new_focus_riter = new_focus_list.rbegin(); new_focus_riter != new_focus_list.rend() && !focus_dirty; new_focus_riter++) { LLView* new_focus_view = new_focus_riter->get(); if (new_focus_view) { mCachedKeyboardFocusList.push_front(new_focus_view->getHandle()); new_focus_view->onFocusReceived(); } } // if focus was changed as part of an onFocusLost or onFocusReceived call // stop iterating on current list since it is now invalid if (focus_dirty) { return; } // If we've got a default keyboard focus, and the caller is // releasing keyboard focus, move to the default. if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL) { mDefaultKeyboardFocus->setFocus(TRUE); } LLView* focus_subtree = dynamic_cast<LLView*>(mKeyboardFocus); LLView* viewp = dynamic_cast<LLView*>(mKeyboardFocus); // find root-most focus root while(viewp) { if (viewp->isFocusRoot()) { focus_subtree = viewp; } viewp = viewp->getParent(); } if (focus_subtree) { LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus); mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>(); } } if (lock) { lockFocus(); } focus_dirty = true; }
void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystrokes_only) { if (mLockedView && (new_focus == NULL || (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView)))) { // don't allow focus to go to anything that is not the locked focus // or one of its descendants return; } //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl; mKeystrokesOnly = keystrokes_only; if( new_focus != mKeyboardFocus ) { mLastKeyboardFocus = mKeyboardFocus; mKeyboardFocus = new_focus; if( mLastKeyboardFocus ) { mLastKeyboardFocus->onFocusLost(); } // clear out any existing flash if (new_focus) { mFocusWeight = 0.f; new_focus->onFocusReceived(); } mFocusTimer.reset(); #ifdef _DEBUG mKeyboardFocusName = new_focus ? new_focus->getName() : std::string("none"); #endif // If we've got a default keyboard focus, and the caller is // releasing keyboard focus, move to the default. if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL) { mDefaultKeyboardFocus->setFocus(TRUE); } LLView* focus_subtree = mKeyboardFocus; LLView* viewp = mKeyboardFocus; // find root-most focus root while(viewp) { if (viewp->isFocusRoot()) { focus_subtree = viewp; } viewp = viewp->getParent(); } if (focus_subtree) { mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle<LLView>(); } } if (lock) { lockFocus(); } }