summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDmitry Zaporozhan <dzaporozhan@productengine.com>2010-02-17 16:00:28 +0200
committerDmitry Zaporozhan <dzaporozhan@productengine.com>2010-02-17 16:00:28 +0200
commit4b161b8839fa115947d8d580c575d9b91c88fbc9 (patch)
treebd9effdf3a08492c06315d30a6719af976564651 /indra/newview
parent619415a99a08f66b8247ccd0b427c8483ba22e82 (diff)
Fixed low bug EXT-4246 - Close button on notification toast is larger than host spot.
Close button is partially positioned out of toast(floater). Usually, hovering or clicking that "outer" part of the button can not be handled. The workaround is to position the button on the floater and make the floater background invisible. Now close button is properly handled, but toast is transparent. To fix this i added wrapper_panel that looks and behaves like a floater. --HG-- branch : product-engine
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llnearbychathandler.cpp2
-rw-r--r--indra/newview/llscreenchannel.cpp25
-rw-r--r--indra/newview/lltoast.cpp159
-rw-r--r--indra/newview/lltoast.h26
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml34
5 files changed, 189 insertions, 57 deletions
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 29e3c66684..3c390c0281 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -282,7 +282,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()
gFloaterView->sendChildToBack(toast);
}
- bottom = toast->getRect().mTop;
+ bottom = toast->getRect().mTop - toast->getTopPad();
}
}
}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 7c2e7e3319..c75d90be6f 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -79,17 +79,12 @@ LLScreenChannelBase::~LLScreenChannelBase()
bool LLScreenChannelBase::isHovering()
{
- bool res = mHoveredToast != NULL;
- if (!res)
+ if (!mHoveredToast)
{
- return res;
+ return false;
}
- S32 x, y;
- mHoveredToast->screenPointToLocal(gViewerWindow->getCurrentMouseX(),
- gViewerWindow->getCurrentMouseY(), &x, &y);
- res = mHoveredToast->pointInView(x, y) == TRUE;
- return res;
+ return mHoveredToast->isHovered();
}
void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
@@ -479,7 +474,8 @@ void LLScreenChannel::showToastsBottom()
{
if(it != mToastList.rbegin())
{
- bottom = (*(it-1)).toast->getRect().mTop;
+ LLToast* toast = (*(it-1)).toast;
+ bottom = toast->getRect().mTop - toast->getTopPad();
toast_margin = gSavedSettings.getS32("ToastGap");
}
@@ -777,23 +773,16 @@ void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter)
{
// because of LLViewerWindow::updateUI() that NOT ALWAYS calls onMouseEnter BEFORE onMouseLeave
// we must check hovering directly to prevent incorrect setting for hovering in a channel
- S32 x,y;
if (mouse_enter)
{
- toast->screenPointToLocal(gViewerWindow->getCurrentMouseX(),
- gViewerWindow->getCurrentMouseY(), &x, &y);
- bool hover = toast->pointInView(x, y) == TRUE;
- if (hover)
+ if (toast->isHovered())
{
mHoveredToast = toast;
}
}
else if (mHoveredToast != NULL)
{
- mHoveredToast->screenPointToLocal(gViewerWindow->getCurrentMouseX(),
- gViewerWindow->getCurrentMouseY(), &x, &y);
- bool hover = mHoveredToast->pointInView(x, y) == TRUE;
- if (!hover)
+ if (!mHoveredToast->isHovered())
{
mHoveredToast = NULL;
}
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 110d158e2d..60a89c02e4 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -68,12 +68,17 @@ LLToast::LLToast(const LLToast::Params& p)
mNotification(p.notification),
mIsHidden(false),
mHideBtnPressed(false),
- mIsTip(p.is_tip)
+ mIsTip(p.is_tip),
+ mWrapperPanel(NULL)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL);
setCanDrag(FALSE);
+ mWrapperPanel = getChild<LLPanel>("wrapper_panel");
+ mWrapperPanel->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this));
+ mWrapperPanel->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this));
+
if(mPanel)
{
insertPanel(mPanel);
@@ -83,6 +88,8 @@ 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
@@ -174,6 +181,42 @@ void LLToast::hide()
mOnFadeSignal(this);
}
+void LLToast::onFocusLost()
+{
+ if(mWrapperPanel && !isBackgroundVisible())
+ {
+ // Lets make wrapper panel behave like a floater
+ setBackgroundOpaque(FALSE);
+ }
+}
+
+void LLToast::onFocusReceived()
+{
+ if(mWrapperPanel && !isBackgroundVisible())
+ {
+ // Lets make wrapper panel behave like a floater
+ setBackgroundOpaque(TRUE);
+ }
+}
+
+S32 LLToast::getTopPad()
+{
+ if(mWrapperPanel)
+ {
+ return getRect().getHeight() - mWrapperPanel->getRect().getHeight();
+ }
+ return 0;
+}
+
+S32 LLToast::getRightPad()
+{
+ if(mWrapperPanel)
+ {
+ return getRect().getWidth() - mWrapperPanel->getRect().getWidth();
+ }
+ return 0;
+}
+
//--------------------------------------------------------------------------
void LLToast::setCanFade(bool can_fade)
{
@@ -199,22 +242,21 @@ void LLToast::reshapeToPanel()
if(!panel)
return;
- LLRect panel_rect;
+ LLRect panel_rect = panel->getRect();
- panel_rect = panel->getRect();
- reshape(panel_rect.getWidth(), panel_rect.getHeight());
panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
- panel->setRect(panel_rect);
+ panel->setShape(panel_rect);
LLRect toast_rect = getRect();
- toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
- setRect(toast_rect);
+ toast_rect.setLeftTopAndSize(toast_rect.mLeft, toast_rect.mTop,
+ panel_rect.getWidth() + getRightPad(), panel_rect.getHeight() + getTopPad());
+ setShape(toast_rect);
}
void LLToast::insertPanel(LLPanel* panel)
{
- addChild(panel);
+ mWrapperPanel->addChild(panel);
reshapeToPanel();
}
@@ -227,6 +269,19 @@ void LLToast::draw()
}
LLFloater::draw();
+
+ if(!isBackgroundVisible())
+ {
+ // Floater background is invisible, lets make wrapper panel look like a
+ // floater - draw shadow.
+ drawShadow(mWrapperPanel);
+
+ // Shadow will probably overlap close button, lets redraw the button
+ if(mHideBtn)
+ {
+ drawChild(mHideBtn);
+ }
+ }
}
//--------------------------------------------------------------------------
@@ -261,43 +316,78 @@ void LLToast::setVisible(BOOL show)
}
}
-//--------------------------------------------------------------------------
-void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
+void LLToast::onToastMouseEnter()
{
- mOnToastHoverSignal(this, MOUSE_ENTER);
+ LLRect panel_rc = mWrapperPanel->calcScreenRect();
+ LLRect button_rc;
+ if(mHideBtn)
+ {
+ button_rc = mHideBtn->calcScreenRect();
+ }
- setBackgroundOpaque(TRUE);
+ S32 x, y;
+ LLUI::getMousePositionScreen(&x, &y);
- //toasts fading is management by Screen Channel
-
- sendChildToFront(mHideBtn);
- if(mHideBtn && mHideBtn->getEnabled())
- mHideBtn->setVisible(TRUE);
- mOnMouseEnterSignal(this);
+ if(panel_rc.pointInRect(x, y) || button_rc.pointInRect(x, y))
+ {
+ mOnToastHoverSignal(this, MOUSE_ENTER);
+
+ setBackgroundOpaque(TRUE);
+
+ //toasts fading is management by Screen Channel
- LLModalDialog::onMouseEnter(x, y, mask);
+ sendChildToFront(mHideBtn);
+ if(mHideBtn && mHideBtn->getEnabled())
+ {
+ mHideBtn->setVisible(TRUE);
+ }
+ mOnMouseEnterSignal(this);
+ mToastMouseEnterSignal(this, getValue());
+ }
}
-//--------------------------------------------------------------------------
-void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mOnToastHoverSignal(this, MOUSE_LEAVE);
+void LLToast::onToastMouseLeave()
+{
+ LLRect panel_rc = mWrapperPanel->calcScreenRect();
+ LLRect button_rc;
+ if(mHideBtn)
+ {
+ button_rc = mHideBtn->calcScreenRect();
+ }
- //toasts fading is management by Screen Channel
+ S32 x, y;
+ LLUI::getMousePositionScreen(&x, &y);
- if(mHideBtn && mHideBtn->getEnabled())
+ if( !panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y))
{
- if( mHideBtnPressed )
+ mOnToastHoverSignal(this, MOUSE_LEAVE);
+
+ //toasts fading is management by Screen Channel
+
+ if(mHideBtn && mHideBtn->getEnabled())
{
- mHideBtnPressed = false;
- return;
+ if( mHideBtnPressed )
+ {
+ mHideBtnPressed = false;
+ return;
+ }
+ mHideBtn->setVisible(FALSE);
}
- mHideBtn->setVisible(FALSE);
+ mToastMouseLeaveSignal(this, getValue());
}
-
- LLModalDialog::onMouseLeave(x, y, mask);
}
+void LLToast::setBackgroundOpaque(BOOL b)
+{
+ if(mWrapperPanel && !isBackgroundVisible())
+ {
+ mWrapperPanel->setBackgroundOpaque(b);
+ }
+ else
+ {
+ LLModalDialog::setBackgroundOpaque(b);
+ }
+}
void LLNotificationsUI::LLToast::stopFading()
{
@@ -315,6 +405,13 @@ void LLNotificationsUI::LLToast::startFading()
}
}
+bool LLToast::isHovered()
+{
+ S32 x, y;
+ LLUI::getMousePositionScreen(&x, &y);
+ return mWrapperPanel->calcScreenRect().pointInRect(x, y);
+}
+
//--------------------------------------------------------------------------
BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 3d25fd4f02..64855020a9 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -86,8 +86,6 @@ public:
// Toast handlers
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual void onMouseEnter(S32 x, S32 y, MASK mask);
- virtual void onMouseLeave(S32 x, S32 y, MASK mask);
//Fading
@@ -97,6 +95,7 @@ public:
/** Start fading timer */
virtual void startFading();
+ bool isHovered();
// Operating with toasts
// insert a panel to a toast
@@ -118,10 +117,22 @@ public:
virtual void draw();
//
virtual void setVisible(BOOL show);
+
+ /*virtual*/ void setBackgroundOpaque(BOOL b);
//
virtual void hide();
+ /*virtual*/ void onFocusLost();
+
+ /*virtual*/ void onFocusReceived();
+ /**
+ * Returns padding between floater top and wrapper_panel top.
+ * This padding should be taken into account when positioning or reshaping toasts
+ */
+ S32 getTopPad();
+
+ S32 getRightPad();
// get/set Toast's flags or states
// get information whether the notification corresponding to the toast is valid or not
@@ -154,9 +165,15 @@ public:
toast_hover_check_signal_t mOnToastHoverSignal;
boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHoverSignal.connect(cb); }
+ boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mToastMouseEnterSignal.connect(cb); };
+ boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mToastMouseLeaveSignal.connect(cb); };
private:
+ void onToastMouseEnter();
+
+ void onToastMouseLeave();
+
void handleTipToastClick(S32 x, S32 y, MASK mask);
// check timer
@@ -168,6 +185,8 @@ private:
LLUUID mSessionID;
LLNotificationPtr mNotification;
+ LLPanel* mWrapperPanel;
+
// timer counts a lifetime of a toast
LLTimer mTimer;
F32 mToastLifetime; // in seconds
@@ -184,6 +203,9 @@ private:
bool mHideBtnPressed;
bool mIsHidden; // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849)
bool mIsTip;
+
+ commit_signal_t mToastMouseEnterSignal;
+ commit_signal_t mToastMouseLeaveSignal;
};
}
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index bfe3cce7d0..11069b3ac3 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -3,17 +3,25 @@
<!-- Don't remove floater's height! It is needed for Overflow and Start-Up toasts!-->
+<!--
+ This floater is invisible. To make toast look like a floater we render wrapper_panel
+ like a floater(draw shadows and so on). This is done with one purpose - make close button
+ look like it is positioned out of floater and able to accept mouse clicks (see EXT-4246)
+-->
+
<floater
- legacy_header_height="18"
+ legacy_header_height="0"
+ header_height="0"
name="toast"
title=""
visible="false"
layout="topleft"
- height="40"
- width="305"
+ height="47"
+ width="310"
left="0"
top="0"
follows="right|bottom"
+ background_visible="false"
bg_opaque_image="Toast_Over"
bg_alpha_image="Toast_Background"
can_minimize="false"
@@ -27,6 +35,21 @@
drop_shadow_visible = "false"
border = "false"
>
+ <panel
+ background_opaque="false"
+ border_visible="false"
+ background_visible="true"
+ bg_opaque_image="Toast_Over"
+ bg_alpha_image="Toast_Background"
+ label="wrapper_panel"
+ layout="topleft"
+ left="0"
+ name="wrapper_panel"
+ top="7"
+ height="40"
+ follows="all"
+ translate="false"
+ width="305">
<!-- Don't remove this wiget! It is needed for Overflow and Start-Up toasts!-->
<text
clip_partial="true"
@@ -46,10 +69,11 @@
width="260">
Toast text;
</text>
+ </panel>
<button
layout="topleft"
- top="-14"
- left="293"
+ top="0"
+ right="310"
width="17"
height="17"
follows="top|right"