diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
| commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
| tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/lltoast.cpp | |
| parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) | |
Fix line endlings
Diffstat (limited to 'indra/newview/lltoast.cpp')
| -rw-r--r-- | indra/newview/lltoast.cpp | 1266 |
1 files changed, 633 insertions, 633 deletions
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index b99514e742..638a01a080 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -1,633 +1,633 @@ -/**
- * @file lltoast.cpp
- * @brief This class implements a placeholder for any notification panel.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * 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.
- *
- * 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.
- *
- * 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$
- */
-
-#include "llviewerprecompiledheaders.h" // must be first include
-
-#include "lltoast.h"
-
-#include "llbutton.h"
-#include "llfocusmgr.h"
-#include "llnotifications.h"
-#include "llviewercontrol.h"
-
-using namespace LLNotificationsUI;
-std::list<LLToast*> LLToast::sModalToastsList;
-
-//--------------------------------------------------------------------------
-LLToastLifeTimer::LLToastLifeTimer(LLToast* toast, F32 period)
- : mToast(toast),
- LLEventTimer(period)
-{
-}
-
-/*virtual*/
-bool LLToastLifeTimer::tick()
-{
- if (mEventTimer.hasExpired())
- {
- mToast->expire();
- }
- return false;
-}
-
-void LLToastLifeTimer::stop()
-{
- mEventTimer.stop();
-}
-
-void LLToastLifeTimer::start()
-{
- mEventTimer.start();
-}
-
-void LLToastLifeTimer::restart()
-{
- mEventTimer.reset();
-}
-
-bool LLToastLifeTimer::getStarted()
-{
- return mEventTimer.getStarted();
-}
-
-void LLToastLifeTimer::setPeriod(F32 period)
-{
- mPeriod = period;
-}
-
-F32 LLToastLifeTimer::getRemainingTimeF32()
-{
- F32 et = mEventTimer.getElapsedTimeF32();
- if (!getStarted() || et > mPeriod) return 0.0f;
- return mPeriod - et;
-}
-
-//--------------------------------------------------------------------------
-LLToast::Params::Params()
-: can_fade("can_fade", true),
- can_be_stored("can_be_stored", true),
- is_modal("is_modal", false),
- is_tip("is_tip", false),
- enable_hide_btn("enable_hide_btn", true),
- force_show("force_show", false),
- force_store("force_store", false),
- fading_time_secs("fading_time_secs", gSavedSettings.getS32("ToastFadingTime")),
- lifetime_secs("lifetime_secs", gSavedSettings.getS32("NotificationToastLifeTime"))
-{};
-
-LLToast::LLToast(const LLToast::Params& p)
-: LLModalDialog(LLSD(), p.is_modal),
- mToastLifetime(p.lifetime_secs),
- mToastFadingTime(p.fading_time_secs),
- mNotificationID(p.notif_id),
- mSessionID(p.session_id),
- mCanFade(p.can_fade),
- mCanBeStored(p.can_be_stored),
- mHideBtnEnabled(p.enable_hide_btn),
- mHideBtn(NULL),
- mPanel(NULL),
- mNotification(p.notification),
- mIsHidden(false),
- mHideBtnPressed(false),
- mIsTip(p.is_tip),
- mWrapperPanel(NULL),
- mIsFading(false),
- mIsHovered(false)
-{
- mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs));
-
- buildFromFile("panel_toast.xml");
-
- setCanDrag(false);
-
- mWrapperPanel = getChild<LLPanel>("wrapper_panel");
-
- setBackgroundOpaque(true); // *TODO: obsolete
- updateTransparency();
-
- if(p.panel())
- {
- insertPanel(p.panel);
- }
-
- if(mHideBtnEnabled)
- {
- mHideBtn = getChild<LLButton>("hide_btn");
- mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
- }
-
- // init callbacks if present
- if(!p.on_delete_toast().empty())
- {
- mOnDeleteToastSignal.connect(p.on_delete_toast());
- }
-
- if (isModal())
- {
- sModalToastsList.push_front(this);
- }
-}
-
-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();
- }
-
- return true;
-}
-
-//--------------------------------------------------------------------------
-void LLToast::setHideButtonEnabled(bool enabled)
-{
- if(mHideBtn)
- mHideBtn->setEnabled(enabled);
-}
-
-//--------------------------------------------------------------------------
-LLToast::~LLToast()
-{
- if(LLApp::isQuitting())
- {
- mOnFadeSignal.disconnect_all_slots();
- mOnDeleteToastSignal.disconnect_all_slots();
- mOnToastDestroyedSignal.disconnect_all_slots();
- mOnToastHoverSignal.disconnect_all_slots();
- mToastMouseEnterSignal.disconnect_all_slots();
- mToastMouseLeaveSignal.disconnect_all_slots();
- }
- else
- {
- mOnToastDestroyedSignal(this);
- }
-
- if (isModal())
- {
- std::list<LLToast*>::iterator iter = std::find(sModalToastsList.begin(), sModalToastsList.end(), this);
- if (iter != sModalToastsList.end())
- {
- sModalToastsList.erase(iter);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-void LLToast::hide()
-{
- if (!mIsHidden)
- {
- setVisible(false);
- setFading(false);
- mTimer->stop();
- mIsHidden = true;
- mOnFadeSignal(this);
- }
-}
-
-/*virtual*/
-void LLToast::setFocus(bool b)
-{
- if (b
- && !hasFocus()
- && mPanel
- && mWrapperPanel
- && !mWrapperPanel->getChildList()->empty())
- {
- LLModalDialog::setFocus(true);
- // mostly for buttons
- mPanel->setFocus(true);
- }
- else
- {
- LLModalDialog::setFocus(b);
- }
-}
-
-void LLToast::onFocusLost()
-{
- if(mWrapperPanel && !isBackgroundVisible())
- {
- // Lets make wrapper panel behave like a floater
- updateTransparency();
- }
-}
-
-void LLToast::onFocusReceived()
-{
- if(mWrapperPanel && !isBackgroundVisible())
- {
- // Lets make wrapper panel behave like a floater
- updateTransparency();
- }
-}
-
-void LLToast::setLifetime(S32 seconds)
-{
- mToastLifetime = seconds;
-}
-
-void LLToast::setFadingTime(S32 seconds)
-{
- mToastFadingTime = seconds;
-}
-
-void LLToast::closeToast()
-{
- mOnDeleteToastSignal(this);
-
- setSoundFlags(SILENT);
-
- closeFloater();
-}
-
-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)
-{
- mCanFade = can_fade;
- if(!mCanFade)
- {
- mTimer->stop();
- }
-}
-
-//--------------------------------------------------------------------------
-void LLToast::expire()
-{
- if (mCanFade)
- {
- if (mIsFading)
- {
- // Fade timer expired. Time to hide.
- hide();
- }
- else
- {
- // "Life" time has ended. Time to fade.
- setFading(true);
- mTimer->restart();
- }
- }
-}
-
-void LLToast::setFading(bool transparent)
-{
- mIsFading = transparent;
- updateTransparency();
-
- if (transparent)
- {
- mTimer->setPeriod(mToastFadingTime);
- }
- else
- {
- mTimer->setPeriod(mToastLifetime);
- }
-}
-
-F32 LLToast::getTimeLeftToLive()
-{
- F32 time_to_live = mTimer->getRemainingTimeF32();
-
- if (!mIsFading)
- {
- time_to_live += mToastFadingTime;
- }
-
- return time_to_live;
-}
-//--------------------------------------------------------------------------
-
-void LLToast::reshapeToPanel()
-{
- LLPanel* panel = getPanel();
- if(!panel)
- return;
-
- LLRect panel_rect = panel->getLocalRect();
- panel->setShape(panel_rect);
-
- LLRect toast_rect = getRect();
-
- 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)
-{
- mPanel = panel;
- mWrapperPanel->addChild(panel);
- reshapeToPanel();
-}
-
-//--------------------------------------------------------------------------
-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);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-void LLToast::setVisible(bool show)
-{
- if(mIsHidden)
- {
- // this toast is invisible after fade until its ScreenChannel will allow it
- //
- // (EXT-1849) according to this bug a toast can be resurrected from
- // invisible state if it faded during a teleportation
- // then it fades a second time and causes a crash
- return;
- }
-
- if (show && getVisible())
- {
- return;
- }
-
- if(show)
- {
- if(!mTimer->getStarted() && mCanFade)
- {
- mTimer->start();
- }
- }
- else
- {
- //hide "hide" button in case toast was hidden without mouse_leave
- if(mHideBtn)
- mHideBtn->setVisible(show);
- }
- LLFloater::setVisible(show);
- if (mPanel
- && !mPanel->isDead()
- && mWrapperPanel
- && !mWrapperPanel->getChildList()->empty()
- // LLInspectToast can take over, but LLToast still appears to act like a data storage
- && mPanel->getParent() == mWrapperPanel
- )
- {
- mPanel->setVisible(show);
- }
-}
-
-void LLToast::updateHoveredState()
-{
- S32 x, y;
- LLUI::getInstance()->getMousePositionScreen(&x, &y);
-
- LLRect panel_rc = mWrapperPanel->calcScreenRect();
- LLRect button_rc;
- if(mHideBtn)
- {
- button_rc = mHideBtn->calcScreenRect();
- }
-
- if (!panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y))
- {
- // mouse is not over this toast
- mIsHovered = false;
- }
- else
- {
- 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;
- }
- }
- }
-
- mIsHovered = !is_overlapped_by_other_floater;
- }
-
- LLToastLifeTimer* timer = getTimer();
-
- if (timer)
- {
- // 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());
- }
- }
-}
-
-void LLToast::setBackgroundOpaque(bool b)
-{
- if(mWrapperPanel && !isBackgroundVisible())
- {
- mWrapperPanel->setBackgroundOpaque(b);
- }
- else
- {
- LLModalDialog::setBackgroundOpaque(b);
- }
-}
-
-void LLToast::updateTransparency()
-{
- ETypeTransparency transparency_type;
-
- if (mCanFade)
- {
- // Notification toasts (including IM/chat toasts) change their transparency on hover.
- if (isHovered())
- {
- transparency_type = TT_ACTIVE;
- }
- else
- {
- transparency_type = mIsFading ? TT_FADING : TT_INACTIVE;
- }
- }
- else
- {
- // Transparency of alert toasts depends on focus.
- transparency_type = hasFocus() ? TT_ACTIVE : TT_INACTIVE;
- }
-
- LLFloater::updateTransparency(transparency_type);
-}
-
-void LLNotificationsUI::LLToast::stopTimer()
-{
- if(mCanFade)
- {
- setFading(false);
- mTimer->stop();
- }
-}
-
-void LLNotificationsUI::LLToast::startTimer()
-{
- if(mCanFade)
- {
- setFading(false);
- mTimer->start();
- }
-}
-
-//--------------------------------------------------------------------------
-
-bool LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- if(mHideBtn && mHideBtn->getEnabled())
- {
- mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y);
- }
-
- return LLModalDialog::handleMouseDown(x, y, mask);
-}
-
-//--------------------------------------------------------------------------
-bool LLToast::isNotificationValid()
-{
- if(mNotification)
- {
- return !mNotification->isCancelled();
- }
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-S32 LLToast::notifyParent(const LLSD& info)
-{
- if (info.has("action") && "hide_toast" == info["action"].asString())
- {
- hide();
- return 1;
- }
-
- return LLModalDialog::notifyParent(info);
-}
-
-//static
-void LLToast::updateClass()
-{
- for (auto& toast : LLInstanceTracker<LLToast>::instance_snapshot())
- {
- toast.updateHoveredState();
- }
-}
-
-// static
-void LLToast::cleanupToasts()
-{
- LLInstanceTracker<LLToast>::instance_snapshot().deleteAll();
-}
-
+/** + * @file lltoast.cpp + * @brief This class implements a placeholder for any notification panel. + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * 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. + * + * 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. + * + * 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$ + */ + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "lltoast.h" + +#include "llbutton.h" +#include "llfocusmgr.h" +#include "llnotifications.h" +#include "llviewercontrol.h" + +using namespace LLNotificationsUI; +std::list<LLToast*> LLToast::sModalToastsList; + +//-------------------------------------------------------------------------- +LLToastLifeTimer::LLToastLifeTimer(LLToast* toast, F32 period) + : mToast(toast), + LLEventTimer(period) +{ +} + +/*virtual*/ +bool LLToastLifeTimer::tick() +{ + if (mEventTimer.hasExpired()) + { + mToast->expire(); + } + return false; +} + +void LLToastLifeTimer::stop() +{ + mEventTimer.stop(); +} + +void LLToastLifeTimer::start() +{ + mEventTimer.start(); +} + +void LLToastLifeTimer::restart() +{ + mEventTimer.reset(); +} + +bool LLToastLifeTimer::getStarted() +{ + return mEventTimer.getStarted(); +} + +void LLToastLifeTimer::setPeriod(F32 period) +{ + mPeriod = period; +} + +F32 LLToastLifeTimer::getRemainingTimeF32() +{ + F32 et = mEventTimer.getElapsedTimeF32(); + if (!getStarted() || et > mPeriod) return 0.0f; + return mPeriod - et; +} + +//-------------------------------------------------------------------------- +LLToast::Params::Params() +: can_fade("can_fade", true), + can_be_stored("can_be_stored", true), + is_modal("is_modal", false), + is_tip("is_tip", false), + enable_hide_btn("enable_hide_btn", true), + force_show("force_show", false), + force_store("force_store", false), + fading_time_secs("fading_time_secs", gSavedSettings.getS32("ToastFadingTime")), + lifetime_secs("lifetime_secs", gSavedSettings.getS32("NotificationToastLifeTime")) +{}; + +LLToast::LLToast(const LLToast::Params& p) +: LLModalDialog(LLSD(), p.is_modal), + mToastLifetime(p.lifetime_secs), + mToastFadingTime(p.fading_time_secs), + mNotificationID(p.notif_id), + mSessionID(p.session_id), + mCanFade(p.can_fade), + mCanBeStored(p.can_be_stored), + mHideBtnEnabled(p.enable_hide_btn), + mHideBtn(NULL), + mPanel(NULL), + mNotification(p.notification), + mIsHidden(false), + mHideBtnPressed(false), + mIsTip(p.is_tip), + mWrapperPanel(NULL), + mIsFading(false), + mIsHovered(false) +{ + mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); + + buildFromFile("panel_toast.xml"); + + setCanDrag(false); + + mWrapperPanel = getChild<LLPanel>("wrapper_panel"); + + setBackgroundOpaque(true); // *TODO: obsolete + updateTransparency(); + + if(p.panel()) + { + insertPanel(p.panel); + } + + if(mHideBtnEnabled) + { + mHideBtn = getChild<LLButton>("hide_btn"); + mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); + } + + // init callbacks if present + if(!p.on_delete_toast().empty()) + { + mOnDeleteToastSignal.connect(p.on_delete_toast()); + } + + if (isModal()) + { + sModalToastsList.push_front(this); + } +} + +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(); + } + + return true; +} + +//-------------------------------------------------------------------------- +void LLToast::setHideButtonEnabled(bool enabled) +{ + if(mHideBtn) + mHideBtn->setEnabled(enabled); +} + +//-------------------------------------------------------------------------- +LLToast::~LLToast() +{ + if(LLApp::isQuitting()) + { + mOnFadeSignal.disconnect_all_slots(); + mOnDeleteToastSignal.disconnect_all_slots(); + mOnToastDestroyedSignal.disconnect_all_slots(); + mOnToastHoverSignal.disconnect_all_slots(); + mToastMouseEnterSignal.disconnect_all_slots(); + mToastMouseLeaveSignal.disconnect_all_slots(); + } + else + { + mOnToastDestroyedSignal(this); + } + + if (isModal()) + { + std::list<LLToast*>::iterator iter = std::find(sModalToastsList.begin(), sModalToastsList.end(), this); + if (iter != sModalToastsList.end()) + { + sModalToastsList.erase(iter); + } + } +} + +//-------------------------------------------------------------------------- +void LLToast::hide() +{ + if (!mIsHidden) + { + setVisible(false); + setFading(false); + mTimer->stop(); + mIsHidden = true; + mOnFadeSignal(this); + } +} + +/*virtual*/ +void LLToast::setFocus(bool b) +{ + if (b + && !hasFocus() + && mPanel + && mWrapperPanel + && !mWrapperPanel->getChildList()->empty()) + { + LLModalDialog::setFocus(true); + // mostly for buttons + mPanel->setFocus(true); + } + else + { + LLModalDialog::setFocus(b); + } +} + +void LLToast::onFocusLost() +{ + if(mWrapperPanel && !isBackgroundVisible()) + { + // Lets make wrapper panel behave like a floater + updateTransparency(); + } +} + +void LLToast::onFocusReceived() +{ + if(mWrapperPanel && !isBackgroundVisible()) + { + // Lets make wrapper panel behave like a floater + updateTransparency(); + } +} + +void LLToast::setLifetime(S32 seconds) +{ + mToastLifetime = seconds; +} + +void LLToast::setFadingTime(S32 seconds) +{ + mToastFadingTime = seconds; +} + +void LLToast::closeToast() +{ + mOnDeleteToastSignal(this); + + setSoundFlags(SILENT); + + closeFloater(); +} + +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) +{ + mCanFade = can_fade; + if(!mCanFade) + { + mTimer->stop(); + } +} + +//-------------------------------------------------------------------------- +void LLToast::expire() +{ + if (mCanFade) + { + if (mIsFading) + { + // Fade timer expired. Time to hide. + hide(); + } + else + { + // "Life" time has ended. Time to fade. + setFading(true); + mTimer->restart(); + } + } +} + +void LLToast::setFading(bool transparent) +{ + mIsFading = transparent; + updateTransparency(); + + if (transparent) + { + mTimer->setPeriod(mToastFadingTime); + } + else + { + mTimer->setPeriod(mToastLifetime); + } +} + +F32 LLToast::getTimeLeftToLive() +{ + F32 time_to_live = mTimer->getRemainingTimeF32(); + + if (!mIsFading) + { + time_to_live += mToastFadingTime; + } + + return time_to_live; +} +//-------------------------------------------------------------------------- + +void LLToast::reshapeToPanel() +{ + LLPanel* panel = getPanel(); + if(!panel) + return; + + LLRect panel_rect = panel->getLocalRect(); + panel->setShape(panel_rect); + + LLRect toast_rect = getRect(); + + 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) +{ + mPanel = panel; + mWrapperPanel->addChild(panel); + reshapeToPanel(); +} + +//-------------------------------------------------------------------------- +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); + } + } +} + +//-------------------------------------------------------------------------- +void LLToast::setVisible(bool show) +{ + if(mIsHidden) + { + // this toast is invisible after fade until its ScreenChannel will allow it + // + // (EXT-1849) according to this bug a toast can be resurrected from + // invisible state if it faded during a teleportation + // then it fades a second time and causes a crash + return; + } + + if (show && getVisible()) + { + return; + } + + if(show) + { + if(!mTimer->getStarted() && mCanFade) + { + mTimer->start(); + } + } + else + { + //hide "hide" button in case toast was hidden without mouse_leave + if(mHideBtn) + mHideBtn->setVisible(show); + } + LLFloater::setVisible(show); + if (mPanel + && !mPanel->isDead() + && mWrapperPanel + && !mWrapperPanel->getChildList()->empty() + // LLInspectToast can take over, but LLToast still appears to act like a data storage + && mPanel->getParent() == mWrapperPanel + ) + { + mPanel->setVisible(show); + } +} + +void LLToast::updateHoveredState() +{ + S32 x, y; + LLUI::getInstance()->getMousePositionScreen(&x, &y); + + LLRect panel_rc = mWrapperPanel->calcScreenRect(); + LLRect button_rc; + if(mHideBtn) + { + button_rc = mHideBtn->calcScreenRect(); + } + + if (!panel_rc.pointInRect(x, y) && !button_rc.pointInRect(x, y)) + { + // mouse is not over this toast + mIsHovered = false; + } + else + { + 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; + } + } + } + + mIsHovered = !is_overlapped_by_other_floater; + } + + LLToastLifeTimer* timer = getTimer(); + + if (timer) + { + // 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()); + } + } +} + +void LLToast::setBackgroundOpaque(bool b) +{ + if(mWrapperPanel && !isBackgroundVisible()) + { + mWrapperPanel->setBackgroundOpaque(b); + } + else + { + LLModalDialog::setBackgroundOpaque(b); + } +} + +void LLToast::updateTransparency() +{ + ETypeTransparency transparency_type; + + if (mCanFade) + { + // Notification toasts (including IM/chat toasts) change their transparency on hover. + if (isHovered()) + { + transparency_type = TT_ACTIVE; + } + else + { + transparency_type = mIsFading ? TT_FADING : TT_INACTIVE; + } + } + else + { + // Transparency of alert toasts depends on focus. + transparency_type = hasFocus() ? TT_ACTIVE : TT_INACTIVE; + } + + LLFloater::updateTransparency(transparency_type); +} + +void LLNotificationsUI::LLToast::stopTimer() +{ + if(mCanFade) + { + setFading(false); + mTimer->stop(); + } +} + +void LLNotificationsUI::LLToast::startTimer() +{ + if(mCanFade) + { + setFading(false); + mTimer->start(); + } +} + +//-------------------------------------------------------------------------- + +bool LLToast::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if(mHideBtn && mHideBtn->getEnabled()) + { + mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y); + } + + return LLModalDialog::handleMouseDown(x, y, mask); +} + +//-------------------------------------------------------------------------- +bool LLToast::isNotificationValid() +{ + if(mNotification) + { + return !mNotification->isCancelled(); + } + return false; +} + +//-------------------------------------------------------------------------- + +S32 LLToast::notifyParent(const LLSD& info) +{ + if (info.has("action") && "hide_toast" == info["action"].asString()) + { + hide(); + return 1; + } + + return LLModalDialog::notifyParent(info); +} + +//static +void LLToast::updateClass() +{ + for (auto& toast : LLInstanceTracker<LLToast>::instance_snapshot()) + { + toast.updateHoveredState(); + } +} + +// static +void LLToast::cleanupToasts() +{ + LLInstanceTracker<LLToast>::instance_snapshot().deleteAll(); +} + |
