diff options
author | Richard Linden <none@none> | 2013-11-05 19:30:38 -0800 |
---|---|---|
committer | Richard Linden <none@none> | 2013-11-05 19:30:38 -0800 |
commit | a10eb7b240675b009430f6718d410399d8045581 (patch) | |
tree | 9e8b615b5fbd4f6fb17b835cd14559f3b85eafba /indra/llui | |
parent | c35801ef1c56b6c84063f47b490a8d2220b77ca7 (diff) |
further fix of inventory keyboard focus and tab order calculations
Diffstat (limited to 'indra/llui')
-rwxr-xr-x | indra/llui/llfloater.cpp | 7 | ||||
-rwxr-xr-x | indra/llui/llpanel.cpp | 201 | ||||
-rwxr-xr-x | indra/llui/llpanel.h | 38 | ||||
-rwxr-xr-x | indra/llui/lluictrl.cpp | 149 | ||||
-rwxr-xr-x | indra/llui/lluictrl.h | 3 | ||||
-rwxr-xr-x | indra/llui/llview.cpp | 172 | ||||
-rwxr-xr-x | indra/llui/llview.h | 34 | ||||
-rwxr-xr-x | indra/llui/llviewquery.cpp | 25 | ||||
-rwxr-xr-x | indra/llui/llviewquery.h | 7 |
9 files changed, 177 insertions, 459 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 6cb77e51a9..44a919a303 100755 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2905,13 +2905,6 @@ void LLFloaterView::syncFloaterTabOrder() } } } - - // sync draw order to tab order - for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) - { - LLFloater* floaterp = (LLFloater*)*child_it; - moveChildToFrontOfTabGroup(floaterp); - } } LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index f2acff9d55..ee90574161 100755 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -38,10 +38,8 @@ #include "lldir.h" #include "lltimer.h" -#include "llaccordionctrltab.h" #include "llbutton.h" #include "llmenugl.h" -//#include "llstatusbar.h" #include "llui.h" #include "llkeyboard.h" #include "lllineeditor.h" @@ -50,7 +48,6 @@ #include "lluictrl.h" #include "lluictrlfactory.h" #include "llviewborder.h" -#include "lltabcontainer.h" static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); LLPanel::factory_stack_t LLPanel::sFactoryStack; @@ -166,8 +163,8 @@ void LLPanel::removeBorder() // virtual void LLPanel::clearCtrls() { - LLView::ctrl_list_t ctrls = getCtrlList(); - for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it) + LLPanel::ctrl_list_t ctrls = getCtrlList(); + for (LLPanel::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it) { LLUICtrl* ctrl = *ctrl_it; ctrl->setFocus( FALSE ); @@ -178,14 +175,29 @@ void LLPanel::clearCtrls() void LLPanel::setCtrlsEnabled( BOOL b ) { - LLView::ctrl_list_t ctrls = getCtrlList(); - for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it) + LLPanel::ctrl_list_t ctrls = getCtrlList(); + for (LLPanel::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it) { LLUICtrl* ctrl = *ctrl_it; ctrl->setEnabled( b ); } } +LLPanel::ctrl_list_t LLPanel::getCtrlList() const +{ + ctrl_list_t controls; + for(child_list_t::const_iterator it = getChildList()->begin(), end_it = getChildList()->end(); it != end_it; ++it) + { + LLView* viewp = *it; + if(viewp->isCtrl()) + { + controls.push_back(static_cast<LLUICtrl*>(viewp)); + } + } + return controls; +} + + void LLPanel::draw() { F32 alpha = getDrawContext().mAlpha; @@ -637,16 +649,6 @@ void LLPanel::childSetVisible(const std::string& id, bool visible) } } -bool LLPanel::childIsVisible(const std::string& id) const -{ - LLView* child = findChild<LLView>(id); - if (child) - { - return (bool)child->getVisible(); - } - return false; -} - void LLPanel::childSetEnabled(const std::string& id, bool enabled) { LLView* child = findChild<LLView>(id); @@ -656,55 +658,6 @@ void LLPanel::childSetEnabled(const std::string& id, bool enabled) } } -void LLPanel::childSetTentative(const std::string& id, bool tentative) -{ - LLUICtrl* child = findChild<LLUICtrl>(id); - if (child) - { - child->setTentative(tentative); - } -} - -bool LLPanel::childIsEnabled(const std::string& id) const -{ - LLView* child = findChild<LLView>(id); - if (child) - { - return (bool)child->getEnabled(); - } - return false; -} - - -void LLPanel::childSetToolTip(const std::string& id, const std::string& msg) -{ - LLView* child = findChild<LLView>(id); - if (child) - { - child->setToolTip(msg); - } -} - -void LLPanel::childSetRect(const std::string& id, const LLRect& rect) -{ - LLView* child = findChild<LLView>(id); - if (child) - { - child->setRect(rect); - } -} - -bool LLPanel::childGetRect(const std::string& id, LLRect& rect) const -{ - LLView* child = findChild<LLView>(id); - if (child) - { - rect = child->getRect(); - return true; - } - return false; -} - void LLPanel::childSetFocus(const std::string& id, BOOL focus) { LLUICtrl* child = findChild<LLUICtrl>(id); @@ -740,15 +693,6 @@ void LLPanel::childSetCommitCallback(const std::string& id, boost::function<void } } -void LLPanel::childSetValidate(const std::string& id, boost::function<bool (const LLSD& data)> cb) -{ - LLUICtrl* child = findChild<LLUICtrl>(id); - if (child) - { - child->setValidateBeforeCommit(cb); - } -} - void LLPanel::childSetColor(const std::string& id, const LLColor4& color) { LLUICtrl* child = findChild<LLUICtrl>(id); @@ -828,95 +772,6 @@ BOOL LLPanel::childSetLabelArg(const std::string& id, const std::string& key, co return FALSE; } -BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text) -{ - LLView* child = findChild<LLView>(id); - if (child) - { - return child->setToolTipArg(key, text); - } - return FALSE; -} - -void LLPanel::childShowTab(const std::string& id, const std::string& tabname, bool visible) -{ - LLTabContainer* child = findChild<LLTabContainer>(id); - if (child) - { - child->selectTabByName(tabname); - } -} - -LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const -{ - LLTabContainer* child = findChild<LLTabContainer>(id); - if (child) - { - return child->getCurrentPanel(); - } - return NULL; -} - -LLPanel* LLPanel::childGetVisibleTabWithHelp() -{ - LLView *child; - - bfs_tree_iterator_t it = beginTreeBFS(); - // skip ourselves - ++it; - for (; it != endTreeBFS(); ++it) - { - child = *it; - LLPanel *curTabPanel = NULL; - - // do we have a tab container? - LLTabContainer *tab = dynamic_cast<LLTabContainer *>(child); - if (tab && tab->getVisible()) - { - curTabPanel = tab->getCurrentPanel(); - } - - // do we have an accordion tab? - LLAccordionCtrlTab* accordion = dynamic_cast<LLAccordionCtrlTab *>(child); - if (accordion && accordion->getDisplayChildren()) - { - curTabPanel = dynamic_cast<LLPanel *>(accordion->getAccordionView()); - } - - // if we found a valid tab, does it have a help topic? - if (curTabPanel && !curTabPanel->getHelpTopic().empty()) - { - return curTabPanel; - } - } - - // couldn't find any active tabs with a help topic string - return NULL; -} - - -LLPanel *LLPanel::childGetVisiblePanelWithHelp() -{ - LLView *child; - - bfs_tree_iterator_t it = beginTreeBFS(); - // skip ourselves - ++it; - for (; it != endTreeBFS(); ++it) - { - child = *it; - // do we have a panel with a help topic? - LLPanel *panel = dynamic_cast<LLPanel *>(child); - if (panel && panel->isInVisibleChain() && !panel->getHelpTopic().empty()) - { - return panel; - } - } - - // couldn't find any active panels with a help topic string - return NULL; -} - void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function) { LLButton* button = findChild<LLButton>(id); @@ -935,24 +790,6 @@ void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> } } -void LLPanel::childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value) -{ - LLTextBox* textbox = findChild<LLTextBox>(id); - if (textbox) - { - textbox->setClickedCallback(boost::bind(function, value)); - } -} - -void LLPanel::childSetControlName(const std::string& id, const std::string& control_name) -{ - LLUICtrl* view = findChild<LLUICtrl>(id); - if (view) - { - view->setControlName(control_name, NULL); - } -} - boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t::slot_type& cb ) { if (!mVisibleSignal) diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index ac8583ece9..9f2a31e632 100755 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -105,6 +105,8 @@ protected: LLPanel(const LLPanel::Params& params = getDefaultParams()); public: + typedef std::vector<class LLUICtrl *> ctrl_list_t; + BOOL buildFromFile(const std::string &filename, const LLPanel::Params& default_params = getDefaultParams()); static LLPanel* createFactoryPanel(const std::string& name); @@ -154,6 +156,7 @@ public: std::string getHelpTopic() const { return mHelpTopic; } void setCtrlsEnabled(BOOL b); + ctrl_list_t getCtrlList() const; LLHandle<LLPanel> getHandle() const { return getDerivedHandle<LLPanel>(); } @@ -174,19 +177,10 @@ public: // LLView void childSetVisible(const std::string& name, bool visible); - void childShow(const std::string& name) { childSetVisible(name, true); } - void childHide(const std::string& name) { childSetVisible(name, false); } - bool childIsVisible(const std::string& id) const; - void childSetTentative(const std::string& name, bool tentative); void childSetEnabled(const std::string& name, bool enabled); void childEnable(const std::string& name) { childSetEnabled(name, true); } void childDisable(const std::string& name) { childSetEnabled(name, false); }; - bool childIsEnabled(const std::string& id) const; - - void childSetToolTip(const std::string& id, const std::string& msg); - void childSetRect(const std::string& id, const LLRect &rect); - bool childGetRect(const std::string& id, LLRect& rect) const; // LLUICtrl void childSetFocus(const std::string& id, BOOL focus = TRUE); @@ -197,9 +191,6 @@ public: // which takes a generic slot. Or use mCommitCallbackRegistrar.add() with // a named callback and reference it in XML. void childSetCommitCallback(const std::string& id, boost::function<void (LLUICtrl*,void*)> cb, void* data); - - void childSetValidate(const std::string& id, boost::function<bool (const LLSD& data)> cb ); - void childSetColor(const std::string& id, const LLColor4& color); LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const; @@ -214,34 +205,11 @@ public: // Not implemented for all types, defaults to noop, returns FALSE if not applicaple BOOL childSetTextArg(const std::string& id, const std::string& key, const LLStringExplicit& text); BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text); - BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text); - // LLTabContainer - void childShowTab(const std::string& id, const std::string& tabname, bool visible = true); - LLPanel *childGetVisibleTab(const std::string& id) const; - - // Find a child with a nonempty Help topic - LLPanel *childGetVisibleTabWithHelp(); - LLPanel *childGetVisiblePanelWithHelp(); - - // LLTextBox/LLTextEditor/LLLineEditor - void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); } - - // *NOTE: Does not return text from <string> tags, use getString() - std::string childGetText(const std::string& id) const { return childGetValue(id).asString(); } - - // LLLineEditor - void childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) ); - // LLButton void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value); void childSetAction(const std::string& id, const commit_signal_t::slot_type& function); - // LLTextBox - void childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value = NULL); - - void childSetControlName(const std::string& id, const std::string& control_name); - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); //call onOpen to let panel know when it's about to be shown or activated diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index ef364dd3d3..d0a5931e8c 100755 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -33,6 +33,8 @@ #include "llfocusmgr.h" #include "llpanel.h" #include "lluictrlfactory.h" +#include "lltabcontainer.h" +#include "llaccordionctrltab.h" static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl"); @@ -702,54 +704,19 @@ BOOL LLUICtrl::getIsChrome() const } } -// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, -// but to switch up the order so that children that have the default tab group come first -// and those that are prior to the default tab group come last -class CompareByDefaultTabGroup: public LLCompareByTabOrder -{ -public: - CompareByDefaultTabGroup(const LLView::child_tab_order_t& order, S32 default_tab_group): - LLCompareByTabOrder(order), - mDefaultTabGroup(default_tab_group) {} -private: - /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const - { - S32 ag = a.first; // tab group for a - S32 bg = b.first; // tab group for b - // these two ifs have the effect of moving elements prior to the default tab group to the end of the list - // (still sorted relative to each other, though) - if(ag < mDefaultTabGroup && bg >= mDefaultTabGroup) return false; - if(bg < mDefaultTabGroup && ag >= mDefaultTabGroup) return true; - return a < b; // sort correctly if they're both on the same side of the default tab group - } - S32 mDefaultTabGroup; -}; -// Sorter for plugging into the query. -// I'd have defined it local to the one method that uses it but that broke the VS 05 compiler. -MG -class LLUICtrl::DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter> -{ -public: - /*virtual*/ void operator() (LLView * parent, viewList_t &children) const - { - children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup())); - } -}; - LLTrace::BlockTimerStatHandle FTM_FOCUS_FIRST_ITEM("Focus First Item"); BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) { LL_RECORD_BLOCK_TIME(FTM_FOCUS_FIRST_ITEM); // try to select default tab group child - LLCtrlQuery query = getTabOrderQuery(); - // sort things such that the default tab group is at the front - query.setSorter(DefaultTabGroupFirstSorter::getInstance()); + LLViewQuery query = getTabOrderQuery(); child_list_t result = query(this); if(result.size() > 0) { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); if(!ctrl->hasFocus()) { ctrl->setFocus(TRUE); @@ -764,17 +731,20 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) // search for text field first if(prefer_text_fields) { - LLCtrlQuery query = getTabOrderQuery(); + LLViewQuery query = getTabOrderQuery(); query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); child_list_t result = query(this); if(result.size() > 0) { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); if(!ctrl->hasFocus()) { ctrl->setFocus(TRUE); ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); + if(focus_flash) + { + gFocusMgr.triggerFocusFlash(); + } } return TRUE; } @@ -783,58 +753,26 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) result = getTabOrderQuery().run(this); if(result.size() > 0) { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front()); + LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); if(!ctrl->hasFocus()) { ctrl->setFocus(TRUE); ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - return FALSE; -} - -BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields) -{ - // search for text field first - if(prefer_text_fields) - { - LLCtrlQuery query = getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - child_list_t result = query(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); - if(!ctrl->hasFocus()) + if(focus_flash) { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); gFocusMgr.triggerFocusFlash(); } - return TRUE; - } - } - // no text field found, or we don't care about text fields - child_list_t result = getTabOrderQuery().run(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); } return TRUE; } return FALSE; } + BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) { // this assumes that this method is called on the focus root. - LLCtrlQuery query = getTabOrderQuery(); + LLViewQuery query = getTabOrderQuery(); static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false); if(text_fields_only || tab_to_text_fields_only) { @@ -847,7 +785,7 @@ BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only) { // this assumes that this method is called on the focus root. - LLCtrlQuery query = getTabOrderQuery(); + LLViewQuery query = getTabOrderQuery(); static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false); if(text_fields_only || tab_to_text_fields_only) { @@ -904,8 +842,26 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out) if (panel) { + + LLView *child; + LLPanel *subpanel = NULL; + // does the panel have a sub-panel with a help topic? - LLPanel *subpanel = panel->childGetVisiblePanelWithHelp(); + bfs_tree_iterator_t it = beginTreeBFS(); + // skip ourselves + ++it; + for (; it != endTreeBFS(); ++it) + { + child = *it; + // do we have a panel with a help topic? + LLPanel *panel = dynamic_cast<LLPanel *>(child); + if (panel && panel->isInVisibleChain() && !panel->getHelpTopic().empty()) + { + subpanel = panel; + break; + } + } + if (subpanel) { help_topic_out = subpanel->getHelpTopic(); @@ -913,10 +869,41 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out) } // does the panel have an active tab with a help topic? - LLPanel *tab = panel->childGetVisibleTabWithHelp(); - if (tab) + LLPanel *tab_panel = NULL; + + it = beginTreeBFS(); + // skip ourselves + ++it; + for (; it != endTreeBFS(); ++it) + { + child = *it; + LLPanel *curTabPanel = NULL; + + // do we have a tab container? + LLTabContainer *tab = dynamic_cast<LLTabContainer *>(child); + if (tab && tab->getVisible()) + { + curTabPanel = tab->getCurrentPanel(); + } + + // do we have an accordion tab? + LLAccordionCtrlTab* accordion = dynamic_cast<LLAccordionCtrlTab *>(child); + if (accordion && accordion->getDisplayChildren()) + { + curTabPanel = dynamic_cast<LLPanel *>(accordion->getAccordionView()); + } + + // if we found a valid tab, does it have a help topic? + if (curTabPanel && !curTabPanel->getHelpTopic().empty()) + { + tab_panel = curTabPanel; + break; + } + } + + if (tab_panel) { - help_topic_out = tab->getHelpTopic(); + help_topic_out = tab_panel->getHelpTopic(); return true; // success (tab) } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index fb2196bb16..99553ee0d2 100755 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -220,7 +220,6 @@ public: BOOL focusNextItem(BOOL text_entry_only); BOOL focusPrevItem(BOOL text_entry_only); BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); - BOOL focusLastItem(BOOL prefer_text_fields = FALSE); // Non Virtuals LLHandle<LLUICtrl> getHandle() const { return getDerivedHandle<LLUICtrl>(); } @@ -315,8 +314,6 @@ private: BOOL mTentative; ETypeTransparency mTransparencyType; - - class DefaultTabGroupFirstSorter; }; // Build time optimization, generate once in .cpp file diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 1982c97b8c..e0fa59793c 100755 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -140,7 +140,6 @@ LLView::LLView(const LLView::Params& p) mFromXUI(p.from_xui), mIsFocusRoot(p.focus_root), mLastVisible(FALSE), - mNextInsertionOrdinal(0), mHoverCursor(getCursorFromString(p.hover_cursor)), mEnabled(p.enabled), mMouseOpaque(p.mouse_opaque), @@ -275,22 +274,6 @@ void LLView::sendChildToBack(LLView* child) } } -void LLView::moveChildToFrontOfTabGroup(LLUICtrl* child) -{ - if(mCtrlOrder.find(child) != mCtrlOrder.end()) - { - mCtrlOrder[child].second = -1 * mNextInsertionOrdinal++; - } -} - -void LLView::moveChildToBackOfTabGroup(LLUICtrl* child) -{ - if(mCtrlOrder.find(child) != mCtrlOrder.end()) - { - mCtrlOrder[child].second = mNextInsertionOrdinal++; - } -} - // virtual bool LLView::addChild(LLView* child, S32 tab_group) { @@ -298,7 +281,8 @@ bool LLView::addChild(LLView* child, S32 tab_group) { return false; } - if (mParentView == child) + + if (this == child) { LL_ERRS() << "Adding view " << child->getName() << " as child of itself" << LL_ENDL; } @@ -312,14 +296,10 @@ bool LLView::addChild(LLView* child, S32 tab_group) // add to front of child list, as normal mChildList.push_front(child); - // add to ctrl list if is LLUICtrl - if (child->isCtrl()) + // add to tab order list + if (tab_group != 0) { - LLUICtrl* ctrl = static_cast<LLUICtrl*>(child); - mCtrlOrder.insert(tab_order_pair_t(ctrl, - tab_order_t(tab_group, mNextInsertionOrdinal))); - - mNextInsertionOrdinal++; + mTabOrder.insert(tab_order_pair_t(child, tab_group)); } child->mParentView = this; @@ -350,13 +330,10 @@ void LLView::removeChild(LLView* child) llassert(child->mInDraw == false); mChildList.remove( child ); child->mParentView = NULL; - if (child->isCtrl()) + child_tab_order_t::iterator found = mTabOrder.find(child); + if(found != mTabOrder.end()) { - child_tab_order_t::iterator found = mCtrlOrder.find(static_cast<LLUICtrl*>(child)); - if(found != mCtrlOrder.end()) - { - mCtrlOrder.erase(found); - } + mTabOrder.erase(found); } } else @@ -366,53 +343,6 @@ void LLView::removeChild(LLView* child) updateBoundingRect(); } -LLView::ctrl_list_t LLView::getCtrlList() const -{ - ctrl_list_t controls; - BOOST_FOREACH(LLView* viewp, mChildList) - { - if(viewp->isCtrl()) - { - controls.push_back(static_cast<LLUICtrl*>(viewp)); - } - } - return controls; -} - -LLView::ctrl_list_t LLView::getCtrlListSorted() const -{ - ctrl_list_t controls = getCtrlList(); - std::sort(controls.begin(), controls.end(), LLCompareByTabOrder(mCtrlOrder)); - return controls; -} - - -// This method compares two LLViews by the tab order specified in the comparator object. The -// code for this is a little convoluted because each argument can have four states: -// 1) not a control, 2) a control but not in the tab order, 3) a control in the tab order, 4) null -bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const b) const -{ - S32 a_score = 0, b_score = 0; - if(a) a_score--; - if(b) b_score--; - if(a && a->isCtrl()) a_score--; - if(b && b->isCtrl()) b_score--; - if(a_score == -2 && b_score == -2) - { - const LLUICtrl * const a_ctrl = static_cast<const LLUICtrl*>(a); - const LLUICtrl * const b_ctrl = static_cast<const LLUICtrl*>(b); - LLView::child_tab_order_const_iter_t a_found = mTabOrder.find(a_ctrl), b_found = mTabOrder.find(b_ctrl); - if(a_found != mTabOrder.end()) a_score--; - if(b_found != mTabOrder.end()) b_score--; - if(a_score == -3 && b_score == -3) - { - // whew! Once we're in here, they're both in the tab order, and we can compare based on that - return compareTabOrders(a_found->second, b_found->second); - } - } - return (a_score == b_score) ? a < b : a_score < b_score; -} - BOOL LLView::isInVisibleChain() const { BOOL visible = TRUE; @@ -536,9 +466,9 @@ BOOL LLView::focusPrevRoot() // static BOOL LLView::focusNext(LLView::child_list_t & result) { - LLView::child_list_iter_t focused = result.end(); - for(LLView::child_list_iter_t iter = result.begin(); - iter != result.end(); + LLView::child_list_reverse_iter_t focused = result.rend(); + for(LLView::child_list_reverse_iter_t iter = result.rbegin(); + iter != result.rend(); ++iter) { if(gFocusMgr.childHasKeyboardFocus(*iter)) @@ -547,14 +477,14 @@ BOOL LLView::focusNext(LLView::child_list_t & result) break; } } - LLView::child_list_iter_t next = focused; - next = (next == result.end()) ? result.begin() : ++next; + LLView::child_list_reverse_iter_t next = focused; + next = (next == result.rend()) ? result.rbegin() : ++next; while(next != focused) { // wrap around to beginning if necessary - if(next == result.end()) + if(next == result.rend()) { - next = result.begin(); + next = result.rbegin(); } if((*next)->isCtrl()) { @@ -572,9 +502,9 @@ BOOL LLView::focusNext(LLView::child_list_t & result) // static BOOL LLView::focusPrev(LLView::child_list_t & result) { - LLView::child_list_reverse_iter_t focused = result.rend(); - for(LLView::child_list_reverse_iter_t iter = result.rbegin(); - iter != result.rend(); + LLView::child_list_iter_t focused = result.end(); + for(LLView::child_list_iter_t iter = result.begin(); + iter != result.end(); ++iter) { if(gFocusMgr.childHasKeyboardFocus(*iter)) @@ -583,14 +513,14 @@ BOOL LLView::focusPrev(LLView::child_list_t & result) break; } } - LLView::child_list_reverse_iter_t next = focused; - next = (next == result.rend()) ? result.rbegin() : ++next; + LLView::child_list_iter_t next = focused; + next = (next == result.end()) ? result.begin() : ++next; while(next != focused) { // wrap around to beginning if necessary - if(next == result.rend()) + if(next == result.end()) { - next = result.rbegin(); + next = result.begin(); } if((*next)->isCtrl()) { @@ -614,7 +544,7 @@ BOOL LLView::focusPrev(LLView::child_list_t & result) void LLView::deleteAllChildren() { // clear out the control ordering - mCtrlOrder.clear(); + mTabOrder.clear(); while (!mChildList.empty()) { @@ -1823,15 +1753,63 @@ BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, const LLV return FALSE; } + +class CompareByTabOrder +{ +public: + CompareByTabOrder(const LLView::child_tab_order_t& order, S32 default_tab_group = 0) + : mTabOrder(order), + mDefaultTabGroup(default_tab_group) + {} + virtual ~CompareByTabOrder() {} + + // This method compares two LLViews by the tab order specified in the comparator object. The + // code for this is a little convoluted because each argument can have four states: + // 1) not a control, 2) a control but not in the tab order, 3) a control in the tab order, 4) null + bool operator() (const LLView* const a, const LLView* const b) const + { + S32 a_group = 0, b_group = 0; + if(!a) return false; + if(!b) return true; + + LLView::child_tab_order_const_iter_t a_found = mTabOrder.find(a), b_found = mTabOrder.find(b); + if(a_found != mTabOrder.end()) + { + a_group = a_found->second; + } + if(b_found != mTabOrder.end()) + { + b_group = b_found->second; + } + + if(a_group < mDefaultTabGroup && b_group >= mDefaultTabGroup) return true; + if(b_group < mDefaultTabGroup && a_group >= mDefaultTabGroup) return false; + return a_group > b_group; // sort correctly if they're both on the same side of the default tab groupreturn a > b; + } +private: + // ok to store a reference, as this should only be allocated on stack during view query operations + const LLView::child_tab_order_t& mTabOrder; + const S32 mDefaultTabGroup; +}; + +class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> +{ + /*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const + { + children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup())); + } +}; + // static -const LLCtrlQuery & LLView::getTabOrderQuery() +const LLViewQuery & LLView::getTabOrderQuery() { - static LLCtrlQuery query; + static LLViewQuery query; if(query.getPreFilters().size() == 0) { query.addPreFilter(LLVisibleFilter::getInstance()); query.addPreFilter(LLEnabledFilter::getInstance()); query.addPreFilter(LLTabStopFilter::getInstance()); query.addPostFilter(LLLeavesFilter::getInstance()); + query.setSorter(SortByTabOrder::getInstance()); } return query; } @@ -1846,9 +1824,9 @@ class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRoots }; // static -const LLCtrlQuery & LLView::getFocusRootsQuery() +const LLViewQuery & LLView::getFocusRootsQuery() { - static LLCtrlQuery query; + static LLViewQuery query; if(query.getPreFilters().size() == 0) { query.addPreFilter(LLVisibleFilter::getInstance()); query.addPreFilter(LLEnabledFilter::getInstance()); diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 665aad70cf..7861c8f729 100755 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -200,12 +200,9 @@ public: typedef child_list_t::reverse_iterator child_list_reverse_iter_t; typedef child_list_t::const_reverse_iterator child_list_const_reverse_iter_t; - typedef std::vector<class LLUICtrl *> ctrl_list_t; - - typedef std::pair<S32, S32> tab_order_t; - typedef std::pair<LLUICtrl *, tab_order_t> tab_order_pair_t; + typedef std::pair<LLView *, S32> tab_order_pair_t; // this structure primarily sorts by the tab group, secondarily by the insertion ordinal (lastly by the value of the pointer) - typedef std::map<const LLUICtrl*, tab_order_t> child_tab_order_t; + typedef std::map<const LLView*, S32> child_tab_order_t; typedef child_tab_order_t::iterator child_tab_order_iter_t; typedef child_tab_order_t::const_iterator child_tab_order_const_iter_t; typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t; @@ -251,8 +248,6 @@ public: void sendChildToFront(LLView* child); void sendChildToBack(LLView* child); - void moveChildToFrontOfTabGroup(LLUICtrl* child); - void moveChildToBackOfTabGroup(LLUICtrl* child); virtual bool addChild(LLView* view, S32 tab_group = 0); @@ -264,9 +259,7 @@ public: virtual BOOL postBuild() { return TRUE; } - const child_tab_order_t& getCtrlOrder() const { return mCtrlOrder; } - ctrl_list_t getCtrlList() const; - ctrl_list_t getCtrlListSorted() const; + const child_tab_order_t& getTabOrder() const { return mTabOrder; } void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } S32 getDefaultTabGroup() const { return mDefaultTabGroup; } @@ -500,9 +493,9 @@ public: static BOOL focusPrev(LLView::child_list_t & result); // returns query for iterating over controls in tab order - static const LLCtrlQuery & getTabOrderQuery(); + static const LLViewQuery & getTabOrderQuery(); // return query for iterating over focus roots in tab order - static const LLCtrlQuery & getFocusRootsQuery(); + static const LLViewQuery & getFocusRootsQuery(); static LLWindow* getWindow(void) { return LLUI::sWindow; } @@ -596,7 +589,7 @@ private: U32 mReshapeFlags; - child_tab_order_t mCtrlOrder; + child_tab_order_t mTabOrder; S32 mDefaultTabGroup; S32 mLastTabGroup; @@ -613,8 +606,6 @@ private: BOOL mLastVisible; - S32 mNextInsertionOrdinal; - bool mInDraw; static LLWindow* sWindow; // All root views must know about their window. @@ -686,19 +677,6 @@ struct TypeValues<LLView::EOrientation> : public LLInitParam::TypeValuesHelper<L }; } - -class LLCompareByTabOrder -{ -public: - LLCompareByTabOrder(const LLView::child_tab_order_t& order) : mTabOrder(order) {} - virtual ~LLCompareByTabOrder() {} - bool operator() (const LLView* const a, const LLView* const b) const; -private: - virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { return a < b; } - // ok to store a reference, as this should only be allocated on stack during view query operations - const LLView::child_tab_order_t& mTabOrder; -}; - template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) const { LLView* child = findChildView(name, recurse); diff --git a/indra/llui/llviewquery.cpp b/indra/llui/llviewquery.cpp index d0b78ba186..66262609ae 100755 --- a/indra/llui/llviewquery.cpp +++ b/indra/llui/llviewquery.cpp @@ -30,7 +30,7 @@ #include "lluictrl.h" #include "llviewquery.h" -void LLQuerySorter::operator() (LLView * parent, viewList_t &children) const {} +void LLQuerySorter::sort(LLView * parent, viewList_t &children) const {} filterResult_t LLLeavesFilter::operator() (const LLView* const view, const viewList_t & children) const { @@ -89,8 +89,8 @@ viewList_t LLViewQuery::run(LLView* view) const if (pre.first) { post = runFilters(view, filtered_children, mPostFilters); - } } + } if(pre.first && post.first) { @@ -105,12 +105,12 @@ viewList_t LLViewQuery::run(LLView* view) const return result; } -void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const +void LLViewQuery::filterChildren(LLView* parent_view, viewList_t & filtered_children) const { - LLView::child_list_t views(*(view->getChildList())); + LLView::child_list_t views(*(parent_view->getChildList())); if (mSorterp) { - (*mSorterp)(view, views); // sort the children per the sorter + mSorterp->sort(parent_view, views); // sort the children per the sorter } for(LLView::child_list_iter_t iter = views.begin(); iter != views.end(); @@ -134,18 +134,3 @@ filterResult_t LLViewQuery::runFilters(LLView * view, const viewList_t children, } return result; } - -class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> -{ - /*virtual*/ void operator() (LLView * parent, LLView::child_list_t &children) const - { - children.sort(LLCompareByTabOrder(parent->getCtrlOrder())); - } -}; - -LLCtrlQuery::LLCtrlQuery() : - LLViewQuery() -{ - setSorter(SortByTabOrder::getInstance()); -} - diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 210f95162a..9044c4ff29 100755 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -49,7 +49,7 @@ class LLQuerySorter { public: virtual ~LLQuerySorter() {}; - virtual void operator() (LLView * parent, viewList_t &children) const; + virtual void sort(LLView * parent, viewList_t &children) const; }; class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter> @@ -127,10 +127,5 @@ private: const LLQuerySorter* mSorterp; }; -class LLCtrlQuery : public LLViewQuery -{ -public: - LLCtrlQuery(); -}; #endif // LL_LLVIEWQUERY_H |