From 941c1ee7f8a0446937c37ba6ce31503a0c360d50 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 9 Jan 2020 20:54:36 +0200 Subject: SL-11172 Scroll to focused object if object is not in visible area --- indra/llui/llaccordionctrl.cpp | 31 +++++++++++++++++++++++++++++++ indra/llui/llaccordionctrl.h | 1 + indra/llui/llaccordionctrltab.cpp | 29 +++++++++++++++++++++++++++++ indra/llui/llaccordionctrltab.h | 1 + indra/llui/lluictrl.cpp | 1 + indra/llui/llview.cpp | 10 ++++++++++ indra/llui/llview.h | 1 + 7 files changed, 74 insertions(+) (limited to 'indra') diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 623f570cef..779508df49 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -655,6 +655,37 @@ void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*) { updateLayout(getRect().getWidth(),getRect().getHeight()); } + +// virtual +void LLAccordionCtrl::onChildGotFocus(const LLUICtrl *cntrl) +{ + if (mScrollbar && mScrollbar->getVisible()) + { + // same as scrollToShowRect + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onChildGotFocus(cntrl); +} + void LLAccordionCtrl::onOpen (const LLSD& key) { for(size_t i=0;igetVisible()) + { + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onChildGotFocus(cntrl); +} + BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask) { if(mCollapsible && mHeaderVisible && mCanOpenClose) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 0263bce4be..53546ad5a1 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -159,6 +159,7 @@ public: * Raises notifyParent event with "child_visibility_change" = new_visibility */ void onVisibilityChange(BOOL new_visibility); + virtual void onChildGotFocus(const LLUICtrl * cntrl); // Changes expand/collapse state and triggers expand/collapse callbacks virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index c98da0d410..e1d275c351 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -679,6 +679,7 @@ void LLUICtrl::setFocus(BOOL b) if (!hasFocus()) { gFocusMgr.setKeyboardFocus( this ); + onChildGotFocus(this); } } else diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index b0e346f513..aa64b2c16e 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -640,6 +640,16 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) } } +// virtual +void LLView::onChildGotFocus(const LLUICtrl * cntrl) +{ + LLView* parent_view = getParent(); + if (parent_view) + { + parent_view->onChildGotFocus(cntrl); + } +} + // virtual void LLView::translate(S32 x, S32 y) { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index b448cc8397..031405035e 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -301,6 +301,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual void onVisibilityChange ( BOOL new_visibility ); + virtual void onChildGotFocus(const LLUICtrl * cntrl); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); } -- cgit v1.2.3