diff options
author | Seth ProductEngine <slitovchuk@productengine.com> | 2011-12-03 01:19:50 +0200 |
---|---|---|
committer | Seth ProductEngine <slitovchuk@productengine.com> | 2011-12-03 01:19:50 +0200 |
commit | 71974461114d81f818f69a4344ce4071c20f331f (patch) | |
tree | 1001c8464a9c79f7fb8e611e7f92af7bc15703d8 /indra/newview | |
parent | ef0552a090123974682790afdafec68218578113 (diff) |
EXP-1506 FIXED updating IM toasts visibility upoon mouse over and mouse leave events.
The mouse position is checked every frame in relation to the toast to catch the mouse leaving the toast "i" button when the toast is moved by the screen channel.
The fix is intended to avoid the toasts that don't fade in the following scenario:
1. Have User A Send 4 IM messages to User B: a, b, c, d
2. Have User B hover their mouse over the i on toast c (don't click on it just hover)
3. As the other toasts fade observe toast c moves up to the top and does not fade
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lltoast.cpp | 146 | ||||
-rw-r--r-- | indra/newview/lltoast.h | 8 |
2 files changed, 74 insertions, 80 deletions
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 2d9d3241d8..c4b226b70b 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -113,7 +113,8 @@ LLToast::LLToast(const LLToast::Params& p) mHideBtnPressed(false), mIsTip(p.is_tip), mWrapperPanel(NULL), - mIsFading(false) + mIsFading(false), + mIsHovered(false) { mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); @@ -122,8 +123,6 @@ LLToast::LLToast(const LLToast::Params& p) setCanDrag(FALSE); mWrapperPanel = getChild<LLPanel>("wrapper_panel"); - mWrapperPanel->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this)); - mWrapperPanel->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this)); setBackgroundOpaque(TRUE); // *TODO: obsolete updateTransparency(); @@ -137,8 +136,6 @@ LLToast::LLToast(const LLToast::Params& p) { mHideBtn = getChild<LLButton>("hide_btn"); mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); - mHideBtn->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this)); - mHideBtn->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this)); } // init callbacks if present @@ -331,6 +328,55 @@ void LLToast::draw() drawChild(mHideBtn); } } + + updateHoveredState(); + + LLToastLifeTimer* timer = getTimer(); + if (!timer) + { + return; + } + + // Started timer means the mouse had left the toast previously. + // If toast is hovered in the current frame we should handle + // a mouse enter event. + if(timer->getStarted() && mIsHovered) + { + mOnToastHoverSignal(this, MOUSE_ENTER); + + updateTransparency(); + + //toasts fading is management by Screen Channel + + sendChildToFront(mHideBtn); + if(mHideBtn && mHideBtn->getEnabled()) + { + mHideBtn->setVisible(TRUE); + } + mToastMouseEnterSignal(this, getValue()); + } + // Stopped timer means the mouse had entered the toast previously. + // If the toast is not hovered in the current frame we should handle + // a mouse leave event. + else if(!timer->getStarted() && !mIsHovered) + { + mOnToastHoverSignal(this, MOUSE_LEAVE); + + updateTransparency(); + + //toasts fading is management by Screen Channel + + if(mHideBtn && mHideBtn->getEnabled()) + { + if( mHideBtnPressed ) + { + mHideBtnPressed = false; + return; + } + mHideBtn->setVisible(FALSE); + } + mToastMouseLeaveSignal(this, getValue()); + } } //-------------------------------------------------------------------------- @@ -378,37 +424,11 @@ void LLToast::setVisible(BOOL show) } } -void LLToast::onToastMouseEnter() +void LLToast::updateHoveredState() { - LLRect panel_rc = mWrapperPanel->calcScreenRect(); - LLRect button_rc; - if(mHideBtn) - { - button_rc = mHideBtn->calcScreenRect(); - } - S32 x, y; LLUI::getMousePositionScreen(&x, &y); - if(panel_rc.pointInRect(x, y) || button_rc.pointInRect(x, y)) - { - mOnToastHoverSignal(this, MOUSE_ENTER); - - updateTransparency(); - - //toasts fading is management by Screen Channel - - sendChildToFront(mHideBtn); - if(mHideBtn && mHideBtn->getEnabled()) - { - mHideBtn->setVisible(TRUE); - } - mToastMouseEnterSignal(this, getValue()); - } -} - -void LLToast::onToastMouseLeave() -{ LLRect panel_rc = mWrapperPanel->calcScreenRect(); LLRect button_rc; if(mHideBtn) @@ -416,25 +436,32 @@ void LLToast::onToastMouseLeave() button_rc = mHideBtn->calcScreenRect(); } - S32 x, y; - LLUI::getMousePositionScreen(&x, &y); - - mOnToastHoverSignal(this, MOUSE_LEAVE); + if (!panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y)) + { + // mouse is not over this toast + mIsHovered = false; + return; + } - updateTransparency(); + bool is_overlapped_by_other_floater = false; - //toasts fading is management by Screen Channel + const child_list_t* child_list = gFloaterView->getChildList(); - if(mHideBtn && mHideBtn->getEnabled()) + // find this toast in gFloaterView child list to check whether any floater + // with higher Z-order is visible under the mouse pointer overlapping this toast + child_list_const_reverse_iter_t r_iter = std::find(child_list->rbegin(), child_list->rend(), this); + if (r_iter != child_list->rend()) { - if( mHideBtnPressed ) + // skip this toast and proceed to views above in Z-order + for (++r_iter; r_iter != child_list->rend(); ++r_iter) { - mHideBtnPressed = false; - return; + LLView* view = *r_iter; + is_overlapped_by_other_floater = view->isInVisibleChain() && view->calcScreenRect().pointInRect(x, y); + if (is_overlapped_by_other_floater) break; } - mHideBtn->setVisible(FALSE); } - mToastMouseLeaveSignal(this, getValue()); + + mIsHovered = !is_overlapped_by_other_floater; } void LLToast::setBackgroundOpaque(BOOL b) @@ -492,37 +519,6 @@ void LLNotificationsUI::LLToast::startTimer() } } -bool LLToast::isHovered() -{ - S32 x, y; - LLUI::getMousePositionScreen(&x, &y); - - if (!mWrapperPanel->calcScreenRect().pointInRect(x, y)) - { - // mouse is not over this toast - return false; - } - - bool is_overlapped_by_other_floater = false; - - const child_list_t* child_list = gFloaterView->getChildList(); - - // find this toast in gFloaterView child list to check whether any floater - // with higher Z-order is visible under the mouse pointer overlapping this toast - child_list_const_reverse_iter_t r_iter = std::find(child_list->rbegin(), child_list->rend(), this); - if (r_iter != child_list->rend()) - { - // skip this toast and proceed to views above in Z-order - for (++r_iter; r_iter != child_list->rend(); ++r_iter) - { - LLView* view = *r_iter; - is_overlapped_by_other_floater = view->isInVisibleChain() && view->calcScreenRect().pointInRect(x, y); - if (is_overlapped_by_other_floater) break; - } - } - return !is_overlapped_by_other_floater; -} - //-------------------------------------------------------------------------- BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask) diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 380c2c391a..77229e7beb 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -120,7 +120,7 @@ public: /** Start lifetime/fading timer */ virtual void startTimer(); - bool isHovered(); + bool isHovered() { return mIsHovered; } // Operating with toasts // insert a panel to a toast @@ -202,10 +202,7 @@ protected: void updateTransparency(); private: - - void onToastMouseEnter(); - - void onToastMouseLeave(); + void updateHoveredState(); void expire(); @@ -236,6 +233,7 @@ private: bool mIsHidden; // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849) bool mIsTip; bool mIsFading; + bool mIsHovered; commit_signal_t mToastMouseEnterSignal; commit_signal_t mToastMouseLeaveSignal; |