EXP-1319 FIX Nearby chat toasts should not underlap toolbars

meow-7.2.2
Richard Linden 2011-10-13 19:16:54 -07:00
parent 064b1918b3
commit d3ef628952
6 changed files with 101 additions and 114 deletions

View File

@ -68,7 +68,7 @@ LLChannelManager::~LLChannelManager()
LLScreenChannel* LLChannelManager::createNotificationChannel()
{
// creating params for a channel
LLChannelManager::Params p;
LLScreenChannelBase::Params p;
p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
p.channel_align = CA_RIGHT;
@ -106,7 +106,7 @@ void LLChannelManager::onLoginCompleted()
else
{
// create a channel for the StartUp Toast
LLChannelManager::Params p;
LLScreenChannelBase::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
mStartUpChannel = createChannel(p);
@ -164,26 +164,15 @@ LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
return channel;
}
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
LLScreenChannel* LLChannelManager::createChannel(LLScreenChannelBase::Params& p)
{
LLScreenChannel* new_channel = new LLScreenChannel(p.id);
LLScreenChannel* new_channel = new LLScreenChannel(p);
if(!new_channel)
{
llerrs << "LLChannelManager::getChannel(LLChannelManager::Params& p) - can't create a channel!" << llendl;
}
else
{
new_channel->setToastAlignment(p.toast_align);
new_channel->setChannelAlignment(p.channel_align);
new_channel->setDisplayToastsAlways(p.display_toasts_always);
addChannel(new_channel);
}
addChannel(new_channel);
return new_channel;
}
LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
LLScreenChannelBase* LLChannelManager::getChannel(LLScreenChannelBase::Params& p)
{
LLScreenChannelBase* new_channel = findChannelByID(p.id);
@ -195,7 +184,7 @@ LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
}
//--------------------------------------------------------------------------
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID& id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())
@ -207,7 +196,7 @@ LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
}
//--------------------------------------------------------------------------
void LLChannelManager::removeChannelByID(const LLUUID id)
void LLChannelManager::removeChannelByID(const LLUUID& id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())

View File

@ -44,17 +44,7 @@ namespace LLNotificationsUI
class LLChannelManager : public LLSingleton<LLChannelManager>
{
public:
struct Params
{
LLUUID id;
bool display_toasts_always;
EToastAlignment toast_align;
EChannelAlignment channel_align;
Params()
: id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
{}
};
struct ChannelElem
{
@ -84,18 +74,18 @@ public:
void onStartUpToastClose();
// creates a new ScreenChannel according to the given parameters or returns existing if present
LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
LLScreenChannelBase* getChannel(LLScreenChannelBase::Params& p);
LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
// returns a channel by its ID
LLScreenChannelBase* findChannelByID(const LLUUID id);
LLScreenChannelBase* findChannelByID(const LLUUID& id);
// creator of the Notification channel, that is used in more than one handler
LLScreenChannel* createNotificationChannel();
// remove channel methods
void removeChannelByID(const LLUUID id);
void removeChannelByID(const LLUUID& id);
/**
* Manages toasts showing for all channels.
@ -117,7 +107,7 @@ public:
std::vector<ChannelElem>& getChannelList() { return mChannelList;}
private:
LLScreenChannel* createChannel(LLChannelManager::Params& p);
LLScreenChannel* createChannel(LLScreenChannelBase::Params& p);
LLScreenChannel* mStartUpChannel;
std::vector<ChannelElem> mChannelList;

View File

@ -42,6 +42,8 @@
#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
#include "llviewerwindow.h"//for screen channel position
#include "llnearbychatbar.h"
#include "llrootview.h"
#include "lllayoutstack.h"
//add LLNearbyChatHandler to LLNotificationsUI namespace
using namespace LLNotificationsUI;
@ -62,7 +64,7 @@ public:
typedef std::vector<LLHandle<LLToast> > toast_vec_t;
typedef std::list<LLHandle<LLToast> > toast_list_t;
LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id)
LLNearbyChatScreenChannel(const Params& p):LLScreenChannelBase(p)
{
mStopProcessing = false;
@ -81,7 +83,6 @@ public:
void addNotification (LLSD& notification);
void arrangeToasts ();
void showToastsBottom ();
typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
@ -150,6 +151,7 @@ protected:
toast_list_t m_toast_pool;
bool mStopProcessing;
bool mChannelRect;
};
//-----------------------------------------------------------------------------------------------
@ -352,27 +354,6 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
arrangeToasts();
}
void LLNearbyChatScreenChannel::arrangeToasts()
{
if(!isHovering())
{
showToastsBottom();
}
if (m_active_toasts.empty())
{
LLHints::registerHintTarget("incoming_chat", LLHandle<LLView>());
}
else
{
LLToast* toast = m_active_toasts.front().get();
if (toast)
{
LLHints::registerHintTarget("incoming_chat", m_active_toasts.front().get()->LLView::getHandle());
}
}
}
static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second)
{
if (!first.get() || !second.get()) return false; // STORM-1352
@ -382,14 +363,30 @@ static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> sec
return v1 > v2;
}
void LLNearbyChatScreenChannel::showToastsBottom()
void LLNearbyChatScreenChannel::arrangeToasts()
{
if(mStopProcessing)
if(mStopProcessing || isHovering())
return;
LLLayoutStack::updateClass();
LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region");
if (!getParent())
{
// connect to floater snap region to get resize events
floater_snap_region->addChild(this);
setFollows(FOLLOWS_ALL);
}
LLRect toast_rect;
updateBottom();
S32 channel_bottom = getRect().mBottom;
LLRect channel_rect;
floater_snap_region->localRectToOtherView(floater_snap_region->getLocalRect(), &channel_rect, gFloaterView);
channel_rect.mRight = channel_rect.mLeft + 300;
S32 channel_bottom = channel_rect.mBottom;
S32 bottom = channel_bottom;
S32 margin = gSavedSettings.getS32("ToastGap");
@ -410,7 +407,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()
S32 toast_top = bottom + toast->getRect().getHeight() + margin;
if(toast_top > gFloaterView->getRect().getHeight())
if(toast_top > channel_rect.getHeight())
{
while(it!=m_active_toasts.end())
{
@ -421,7 +418,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()
}
toast_rect = toast->getRect();
toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
toast_rect.setLeftTopAndSize(channel_rect.mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
toast->setRect(toast_rect);
bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
@ -458,7 +455,9 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i
mType = type;
// Getting a Channel for our notifications
LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
LLNearbyChatScreenChannel::Params p;
p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(p);
LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
@ -474,11 +473,8 @@ LLNearbyChatHandler::~LLNearbyChatHandler()
void LLNearbyChatHandler::initChannel()
{
LLNearbyChatBar* chat_bar = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar", LLSD());
LLView* chat_box = chat_bar->getChatBox();
LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
S32 channel_right_bound = nearby_chat->getRect().mRight;
mChannel->init(chat_box->getRect().mLeft, channel_right_bound);
//LLRect snap_rect = gFloaterView->getSnapRect();
//mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
}

View File

@ -44,7 +44,7 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo
{
mType = type;
LLChannelManager::Params p;
LLScreenChannelBase::Params p;
p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
p.display_toasts_always = true;
p.toast_align = NA_CENTRE;
@ -114,7 +114,7 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
// Show alert in middle of progress view (during teleport) (EXT-1093)
LLProgressView* progress = gViewerWindow->getProgressView();
LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
mChannel->updatePositionAndSize(rc, rc);
mChannel->updatePositionAndSize(rc);
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
if(channel)

View File

@ -48,29 +48,38 @@ using namespace LLNotificationsUI;
bool LLScreenChannel::mWasStartUpToastShown = false;
LLRect get_channel_rect()
{
LLRect channel_rect;
LLView* floater_snap_region = LLUI::getRootView()->getChildView("floater_snap_region");
floater_snap_region->localRectToScreen(floater_snap_region->getLocalRect(), &channel_rect);
return channel_rect;
}
//--------------------------------------------------------------------------
//////////////////////
// LLScreenChannelBase
//////////////////////
LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
mToastAlignment(NA_BOTTOM)
,mCanStoreToasts(true)
,mHiddenToastsNum(0)
,mHoveredToast(NULL)
,mControlHovering(false)
,mShowToasts(true)
LLScreenChannelBase::LLScreenChannelBase(const Params& p)
: LLUICtrl(p),
mToastAlignment(p.toast_align),
mCanStoreToasts(true),
mHiddenToastsNum(0),
mHoveredToast(NULL),
mControlHovering(false),
mShowToasts(true),
mID(p.id),
mDisplayToastsAlways(p.display_toasts_always),
mChannelAlignment(p.channel_align)
{
mID = id;
mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
mID = p.id;
setMouseOpaque( false );
setVisible(FALSE);
}
LLScreenChannelBase::~LLScreenChannelBase()
{
mWorldViewRectConnection.disconnect();
}
bool LLScreenChannelBase::isHovering()
{
@ -82,21 +91,20 @@ bool LLScreenChannelBase::isHovering()
return mHoveredToast->isHovered();
}
void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
void LLScreenChannelBase::updatePositionAndSize(LLRect rect)
{
S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
LLRect this_rect = getRect();
this_rect.mTop -= top_delta;
this_rect.mTop = rect.mTop;
switch(mChannelAlignment)
{
case CA_LEFT :
break;
case CA_CENTRE :
this_rect.setCenterAndSize( (new_world_rect.getWidth()) / 2, new_world_rect.getHeight() / 2, this_rect.getWidth(), this_rect.getHeight());
this_rect.setCenterAndSize( (rect.getWidth()) / 2, rect.getHeight() / 2, this_rect.getWidth(), this_rect.getHeight());
break;
case CA_RIGHT :
this_rect.setLeftTopAndSize(new_world_rect.mRight - this_rect.getWidth(),
this_rect.setLeftTopAndSize(rect.mRight - this_rect.getWidth(),
this_rect.mTop,
this_rect.getWidth(),
this_rect.getHeight());
@ -116,31 +124,30 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
void LLScreenChannelBase::updateBottom()
{
S32 channel_top = gViewerWindow->getWorldViewRectScaled().getHeight();
S32 channel_bottom = gSavedSettings.getS32("ChannelBottomPanelMargin");
S32 channel_top = get_channel_rect().mTop;
S32 channel_bottom = get_channel_rect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
S32 channel_left = getRect().mLeft;
S32 channel_right = getRect().mRight;
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
}
//--------------------------------------------------------------------------
//////////////////////
// LLScreenChannel
//////////////////////
//--------------------------------------------------------------------------
LLScreenChannel::LLScreenChannel(LLUUID& id):
LLScreenChannelBase(id)
,mStartUpToastPanel(NULL)
{
LLScreenChannel::LLScreenChannel(const Params& p)
: LLScreenChannelBase(p),
mStartUpToastPanel(NULL)
{
}
//--------------------------------------------------------------------------
void LLScreenChannel::init(S32 channel_left, S32 channel_right)
{
LLScreenChannelBase::init(channel_left, channel_right);
LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
updatePositionAndSize(world_rect, world_rect);
LLRect channel_rect = get_channel_rect();
updatePositionAndSize(channel_rect);
}
//--------------------------------------------------------------------------
@ -177,7 +184,7 @@ std::list<LLToast*> LLScreenChannel::findToasts(const Matcher& matcher)
}
//--------------------------------------------------------------------------
void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
void LLScreenChannel::updatePositionAndSize(LLRect new_world_rect)
{
LLRect this_rect = getRect();
@ -187,7 +194,7 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
this_rect.mTop = (S32) (new_world_rect.getHeight() * getHeightRatio());
break;
case CA_CENTRE :
LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
LLScreenChannelBase::updatePositionAndSize(new_world_rect);
return;
case CA_RIGHT :
this_rect.mTop = (S32) (new_world_rect.getHeight() * getHeightRatio());
@ -511,9 +518,9 @@ void LLScreenChannel::showToastsBottom()
(*it).toast->translate(0, shift);
}
LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
LLRect channel_rect = get_channel_rect();
// don't show toasts if there is not enough space
if(toast_rect.mTop > world_rect.mTop)
if(toast_rect.mTop > channel_rect.mTop)
{
break;
}

View File

@ -53,21 +53,30 @@ class LLScreenChannelBase : public LLUICtrl
{
friend class LLChannelManager;
public:
LLScreenChannelBase(const LLUUID& id);
~LLScreenChannelBase();
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Mandatory<LLUUID> id;
Optional<bool> display_toasts_always;
Optional<EToastAlignment> toast_align;
Optional<EChannelAlignment> channel_align;
Params()
: id("id", LLUUID("")),
display_toasts_always("display_toasts_always", false),
toast_align("toast_align", NA_BOTTOM),
channel_align("channel_align", CA_LEFT)
{}
};
LLScreenChannelBase(const Params&);
// 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);
virtual void updatePositionAndSize(LLRect rect);
// initialization of channel's shape and position
virtual void init(S32 channel_left, S32 channel_right);
virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
// kill or modify a toast by its ID
virtual void killToastByNotificationID(LLUUID id) {};
virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {};
@ -90,7 +99,6 @@ public:
void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
// get number of hidden notifications from a channel
@ -124,9 +132,6 @@ protected:
// channel's ID
LLUUID mID;
// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
boost::signals2::connection mWorldViewRectConnection;
};
@ -137,7 +142,7 @@ class LLScreenChannel : public LLScreenChannelBase
{
friend class LLChannelManager;
public:
LLScreenChannel(LLUUID& id);
LLScreenChannel(const Params&);
virtual ~LLScreenChannel();
class Matcher
@ -152,7 +157,7 @@ public:
// Channel's outfit-functions
// update channel's size and position in the World View
void updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
void updatePositionAndSize(LLRect new_rect);
// initialization of channel's shape and position
void init(S32 channel_left, S32 channel_right);