Skip to content
Snippets Groups Projects
Commit 71974461 authored by Seth ProductEngine's avatar Seth ProductEngine
Browse files

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
parent ef0552a0
No related branches found
No related tags found
No related merge requests found
...@@ -113,7 +113,8 @@ LLToast::LLToast(const LLToast::Params& p) ...@@ -113,7 +113,8 @@ LLToast::LLToast(const LLToast::Params& p)
mHideBtnPressed(false), mHideBtnPressed(false),
mIsTip(p.is_tip), mIsTip(p.is_tip),
mWrapperPanel(NULL), mWrapperPanel(NULL),
mIsFading(false) mIsFading(false),
mIsHovered(false)
{ {
mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs));
...@@ -122,8 +123,6 @@ LLToast::LLToast(const LLToast::Params& p) ...@@ -122,8 +123,6 @@ LLToast::LLToast(const LLToast::Params& p)
setCanDrag(FALSE); setCanDrag(FALSE);
mWrapperPanel = getChild<LLPanel>("wrapper_panel"); mWrapperPanel = getChild<LLPanel>("wrapper_panel");
mWrapperPanel->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this));
mWrapperPanel->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this));
setBackgroundOpaque(TRUE); // *TODO: obsolete setBackgroundOpaque(TRUE); // *TODO: obsolete
updateTransparency(); updateTransparency();
...@@ -137,8 +136,6 @@ LLToast::LLToast(const LLToast::Params& p) ...@@ -137,8 +136,6 @@ LLToast::LLToast(const LLToast::Params& p)
{ {
mHideBtn = getChild<LLButton>("hide_btn"); mHideBtn = getChild<LLButton>("hide_btn");
mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); 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 // init callbacks if present
...@@ -331,6 +328,55 @@ void LLToast::draw() ...@@ -331,6 +328,55 @@ void LLToast::draw()
drawChild(mHideBtn); 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) ...@@ -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; S32 x, y;
LLUI::getMousePositionScreen(&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 panel_rc = mWrapperPanel->calcScreenRect();
LLRect button_rc; LLRect button_rc;
if(mHideBtn) if(mHideBtn)
...@@ -416,25 +436,32 @@ void LLToast::onToastMouseLeave() ...@@ -416,25 +436,32 @@ void LLToast::onToastMouseLeave()
button_rc = mHideBtn->calcScreenRect(); button_rc = mHideBtn->calcScreenRect();
} }
S32 x, y; if (!panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y))
LLUI::getMousePositionScreen(&x, &y); {
// mouse is not over this toast
mOnToastHoverSignal(this, MOUSE_LEAVE); 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; LLView* view = *r_iter;
return; 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) void LLToast::setBackgroundOpaque(BOOL b)
...@@ -492,37 +519,6 @@ void LLNotificationsUI::LLToast::startTimer() ...@@ -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) BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
......
...@@ -120,7 +120,7 @@ class LLToast : public LLModalDialog ...@@ -120,7 +120,7 @@ class LLToast : public LLModalDialog
/** Start lifetime/fading timer */ /** Start lifetime/fading timer */
virtual void startTimer(); virtual void startTimer();
bool isHovered(); bool isHovered() { return mIsHovered; }
// Operating with toasts // Operating with toasts
// insert a panel to a toast // insert a panel to a toast
...@@ -202,10 +202,7 @@ class LLToast : public LLModalDialog ...@@ -202,10 +202,7 @@ class LLToast : public LLModalDialog
void updateTransparency(); void updateTransparency();
private: private:
void updateHoveredState();
void onToastMouseEnter();
void onToastMouseLeave();
void expire(); void expire();
...@@ -236,6 +233,7 @@ class LLToast : public LLModalDialog ...@@ -236,6 +233,7 @@ class LLToast : public LLModalDialog
bool mIsHidden; // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849) bool mIsHidden; // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849)
bool mIsTip; bool mIsTip;
bool mIsFading; bool mIsFading;
bool mIsHovered;
commit_signal_t mToastMouseEnterSignal; commit_signal_t mToastMouseEnterSignal;
commit_signal_t mToastMouseLeaveSignal; commit_signal_t mToastMouseLeaveSignal;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment