diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d5eb0f0192..c4cfc52027 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -806,6 +806,18 @@ 1 + ShowGroupNoticesTopRight + + Comment + Show group notifications to the top right corner of the screen. + Persist + 1 + Type + Boolean + Value + 0 + + FirstUseFlyOverride Comment diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 4ab3d8dc98..5270b1b723 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -53,6 +53,7 @@ LLChannelManager::LLChannelManager() } } + //-------------------------------------------------------------------------- LLChannelManager::~LLChannelManager() { diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index 1a0b98f6cf..3ba0d891d7 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -51,9 +51,11 @@ public: EToastAlignment toast_align; EChannelAlignment channel_align; - Params() - : id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT) - {} + Params(): id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT) + { + if(gSavedSettings.getBOOL("ShowGroupNoticesTopRight")) + toast_align = NA_TOP; + } }; struct ChannelElem diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index aa4df0faf0..3b4ce81ac2 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -91,6 +91,7 @@ public: void addNotification (LLSD& notification); void arrangeToasts (); void showToastsBottom (); + void showToastsTop (); typedef boost::function create_toast_panel_callback_t; void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;} @@ -397,7 +398,10 @@ void LLNearbyChatScreenChannel::arrangeToasts() { if(!isHovering()) { - showToastsBottom(); + if(gSavedSettings.getBOOL("ShowGroupNoticesTopRight")) + showToastsTop(); + else + showToastsBottom(); } if (m_active_toasts.empty()) @@ -423,16 +427,23 @@ static bool sort_toasts_predicate(LLHandle first, LLHandle sec return v1 > v2; } +void LLNearbyChatScreenChannel::showToastsTop() +{ + if(mStopProcessing) + return; + +} + void LLNearbyChatScreenChannel::showToastsBottom() { if(mStopProcessing) return; LLRect toast_rect; - updateBottom(); - S32 channel_bottom = getRect().mBottom; + updateRect(); - S32 bottom = channel_bottom; + S32 channel_bottom = getRect().mBottom; + S32 bottom = channel_bottom + 10; S32 margin = gSavedSettings.getS32("ToastGap"); //sort active toasts @@ -474,7 +485,7 @@ void LLNearbyChatScreenChannel::showToastsBottom() { LLToast* toast = it->get(); if (toast) - { + { toast->setIsHidden(false); toast->setVisible(TRUE); } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 549330001d..d23360dc06 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -34,6 +34,7 @@ #include "lltoastpanel.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llrootview.h" #include "llfloaterreg.h" #include "lltrans.h" @@ -49,6 +50,22 @@ using namespace LLNotificationsUI; bool LLScreenChannel::mWasStartUpToastShown = false; +LLFastTimer::DeclareTimer FTM_GET_CHANNEL_RECT("Calculate Notification Channel Region"); +LLRect LLScreenChannelBase::getChannelRect() +{ + LLFastTimer _(FTM_GET_CHANNEL_RECT); + LLRect channel_rect; + LLRect chiclet_rect; + LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + floater_snap_region->localRectToScreen(floater_snap_region->getLocalRect(), &channel_rect); + + LLView* chiclet_region = gViewerWindow->getRootView()->getChildView("chiclet_container"); + chiclet_region->localRectToScreen(chiclet_region->getLocalRect(), &chiclet_rect); + + channel_rect.mTop = chiclet_rect.mBottom; + return channel_rect; +} + //-------------------------------------------------------------------------- ////////////////////// // LLScreenChannelBase @@ -62,6 +79,9 @@ LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) : ,mControlHovering(false) ,mShowToasts(true) { + if(gSavedSettings.getBOOL("ShowGroupNoticesTopRight")) + mToastAlignment = NA_TOP; + mID = id; mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2)); @@ -72,6 +92,11 @@ LLScreenChannelBase::~LLScreenChannelBase() { mWorldViewRectConnection.disconnect(); } + +void LLScreenChannelBase::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + redrawToasts(); +} bool LLScreenChannelBase::isHovering() { @@ -132,13 +157,13 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right) side_bar->setVisibleWidthChangeCallback(boost::bind(&LLScreenChannelBase::resetPositionAndSize, this)); } - // top and bottom set by updateBottom() + // top and bottom set by updateRect() setRect(LLRect(channel_left, 0, channel_right, 0)); - updateBottom(); + updateRect(); setVisible(TRUE); } -void LLScreenChannelBase::updateBottom() +void LLScreenChannelBase::updateRect() { S32 channel_top = gViewerWindow->getWorldViewRectScaled().getHeight(); S32 channel_bottom = gSavedSettings.getS32("ChannelBottomPanelMargin"); @@ -514,7 +539,7 @@ void LLScreenChannel::showToastsBottom() S32 toast_margin = 0; std::vector::reverse_iterator it; - updateBottom(); + updateRect(); LLDockableFloater* floater = dynamic_cast(LLDockableFloater::getInstanceHandle().get()); @@ -619,6 +644,98 @@ void LLScreenChannel::showToastsCentre() //-------------------------------------------------------------------------- void LLScreenChannel::showToastsTop() { + LLRect channel_rect = getChannelRect(); + + LLRect toast_rect; + S32 top = getRect().mTop + mToastList[0].toast->getRect().getHeight()/2; // - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2; + S32 bottom = (getRect().mTop - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2; + S32 toast_margin = 0; + std::vector::reverse_iterator it; + + updateRect(); + + LLDockableFloater* floater = dynamic_cast(LLDockableFloater::getInstanceHandle().get()); + + for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + { + if(it != mToastList.rbegin()) + { + LLToast* toast = (*(it-1)).toast; + bottom = toast->getRect().mTop - toast->getTopPad(); + toast_margin = gSavedSettings.getS32("ToastGap"); + } + + toast_rect = (*it).toast->getRect(); + + toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, + top - gSavedSettings.getS32("ToastGap"), + toast_rect.getWidth(), + toast_rect.getHeight()); + (*it).toast->setRect(toast_rect); + + if(floater && floater->overlapsScreenChannel()) + { + if(it == mToastList.rbegin()) + { + // move first toast below docked floater + S32 shift = floater->getRect().getHeight(); + if(floater->getDockControl()) + { + shift += floater->getDockControl()->getTongueHeight(); + } + (*it).toast->translate(0, -shift); + } + + // don't show toasts if there is not enough space + if(toast_rect.mBottom < channel_rect.mBottom) + { + break; + } + } + + bool stop_showing_toasts = (*it).toast->getRect().mBottom < channel_rect.mBottom; + + if(!stop_showing_toasts) + { + if( it != mToastList.rend()-1) + { + S32 toast_bottom = (*it).toast->getRect().mBottom - gSavedSettings.getS32("ToastGap"); + stop_showing_toasts = toast_bottom < channel_rect.mBottom; + } + } + + // at least one toast should be visible + if(it == mToastList.rbegin()) + { + stop_showing_toasts = false; + } + + if(stop_showing_toasts) + break; + + if( !(*it).toast->getVisible() ) + { + // HACK + // EXT-2653: it is necessary to prevent overlapping for secondary showed toasts + (*it).toast->setVisible(TRUE); + } + if(!(*it).toast->hasFocus()) + { + // Fixing Z-order of toasts (EXT-4862) + // Next toast will be positioned under this one. + gFloaterView->sendChildToBack((*it).toast); + } + } + + // Dismiss toasts we don't have space for (STORM-391). + if(it != mToastList.rend()) + { + mHiddenToastsNum = 0; + for(; it != mToastList.rend(); it++) + { + (*it).toast->hide(); + } + } } //-------------------------------------------------------------------------- @@ -848,7 +965,7 @@ void LLScreenChannel::updateShowToastsState() return; } - updateBottom(); + updateRect(); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index d207d13981..a78d18a83c 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -56,6 +56,8 @@ public: LLScreenChannelBase(const LLUUID& id); ~LLScreenChannelBase(); + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + // Channel's outfit-functions // update channel's size and position in the World View virtual void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect); @@ -108,7 +110,8 @@ public: LLUUID getChannelID() { return mID; } protected: - void updateBottom(); + void updateRect(); + LLRect getChannelRect(); // Channel's flags bool mControlHovering; diff --git a/indra/newview/llsidetraytab.h b/indra/newview/llsidetraytab.h index 31652bc23f..0a92f75946 100644 --- a/indra/newview/llsidetraytab.h +++ b/indra/newview/llsidetraytab.h @@ -27,8 +27,10 @@ #include "llpanel.h" #include "llbadge.h" + #include "llfloater.h" + class LLSideTray; class LLSideTrayButton; diff --git a/indra/newview/skins/default/xui/en/panel_preferences_UI.xml b/indra/newview/skins/default/xui/en/panel_preferences_UI.xml index e17b664570..b90db112c4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_UI.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_UI.xml @@ -145,6 +145,18 @@ width="256" /> + + + +