diff options
Diffstat (limited to 'indra/newview/lltoast.cpp')
-rw-r--r-- | indra/newview/lltoast.cpp | 292 |
1 files changed, 188 insertions, 104 deletions
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 110d158e2d..749cf2c948 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -2,31 +2,25 @@ * @file lltoast.cpp * @brief This class implements a placeholder for any notification panel. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,6 +35,16 @@ using namespace LLNotificationsUI; +/*virtual*/ +BOOL LLToastLifeTimer::tick() +{ + if (mEventTimer.hasExpired()) + { + mToast->expire(); + } + return FALSE; +} + //-------------------------------------------------------------------------- LLToast::Params::Params() : can_fade("can_fade", true), @@ -68,12 +72,19 @@ LLToast::LLToast(const LLToast::Params& p) mNotification(p.notification), mIsHidden(false), mHideBtnPressed(false), - mIsTip(p.is_tip) + mIsTip(p.is_tip), + mWrapperPanel(NULL) { + mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); + 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 +94,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 @@ -93,38 +106,26 @@ LLToast::LLToast(const LLToast::Params& p) mOnMouseEnterSignal.connect(p.on_mouse_enter()); } +void LLToast::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // We shouldn't use reshape from LLModalDialog since it changes toasts position. + // Toasts position should be controlled only by toast screen channel, see LLScreenChannelBase. + // see EXT-8044 + LLFloater::reshape(width, height, called_from_parent); +} + //-------------------------------------------------------------------------- BOOL LLToast::postBuild() { if(!mCanFade) { - mTimer.stop(); - } - - if (mIsTip) - { - mTextEditor = mPanel->getChild<LLTextEditor>("text_editor_box"); - - if (mTextEditor) - { - mTextEditor->setMouseUpCallback(boost::bind(&LLToast::hide,this)); - mPanel->setMouseUpCallback(boost::bind(&LLToast::handleTipToastClick, this, _2, _3, _4)); - } + mTimer->stop(); } return TRUE; } //-------------------------------------------------------------------------- -void LLToast::handleTipToastClick(S32 x, S32 y, MASK mask) -{ - if (!mTextEditor->getRect().pointInRect(x, y)) - { - hide(); - } -} - -//-------------------------------------------------------------------------- void LLToast::setHideButtonEnabled(bool enabled) { if(mHideBtn) @@ -138,40 +139,48 @@ LLToast::~LLToast() } //-------------------------------------------------------------------------- -void LLToast::setAndStartTimer(F32 period) +void LLToast::hide() { - if(mCanFade) + setVisible(FALSE); + mTimer->stop(); + mIsHidden = true; + mOnFadeSignal(this); +} + +void LLToast::onFocusLost() +{ + if(mWrapperPanel && !isBackgroundVisible()) { - mToastLifetime = period; - mTimer.start(); + // Lets make wrapper panel behave like a floater + setBackgroundOpaque(FALSE); } } -//-------------------------------------------------------------------------- -bool LLToast::lifetimeHasExpired() +void LLToast::onFocusReceived() { - if (mTimer.getStarted()) + if(mWrapperPanel && !isBackgroundVisible()) { - F32 elapsed_time = mTimer.getElapsedTimeF32(); - if ((mToastLifetime - elapsed_time) <= mToastFadingTime) - { - setBackgroundOpaque(FALSE); - } - if (elapsed_time > mToastLifetime) - { - return true; - } + // Lets make wrapper panel behave like a floater + setBackgroundOpaque(TRUE); } - return false; } -//-------------------------------------------------------------------------- -void LLToast::hide() +S32 LLToast::getTopPad() { - setVisible(FALSE); - mTimer.stop(); - mIsHidden = true; - mOnFadeSignal(this); + if(mWrapperPanel) + { + return getRect().getHeight() - mWrapperPanel->getRect().getHeight(); + } + return 0; +} + +S32 LLToast::getRightPad() +{ + if(mWrapperPanel) + { + return getRect().getWidth() - mWrapperPanel->getRect().getWidth(); + } + return 0; } //-------------------------------------------------------------------------- @@ -179,12 +188,13 @@ void LLToast::setCanFade(bool can_fade) { mCanFade = can_fade; if(!mCanFade) - mTimer.stop(); + mTimer->stop(); } //-------------------------------------------------------------------------- -void LLToast::tick() +void LLToast::expire() { + // if toast has fade property - hide it if(mCanFade) { hide(); @@ -199,34 +209,48 @@ 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(); } //-------------------------------------------------------------------------- void LLToast::draw() { - if(lifetimeHasExpired()) + LLFloater::draw(); + + if(!isBackgroundVisible()) { - tick(); + // 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); + } } - LLFloater::draw(); + // if timer started and remaining time <= fading time + if (mTimer->getStarted() && (mToastLifetime + - mTimer->getEventTimer().getElapsedTimeF32()) <= mToastFadingTime) + { + setBackgroundOpaque(FALSE); + } } //-------------------------------------------------------------------------- @@ -245,11 +269,20 @@ void LLToast::setVisible(BOOL show) if(show) { setBackgroundOpaque(TRUE); - if(!mTimer.getStarted() && mCanFade) + if(!mTimer->getStarted() && mCanFade) { - mTimer.start(); + mTimer->start(); } - LLModalDialog::setFrontmost(FALSE); + if (!getVisible()) + { + LLModalDialog::setFrontmost(FALSE); + } + } + else + { + //hide "hide" button in case toast was hidden without mouse_leave + if(mHideBtn) + mHideBtn->setVisible(show); } LLFloater::setVisible(show); if(mPanel) @@ -261,43 +294,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); - LLModalDialog::onMouseEnter(x, y, mask); + //toasts fading is management by Screen Channel + + 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 +383,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) @@ -339,4 +414,13 @@ bool LLToast::isNotificationValid() //-------------------------------------------------------------------------- +S32 LLToast::notifyParent(const LLSD& info) +{ + if (info.has("action") && "hide_toast" == info["action"].asString()) + { + hide(); + return 1; + } + return LLModalDialog::notifyParent(info); +} |