void LLNearbyChatScreenChannel::showToastsBottom()
{
	if(mStopProcessing)
		return;

	LLRect	toast_rect;	
	updateBottom();
	S32 channel_bottom = getRect().mBottom;

	S32		bottom = channel_bottom;
	S32		margin = gSavedSettings.getS32("ToastGap");

	//sort active toasts
	std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);

	//calc max visible item and hide other toasts.

	for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
	{
		LLToast* toast = it->get();
		if (!toast)
		{
			llwarns << "NULL found in the active chat toasts list!" << llendl;
			continue;
		}

		S32 toast_top = bottom + toast->getRect().getHeight() + margin;

		if(toast_top > gFloaterView->getRect().getHeight())
		{
			while(it!=m_active_toasts.end())
			{
				addToToastPool(it->get());
				it=m_active_toasts.erase(it);
			}
			break;
		}

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());

		toast->setRect(toast_rect);
		bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
	}
	
	// use reverse order to provide correct z-order and avoid toast blinking
	
	for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
	{
		LLToast* toast = it->get();
		if (toast)
	{
		toast->setIsHidden(false);
		toast->setVisible(TRUE);
		}
	}

	}
void LLNearbyChatScreenChannel::showToastsBottom()
{
	if(mStopProcessing)
		return;

	LLRect	toast_rect;	
	S32		bottom = getRect().mBottom;
	S32		margin = gSavedSettings.getS32("ToastGap");

	for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
	{
		LLToast* toast = (*it);
		S32 toast_top = bottom + toast->getRect().getHeight() + margin;

		if(toast_top > gFloaterView->getRect().getHeight())
		{
			while(it!=m_active_toasts.end())
			{
				toast->setVisible(FALSE);
				toast->stopTimer();
				m_toast_pool.push_back(toast);
				it=m_active_toasts.erase(it);
			}
			break;
		}
		bottom = toast_top - toast->getTopPad();
	}

	// use reverse order to provide correct z-order and avoid toast blinking
	for(std::vector<LLToast*>::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
	{
		LLToast* toast = (*it);
		S32 toast_top = bottom + toast->getTopPad();

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(getRect().mLeft , toast_top, toast_rect.getWidth() ,toast_rect.getHeight());

		toast->setRect(toast_rect);
		toast->setIsHidden(false);
		toast->setVisible(TRUE);

		bottom = toast->getRect().mBottom - margin;
	}
}
//--------------------------------------------------------------------------
void LLScreenChannel::showToastsTop()
{
	LLRect channel_rect = getChannelRect();

	LLRect	toast_rect;	
	S32		top = channel_rect.mTop;
	std::vector<ToastElem>::reverse_iterator it;

	updateRect();

	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());

	// <FS:Ansariel> Show toasts in front of other floaters
	BOOL toasts_in_front = gSavedSettings.getBOOL("FSShowToastsInFront");

	// Use a local variable instead of mToastList.
	// mToastList can be modified during recursive calls and then all iteratos will be invalidated.
	std::vector<ToastElem> vToastList( mToastList );

	for(it = vToastList.rbegin(); it != vToastList.rend(); ++it)
	{
		if(it != vToastList.rbegin())
		{
			LLToast* toast = (it-1)->getToast();
			if (!toast)
			{
				llwarns << "Attempt to display a deleted toast." << llendl;
				return;
			}

			top = toast->getRect().mBottom - toast->getTopPad();
			gSavedSettings.getS32("ToastGap");
		}

		LLToast* toast = it->getToast();
		if (!toast)
		{
			llwarns << "Attempt to display a deleted toast." << llendl;
			return;
		}

		toast_rect = toast->getRect();
		toast_rect.setLeftTopAndSize(channel_rect.mRight - toast_rect.getWidth(),
			top, toast_rect.getWidth(),
			toast_rect.getHeight());
		toast->setRect(toast_rect);

		if(floater && floater->overlapsScreenChannel())
		{
			if(it == vToastList.rbegin())
			{
				// move first toast above docked floater
				S32 shift = -floater->getRect().getHeight();
				if(floater->getDockControl())
				{
					shift -= floater->getDockControl()->getTongueHeight();
				}
				toast->translate(0, shift);
			}

			LLRect channel_rect = getChannelRect();
			// don't show toasts if there is not enough space
			if(toast_rect.mBottom < channel_rect.mBottom)
			{
				break;
			}
		}

		bool stop_showing_toasts = toast->getRect().mBottom < channel_rect.mBottom;

		if(!stop_showing_toasts)
		{
			if( it != vToastList.rend()-1)
			{
				S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap");
				stop_showing_toasts = toast_bottom < channel_rect.mBottom;
			}
		} 

		// at least one toast should be visible
		if(it == vToastList.rbegin())
		{
			stop_showing_toasts = false;
		}

		if(stop_showing_toasts)
			break;

		if (!toast->getVisible())
		{
			// HACK
			// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
			toast->setVisible(TRUE);
		}		
		// <FS:Ansariel> Show toasts in front of other floaters
		//if (!toast->hasFocus())
		if (!toast->hasFocus() && !toasts_in_front)
		// </FS:Ansariel> Show toasts in front of other floaters
		{
			// Fixing Z-order of toasts (EXT-4862)
			// Next toast will be positioned under this one.
			gFloaterView->sendChildToBack(toast);
		}
	}

	// Dismiss toasts we don't have space for (STORM-391).
	std::vector<LLToast*> toasts_to_hide;

	if(it != vToastList.rend())
	{
		mHiddenToastsNum = 0;

		for(; it != vToastList.rend(); it++)
		{
			LLToast* toast = it->getToast();
			if (toast)
			{
				toasts_to_hide.push_back(toast);
			}
		}
	}

	for (std::vector<LLToast*>::iterator it = toasts_to_hide.begin(), end_it = toasts_to_hide.end();
		it != end_it;
		++it)
	{
		(*it)->hide();
	}
}
示例#4
0
//--------------------------------------------------------------------------
void LLScreenChannel::showToastsBottom()
{
	LLRect	toast_rect;	
	S32		bottom = getRect().mBottom - gFloaterView->getRect().mBottom;
	S32		toast_margin = 0;
	std::vector<ToastElem>::reverse_iterator it;

	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(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.setOriginAndSize(getRect().mRight - toast_rect.getWidth(),
				bottom + toast_margin, toast_rect.getWidth(),
				toast_rect.getHeight());
		(*it).toast->setRect(toast_rect);

		if(floater && floater->overlapsScreenChannel())
		{
			if(it == mToastList.rbegin())
			{
				// move first toast above docked floater
				S32 shift = floater->getRect().getHeight();
				if(floater->getDockControl())
				{
					shift += floater->getDockControl()->getTongueHeight();
				}
				(*it).toast->translate(0, shift);
			}

			LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
			// don't show toasts if there is not enough space
			if(toast_rect.mTop > world_rect.mTop)
			{
				break;
			}
		}

		bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().mTop;

		if(!stop_showing_toasts)
		{
			if( it != mToastList.rend()-1)
			{
				S32 toast_top = (*it).toast->getRect().mTop + gSavedSettings.getS32("ToastGap");
				stop_showing_toasts = toast_top > getRect().mTop;
			}
		} 

		// 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);
		}
	}

	if(it != mToastList.rend())
	{
		mHiddenToastsNum = 0;
		for(; it != mToastList.rend(); it++)
		{
			(*it).toast->stopTimer();
			(*it).toast->setVisible(FALSE);
			mHiddenToastsNum++;
		}
	}
	else
	{
		closeOverflowToastPanel();
	}
}
void LLNearbyChatScreenChannel::arrangeToasts()
{
	if(mStopProcessing || isHovering())
		return;

	if (mFloaterSnapRegion == NULL)
	{
		mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region");
	}
	
	if (!getParent())
	{
		// connect to floater snap region just to get resize events, we don't care about being a proper widget 
		mFloaterSnapRegion->addChild(this);
		setFollows(FOLLOWS_ALL);
	}

	LLRect	toast_rect;	
	updateRect();

	LLRect channel_rect;
	mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView);
	channel_rect.mLeft += 10;
	channel_rect.mRight = channel_rect.mLeft + 300;

	S32 channel_bottom = channel_rect.mBottom;

	// <FS:Ansariel> Configurable nearby chat toasts offset
	//S32		bottom = channel_bottom + 80;
	S32		bottom = channel_bottom + gSavedSettings.getS32("FSNearbyChatToastsOffset");
	S32		margin = gSavedSettings.getS32("ToastGap");

	//sort active toasts
	std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);

	//calc max visible item and hide other toasts.

	for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
	{
		LLToast* toast = it->get();
		if (!toast)
		{
			llwarns << "NULL found in the active chat toasts list!" << llendl;
			continue;
		}

		S32 toast_top = bottom + toast->getRect().getHeight() + margin;

		if(toast_top > channel_rect.getHeight())
		{
			while(it!=m_active_toasts.end())
			{
				addToToastPool(it->get());
				it=m_active_toasts.erase(it);
			}
			break;
		}

		toast_rect = toast->getRect();
		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;
	}
	
	// use reverse order to provide correct z-order and avoid toast blinking
	
	for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
	{
		LLToast* toast = it->get();
		if (toast)
		{
		toast->setIsHidden(false);
		toast->setVisible(TRUE);
		}
	}

}