diff options
104 files changed, 3893 insertions, 5146 deletions
diff --git a/BuildParams b/BuildParams index 1c39dd7cc7..84e51e1442 100644 --- a/BuildParams +++ b/BuildParams @@ -111,6 +111,18 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"  viewer-mesh.viewer_grid = aditi  viewer-mesh.email = shining@lists.lindenlab.com +# ======================================== +# viewer-chui +# +# ======================================== + +viewer-chui.viewer_channel = "Project Viewer - CHUI" +viewer-chui.login_channel = "Project Viewer - CHUI" +viewer-chui.viewer_grid = agni +viewer-chui.build_debug_release_separately = true +viewer-chui.build_CYGWIN_Debug = false +viewer-chui.build_viewer_update_version_manager = false +  # ================  # oz  # ================ diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 34d841a4e0..11f582372e 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -43,7 +43,7 @@   * semantics: one instance per process, rather than one instance per module as   * sometimes happens with data simply declared static.   */ -class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable +class LL_COMMON_API LLInstanceTrackerBase  {  protected:  	/// Get a process-unique void* pointer slot for the specified type_info @@ -209,6 +209,9 @@ protected:  	virtual const KEY& getKey() const { return mInstanceKey; }  private: +	LLInstanceTracker( const LLInstanceTracker& ); +	const LLInstanceTracker& operator=( const LLInstanceTracker& ); +  	void add_(KEY key)   	{   		mInstanceKey = key;  diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 8eb5d53f3f..32ae15435a 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -27,6 +27,7 @@  #define LLREFCOUNT_H  #include <boost/noncopyable.hpp> +#include <boost/intrusive_ptr.hpp>  #define LL_REF_COUNT_DEBUG 0  #if LL_REF_COUNT_DEBUG @@ -86,4 +87,22 @@ private:  #endif  }; +/** + * intrusive pointer support + * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type + */ +namespace boost +{ +	inline void intrusive_ptr_add_ref(LLRefCount* p) +	{ +		p->ref(); +	} + +	inline void intrusive_ptr_release(LLRefCount* p) +	{ +		p->unref(); +	} +}; + +  #endif diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b52e70ab2e..cf39696b4f 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -30,6 +30,7 @@  #include "llapp.h"  #include "llapr.h"  #include "apr_thread_cond.h" +#include "boost/intrusive_ptr.hpp"  class LLThread;  class LLMutex; @@ -266,6 +267,22 @@ private:  	S32	mRef;   }; +/** + * intrusive pointer support for LLThreadSafeRefCount + * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type + */ +namespace boost +{ +	inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)  +	{ +		p->ref(); +	} + +	inline void intrusive_ptr_release(LLThreadSafeRefCount* p)  +	{ +		p->unref();  +	} +};  //============================================================================  // Simple responder for self destructing callbacks diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp index 6ac38f5ad4..1ede5b706f 100644 --- a/indra/llui/llloadingindicator.cpp +++ b/indra/llui/llloadingindicator.cpp @@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)  void LLLoadingIndicator::initFromParams(const Params& p)  { -	BOOST_FOREACH(LLUIImage* image, p.images.image) +	BOOST_FOREACH(LLUIImage* image, p.images().image)  	{  		mImages.push_back(image);  	} diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index c1f979c111..ffcb329f42 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -51,7 +51,7 @@ class LLLoadingIndicator  	LOG_CLASS(LLLoadingIndicator);  public: -	struct Images : public LLInitParam::BatchBlock<Images> +	struct Images : public LLInitParam::Block<Images>  	{  		Multiple<LLUIImage*>	image; @@ -62,8 +62,8 @@ public:  	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>  	{ -		Optional<F32>			images_per_sec; -		Optional<Images>		images; +		Optional<F32>				images_per_sec; +		Optional<Atomic<Images> >	images;  		Params()  		:	images_per_sec("images_per_sec", 1.0f), diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 50d59f79f4..746ade4648 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -44,33 +44,27 @@ void LLMenuButton::MenuPositions::declareValues()  LLMenuButton::Params::Params()  :	menu_filename("menu_filename"), -	position("position", MP_BOTTOM_LEFT) +	position("menu_position", MP_BOTTOM_LEFT)  { +	addSynonym(position, "position");  }  LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)  :	LLButton(p),  	mIsMenuShown(false), -	mMenuPosition(p.position) +	mMenuPosition(p.position), +	mOwnMenu(false)  {  	std::string menu_filename = p.menu_filename; -	if (!menu_filename.empty()) -	{ -		LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); -		if (!menu) -		{ -			llwarns << "Error loading menu_button menu" << llendl; -			return; -		} - -		menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2)); - -		mMenuHandle = menu->getHandle(); +	setMenu(menu_filename, mMenuPosition); +	updateMenuOrigin(); +} -		updateMenuOrigin(); -	} +LLMenuButton::~LLMenuButton() +{ +	cleanup();  }  boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb ) @@ -80,9 +74,7 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign  void LLMenuButton::hideMenu()  { -	if(mMenuHandle.isDead()) return; - -	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get()); +	LLToggleableMenu* menu = getMenu();  	if (menu)  	{  		menu->setVisible(FALSE); @@ -94,19 +86,39 @@ LLToggleableMenu* LLMenuButton::getMenu()  	return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());  } -void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/) +void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/) +{ +	if (menu_filename.empty()) +	{ +		return; +	} + +	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); +	if (!menu) +	{ +		llwarns << "Error loading menu_button menu" << llendl; +		return; +	} + +	setMenu(menu, position, true); +} + +void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)  {  	if (!menu) return; +	cleanup(); // destroy the previous memnu if we own it +  	mMenuHandle = menu->getHandle();  	mMenuPosition = position; +	mOwnMenu = take_ownership;  	menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));  }  BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )  { -	if (mMenuHandle.isDead()) return FALSE; +	if (!getMenu()) return FALSE;  	if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))  	{ @@ -118,7 +130,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )  		return TRUE;  	} -	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get()); +	LLToggleableMenu* menu = getMenu();  	if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)  	{  		menu->setVisible(FALSE); @@ -139,9 +151,12 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)  void LLMenuButton::toggleMenu()  { -	if(mMenuHandle.isDead()) return; +	if (mValidateSignal && !(*mValidateSignal)(this, LLSD())) +	{ +		return; +	} -	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get()); +	LLToggleableMenu* menu = getMenu();  	if (!menu) return;  	// Store the button rectangle to toggle menu visibility if a mouse event @@ -170,7 +185,8 @@ void LLMenuButton::toggleMenu()  void LLMenuButton::updateMenuOrigin()  { -	if (mMenuHandle.isDead()) return; +	LLToggleableMenu* menu = getMenu(); +	if (!menu) return;  	LLRect rect = getRect(); @@ -179,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()  		case MP_TOP_LEFT:  		{  			mX = rect.mLeft; -			mY = rect.mTop + mMenuHandle.get()->getRect().getHeight(); +			mY = rect.mTop + menu->getRect().getHeight();  			break;  		}  		case MP_TOP_RIGHT:  		{ -			const LLRect& menu_rect = mMenuHandle.get()->getRect(); +			const LLRect& menu_rect = menu->getRect();  			mX = rect.mRight - menu_rect.getWidth();  			mY = rect.mTop + menu_rect.getHeight();  			break; @@ -211,3 +227,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)  		mIsMenuShown = false;  	}  } + +void LLMenuButton::cleanup() +{ +	if (mMenuHandle.get() && mOwnMenu) +	{ +		mMenuHandle.get()->die(); +	} +} diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h index e2396e7fb2..67ec1983b3 100644 --- a/indra/llui/llmenubutton.h +++ b/indra/llui/llmenubutton.h @@ -34,6 +34,8 @@ class LLToggleableMenu;  class LLMenuButton  : public LLButton  { +	LOG_CLASS(LLMenuButton); +  public:  	typedef enum e_menu_position  	{ @@ -53,7 +55,7 @@ public:  	{  		// filename for it's toggleable menu  		Optional<std::string>	menu_filename; -		Optional<EMenuPosition>	position; +		Optional<EMenuPosition, MenuPositions>	position;  		Params();  	}; @@ -68,13 +70,15 @@ public:  	void hideMenu();  	LLToggleableMenu* getMenu(); -	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT); +	void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT); +	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);  	void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }  protected:  	friend class LLUICtrlFactory;  	LLMenuButton(const Params&); +	~LLMenuButton();  	void toggleMenu();  	void updateMenuOrigin(); @@ -82,11 +86,14 @@ protected:  	void onMenuVisibilityChange(const LLSD& param);  private: +	void cleanup(); +  	LLHandle<LLView>		mMenuHandle;  	bool					mIsMenuShown;  	EMenuPosition			mMenuPosition;  	S32						mX;  	S32						mY; +	bool					mOwnMenu; // true if we manage the menu lifetime  }; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index ff6928ffda..32e5cdd556 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -4021,11 +4021,6 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )  	return result;  } -void LLContextMenu::draw() -{ -	LLMenuGL::draw(); -} -  BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)  { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 36f3ba34b9..c6ee5434b0 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -668,8 +668,6 @@ public:  	// can't set visibility directly, must call show or hide  	virtual void	setVisible			(BOOL visible); -	virtual void	draw				(); -	  	virtual void	show				(S32 x, S32 y);  	virtual void	hide				(); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 8aa548b974..9ef9b4bbec 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -246,7 +246,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica  	LLParamSDParser parser;  	parser.writeSD(mFormData, p.form_elements); -	if (!mFormData.isArray()) +	if (!mFormData.isArray() && !mFormData.isUndefined())  	{  		// change existing contents to a one element array  		LLSD new_llsd_array = LLSD::emptyArray(); @@ -407,9 +407,12 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par  	mURLOption(p.url.option),  	mURLTarget(p.url.target),  	mUnique(p.unique.isProvided()), +	mCombineBehavior(p.unique.combine),  	mPriority(p.priority),  	mPersist(p.persist), -	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()) +	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()), +	mLogToChat(p.log_to_chat), +	mLogToIM(p.log_to_im)  {  	if (p.sound.isProvided()  		&& LLUI::sSettingGroups["config"]->controlExists(p.sound)) @@ -886,6 +889,28 @@ std::string LLNotification::getURL() const  	return (mTemplatep ? url : "");  } +bool LLNotification::canLogToChat() const +{ +	return mTemplatep->mLogToChat; +} + +bool LLNotification::canLogToIM() const +{ +	return mTemplatep->mLogToIM; +} + +bool LLNotification::hasFormElements() const +{ +	return mTemplatep->mForm->getNumElements() != 0; +} + +LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const +{ +	return mTemplatep->mCombineBehavior; +} + + +  // =========================================================  // LLNotificationChannel implementation  // --- @@ -946,7 +971,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt  	std::string cmd = payload["sigtype"];  	LLNotificationSet::iterator foundItem = mItems.find(pNotification);  	bool wasFound = (foundItem != mItems.end()); -	bool passesFilter = mFilter(pNotification); +	bool passesFilter = mFilter ? mFilter(pNotification) : true;  	// first, we offer the result of the filter test to the simple  	// signals for pass/fail. One of these is guaranteed to be called. @@ -1051,41 +1076,28 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt  	return abortProcessing;  } -/* static */ -LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,  -															 const std::string& parent, -															 LLNotificationFilter filter,  -															 LLNotificationComparator comparator) +LLNotificationChannel::LLNotificationChannel(const Params& p) +:	LLNotificationChannelBase(p.filter(), p.comparator()), +	LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()), +	mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())  { -	// note: this is not a leak; notifications are self-registering. -	// This factory helps to prevent excess deletions by making sure all smart -	// pointers to notification channels come from the same source -	new LLNotificationChannel(name, parent, filter, comparator); -	return LLNotifications::instance().getChannel(name); +	BOOST_FOREACH(const std::string& source, p.sources) +{ +		connectToChannel(source); +	}  }  LLNotificationChannel::LLNotificationChannel(const std::string& name,   											 const std::string& parent,  											 LLNotificationFilter filter,  -											 LLNotificationComparator comparator) :  -LLNotificationChannelBase(filter, comparator), -mName(name), -mParent(parent) +											 LLNotificationComparator comparator)  +:	LLNotificationChannelBase(filter, comparator), +	LLInstanceTracker<LLNotificationChannel, std::string>(name), +	mName(name)  { -	// store myself in the channel map -	LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));  	// bind to notification broadcast -	if (parent.empty()) -	{ -		LLNotifications::instance().connectChanged( -			boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); -	} -	else -	{ -		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent); -		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); -	} +	connectToChannel(parent);  } @@ -1128,6 +1140,21 @@ std::string LLNotificationChannel::summarize()  	return s;  } +void LLNotificationChannel::connectToChannel( const std::string& channel_name ) +{ +	if (channel_name.empty()) +	{ +		LLNotifications::instance().connectChanged( +			boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); +	} +	else +	{ +		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name); +		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); +	} +} + +  // ---  // END OF LLNotificationChannel implementation @@ -1220,6 +1247,8 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)  		return false;  	} +	if (pNotif->getCombineBehavior() == LLNotification::USE_NEWEST) +	{  	// Update the existing unique notification with the data from this particular instance...  	// This guarantees that duplicate notifications will be collapsed to the one  	// most recently triggered @@ -1238,25 +1267,14 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)  			cancel(pNotif);  		}  	} +	}  	return false;  } - -void LLNotifications::addChannel(LLNotificationChannelPtr pChan) -{ -	mChannels[pChan->getName()] = pChan; -} -  LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)  { -	ChannelMap::iterator p = mChannels.find(channelName); -	if(p == mChannels.end()) -	{ -		llerrs << "Did not find channel named " << channelName << llendl; -		return LLNotificationChannelPtr(); -	} -	return p->second; +	return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));  } @@ -1272,24 +1290,21 @@ void LLNotifications::createDefaultChannels()  {  	// now construct the various channels AFTER loading the notifications,  	// because the history channel is going to rewrite the stored notifications file -	LLNotificationChannel::buildChannel("Enabled", "", -		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this)); -	LLNotificationChannel::buildChannel("Expiration", "Enabled", -		boost::bind(&LLNotifications::expirationFilter, this, _1)); -	LLNotificationChannel::buildChannel("Unexpired", "Enabled", -		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind -	LLNotificationChannel::buildChannel("Unique", "Unexpired", -		boost::bind(&LLNotifications::uniqueFilter, this, _1)); -	LLNotificationChannel::buildChannel("Ignore", "Unique", -		filterIgnoredNotifications); -	LLNotificationChannel::buildChannel("VisibilityRules", "Ignore", -		boost::bind(&LLNotifications::isVisibleByRules, this, _1)); -	LLNotificationChannel::buildChannel("Visible", "VisibilityRules", -		&LLNotificationFilters::includeEverything); - -	// create special persistent notification channel -	// this isn't a leak, don't worry about the empty "new" -	new LLPersistentNotificationChannel(); +	mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "", +		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this))); +	mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled", +		boost::bind(&LLNotifications::expirationFilter, this, _1))); +	mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled", +		!boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind +	mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired", +		boost::bind(&LLNotifications::uniqueFilter, this, _1))); +	mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique", +		filterIgnoredNotifications)); +	mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore", +		boost::bind(&LLNotifications::isVisibleByRules, this, _1))); +	mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules", +		&LLNotificationFilters::includeEverything)); +	mDefaultChannels.push_back(new LLPersistentNotificationChannel());  	// connect action methods to these channels  	LLNotifications::instance().getChannel("Enabled")-> diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 3df2efcac3..21a4318aab 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -94,10 +94,11 @@  // and we need this to manage the notification callbacks  #include "llevents.h"  #include "llfunctorregistry.h" -#include "llpointer.h"  #include "llinitparam.h"  #include "llnotificationslistener.h"  #include "llnotificationptr.h" +#include "llpointer.h" +#include "llrefcount.h"  class LLAvatarName;  typedef enum e_notification_priority @@ -296,6 +297,7 @@ LOG_CLASS(LLNotification);  friend class LLNotifications;  public: +  	// parameter object used to instantiate a new notification  	struct Params : public LLInitParam::Block<Params>  	{ @@ -513,7 +515,17 @@ public:  	std::string getURL() const;  	S32 getURLOption() const;      S32 getURLOpenExternally() const; +	bool canLogToChat() const; +	bool canLogToIM() const; +	bool hasFormElements() const; + +	typedef enum e_combine_behavior +	{ +		USE_NEWEST, +		USE_OLDEST +	} ECombineBehavior; +	ECombineBehavior getCombineBehavior() const;  	const LLNotificationFormPtr getForm();  	const LLDate getExpiration() const @@ -704,7 +716,8 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;  // all of the built-in tests should attach to the "Visible" channel  //  class LLNotificationChannelBase : -	public LLEventTrackable +	public LLEventTrackable, +	public LLRefCount  {  	LOG_CLASS(LLNotificationChannelBase);  public: @@ -784,32 +797,47 @@ protected:  // destroy it, but if it becomes necessary to do so, the shared_ptr model  // will ensure that we don't leak resources.  class LLNotificationChannel; -typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr; +typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;  // manages a list of notifications  // Note that if this is ever copied around, we might find ourselves with multiple copies  // of a queue with notifications being added to different nonequivalent copies. So we  -// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it. -//  -// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to  -// do something like: -//		LLNotificationChannel::buildChannel("name", "parent"...); -// This returns an LLNotificationChannelPtr, which you can store, or -// you can then retrieve the channel by using the registry: -//		LLNotifications::instance().getChannel("name")... +// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.  //  class LLNotificationChannel :   	boost::noncopyable,  -	public LLNotificationChannelBase +	public LLNotificationChannelBase, +	public LLInstanceTracker<LLNotificationChannel, std::string>  {  	LOG_CLASS(LLNotificationChannel);  public:   +	// Notification Channels have a filter, which determines which notifications +	// will be added to this channel.  +	// Channel filters cannot change. +	struct Params : public LLInitParam::Block<Params> +	{ +		Mandatory<std::string>				name; +		Optional<LLNotificationFilter>		filter; +		Optional<LLNotificationComparator>	comparator; +		Multiple<std::string>				sources; + +		Params() +		:	comparator("", LLNotificationComparators::orderByUUID()) +		{} +	}; + +	LLNotificationChannel(const Params& p = Params()); + +	LLNotificationChannel(const std::string& name, const std::string& parent, +		LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID()); +  	virtual ~LLNotificationChannel() {}  	typedef LLNotificationSet::iterator Iterator;  	std::string getName() const { return mName; } -	std::string getParentChannelName() { return mParent; } +     +	void connectToChannel(const std::string& channel_name);      bool isEmpty() const; @@ -822,21 +850,6 @@ public:  	std::string summarize(); -	// factory method for constructing these channels; since they're self-registering, -	// we want to make sure that you can't use new to make them -	static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent, -						LLNotificationFilter filter=LLNotificationFilters::includeEverything,  -						LLNotificationComparator comparator=LLNotificationComparators::orderByUUID()); -	 -protected: -    // Notification Channels have a filter, which determines which notifications -	// will be added to this channel.  -	// Channel filters cannot change. -	// Channels have a protected constructor so you can't make smart pointers that don't  -	// come from our internal reference; call NotificationChannel::build(args) -	LLNotificationChannel(const std::string& name, const std::string& parent, -						  LLNotificationFilter filter, LLNotificationComparator comparator); -  private:  	std::string mName;  	std::string mParent; @@ -923,10 +936,6 @@ public:  	void createDefaultChannels(); -	typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap; -	ChannelMap mChannels; - -	void addChannel(LLNotificationChannelPtr pChan);  	LLNotificationChannelPtr getChannel(const std::string& channelName);  	std::string getGlobalString(const std::string& key) const; @@ -965,6 +974,7 @@ private:  	bool mIgnoreAllNotifications;      boost::scoped_ptr<LLNotificationsListener> mListener; +	std::vector<LLNotificationChannelPtr> mDefaultChannels;  };  /** diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp index 3bbeb3a778..e4e127336b 100644 --- a/indra/llui/llnotificationslistener.cpp +++ b/indra/llui/llnotificationslistener.cpp @@ -121,13 +121,13 @@ void LLNotificationsListener::listChannels(const LLSD& params) const  {      LLReqID reqID(params);      LLSD response(reqID.makeResponse()); -    for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()), -                                                     cmend(mNotifications.mChannels.end()); +    for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()), +                                                     cmend(LLNotificationChannel::endInstances());           cmi != cmend; ++cmi)      {          LLSD channelInfo; -        channelInfo["parent"] = cmi->second->getParentChannelName(); -        response[cmi->first] = channelInfo; +        //channelInfo["parent"] = cmi->second->getParentChannelName(); +        response[cmi->getName()] = channelInfo;      }      LLEventPumps::instance().obtain(params["reply"]).post(response);  } diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index fb50c9c123..f7d08ae1f4 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -61,6 +61,17 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;  // from the appropriate local language directory).  struct LLNotificationTemplate  { +	struct CombineBehaviorNames +		:	public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames> +	{ +		static void declareValues() +		{ +			declare("newest", LLNotification::USE_NEWEST); +			declare("oldest", LLNotification::USE_OLDEST); +		} +	}; + +  	struct GlobalString : public LLInitParam::Block<GlobalString>  	{  		Mandatory<std::string>	name, @@ -94,9 +105,11 @@ struct LLNotificationTemplate  		Optional<LLInitParam::Flag>	dummy_val;  	public:  		Multiple<UniquenessContext>	contexts; +		Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;  		UniquenessConstraint()  		:	contexts("context"), +			combine("combine", LLNotification::USE_NEWEST),  			dummy_val("")  		{}  	}; @@ -170,7 +183,9 @@ struct LLNotificationTemplate  	struct Params : public LLInitParam::Block<Params>  	{  		Mandatory<std::string>			name; -		Optional<bool>					persist; +		Optional<bool>					persist, +										log_to_im, +										log_to_chat;  		Optional<std::string>			functor,  										icon,  										label, @@ -190,6 +205,8 @@ struct LLNotificationTemplate  		Params()  		:	name("name"),  			persist("persist", false), +			log_to_im("log_to_im", false), +			log_to_chat("log_to_chat", true),  			functor("functor"),  			icon("icon"),  			label("label"), @@ -245,6 +262,7 @@ struct LLNotificationTemplate      // (used for things like progress indications, or repeating warnings      // like "the grid is going down in N minutes")      bool mUnique; +	LLNotification::ECombineBehavior mCombineBehavior;      // if we want to be unique only if a certain part of the payload or substitutions args  	// are constant specify the field names for the payload. The notification will only be      // combined if all of the fields named in the context are identical in the @@ -291,6 +309,10 @@ struct LLNotificationTemplate  	LLUUID mSoundEffect;  	// List of tags that rules can match against.  	std::list<std::string> mTags; + +	// inject these notifications into chat/IM streams +	bool mLogToChat; +	bool mLogToIM;  };  #endif //LL_LLNOTIFICATION_TEMPLATE_H diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index 0e29873bb0..bcfb38aa11 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -313,7 +313,7 @@ namespace LLInitParam  {  	// LLSD specialization  	// block param interface -	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name) +	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)  	{  		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack); @@ -328,12 +328,12 @@ namespace LLInitParam  	}  	//static -	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack) +	void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)  	{  		p.writeValue<LLSD::String>(sd.asString(), name_stack);  	} -	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const +	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const  	{  		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)  		Parser::name_stack_t stack; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index b5e27616b7..8da0d58f51 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -974,31 +974,31 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)  {  	if (!LLGLSLShader::sNoFixedFunction)  	{  -		// Initialize the first time this is called. -		const S32 PIXELS = 32; -		static GLubyte checkerboard[PIXELS * PIXELS]; -		static BOOL first = TRUE; -		if( first ) +	// Initialize the first time this is called. +	const S32 PIXELS = 32; +	static GLubyte checkerboard[PIXELS * PIXELS]; +	static BOOL first = TRUE; +	if( first ) +	{ +		for( S32 i = 0; i < PIXELS; i++ )  		{ -			for( S32 i = 0; i < PIXELS; i++ ) +			for( S32 j = 0; j < PIXELS; j++ )  			{ -				for( S32 j = 0; j < PIXELS; j++ ) -				{ -					checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; -				} +				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;  			} -			first = FALSE;  		} +		first = FALSE; +	} -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		// ...white squares -		gGL.color4f( 1.f, 1.f, 1.f, alpha ); -		gl_rect_2d(rect); +	// ...white squares +	gGL.color4f( 1.f, 1.f, 1.f, alpha ); +	gl_rect_2d(rect); -		// ...gray squares -		gGL.color4f( .7f, .7f, .7f, alpha ); -		gGL.flush(); +	// ...gray squares +	gGL.color4f( .7f, .7f, .7f, alpha ); +	gGL.flush();  		glPolygonStipple( checkerboard ); @@ -1474,144 +1474,132 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  	gGL.popUIMatrix();  } -void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,  -							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, -							  const U32 edges) +void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,  +							 const LLVector3& width_vec, const LLVector3& height_vec)  { -	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero; -	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; - -	LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; -	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; - -  	gGL.begin(LLRender::QUADS);  	{  		// draw bottom left -		gGL.texCoord2f(0.f, 0.f); +		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);  		gGL.vertex3f(0.f, 0.f, 0.f); -		gGL.texCoord2f(border_scale.mV[VX], 0.f); -		gGL.vertex3fv(left_border_width.mV); +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(0.f, border_scale.mV[VY]); -		gGL.vertex3fv(bottom_border_height.mV); +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);  		// draw bottom middle -		gGL.texCoord2f(border_scale.mV[VX], 0.f); -		gGL.vertex3fv(left_border_width.mV); +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); -		gGL.vertex3fv((width_vec - right_border_width).mV); +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);  		// draw bottom right -		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); -		gGL.vertex3fv((width_vec - right_border_width).mV); +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); -		gGL.texCoord2f(1.f, 0.f); +		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);  		gGL.vertex3fv(width_vec.mV); -		gGL.texCoord2f(1.f, border_scale.mV[VY]); -		gGL.vertex3fv((width_vec + bottom_border_height).mV); +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);  		// draw left  -		gGL.texCoord2f(0.f, border_scale.mV[VY]); -		gGL.vertex3fv(bottom_border_height.mV); +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((height_vec - top_border_height).mV); +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);  		// draw middle -		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);  		// draw right  -		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(1.f, border_scale.mV[VY]); -		gGL.vertex3fv((width_vec + bottom_border_height).mV); +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); +		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); -		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);  		// draw top left -		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((height_vec - top_border_height).mV); +		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], 1.f); -		gGL.vertex3fv((left_border_width + height_vec).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); -		gGL.texCoord2f(0.f, 1.f); +		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);  		gGL.vertex3fv((height_vec).mV);  		// draw top middle -		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); -		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); -		gGL.texCoord2f(border_scale.mV[VX], 1.f); -		gGL.vertex3fv((left_border_width + height_vec).mV); +		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);  		// draw top right -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); +		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); -		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); +		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); +		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); -		gGL.texCoord2f(1.f, 1.f); +		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);  		gGL.vertex3fv((width_vec + height_vec).mV); -		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); -		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); +		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); +		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);  	}  	gGL.end();  } -void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) -{ -	gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); -}  void LLUI::initClass(const settings_map_t& settings,  					 LLImageProviderInterface* image_provider, @@ -2114,7 +2102,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)  namespace LLInitParam  { -	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)  	:	super_t(color),  		red("red"),  		green("green"), @@ -2125,7 +2113,7 @@ namespace LLInitParam  		updateBlockFromValue(false);  	} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() +	void ParamValue<LLUIColor>::updateValueFromBlock()  	{  		if (control.isProvided() && !control().empty())  		{ @@ -2137,7 +2125,7 @@ namespace LLInitParam  		}  	} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative) +	void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative)  	{  		LLColor4 color = getValue();  		red.set(color.mV[VRED], make_block_authoritative); @@ -2153,7 +2141,7 @@ namespace LLInitParam  			&& !(b->getFontDesc() < a->getFontDesc());  	} -	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)  	:	super_t(fontp),  		name("name"),  		size("size"), @@ -2167,7 +2155,7 @@ namespace LLInitParam  		updateBlockFromValue(false);  	} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock() +	void ParamValue<const LLFontGL*>::updateValueFromBlock()  	{  		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);  		if (res_fontp) @@ -2190,7 +2178,7 @@ namespace LLInitParam  		}  	} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative) +	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative)  	{  		if (getValue())  		{ @@ -2200,7 +2188,7 @@ namespace LLInitParam  		}  	} -	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect) +	ParamValue<LLRect>::ParamValue(const LLRect& rect)  	:	super_t(rect),  		left("left"),  		top("top"), @@ -2212,7 +2200,7 @@ namespace LLInitParam  		updateBlockFromValue(false);  	} -	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock() +	void ParamValue<LLRect>::updateValueFromBlock()  	{  		LLRect rect; @@ -2276,7 +2264,7 @@ namespace LLInitParam  		updateValue(rect);  	} -	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative) +	void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative)  	{  		// because of the ambiguity in specifying a rect by position and/or dimensions  		// we use the lowest priority pairing so that any valid pairing in xui  @@ -2293,7 +2281,7 @@ namespace LLInitParam  		height.set(value.getHeight(), make_block_authoritative);  	} -	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord) +	ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord)  	:	super_t(coord),  		x("x"),  		y("y") @@ -2301,12 +2289,12 @@ namespace LLInitParam  		updateBlockFromValue(false);  	} -	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock() +	void ParamValue<LLCoordGL>::updateValueFromBlock()  	{  		updateValue(LLCoordGL(x, y));  	} -	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative) +	void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative)  	{  		x.set(getValue().mX, make_block_authoritative);  		y.set(getValue().mY, make_block_authoritative); diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 28e84fa444..1fbfbd7a07 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -127,8 +127,7 @@ typedef enum e_rounded_edge  void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);  void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec); +void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);  inline void gl_rect_2d( const LLRect& rect, BOOL filled )  { @@ -512,7 +511,7 @@ public:  namespace LLInitParam  {  	template<> -	class ParamValue<LLRect, TypeValues<LLRect> >  +	class ParamValue<LLRect>   	:	public CustomParamValue<LLRect>  	{          typedef CustomParamValue<LLRect> super_t; @@ -531,7 +530,7 @@ namespace LLInitParam  	};  	template<> -	class ParamValue<LLUIColor, TypeValues<LLUIColor> >  +	class ParamValue<LLUIColor>   	:	public CustomParamValue<LLUIColor>  	{          typedef CustomParamValue<LLUIColor> super_t; @@ -549,7 +548,7 @@ namespace LLInitParam  	};  	template<> -	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >  +	class ParamValue<const LLFontGL*>   	:	public CustomParamValue<const LLFontGL* >  	{          typedef CustomParamValue<const LLFontGL*> super_t; @@ -589,7 +588,7 @@ namespace LLInitParam  	template<> -	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> > +	class ParamValue<LLCoordGL>  	:	public CustomParamValue<LLCoordGL>  	{  		typedef CustomParamValue<LLCoordGL> super_t; diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 1d9ce29ba9..9ed98f941f 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -112,6 +112,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&  	drawSolid(border_rect, color);  } +void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,  +						const LLRect& rect, const LLColor4& color) +{ +	F32 border_scale = 1.f; +	F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight(); +	F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth(); +	if (rect.getHeight() < border_height || rect.getWidth() < border_width) +	{ +		 if(border_height - rect.getHeight() > border_width - rect.getWidth()) +		 { +			 border_scale = (F32)rect.getHeight() / border_height; +		 } +		 else +		 { +			border_scale = (F32)rect.getWidth() / border_width; +		 } +	} + +	LLUI::pushMatrix(); +	{  +		LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);  +		LLUI::translate(rect_origin.mV[VX], +						rect_origin.mV[VY],  +						rect_origin.mV[VZ]); +		gGL.getTexUnit(0)->bind(getImage()); +		gGL.color4fv(color.mV); + +		LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(), +							mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(), +							mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(), +							mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight()); +		gl_segmented_rect_3d_tex(mClipRegion, +								center_uv_rect, +								LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(), +										(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(), +										(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(), +										(border_height * border_scale * 0.5f) / (F32)rect.getHeight()), +								rect.getWidth() * x_axis,  +								rect.getHeight() * y_axis); +		 +	} LLUI::popMatrix(); +} + +  S32 LLUIImage::getWidth() const  {   	// return clipped dimensions of actual image area @@ -155,7 +199,7 @@ void LLUIImage::onImageLoaded()  namespace LLInitParam  { -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock() +	void ParamValue<LLUIImage*>::updateValueFromBlock()  	{  		// The keyword "none" is specifically requesting a null image  		// do not default to current value. Used to overwrite template images.  @@ -172,7 +216,7 @@ namespace LLInitParam  		}  	} -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative) +	void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)  	{  		if (getValue() == NULL)  		{ diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index f07e8fa746..7817ba1c7b 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -64,7 +64,9 @@ public:  	void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;  	void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }  	void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); } -	 + +	void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color); +  	const std::string& getName() const { return mName; }  	virtual S32 getWidth() const; @@ -92,7 +94,7 @@ protected:  namespace LLInitParam  {  	template<> -	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >  +	class ParamValue<LLUIImage*>   	:	public CustomParamValue<LLUIImage*>  	{  		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref; @@ -100,7 +102,7 @@ namespace LLInitParam  	public:  		Optional<std::string> name; -		ParamValue(LLUIImage* const& image) +		ParamValue(LLUIImage* const& image = NULL)  		:	super_t(image)  		{  			updateBlockFromValue(false); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index c75df86891..9cb6a89eee 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -113,7 +113,7 @@ namespace LLInitParam  		mEnclosingBlockOffset = (U16)(my_addr - block_addr);  	} -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){} +	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}  	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} @@ -127,14 +127,14 @@ namespace LLInitParam  	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)  	:	super_t(color)  	{} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()  +	void ParamValue<LLUIColor>::updateValueFromBlock()   	{} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool) +	void ParamValue<LLUIColor>::updateBlockFromValue(bool)  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -142,14 +142,14 @@ namespace LLInitParam  		return false;  	} -	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)  	:	super_t(fontp)  	{} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock() +	void ParamValue<const LLFontGL*>::updateValueFromBlock()  	{} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool) +	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -161,10 +161,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock() +	void ParamValue<LLUIImage*>::updateValueFromBlock()  	{} -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool) +	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)  	{} diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index 7183413463..36402f5b27 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -74,7 +74,7 @@ namespace LLInitParam  						S32 max_count){}  	ParamDescriptor::~ParamDescriptor() {} -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){} +	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}  	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {} @@ -97,14 +97,14 @@ namespace LLInitParam  	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)  	:	super_t(color)  	{} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() +	void ParamValue<LLUIColor>::updateValueFromBlock()  	{} -	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool) +	void ParamValue<LLUIColor>::updateBlockFromValue(bool)  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -113,14 +113,14 @@ namespace LLInitParam  	} -	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)  	:	super_t(fontp)  	{} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock() +	void ParamValue<const LLFontGL*>::updateValueFromBlock()  	{} -	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool) +	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -132,10 +132,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock() +	void ParamValue<LLUIImage*>::updateValueFromBlock()  	{} -	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool) +	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)  	{}  	bool ParamCompare<LLUIImage*, false>::equals( diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index db72aa19b9..3cf145cdde 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -112,6 +112,35 @@ namespace LLInitParam  		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));  	} +	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name) +	{ +		// create a copy of the param descriptor in mAllParams +		// so other data structures can store a pointer to it +		mAllParams.push_back(in_param); +		ParamDescriptorPtr param(mAllParams.back()); + +		std::string name(char_name); +		if ((size_t)param->mParamHandle > mMaxParamOffset) +		{ +			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl; +		} + +		if (name.empty()) +		{ +			mUnnamedParams.push_back(param); +		} +		else +		{ +			// don't use insert, since we want to overwrite existing entries +			mNamedParams[name] = param; +		} + +		if (param->mValidationFunc) +		{ +			mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc)); +		} +	} +  	BlockDescriptor::BlockDescriptor()  	:	mMaxParamOffset(0),  		mInitializationState(UNINITIALIZED), @@ -358,36 +387,6 @@ namespace LLInitParam  		return false;  	} -	//static  -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name) -	{ -		// create a copy of the param descriptor in mAllParams -		// so other data structures can store a pointer to it -		block_data.mAllParams.push_back(in_param); -		ParamDescriptorPtr param(block_data.mAllParams.back()); - -		std::string name(char_name); -		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset) -		{ -			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl; -		} - -		if (name.empty()) -		{ -			block_data.mUnnamedParams.push_back(param); -		} -		else -		{ -			// don't use insert, since we want to overwrite existing entries -			block_data.mNamedParams[name] = param; -		} - -		if (param->mValidationFunc) -		{ -			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc)); -		} -	} -  	void BaseBlock::addSynonym(Param& param, const std::string& synonym)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor(); diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 4ab1d891a3..2c854d8287 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -36,6 +36,71 @@  #include "llerror.h" +namespace LLTypeTags +{ +	template <typename INNER_TYPE, int _SORT_ORDER> +	struct TypeTagBase +	{ +		typedef void		is_tag_t; +		typedef INNER_TYPE	inner_t; +		static const int	SORT_ORDER=_SORT_ORDER; +	}; + +	template <int VAL1, int VAL2> +	struct GreaterThan +	{ +		static const bool value = VAL1 > VAL2; +	}; + +	template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value > +	struct Swap +	{ +		typedef typename ITEM::template Cons<REST>::value_t value_t; +	}; + +	template<typename ITEM, typename REST> +	struct Swap<ITEM, REST, true> +	{ +		typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t; +	}; + +	template<typename T, typename SORTABLE = void> +	struct IsSortable +	{ +		static const bool value = false; +	}; + +	template<typename T> +	struct IsSortable<T, typename T::is_tag_t> +	{ +		static const bool value = true; +	}; + +	template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value> +	struct InsertInto +	{ +		typedef typename ITEM::template Cons<REST>::value_t value_t; +	}; + +	template<typename ITEM, typename REST> +	struct InsertInto <ITEM, REST, true> +	{ +		typedef typename Swap<ITEM, REST>::value_t value_t; +	}; + +	template<typename T, bool SORTABLE = IsSortable<T>::value> +	struct Sorted +	{ +		typedef T value_t; +	}; + +	template<typename T> +	struct Sorted <T, true> +	{ +		typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t; +	}; +} +  namespace LLInitParam  {  	// used to indicate no matching value to a given name when parsing @@ -43,6 +108,8 @@ namespace LLInitParam  	template<typename T> const T& defaultValue() { static T value; return value; } +	// wraps comparison operator between any 2 values of the same type +	// specialize to handle cases where equality isn't defined well, or at all  	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >      struct ParamCompare   	{ @@ -77,24 +144,123 @@ namespace LLInitParam  	// helper functions and classes  	typedef ptrdiff_t param_handle_t; +	struct IS_A_BLOCK {}; +	struct NOT_BLOCK {}; + +	// these templates allow us to distinguish between template parameters +	// that derive from BaseBlock and those that don't +	template<typename T, typename BLOCK_IDENTIFIER = void> +	struct IsBlock +	{ +		typedef NOT_BLOCK value_t; +	}; + +	template<typename T> +	struct IsBlock<T, typename T::baseblock_base_class_t> +	{ +		typedef IS_A_BLOCK value_t; +	}; + +	// ParamValue class directly manages the wrapped value +	// by holding on to a copy (scalar params) +	// or deriving from it (blocks) +	// has specializations for custom value behavior +	// and "tag" values like Lazy and Atomic +	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t> +	class ParamValue +	{ +		typedef ParamValue<T, VALUE_IS_BLOCK>	self_t; + +	public: +		typedef T	default_value_t; +		typedef T	value_t; + +		ParamValue(): mValue() {} +		ParamValue(const default_value_t& other) : mValue(other) {} + +		void setValue(const value_t& val) +		{ +			mValue = val; +		} + +		const value_t& getValue() const +		{ +			return mValue; +		} + +		T& getValue() +		{ +			return mValue; +		} + +	protected: +		T mValue; +	}; + +	template<typename T> +	class ParamValue<T, IS_A_BLOCK>  +	:	public T +	{ +		typedef ParamValue<T, IS_A_BLOCK>	self_t; +	public: +		typedef T	default_value_t; +		typedef T	value_t; + +		ParamValue()  +		:	T(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& other) +			:	T(other), +			mValidated(false) +		{} + +		void setValue(const value_t& val) +		{ +			*this = val; +		} + +		const value_t& getValue() const +		{ +			return *this; +		} + +		T& getValue() +		{ +			return *this; +		} + +	protected: +		mutable bool 	mValidated; // lazy validation flag +	}; +  	// empty default implementation of key cache  	// leverages empty base class optimization  	template <typename T>  	class TypeValues +	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>  	{  	private:  		struct Inaccessable{};  	public:  		typedef std::map<std::string, T> value_name_map_t;  		typedef Inaccessable name_t; +		typedef TypeValues<T> type_value_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t; +		typedef typename param_value_t::value_t	value_t; + +		TypeValues(const typename param_value_t::value_t& val) +		:	param_value_t(val) +		{}  		void setValueName(const std::string& key) {}  		std::string getValueName() const { return ""; } -		std::string calcValueName(const T& value) const { return ""; } +		std::string calcValueName(const value_t& value) const { return ""; }  		void clearValueName() const {} -		static bool getValueFromName(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, value_t& value)  		{  			return false;  		} @@ -109,15 +275,39 @@ namespace LLInitParam  			return NULL;  		} +		void assignNamedValue(const Inaccessable& name) +		{} + +		operator const value_t&() const +		{ +			return param_value_t::getValue(); +		} + +		const value_t& operator()() const +		{ +			return param_value_t::getValue(); +		} +  		static value_name_map_t* getValueNames() {return NULL;}  	}; -	template <typename T, typename DERIVED_TYPE = TypeValues<T> > +	// helper class to implement name value lookups +	// and caching of last used name +	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >  	class TypeValuesHelper +	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>  	{ +		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;  	public:  		typedef typename std::map<std::string, T> value_name_map_t;  		typedef std::string name_t; +		typedef self_t type_value_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t; +		typedef typename param_value_t::value_t	value_t; + +		TypeValuesHelper(const typename param_value_t::value_t& val) +		:	param_value_t(val) +		{}  		//TODO: cache key by index to save on param block size  		void setValueName(const std::string& value_name)  @@ -130,7 +320,7 @@ namespace LLInitParam  			return mValueName;   		} -		std::string calcValueName(const T& value) const +		std::string calcValueName(const value_t& value) const  		{  			value_name_map_t* map = getValueNames();  			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end(); @@ -151,7 +341,7 @@ namespace LLInitParam  			mValueName.clear();  		} -		static bool getValueFromName(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, value_t& value)  		{  			value_name_map_t* map = getValueNames();  			typename value_name_map_t::iterator found_it = map->find(name); @@ -193,18 +383,90 @@ namespace LLInitParam  			return &sValues;  		} -		static void declare(const std::string& name, const T& value) +		static void declare(const std::string& name, const value_t& value)  		{  			(*getValueNames())[name] = value;  		} +		void operator ()(const std::string& name) +		{ +			*this = name; +		} + +		void assignNamedValue(const std::string& name) +		{ +			if (getValueFromName(name, param_value_t::getValue())) +			{ +				setValueName(name); +			} +		} + +		operator const value_t&() const +		{ +			return param_value_t::getValue(); +		} + +		const value_t& operator()() const +		{ +			return param_value_t::getValue(); +		} +  	protected: -		static void getName(const std::string& name, const T& value) +		static void getName(const std::string& name, const value_t& value)  		{}  		mutable std::string	mValueName;  	}; +	// string types can support custom named values, but need +	// to disambiguate in code between a string that is a named value +	// and a string that is a name +	template <typename DERIVED_TYPE> +	class TypeValuesHelper<std::string, DERIVED_TYPE, true> +	:	public TypeValuesHelper<std::string, DERIVED_TYPE, false> +	{ +	public: +		typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t; +		typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t; +		typedef std::string value_t; +		typedef std::string name_t; +		typedef self_t type_value_t; + +		TypeValuesHelper(const std::string& val) +		:	TypeValuesHelper(val) +		{} + +		void operator ()(const std::string& name) +		{ +			*this = name; +		} + +		self_t& operator =(const std::string& name) +		{ +			if (base_t::getValueFromName(name, ParamValue<std::string>::getValue())) +			{ +				base_t::setValueName(name); +			} +			else +			{ +				ParamValue<std::string>::setValue(name); +			} +			return *this; +		} +		 +		operator const value_t&() const +		{ +			return ParamValue<std::string>::getValue(); +		} + +		const value_t& operator()() const +		{ +			return ParamValue<std::string>::getValue(); +		} + +	}; + +	// parser base class with mechanisms for registering readers/writers/inspectors of different types  	class Parser  	{  		LOG_CLASS(Parser); @@ -354,6 +616,7 @@ namespace LLInitParam  		} EInitializationState;  		void aggregateBlockData(BlockDescriptor& src_block_data); +		void addParam(ParamDescriptorPtr param, const char* name);  		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t;   		typedef std::vector<ParamDescriptorPtr>													param_list_t;  @@ -369,48 +632,58 @@ namespace LLInitParam  		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed  	}; -	class BaseBlock -	{ -	public:  		//TODO: implement in terms of owned_ptr  		template<typename T> -		class Lazy +	class LazyValue  		{  		public: -			Lazy() +		LazyValue()  				: mPtr(NULL)  			{} -			~Lazy() +		~LazyValue()  			{  				delete mPtr;  			} -			Lazy(const Lazy& other) +		LazyValue(const T& value)  			{ -				if (other.mPtr) +			mPtr = new T(value); +		} + +		LazyValue(const LazyValue& other) +		:	mPtr(NULL)  				{ -					mPtr = new T(*other.mPtr); +			*this = other;  				} -				else + +		LazyValue& operator = (const LazyValue& other) +		{ +			if (!other.mPtr)  				{ +				delete mPtr;  					mPtr = NULL;  				} -			} - -			Lazy<T>& operator = (const Lazy<T>& other) +			else  			{ -				if (other.mPtr) +				if (!mPtr)  				{  					mPtr = new T(*other.mPtr);  				}  				else  				{ -					mPtr = NULL; +					*mPtr = *(other.mPtr); +				}  				}  				return *this;  			} +		bool operator==(const LazyValue& other) const +		{ +			if (empty() || other.empty()) return false; +			return *mPtr == *other.mPtr; +		} +  			bool empty() const  			{  				return mPtr == NULL; @@ -418,18 +691,29 @@ namespace LLInitParam  			void set(const T& other)  			{ -				delete mPtr; +			if (!mPtr) +			{  				mPtr = new T(other);  			} +			else +			{ +				*mPtr = other; +			} +		}  			const T& get() const  			{ -				return ensureInstance(); +			return *ensureInstance();  			}  			T& get()  			{ -				return ensureInstance(); +			return *ensureInstance(); +		} + +		operator const T&() const +		{  +			return get();   			}  		private: @@ -444,13 +728,50 @@ namespace LLInitParam  			}  		private: -			// if you get a compilation error with this, that means you are using a forward declared struct for T -			// unfortunately, the type traits we rely on don't work with forward declared typed -			//static const int dummy = sizeof(T);  			mutable T* mPtr;  		}; +	// root class of all parameter blocks + +	class BaseBlock +	{ +	public: +		// lift block tags into baseblock namespace so derived classes do not need to qualify them +		typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK; +		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK; + +		template<typename T> +		struct Sequential : public LLTypeTags::TypeTagBase<T, 2> +		{ +			template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; }; +			template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; }; +		}; + +		template<typename T> +		struct Atomic : public LLTypeTags::TypeTagBase<T, 1> +		{ +			template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; }; +			template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; }; +		}; + +		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t > +		struct Lazy : public LLTypeTags::TypeTagBase<T, 0> +		{ +			template <typename S> struct Cons +			{ +				typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t; +			}; +			template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> > +			{ +				typedef Lazy<S, IS_A_BLOCK> value_t; +			}; +			template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> > +			{ +				typedef Lazy<S, BLOCK_T> value_t; +			}; +		}; +  		// "Multiple" constraint types, put here in root class to avoid ambiguity during use  		struct AnyAmount  		{ @@ -520,8 +841,8 @@ namespace LLInitParam  		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const; -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  		// take all provided params from other and apply to self  		bool overwriteFrom(const BaseBlock& other) @@ -535,10 +856,17 @@ namespace LLInitParam  			return false;  		} -		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name); -  		ParamDescriptorPtr findParamDescriptor(const Param& param); +		// take all provided params from other and apply to self +		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); + +		static BlockDescriptor& getBlockDescriptor() +		{ +			static BlockDescriptor sBlockDescriptor; +			return sBlockDescriptor; +		} +  	protected:  		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size); @@ -547,25 +875,11 @@ namespace LLInitParam  		{  			return mergeBlock(block_data, source, overwrite);  		} -		// take all provided params from other and apply to self -		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); - -		static BlockDescriptor& selfBlockDescriptor() -		{ -			static BlockDescriptor sBlockDescriptor; -			return sBlockDescriptor; -		}  	private:  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;  	}; -	template<typename T> -	struct ParamCompare<BaseBlock::Lazy<T>, false > -	{ -		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); } -	}; -  	class Param  	{  	public: @@ -605,240 +919,45 @@ namespace LLInitParam  	}; -	// these templates allow us to distinguish between template parameters -	// that derive from BaseBlock and those that don't -	template<typename T, typename Void = void> -	struct IsBlock -	{ -		static const bool value = false; -		struct EmptyBase {}; -		typedef EmptyBase base_class_t; -	}; - -	template<typename T> -	struct IsBlock<T, typename T::baseblock_base_class_t> -	{ -		static const bool value = true; -		typedef BaseBlock base_class_t; -	}; - -	template<typename T> -	struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t > -	{ -		static const bool value = true; -		typedef BaseBlock base_class_t; -	}; - -	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value> -	class ParamValue : public NAME_VALUE_LOOKUP -	{ -	public: -		typedef const T&							value_assignment_t; -		typedef T									value_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t; - -		ParamValue(): mValue() {} -		ParamValue(value_assignment_t other) : mValue(other) {} - -		void setValue(value_assignment_t val) -		{ -			mValue = val; -		} - -		value_assignment_t getValue() const -		{ -			return mValue; -		} - -		T& getValue() -		{ -			return mValue; -		} - -		operator value_assignment_t() const -		{ -			return mValue; -		} - -		value_assignment_t operator()() const -		{ -			return mValue; -		} - -		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			*this = name; -		} - -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue)) -			{ -				setValueName(name); -			} - -			return *this; -		} - -	protected: -		T mValue; -	}; - -	template<typename T, typename NAME_VALUE_LOOKUP> -	class ParamValue<T, NAME_VALUE_LOOKUP, true>  -	:	public T, -		public NAME_VALUE_LOOKUP -	{ -	public: -		typedef const T&							value_assignment_t; -		typedef T									value_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP, true>	self_t; - -		ParamValue()  -		:	T(), -			mValidated(false) -		{} - -		ParamValue(value_assignment_t other) -		:	T(other), -			mValidated(false) -		{} - -		void setValue(value_assignment_t val) -		{ -			*this = val; -		} - -		value_assignment_t getValue() const -		{ -			return *this; -		} - -		T& getValue() -		{ -			return *this; -		} - -		operator value_assignment_t() const -		{ -			return *this; -		} -		 -		value_assignment_t operator()() const -		{ -			return *this; -		} - -		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			*this = name; -		} - -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(name, *this)) -			{ -				setValueName(name); -			} - -			return *this; -		} - -	protected: -		mutable bool 	mValidated; // lazy validation flag -	}; - -	template<typename NAME_VALUE_LOOKUP> -	class ParamValue<std::string, NAME_VALUE_LOOKUP, false> -	: public NAME_VALUE_LOOKUP -	{ -	public: -		typedef const std::string&	value_assignment_t; -		typedef std::string			value_t; -		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false>	self_t; - -		ParamValue(): mValue() {} -		ParamValue(value_assignment_t other) : mValue(other) {} - -		void setValue(value_assignment_t val) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue)) -			{ -				NAME_VALUE_LOOKUP::setValueName(val); -			} -			else -			{ -				mValue = val; -			} -		} - -		value_assignment_t getValue() const -		{ -			return mValue; -		} - -		std::string& getValue() -		{ -			return mValue; -		} - -		operator value_assignment_t() const -		{ -			return mValue; -		} - -		value_assignment_t operator()() const -		{ -			return mValue; -		} - -	protected: -		std::string mValue; -	}; - -  	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >  	struct ParamIterator  	{ -		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator; -		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator	const_iterator; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator			iterator;  	}; -	// specialize for custom parsing/decomposition of specific classes -	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc... +	// wrapper for parameter with a known type +	// specialized to handle 4 cases: +	// simple "scalar" value +	// parameter that is itself a block +	// multiple scalar values, stored in a vector +	// multiple blocks, stored in a vector  	template<typename	T,  			typename	NAME_VALUE_LOOKUP = TypeValues<T>,  			bool		HAS_MULTIPLE_VALUES = false, -			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> +			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>  	class TypedParam   	:	public Param,  -		public ParamValue<T, NAME_VALUE_LOOKUP> +		public NAME_VALUE_LOOKUP::type_value_t  	{ +	protected: +		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>						param_value_t; +		typedef typename param_value_t::default_value_t									default_value_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;  	public: -		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t; -		typedef typename param_value_t::value_assignment_t				value_assignment_t; -		typedef NAME_VALUE_LOOKUP															name_value_lookup_t; +		typedef typename param_value_t::value_t											value_t; -		using param_value_t::operator(); +		using named_value_t::operator(); -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  -		:	Param(block_descriptor.mCurrentBlockPtr) +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) +		:	Param(block_descriptor.mCurrentBlockPtr), +			named_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ - 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			} - -			setValue(value);  		}   		bool isProvided() const { return Param::anyProvided(); } @@ -857,14 +976,15 @@ namespace LLInitParam  				}  				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist()) +				if(named_value_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue())) + +						if (named_value_t::getValueFromName(name, typed_param.getValue()))  						{  							typed_param.setValueName(name);  							typed_param.setProvided(); @@ -917,22 +1037,23 @@ namespace LLInitParam  			// tell parser about our actual type  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);  			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) -			if (name_value_lookup_t::getPossibleValues()) +			if (named_value_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const value_t& val, bool flag_as_provided = true)  		{ -			param_value_t::clearValueName(); +			named_value_t::clearValueName();  			setValue(val);  			setProvided(flag_as_provided);  		} -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) +		self_t& operator =(const typename named_value_t::name_t& name)  		{ -			return static_cast<self_t&>(param_value_t::operator =(name)); +			named_value_t::assignNamedValue(name); +			return *this;  		}  	protected: @@ -957,37 +1078,43 @@ namespace LLInitParam  			}  			return false;  		} +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	// parameter that is a block  	template <typename T, typename NAME_VALUE_LOOKUP> -	class TypedParam<T, NAME_VALUE_LOOKUP, false, true>  +	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>   	:	public Param, -		public ParamValue<T, NAME_VALUE_LOOKUP> +		public NAME_VALUE_LOOKUP::type_value_t  	{ +	protected: +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t; +		typedef typename param_value_t::default_value_t				default_value_t; +		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;  	public: -		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t; -		typedef typename param_value_t::value_assignment_t		value_assignment_t; -		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t; -		typedef NAME_VALUE_LOOKUP								name_value_lookup_t; - -		using param_value_t::operator(); +		using named_value_t::operator(); +		typedef typename param_value_t::value_t						value_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr), -			param_value_t(value) +			named_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func,  -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			}  		} @@ -1002,14 +1129,14 @@ namespace LLInitParam  				return true;  			} -			if(name_value_lookup_t::valueNamesExist()) +			if(named_value_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue())) +					if (named_value_t::getValueFromName(name, typed_param.getValue()))  					{  						typed_param.setValueName(name);  						typed_param.setProvided(); @@ -1034,9 +1161,9 @@ namespace LLInitParam  			std::string key = typed_param.getValueName();  			if (!key.empty())  			{ -				if (!parser.writeValue(key, name_stack)) +				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{ -					return; +					parser.writeValue(key, name_stack);  				}  			}  			else @@ -1047,8 +1174,16 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{ -			// I am a param that is also a block, so just recurse into my contents  			const self_t& typed_param = static_cast<const self_t&>(param); + +			// tell parser about our actual type +			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL); +			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) +			if (named_value_t::getPossibleValues()) +			{ +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues()); +			} +  			typed_param.inspectBlock(parser, name_stack, min_count, max_count);  		} @@ -1066,32 +1201,34 @@ namespace LLInitParam  		}  		// assign block contents to this param-that-is-a-block -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const value_t& val, bool flag_as_provided = true)  		{  			setValue(val); -			param_value_t::clearValueName(); +			named_value_t::clearValueName();  			// force revalidation of block  			// next call to isProvided() will update provision status based on validity  			param_value_t::mValidated = false;  			setProvided(flag_as_provided);  		} -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) +		self_t& operator =(const typename named_value_t::name_t& name)  		{ -			return static_cast<self_t&>(param_value_t::operator =(name)); +			named_value_t::assignNamedValue(name); +			return *this;  		}  		// propagate changed status up to enclosing block  		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{   			param_value_t::paramChanged(changed_param, user_provided); +  			if (user_provided)  			{  				// a child param has been explicitly changed  				// so *some* aspect of this block is now provided  				param_value_t::mValidated = false;  				setProvided(); -				param_value_t::clearValueName(); +				named_value_t::clearValueName();  			}  			else  			{ @@ -1115,7 +1252,7 @@ namespace LLInitParam  			if (src_typed_param.anyProvided())  			{ -				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite)) +				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))  				{  					dst_typed_param.clearValueName();  					dst_typed_param.setProvided(true); @@ -1124,38 +1261,46 @@ namespace LLInitParam  			}  			return false;  		} + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func,  +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	// container of non-block parameters  	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>  +	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>   	:	public Param  	{ +	protected: +		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t; +		typedef container_t														default_value_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t; +		  	public: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t; -		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t; -		typedef typename std::vector<param_value_t>							container_t; -		typedef const container_t&											value_assignment_t; -  		typedef typename param_value_t::value_t								value_t; -		typedef NAME_VALUE_LOOKUP											name_value_lookup_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			std::copy(value.begin(), value.end(), std::back_inserter(mValues));  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name); +  			}  		}  @@ -1176,14 +1321,14 @@ namespace LLInitParam  				}  				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist()) +				if(named_value_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (name_value_lookup_t::getValueFromName(name, value)) +						if (named_value_t::getValueFromName(name, value))  						{  							typed_param.add(value);  							typed_param.mValues.back().setValueName(name); @@ -1234,13 +1379,13 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL); -			if (name_value_lookup_t::getPossibleValues()) +			if (named_value_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const container_t& val, bool flag_as_provided = true)  		{  			mValues = val;  			setProvided(flag_as_provided); @@ -1248,26 +1393,24 @@ namespace LLInitParam  		param_value_t& add()  		{ -			mValues.push_back(param_value_t(value_t())); +			mValues.push_back(value_t());  			Param::setProvided();  			return mValues.back();  		}  		self_t& add(const value_t& item)  		{ -			param_value_t param_value; -			param_value.setValue(item); -			mValues.push_back(param_value); +			mValues.push_back(item);  			setProvided();  			return *this;  		} -		self_t& add(const typename name_value_lookup_t::name_t& name) +		self_t& add(const typename named_value_lookup_t::name_t& name)  		{  			value_t value;  			// try to parse a per type named value -			if (name_value_lookup_t::getValueFromName(name, value)) +			if (named_value_t::getValueFromName(name, value))  			{  				add(value);  				mValues.back().setValueName(name); @@ -1277,9 +1420,9 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return mValues; }  +		operator const container_t&() const { return mValues; }   		// explicit conversion		 -		value_assignment_t operator()() const { return mValues; } +		const container_t& operator()() const { return mValues; }  		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1320,37 +1463,46 @@ namespace LLInitParam  		}  		container_t		mValues; + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	// container of block parameters  	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>  +	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>   	:	public Param  	{ +	protected: +		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t; +		typedef container_t														default_value_t; +		typedef typename container_t::iterator									iterator; +		typedef typename container_t::const_iterator							const_iterator;  	public: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t; -		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t; -		typedef typename std::vector<param_value_t>						container_t; -		typedef const container_t&										value_assignment_t;  		typedef typename param_value_t::value_t							value_t; -		typedef NAME_VALUE_LOOKUP										name_value_lookup_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			std::copy(value.begin(), value.end(), back_inserter(mValues));  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			}  		}  @@ -1375,14 +1527,14 @@ namespace LLInitParam  				typed_param.setProvided();  				return true;  			} -			else if(name_value_lookup_t::valueNamesExist()) +			else if(named_value_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (name_value_lookup_t::getValueFromName(name, value.getValue())) +					if (named_value_t::getValueFromName(name, value.getValue()))  					{  						typed_param.mValues.back().setValueName(name);  						typed_param.setProvided(); @@ -1427,11 +1579,20 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{ -			// I am a vector of blocks, so describe my contents recursively -			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count); +			const param_value_t& value_param = param_value_t(value_t()); + +			// tell parser about our actual type +			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL); +			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) +			if (named_value_t::getPossibleValues()) +			{ +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues()); +		} + +			value_param.inspectBlock(parser, name_stack, min_count, max_count);  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const container_t& val, bool flag_as_provided = true)  		{  			mValues = val;  			setProvided(flag_as_provided); @@ -1451,12 +1612,12 @@ namespace LLInitParam  			return *this;  		} -		self_t& add(const typename name_value_lookup_t::name_t& name) +		self_t& add(const typename named_value_lookup_t::name_t& name)  		{  			value_t value;  			// try to parse a per type named value -			if (name_value_lookup_t::getValueFromName(name, value)) +			if (named_value_t::getValueFromName(name, value))  			{  				add(value);  				mValues.back().setValueName(name); @@ -1465,12 +1626,10 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return mValues; }  +		operator const container_t&() const { return mValues; }   		// explicit conversion -		value_assignment_t operator()() const { return mValues; } +		const container_t& operator()() const { return mValues; } -		typedef typename container_t::iterator iterator; -		typedef typename container_t::const_iterator const_iterator;  		iterator begin() { return mValues.begin(); }  		iterator end() { return mValues.end(); }  		const_iterator begin() const { return mValues.begin(); } @@ -1517,6 +1676,20 @@ namespace LLInitParam  		}  		container_t			mValues; + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> @@ -1531,13 +1704,13 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);  		}  		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite) @@ -1555,7 +1728,7 @@ namespace LLInitParam  		bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)  		{  			mCurChoice = other.mCurChoice; -			return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite); +			return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);  		}  		// clear out old choice when param has changed @@ -1576,38 +1749,38 @@ namespace LLInitParam  			base_block_t::paramChanged(changed_param, user_provided);  		} -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  	protected:  		ChoiceBlock()  		:	mCurChoice(0)  		{ -			BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK)); +			BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));  		}  		// Alternatives are mutually exclusive wrt other Alternatives in the same block.    		// One alternative in a block will always have isChosen() == true.  		// At most one alternative in a block will have isProvided() == true. -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t; +			typedef typename super_t::value_t				value_t; +			typedef typename super_t::default_value_t		default_value_t; +  		public:  			friend class ChoiceBlock<DERIVED_BLOCK>; -			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t; -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; -  			using super_t::operator =; -			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), +			explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),  				mOriginalValue(val)  			{  				// assign initial choice to first declared option -				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr); -				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING)) +				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr); +				if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))  				{  					if(blockp->mCurChoice == 0)  					{ @@ -1621,27 +1794,27 @@ namespace LLInitParam  				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);  			} -			void chooseAs(value_assignment_t val) +			void chooseAs(const value_t& val)  			{  				super_t::set(val);  			} -			void operator =(value_assignment_t val) +			void operator =(const value_t& val)  			{  				super_t::set(val);  			} -			void operator()(typename super_t::value_assignment_t val)  +			void operator()(const value_t& val)   			{   				super_t::set(val);  			} -			operator value_assignment_t() const  +			operator const value_t&() const   			{  				return (*this)();  			}  -			value_assignment_t operator()() const  +			const value_t& operator()() const   			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ @@ -1656,11 +1829,11 @@ namespace LLInitParam  			}  		private: -			T			mOriginalValue; +			default_value_t mOriginalValue;  		}; -	protected: -		static BlockDescriptor& selfBlockDescriptor() +	public: +		static BlockDescriptor& getBlockDescriptor()  		{  			static BlockDescriptor sBlockDescriptor;  			return sBlockDescriptor; @@ -1680,6 +1853,8 @@ namespace LLInitParam  	:	public BASE_BLOCK  	{  		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t; + +	protected:  		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;  	public: @@ -1688,80 +1863,82 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);  		} -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  	protected:  		Block()  		{  			//#pragma message("Parsing LLInitParam::Block") -			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK)); +			BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));  		}  		//  		// Nested classes for declaring parameters  		// -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t; +			typedef typename super_t::value_t					value_t; +			typedef typename super_t::default_value_t			default_value_t; +		public:  			using super_t::operator();  			using super_t::operator =; -			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1) +			explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)  			{  				//#pragma message("Parsing LLInitParam::Block::Optional")  			} -			Optional& operator =(value_assignment_t val) +			Optional& operator =(const value_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(value_assignment_t val) +			DERIVED_BLOCK& operator()(const value_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());  			}  		}; -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;  			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; +			typedef typename super_t::value_t					value_t; +			typedef typename super_t::default_value_t			default_value_t; +		public:  			using super_t::operator();  			using super_t::operator =;  			// mandatory parameters require a name to be parseable -			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1) +			explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)  			{} -			Mandatory& operator =(value_assignment_t val) +			Mandatory& operator =(const value_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(const value_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1775,28 +1952,29 @@ namespace LLInitParam  		}; -		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;  			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;  			typedef typename super_t::container_t									container_t; -			typedef typename super_t::value_assignment_t							value_assignment_t; +			typedef typename super_t::value_t				value_t; + +		public:  			typedef typename super_t::iterator										iterator;  			typedef typename super_t::const_iterator								const_iterator;  			explicit Multiple(const char* name = "") -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)  			{} -			Multiple& operator =(value_assignment_t val) +			Multiple& operator =(const container_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(const container_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1813,9 +1991,9 @@ namespace LLInitParam  		{  		public:  			explicit Deprecated(const char* name) -			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr) +			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)  			{ -				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();  				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  				{  					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( @@ -1826,7 +2004,7 @@ namespace LLInitParam  													NULL,  													NULL,   													0, S32_MAX)); -					BaseBlock::addParam(block_descriptor, param_descriptor, name); +					block_descriptor.addParam(param_descriptor, name);  				}  			} @@ -1846,16 +2024,17 @@ namespace LLInitParam  		// different semantics for documentation purposes, but functionally identical  		typedef Deprecated Ignored; -	protected: -		static BlockDescriptor& selfBlockDescriptor() +	public: +		static BlockDescriptor& getBlockDescriptor()  		{  			static BlockDescriptor sBlockDescriptor;  			return sBlockDescriptor;  		} -		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block> +	protected: +		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>  		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,  -			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value) +			const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)  		{  			if (!param.isProvided())  			{ @@ -1865,202 +2044,414 @@ namespace LLInitParam  	}; -	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> -	class BatchBlock -	:	public Block<DERIVED_BLOCK, BASE_BLOCK> +	template<typename T, typename BLOCK_T> +	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void> +	{ +		typedef IS_A_BLOCK value_t; +	}; + +	template<typename T, typename BLOCK_T> +	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void> +	{ +		typedef NOT_BLOCK value_t; +	}; + +	template<typename T, typename BLOCK_IDENTIFIER> +	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER> +	{ +		typedef typename IsBlock<T>::value_t value_t; +	}; + +	template<typename T, typename BLOCK_IDENTIFIER> +	struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>  	{ +		typedef typename IsBlock<T>::value_t value_t; +	}; + + +	template<typename T> +	struct InnerMostType +	{ +		typedef T value_t; +	}; + +	template<typename T> +	struct InnerMostType<ParamValue<T, NOT_BLOCK> > +	{ +		typedef typename InnerMostType<T>::value_t value_t; +	}; + +	template<typename T> +	struct InnerMostType<ParamValue<T, IS_A_BLOCK> > +	{ +		typedef typename InnerMostType<T>::value_t value_t; +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Atomic<T>, BLOCK_T> +	{ +		typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t; +  	public: -		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t; -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t; -		BatchBlock() +		ParamValue() +		:	mValue(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& value) +		:	mValue(value), +			mValidated(false)  		{} +		void setValue(const value_t& val) +		{ +			mValue.setValue(val); +		} + +		const value_t& getValue() const +		{ +			return mValue.getValue(); +		} + +		value_t& getValue() +		{ +			return mValue.getValue(); +		} +  		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)  		{  			if (new_name)  			{ -				// reset block -				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); +				resetToDefault(); +			} +			return mValue.deserializeBlock(p, name_stack_range, new_name);  			} -			return super_t::deserializeBlock(p, name_stack_range, new_name); + +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const +		{ +			const BaseBlock* base_block = diff_block +				? &(diff_block->mValue) +				: NULL; +			mValue.serializeBlock(p, name_stack, base_block); +		} + +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		{ +			return mValue.inspectBlock(p, name_stack, min_count, max_count);  		} -		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)  		{  			if (overwrite)  			{ -				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); -				// merge individual parameters into destination -				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite); +				resetToDefault(); +				return mValue.mergeBlock(block_data, source.getValue(), overwrite);  			}  			return false;  		} -	protected: -		static const DERIVED_BLOCK& defaultBatchValue() + +		bool validateBlock(bool emit_errors = true) const +		{ +			return mValue.validateBlock(emit_errors); +		} + +		static BlockDescriptor& getBlockDescriptor() +		{ +			return value_t::getBlockDescriptor(); +		} + + +		mutable bool 	mValidated; // lazy validation flag + +	private: +		void resetToDefault()  		{ -			static DERIVED_BLOCK default_value; -			return default_value; +			static T default_value; +			mValue = default_value;  		} + +		T	mValue;  	}; -	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class -	// and not the derived class with the actual params -	template<typename DERIVED_BLOCK, -			typename BASE_BLOCK, -			typename NAME_VALUE_LOOKUP> -	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>, -					NAME_VALUE_LOOKUP, -					true> -	:	public NAME_VALUE_LOOKUP, -		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK> +	template<typename T> +	class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>  	{ +		typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t; +  	public: -		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t; -		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t; -		typedef block_t value_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t;  		ParamValue() -		:	block_t(), +		:	mValue(),  			mValidated(false) -		{} +		{ +			mCurParam = getBlockDescriptor().mAllParams.begin(); +		} -		ParamValue(value_assignment_t other) -		:	block_t(other), +		ParamValue(const default_value_t& value) +		:	mValue(value),  			mValidated(false)  		{ +			mCurParam = getBlockDescriptor().mAllParams.begin();  		} -		void setValue(value_assignment_t val) +		void setValue(const value_t& val)  		{ -			*this = val; +			mValue.setValue(val);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{ -			return *this; +			return mValue.getValue();  		} -		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue() +		value_t& getValue()  		{ -			return *this; +			return mValue.getValue();  		} -		operator value_assignment_t() const +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)  		{ -			return *this; +			if (new_name) +			{ +				mCurParam = getBlockDescriptor().mAllParams.begin(); +			} +			if (name_stack_range.first == name_stack_range.second  +				&& mCurParam != getBlockDescriptor().mAllParams.end()) +			{ +				// deserialize to mCurParam +				ParamDescriptor& pd = *(*mCurParam); +				ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc; +				Param* paramp = mValue.getParamFromHandle(pd.mParamHandle); + +				if (deserialize_func  +					&& paramp  +					&& deserialize_func(*paramp, p, name_stack_range, new_name)) +				{ +					++mCurParam; +					return true; +				} +				else +				{ +					return false; +				} +			} +			else +			{ +				return mValue.deserializeBlock(p, name_stack_range, new_name); +			}  		} -		value_assignment_t operator()() const +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const  		{ -			return *this; +			const BaseBlock* base_block = diff_block +				? &(diff_block->mValue) +				: NULL; +			mValue.serializeBlock(p, name_stack, base_block); +		} + +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		{ +			return mValue.inspectBlock(p, name_stack, min_count, max_count); +		} + +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite) +		{ +			return mValue.mergeBlock(block_data, source.getValue(), overwrite); +		} + +		bool validateBlock(bool emit_errors = true) const +		{ +			return mValue.validateBlock(emit_errors); +		} + +		static BlockDescriptor& getBlockDescriptor() +		{ +			return value_t::getBlockDescriptor();  		} -	protected:  		mutable bool 	mValidated; // lazy validation flag + +	private: + +		BlockDescriptor::all_params_list_t::iterator	mCurParam; +		T												mValue;  	}; -	template<typename T, bool IS_BLOCK> -	class ParamValue <BaseBlock::Lazy<T>, -					TypeValues<T>, -					IS_BLOCK> -	:	public IsBlock<T>::base_class_t +	template<typename T> +	class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> +	: public T  	{ +		typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t; +  	public: -		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t; -		typedef const T& value_assignment_t; -		typedef T value_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t; + +		ParamValue() +		:	T(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& value) +		:	T(value.getValue()), +			mValidated(false) +		{} + +		mutable bool 	mValidated; // lazy validation flag +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T>  +	{ +		typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t; + +	public: +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef LazyValue<T>						default_value_t;  		ParamValue()  		:	mValue(),  			mValidated(false)  		{} -		ParamValue(value_assignment_t other) +		ParamValue(const default_value_t& other)  		:	mValue(other),  			mValidated(false)  		{} -		void setValue(value_assignment_t val) +		ParamValue(const T& value) +		:	mValue(value), +			mValidated(false) +		{} + +		void setValue(const value_t& val)  		{  			mValue.set(val);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{ -			return mValue.get(); +			return mValue.get().getValue();  		} -		T& getValue() +		value_t& getValue() +		{ +			return mValue.get().getValue(); +		} + +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)  		{ -			return mValue.get(); +			return mValue.get().deserializeBlock(p, name_stack_range, new_name);  		} -		operator value_assignment_t() const +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const  		{ -			return mValue.get(); +			if (mValue.empty()) return; +			 +			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty()) +											? &(diff_block->mValue.get().getValue()) +											: NULL; +			mValue.get().serializeBlock(p, name_stack, base_block);  		} -		value_assignment_t operator()() const +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{ -			return mValue.get(); +			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);  		} -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name) +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)  		{ -			return mValue.get().deserializeBlock(p, name_stack_range, new_name); +			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);  		} -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const +		bool validateBlock(bool emit_errors = true) const  		{ -			if (mValue.empty()) return; +			return mValue.empty() || mValue.get().validateBlock(emit_errors); +		} + +		static BlockDescriptor& getBlockDescriptor() +		{ +			return value_t::getBlockDescriptor(); +		} + +		mutable bool 	mValidated; // lazy validation flag + +	private: +		LazyValue<T>	mValue; +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> +		{ +		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t; + +	public: +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef LazyValue<T>						default_value_t; + +		ParamValue() +		:	mValue(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& other) +		:	mValue(other), +			mValidated(false) +		{} + +		ParamValue(const T& value) +		:	mValue(value), +			mValidated(false) +		{} -			mValue.get().serializeBlock(p, name_stack, diff_block); +		void setValue(const value_t& val) +		{ +			mValue.set(val);  		} -		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		const value_t& getValue() const  		{ -			if (mValue.empty()) return false; +			return mValue.get().getValue(); +		} -			return mValue.get().inspectBlock(p, name_stack, min_count, max_count); +		value_t& getValue() +		{ +			return mValue.get().getValue();  		} -	protected:  		mutable bool 	mValidated; // lazy validation flag  	private: -		BaseBlock::Lazy<T>	mValue; +		LazyValue<T>	mValue;  	};  	template <> -	class ParamValue <LLSD, -					TypeValues<LLSD>, -					false> -	:	public TypeValues<LLSD>, -		public BaseBlock +	class ParamValue <LLSD, NOT_BLOCK> +	:	public BaseBlock  	{  	public: -		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t; -		typedef const LLSD&	value_assignment_t; +		typedef LLSD			value_t; +		typedef LLSD			default_value_t;  		ParamValue()  		:	mValidated(false)  		{} -		ParamValue(value_assignment_t other) +		ParamValue(const default_value_t& other)  		:	mValue(other),  			mValidated(false)  		{} -		void setValue(value_assignment_t val) { mValue = val; } +		void setValue(const value_t& val) { mValue = val; } -		value_assignment_t getValue() const { return mValue; } +		const value_t& getValue() const { return mValue; }  		LLSD& getValue() { return mValue; } -		operator value_assignment_t() const { return mValue; } -		value_assignment_t operator()() const { return mValue; } -		 -  		// block param interface  		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);  		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const; @@ -2081,8 +2472,7 @@ namespace LLInitParam  	template<typename T>  	class CustomParamValue -	:	public Block<ParamValue<T, TypeValues<T> > >, -		public TypeValues<T> +	:	public Block<ParamValue<T> >  	{  	public:  		typedef enum e_value_age @@ -2092,14 +2482,15 @@ namespace LLInitParam  			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative  		} EValueAge; -		typedef ParamValue<T, TypeValues<T> >	derived_t; +		typedef ParamValue<T>			derived_t;  		typedef CustomParamValue<T>				self_t;  		typedef Block<derived_t>				block_t; -		typedef const T&						value_assignment_t; +		typedef T						default_value_t;  		typedef T								value_t; +		typedef void					baseblock_base_class_t; -		CustomParamValue(const T& value = T()) +		CustomParamValue(const default_value_t& value = T())  		:	mValue(value),  			mValueAge(VALUE_AUTHORITATIVE),  			mValidated(false) @@ -2116,8 +2507,6 @@ namespace LLInitParam  					typed_param.mValueAge = VALUE_AUTHORITATIVE;  					typed_param.updateBlockFromValue(false); -					typed_param.clearValueName(); -  					return true;  				}  			} @@ -2131,18 +2520,8 @@ namespace LLInitParam  			const derived_t& typed_param = static_cast<const derived_t&>(*this);  			const derived_t* diff_param = static_cast<const derived_t*>(diff_block); -			std::string key = typed_param.getValueName(); - -			// first try to write out name of name/value pair -			if (!key.empty()) -			{ -				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key)) -				{ -					parser.writeValue(key, name_stack); -				} -			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue())) +			if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))              {  				if (!parser.writeValue(typed_param.getValue(), name_stack))  @@ -2172,19 +2551,6 @@ namespace LLInitParam  			}  		} -		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const -		{ -			// first, inspect with actual type... -			parser.inspectValue<T>(name_stack, min_count, max_count, NULL); -			if (TypeValues<T>::getPossibleValues()) -			{ -				//...then inspect with possible string values... -				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues()); -			} -			// then recursively inspect contents... -			return block_t::inspectBlock(parser, name_stack, min_count, max_count); -		} -  		bool validateBlock(bool emit_errors = true) const  		{  			if (mValueAge == VALUE_NEEDS_UPDATE) @@ -2192,7 +2558,6 @@ namespace LLInitParam  				if (block_t::validateBlock(emit_errors))  				{  					// clear stale keyword associated with old value -					TypeValues<T>::clearValueName();  					mValueAge = BLOCK_AUTHORITATIVE;  					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();  					return true; @@ -2222,17 +2587,15 @@ namespace LLInitParam  			}  		} -		void setValue(value_assignment_t val) +		void setValue(const value_t& val)  		{ -			derived_t& typed_param = static_cast<derived_t&>(*this);  			// set param version number to be up to date, so we ignore block contents  			mValueAge = VALUE_AUTHORITATIVE;  			mValue = val; -			typed_param.clearValueName();  			static_cast<derived_t*>(this)->updateBlockFromValue(false);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{  			validateBlock(true);  			return mValue; @@ -2244,20 +2607,10 @@ namespace LLInitParam  			return mValue;  		} -		operator value_assignment_t() const -		{ -			return getValue(); -		} - -		value_assignment_t operator()() const -		{ -			return getValue(); -		} -  	protected:  		// use this from within updateValueFromBlock() to set the value without making it authoritative -		void updateValue(value_assignment_t value) +		void updateValue(const value_t& value)  		{  			mValue = value;  		} diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index afc76024d1..9cd88a1620 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -42,7 +42,7 @@  #include <boost/spirit/include/classic_core.hpp>  #include "lluicolor.h" - +#include "v3math.h"  using namespace BOOST_SPIRIT_CLASSIC_NS;  const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; @@ -79,7 +79,6 @@ struct Occurs : public LLInitParam::Block<Occurs>  	{}  }; -  typedef enum  {  	USE_REQUIRED, @@ -101,14 +100,23 @@ namespace LLInitParam  struct Element;  struct Group; -struct Choice;  struct Sequence; -struct Any; + +struct All : public LLInitParam::Block<All, Occurs> +{ +	Multiple< Lazy<Element, IS_A_BLOCK> > elements; + +	All() +	:	elements("element") +	{ +		maxOccurs = 1; +	} +};  struct Attribute : public LLInitParam::Block<Attribute>  { -	Mandatory<std::string>	name; -	Mandatory<std::string>	type; +	Mandatory<std::string>	name, +							type;  	Mandatory<EUse>			use;  	Attribute() @@ -127,24 +135,13 @@ struct Any : public LLInitParam::Block<Any, Occurs>  	{}  }; -struct All : public LLInitParam::Block<All, Occurs> -{ -	Multiple< Lazy<Element> > elements; - -	All() -	:	elements("element") -	{ -		maxOccurs = 1; -	} -}; -  struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>  { -	Alternative< Lazy<Element> >	element; -	Alternative< Lazy<Group> >		group; -	Alternative< Lazy<Choice> >		choice; -	Alternative< Lazy<Sequence> >	sequence; -	Alternative< Lazy<Any> >		any; +	Alternative< Lazy<Element, IS_A_BLOCK> >	element; +	Alternative< Lazy<Group, IS_A_BLOCK> >		group; +	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice; +	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence; +	Alternative< Lazy<Any> >					any;  	Choice()  	:	element("element"), @@ -158,11 +155,11 @@ struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>  struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>  { -	Alternative< Lazy<Element> >	element; -	Alternative< Lazy<Group> >		group; -	Alternative< Lazy<Choice> >		choice; -	Alternative< Lazy<Sequence> >	sequence; -	Alternative< Lazy<Any> >		any; +	Alternative< Lazy<Element, IS_A_BLOCK> >	element; +	Alternative< Lazy<Group, IS_A_BLOCK> >		group; +	Alternative< Lazy<Choice> >					choice; +	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence; +	Alternative< Lazy<Any> >					any;  };  struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs> @@ -247,7 +244,7 @@ struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>  	Optional<bool>					mixed;  	Multiple<Attribute>				attribute; -	Multiple< Lazy<Element> >			elements; +	Multiple< Lazy<Element, IS_A_BLOCK > >			elements;  	ComplexType()  	:	name("name"), @@ -313,7 +310,6 @@ public:  			setNameSpace(ns);  		};  	} -  };  // @@ -670,6 +666,7 @@ LLXUIParser::LLXUIParser()  		registerParserFuncs<S32>(readS32Value, writeS32Value);  		registerParserFuncs<F32>(readF32Value, writeF32Value);  		registerParserFuncs<F64>(readF64Value, writeF64Value); +		registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);  		registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);  		registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);  		registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue); @@ -1144,6 +1141,31 @@ bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_  	return false;  } +bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr) +{ +	LLXUIParser& self = static_cast<LLXUIParser&>(parser); +	LLVector3* vecp = (LLVector3*)val_ptr; +	if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3) +	{ +		return true; +	} + +	return false; +} + +bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack) +{ +	LLXUIParser& self = static_cast<LLXUIParser&>(parser); +	LLXMLNodePtr node = self.getNode(stack); +	if (node.notNull()) +	{ +		LLVector3 vector = *((LLVector3*)val_ptr); +		node->setFloatValue(3, vector.mV); +		return true; +	} +	return false; +} +  bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser); diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index d7cd256967..e48663e5cc 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -127,6 +127,7 @@ private:  	static bool readS32Value(Parser& parser, void* val_ptr);  	static bool readF32Value(Parser& parser, void* val_ptr);  	static bool readF64Value(Parser& parser, void* val_ptr); +	static bool readVector3Value(Parser& parser, void* val_ptr);  	static bool readColor4Value(Parser& parser, void* val_ptr);  	static bool readUIColorValue(Parser& parser, void* val_ptr);  	static bool readUUIDValue(Parser& parser, void* val_ptr); @@ -144,6 +145,7 @@ private:  	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);  	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);  	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);  	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);  	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);  	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3c9bde34b7..b780a27ce2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES      llfloateruipreview.cpp      llfloaterurlentry.cpp      llfloatervoiceeffect.cpp +    llfloatervoicevolume.cpp      llfloaterwebcontent.cpp      llfloaterwebprofile.cpp      llfloaterwhitelistentry.cpp @@ -800,6 +801,7 @@ set(viewer_HEADER_FILES      llfloateruipreview.h      llfloaterurlentry.h      llfloatervoiceeffect.h +    llfloatervoicevolume.h      llfloaterwebcontent.h      llfloaterwebprofile.h      llfloaterwhitelistentry.h diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 9a7cdcfa21..ac14ec2cc0 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -809,6 +809,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)  }  // static +void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +{ +	std::string name; +	gCacheName->getFullName(id, name); // needed for mute + +	LLMuteList* mute_list = LLMuteList::getInstance(); +	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat); + +	LLMute mute(id, name, LLMute::AGENT); +	if (!is_muted) +	{ +		mute_list->add(mute, LLMute::flagVoiceChat); +	} +	else +	{ +		mute_list->remove(mute, LLMute::flagVoiceChat); +	} +} + +// static  bool LLAvatarActions::canOfferTeleport(const LLUUID& id)  {  	// First use LLAvatarTracker::isBuddy() @@ -1023,6 +1043,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)  }  // static +bool LLAvatarActions::isVoiceMuted(const LLUUID& id) +{ +	return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); +} + +// static  bool LLAvatarActions::canBlock(const LLUUID& id)  {  	std::string full_name; diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 748b7cb3d1..e5dad74fc8 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -124,6 +124,11 @@ public:  	static void toggleBlock(const LLUUID& id);  	/** +	 * Block/unblock the avatar voice. +	 */ +	static void toggleMuteVoice(const LLUUID& id); + +	/**  	 * Return true if avatar with "id" is a friend  	 */  	static bool isFriend(const LLUUID& id); @@ -134,6 +139,11 @@ public:  	static bool isBlocked(const LLUUID& id);  	/** +	 * @return true if the avatar voice is blocked +	 */ +	static bool isVoiceMuted(const LLUUID& id); + +	/**  	 * @return true if you can block the avatar  	 */  	static bool canBlock(const LLUUID& id); diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 6e77d1e336..9e608d2c8b 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -35,11 +35,8 @@  using namespace LLNotificationsUI; -bool LLBrowserNotification::processNotification(const LLSD& notify) +bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)  { -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); -	if (!notification) return false; -  	LLUUID media_id = notification->getPayload()["media_id"].asUUID();  	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);  	if (media_instance) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index f530d10ddc..5bdfb5adbc 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -143,7 +143,8 @@ public:  		{  			LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT)); -			LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId())); +			LLFloaterSidePanelContainer::showPanel("people", "panel_people", +				LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));  		}  	} diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a661808d1f..17181edffc 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -335,30 +335,15 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)  /*               LLNotificationChiclet implementation                   */  /************************************************************************/  LLNotificationChiclet::LLNotificationChiclet(const Params& p) -: LLSysWellChiclet(p) -, mUreadSystemNotifications(0) +:	LLSysWellChiclet(p), +	mUreadSystemNotifications(0)  { -	// connect counter handlers to the signals -	connectCounterUpdatersToSignal("notify"); -	connectCounterUpdatersToSignal("groupnotify"); -	connectCounterUpdatersToSignal("offer"); - +	mNotificationChannel.reset(new ChicletNotificationChannel(this));  	// ensure that notification well window exists, to synchronously  	// handle toast add/delete events.  	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);  } -void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type) -{ -	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance(); -	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type); -	if(n_handler) -	{ -		n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this)); -		n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this)); -	} -} -  void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)  {  	std::string action = user_data.asString(); @@ -407,6 +392,18 @@ void LLNotificationChiclet::setCounter(S32 counter)  	updateWidget(getCounter() == 0);  } + +bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification ) +{ +	if( !(notification->canLogToIM() && notification->hasFormElements()) +		&& (!notification->getPayload().has("give_inventory_notification") +			|| notification->getPayload()["give_inventory_notification"])) +	{ +		return true; +	} +	return false; +} +  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 19683492c2..3973b6547a 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -34,6 +34,7 @@  #include "lloutputmonitorctrl.h"  #include "llgroupmgr.h"  #include "llimview.h" +#include "llnotifications.h"  class LLMenuGL;  class LLIMFloater; @@ -911,11 +912,35 @@ protected:  class LLNotificationChiclet : public LLSysWellChiclet  { +	LOG_CLASS(LLNotificationChiclet); +	  	friend class LLUICtrlFactory;  public:  	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};  protected: +	struct ChicletNotificationChannel : public LLNotificationChannel +	{ +		ChicletNotificationChannel(LLNotificationChiclet* chiclet)  +		:	LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())), +			mChiclet(chiclet) +		{ +			// connect counter handlers to the signals +			connectToChannel("Group Notifications"); +			connectToChannel("Offer"); +			connectToChannel("Notifications"); +		} + +		static bool filterNotification(LLNotificationPtr notify); +		// connect counter updaters to the corresponding signals +		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } +		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); } + +		LLNotificationChiclet* const mChiclet; +	}; + +	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel; +  	LLNotificationChiclet(const Params& p);  	/** @@ -933,12 +958,6 @@ protected:  	 */  	/*virtual*/ void createMenu(); -	// connect counter updaters to the corresponding signals -	void connectCounterUpdatersToSignal(const std::string& notification_type); - -	// methods for updating a number of unread System notifications -	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); } -	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }  	/*virtual*/ void setCounter(S32 counter);  	S32 mUreadSystemNotifications;  }; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 2681d4b34d..4f35c325a8 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -44,21 +44,16 @@ public:  	BOOL postBuild();  private: -	bool update(const LLSD& payload, bool passed_filter); +	bool update(const LLSD& payload);  	static void toggleClick(void* user_data);  	static void onClickNotification(void* user_data); -	static void onClickNotificationReject(void* user_data);  	LLNotificationChannelPtr mChannelPtr; -	LLNotificationChannelPtr mChannelRejectsPtr;  };  LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p)   :	LLLayoutPanel(p)  {  	mChannelPtr = LLNotifications::instance().getChannel(p.name); -	mChannelRejectsPtr = LLNotificationChannelPtr( -		LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(), -											!boost::bind(mChannelPtr->getFilter(), _1)));  	buildFromFile( "panel_notifications_channel.xml");  } @@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild()  	header_button->setLabel(mChannelPtr->getName());  	header_button->setClickedCallback(toggleClick, this); -	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true)); -	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false)); +	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1));  	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");  	scroll->setDoubleClickCallback(onClickNotification, this);  	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0)); -	scroll = getChild<LLScrollListCtrl>("notification_rejects_list"); -	scroll->setDoubleClickCallback(onClickNotificationReject, this); -	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));  	return TRUE;  } @@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data)  	// turn off tab stop for collapsed panel  	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());  	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState()); -	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState()); -	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());  }  /*static*/ @@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data)  	}  } -/*static*/ -void LLNotificationChannelPanel::onClickNotificationReject(void* user_data) -{ -	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data; -	if (!self) return; -	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected(); -	llassert(firstselected); -	if (firstselected) -	{ -		void* data = firstselected->getUserdata(); -		if (data) -		{ -			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE); -		} -	} -} - -bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) +bool LLNotificationChannelPanel::update(const LLSD& payload)  {  	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());  	if (notification) @@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)  		row["columns"][2]["column"] = "date";  		row["columns"][2]["type"] = "date"; -		LLScrollListItem* sli = passed_filter ?  -			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) : -			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row); +		LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row);  		sli->setUserdata(&(*notification));  	} diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index 540f977305..c55970ad69 100644 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -44,14 +44,12 @@  #include "llviewernetwork.h"  #include "llwindowshade.h" -#define USE_WINDOWSHADE_DIALOGS	0 -  ///----------------------------------------------------------------------------  /// LLOutboxNotification class  ///---------------------------------------------------------------------------- -bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify) +bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)  {  	LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox"); @@ -60,6 +58,14 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& no  	return false;  } +void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p) +{ +	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get()); +	if (sys_handler) +	{ +		sys_handler->onDelete(p); +	} +}  ///----------------------------------------------------------------------------  /// LLOutboxAddedObserver helper class @@ -516,52 +522,11 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)  	updateView();  } -void LLFloaterOutbox::showNotification(const LLSD& notify) +void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)  { -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); -	 -	if (!notification) -	{ -		llerrs << "Unable to find outbox notification!" << notify.asString() << llendl; -		 -		return; -	} - -#if USE_WINDOWSHADE_DIALOGS - -	if (mWindowShade) -	{ -		delete mWindowShade; -	} -	 -	LLRect floater_rect = getLocalRect(); -	floater_rect.mTop -= getHeaderHeight(); -	floater_rect.stretch(-5, 0); -	 -	LLWindowShade::Params params; -	params.name = "notification_shade"; -	params.rect = floater_rect; -	params.follows.flags = FOLLOWS_ALL; -	params.modal = true; -	params.can_close = false; -	params.shade_color = LLColor4::white % 0.25f; -	params.text_color = LLColor4::white; -	 -	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); -	 -	addChild(mWindowShade); -	mWindowShade->show(notification); -	 -#else -	 -	LLNotificationsUI::LLEventHandler * handler = -		LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal"); -	 -	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler); +	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());  	llassert(sys_handler); -	sys_handler->processNotification(notify); -	 -#endif +	sys_handler->processNotification(notification);  } diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h index 18baccf1c9..a91d8c1139 100644 --- a/indra/newview/llfloateroutbox.h +++ b/indra/newview/llfloateroutbox.h @@ -64,7 +64,7 @@ public:  						   EAcceptance* accept,  						   std::string& tooltip_msg); -	void showNotification(const LLSD& notify); +	void showNotification(const LLNotificationPtr& notification);  	BOOL handleHover(S32 x, S32 y, MASK mask);  	void onMouseLeave(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 173b0e538c..1c29323594 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1502,7 +1502,8 @@ void LLFloaterPreference::onChangeMaturity()  // but the UI for this will still be enabled  void LLFloaterPreference::onClickBlockList()  { -	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); +	LLFloaterSidePanelContainer::showPanel("people", "panel_people", +		LLSD().with("people_panel_tab_name", "blocked_panel"));  }  void LLFloaterPreference::onClickProxySettings() diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp index 5385977d95..96b5c6b09b 100644 --- a/indra/newview/llfloatersidepanelcontainer.cpp +++ b/indra/newview/llfloatersidepanelcontainer.cpp @@ -61,7 +61,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na  	if (!getVisible())  	{ -		openFloater(); +	openFloater();  	}  	LLPanel* panel = NULL; @@ -69,10 +69,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na  	LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());  	if (container)  	{ -		LLSD new_params = params; -		new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name; -		container->onOpen(new_params); - +		container->openPanel(panel_name, params);  		panel = container->getCurrentPanel();  	}  	else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL) diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp new file mode 100644 index 0000000000..87b388b30a --- /dev/null +++ b/indra/newview/llfloatervoicevolume.cpp @@ -0,0 +1,209 @@ +/**  + * @file llfloatervoicevolume.cpp + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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" + +#include "llfloatervoicevolume.h" + +// Linden libraries +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llfloater.h" +#include "llfloaterreg.h" +#include "lltextbox.h" + +// viewer files +#include "llagent.h" +#include "llavataractions.h" +#include "llinspect.h" +#include "lltransientfloatermgr.h" +#include "llvoiceclient.h" + +class LLAvatarName; + +////////////////////////////////////////////////////////////////////////////// +// LLFloaterVoiceVolume +////////////////////////////////////////////////////////////////////////////// + +// Avatar Inspector, a small information window used when clicking +// on avatar names in the 2D UI and in the ambient inspector widget for +// the 3D world. +class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater +{ +	friend class LLFloaterReg; +	 +public: +	// avatar_id - Avatar ID for which to show information +	// Inspector will be positioned relative to current mouse position +	LLFloaterVoiceVolume(const LLSD& avatar_id); +	virtual ~LLFloaterVoiceVolume(); +	 +	/*virtual*/ BOOL postBuild(void); +	 +	// Because floater is single instance, need to re-parse data on each spawn +	// (for example, inspector about same avatar but in different position) +	/*virtual*/ void onOpen(const LLSD& avatar_id); + +	/*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } + +private: +	// Set the volume slider to this user's current client-side volume setting, +	// hiding/disabling if the user is not nearby. +	void updateVolumeControls(); + +	void onClickMuteVolume(); +	void onVolumeChange(const LLSD& data); +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); +	 +private: +	LLUUID				mAvatarID; +	// Need avatar name information to spawn friend add request +	LLAvatarName		mAvatarName; +}; + +LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd) +:	LLInspect(LLSD())		// single_instance, doesn't really need key +,	mAvatarID()				// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* +,	mAvatarName() +{ +	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this); +	LLTransientFloater::init(this); +} + +LLFloaterVoiceVolume::~LLFloaterVoiceVolume() +{ +	LLTransientFloaterMgr::getInstance()->removeControlView(this); +} + +/*virtual*/ +BOOL LLFloaterVoiceVolume::postBuild(void) +{ +	getChild<LLUICtrl>("mute_btn")->setCommitCallback( +		boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) ); + +	getChild<LLUICtrl>("volume_slider")->setCommitCallback( +		boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2)); + +	return TRUE; +} + + +// Multiple calls to showInstance("floater_voice_volume", foo) will provide different +// LLSD for foo, which we will catch here. +//virtual +void LLFloaterVoiceVolume::onOpen(const LLSD& data) +{ +	// Start open animation +	LLInspect::onOpen(data); + +	// Extract appropriate avatar id +	mAvatarID = data["avatar_id"]; + +	LLUI::positionViewNearMouse(this); + +	getChild<LLUICtrl>("avatar_name")->setValue(""); +	updateVolumeControls(); + +	LLAvatarNameCache::get(mAvatarID, +		boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2)); +} + +void LLFloaterVoiceVolume::updateVolumeControls() +{ +	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID); + +	LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); +	LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); + +	// Do not display volume slider and mute button if it  +	// is ourself or we are not in a voice channel together +	if (!voice_enabled || (mAvatarID == gAgent.getID())) +	{ +		mute_btn->setVisible(false); +		volume_slider->setVisible(false); +	} +	else  +	{ +		mute_btn->setVisible(true); +		volume_slider->setVisible(true); + +		// By convention, we only display and toggle voice mutes, not all mutes +		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID); +		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); + +		mute_btn->setEnabled(!is_linden); +		mute_btn->setValue(is_muted); + +		volume_slider->setEnabled(!is_muted); + +		F32 volume; +		if (is_muted) +		{ +			// it's clearer to display their volume as zero +			volume = 0.f; +		} +		else +		{ +			// actual volume +			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); +		} +		volume_slider->setValue((F64)volume); +	} + +} + +void LLFloaterVoiceVolume::onClickMuteVolume() +{ +	LLAvatarActions::toggleMuteVoice(mAvatarID); +	updateVolumeControls(); +} + +void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data) +{ +	F32 volume = (F32)data.asReal(); +	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); +} + +void LLFloaterVoiceVolume::onAvatarNameCache( +		const LLUUID& agent_id, +		const LLAvatarName& av_name) +{ +	if (agent_id != mAvatarID) +	{ +		return; +	} + +	getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName()); +	mAvatarName = av_name; +} + +////////////////////////////////////////////////////////////////////////////// +// LLFloaterVoiceVolumeUtil +////////////////////////////////////////////////////////////////////////////// +void LLFloaterVoiceVolumeUtil::registerFloater() +{ +	LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml", +					  &LLFloaterReg::build<LLFloaterVoiceVolume>); +} diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h new file mode 100644 index 0000000000..8fcf7f250b --- /dev/null +++ b/indra/newview/llfloatervoicevolume.h @@ -0,0 +1,35 @@ +/**  + * @file llfloatervoicevolume.h + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + +#ifndef LL_LLFLOATERVOICEVOLUME_H +#define LL_LLFLOATERVOICEVOLUME_H + +namespace LLFloaterVoiceVolumeUtil +{ +	// Register with LLFloaterReg +	void registerFloater(); +} + +#endif // LL_LLFLOATERVOICEVOLUME_H diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 86001e4146..f375443e38 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -176,6 +176,7 @@ LLFolderView::Params::Params()  	show_load_status("show_load_status", true),  	use_ellipses("use_ellipses", false)  { +	folder_indentation = -4;  } @@ -224,10 +225,7 @@ LLFolderView::LLFolderView(const Params& p)  	mAutoOpenCandidate = NULL;  	mAutoOpenTimer.stop();  	mKeyboardSelection = FALSE; -	const LLFolderViewItem::Params& item_params = -		LLUICtrlFactory::getDefaultParams<LLFolderViewItem>(); -	S32 indentation = item_params.folder_indentation(); -	mIndentation = -indentation; // children start at indentation 0 +	mIndentation = p.folder_indentation;  	gIdleCallbacks.addFunction(idle, this);  	//clear label @@ -235,7 +233,6 @@ LLFolderView::LLFolderView(const Params& p)  	// just make sure the label ("Inventory Folder") never shows up  	mLabel = LLStringUtil::null; -	//mRenamer->setWriteableBgColor(LLColor4::white);  	// Escape is handled by reverting the rename, not commiting it (default behavior)  	LLLineEditor::Params params;  	params.name("ren"); @@ -527,7 +524,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)  		LLView::reshape(width, height, called_from_parent);  		scroll_rect = mScrollContainer->getContentWindowRect();  	} -	width  = llmax(mMinWidth, scroll_rect.getWidth()); +	width = llmax(mMinWidth, scroll_rect.getWidth());  	height = llmax(mRunningHeight, scroll_rect.getHeight());  	// Restrict width within scroll container's width @@ -1921,21 +1918,11 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	// when drop is not handled by child, it should be handled  	// by the folder which is the hierarchy root. -	if (!handled) -	{ -		if (getListener()->getUUID().notNull()) +	if (!handled +		&& getListener()->getUUID().notNull())  		{  			handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);  		} -		else -		{ -			if (!mFolders.empty()) -			{ -				// dispatch to last folder as a hack to support "Contents" folder in object inventory -				handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); -			} -		} -	}  	if (handled)  	{ diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 1d018b5e6a..9a6bf05cd1 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -187,14 +187,6 @@ public:  	// public rename functionality - can only start the process  	void startRenamingSelectedItem( void ); -	// These functions were used when there was only one folderview, -	// and relied on that concept. This functionality is now handled -	// by the listeners and the lldraganddroptool. -	//LLFolderViewItem*	getMovingItem() { return mMovingItem; } -	//void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; } -	//void				dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); -	//void				dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); -  	// LLView functionality  	///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );  	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index afad27b4e0..c2dec4ab27 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -417,9 +417,8 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)  	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();  	S32 indentation = p.folder_indentation();  	// Only indent deeper items in hierarchy -	mIndentation = (getParentFolder()  -					&& getParentFolder()->getParentFolder() ) -		? mParentFolder->getIndentation() + indentation +	mIndentation = (getParentFolder()) +		? getParentFolder()->getIndentation() + indentation  		: 0;  	if (mLabelWidthDirty)  	{ diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index b670af1782..47612fe25c 100644 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;  //-------------------------------------------------------  // constants  //------------------------------------------------------- -const F32 ONE_HALF							= 0.5;   const F32 FOLLOW_CAM_ZOOM_FACTOR			= 0.1f;  const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT		= 0.1f;  const F32 DISTANCE_EPSILON					= 0.0001f; diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 482294c8a6..3336097955 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&  	}  	// scale screen size of borders down -	//RN: for now, text on hud objects is never occluded  	LLVector3 x_pixel_vec;  	LLVector3 y_pixel_vec; @@ -187,45 +186,29 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&  			+ (y_pixel_vec * screen_offset.mV[VY]); -	//if (mUseBubble) +	LLVector3 bg_pos = render_position +		+ (F32)mOffsetY * y_pixel_vec +		- (width_vec / 2.f) +		- (height_vec); + +	LLVector3 v[] =   	{ -		LLVector3 bg_pos = render_position -			+ (F32)mOffsetY * y_pixel_vec -			- (width_vec / 2.f) -			- (height_vec); -		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); +		bg_pos, +		bg_pos + width_vec, +		bg_pos + width_vec + height_vec, +		bg_pos + height_vec, +	}; -		LLVector3 v[] =  -		{ -			bg_pos, -			bg_pos + width_vec, -			bg_pos + width_vec + height_vec, -			bg_pos + height_vec, -		}; +	LLVector3 dir = end-start; +	F32 a, b, t; -		if (debug_render) +	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || +		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) +	{ +		if (t <= 1.f)  		{ -			gGL.begin(LLRender::LINE_STRIP); -			gGL.vertex3fv(v[0].mV); -			gGL.vertex3fv(v[1].mV); -			gGL.vertex3fv(v[2].mV); -			gGL.vertex3fv(v[3].mV); -			gGL.vertex3fv(v[0].mV); -			gGL.vertex3fv(v[2].mV); -			gGL.end(); -		} - -		LLVector3 dir = end-start; -		F32 a, b, t; - -		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || -			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) -		{ -			if (t <= 1.f) -			{ -				intersection = start + dir*t; -				return TRUE; -			} +			intersection = start + dir*t; +			return TRUE;  		}  	} @@ -241,12 +224,6 @@ void LLHUDNameTag::render()  	}  } -void LLHUDNameTag::renderForSelect() -{ -	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); -	renderText(TRUE); -} -  void LLHUDNameTag::renderText(BOOL for_select)  {  	if (!mVisible || mHidden) @@ -299,24 +276,6 @@ void LLHUDNameTag::renderText(BOOL for_select)  	LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");  	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); -	// maybe a no-op? -	//const S32 border_height = 16; -	//const S32 border_width = 16; -	const S32 border_height = 8; -	const S32 border_width = 8; - -	// *TODO move this into helper function -	F32 border_scale = 1.f; - -	if (border_height * 2 > mHeight) -	{ -		border_scale = (F32)mHeight / ((F32)border_height * 2.f); -	} -	if (border_width * 2 > mWidth) -	{ -		border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f)); -	} -  	// scale screen size of borders down  	//RN: for now, text on hud objects is never occluded @@ -325,152 +284,34 @@ void LLHUDNameTag::renderText(BOOL for_select)  	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); -	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());  	LLVector3 width_vec = mWidth * x_pixel_vec;  	LLVector3 height_vec = mHeight * y_pixel_vec; -	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec; -	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;  	mRadius = (width_vec + height_vec).magVec() * 0.5f;  	LLCoordGL screen_pos;  	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); -	LLVector2 screen_offset; -//	if (!mUseBubble) -//	{ -//		screen_offset = mPositionOffset; -//	} -//	else -//	{ -		screen_offset = updateScreenPos(mPositionOffset); -//	} +	LLVector2 screen_offset = updateScreenPos(mPositionOffset);  	LLVector3 render_position = mPositionAgent    			+ (x_pixel_vec * screen_offset.mV[VX])  			+ (y_pixel_vec * screen_offset.mV[VY]); -//	if (mUseBubble) +	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +	LLRect screen_rect; +	screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight))); +	imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color); +	if (mLabelSegments.size())  	{ -		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); -		LLUI::pushMatrix(); -		{ -			LLVector3 bg_pos = render_position -				+ (F32)mOffsetY * y_pixel_vec -				- (width_vec / 2.f) -				- (height_vec); -			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); - -			if (for_select) -			{ -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -				S32 name = mSourceObject->mGLName; -				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name); -				gGL.color4ubv(coloru.mV); -				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); -				LLUI::popMatrix(); -				return; -			} -			else -			{ -				gGL.getTexUnit(0)->bind(imagep->getImage()); -				 -				gGL.color4fv(bg_color.mV); -				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); -		 -				if ( mLabelSegments.size()) -				{ -					LLUI::pushMatrix(); -					{ -						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); -						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec; -						LLVector3 label_offset = height_vec - label_height; -						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]); -						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height); -					} -					LLUI::popMatrix(); -				} -			} - -			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f; -			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f); +		LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top"); +		LLRect label_top_rect = screen_rect; +		const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f))); +		label_top_rect.mBottom = label_top_rect.mTop - label_height; +		LLColor4 label_top_color = text_color; +		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; -			// draw line segments pointing to parent object -			if (!mOffscreen && (outside_width || outside_height)) -			{ -				LLUI::pushMatrix(); -				{ -					gGL.color4fv(bg_color.mV); -					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec); -					target_pos += (width_vec / 2.f); -					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero; -					target_pos -= 3.f * x_pixel_vec; -					target_pos -= 6.f * y_pixel_vec; -					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]); -					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	 -				} -				LLUI::popMatrix(); - -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE); -				 -				LLVector3 box_center_offset; -				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f); -				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]); -				gGL.color4fv(bg_color.mV); -				LLUI::setLineWidth(2.0); -				gGL.begin(LLRender::LINES); -				{ -					if (outside_width) -					{ -						LLVector3 vert; -						// draw line in x then y -						if (mPositionOffset.mV[VX] < 0.f) -						{ -							// start at right edge -							vert = width_vec * 0.5f; -							gGL.vertex3fv(vert.mV); -						} -						else -						{ -							// start at left edge -							vert = width_vec * -0.5f; -							gGL.vertex3fv(vert.mV); -						} -						vert = -mPositionOffset.mV[VX] * x_pixel_vec; -						gGL.vertex3fv(vert.mV); -						gGL.vertex3fv(vert.mV); -						vert -= mPositionOffset.mV[VY] * y_pixel_vec; -						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); -						gGL.vertex3fv(vert.mV); -					} -					else -					{ -						LLVector3 vert; -						// draw line in y then x -						if (mPositionOffset.mV[VY] < 0.f) -						{ -							// start at top edge -							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); -							gGL.vertex3fv(vert.mV); -						} -						else -						{ -							// start at bottom edge -							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec); -							gGL.vertex3fv(vert.mV); -						} -						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec; -						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); -						gGL.vertex3fv(vert.mV); -					} -				} -				gGL.end(); -				LLUI::setLineWidth(1.0); - -			} -		} -		LLUI::popMatrix(); +		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);  	}  	F32 y_offset = (F32)mOffsetY; @@ -874,29 +715,26 @@ void LLHUDNameTag::updateAll()  	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)  	{  		LLHUDNameTag* textp = (*r_it); -//		if (textp->mUseBubble) -//		{ -			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) -			{ -				textp->setLOD(3); -			} -			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) -			{ -				textp->setLOD(2); -			} -			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) -			{ -				textp->setLOD(1); -			} -			else -			{ -				textp->setLOD(0); -			} -			textp->updateSize(); -			// find on-screen position and initialize collision rectangle -			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); -			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); -//		} +		if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) +		{ +			textp->setLOD(3); +		} +		else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) +		{ +			textp->setLOD(2); +		} +		else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) +		{ +			textp->setLOD(1); +		} +		else +		{ +			textp->setLOD(0); +		} +		textp->updateSize(); +		// find on-screen position and initialize collision rectangle +		textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); +		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());  	}  	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); @@ -914,20 +752,12 @@ void LLHUDNameTag::updateAll()  		{  			LLHUDNameTag* src_textp = (*src_it); -//			if (!src_textp->mUseBubble) -//			{ -//				continue; -//			}  			VisibleTextObjectIterator dst_it = src_it;  			++dst_it;  			for (; dst_it != sVisibleTextObjects.end(); ++dst_it)  			{  				LLHUDNameTag* dst_textp = (*dst_it); -//				if (!dst_textp->mUseBubble) -//				{ -//					continue; -//				}  				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))  				{  					LLRectf intersect_rect = src_textp->mSoftScreenRect; @@ -976,10 +806,6 @@ void LLHUDNameTag::updateAll()  	VisibleTextObjectIterator this_object_it;  	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)  	{ -//		if (!(*this_object_it)->mUseBubble) -//		{ -//			continue; -//		}  		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));  	}  } @@ -1037,10 +863,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)  	VisibleTextObjectIterator text_it;  	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)  	{ -//		if (!(*text_it)->mUseBubble) -//		{ -//			continue; -//		}  		pick_list.insert((*text_it)->mSourceObject);  	}  } diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 3325c22def..72647d5b26 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -118,7 +118,6 @@ public:  	/*virtual*/ void markDead();  	friend class LLHUDObject;  	/*virtual*/ F32 getDistance() const { return mLastDistance; } -	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }  	S32  getLOD() { return mLOD; }  	BOOL getVisible() { return mVisible; }  	BOOL getHidden() const { return mHidden; } @@ -136,7 +135,6 @@ protected:  	LLHUDNameTag(const U8 type);  	/*virtual*/ void render(); -	/*virtual*/ void renderForSelect();  	void renderText(BOOL for_select);  	static void updateAll();  	void setLOD(S32 lod); diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index 95d57d08d8..0960846510 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -232,9 +232,11 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)  	case LL_HUD_EFFECT_LOOKAT:  		hud_objectp = new LLHUDEffectLookAt(type);  		break; +#ifdef XXX_STINSON_CHUI_REWORK  	case LL_HUD_EFFECT_VOICE_VISUALIZER:  		hud_objectp = new LLVoiceVisualizer(type);  		break; +#endif // XXX_STINSON_CHUI_REWORK  	case LL_HUD_EFFECT_POINTAT:  		hud_objectp = new LLHUDEffectPointAt(type);  		break; diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 2f7a98c86c..21cf5fe17c 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -94,7 +94,9 @@ public:  		LL_HUD_EFFECT_EDIT,  		LL_HUD_EFFECT_LOOKAT,  		LL_HUD_EFFECT_POINTAT, +#ifdef XXX_STINSON_CHUI_REWORK  		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella +#endif // XXX_STINSON_CHUI_REWORK  		LL_HUD_NAME_TAG,  		LL_HUD_EFFECT_BLOB  	}; diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index 07d73c8c66..c7034aea3a 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -37,10 +37,9 @@  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- -LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id) +LLIMHandler::LLIMHandler() +:	LLSysHandler("IM Notifications", "notifytoast")  { -	mType = type; -  	// Getting a Channel for our notifications  	mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();  } @@ -59,26 +58,19 @@ void LLIMHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLIMHandler::processNotification(const LLSD& notify) +bool LLIMHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false; -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") -	{  		LLSD substitutions = notification->getSubstitutions();  		// According to comments in LLIMMgr::addMessage(), if we get message @@ -103,28 +95,12 @@ bool LLIMHandler::processNotification(const LLSD& notify)  		p.notification = notification;  		p.panel = im_box;  		p.can_be_stored = false; -		p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);  		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());  		if(channel)  			channel->addToast(p); - -		// send a signal to the counter manager; -		mNewNotificationSignal(); -	} -	else if (notify["sigtype"].asString() == "delete") -	{ -		mChannel.get()->killToastByNotificationID(notification->getID());  	}  	return false;  } -//-------------------------------------------------------------------------- -void LLIMHandler::onDeleteToast(LLToast* toast) -{ -	// send a signal to the counter manager -	mDelNotificationSignal(); -} - -//-------------------------------------------------------------------------- diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 17d0b0ffbb..8a15cd279f 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -28,38 +28,21 @@  #include "llinspectavatar.h"  // viewer files -#include "llagent.h" -#include "llagentdata.h" -#include "llavataractions.h" +#include "llavatariconctrl.h"  #include "llavatarnamecache.h"  #include "llavatarpropertiesprocessor.h" -#include "llcallingcard.h"  #include "lldateutil.h" -#include "llfloaterreporter.h" -#include "llfloaterworldmap.h" -#include "llimview.h"  #include "llinspect.h" -#include "llmutelist.h" -#include "llpanelblockedlist.h" +#include "llslurl.h"  #include "llstartup.h" -#include "llspeakers.h" -#include "llviewermenu.h" -#include "llvoiceclient.h" -#include "llviewerobjectlist.h"  #include "lltransientfloatermgr.h" -#include "llnotificationsutil.h"  // Linden libraries  #include "llfloater.h"  #include "llfloaterreg.h" -#include "llmenubutton.h"  #include "lltextbox.h" -#include "lltoggleablemenu.h"  #include "lltooltip.h"	// positionViewNearMouse()  #include "lltrans.h" -#include "lluictrl.h" - -#include "llavatariconctrl.h"  class LLFetchAvatarData; @@ -81,22 +64,13 @@ public:  	LLInspectAvatar(const LLSD& avatar_id);  	virtual ~LLInspectAvatar(); -	/*virtual*/ BOOL postBuild(void); -	  	// Because floater is single instance, need to re-parse data on each spawn  	// (for example, inspector about same avatar but in different position)  	/*virtual*/ void onOpen(const LLSD& avatar_id); -	// When closing they should close their gear menu  -	/*virtual*/ void onClose(bool app_quitting); -	  	// Update view based on information from avatar properties processor  	void processAvatarData(LLAvatarData* data); -	// override the inspector mouse leave so timer is only paused if  -	// gear menu is not open -	/* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask); -	  	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }  private: @@ -104,47 +78,6 @@ private:  	// Used on construction and if avatar id changes.  	void requestUpdate(); -	// Set the volume slider to this user's current client-side volume setting, -	// hiding/disabling if the user is not nearby. -	void updateVolumeSlider(); - -	// Shows/hides moderator panel depending on voice state  -	void updateModeratorPanel(); - -	// Moderator ability to enable/disable voice chat for avatar -	void toggleSelectedVoice(bool enabled); -	 -	// Button callbacks -	void onClickAddFriend(); -	void onClickViewProfile(); -	void onClickIM(); -	void onClickCall(); -	void onClickTeleport(); -	void onClickInviteToGroup(); -	void onClickPay(); -	void onClickShare(); -	void onToggleMute(); -	void onClickReport(); -	void onClickFreeze(); -	void onClickEject(); -	void onClickKick(); -	void onClickCSR(); -	void onClickZoomIn();   -	void onClickFindOnMap(); -	bool onVisibleFindOnMap(); -	bool onVisibleEject(); -	bool onVisibleFreeze(); -	bool onVisibleZoomIn(); -	void onClickMuteVolume(); -	void onVolumeChange(const LLSD& data); -	bool enableMute(); -	bool enableUnmute(); -	bool enableTeleportOffer(); -	bool godModeEnabled(); - -	// Is used to determine if "Add friend" option should be enabled in gear menu -	bool isNotFriend(); -	  	void onAvatarNameCache(const LLUUID& agent_id,  						   const LLAvatarName& av_name); @@ -209,39 +142,8 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)  	mAvatarName(),  	mPropertiesRequest(NULL)  { -	mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile",	boost::bind(&LLInspectAvatar::onClickViewProfile, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.AddFriend",	boost::bind(&LLInspectAvatar::onClickAddFriend, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.IM", -		boost::bind(&LLInspectAvatar::onClickIM, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Call",		boost::bind(&LLInspectAvatar::onClickCall, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Teleport",	boost::bind(&LLInspectAvatar::onClickTeleport, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup",	boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Pay",	boost::bind(&LLInspectAvatar::onClickPay, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Share",	boost::bind(&LLInspectAvatar::onClickShare, this)); -	mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute",	boost::bind(&LLInspectAvatar::onToggleMute, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.Report",	boost::bind(&LLInspectAvatar::onClickReport, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap",	boost::bind(&LLInspectAvatar::onClickFindOnMap, this));	 -	mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this)); -	mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false)); -	mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true)); - -	mEnableCallbackRegistrar.add("InspectAvatar.EnableGod",	boost::bind(&LLInspectAvatar::godModeEnabled, this));	 -	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap",	boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));	 -	mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject",	boost::bind(&LLInspectAvatar::onVisibleEject, this));	 -	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze",	boost::bind(&LLInspectAvatar::onVisibleFreeze, this));	 -	mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this)); -	mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this)); -	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall)); -	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this)); -	mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this)); -	mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this)); -  	// can't make the properties request until the widgets are constructed -	// as it might return immediately, so do it in postBuild. +	// as it might return immediately, so do it in onOpen.  	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);  	LLTransientFloater::init(this); @@ -257,25 +159,6 @@ LLInspectAvatar::~LLInspectAvatar()  	LLTransientFloaterMgr::getInstance()->removeControlView(this);  } -/*virtual*/ -BOOL LLInspectAvatar::postBuild(void) -{ -	getChild<LLUICtrl>("add_friend_btn")->setCommitCallback( -		boost::bind(&LLInspectAvatar::onClickAddFriend, this) ); - -	getChild<LLUICtrl>("view_profile_btn")->setCommitCallback( -		boost::bind(&LLInspectAvatar::onClickViewProfile, this) ); - -	getChild<LLUICtrl>("mute_btn")->setCommitCallback( -		boost::bind(&LLInspectAvatar::onClickMuteVolume, this) ); - -	getChild<LLUICtrl>("volume_slider")->setCommitCallback( -		boost::bind(&LLInspectAvatar::onVolumeChange, this, _2)); - -	return TRUE; -} - -  // Multiple calls to showInstance("inspect_avatar", foo) will provide different  // LLSD for foo, which we will catch here.  //virtual @@ -287,11 +170,6 @@ void LLInspectAvatar::onOpen(const LLSD& data)  	// Extract appropriate avatar id  	mAvatarID = data["avatar_id"]; -	BOOL self = mAvatarID == gAgent.getID(); -	 -	getChild<LLUICtrl>("gear_self_btn")->setVisible(self); -	getChild<LLUICtrl>("gear_btn")->setVisible(!self); -  	// Position the inspector relative to the mouse cursor  	// Similar to how tooltips are positioned  	// See LLToolTipMgr::createToolTip @@ -304,20 +182,13 @@ void LLInspectAvatar::onOpen(const LLSD& data)  		LLUI::positionViewNearMouse(this);  	} +	// Generate link to avatar profile. +	getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString()); +  	// can't call from constructor as widgets are not built yet  	requestUpdate(); - -	updateVolumeSlider(); - -	updateModeratorPanel();  } -// virtual -void LLInspectAvatar::onClose(bool app_quitting) -{   -  getChild<LLMenuButton>("gear_btn")->hideMenu(); -}	 -  void LLInspectAvatar::requestUpdate()  {  	// Don't make network requests when spawning from the debug menu at the @@ -344,25 +215,6 @@ void LLInspectAvatar::requestUpdate()  	delete mPropertiesRequest;  	mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this); -	// You can't re-add someone as a friend if they are already your friend -	bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL; -	bool is_self = (mAvatarID == gAgentID); -	if (is_self) -	{ -		getChild<LLUICtrl>("add_friend_btn")->setVisible(false); -		getChild<LLUICtrl>("im_btn")->setVisible(false); -	} -	else if (is_friend) -	{ -		getChild<LLUICtrl>("add_friend_btn")->setVisible(false); -		getChild<LLUICtrl>("im_btn")->setVisible(true); -	} -	else -	{ -		getChild<LLUICtrl>("add_friend_btn")->setVisible(true); -		getChild<LLUICtrl>("im_btn")->setVisible(false); -	} -  	// Use an avatar_icon even though the image id will come down with the  	// avatar properties because the avatar_icon code maintains a cache of icons  	// and this may result in the image being visible sooner. @@ -405,214 +257,6 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)  	mPropertiesRequest = NULL;  } -// For the avatar inspector, we only want to unpause the fade timer  -// if neither the gear menu or self gear menu are open -void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask) -{ -	LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu(); -	LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu(); -	if ( gear_menu && gear_menu->getVisible() && -		 gear_menu_self && gear_menu_self->getVisible() ) -	{ -		return; -	} - -	if(childHasVisiblePopupMenu()) -	{ -		return; -	} - -	mOpenTimer.unpause(); -} - -void LLInspectAvatar::updateModeratorPanel() -{ -	bool enable_moderator_panel = false; - -    if (LLVoiceChannel::getCurrentVoiceChannel() && -		mAvatarID != gAgent.getID()) -    { -		LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID(); - -		if (session_id != LLUUID::null) -		{ -			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); - -			if (speaker_mgr) -			{ -				LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID()); -				LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID); -				 -				if(speaker_mgr->isVoiceActive() && selected_speakerp &&  -					selected_speakerp->isInVoiceChannel() && -					((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike())) -				{ -					getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice); -					getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice); - -					enable_moderator_panel = true; -				} -			} -		} -	} - -	if (enable_moderator_panel) -	{ -		if (!getChild<LLUICtrl>("moderator_panel")->getVisible()) -		{ -			getChild<LLUICtrl>("moderator_panel")->setVisible(true); -			// stretch the floater so it can accommodate the moderator panel -			reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight()); -		} -	} -	else if (getChild<LLUICtrl>("moderator_panel")->getVisible()) -	{ -		getChild<LLUICtrl>("moderator_panel")->setVisible(false); -		// shrink the inspector floater back to original size -		reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());					 -	} -} - -void LLInspectAvatar::toggleSelectedVoice(bool enabled) -{ -	LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID(); -	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); - -	if (speaker_mgr) -	{ -		if (!gAgent.getRegion()) -			return; - -		std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); -		LLSD data; -		data["method"] = "mute update"; -		data["session-id"] = session_id; -		data["params"] = LLSD::emptyMap(); -		data["params"]["agent_id"] = mAvatarID; -		data["params"]["mute_info"] = LLSD::emptyMap(); -		// ctrl value represents ability to type, so invert -		data["params"]["mute_info"]["voice"] = !enabled; - -		class MuteVoiceResponder : public LLHTTPClient::Responder -		{ -		public: -			MuteVoiceResponder(const LLUUID& session_id) -			{ -				mSessionID = session_id; -			} - -			virtual void error(U32 status, const std::string& reason) -			{ -				llwarns << status << ": " << reason << llendl; - -				if ( gIMMgr ) -				{ -					//403 == you're not a mod -					//should be disabled if you're not a moderator -					if ( 403 == status ) -					{ -						gIMMgr->showSessionEventError( -							"mute", -							"not_a_moderator", -							mSessionID); -					} -					else -					{ -						gIMMgr->showSessionEventError( -							"mute", -							"generic", -							mSessionID); -					} -				} -			} - -		private: -			LLUUID mSessionID; -		}; - -		LLHTTPClient::post( -			url, -			data, -			new MuteVoiceResponder(speaker_mgr->getSessionID())); -	} - -	closeFloater(); - -} - -void LLInspectAvatar::updateVolumeSlider() -{ -	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID); - -	// Do not display volume slider and mute button if it  -	// is ourself or we are not in a voice channel together -	if (!voice_enabled || (mAvatarID == gAgent.getID())) -	{ -		getChild<LLUICtrl>("mute_btn")->setVisible(false); -		getChild<LLUICtrl>("volume_slider")->setVisible(false); -	} - -	else  -	{ -		getChild<LLUICtrl>("mute_btn")->setVisible(true); -		getChild<LLUICtrl>("volume_slider")->setVisible(true); - -		// By convention, we only display and toggle voice mutes, not all mutes -		bool is_muted = LLMuteList::getInstance()-> -							isMuted(mAvatarID, LLMute::flagVoiceChat); - -		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); - -		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); - -		mute_btn->setEnabled( !is_linden); -		mute_btn->setValue( is_muted ); - -		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); -		volume_slider->setEnabled( !is_muted ); - -		F32 volume; -		 -		if (is_muted) -		{ -			// it's clearer to display their volume as zero -			volume = 0.f; -		} -		else -		{ -			// actual volume -			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); -		} -		volume_slider->setValue( (F64)volume ); -	} - -} - -void LLInspectAvatar::onClickMuteVolume() -{ -	// By convention, we only display and toggle voice mutes, not all mutes -	LLMuteList* mute_list = LLMuteList::getInstance(); -	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - -	LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT); -	if (!is_muted) -	{ -		mute_list->add(mute, LLMute::flagVoiceChat); -	} -	else -	{ -		mute_list->remove(mute, LLMute::flagVoiceChat); -	} - -	updateVolumeSlider(); -} - -void LLInspectAvatar::onVolumeChange(const LLSD& data) -{ -	F32 volume = (F32)data.asReal(); -	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); -} -  void LLInspectAvatar::onAvatarNameCache(  		const LLUUID& agent_id,  		const LLAvatarName& av_name) @@ -640,215 +284,6 @@ void LLInspectAvatar::onAvatarNameCache(  	}  } -void LLInspectAvatar::onClickAddFriend() -{ -	LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName()); -	closeFloater(); -} - -void LLInspectAvatar::onClickViewProfile() -{ -	LLAvatarActions::showProfile(mAvatarID); -	closeFloater(); -} - -bool LLInspectAvatar::isNotFriend() -{ -	return !LLAvatarActions::isFriend(mAvatarID); -} - -bool LLInspectAvatar::onVisibleFindOnMap() -{ -	return gAgent.isGodlike() || is_agent_mappable(mAvatarID); -} - -bool LLInspectAvatar::onVisibleEject() -{ -	return enable_freeze_eject( LLSD(mAvatarID) ); -} - -bool LLInspectAvatar::onVisibleFreeze() -{ -	// either user is a god and can do long distance freeze -	// or check for target proximity and permissions -	return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID)); -} - -bool LLInspectAvatar::onVisibleZoomIn() -{ -	return gObjectList.findObject(mAvatarID); -} - -void LLInspectAvatar::onClickIM() -{  -	LLAvatarActions::startIM(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickCall() -{  -	LLAvatarActions::startCall(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickTeleport() -{ -	LLAvatarActions::offerTeleport(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickInviteToGroup() -{ -	LLAvatarActions::inviteToGroup(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickPay() -{ -	LLAvatarActions::pay(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickShare() -{ -	LLAvatarActions::share(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onToggleMute() -{ -	LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT); - -	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName)) -	{ -		LLMuteList::getInstance()->remove(mute); -	} -	else -	{ -		LLMuteList::getInstance()->add(mute); -	} - -	LLPanelBlockedList::showPanelAndSelect(mute.mID); -	closeFloater(); -} - -void LLInspectAvatar::onClickReport() -{ -	LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName()); -	closeFloater(); -} - -bool godlike_freeze(const LLSD& notification, const LLSD& response) -{ -	LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID(); -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - -	switch (option) -	{ -	case 0: -		LLAvatarActions::freeze(avatar_id); -		break; -	case 1: -		LLAvatarActions::unfreeze(avatar_id); -		break; -	default: -		break; -	} - -	return false; -} - -void LLInspectAvatar::onClickFreeze() -{ -	if (gAgent.isGodlike()) -	{ -		// use godlike freeze-at-a-distance, with confirmation -		LLNotificationsUtil::add("FreezeAvatar", -			LLSD(), -			LLSD().with("avatar_id", mAvatarID), -			godlike_freeze); -	} -	else -	{ -		// use default "local" version of freezing that requires avatar to be in range -		handle_avatar_freeze( LLSD(mAvatarID) ); -	} -	closeFloater(); -} - -void LLInspectAvatar::onClickEject() -{ -	handle_avatar_eject( LLSD(mAvatarID) ); -	closeFloater(); -} - -void LLInspectAvatar::onClickKick() -{ -	LLAvatarActions::kick(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickCSR() -{ -	std::string name; -	gCacheName->getFullName(mAvatarID, name); -	LLAvatarActions::csr(mAvatarID, name); -	closeFloater(); -} - -void LLInspectAvatar::onClickZoomIn()  -{ -	handle_zoom_to_object(mAvatarID); -	closeFloater(); -} - -void LLInspectAvatar::onClickFindOnMap() -{ -	gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName); -	LLFloaterReg::showInstance("world_map"); -} - - -bool LLInspectAvatar::enableMute() -{ -		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); -		bool is_self = mAvatarID == gAgent.getID(); - -		if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) -		{ -			return true; -		} -		else -		{ -			return false; -		} -} - -bool LLInspectAvatar::enableUnmute() -{ -		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); -		bool is_self = mAvatarID == gAgent.getID(); - -		if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) -		{ -			return true; -		} -		else -		{ -			return false; -		} -} - -bool LLInspectAvatar::enableTeleportOffer() -{ -	return LLAvatarActions::canOfferTeleport(mAvatarID); -} - -bool LLInspectAvatar::godModeEnabled() -{ -	return gAgent.isGodlike(); -} -  //////////////////////////////////////////////////////////////////////////////  // LLInspectAvatarUtil  ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h index fabd68ee20..04d3314829 100644 --- a/indra/newview/lllistcontextmenu.h +++ b/indra/newview/lllistcontextmenu.h @@ -37,7 +37,7 @@ class LLContextMenu;  /**   * Context menu for single or multiple list items.   *  - * Derived classes must implement contextMenu(). + * Derived classes must implement createMenu().   *    * Typical usage:   * <code> diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 600fd395fb..4d9db01e0d 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -445,10 +445,8 @@ void LLNearbyChatScreenChannel::arrangeToasts()  //-----------------------------------------------------------------------------------------------  boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat")); -LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id) +LLNearbyChatHandler::LLNearbyChatHandler()  { -	mType = type; -  	// Getting a Channel for our notifications  	LLNearbyChatScreenChannel::Params p;  	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID")); @@ -617,10 +615,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,  	}  } -void LLNearbyChatHandler::onDeleteToast(LLToast* toast) -{ -} -  //-----------------------------------------------------------------------------------------------  // LLNearbyChatToast diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h index b0e4f62d51..a5034ac1cb 100644 --- a/indra/newview/llnearbychathandler.h +++ b/indra/newview/llnearbychathandler.h @@ -37,14 +37,13 @@ namespace LLNotificationsUI{  class LLNearbyChatHandler : public LLChatHandler  {  public: -	LLNearbyChatHandler(e_notification_type type,const LLSD& id); +	LLNearbyChatHandler();  	virtual ~LLNearbyChatHandler();  	virtual void processChat(const LLChat& chat_msg, const LLSD &args);  protected: -	virtual void onDeleteToast(LLToast* toast);  	virtual void initChannel();  	static boost::scoped_ptr<LLEventPump> sChatWatcher; diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index 89fe7bb3c2..d13e2b629d 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -40,10 +40,10 @@  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- -LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false) +LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal)  +:	LLSysHandler(name, notification_type), +	mIsModal(is_modal)  { -	mType = type; -  	LLScreenChannelBase::Params p;  	p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));  	p.display_toasts_always = true; @@ -68,27 +68,20 @@ void LLAlertHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLAlertHandler::processNotification(const LLSD& notify) +bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false; -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") -	{ -		if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification)) +	if (notification->canLogToIM() && notification->hasFormElements())  		{  			const std::string name = LLHandlerUtil::getSubstitutionName(notification); @@ -119,28 +112,14 @@ bool LLAlertHandler::processNotification(const LLSD& notify)  		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());  		if(channel)  			channel->addToast(p); -	} -	else if (notify["sigtype"].asString() == "change") -	{ -		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); -		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); -		if(channel) -			channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog); -	} -	else -	{ -		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); -		if(channel) -			channel->killToastByNotificationID(notification->getID()); -	} +	  	return false; -} - -//-------------------------------------------------------------------------- +	} -void LLAlertHandler::onDeleteToast(LLToast* toast) +void LLAlertHandler::onChange( LLNotificationPtr notification )  { +	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); +	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); +	if(channel) +		channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);  } - -//-------------------------------------------------------------------------- - diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index ad51389241..50db4737ce 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -37,15 +37,13 @@  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- -LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id) +LLGroupHandler::LLGroupHandler() +:	LLSysHandler("Group Notifications", "groupnotify")  { -	mType = type; -  	// Getting a Channel for our notifications  	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();  	if(channel) -	{ -		channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1)); +		channel->addOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));  		mChannel = channel->getHandle();  	}  } @@ -64,68 +62,43 @@ void LLGroupHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLGroupHandler::processNotification(const LLSD& notify) +bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false; -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") -	{ -		LLHandlerUtil::logGroupNoticeToIMGroup(notification); +	LLHandlerUtil::logGroupNoticeToIMGroup(notification); -		LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); -		LLToast::Params p; -		p.notif_id = notification->getID(); -		p.notification = notification; -		p.panel = notify_box; -		p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1); +	LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); +	LLToast::Params p; +	p.notif_id = notification->getID(); +	p.notification = notification; +	p.panel = notify_box; +	p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1); -		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); -		if(channel) -			channel->addToast(p); +	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get()); +	if(channel) +		channel->addToast(p); -		// send a signal to the counter manager -		mNewNotificationSignal(); +	LLGroupActions::refresh_notices(); -		LLGroupActions::refresh_notices(); -	} -	else if (notify["sigtype"].asString() == "delete") -	{ -		mChannel.get()->killToastByNotificationID(notification->getID()); -	}  	return false;  }  //-------------------------------------------------------------------------- -void LLGroupHandler::onDeleteToast(LLToast* toast) -{ -	// send a signal to the counter manager -	mDelNotificationSignal(); - -	// send a signal to a listener to let him perform some action -	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list -	mNotificationIDSignal(toast->getNotificationID()); -} - -//--------------------------------------------------------------------------  void LLGroupHandler::onRejectToast(LLUUID& id)  {  	LLNotificationPtr notification = LLNotifications::instance().find(id); -	if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this) +	if (notification && mItems.find(notification) != mItems.end())  	{  		LLNotifications::instance().cancel(notification);  	} diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 3569ad6447..805e29e2a4 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -30,7 +30,7 @@  #include "llwindow.h" -//#include "llnotificationsutil.h" +#include "llnotifications.h"  #include "llchannelmanager.h"  #include "llchat.h"  #include "llinstantmessage.h" @@ -40,20 +40,6 @@ class LLIMFloater;  namespace LLNotificationsUI  { -// ENotificationType enumerates all possible types of notifications that could be met -//  -typedef enum e_notification_type -{ -	NT_NOTIFY,  -	NT_NOTIFYTIP, -	NT_GROUPNOTIFY, -	NT_IMCHAT,  -	NT_GROUPCHAT,  -	NT_NEARBYCHAT,  -	NT_ALERT, -	NT_ALERTMODAL, -	NT_OFFER -} ENotificationType;  /**   * Handler of notification events. @@ -81,21 +67,8 @@ class LLEventHandler  public:  	virtual ~LLEventHandler() {}; -	// callbacks for counters -	typedef boost::function<void (void)> notification_callback_t; -	typedef boost::signals2::signal<void (void)> notification_signal_t; -	notification_signal_t mNewNotificationSignal; -	notification_signal_t mDelNotificationSignal; -	boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); } -	boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); } -	// callback for notification/toast -	typedef boost::function<void (const LLUUID id)> notification_id_callback_t; -	typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t; -	notification_id_signal_t mNotificationIDSignal; -	boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); } -  protected: -	virtual void onDeleteToast(LLToast* toast)=0; +	virtual void onDeleteToast(LLToast* toast) {}  	// arrange handler's channel on a screen  	// is necessary to unbind a moment of creation of a channel and a moment of positioning of it @@ -104,8 +77,6 @@ protected:  	virtual void initChannel()=0;  	LLHandle<LLScreenChannelBase>	mChannel; -	e_notification_type				mType; -  };  // LLSysHandler and LLChatHandler are more specific base classes @@ -115,13 +86,18 @@ protected:  /**   * Handler for system notifications.   */ -class LLSysHandler : public LLEventHandler +class LLSysHandler : public LLEventHandler, public LLNotificationChannel  {  public: -	LLSysHandler(); +	LLSysHandler(const std::string& name, const std::string& notification_type);  	virtual ~LLSysHandler() {}; -	virtual bool processNotification(const LLSD& notify)=0; +	// base interface functions +	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel) mChannel->killToastByNotificationID(p->getID());} + +	virtual bool processNotification(const LLNotificationPtr& notify)=0;  protected :  	static void init(); @@ -149,15 +125,12 @@ public:  class LLIMHandler : public LLSysHandler  {  public: -	LLIMHandler(e_notification_type type, const LLSD& id); +	LLIMHandler();  	virtual ~LLIMHandler(); -	// base interface functions -	virtual bool processNotification(const LLSD& notify); -  protected: -	virtual void onDeleteToast(LLToast* toast); -	virtual void initChannel(); +	bool processNotification(const LLNotificationPtr& p); +	/*virtual*/ void initChannel();  };  /** @@ -167,16 +140,16 @@ protected:  class LLTipHandler : public LLSysHandler  {  public: -	LLTipHandler(e_notification_type type, const LLSD& id); +	LLTipHandler();  	virtual ~LLTipHandler();  	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ bool processNotification(const LLNotificationPtr& p);  protected: -	virtual void onDeleteToast(LLToast* toast); -	virtual void onRejectToast(const LLUUID& id); -	virtual void initChannel(); +	/*virtual*/ void onRejectToast(const LLUUID& id); +	/*virtual*/ void initChannel();  };  /** @@ -186,15 +159,16 @@ protected:  class LLScriptHandler : public LLSysHandler  {  public: -	LLScriptHandler(e_notification_type type, const LLSD& id); +	LLScriptHandler();  	virtual ~LLScriptHandler(); +	/*virtual*/ void onDelete(LLNotificationPtr p);  	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ bool processNotification(const LLNotificationPtr& p);  protected: -	virtual void onDeleteToast(LLToast* toast); -	virtual void initChannel(); +	/*virtual*/ void onDeleteToast(LLToast* toast); +	/*virtual*/ void initChannel();  	// own handlers  	void onRejectToast(LLUUID& id); @@ -207,14 +181,14 @@ protected:  class LLGroupHandler : public LLSysHandler  {  public: -	LLGroupHandler(e_notification_type type, const LLSD& id); +	LLGroupHandler();  	virtual ~LLGroupHandler();  	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ bool processNotification(const LLNotificationPtr& p);  protected: -	virtual void onDeleteToast(LLToast* toast);  	virtual void initChannel();  	// own handlers @@ -227,16 +201,14 @@ protected:  class LLAlertHandler : public LLSysHandler  {  public: -	LLAlertHandler(e_notification_type type, const LLSD& id); +	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);  	virtual ~LLAlertHandler(); -	void setAlertMode(bool is_modal) { mIsModal = is_modal; } - -	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ void onChange(LLNotificationPtr p); +	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ bool processNotification(const LLNotificationPtr& p);  protected: -	virtual void onDeleteToast(LLToast* toast);  	virtual void initChannel();  	bool	mIsModal; @@ -249,15 +221,16 @@ protected:  class LLOfferHandler : public LLSysHandler  {  public: -	LLOfferHandler(e_notification_type type, const LLSD& id); +	LLOfferHandler();  	virtual ~LLOfferHandler();  	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onDelete(LLNotificationPtr notification); +	/*virtual*/ bool processNotification(const LLNotificationPtr& p);  protected: -	virtual void onDeleteToast(LLToast* toast); -	virtual void initChannel(); +	/*virtual*/ void initChannel();  	// own handlers  	void onRejectToast(LLUUID& id); @@ -266,85 +239,56 @@ protected:  /**   * Handler for UI hints.   */ -class LLHintHandler : public LLSingleton<LLHintHandler> +class LLHintHandler : public LLNotificationChannel  {  public: -	LLHintHandler(); -	virtual ~LLHintHandler(); +	LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint")) +	{} +	virtual ~LLHintHandler() {} -	// base interface functions -	virtual bool processNotification(const LLSD& notify); +	/*virtual*/ void onAdd(LLNotificationPtr p); +	/*virtual*/ void onLoad(LLNotificationPtr p); +	/*virtual*/ void onDelete(LLNotificationPtr p);  };  /**   * Handler for browser notifications   */ -class LLBrowserNotification : public LLSingleton<LLBrowserNotification> +class LLBrowserNotification : public LLNotificationChannel  {  public: -	virtual bool processNotification(const LLSD& notify); +	LLBrowserNotification() +	: LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser")) +	{} +	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); } +	bool processNotification(const LLNotificationPtr& p);  };  /**   * Handler for outbox notifications   */ -class LLOutboxNotification : public LLSingleton<LLOutboxNotification> +class LLOutboxNotification : public LLNotificationChannel  {  public: -	virtual bool processNotification(const LLSD& notify); +	LLOutboxNotification() +	:	LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox")) +	{} +	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); } +	/*virtual*/ void onDelete(LLNotificationPtr p); +	bool processNotification(const LLNotificationPtr& p);  };  class LLHandlerUtil  {  public:  	/** -	 * Checks sufficient conditions to log notification message to IM session. -	 */ -	static bool canLogToIM(const LLNotificationPtr& notification); - -	/** -	 * Checks sufficient conditions to log notification message to nearby chat session. -	 */ -	static bool canLogToNearbyChat(const LLNotificationPtr& notification); - -	/** -	 * Checks sufficient conditions to spawn IM session. -	 */ -	static bool canSpawnIMSession(const LLNotificationPtr& notification); - -	/** -	 * Checks sufficient conditions to add notification toast panel IM floater. -	 */ -	static bool canAddNotifPanelToIM(const LLNotificationPtr& notification); - -	/** -	 * Checks whether notification can be used multiple times or not. -	 */ -	static bool isNotificationReusable(const LLNotificationPtr& notification); - -	/** -	 * Checks if passed notification can create IM session and be written into it. -	 * -	 * This method uses canLogToIM() & canSpawnIMSession(). -	 */ -	static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification); - -	/** -	 * Checks if passed notification can create toast. -	 */ -	static bool canSpawnToast(const LLNotificationPtr& notification); - -	/**  	 * Determines whether IM floater is opened.  	 */  	static bool isIMFloaterOpened(const LLNotificationPtr& notification);  	/** -	* Determines whether IM floater is focused. -	*/ -	static bool isIMFloaterFocused(const LLNotificationPtr& notification); - -	/**  	 * Writes notification message to IM session.  	 */  	static void logToIM(const EInstantMessage& session_type, @@ -355,12 +299,7 @@ public:  	/**  	 * Writes notification message to IM  p2p session.  	 */ -	static void logToIMP2P(const LLNotificationPtr& notification); - -	/** -	 * Writes notification message to IM  p2p session. -	 */ -	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only); +	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);  	/**  	 * Writes group notice notification message to IM  group session. @@ -406,13 +345,6 @@ public:  	 */  	static void decIMMesageCounter(const LLNotificationPtr& notification); -private: - -	/** -	 * Find IM floater based on "from_id" -	 */ -	static LLIMFloater* findIMFloater(const LLNotificationPtr& notification); -  };  } diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 7c6287967a..1494ac6b5c 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -54,7 +54,8 @@ void LLSysHandler::init()  	sExclusiveNotificationGroups.push_back(online_offline_group);  } -LLSysHandler::LLSysHandler() +LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type) +:	LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))  {  	if(sExclusiveNotificationGroups.empty())  	{ @@ -110,131 +111,15 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)  	}  } -const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), -		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), -		OBJECT_GIVE_ITEM("ObjectGiveItem"), -		OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"), -						PAYMENT_RECEIVED("PaymentReceived"), -						PAYMENT_SENT("PaymentSent"), -						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"), -						USER_GIVE_ITEM("UserGiveItem"), -						INVENTORY_ACCEPTED("InventoryAccepted"), -						INVENTORY_DECLINED("InventoryDeclined"), -						OFFER_FRIENDSHIP("OfferFriendship"), -						FRIENDSHIP_ACCEPTED("FriendshipAccepted"), -						FRIENDSHIP_OFFERED("FriendshipOffered"), -						FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"), -						FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"), -						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"), -						SERVER_OBJECT_MESSAGE("ServerObjectMessage"), -						TELEPORT_OFFERED("TeleportOffered"), -						TELEPORT_OFFER_SENT("TeleportOfferSent"), -						IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip"); - - -// static -bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) -{ -	return GRANTED_MODIFY_RIGHTS == notification->getName() -			|| REVOKED_MODIFY_RIGHTS == notification->getName() -			|| PAYMENT_RECEIVED == notification->getName() -			|| PAYMENT_SENT == notification->getName() -			|| OFFER_FRIENDSHIP == notification->getName() -			|| FRIENDSHIP_OFFERED == notification->getName() -			|| FRIENDSHIP_ACCEPTED == notification->getName() -			|| FRIENDSHIP_ACCEPTED_BYME == notification->getName() -			|| FRIENDSHIP_DECLINED_BYME == notification->getName() -			|| SERVER_OBJECT_MESSAGE == notification->getName() -			|| INVENTORY_ACCEPTED == notification->getName() -			|| INVENTORY_DECLINED == notification->getName() -			|| USER_GIVE_ITEM == notification->getName() -			|| TELEPORT_OFFERED == notification->getName() -			|| TELEPORT_OFFER_SENT == notification->getName() -			|| IM_SYSTEM_MESSAGE_TIP == notification->getName(); -} - -// static -bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification) -{ -	return notification->getType() == "notifytip" -			&&  FRIEND_ONLINE != notification->getName() -			&& FRIEND_OFFLINE != notification->getName() -			&& INVENTORY_ACCEPTED != notification->getName() -			&& INVENTORY_DECLINED != notification->getName() -			&& IM_SYSTEM_MESSAGE_TIP != notification->getName(); -} - -// static -bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification) -{ -	return OFFER_FRIENDSHIP == notification->getName() -			|| USER_GIVE_ITEM == notification->getName() -			|| TELEPORT_OFFERED == notification->getName(); -} - -// static -bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification) -{ -	return OFFER_FRIENDSHIP == notification->getName() -					|| USER_GIVE_ITEM == notification->getName() -					|| TELEPORT_OFFERED == notification->getName(); -} -  // static -bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification) -{ -	return OFFER_FRIENDSHIP == notification->getName() -		|| USER_GIVE_ITEM == notification->getName() -		|| TELEPORT_OFFERED == notification->getName(); -} - -// static -bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification) -{ -	return canLogToIM(notification) && canSpawnIMSession(notification); -} - -// static -bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification) +bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)  { -	if(INVENTORY_DECLINED == notification->getName()  -		|| INVENTORY_ACCEPTED == notification->getName()) -	{ -		// return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909) -		return ! isIMFloaterOpened(notification); -	} - -	if(FRIENDSHIP_ACCEPTED == notification->getName()) -	{ -		// don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441 -		return ! isIMFloaterFocused(notification); -	} - -	if(OFFER_FRIENDSHIP == notification->getName() -		|| USER_GIVE_ITEM == notification->getName() -		|| TELEPORT_OFFERED == notification->getName()) -	{ -		// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904 -		return ! isIMFloaterOpened(notification); -	} - -	return true; -} +	bool res = false; -// static -LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification) -{  	LLUUID from_id = notification->getPayload()["from_id"];  	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); -	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -} - -// static -bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) -{ -	bool res = false; +	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -	LLIMFloater* im_floater = findIMFloater(notification);  	if (im_floater != NULL)  	{  		res = im_floater->getVisible() == TRUE; @@ -243,19 +128,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)  	return res;  } -bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification) -{ -	bool res = false; - -	LLIMFloater* im_floater = findIMFloater(notification); -	if (im_floater != NULL) -	{ -		res = im_floater->hasFocus() == TRUE; -	} - -	return res; -} -  // static  void LLHandlerUtil::logToIM(const EInstantMessage& session_type,  		const std::string& session_name, const std::string& from_name, @@ -317,12 +189,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,  	}  } -// static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification) -{ -	logToIMP2P(notification, false); -} -  void log_name_callback(const std::string& full_name, const std::string& from_name,   					   const std::string& message, const LLUUID& from_id) @@ -334,9 +200,6 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam  // static  void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)  { -	// don't create IM p2p session with objects, it's necessary condition to log -	if (notification->getName() != OBJECT_GIVE_ITEM) -	{  		LLUUID from_id = notification->getPayload()["from_id"];  		if (from_id.isNull()) @@ -354,7 +217,6 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi  			gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));  		}  	} -}  // static  void LLHandlerUtil::logGroupNoticeToIMGroup( @@ -489,14 +351,10 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)  	LLUUID from_id = notification->getPayload()["from_id"];  	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); -	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession( -			session_id); +	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id); -	if (session == NULL) +	if (session)  	{ -		return; -	} -  	LLSD arg;  	arg["session_id"] = session_id;  	session->mNumUnread--; @@ -505,3 +363,5 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)  	arg["participant_unread"] = session->mParticipantUnreadMessageCount;  	LLIMModel::getInstance()->mNewMsgSignal(arg);  } +} + diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp index f7163cb04f..271f418507 100644 --- a/indra/newview/llnotificationhinthandler.cpp +++ b/indra/newview/llnotificationhinthandler.cpp @@ -33,26 +33,6 @@  using namespace LLNotificationsUI; -LLHintHandler::LLHintHandler() -{ -} - -LLHintHandler::~LLHintHandler() -{ -} - -bool LLHintHandler::processNotification(const LLSD& notify) -{ -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	std::string sigtype = notify["sigtype"].asString(); -	if (sigtype == "add" || sigtype == "load") -	{ -		LLHints::show(notification); -	} -	else if (sigtype == "delete") -	{ -		LLHints::hide(notification); -	} -	return false; -} +void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); } +void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); } +void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); } diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index f792f53ac5..2862ad6962 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -42,107 +42,35 @@ using namespace LLNotificationsUI;  //--------------------------------------------------------------------------  LLNotificationManager::LLNotificationManager()  { -	mNotifyHandlers.clear();  	init();  }  //--------------------------------------------------------------------------  LLNotificationManager::~LLNotificationManager()  { -	BOOST_FOREACH(listener_pair_t& pair, mChannelListeners) -	{ -		pair.second.disconnect(); -	}  }  //--------------------------------------------------------------------------  void LLNotificationManager::init()  { -	LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify")); -	LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip")); -	LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify")); -	LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")); -	LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); -	LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast")); -	LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer")); -	LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint")); -	LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser")); -	LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox")); +	mChannels.push_back(new LLScriptHandler()); +	mChannels.push_back(new LLTipHandler()); +	mChannels.push_back(new LLGroupHandler()); +	mChannels.push_back(new LLAlertHandler("Alerts", "alert", false)); +	mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true)); +	mChannels.push_back(new LLOfferHandler()); +	mChannels.push_back(new LLHintHandler()); +	mChannels.push_back(new LLBrowserNotification()); +	mChannels.push_back(new LLOutboxNotification()); +	mChannels.push_back(new LLIMHandler()); -	mChannelListeners["Notifications"] = LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["NotificationTips"] = LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["Group Notifications"] = LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["Alerts"] = LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["AlertModal"] = LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["IM Notifications"] = LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["Offer"] = LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); -	mChannelListeners["Hints"] = LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1)); -	mChannelListeners["Browser"] = LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1)); -	mChannelListeners["Outbox"] = LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1)); - -	mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD())); -	mNotifyHandlers["notifytip"] =  boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD())); -	mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD())); -	mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD())); -	mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD())); -	static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true); -	mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD())); -	 -	mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD())); -	mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD())); -} - -//-------------------------------------------------------------------------- -bool LLNotificationManager::onNotification(const LLSD& notify) -{ -	LLSysHandler* handle = NULL; - -	if (LLNotifications::destroyed()) -		return false; - -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); -	 -	if (!notification)  -		return false; - -	std::string notification_type = notification->getType(); -	handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get()); - -	if(!handle) -		return false; -	 -	return handle->processNotification(notify); +	mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler());  }  //--------------------------------------------------------------------------  void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args)  { -	// check ENotificationType argument -	switch(args["type"].asInteger()) -	{ -	case NT_NEARBYCHAT: -		{ -			LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get()); - -			if(handle) -				handle->processChat(msg, args); -		} -		break; -	default: 	//no need to handle all enum types -		break; -	} -} - -//-------------------------------------------------------------------------- -LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type)  -{  -	std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type); - -	if(it != mNotifyHandlers.end()) -		return (*it).second.get(); - -	return NULL; +	if(mChatHandler) +		mChatHandler->processChat(msg, args);  } -//-------------------------------------------------------------------------- - diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 27b6ba1c71..c8afdf9e46 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -28,8 +28,6 @@  #ifndef LL_LLNOTIFICATIONMANAGER_H  #define LL_LLNOTIFICATIONMANAGER_H -#include "llevents.h" -  #include "lluictrl.h"  #include "llnotificationhandler.h" @@ -49,7 +47,6 @@ class LLToast;  class LLNotificationManager : public LLSingleton<LLNotificationManager>  {  	typedef std::pair<std::string, LLEventHandler*> eventhandlers; -	typedef std::pair<const std::string, LLBoundListener> listener_pair_t;  public:	  	LLNotificationManager();	  	virtual ~LLNotificationManager(); @@ -59,22 +56,12 @@ public:  	void init(void);  	//TODO: combine processing and storage (*) -	// this method reacts on system notifications and calls an appropriate handler -	bool onNotification(const LLSD& notification); -  	// this method reacts on chat notifications and calls an appropriate handler  	void onChat(const LLChat& msg, const LLSD &args); -	// get a handler for a certain type of notification -	LLEventHandler* getHandlerForNotification(std::string notification_type); - -  private: -	//TODO (*) -	std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers; -	// cruft std::map<std::string, LLChatHandler*> mChatHandlers; - -	std::map<std::string, LLBoundListener> mChannelListeners; +	boost::shared_ptr<class LLNearbyChatHandler> mChatHandler; +	std::vector<LLNotificationChannelPtr> mChannels;  };  } diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 1552ed3346..52cc518968 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -40,10 +40,9 @@  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- -LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id) +LLOfferHandler::LLOfferHandler() +:	LLSysHandler("Offer", "offer")  { -	mType = type; -  	// Getting a Channel for our notifications  	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();  	if(channel) @@ -68,52 +67,40 @@ void LLOfferHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLOfferHandler::processNotification(const LLSD& notify) +bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false; -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") -	{ -  		if( notification->getPayload().has("give_inventory_notification") -			&& !notification->getPayload()["give_inventory_notification"] ) +		&& notification->getPayload()["give_inventory_notification"].asBoolean() == false)  		{  			// This is an original inventory offer, so add a script floater  			LLScriptFloaterManager::instance().onAddNotification(notification->getID());  		}  		else  		{ -			notification->setReusable(LLHandlerUtil::isNotificationReusable(notification)); +		bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements(); + +		notification->setReusable(add_notif_to_im);  			LLUUID session_id; -			if (LLHandlerUtil::canSpawnIMSession(notification)) +		if (add_notif_to_im)  			{  				const std::string name = LLHandlerUtil::getSubstitutionName(notification);  				LLUUID from_id = notification->getPayload()["from_id"];  				session_id = LLHandlerUtil::spawnIMSession(name, from_id); -			} - -			bool show_toast = LLHandlerUtil::canSpawnToast(notification); -			bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification); -			if (add_notid_to_im) -			{  				LLHandlerUtil::addNotifPanelToIM(notification);  			} @@ -122,46 +109,35 @@ bool LLOfferHandler::processNotification(const LLSD& notify)  			{  				LLNotificationsUtil::cancel(notification);  			} -			else if(show_toast) +		else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))  			{  				LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);  				// don't close notification on panel destroy since it will be used by IM floater -				notify_box->setCloseNotificationOnDestroy(!add_notid_to_im); +			notify_box->setCloseNotificationOnDestroy(!add_notif_to_im);  				LLToast::Params p;  				p.notif_id = notification->getID();  				p.notification = notification;  				p.panel = notify_box; -				p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);  				// we not save offer notifications to the syswell floater that should be added to the IM floater -				p.can_be_stored = !add_notid_to_im; +			p.can_be_stored = !add_notif_to_im;  				LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());  				if(channel)  					channel->addToast(p); - -				// if we not add notification to IM - add it to notification well -				if (!add_notid_to_im) -				{ -					// send a signal to the counter manager -					mNewNotificationSignal(); -				}  			} -			if (LLHandlerUtil::canLogToIM(notification)) +		if (notification->canLogToIM())  			{  				// log only to file if notif panel can be embedded to IM and IM is opened -				if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification)) -				{ -					LLHandlerUtil::logToIMP2P(notification, true); +			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); +			LLHandlerUtil::logToIMP2P(notification, file_only);  				} -				else -				{ -					LLHandlerUtil::logToIMP2P(notification);  				} + +	return false;  			} -		} -	} -	else if (notify["sigtype"].asString() == "delete") + +/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)  	{  		if( notification->getPayload().has("give_inventory_notification")  			&& !notification->getPayload()["give_inventory_notification"] ) @@ -171,7 +147,8 @@ bool LLOfferHandler::processNotification(const LLSD& notify)  		}  		else  		{ -			if (LLHandlerUtil::canAddNotifPanelToIM(notification) +		if (notification->canLogToIM()  +			&& notification->hasFormElements()  					&& !LLHandlerUtil::isIMFloaterOpened(notification))  			{  				LLHandlerUtil::decIMMesageCounter(notification); @@ -180,34 +157,15 @@ bool LLOfferHandler::processNotification(const LLSD& notify)  		}  	} -	return false; -} - -//-------------------------------------------------------------------------- - -void LLOfferHandler::onDeleteToast(LLToast* toast) -{ -	if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification())) -	{ -		// send a signal to the counter manager -		mDelNotificationSignal(); -	} - -	// send a signal to a listener to let him perform some action -	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list -	mNotificationIDSignal(toast->getNotificationID()); -} -  //--------------------------------------------------------------------------  void LLOfferHandler::onRejectToast(LLUUID& id)  {  	LLNotificationPtr notification = LLNotifications::instance().find(id);  	if (notification -			&& LLNotificationManager::getInstance()->getHandlerForNotification( -					notification->getType()) == this +		&& mItems.find(notification) != mItems.end()  					// don't delete notification since it may be used by IM floater -					&& !LLHandlerUtil::canAddNotifPanelToIM(notification)) +		&& (!notification->canLogToIM() || !notification->hasFormElements()))  	{  		LLNotifications::instance().cancel(notification);  	} diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 995915206b..8472f9b2ae 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -37,21 +37,16 @@  using namespace LLNotificationsUI; -static const std::string SCRIPT_DIALOG				("ScriptDialog"); -static const std::string SCRIPT_DIALOG_GROUP		("ScriptDialogGroup"); -static const std::string SCRIPT_LOAD_URL			("LoadWebPage"); -  //-------------------------------------------------------------------------- -LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id) +LLScriptHandler::LLScriptHandler() +:	LLSysHandler("Notifications", "notify")  { -	mType = type; -  	// Getting a Channel for our notifications  	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();  	if(channel)  	{  		channel->setControlHovering(true); -		channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1)); +		channel->addOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));  		mChannel = channel->getHandle();  	}  } @@ -70,32 +65,25 @@ void LLScriptHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLScriptHandler::processNotification(const LLSD& notify) +bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false; -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if(notify["sigtype"].asString() == "add") -	{ -		if (LLHandlerUtil::canLogToIM(notification)) +	if (notification->canLogToIM())  		{  			LLHandlerUtil::logToIMP2P(notification);  		} -		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) +	if(notification->hasFormElements())  		{  			LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());  		} @@ -114,14 +102,15 @@ bool LLScriptHandler::processNotification(const LLSD& notify)  			{  				channel->addToast(p);  			} +	} -			// send a signal to the counter manager -			mNewNotificationSignal(); +	return false;  		} -	} -	else if (notify["sigtype"].asString() == "delete") + + +void LLScriptHandler::onDelete( LLNotificationPtr notification )  	{ -		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) +	if(notification->hasFormElements())  		{  			LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());  		} @@ -130,24 +119,17 @@ bool LLScriptHandler::processNotification(const LLSD& notify)  			mChannel.get()->killToastByNotificationID(notification->getID());  		}  	} -	return false; -} +  //--------------------------------------------------------------------------  void LLScriptHandler::onDeleteToast(LLToast* toast)  { -	// send a signal to the counter manager -	mDelNotificationSignal(); -  	// send a signal to a listener to let him perform some action  	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list -	mNotificationIDSignal(toast->getNotificationID()); -  	LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID()); -	if( notification &&  -		(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) ) +	if( notification && notification->hasFormElements())  	{  		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());  	} @@ -158,9 +140,7 @@ void LLScriptHandler::onRejectToast(LLUUID& id)  {  	LLNotificationPtr notification = LLNotifications::instance().find(id); -	if (notification -			&& LLNotificationManager::getInstance()->getHandlerForNotification( -					notification->getType()) == this) +	if (notification && mItems.find(notification) != mItems.end())  	{  		LLNotifications::instance().cancel(notification);  	} diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index e397cfa046..f07109335d 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -41,15 +41,14 @@  using namespace LLNotificationsUI;  //-------------------------------------------------------------------------- -LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id) +LLTipHandler::LLTipHandler() +:	LLSysHandler("NotificationTips", "notifytip")  { -	mType = type;	 -  	// Getting a Channel for our notifications  	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();  	if(channel)  	{ -		channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1)); +		channel->addOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));  		mChannel = channel->getHandle();  	}  } @@ -68,28 +67,21 @@ void LLTipHandler::initChannel()  }  //-------------------------------------------------------------------------- -bool LLTipHandler::processNotification(const LLSD& notify) +bool LLTipHandler::processNotification(const LLNotificationPtr& notification)  {  	if(mChannel.isDead())  	{  		return false;  	} -	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); - -	if(!notification) -		return false;	 -  	// arrange a channel on a screen  	if(!mChannel.get()->getVisible())  	{  		initChannel();  	} -	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") -	{  		// archive message in nearby chat -		if (LLHandlerUtil::canLogToNearbyChat(notification)) +	if (notification->canLogToChat())  		{  			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM); @@ -109,19 +101,18 @@ bool LLTipHandler::processNotification(const LLSD& notify)  			session_name = name;  		}  		LLUUID from_id = notification->getPayload()["from_id"]; -		if (LLHandlerUtil::canLogToIM(notification)) +	if (notification->canLogToIM())  		{  			LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,  					notification->getMessage(), from_id, from_id);  		} -		if (LLHandlerUtil::canSpawnIMSession(notification)) +	if (notification->canLogToIM() && notification->hasFormElements())  		{  			LLHandlerUtil::spawnIMSession(name, from_id);  		} -		// don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909) -		if (!LLHandlerUtil::canSpawnToast(notification)) +	if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))  		{  			return false;  		} @@ -144,25 +135,18 @@ bool LLTipHandler::processNotification(const LLSD& notify)  	}  	else if (notify["sigtype"].asString() == "delete")  	{ -		mChannel.get()->killToastByNotificationID(notification->getID()); +		mChannel->killToastByNotificationID(notification->getID());  	}  	return false;  }  //-------------------------------------------------------------------------- -void LLTipHandler::onDeleteToast(LLToast* toast) -{ -} - -//--------------------------------------------------------------------------  void LLTipHandler::onRejectToast(const LLUUID& id)  {  	LLNotificationPtr notification = LLNotifications::instance().find(id); -	if (notification -			&& LLNotificationManager::getInstance()->getHandlerForNotification( -					notification->getType()) == this) +	if (notification && mItems.find(notification) != mItems.end())  	{  		LLNotifications::instance().cancel(notification);  	} diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 85626d8783..096e714981 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -28,6 +28,7 @@  #include "lloutputmonitorctrl.h"  // library includes  +#include "llfloaterreg.h"  #include "llui.h"  // viewer includes @@ -241,6 +242,17 @@ void LLOutputMonitorCtrl::draw()  		gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);  } +// virtual +BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask) +{ +	if (mSpeakerId != gAgentID) +	{ +		LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId)); +	} + +	return TRUE; +} +  void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)  {  	if (speaker_id.isNull() && mSpeakerId.notNull()) diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 2d23753d46..7b02e84744 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -68,6 +68,7 @@ public:  	// llview overrides  	virtual void	draw(); +	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);  	void			setPower(F32 val);  	F32				getPower(F32 val) const { return mPower; } diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp index 5c85ec438c..d2dff63948 100644 --- a/indra/newview/llpanelblockedlist.cpp +++ b/indra/newview/llpanelblockedlist.cpp @@ -69,8 +69,6 @@ BOOL LLPanelBlockedList::postBuild()  	mBlockedList = getChild<LLScrollListCtrl>("blocked");  	mBlockedList->setCommitOnSelectionChange(TRUE); -	childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL); -  	LLMuteList::getInstance()->addObserver(this);  	refreshBlockedList(); @@ -99,7 +97,8 @@ void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)  void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)  { -	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect)); +	LLFloaterSidePanelContainer::showPanel("people", "panel_people", +		LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect));  } @@ -130,17 +129,6 @@ void LLPanelBlockedList::updateButtons()  	getChildView("Unblock")->setEnabled(hasSelected);  } - - -void LLPanelBlockedList::onBackBtnClick() -{ -	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); -	if(parent) -	{ -		parent->openPreviousPanel(); -	} -} -  void LLPanelBlockedList::onRemoveBtnClick()  {  	std::string name = mBlockedList->getSelectedItemLabel(); diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h index 74ad82e32d..97236ecdbf 100644 --- a/indra/newview/llpanelblockedlist.h +++ b/indra/newview/llpanelblockedlist.h @@ -68,7 +68,6 @@ private:  	void updateButtons();  	// UI callbacks -	void onBackBtnClick();  	void onRemoveBtnClick();  	void onPickBtnClick();  	void onBlockByNameClick(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 98ea680504..1efd1c3d9c 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -738,15 +738,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const  	if (cat)  	{ -		// Localize "Contents" folder. -		if (cat->getParentUUID().isNull() && cat->getName() == "Contents") -		{ -			mDisplayName.assign(LLTrans::getString("ViewerObjectContents")); -		} -		else -		{ -			mDisplayName.assign(cat->getName()); -		} +		mDisplayName.assign(cat->getName());  	}  	return mDisplayName; @@ -1552,6 +1544,7 @@ void LLPanelObjectInventory::reset()  	p.parent_panel = this;  	p.tool_tip= LLTrans::getString("PanelContentsTooltip");  	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL); +	p.folder_indentation = -14; // subtract space normally reserved for folder expanders  	mFolders = LLUICtrlFactory::create<LLFolderView>(p);  	// this ensures that we never say "searching..." or "no items found"  	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); @@ -1630,10 +1623,11 @@ void LLPanelObjectInventory::updateInventory()  		LLInventoryObject* inventory_root = objectp->getInventoryRoot();  		LLInventoryObject::object_list_t contents;  		objectp->getInventoryContents(contents); -		if (inventory_root) +		mHaveInventory = TRUE; + +		if (inventory_root && !contents.empty())  		{  			createFolderViews(inventory_root, contents); -			mHaveInventory = TRUE;  			mIsInventoryEmpty = FALSE;  			mFolders->setEnabled(TRUE);  		} @@ -1641,7 +1635,6 @@ void LLPanelObjectInventory::updateInventory()  		{  			// TODO: create an empty inventory  			mIsInventoryEmpty = TRUE; -			mHaveInventory = TRUE;  		}  	}  	else @@ -1693,19 +1686,19 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root  	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);  	if(bridge)  	{ -		LLFolderViewFolder* new_folder = NULL; -		LLFolderViewFolder::Params p; -		p.name = inventory_root->getName(); -		p.icon = LLUI::getUIImage("Inv_FolderClosed"); -		p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); -		p.root = mFolders; -		p.listener = bridge; -		p.tool_tip = p.name; -		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); -		new_folder->addToFolder(mFolders, mFolders); -		new_folder->toggleOpen(); - -		createViewsForCategory(&contents, inventory_root, new_folder); +		//LLFolderViewFolder* new_folder = NULL; +		//LLFolderViewFolder::Params p; +		//p.name = inventory_root->getName(); +		//p.icon = LLUI::getUIImage("Inv_FolderClosed"); +		//p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); +		//p.root = mFolders; +		//p.listener = bridge; +		//p.tool_tip = p.name; +		//new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); +		//new_folder->addToFolder(mFolders, mFolders); +		//new_folder->toggleOpen(); + +		createViewsForCategory(&contents, inventory_root, mFolders);  	}  } diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index f1380e7a36..9b06d05b4b 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -72,6 +72,7 @@ static const std::string NEARBY_TAB_NAME	= "nearby_panel";  static const std::string FRIENDS_TAB_NAME	= "friends_panel";  static const std::string GROUP_TAB_NAME		= "groups_panel";  static const std::string RECENT_TAB_NAME	= "recent_panel"; +static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars  static const std::string COLLAPSED_BY_USER  = "collapsed_by_user"; @@ -492,26 +493,37 @@ public:  LLPanelPeople::LLPanelPeople()  	:	LLPanel(), -		mFilterSubString(LLStringUtil::null), -		mFilterSubStringOrig(LLStringUtil::null), -		mFilterEditor(NULL),  		mTabContainer(NULL),  		mOnlineFriendList(NULL),  		mAllFriendList(NULL),  		mNearbyList(NULL),  		mRecentList(NULL),  		mGroupList(NULL), -		mNearbyGearButton(NULL), -		mFriendsGearButton(NULL), -		mGroupsGearButton(NULL), -		mRecentGearButton(NULL),  		mMiniMap(NULL)  {  	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));  	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));  	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));  	mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this)); -	mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); + +	mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); +	mCommitCallbackRegistrar.add("People.AddFriendWizard",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this)); +	mCommitCallbackRegistrar.add("People.DelFriend",		boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this)); +	mCommitCallbackRegistrar.add("People.Group.Minus",		boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this)); +	mCommitCallbackRegistrar.add("People.Chat",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this)); +	mCommitCallbackRegistrar.add("People.Gear",			boost::bind(&LLPanelPeople::onGearButtonClicked,		this, _1)); + +	mCommitCallbackRegistrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2)); +	mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2)); +	mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2)); +	mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2)); +	mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2)); + +	mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2)); +	mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2)); +	mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2)); + +	mEnableCallbackRegistrar.add("People.Group.Plus.Validate",	boost::bind(&LLPanelPeople::onGroupPlusButtonValidate,	this));  }  LLPanelPeople::~LLPanelPeople() @@ -525,13 +537,6 @@ LLPanelPeople::~LLPanelPeople()  	{  		LLVoiceClient::getInstance()->removeObserver(this);  	} - -	if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die(); -	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die(); -	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die(); -	if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die(); -	if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die(); -  }  void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list) @@ -553,11 +558,15 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL  BOOL LLPanelPeople::postBuild()  { -	mFilterEditor = getChild<LLFilterEditor>("filter_input"); -	mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); +	getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); +	getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); +	getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); +	getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	mTabContainer = getChild<LLTabContainer>("tabs");  	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); +	mSavedFilters.resize(mTabContainer->getTabCount()); +	mSavedOriginalFilters.resize(mTabContainer->getTabCount());  	LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);  	// updater is active only if panel is visible to user. @@ -601,14 +610,6 @@ BOOL LLPanelPeople::postBuild()  	setSortOrder(mAllFriendList,	(ESortOrder)gSavedSettings.getU32("FriendsSortOrder"),		false);  	setSortOrder(mNearbyList,		(ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"),	false); -	LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME); -	groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked,	this)); -	groups_panel->childSetAction("plus_btn",	boost::bind(&LLPanelPeople::onGroupPlusButtonClicked,	this)); - -	LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME); -	friends_panel->childSetAction("add_btn",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this)); -	friends_panel->childSetAction("del_btn",	boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this)); -  	mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));  	mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));  	mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); @@ -637,70 +638,9 @@ BOOL LLPanelPeople::postBuild()  	accordion_tab->setDropDownStateChangedCallback(  		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList)); -	buttonSetAction("view_profile_btn",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this)); -	buttonSetAction("group_info_btn",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this)); -	buttonSetAction("chat_btn",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this)); -	buttonSetAction("im_btn",			boost::bind(&LLPanelPeople::onImButtonClicked,			this)); -	buttonSetAction("call_btn",			boost::bind(&LLPanelPeople::onCallButtonClicked,		this)); -	buttonSetAction("group_call_btn",	boost::bind(&LLPanelPeople::onGroupCallButtonClicked,	this)); -	buttonSetAction("teleport_btn",		boost::bind(&LLPanelPeople::onTeleportButtonClicked,	this)); -	buttonSetAction("share_btn",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this)); -  	// Must go after setting commit callback and initializing all pointers to children.  	mTabContainer->selectTabByName(NEARBY_TAB_NAME); -	// Create menus. -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; -	 -	registrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2)); -	registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this)); -	registrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2)); -	registrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2)); -	registrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2)); -	registrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2)); - -	enable_registrar.add("People.Group.Minus.Enable",	boost::bind(&LLPanelPeople::isRealGroup,	this)); -	enable_registrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2)); -	enable_registrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2)); -	enable_registrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2)); - -	mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn"); -	mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn"); -	mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn"); -	mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn"); - -	LLMenuGL* plus_menu  = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	mGroupPlusMenuHandle  = plus_menu->getHandle(); - -	LLToggleableMenu* nearby_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if(nearby_view_sort) -	{ -		mNearbyViewSortMenuHandle  = nearby_view_sort->getHandle(); -		mNearbyGearButton->setMenu(nearby_view_sort); -	} - -	LLToggleableMenu* friend_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if(friend_view_sort) -	{ -		mFriendsViewSortMenuHandle  = friend_view_sort->getHandle(); -		mFriendsGearButton->setMenu(friend_view_sort); -	} - -	LLToggleableMenu* group_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if(group_view_sort) -	{ -		mGroupsViewSortMenuHandle  = group_view_sort->getHandle(); -		mGroupsGearButton->setMenu(group_view_sort); -	} - -	LLToggleableMenu* recent_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if(recent_view_sort) -	{ -		mRecentViewSortMenuHandle  = recent_view_sort->getHandle(); -		mRecentGearButton->setMenu(recent_view_sort); -	} -  	LLVoiceClient::getInstance()->addObserver(this);  	// call this method in case some list is empty and buttons can be in inconsistent state @@ -735,9 +675,11 @@ void LLPanelPeople::updateFriendListHelpText()  	if (no_friends_text->getVisible())  	{  		//update help text for empty lists -		std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg"; +		const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()]; + +		std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg";  		LLStringUtil::format_map_t args; -		args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig); +		args["[SEARCH_TERM]"] = LLURI::escape(filter);  		no_friends_text->setText(getString(message_name, args));  	}  } @@ -821,31 +763,9 @@ void LLPanelPeople::updateRecentList()  	mRecentList->setDirty();  } -void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible) -{ -	// To make sure we're referencing the right widget (a child of the button bar). -	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); -	button->setVisible(visible); -} - -void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled) -{ -	// To make sure we're referencing the right widget (a child of the button bar). -	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); -	button->setEnabled(enabled); -} - -void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb) -{ -	// To make sure we're referencing the right widget (a child of the button bar). -	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name); -	button->setClickedCallback(cb); -} -  void LLPanelPeople::updateButtons()  {  	std::string cur_tab		= getActiveTabName(); -	bool nearby_tab_active	= (cur_tab == NEARBY_TAB_NAME);  	bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);  	bool group_tab_active	= (cur_tab == GROUP_TAB_NAME);  	//bool recent_tab_active	= (cur_tab == RECENT_TAB_NAME); @@ -856,28 +776,15 @@ void LLPanelPeople::updateButtons()  	bool item_selected = (selected_uuids.size() == 1);  	bool multiple_selected = (selected_uuids.size() >= 1); -	buttonSetVisible("group_info_btn",		group_tab_active); -	buttonSetVisible("chat_btn",			group_tab_active); -	buttonSetVisible("view_profile_btn",	!group_tab_active); -	buttonSetVisible("im_btn",				!group_tab_active); -	buttonSetVisible("call_btn",			!group_tab_active); -	buttonSetVisible("group_call_btn",		group_tab_active); -	buttonSetVisible("teleport_btn",		friends_tab_active); -	buttonSetVisible("share_btn",			nearby_tab_active || friends_tab_active); -  	if (group_tab_active)  	{ -		bool cur_group_active = true; -  		if (item_selected)  		{  			selected_id = mGroupList->getSelectedUUID(); -			cur_group_active = (gAgent.getGroupID() == selected_id);  		}  		LLPanel* groups_panel = mTabContainer->getCurrentPanel(); -		groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected -		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); +		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected  	}  	else  	{ @@ -893,26 +800,20 @@ void LLPanelPeople::updateButtons()  		LLPanel* cur_panel = mTabContainer->getCurrentPanel();  		if (cur_panel)  		{ -			cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend); +			if (cur_panel->hasChild("add_friend_btn", TRUE)) +				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend); +  			if (friends_tab_active)  			{ -				cur_panel->getChildView("del_btn")->setEnabled(multiple_selected); +				cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected); +			} + +			if (!group_tab_active) +			{ +				cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected);  			}  		}  	} - -	bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled(); - -	buttonSetEnabled("view_profile_btn",item_selected); -	buttonSetEnabled("share_btn",		item_selected); -	buttonSetEnabled("im_btn",			multiple_selected); // allow starting the friends conference for multiple selection -	buttonSetEnabled("call_btn",		multiple_selected && enable_calls); -	buttonSetEnabled("teleport_btn",	multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids)); - -	bool none_group_selected = item_selected && selected_id.isNull(); -	buttonSetEnabled("group_info_btn", !none_group_selected); -	buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls); -	buttonSetEnabled("chat_btn", !none_group_selected);  }  std::string LLPanelPeople::getActiveTabName() const @@ -943,6 +844,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const  	if (cur_tab == GROUP_TAB_NAME)  		return mGroupList->getSelectedUUID(); +	if (cur_tab == BLOCKED_TAB_NAME) +		return LLUUID::null; // FIXME? +  	llassert(0 && "unknown tab selected");  	return LLUUID::null;  } @@ -963,6 +867,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const  		mRecentList->getSelectedUUIDs(selected_uuids);  	else if (cur_tab == GROUP_TAB_NAME)  		mGroupList->getSelectedUUIDs(selected_uuids); +	else if (cur_tab == BLOCKED_TAB_NAME) +		selected_uuids.clear(); // FIXME?  	else  		llassert(0 && "unknown tab selected"); @@ -1031,49 +937,60 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save  	}  } -bool LLPanelPeople::isRealGroup() -{ -	return getCurrentItemID() != LLUUID::null; -} -  void LLPanelPeople::onFilterEdit(const std::string& search_string)  { -	mFilterSubStringOrig = search_string; -	LLStringUtil::trimHead(mFilterSubStringOrig); +	const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex(); +	std::string& filter = mSavedOriginalFilters[cur_tab_idx]; +	std::string& saved_filter = mSavedFilters[cur_tab_idx]; + +	filter = search_string; +	LLStringUtil::trimHead(filter); +  	// Searches are case-insensitive -	std::string search_upper = mFilterSubStringOrig; +	std::string search_upper = filter;  	LLStringUtil::toUpper(search_upper); -	if (mFilterSubString == search_upper) +	if (saved_filter == search_upper)  		return; -	mFilterSubString = search_upper; +	saved_filter = search_upper; -	//store accordion tabs state before any manipulation with accordion tabs -	if(!mFilterSubString.empty()) +	// Apply new filter to the current tab. +	const std::string cur_tab = getActiveTabName(); +	if (cur_tab == NEARBY_TAB_NAME) +	{ +		mNearbyList->setNameFilter(filter); +	} +	else if (cur_tab == FRIENDS_TAB_NAME) +	{ +		// store accordion tabs opened/closed state before any manipulation with accordion tabs +		if (!saved_filter.empty())  	{  		notifyChildren(LLSD().with("action","store_state"));  	} - -	// Apply new filter. -	mNearbyList->setNameFilter(mFilterSubStringOrig); -	mOnlineFriendList->setNameFilter(mFilterSubStringOrig); -	mAllFriendList->setNameFilter(mFilterSubStringOrig); -	mRecentList->setNameFilter(mFilterSubStringOrig); -	mGroupList->setNameFilter(mFilterSubStringOrig); +		mOnlineFriendList->setNameFilter(filter); +		mAllFriendList->setNameFilter(filter);  	setAccordionCollapsedByUser("tab_online", false);  	setAccordionCollapsedByUser("tab_all", false); -  	showFriendsAccordionsIfNeeded(); -	//restore accordion tabs state _after_ all manipulations... -	if(mFilterSubString.empty()) +		// restore accordion tabs state _after_ all manipulations +		if(saved_filter.empty())  	{  		notifyChildren(LLSD().with("action","restore_state"));  	}  } +	else if (cur_tab == GROUP_TAB_NAME) +	{ +		mGroupList->setNameFilter(filter); +	} +	else if (cur_tab == RECENT_TAB_NAME) +	{ +		mRecentList->setNameFilter(filter); +	} +}  void LLPanelPeople::onTabSelected(const LLSD& param)  { @@ -1081,11 +998,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param)  	updateButtons();  	showFriendsAccordionsIfNeeded(); - -	if (GROUP_TAB_NAME == tab_name) -		mFilterEditor->setLabel(getString("groups_filter_label")); -	else -		mFilterEditor->setLabel(getString("people_filter_label"));  }  void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) @@ -1127,12 +1039,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)  	updateButtons();  } -void LLPanelPeople::onViewProfileButtonClicked() -{ -	LLUUID id = getCurrentItemID(); -	LLAvatarActions::showProfile(id); -} -  void LLPanelPeople::onAddFriendButtonClicked()  {  	LLUUID id = getCurrentItemID(); @@ -1191,11 +1097,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked()  	}  } -void LLPanelPeople::onGroupInfoButtonClicked() -{ -	LLGroupActions::show(getCurrentItemID()); -} -  void LLPanelPeople::onChatButtonClicked()  {  	LLUUID group_id = getCurrentItemID(); @@ -1203,6 +1104,14 @@ void LLPanelPeople::onChatButtonClicked()  		LLGroupActions::startIM(group_id);  } +void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn) +{ +	uuid_vec_t selected_uuids; +	getCurrentItemIDs(selected_uuids); +	// Spawn at bottom left corner of the button. +	LLPanelPeopleMenus::gNearbyMenu.show(btn, selected_uuids, 0, 0); +} +  void LLPanelPeople::onImButtonClicked()  {  	uuid_vec_t selected_uuids; @@ -1219,11 +1128,6 @@ void LLPanelPeople::onImButtonClicked()  	}  } -void LLPanelPeople::onActivateButtonClicked() -{ -	LLGroupActions::activate(mGroupList->getSelectedUUID()); -} -  // static  void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)  { @@ -1231,19 +1135,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv  		LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());  } -void LLPanelPeople::onGroupPlusButtonClicked() +bool LLPanelPeople::onGroupPlusButtonValidate()  {  	if (!gAgent.canJoinGroups())  	{  		LLNotificationsUtil::add("JoinedTooManyGroups"); -		return; +		return false;  	} -	LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get(); -	if (!plus_menu) -		return; - -	showGroupMenu(plus_menu); +	return true;  }  void LLPanelPeople::onGroupMinusButtonClicked() @@ -1288,10 +1188,6 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)  		mAllFriendList->showPermissions(show_permissions);  		mOnlineFriendList->showPermissions(show_permissions);  	} -	else if (chosen_item == "panel_block_list_sidetray") -	{ -		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); -	}  }  void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata) @@ -1324,10 +1220,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)  	{  		setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);  	} -	else if (chosen_item == "panel_block_list_sidetray") -	{ -		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); -	}  }  bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata) @@ -1361,10 +1253,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)  	{  		mRecentList->toggleIcons();  	} -	else if (chosen_item == "panel_block_list_sidetray") -	{ -		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD()); -	}  }  bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata)  @@ -1393,40 +1281,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata)  	return false;  } -void LLPanelPeople::onCallButtonClicked() -{ -	uuid_vec_t selected_uuids; -	getCurrentItemIDs(selected_uuids); - -	if (selected_uuids.size() == 1) -	{ -		// initiate a P2P voice chat with the selected user -		LLAvatarActions::startCall(getCurrentItemID()); -	} -	else if (selected_uuids.size() > 1) -	{ -		// initiate an ad-hoc voice chat with multiple users -		LLAvatarActions::startAdhocCall(selected_uuids); -	} -} - -void LLPanelPeople::onGroupCallButtonClicked() -{ -	LLGroupActions::startCall(getCurrentItemID()); -} - -void LLPanelPeople::onTeleportButtonClicked() -{ -	uuid_vec_t selected_uuids; -	getCurrentItemIDs(selected_uuids); -	LLAvatarActions::offerTeleport(selected_uuids); -} - -void LLPanelPeople::onShareButtonClicked() -{ -	LLAvatarActions::share(getCurrentItemID()); -} -  void LLPanelPeople::onMoreButtonClicked()  {  	// *TODO: not implemented yet diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 46c58cd139..da27f83074 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -80,31 +80,22 @@ private:  	std::string				getActiveTabName() const;  	LLUUID					getCurrentItemID() const;  	void					getCurrentItemIDs(uuid_vec_t& selected_uuids) const; -	void					buttonSetVisible(std::string btn_name, BOOL visible); -	void					buttonSetEnabled(const std::string& btn_name, bool enabled); -	void					buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);  	void					showGroupMenu(LLMenuGL* menu);  	void					setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);  	// UI callbacks  	void					onFilterEdit(const std::string& search_string);  	void					onTabSelected(const LLSD& param); -	void					onViewProfileButtonClicked();  	void					onAddFriendButtonClicked();  	void					onAddFriendWizButtonClicked();  	void					onDeleteFriendButtonClicked(); -	void					onGroupInfoButtonClicked();  	void					onChatButtonClicked(); +	void					onGearButtonClicked(LLUICtrl* btn);  	void					onImButtonClicked(); -	void					onCallButtonClicked(); -	void					onGroupCallButtonClicked(); -	void					onTeleportButtonClicked(); -	void					onShareButtonClicked();  	void					onMoreButtonClicked(); -	void					onActivateButtonClicked();  	void					onAvatarListDoubleClicked(LLUICtrl* ctrl);  	void					onAvatarListCommitted(LLAvatarList* list); -	void					onGroupPlusButtonClicked(); +	bool					onGroupPlusButtonValidate();  	void					onGroupMinusButtonClicked();  	void					onGroupPlusMenuItemClicked(const LLSD& userdata); @@ -113,8 +104,6 @@ private:  	void					onGroupsViewSortMenuItemClicked(const LLSD& userdata);  	void					onRecentViewSortMenuItemClicked(const LLSD& userdata); -	//returns false only if group is "none" -	bool					isRealGroup();  	bool					onFriendsViewSortMenuItemCheck(const LLSD& userdata);  	bool					onRecentViewSortMenuItemCheck(const LLSD& userdata);  	bool					onNearbyViewSortMenuItemCheck(const LLSD& userdata); @@ -135,7 +124,6 @@ private:  	bool					isAccordionCollapsedByUser(LLUICtrl* acc_tab);  	bool					isAccordionCollapsedByUser(const std::string& name); -	LLFilterEditor*			mFilterEditor;  	LLTabContainer*			mTabContainer;  	LLAvatarList*			mOnlineFriendList;  	LLAvatarList*			mAllFriendList; @@ -144,24 +132,13 @@ private:  	LLGroupList*			mGroupList;  	LLNetMap*				mMiniMap; -	LLHandle<LLView>		mGroupPlusMenuHandle; -	LLHandle<LLView>		mNearbyViewSortMenuHandle; -	LLHandle<LLView>		mFriendsViewSortMenuHandle; -	LLHandle<LLView>		mGroupsViewSortMenuHandle; -	LLHandle<LLView>		mRecentViewSortMenuHandle; +	std::vector<std::string> mSavedOriginalFilters; +	std::vector<std::string> mSavedFilters;  	Updater*				mFriendListUpdater;  	Updater*				mNearbyListUpdater;  	Updater*				mRecentListUpdater;  	Updater*				mButtonsUpdater; - -	LLMenuButton*			mNearbyGearButton; -	LLMenuButton*			mFriendsGearButton; -	LLMenuButton*			mGroupsGearButton; -	LLMenuButton*			mRecentGearButton; - -	std::string				mFilterSubString; -	std::string				mFilterSubStringOrig;  };  #endif //LL_LLPANELPEOPLE_H diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 88727bf59b..29eb5ce69e 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -305,7 +305,11 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)  {  	if (mEditorCore)  	{ -		return mEditorCore->handleKeyHere(key, mask); +		BOOL handled = mEditorCore->handleKeyHere(key, mask); +		if (!handled) +		{ +			LLFloater::handleKeyHere(key, mask); +		}  	}  	return FALSE; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index d340b304ca..003b53b28c 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -253,7 +253,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)  {  	bool store_toast = false, show_toast = false; -	mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show); +	if (mDisplayToastsAlways) +	{ +		show_toast = true; +	} +	else +	{ +		show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show); +	}  	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;  	if(!show_toast && !store_toast) @@ -371,7 +378,7 @@ void LLScreenChannel::storeToast(ToastElem& toast_elem)  	const LLToast* toast = toast_elem.getToast();  	if (toast)  	{ -		mStoredToastList.push_back(toast_elem); +	mStoredToastList.push_back(toast_elem);  		mOnStoreToast(toast->getPanel(), toast->getNotificationID());  	}  } @@ -410,14 +417,14 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)  	LLToast* toast = it->getToast();  	if (toast)  	{ -		if(toast->getVisible()) -		{ -			// toast is already in channel -			return; -		} +	if(toast->getVisible()) +	{ +		// toast is already in channel +		return; +	} -		toast->setIsHidden(false); -		toast->startTimer(); +	toast->setIsHidden(false); +	toast->startTimer();  		mToastList.push_back(*it);  	} @@ -444,7 +451,7 @@ void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)  	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);  	if (it != mStoredToastList.end())  	{ -		mStoredToastList.erase(it); +	mStoredToastList.erase(it);  	}  } @@ -480,16 +487,16 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)  	// searching among stored toasts  	it = find(mStoredToastList.begin(), mStoredToastList.end(), id); -	if (it != mStoredToastList.end()) +	if( it != mStoredToastList.end() )  	{  		LLToast* toast = it->getToast();  		if (toast)  		{ -			// send signal to a listener to let him perform some action on toast rejecting -			mRejectToastSignal(toast->getNotificationID()); -			deleteToast(toast); -		} +		// send signal to a listener to let him perform some action on toast rejecting +		mRejectToastSignal(toast->getNotificationID()); +		deleteToast(toast);  	} +}  	// Call find() once more, because the mStoredToastList could have been changed  	// in mRejectToastSignal callback and the iterator could have become invalid. @@ -521,11 +528,11 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)  		LLToast* toast = it->getToast();  		if (toast)  		{ -			LLPanel* old_panel = toast->getPanel(); -			toast->removeChild(old_panel); -			delete old_panel; -			toast->insertPanel(panel); -			toast->startTimer(); +		LLPanel* old_panel = toast->getPanel(); +		toast->removeChild(old_panel); +		delete old_panel; +		toast->insertPanel(panel); +		toast->startTimer();  		}  		redrawToasts();  	} @@ -679,7 +686,7 @@ void LLScreenChannel::showToastsCentre()  		return;  	} -	LLRect	toast_rect; +	LLRect	toast_rect;	  	S32		bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2;  	std::vector<ToastElem>::reverse_iterator it; diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 56a9cf8b4b..eaff61a0f4 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -227,16 +227,16 @@ public:  	// Channel's signals  	// signal on storing of faded toasts event -	typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t; -	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t; -	store_tost_signal_t mOnStoreToast;	 -	boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); } +	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t; +	boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }  	// signal on rejecting of a toast event -	typedef boost::function<void (LLUUID id)> reject_tost_callback_t; -	typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t; -	reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); } +	typedef boost::signals2::signal<void (LLUUID id)> reject_toast_signal_t; +	boost::signals2::connection addOnRejectToastCallback(reject_toast_signal_t::slot_type cb) { return mRejectToastSignal.connect(cb); }  private: +	store_toast_signal_t mOnStoreToast;	 +	reject_toast_signal_t mRejectToastSignal;  +  	class ToastElem  	{  	public: diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5d196a465f..1333862855 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2774,7 +2774,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)  void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)  { -	gGL.diffuseColor4fv(color.mV); +	gGL.color4fv(color.mV);  	gGL.begin(LLRender::LINES);  	{  		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV); @@ -3904,7 +3904,7 @@ void renderAgentTarget(LLVOAvatar* avatar)  	if (avatar->isSelf())  	{  		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); -		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); +		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));  		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));  		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));  	} diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 0cb6c85012..18e0d9d0d2 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -433,13 +433,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas  //////////////////////////////////////////////////////////////////////////  // PUBLIC METHODS +LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window) +:	LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())), +	mWellWindow(well_window) +{ +	connectToChannel("Notifications"); +	connectToChannel("Group Notifications"); +	connectToChannel("Offer"); +} +  LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key) -: LLSysWellWindow(key) +:	LLSysWellWindow(key)  { -	// init connections to the list's update events -	connectListUpdaterToSignal("notify"); -	connectListUpdaterToSignal("groupnotify"); -	connectListUpdaterToSignal("offer"); +	mNotificationUpdates.reset(new WellNotificationChannel(this));  }  // static @@ -519,7 +525,7 @@ void LLNotificationWellWindow::initChannel()  	LLSysWellWindow::initChannel();  	if(mChannel)  	{ -		mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2)); +		mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));  	}  } @@ -546,20 +552,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)  	addItem(p);  } -void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type) -{ -	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance(); -	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type); -	if(n_handler) -	{ -		n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1)); -	} -	else -	{ -		llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl; -	} -} -  void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)  {  	LLUUID id = item->getID(); @@ -574,6 +566,12 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)  		mChannel->killToastByNotificationID(id);  } +void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) +{ +	removeItemByID(notify->getID()); +} + +  /************************************************************************/ @@ -867,4 +865,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo  	return false;  } -// EOF + diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 272e9cfcb1..f497f546aa 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -34,6 +34,7 @@  #include "llscreenchannel.h"  #include "llscrollcontainer.h"  #include "llimview.h" +#include "llnotifications.h"  #include "boost/shared_ptr.hpp" @@ -111,7 +112,7 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void setVisible(BOOL visible); - +	/*virtual*/ void onAdd(LLNotificationPtr notify);  	// Operating with items  	void addItem(LLSysWellItem::Params p); @@ -119,6 +120,18 @@ public:  	void closeAll();  protected: +	struct WellNotificationChannel : public LLNotificationChannel +	{ +		WellNotificationChannel(LLNotificationWellWindow*); +		void onDelete(LLNotificationPtr notify) +		{ +			mWellWindow->removeItemByID(notify->getID()); +		}  + +		LLNotificationWellWindow* mWellWindow; +	}; + +	LLNotificationChannelPtr mNotificationUpdates;  	/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }  private: @@ -126,12 +139,8 @@ private:  	void initChannel();  	void clearScreenChannels(); -  	void onStoreToast(LLPanel* info_panel, LLUUID id); -	// connect counter and list updaters to the corresponding signals -	void connectListUpdaterToSignal(std::string notification_type); -  	// Handlers  	void onItemClick(LLSysWellItem* item);  	void onItemClose(LLSysWellItem* item); diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 75178a6ef8..707d2d9765 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -51,7 +51,7 @@  const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 7; -LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification) +LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification)  :	LLToastPanel(notification),  	mInventoryOffer(NULL)  { diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h index 7794ec9f63..dfdc6ae559 100644 --- a/indra/newview/lltoastgroupnotifypanel.h +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -47,13 +47,10 @@ class LLToastGroupNotifyPanel  public:  	void close(); -	static bool onNewNotification(const LLSD& notification); - -  	// Non-transient messages.  You can specify non-default button  	// layouts (like one for script dialogs) by passing various  	// numbers in for "layout". -	LLToastGroupNotifyPanel(LLNotificationPtr& notification); +	LLToastGroupNotifyPanel(const LLNotificationPtr& notification);  	/*virtual*/ ~LLToastGroupNotifyPanel();  protected: diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index de305bf3d9..dc5cc88dc4 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -52,7 +52,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;  LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) :  +LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) :   LLToastPanel(notification),  mTextBox(NULL),  mInfoPanel(NULL), @@ -536,7 +536,7 @@ void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id  	}  } -void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification) +void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)  {  	LLSD response = notification->getResponse();  	for (LLSD::map_const_iterator response_it = response.beginMap();  diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 57711b3d80..db517ec858 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -60,7 +60,7 @@ public:  	 * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to  	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.  	 */ -	LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); +	LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);  	virtual ~LLToastNotifyPanel();  	LLPanel * getControlPanel() { return mControlPanel; } @@ -118,7 +118,7 @@ protected:  	/**  	 * Process response data. Will disable selected options  	 */ -	void disableRespondedOptions(LLNotificationPtr& notification); +	void disableRespondedOptions(const LLNotificationPtr& notification);  	bool mIsTip;  	bool mAddedDefaultBtn; diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h index 8e69d8834d..7d33446248 100644 --- a/indra/newview/lltoastscripttextbox.h +++ b/indra/newview/lltoastscripttextbox.h @@ -39,8 +39,6 @@ class LLToastScriptTextbox  public:  	void close(); -	static bool onNewNotification(const LLSD& notification); -  	// Non-transient messages.  You can specify non-default button  	// layouts (like one for script dialogs) by passing various  	// numbers in for "layout". diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7fdaac68c8..5ced32a9ab 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -110,6 +110,7 @@  #include "llfloatertranslationsettings.h"  #include "llfloateruipreview.h"  #include "llfloatervoiceeffect.h" +#include "llfloatervoicevolume.h"  #include "llfloaterwhitelistentry.h"  #include "llfloaterwindowsize.h"  #include "llfloaterworldmap.h" @@ -220,6 +221,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLInspectGroupUtil::registerFloater();  	LLInspectObjectUtil::registerFloater();  	LLInspectRemoteObjectUtil::registerFloater(); +	LLFloaterVoiceVolumeUtil::registerFloater();  	LLNotificationsUI::registerFloater();  	LLFloaterDisplayNameUtil::registerFloater(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 12aed8f448..d75651835f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3190,15 +3190,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)  	return new_value;  } - -void login_done(S32 which, void *user) -{ -	llinfos << "Login done " << which << llendl; - -	LLPanelLogin::closePanel(); -} - -  bool callback_leave_group(const LLSD& notification, const LLSD& response)  {  	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 2917fee62e..c2bafd043d 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1148,7 +1148,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)  		}  	}  } - +   // Return "true" if we have a preview method for that asset type, "false" otherwise  bool check_asset_previewable(const LLAssetType::EType asset_type)  { @@ -2373,7 +2373,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;  			bool mute_im = is_muted; -			if (accept_im_from_only_friend && !is_friend) +			if(accept_im_from_only_friend&&!is_friend)  			{  				if (!gIMMgr->isNonFriendSessionNotified(session_id))  				{ @@ -2796,7 +2796,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				chat.mOwnerID = from_id;  				LLSD args;  				args["slurl"] = location; -				args["type"] = LLNotificationsUI::NT_NEARBYCHAT;  				// Look for IRC-style emotes here so object name formatting is correct  				std::string prefix = message.substr(0, 4); @@ -3399,7 +3398,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  		// pass owner_id to chat so that we can display the remote  		// object inspect for an object that is chatting with you  		LLSD args; -		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;  		chat.mOwnerID = owner_id;  		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 589714c25c..117078bcd1 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -610,7 +610,7 @@ public:  				addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,  					LLMeshRepository::sHTTPRetryCount));  				ypos += y_inc; -				 +  				addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));  				ypos += y_inc; @@ -1542,13 +1542,14 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	// pass its value right now. Instead, pass it a nullary function that  	// will, when we later need it, return the value of gKeyboard.  	// boost::lambda::var() constructs such a functor on the fly. -	mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard))); -	mViewerWindowListener.reset(new LLViewerWindowListener(this)); -	LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")); -	LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); +	mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))), +	mViewerWindowListener(new LLViewerWindowListener(this)), -	LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert); -	LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert); +	LLNotificationChannelPtr vw_alerts_channel(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"))); +	LLNotificationChannelPtr vw_alerts_modal_channel(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"))); + +	vw_alerts_channel->connectChanged(&LLViewerWindow::onAlert); +	vw_alerts_modal_channel->connectChanged(&LLViewerWindow::onAlert);  	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));  	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; @@ -1969,12 +1970,12 @@ void LLViewerWindow::shutdownViews()  		gMorphView->setVisible(FALSE);  	}  	llinfos << "Global views cleaned." << llendl ; - +	  	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open  	// will crump with LL_ERRS.  	LLModalDialog::shutdownModals();  	llinfos << "LLModalDialog shut down." << llendl;  -	 +  	// destroy the nav bar, not currently part of gViewerWindow  	// *TODO: Make LLNavigationBar part of gViewerWindow  	if (LLNavigationBar::instanceExists()) @@ -1982,17 +1983,17 @@ void LLViewerWindow::shutdownViews()  		delete LLNavigationBar::getInstance();  	}  	llinfos << "LLNavigationBar destroyed." << llendl ; - +	  	// destroy menus after instantiating navbar above, as it needs  	// access to gMenuHolder  	cleanup_menus();  	llinfos << "menus destroyed." << llendl ; - +	  	// Delete all child views.  	delete mRootView;  	mRootView = NULL;  	llinfos << "RootView deleted." << llendl ; - +	  	// Automatically deleted as children of mRootView.  Fix the globals.  	gStatusBar = NULL;  	gIMMgr = NULL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bc7f5a9744..e1d29da664 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -62,6 +62,7 @@  #include "llhudmanager.h"  #include "llhudnametag.h"  #include "llhudtext.h"				// for mText/mDebugText +#include "llinitparam.h"  #include "llkeyframefallmotion.h"  #include "llkeyframestandmotion.h"  #include "llkeyframewalkmotion.h" @@ -193,6 +194,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;  const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;  const F32 CHAT_FADE_TIME = 8.0;  const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; +const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f; +const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; +const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;  const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); @@ -224,55 +228,62 @@ struct LLTextureMaskData   **/  //------------------------------------------------------------------------ -// LLVOBoneInfo +// LLVOAvatarBoneInfo  // Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.  //------------------------------------------------------------------------ -class LLVOAvatarBoneInfo +struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>  { -	friend class LLVOAvatar; -	friend class LLVOAvatarSkeletonInfo; -public: -	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} -	~LLVOAvatarBoneInfo() -	{ -		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); +	LLVOAvatarCollisionVolumeInfo()  +	:	name("name"), +		pos("pos"), +		rot("rot"), +		scale("scale") +	{} + +	Mandatory<std::string>	name; +	Mandatory<LLVector3>	pos, +							rot, +							scale; +}; + +struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint> +{ +	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone; +	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume; + +	LLVOAvatarChildJoint() +	:	bone("bone"), +		collision_volume("collision_volume") +	{} +}; + +struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo> +{ +	LLVOAvatarBoneInfo()  +	:	pivot("pivot") +	{} -private: -	std::string mName; -	BOOL mIsJoint; -	LLVector3 mPos; -	LLVector3 mRot; -	LLVector3 mScale; -	LLVector3 mPivot; -	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t; -	child_list_t mChildList; +	Mandatory<LLVector3>					pivot; +	Multiple<LLVOAvatarChildJoint>			children;  };  //------------------------------------------------------------------------  // LLVOAvatarSkeletonInfo  // Overall avatar skeleton  //------------------------------------------------------------------------ -class LLVOAvatarSkeletonInfo +struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>  { -	friend class LLVOAvatar; -public: -	LLVOAvatarSkeletonInfo() : -		mNumBones(0), mNumCollisionVolumes(0) {} -	~LLVOAvatarSkeletonInfo() -	{ -		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); -	S32 getNumBones() const { return mNumBones; } -	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } +	LLVOAvatarSkeletonInfo() +	:	skeleton_root(""), +		num_bones("num_bones"), +		num_collision_volumes("num_collision_volumes"), +		version("version") +	{} -private: -	S32 mNumBones; -	S32 mNumCollisionVolumes; -	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t; -	bone_info_list_t mBoneInfoList; +	Mandatory<std::string>			version; +	Mandatory<S32>					num_bones, +									num_collision_volumes; +	Mandatory<LLVOAvatarChildJoint>	skeleton_root;  };  //----------------------------------------------------------------------------- @@ -597,7 +608,7 @@ private:  // Static Data  //-----------------------------------------------------------------------------  LLXmlTree LLVOAvatar::sXMLTree; -LLXmlTree LLVOAvatar::sSkeletonXMLTree; +LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree;  LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;  LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;  LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL; @@ -698,9 +709,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	LLMemType mt(LLMemType::MTYPE_AVATAR);  	//VTResume();  // VTune +#ifdef XXX_STINSON_CHUI_REWORK  	// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline  	const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job  	mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim ); +#else // XXX_STINSON_CHUI_REWORK +	mVoiceVisualizer = new LLVoiceVisualizer(); +#endif // XXX_STINSON_CHUI_REWORK  	lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl; @@ -859,7 +874,11 @@ void LLVOAvatar::markDead()  		mNameText = NULL;  		sNumVisibleChatBubbles--;  	} +#ifdef XXX_STINSON_CHUI_REWORK  	mVoiceVisualizer->markDead(); +#else // XXX_STINSON_CHUI_REWORK +	mVoiceVisualizer->setStopSpeaking(); +#endif // XXX_STINSON_CHUI_REWORK  	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;  	LLViewerObject::markDead();  } @@ -1123,18 +1142,6 @@ void LLVOAvatar::initClass()  		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;  	} -	// Process XML data - -	// avatar_skeleton.xml -	if (sAvatarSkeletonInfo) -	{ //this can happen if a login attempt failed -		delete sAvatarSkeletonInfo; -	} -	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; -	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) -	{ -		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; -	}  	// parse avatar_lad.xml  	if (sAvatarXmlInfo)  	{ //this can happen if a login attempt failed @@ -1183,7 +1190,7 @@ void LLVOAvatar::initClass()  void LLVOAvatar::cleanupClass()  {  	deleteAndClear(sAvatarXmlInfo); -	sSkeletonXMLTree.cleanup(); +	sSkeletonXMLTree = NULL;  	sXMLTree.cleanup();  } @@ -1329,7 +1336,9 @@ void LLVOAvatar::initInstance(void)  	//VTPause();  // VTune +#ifdef XXX_STINSON_CHUI_REWORK  	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) ); +#endif // XXX_STINSON_CHUI_REWORK  } @@ -1655,33 +1664,39 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)  	//-------------------------------------------------------------------------  	// parse the file  	//------------------------------------------------------------------------- -	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); +	 +	LLXMLNodePtr skeleton_xml; +	BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL); -	if (!parsesuccess) +	if (!parsesuccess || skeleton_xml.isNull())  	{  		llerrs << "Can't parse skeleton file: " << filename << llendl;  		return FALSE;  	} -	// now sanity check xml file -	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); -	if (!root)  +	// Process XML data +	if (sAvatarSkeletonInfo) +	{ //this can happen if a login attempt failed +		delete sAvatarSkeletonInfo; +	} +	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; + +	LLXUIParser parser; +	parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename); +	if (!sAvatarSkeletonInfo->validateBlock())  	{ -		llerrs << "No root node found in avatar skeleton file: " << filename << llendl; -		return FALSE; +		llerrs << "Error parsing skeleton XML file: " << filename << llendl;  	} -	if( !root->hasName( "linden_skeleton" ) ) +	if( !skeleton_xml->hasName( "linden_skeleton" ) )  	{  		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;  		return FALSE;  	} -	std::string version; -	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); -	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) +	if (sAvatarSkeletonInfo->version() != "1.0")  	{ -		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; +		llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl;  		return FALSE;  	} @@ -1690,14 +1705,13 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)  //-----------------------------------------------------------------------------  // setupBone() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) +//----------------------------------------------------------- +BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)  {  	LLMemType mt(LLMemType::MTYPE_AVATAR);  	LLViewerJoint* joint = NULL; - -	if (info->mIsJoint) +	if (info.bone.isChosen())  	{  		joint = (LLViewerJoint*)getCharacterJoint(joint_num);  		if (!joint) @@ -1705,7 +1719,23 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent  			llwarns << "Too many bones" << llendl;  			return FALSE;  		} -		joint->setName( info->mName ); +		joint->setName( info.bone().name ); +		joint->setPosition(info.bone().pos); +		joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ)); +		joint->setScale(info.bone().scale); +		joint->setSkinOffset( info.bone().pivot ); +		joint_num++; + +		for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(), +				end_it = info.bone().children.end(); +			child_it != end_it; +			++child_it) +		{ +			if (!setupBone(*child_it, joint, volume_num, joint_num)) +			{ +				return FALSE; +			} +		}  	}  	else // collision volume  	{ @@ -1715,7 +1745,11 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent  			return FALSE;  		}  		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]); -		joint->setName( info->mName ); +		joint->setName( info.collision_volume.name); +		joint->setPosition(info.collision_volume.pos); +		joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ)); +		joint->setScale(info.collision_volume.scale); +		volume_num++;  	}  	// add to parent @@ -1724,34 +1758,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent  		parent->addChild( joint );  	} -	joint->setPosition(info->mPos); -	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], -							 info->mRot.mV[VZ], LLQuaternion::XYZ)); -	joint->setScale(info->mScale); -  	joint->setDefaultFromCurrentXform(); -	if (info->mIsJoint) -	{ -		joint->setSkinOffset( info->mPivot ); -		joint_num++; -	} -	else // collision volume -	{ -		volume_num++; -	} - -	// setup children -	LLVOAvatarBoneInfo::child_list_t::const_iterator iter; -	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) -	{ -		LLVOAvatarBoneInfo *child_info = *iter; -		if (!setupBone(child_info, joint, volume_num, joint_num)) -		{ -			return FALSE; -		} -	} -  	return TRUE;  } @@ -1765,35 +1773,31 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)  	//-------------------------------------------------------------------------  	// allocate joints  	//------------------------------------------------------------------------- -	if (!allocateCharacterJoints(info->mNumBones)) +	if (!allocateCharacterJoints(info->num_bones))  	{ -		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; +		llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl;  		return FALSE;  	}  	//-------------------------------------------------------------------------  	// allocate volumes  	//------------------------------------------------------------------------- -	if (info->mNumCollisionVolumes) +	if (info->num_collision_volumes)  	{ -		if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) +		if (!allocateCollisionVolumes(info->num_collision_volumes))  		{ -			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; +			llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl;  			return FALSE;  		}  	}  	S32 current_joint_num = 0;  	S32 current_volume_num = 0; -	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; -	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) + +	if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num))  	{ -		LLVOAvatarBoneInfo *info = *iter; -		if (!setupBone(info, NULL, current_volume_num, current_joint_num)) -		{ -			llerrs << "Error parsing bone in skeleton file" << llendl; -			return FALSE; -		} +		llerrs << "Error parsing bone in skeleton file" << llendl; +		return FALSE;  	}  	return TRUE; @@ -2430,6 +2434,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)  { +#ifdef XXX_STINSON_CHUI_REWORK  	bool render_visualizer = voice_enabled;  	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled. @@ -2442,6 +2447,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)  	}  	mVoiceVisualizer->setVoiceEnabled(render_visualizer); +#endif // XXX_STINSON_CHUI_REWORK  	if ( voice_enabled )  	{		 @@ -2517,6 +2523,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)  			}  		} +#ifdef XXX_STINSON_CHUI_REWORK  		//--------------------------------------------------------------------------------------------  		// here we get the approximate head position and set as sound source for the voice symbol  		// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) @@ -2534,6 +2541,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)  			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );  			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );  		} +#endif // XXX_STINSON_CHUI_REWORK  	}//if ( voiceEnabled )  }		 @@ -2922,43 +2930,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		return;  	} -		BOOL new_name = FALSE; -		if (visible_chat != mVisibleChat) -		{ -			mVisibleChat = visible_chat; -			new_name = TRUE; -		} +	BOOL new_name = FALSE; +	if (visible_chat != mVisibleChat) +	{ +		mVisibleChat = visible_chat; +		new_name = TRUE; +	} -		if (sRenderGroupTitles != mRenderGroupTitles) -		{ -			mRenderGroupTitles = sRenderGroupTitles; -			new_name = TRUE; -		} +	if (sRenderGroupTitles != mRenderGroupTitles) +	{ +		mRenderGroupTitles = sRenderGroupTitles; +		new_name = TRUE; +	} -		// First Calculate Alpha -		// If alpha > 0, create mNameText if necessary, otherwise delete it -			F32 alpha = 0.f; -			if (mAppAngle > 5.f) +	// First Calculate Alpha +	// If alpha > 0, create mNameText if necessary, otherwise delete it +		F32 alpha = 0.f; +		if (mAppAngle > 5.f) +		{ +			const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; +			if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)  			{ -				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; -				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) -				{ -					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; -				} -				else -				{ -					// ...not fading, full alpha -					alpha = 1.f; -				} +				alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;  			} -			else if (mAppAngle > 2.f) +			else  			{ -				// far away is faded out also -				alpha = (mAppAngle-2.f)/3.f; +				// ...not fading, full alpha +				alpha = 1.f;  			} +		} +		else if (mAppAngle > 2.f) +		{ +			// far away is faded out also +			alpha = (mAppAngle-2.f)/3.f; +		}  	if (alpha <= 0.f) -			{ +	{  		if (mNameText)  		{  			mNameText->markDead(); @@ -2968,31 +2976,30 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		return;  	} -				if (!mNameText) -				{ +	if (!mNameText) +	{  		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(  			LLHUDObject::LL_HUD_NAME_TAG) );  		//mNameText->setMass(10.f); -					mNameText->setSourceObject(this); +		mNameText->setSourceObject(this);  		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); -					mNameText->setVisibleOffScreen(TRUE); -					mNameText->setMaxLines(11); -					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -					sNumVisibleChatBubbles++; -					new_name = TRUE; -				} +		mNameText->setVisibleOffScreen(TRUE); +		mNameText->setMaxLines(11); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		sNumVisibleChatBubbles++; +		new_name = TRUE; +	} -	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); -	mNameText->setPositionAgent(name_position);				 +	idleUpdateNameTagPosition(root_pos_last);  	idleUpdateNameTagText(new_name);			  	idleUpdateNameTagAlpha(new_name, alpha);  }  void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) -			{ -		LLNameValue *title = getNVPair("Title"); -		LLNameValue* firstname = getNVPair("FirstName"); -		LLNameValue* lastname = getNVPair("LastName"); +{ +	LLNameValue *title = getNVPair("Title"); +	LLNameValue* firstname = getNVPair("FirstName"); +	LLNameValue* lastname = getNVPair("LastName");  	// Avatars must have a first and last name  	if (!firstname || !lastname) return; @@ -3006,34 +3013,29 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		is_muted = false;  	}  	else -		{ +	{  		is_muted = LLMuteList::getInstance()->isMuted(getID());  	}  	bool is_friend = LLAvatarTracker::instance().isBuddy(getID());  	bool is_cloud = getIsCloud(); -			if (gSavedSettings.getBOOL("DebugAvatarRezTime")) -			{ -				if (is_appearance != mNameAppearance) -				{ -					if (is_appearance) -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; -					} -					else -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; -					} -				} -			} +	if (gSavedSettings.getBOOL("DebugAvatarRezTime") +		&& is_appearance != mNameAppearance) +	{ +		LLSD args; +		args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); +		args["NAME"] = getFullname(); +		if (is_appearance) +		{ +			LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); +			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; +		} +		else +		{ +			LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); +			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; +		} +	}  	// Rebuild name tag if state change detected  	if (mNameString.empty() @@ -3043,39 +3045,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		|| is_away != mNameAway   		|| is_busy != mNameBusy   		|| is_muted != mNameMute -				|| is_appearance != mNameAppearance  +		|| is_appearance != mNameAppearance   		|| is_friend != mNameFriend  		|| is_cloud != mNameCloud) -				{ +	{  		LLColor4 name_tag_color = getNameTagColor(is_friend);  		clearNameTag();  		if (is_away || is_muted || is_busy || is_appearance) -				{ +		{  			std::string line; -					if (is_away) -					{ -						line += LLTrans::getString("AvatarAway"); +			if (is_away) +			{ +				line += LLTrans::getString("AvatarAway");  				line += ", "; -					} -					if (is_busy) -					{ +			} +			if (is_busy) +			{  				line += LLTrans::getString("AvatarBusy");  				line += ", ";  			}  			if (is_muted) -						{ +			{  				line += LLTrans::getString("AvatarMuted"); -							line += ", "; -						} +				line += ", "; +			}  			if (is_appearance)  			{  				line += LLTrans::getString("AvatarEditingAppearance");  				line += ", "; -					} +			}  			if (is_cloud) -					{ +			{  				line += LLTrans::getString("LoadingData");  				line += ", ";  			} @@ -3087,12 +3089,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		if (sRenderGroupTitles  			&& title && title->getString() && title->getString()[0] != '\0') -						{ +		{  			std::string title_str = title->getString();  			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);  			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,  				LLFontGL::getFontSansSerifSmall()); -						} +		}  		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");  		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); @@ -3106,119 +3108,118 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  				// and force a rebuild  				LLAvatarNameCache::get(getID(),  					boost::bind(&LLVOAvatar::clearNameTag, this)); -					} +			}  			// Might be blank if name not available yet, that's OK  			if (show_display_names)  			{  				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,  					LLFontGL::getFontSansSerif()); -				} +			}  			// Suppress SLID display if display name matches exactly (ugh)  			if (show_usernames && !av_name.mIsDisplayNameDefault) -				{ +			{  				// *HACK: Desaturate the color  				LLColor4 username_color = name_tag_color * 0.83f;  				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,  					LLFontGL::getFontSansSerifSmall());  			} -				} +		}  		else -				{ +		{  			const LLFontGL* font = LLFontGL::getFontSansSerif(); -			std::string full_name = -				LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); +			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );  			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); -				} +		} -				mNameAway = is_away; -				mNameBusy = is_busy; -				mNameMute = is_muted; -				mNameAppearance = is_appearance; -		mNameFriend = is_friend; -				mNameCloud = is_cloud; -				mTitle = title ? title->getString() : ""; -				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); -				new_name = TRUE; -			} +		mNameAway 		= is_away; +		mNameBusy 		= is_busy; +		mNameMute 		= is_muted; +		mNameAppearance = is_appearance; +		mNameFriend 	= is_friend; +		mNameCloud 		= is_cloud; +		mTitle 			= title ? title->getString() : ""; +		LLStringFn::replace_ascii_controlchars(mTitle, LL_UNKNOWN_CHAR); +		new_name = TRUE; +	}  	if (mVisibleChat) -			{ -				mNameText->setFont(LLFontGL::getFontSansSerif()); +	{ +		mNameText->setFont(LLFontGL::getFontSansSerif());  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -			 -				char line[MAX_STRING];		/* Flawfinder: ignore */ -				line[0] = '\0'; -				std::deque<LLChat>::iterator chat_iter = mChats.begin(); -				mNameText->clearString(); - -				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); -				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); -				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); -				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)  -				{ -					++chat_iter; -				} +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -				for(; chat_iter != mChats.end(); ++chat_iter) -				{ -					F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); -					LLFontGL::StyleFlags style; -					switch(chat_iter->mChatType) -					{ -						case CHAT_TYPE_WHISPER: -							style = LLFontGL::ITALIC; -							break; -						case CHAT_TYPE_SHOUT: -							style = LLFontGL::BOLD; -							break; -						default: -							style = LLFontGL::NORMAL; -							break; -					} -					if (chat_fade_amt < 1.f) -					{ -						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); -						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); -					} -					else if (chat_fade_amt < 2.f) -					{ -						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); -						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); -					} -					else if (chat_fade_amt < 3.f) -					{ -						// *NOTE: only remove lines down to minimum number -						mNameText->addLine(chat_iter->mText, old_chat, style); -					} -				} -				mNameText->setVisibleOffScreen(TRUE); +		char line[MAX_STRING];		/* Flawfinder: ignore */ +		line[0] = '\0'; +		std::deque<LLChat>::iterator chat_iter = mChats.begin(); +		mNameText->clearString(); -				if (mTyping) -				{ -					S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; -					switch(dot_count) -					{ -						case 1: -							mNameText->addLine(".", new_chat); -							break; -						case 2: -							mNameText->addLine("..", new_chat); -							break; -						case 3: -							mNameText->addLine("...", new_chat); -							break; -					} +		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); +		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); +		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); +		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)  +		{ +			++chat_iter; +		} -				} +		for(; chat_iter != mChats.end(); ++chat_iter) +		{ +			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); +			LLFontGL::StyleFlags style; +			switch(chat_iter->mChatType) +			{ +			case CHAT_TYPE_WHISPER: +				style = LLFontGL::ITALIC; +				break; +			case CHAT_TYPE_SHOUT: +				style = LLFontGL::BOLD; +				break; +			default: +				style = LLFontGL::NORMAL; +				break;  			} -			else +			if (chat_fade_amt < 1.f)  			{ +				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); +				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); +			} +			else if (chat_fade_amt < 2.f) +			{ +				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); +				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); +			} +			else if (chat_fade_amt < 3.f) +			{ +				// *NOTE: only remove lines down to minimum number +				mNameText->addLine(chat_iter->mText, old_chat, style); +			} +		} +		mNameText->setVisibleOffScreen(TRUE); + +		if (mTyping) +		{ +			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; +			switch(dot_count) +			{ +			case 1: +				mNameText->addLine(".", new_chat); +				break; +			case 2: +				mNameText->addLine("..", new_chat); +				break; +			case 3: +				mNameText->addLine("...", new_chat); +				break; +			} + +		} +	} +	else +	{  		// ...not using chat bubbles, just names  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -				mNameText->setVisibleOffScreen(FALSE); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		mNameText->setVisibleOffScreen(FALSE);  	}  } @@ -3241,8 +3242,8 @@ void LLVOAvatar::clearNameTag()  {  	mNameString.clear();  	if (mNameText) -				{ -					mNameText->setLabel(""); +	{ +		mNameText->setLabel("");  		mNameText->setString( "" );  	}  } @@ -3270,34 +3271,45 @@ void LLVOAvatar::invalidateNameTags()  		if (avatar->isDead()) continue;  		avatar->clearNameTag(); -  	}  }  // Compute name tag position during idle update -LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) +void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  {  	LLQuaternion root_rot = mRoot.getWorldRotation(); +	LLQuaternion inv_root_rot = ~root_rot;  	LLVector3 pixel_right_vec;  	LLVector3 pixel_up_vec;  	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);  	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();  	camera_to_av.normalize(); -	LLVector3 local_camera_at = camera_to_av * ~root_rot; +	LLVector3 local_camera_at = camera_to_av * inv_root_rot;  	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();  	local_camera_up.normalize(); -	local_camera_up = local_camera_up * ~root_rot; +	local_camera_up = local_camera_up * inv_root_rot; + +	LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f, +								mBodySize.mV[VY] * 0.4f, +								mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT); -	local_camera_up.scaleVec(mBodySize * 0.5f); -	local_camera_at.scaleVec(mBodySize * 0.5f); +	local_camera_up.scaleVec(avatar_ellipsoid); +	local_camera_at.scaleVec(avatar_ellipsoid); -	LLVector3 name_position = mRoot.getWorldPosition(); -	name_position[VZ] -= mPelvisToFoot; -	name_position[VZ] += (mBodySize[VZ]* 0.55f); +	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot; + +	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD) +	{ +		mTargetRootToHeadOffset = head_offset; +	} +	 +	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f)); + +	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);  	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	 -	name_position += pixel_up_vec * 15.f; +	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; -	return name_position; +	mNameText->setPositionAgent(name_position);				  }  void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) @@ -3333,7 +3345,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)  		else  		{  			color_name = "NameTagMismatch"; -	} +		}  	}  	else  	{ @@ -3370,9 +3382,9 @@ bool LLVOAvatar::isVisuallyMuted()  	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");  	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); -	return LLMuteList::getInstance()->isMuted(getID()) || -			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || -			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); +	return LLMuteList::getInstance()->isMuted(getID())  +			|| (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0)  +			|| (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);  }  //------------------------------------------------------------------------ @@ -3413,8 +3425,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		}  	} -	LLVector3d root_pos_global; -  	if (!mIsBuilt)  	{  		return FALSE; @@ -3428,7 +3438,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	{  		mTimeVisible.reset();  	} -  	//--------------------------------------------------------------------  	// the rest should only be done occasionally for far away avatars @@ -3823,10 +3832,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		if ( playSound )  		{ -//			F32 gain = clamp_rescale( mSpeedAccum, -//							AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, -//							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); -  			const F32 STEP_VOLUME = 0.1f;  			const LLUUID& step_sound_id = getStepSound(); @@ -4043,13 +4048,6 @@ void LLVOAvatar::updateVisibility()  		{  			releaseMeshData();  		} -		// this breaks off-screen chat bubbles -		//if (mNameText) -		//{ -		//	mNameText->markDead(); -		//	mNameText = NULL; -		//	sNumVisibleChatBubbles--; -		//}  	}  	mVisible = visible; @@ -4065,46 +4063,6 @@ bool LLVOAvatar::shouldAlphaMask()  } -U32 LLVOAvatar::renderSkinnedAttachments() -{ -	/*U32 num_indices = 0; -	 -	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX |  -							LLVertexBuffer::MAP_NORMAL |  -							LLVertexBuffer::MAP_TEXCOORD0 | -							LLVertexBuffer::MAP_COLOR | -							LLVertexBuffer::MAP_WEIGHT4; - -	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();  -		 iter != mAttachmentPoints.end(); -		 ++iter) -	{ -		LLViewerJointAttachment* attachment = iter->second; -		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -			 attachment_iter != attachment->mAttachedObjects.end(); -			 ++attachment_iter) -		{ -			const LLViewerObject* attached_object = (*attachment_iter); -			if (attached_object && !attached_object->isHUDAttachment()) -			{ -				const LLDrawable* drawable = attached_object->mDrawable; -				if (drawable) -				{ -					for (S32 i = 0; i < drawable->getNumFaces(); ++i) -					{ -						LLFace* face = drawable->getFace(i); -						if (face->isState(LLFace::RIGGED)) -						{ -							 -				} -			} -		} -	} - -	return num_indices;*/ -	return 0; -} -  //-----------------------------------------------------------------------------  // renderSkinned()  //----------------------------------------------------------------------------- @@ -4125,11 +4083,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  	{	//LOD changed or new mesh created, allocate new vertex buffer if needed  		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)  		{ -		updateMeshData(); +			updateMeshData();  			mDirtyMesh = 0; -		mNeedsSkin = TRUE; -		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); -	} +			mNeedsSkin = TRUE; +			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); +		}  	}  	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) @@ -5790,36 +5748,34 @@ BOOL LLVOAvatar::updateJointLODs()  	F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);  	F32 area_scale = 0.16f; +	if (isSelf())  	{ -		if (isSelf()) -		{ -			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook()) -			{ -				mAdjustedPixelArea = MAX_PIXEL_AREA; -			} -			else -			{ -				mAdjustedPixelArea = mPixelArea*area_scale; -			} -		} -		else if (mIsDummy) +		if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())  		{  			mAdjustedPixelArea = MAX_PIXEL_AREA;  		}  		else  		{ -			// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars -			mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; +			mAdjustedPixelArea = mPixelArea*area_scale;  		} +	} +	else if (mIsDummy) +	{ +		mAdjustedPixelArea = MAX_PIXEL_AREA; +	} +	else +	{ +		// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars +		mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; +	} -		// now select meshes to render based on adjusted pixel area -		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); - 		if (res) -		{ -			sNumLODChangesThisFrame++; -			dirtyMesh(2); -			return TRUE; -		} +	// now select meshes to render based on adjusted pixel area +	BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); + 	if (res) +	{ +		sNumLODChangesThisFrame++; +		dirtyMesh(2); +		return TRUE;  	}  	return FALSE; @@ -6109,25 +6065,18 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  		if ( pVObj )  		{  			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); -			if ( pSkinData ) -			{ -				const int jointCnt = pSkinData->mJointNames.size(); -				bool fullRig = ( jointCnt>=20 ) ? true : false; -				if ( fullRig ) +			if (pSkinData  +				&& pSkinData->mJointNames.size() > 20				// full rig +				&& pSkinData->mAlternateBindMatrix.size() > 0) +			{ +				LLVOAvatar::resetJointPositionsToDefault(); +				//Need to handle the repositioning of the cam, updating rig data etc during outfit editing  +				//This handles the case where we detach a replacement rig. +				if ( gAgentCamera.cameraCustomizeAvatar() )  				{ -					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							 -					if ( bindCnt > 0 ) -					{ -						LLVOAvatar::resetJointPositionsToDefault(); -						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing  -						//This handles the case where we detach a replacement rig. -						if ( gAgentCamera.cameraCustomizeAvatar() ) -						{ -							gAgent.unpauseAnimation(); -							//Still want to refocus on head bone -							gAgentCamera.changeCameraToCustomizeAvatar(); -						} -					} +					gAgent.unpauseAnimation(); +					//Still want to refocus on head bone +					gAgentCamera.changeCameraToCustomizeAvatar();  				}  			}				  		} @@ -6281,11 +6230,7 @@ void LLVOAvatar::getOffObject()  		at_axis.mV[VZ] = 0.f;  		at_axis.normalize();  		gAgent.resetAxes(at_axis); - -		//reset orientation -//		mRoot.setRotation(avWorldRot);  		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); -  		gAgentCamera.setSitCamera(LLUUID::null);  	}  } @@ -6335,7 +6280,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const  	}  	else  	{ -//		return LLColor4( .5f, .5f, .5f, .5f );  		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color  	}  } @@ -7067,10 +7011,6 @@ LLBBox LLVOAvatar::getHUDBBox() const  	return bbox;  } -void LLVOAvatar::rebuildHUD() -{ -} -  //-----------------------------------------------------------------------------  // onFirstTEMessageReceived()  //----------------------------------------------------------------------------- @@ -7192,7 +7132,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  			&& baked_index != BAKED_SKIRT)  		{  			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,  -				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex,  +																TRUE,  +																LLViewerTexture::BOOST_NONE,  +																LLViewerTexture::LOD_TEXTURE));  		}  	} @@ -7483,11 +7426,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_  // Called when baked texture is loaded and also when we start up with a baked texture  void LLVOAvatar::useBakedTexture( const LLUUID& id )  { -	/* if(id == head_baked->getID()) -		 mHeadBakedLoaded = TRUE; -		 mLastHeadBakedID = id; -		 mHeadMesh0.setTexture( head_baked ); -		 mHeadMesh1.setTexture( head_baked ); */  	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)  	{  		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); @@ -7718,111 +7656,111 @@ LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()  	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());  } -//----------------------------------------------------------------------------- -// LLVOAvatarBoneInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) -{ -	if (node->hasName("bone")) -	{ -		mIsJoint = TRUE; -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (!node->getFastAttributeString(name_string, mName)) -		{ -			llwarns << "Bone without name" << llendl; -			return FALSE; -		} -	} -	else if (node->hasName("collision_volume")) -	{ -		mIsJoint = FALSE; -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (!node->getFastAttributeString(name_string, mName)) -		{ -			mName = "Collision Volume"; -		} -	} -	else -	{ -		llwarns << "Invalid node " << node->getName() << llendl; -		return FALSE; -	} - -	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); -	if (!node->getFastAttributeVector3(pos_string, mPos)) -	{ -		llwarns << "Bone without position" << llendl; -		return FALSE; -	} - -	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); -	if (!node->getFastAttributeVector3(rot_string, mRot)) -	{ -		llwarns << "Bone without rotation" << llendl; -		return FALSE; -	} -	 -	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); -	if (!node->getFastAttributeVector3(scale_string, mScale)) -	{ -		llwarns << "Bone without scale" << llendl; -		return FALSE; -	} - -	if (mIsJoint) -	{ -		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); -		if (!node->getFastAttributeVector3(pivot_string, mPivot)) -		{ -			llwarns << "Bone without pivot" << llendl; -			return FALSE; -		} -	} - -	// parse children -	LLXmlTreeNode* child; -	for( child = node->getFirstChild(); child; child = node->getNextChild() ) -	{ -		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; -		if (!child_info->parseXml(child)) -		{ -			delete child_info; -			return FALSE; -		} -		mChildList.push_back(child_info); -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// LLVOAvatarSkeletonInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) -{ -	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); -	if (!node->getFastAttributeS32(num_bones_string, mNumBones)) -	{ -		llwarns << "Couldn't find number of bones." << llendl; -		return FALSE; -	} - -	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); -	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); - -	LLXmlTreeNode* child; -	for( child = node->getFirstChild(); child; child = node->getNextChild() ) -	{ -		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; -		if (!info->parseXml(child)) -		{ -			delete info; -			llwarns << "Error parsing bone in skeleton file" << llendl; -			return FALSE; -		} -		mBoneInfoList.push_back(info); -	} -	return TRUE; -} +////----------------------------------------------------------------------------- +//// LLVOAvatarBoneInfo::parseXml() +////----------------------------------------------------------------------------- +//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) +//{ +//	if (node->hasName("bone")) +//	{ +//		mIsJoint = TRUE; +//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +//		if (!node->getFastAttributeString(name_string, mName)) +//		{ +//			llwarns << "Bone without name" << llendl; +//			return FALSE; +//		} +//	} +//	else if (node->hasName("collision_volume")) +//	{ +//		mIsJoint = FALSE; +//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +//		if (!node->getFastAttributeString(name_string, mName)) +//		{ +//			mName = "Collision Volume"; +//		} +//	} +//	else +//	{ +//		llwarns << "Invalid node " << node->getName() << llendl; +//		return FALSE; +//	} +// +//	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); +//	if (!node->getFastAttributeVector3(pos_string, mPos)) +//	{ +//		llwarns << "Bone without position" << llendl; +//		return FALSE; +//	} +// +//	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); +//	if (!node->getFastAttributeVector3(rot_string, mRot)) +//	{ +//		llwarns << "Bone without rotation" << llendl; +//		return FALSE; +//	} +//	 +//	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); +//	if (!node->getFastAttributeVector3(scale_string, mScale)) +//	{ +//		llwarns << "Bone without scale" << llendl; +//		return FALSE; +//	} +// +//	if (mIsJoint) +//	{ +//		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); +//		if (!node->getFastAttributeVector3(pivot_string, mPivot)) +//		{ +//			llwarns << "Bone without pivot" << llendl; +//			return FALSE; +//		} +//	} +// +//	// parse children +//	LLXmlTreeNode* child; +//	for( child = node->getFirstChild(); child; child = node->getNextChild() ) +//	{ +//		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; +//		if (!child_info->parseXml(child)) +//		{ +//			delete child_info; +//			return FALSE; +//		} +//		mChildList.push_back(child_info); +//	} +//	return TRUE; +//} +// +////----------------------------------------------------------------------------- +//// LLVOAvatarSkeletonInfo::parseXml() +////----------------------------------------------------------------------------- +//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) +//{ +//	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); +//	if (!node->getFastAttributeS32(num_bones_string, mNumBones)) +//	{ +//		llwarns << "Couldn't find number of bones." << llendl; +//		return FALSE; +//	} +// +//	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); +//	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); +// +//	LLXmlTreeNode* child; +//	for( child = node->getFirstChild(); child; child = node->getNextChild() ) +//	{ +//		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; +//		if (!info->parseXml(child)) +//		{ +//			delete info; +//			llwarns << "Error parsing bone in skeleton file" << llendl; +//			return FALSE; +//		} +//		mBoneInfoList.push_back(info); +//	} +//	return TRUE; +//}  //-----------------------------------------------------------------------------  // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index dd0317f555..e84acd51ff 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -66,8 +66,9 @@ class LLVoiceVisualizer;  class LLHUDNameTag;  class LLHUDEffectSpiral;  class LLTexGlobalColor; -class LLVOAvatarBoneInfo; -class LLVOAvatarSkeletonInfo; +struct LLVOAvatarBoneInfo; +struct LLVOAvatarChildJoint; +struct LLVOAvatarSkeletonInfo;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLVOAvatar @@ -232,7 +233,7 @@ public:  	void 			idleUpdateWindEffect();  	void 			idleUpdateNameTag(const LLVector3& root_pos_last);  	void			idleUpdateNameTagText(BOOL new_name); -	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last); +	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);  	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);  	LLColor4		getNameTagColor(bool is_friend);  	void			clearNameTag(); @@ -317,6 +318,8 @@ public:  	F32					mLastPelvisToFoot;  	F32					mPelvisFixup;  	F32					mLastPelvisFixup; +	LLVector3			mCurRootToHeadOffset; +	LLVector3			mTargetRootToHeadOffset;  	LLVector3			mHeadOffset; // current head position  	LLViewerJoint		mRoot; @@ -325,7 +328,7 @@ protected:  	void				buildCharacter();  	virtual BOOL		loadAvatar(); -	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); +	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num);  	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);  private:  	BOOL				mIsBuilt; // state of deferred character building @@ -369,7 +372,7 @@ public:  	//--------------------------------------------------------------------  private:  	static LLXmlTree 	sXMLTree; // avatar config file -	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file +	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file  /**                    Skeleton   **                                                                            ** @@ -387,7 +390,6 @@ public:  	U32 		renderRigid();  	U32 		renderSkinned(EAvatarRenderPass pass);  	F32			getLastSkinTime() { return mLastSkinTime; } -	U32			renderSkinnedAttachments();  	U32 		renderTransparent(BOOL first_pass);  	void 		renderCollisionVolumes();  	static void	deleteCachedImages(bool clearAll=true); @@ -735,7 +737,6 @@ public:  public:  	BOOL 				hasHUDAttachment() const;  	LLBBox 				getHUDBBox() const; -	void 				rebuildHUD();  	void 				resetHUDAttachments();  	BOOL				canAttachMoreObjects() const;  	BOOL				canAttachMoreObjects(U32 n) const; diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index 47060720e7..dcf33bce10 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -1,625 +1,642 @@ -/**  - * @file llvoicevisualizer.cpp - * @brief Draws in-world speaking indicators. - * - * $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$ - */ - -//---------------------------------------------------------------------- -// Voice Visualizer -// author: JJ Ventrella -// (information about this stuff can be found in "llvoicevisualizer.h") -//---------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llglheaders.h" -#include "llsphere.h" -#include "llvoicevisualizer.h" -#include "llviewercamera.h" -#include "llviewerobject.h" -#include "llviewertexture.h" -#include "llviewertexturelist.h" -#include "llvoiceclient.h" -#include "llrender.h" - -//brent's wave image -//29de489d-0491-fb00-7dab-f9e686d31e83 - - -//-------------------------------------------------------------------------------------- -// sound symbol constants -//-------------------------------------------------------------------------------------- -const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear -const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red -const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green -const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away -const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size -const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0  -const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves  -const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves  -const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold) -const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture -const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is -const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude - -//-------------------------------------------------------------------------------------- -// gesticulation constants -//-------------------------------------------------------------------------------------- -const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f;  -const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f; - -//-------------------------------------------------------------------------------------- -// other constants -//-------------------------------------------------------------------------------------- -const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.  -const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL - - -//------------------------------------------------------------------ -// handles parameter updates -//------------------------------------------------------------------ -static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue) -{ -	// Note: Ignore the specific event value, we look up the ones we want -	LLVoiceVisualizer::setPreferences(); -	return true; -} - -//------------------------------------------------------------------ -// Initialize the statics -//------------------------------------------------------------------ -bool LLVoiceVisualizer::sPrefsInitialized	= false; -BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE; -F32* LLVoiceVisualizer::sOoh				= NULL; -F32* LLVoiceVisualizer::sAah				= NULL; -U32	 LLVoiceVisualizer::sOohs				= 0; -U32	 LLVoiceVisualizer::sAahs				= 0; -F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f; -F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL; -U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0; -F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f; -F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL; -U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0; -F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f; - - -//----------------------------------------------- -// constructor -//----------------------------------------------- -LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) -:LLHUDEffect( type ) -{ -	mCurrentTime					= mTimer.getTotalSeconds(); -	mPreviousTime					= mCurrentTime; -	mStartTime						= mCurrentTime; -	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f ); -	mSpeakingAmplitude				= 0.0f; -	mCurrentlySpeaking				= false; -	mVoiceEnabled					= false; -	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE; -	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE; -	mSoundSymbol.mActive			= true; -	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f ); -	 -	mTimer.reset(); -	 -	const char* sound_level_img[] =  -	{ -		"voice_meter_dot.j2c", -		"voice_meter_rings.j2c", -		"voice_meter_rings.j2c", -		"voice_meter_rings.j2c", -		"voice_meter_rings.j2c", -		"voice_meter_rings.j2c", -		"voice_meter_rings.j2c" -	}; - -	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++) -	{ -		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime; -		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI); -		mSoundSymbol.mWaveActive			[i] = false; -		mSoundSymbol.mWaveOpacity			[i] = 1.0f; -		mSoundSymbol.mWaveExpansion			[i] = 1.0f; -	} - -	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - -	// The first instance loads the initial state from prefs. -	if (!sPrefsInitialized) -	{ -		setPreferences(); -        -		// Set up our listener to get updates on all prefs values we care about. -		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); -		 -		sPrefsInitialized = true; -	} - -}//--------------------------------------------------- - -//--------------------------------------------------- -void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m ) -{ -	mMinGesticulationAmplitude = m; - -}//--------------------------------------------------- - -//--------------------------------------------------- -void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m ) -{ -	mMaxGesticulationAmplitude = m; - -}//--------------------------------------------------- - -//--------------------------------------------------- -void LLVoiceVisualizer::setVoiceEnabled( bool v ) -{ -	mVoiceEnabled = v; - -}//--------------------------------------------------- - -//--------------------------------------------------- -void LLVoiceVisualizer::setStartSpeaking() -{ -	mStartTime				= mTimer.getTotalSeconds(); -	mCurrentlySpeaking		= true; -	mSoundSymbol.mActive	= true; -		 -}//--------------------------------------------------- - - -//--------------------------------------------------- -bool LLVoiceVisualizer::getCurrentlySpeaking() -{ -	return mCurrentlySpeaking; -	 -}//--------------------------------------------------- - - -//--------------------------------------------------- -void LLVoiceVisualizer::setStopSpeaking() -{ -	mCurrentlySpeaking = false; -	mSpeakingAmplitude = 0.0f; -	 -}//--------------------------------------------------- - - -//--------------------------------------------------- -void LLVoiceVisualizer::setSpeakingAmplitude( F32 a ) -{ -	mSpeakingAmplitude = a; -	 -}//--------------------------------------------------- - - -//--------------------------------------------------- -void LLVoiceVisualizer::setPreferences( ) -{ -	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); -	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate"); - -	std::string oohString = gSavedSettings.getString("LipSyncOoh"); -	lipStringToF32s (oohString, sOoh, sOohs); - -	std::string aahString = gSavedSettings.getString("LipSyncAah"); -	lipStringToF32s (aahString, sAah, sAahs); - -	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer"); -	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers); -	sOohPowerTransfersf = (F32) sOohPowerTransfers; - -	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer"); -	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers); -	sAahPowerTransfersf = (F32) sAahPowerTransfers; - -}//--------------------------------------------------- - - -//--------------------------------------------------- -// convert a string of digits to an array of floats. -// the result for each digit is the value of the -// digit multiplied by 0.11 -//--------------------------------------------------- -void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ) -{ -	delete[] out_F32s;	// get rid of the current array - -	count_F32s = in_string.length(); -	if (count_F32s == 0) -	{ -		// we don't like zero length arrays - -		count_F32s  = 1; -		out_F32s	   = new F32[1]; -		out_F32s[0] = 0.0f; -	} -	else -	{ -		out_F32s = new F32[count_F32s]; - -		for (U32 i=0; i<count_F32s; i++) -		{ -			// we convert the characters 0 to 9 to their numeric value -			// anything else we take the low order four bits with a ceiling of 9 - -		    U8 digit = in_string[i]; -			U8 four_bits = digit % 16; -			if (four_bits > 9) -			{ -				four_bits = 9; -			} -			out_F32s[i] = 0.11f * (F32) four_bits; -		}  -	} - -}//--------------------------------------------------- - - -//-------------------------------------------------------------------------- -// find the amount to blend the ooh and aah mouth morphs -//-------------------------------------------------------------------------- -void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah ) -{ -	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking ) -	{ -		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude); -		if (transfer_index >= sOohPowerTransfers) -		{ -		   transfer_index = sOohPowerTransfers - 1; -		} -		F32 transfer_ooh = sOohPowerTransfer[transfer_index]; - -		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude); -		if (transfer_index >= sAahPowerTransfers) -		{ -		   transfer_index = sAahPowerTransfers - 1; -		} -		F32 transfer_aah = sAahPowerTransfer[transfer_index]; - -		F64 current_time   = mTimer.getTotalSeconds(); -		F64 elapsed_time   = current_time - mStartTime; -		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate); -		U32 elapsed_oohs   = elapsed_frames % sOohs; -		U32 elapsed_aahs   = elapsed_frames % sAahs; - -		ooh = transfer_ooh * sOoh[elapsed_oohs]; -		aah = transfer_aah * sAah[elapsed_aahs]; - -		/* -		llinfos << " elapsed frames " << elapsed_frames -				<< " ooh "            << ooh -				<< " aah "            << aah -				<< " transfer ooh"    << transfer_ooh -				<< " transfer aah"    << transfer_aah -				<< " start time "     << mStartTime -				<< " current time "   << current_time -				<< " elapsed time "   << elapsed_time -				<< " elapsed oohs "   << elapsed_oohs -				<< " elapsed aahs "   << elapsed_aahs -				<< llendl; -		*/ -	} -	else -	{ -		ooh = 0.0f; -		aah = 0.0f; -	} -	 -}//--------------------------------------------------- - - -//--------------------------------------------------- -// this method is inherited from HUD Effect -//--------------------------------------------------- -void LLVoiceVisualizer::render() -{ -	if ( ! mVoiceEnabled ) -	{ -		return; -	} -	 -	if ( mSoundSymbol.mActive )  -	{				 -		mPreviousTime = mCurrentTime; -		mCurrentTime = mTimer.getTotalSeconds(); -	 -		//--------------------------------------------------------------- -		// set the sound symbol position over the source (avatar's head) -		//--------------------------------------------------------------- -		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD; -	 -		//--------------------------------------------------------------- -		// some gl state -		//--------------------------------------------------------------- -		LLGLSPipelineAlpha alpha_blend; -		LLGLDepthTest depth(GL_TRUE, GL_FALSE); -		 -		//------------------------------------------------------------- -		// create coordinates of the geometry for the dot -		//------------------------------------------------------------- -		LLViewerCamera* camera = LLViewerCamera::getInstance(); -		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE; -		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE; - -		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u; -		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u; -		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u; -		LLVector3 topRight		= mSoundSymbol.mPosition - l + u; -		 -		//----------------------------- -		// bind texture 0 (the dot) -		//----------------------------- -		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]); -		 -		//------------------------------------------------------------- -		// now render the dot -		//------------------------------------------------------------- -		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	 -		 -		gGL.begin( LLRender::TRIANGLE_STRIP ); -			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV ); -			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV ); -			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV ); -		gGL.end(); - -		gGL.begin( LLRender::TRIANGLE_STRIP ); -			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV ); -			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV ); -			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV ); -		gGL.end(); -		 -		 -		 -		//-------------------------------------------------------------------------------------- -		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude -		//-------------------------------------------------------------------------------------- -		if ( mCurrentlySpeaking ) -		{ -			F32 min = 0.2f; -			F32 max = 0.7f; -			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min ); -		 -			// in case mSpeakingAmplitude > max.... -			if ( fraction > 1.0f ) -			{ -				fraction = 1.0f; -			} -														 -			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) ); -																										 -			for (int i=0; i<level+1; i++) -			{ -				mSoundSymbol.mWaveActive			[i] = true; -				mSoundSymbol.mWaveOpacity			[i] = 1.0f; -				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime; -			}			 -			 -		} // if currently speaking -								 -		//--------------------------------------------------- -		// determine color -		//--------------------------------------------------- -		F32 red		= 0.0f; -		F32 green	= 0.0f; -		F32 blue	= 0.0f; -        if ( mSpeakingAmplitude < RED_THRESHOLD ) -        { -			if ( mSpeakingAmplitude < GREEN_THRESHOLD ) -			{ -				red		= BASE_BRIGHTNESS; -				green	= BASE_BRIGHTNESS; -				blue	= BASE_BRIGHTNESS; -			} -			else -			{ -				//--------------------------------------------------- -				// fade from gray to bright green -				//--------------------------------------------------- -				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD ); -				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS ); -				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS ); -				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS ); -			} -        } -        else -        { -			//--------------------------------------------------- -			// redish -			//--------------------------------------------------- -			red		= 1.0f; -			green	= 0.2f; -			blue	= 0.2f; -        } -														 -		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++) -		{ -			if ( mSoundSymbol.mWaveActive[i] )  -			{ -				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION; - -				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction; -				 -				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f ) -				{ -					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime; -					mSoundSymbol.mWaveOpacity			[i] = 0.0f; -					mSoundSymbol.mWaveActive			[i] = false; -				} -				 -				//---------------------------------------------------------------------------------- -				// This is where we calculate the expansion of the waves - that is, the -				// rate at which they are scaled greater than 1.0 so that they grow over time. -				//---------------------------------------------------------------------------------- -				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime ); -				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE; -				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed ); -				 -				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX ) -				{ -					mSoundSymbol.mWaveExpansion[i] = 1.0f; -				}			 -								 -				//---------------------------------------------------------------------------------- -				// create geometry for the wave billboard textures -				//---------------------------------------------------------------------------------- -				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i]; -				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i]; - -				LLVector3 l	= camera->getLeftAxis() * width; -				LLVector3 u	= camera->getUpAxis()   * height; - -				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u; -				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u; -				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u; -				LLVector3 topRight		= mSoundSymbol.mPosition - l + u; -							 -				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		 -				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]); - -				 -				//--------------------------------------------------- -				// now, render the mofo -				//--------------------------------------------------- -				gGL.begin( LLRender::TRIANGLE_STRIP ); -					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); -					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); -					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); -				gGL.end(); - -				gGL.begin( LLRender::TRIANGLE_STRIP ); -					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); -					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); -					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); -				gGL.end(); -				 -			} //if ( mSoundSymbol.mWaveActive[i] )  -			 -		}// for loop -											 -	}//if ( mSoundSymbol.mActive )  - -}//--------------------------------------------------- - - - - - -//--------------------------------------------------- -void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p ) -{ -	mVoiceSourceWorldPosition	= p; - -}//--------------------------------------------------- - -//--------------------------------------------------- -VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel() -{ -	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default -	 -	//----------------------------------------------------------------------------------------- -	// Within the range of gesticulation amplitudes, the sound signal is split into -	// three equal amplitude regimes, each specifying one of three gesticulation levels. -	//----------------------------------------------------------------------------------------- -	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude; -	 -			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		} -	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	} -	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		} - -	return gesticulationLevel; - -}//--------------------------------------------------- - - - -//------------------------------------ -// Destructor -//------------------------------------ -LLVoiceVisualizer::~LLVoiceVisualizer() -{ -}//---------------------------------------------- - - -//--------------------------------------------------- -// "packData" is inherited from HUDEffect -//--------------------------------------------------- -void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys) -{ -	// Pack the default data -	LLHUDEffect::packData(mesgsys); - -	// TODO -- pack the relevant data for voice effects -	// we'll come up with some cool configurations....TBD -	//U8 packed_data[41]; -	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41); -	U8 packed_data = 0; -	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1); -} - - -//--------------------------------------------------- -// "unpackData" is inherited from HUDEffect -//--------------------------------------------------- -void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum) -{ -	// TODO -- find the speaker, unpack binary data, set the properties of this effect -	/* -	LLHUDEffect::unpackData(mesgsys, blocknum); -	LLUUID source_id; -	LLUUID target_id; -	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); -	if (size != 1) -	{ -		llwarns << "Voice effect with bad size " << size << llendl; -		return; -	} -	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum); -	*/ -} - - -//------------------------------------------------------------------ -// this method is inherited from HUD Effect -//------------------------------------------------------------------ -void LLVoiceVisualizer::markDead() -{ -	mCurrentlySpeaking		= false; -	mVoiceEnabled			= false; -	mSoundSymbol.mActive	= false; - -	LLHUDEffect::markDead(); -}//------------------------------------------------------------------ - - - - - - - - +/** 
 + * @file llvoicevisualizer.cpp
 + * @brief Draws in-world speaking indicators.
 + *
 + * $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$
 + */
 +
 +//----------------------------------------------------------------------
 +// Voice Visualizer
 +// author: JJ Ventrella
 +// (information about this stuff can be found in "llvoicevisualizer.h")
 +//----------------------------------------------------------------------
 +#include "llviewerprecompiledheaders.h"
 +#include "llviewercontrol.h"
 +#include "llglheaders.h"
 +#include "llsphere.h"
 +#include "llvoicevisualizer.h"
 +#include "llviewercamera.h"
 +#include "llviewerobject.h"
 +#include "llviewertexture.h"
 +#include "llviewertexturelist.h"
 +#include "llvoiceclient.h"
 +#include "llrender.h"
 +
 +//brent's wave image
 +//29de489d-0491-fb00-7dab-f9e686d31e83
 +
 +
 +#ifdef XXX_STINSON_CHUI_REWORK
 +//--------------------------------------------------------------------------------------
 +// sound symbol constants
 +//--------------------------------------------------------------------------------------
 +const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear
 +const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red
 +const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green
 +const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away
 +const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size
 +const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0 
 +const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves 
 +const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves 
 +const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold)
 +const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
 +const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
 +const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
 +#endif // XXX_STINSON_CHUI_REWORK
 +
 +//--------------------------------------------------------------------------------------
 +// gesticulation constants
 +//--------------------------------------------------------------------------------------
 +const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
 +const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
 +
 +#ifdef XXX_STINSON_CHUI_REWORK
 +//--------------------------------------------------------------------------------------
 +// other constants
 +//--------------------------------------------------------------------------------------
 +const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
 +const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
 +#endif // XXX_STINSON_CHUI_REWORK
 +
 +//------------------------------------------------------------------
 +// Initialize the statics
 +//------------------------------------------------------------------
 +bool LLVoiceVisualizer::sPrefsInitialized	= false;
 +BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE;
 +F32* LLVoiceVisualizer::sOoh				= NULL;
 +F32* LLVoiceVisualizer::sAah				= NULL;
 +U32	 LLVoiceVisualizer::sOohs				= 0;
 +U32	 LLVoiceVisualizer::sAahs				= 0;
 +F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f;
 +F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL;
 +U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0;
 +F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
 +F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL;
 +U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0;
 +F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
 +
 +
 +//-----------------------------------------------
 +// constructor
 +//-----------------------------------------------
 +#ifdef XXX_STINSON_CHUI_REWORK
 +LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 +#else // XXX_STINSON_CHUI_REWORK
 +LLVoiceVisualizer::LLVoiceVisualizer()
 +	: LLRefCount(),
 +	mTimer(),
 +	mStartTime(0.0),
 +	mCurrentlySpeaking(false),
 +	mSpeakingAmplitude(0.0f),
 +	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
 +	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
 +#endif // XXX_STINSON_CHUI_REWORK
 +{
 +#ifdef XXX_STINSON_CHUI_REWORK
 +	mCurrentTime					= mTimer.getTotalSeconds();
 +	mPreviousTime					= mCurrentTime;
 +	mStartTime						= mCurrentTime;
 +#else // XXX_STINSON_CHUI_REWORK
 +	mStartTime						= mTimer.getTotalSeconds();
 +#endif // XXX_STINSON_CHUI_REWORK
 +#ifdef XXX_STINSON_CHUI_REWORK
 +	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
 +	mSpeakingAmplitude				= 0.0f;
 +	mCurrentlySpeaking				= false;
 +	mVoiceEnabled					= false;
 +	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
 +	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
 +	mSoundSymbol.mActive			= true;
 +	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
 +#endif // XXX_STINSON_CHUI_REWORK
 +	
 +	mTimer.reset();
 +	
 +#ifdef XXX_STINSON_CHUI_REWORK
 +	const char* sound_level_img[] = 
 +	{
 +		"voice_meter_dot.j2c",
 +		"voice_meter_rings.j2c",
 +		"voice_meter_rings.j2c",
 +		"voice_meter_rings.j2c",
 +		"voice_meter_rings.j2c",
 +		"voice_meter_rings.j2c",
 +		"voice_meter_rings.j2c"
 +	};
 +
 +	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
 +	{
 +		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
 +		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
 +		mSoundSymbol.mWaveActive			[i] = false;
 +		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
 +		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
 +	}
 +
 +	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
 +#endif // XXX_STINSON_CHUI_REWORK
 +
 +	// The first instance loads the initial state from prefs.
 +	if (!sPrefsInitialized)
 +	{
 +		setPreferences();
 +       
 +		// Set up our listener to get updates on all prefs values we care about.
 +		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 +		
 +		sPrefsInitialized = true;
 +	}
 +
 +}//---------------------------------------------------
 +
 +#ifdef XXX_STINSON_CHUI_REWORK
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
 +{
 +	mMinGesticulationAmplitude = m;
 +
 +}//---------------------------------------------------
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
 +{
 +	mMaxGesticulationAmplitude = m;
 +
 +}//---------------------------------------------------
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setVoiceEnabled( bool v )
 +{
 +	mVoiceEnabled = v;
 +
 +}//---------------------------------------------------
 +#endif // XXX_STINSON_CHUI_REWORK
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setStartSpeaking()
 +{
 +	mStartTime				= mTimer.getTotalSeconds();
 +	mCurrentlySpeaking		= true;
 +#ifdef XXX_STINSON_CHUI_REWORK
 +	mSoundSymbol.mActive	= true;
 +#endif // XXX_STINSON_CHUI_REWORK
 +		
 +}//---------------------------------------------------
 +
 +
 +//---------------------------------------------------
 +bool LLVoiceVisualizer::getCurrentlySpeaking()
 +{
 +	return mCurrentlySpeaking;
 +	
 +}//---------------------------------------------------
 +
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setStopSpeaking()
 +{
 +	mCurrentlySpeaking = false;
 +	mSpeakingAmplitude = 0.0f;
 +	
 +}//---------------------------------------------------
 +
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
 +{
 +	mSpeakingAmplitude = a;
 +	
 +}//---------------------------------------------------
 +
 +//------------------------------------------------------------------
 +// handles parameter updates
 +//------------------------------------------------------------------
 +bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
 +{
 +	// Note: Ignore the specific event value, we look up the ones we want
 +	LLVoiceVisualizer::setPreferences();
 +	return true;
 +}
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setPreferences( )
 +{
 +	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
 +	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate");
 +
 +	std::string oohString = gSavedSettings.getString("LipSyncOoh");
 +	lipStringToF32s (oohString, sOoh, sOohs);
 +
 +	std::string aahString = gSavedSettings.getString("LipSyncAah");
 +	lipStringToF32s (aahString, sAah, sAahs);
 +
 +	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
 +	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
 +	sOohPowerTransfersf = (F32) sOohPowerTransfers;
 +
 +	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
 +	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
 +	sAahPowerTransfersf = (F32) sAahPowerTransfers;
 +
 +}//---------------------------------------------------
 +
 +
 +//---------------------------------------------------
 +// convert a string of digits to an array of floats.
 +// the result for each digit is the value of the
 +// digit multiplied by 0.11
 +//---------------------------------------------------
 +void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
 +{
 +	delete[] out_F32s;	// get rid of the current array
 +
 +	count_F32s = in_string.length();
 +	if (count_F32s == 0)
 +	{
 +		// we don't like zero length arrays
 +
 +		count_F32s  = 1;
 +		out_F32s	   = new F32[1];
 +		out_F32s[0] = 0.0f;
 +	}
 +	else
 +	{
 +		out_F32s = new F32[count_F32s];
 +
 +		for (U32 i=0; i<count_F32s; i++)
 +		{
 +			// we convert the characters 0 to 9 to their numeric value
 +			// anything else we take the low order four bits with a ceiling of 9
 +
 +		    U8 digit = in_string[i];
 +			U8 four_bits = digit % 16;
 +			if (four_bits > 9)
 +			{
 +				four_bits = 9;
 +			}
 +			out_F32s[i] = 0.11f * (F32) four_bits;
 +		} 
 +	}
 +
 +}//---------------------------------------------------
 +
 +
 +//--------------------------------------------------------------------------
 +// find the amount to blend the ooh and aah mouth morphs
 +//--------------------------------------------------------------------------
 +void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
 +{
 +	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
 +	{
 +		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
 +		if (transfer_index >= sOohPowerTransfers)
 +		{
 +		   transfer_index = sOohPowerTransfers - 1;
 +		}
 +		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
 +
 +		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
 +		if (transfer_index >= sAahPowerTransfers)
 +		{
 +		   transfer_index = sAahPowerTransfers - 1;
 +		}
 +		F32 transfer_aah = sAahPowerTransfer[transfer_index];
 +
 +		F64 current_time   = mTimer.getTotalSeconds();
 +		F64 elapsed_time   = current_time - mStartTime;
 +		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
 +		U32 elapsed_oohs   = elapsed_frames % sOohs;
 +		U32 elapsed_aahs   = elapsed_frames % sAahs;
 +
 +		ooh = transfer_ooh * sOoh[elapsed_oohs];
 +		aah = transfer_aah * sAah[elapsed_aahs];
 +
 +		/*
 +		llinfos << " elapsed frames " << elapsed_frames
 +				<< " ooh "            << ooh
 +				<< " aah "            << aah
 +				<< " transfer ooh"    << transfer_ooh
 +				<< " transfer aah"    << transfer_aah
 +				<< " start time "     << mStartTime
 +				<< " current time "   << current_time
 +				<< " elapsed time "   << elapsed_time
 +				<< " elapsed oohs "   << elapsed_oohs
 +				<< " elapsed aahs "   << elapsed_aahs
 +				<< llendl;
 +		*/
 +	}
 +	else
 +	{
 +		ooh = 0.0f;
 +		aah = 0.0f;
 +	}
 +	
 +}//---------------------------------------------------
 +
 +
 +#ifdef XXX_STINSON_CHUI_REWORK
 +//---------------------------------------------------
 +// this method is inherited from HUD Effect
 +//---------------------------------------------------
 +void LLVoiceVisualizer::render()
 +{
 +	if ( ! mVoiceEnabled )
 +	{
 +		return;
 +	}
 +	
 +	if ( mSoundSymbol.mActive ) 
 +	{				
 +		mPreviousTime = mCurrentTime;
 +		mCurrentTime = mTimer.getTotalSeconds();
 +	
 +		//---------------------------------------------------------------
 +		// set the sound symbol position over the source (avatar's head)
 +		//---------------------------------------------------------------
 +		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
 +	
 +		//---------------------------------------------------------------
 +		// some gl state
 +		//---------------------------------------------------------------
 +		LLGLSPipelineAlpha alpha_blend;
 +		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 +		
 +		//-------------------------------------------------------------
 +		// create coordinates of the geometry for the dot
 +		//-------------------------------------------------------------
 +		LLViewerCamera* camera = LLViewerCamera::getInstance();
 +		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE;
 +		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE;
 +
 +		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
 +		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
 +		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
 +		LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
 +		
 +		//-----------------------------
 +		// bind texture 0 (the dot)
 +		//-----------------------------
 +		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
 +		
 +		//-------------------------------------------------------------
 +		// now render the dot
 +		//-------------------------------------------------------------
 +		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
 +		
 +		gGL.begin( LLRender::TRIANGLE_STRIP );
 +			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
 +			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
 +			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
 +		gGL.end();
 +
 +		gGL.begin( LLRender::TRIANGLE_STRIP );
 +			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
 +			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
 +			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
 +		gGL.end();
 +		
 +		
 +		
 +		//--------------------------------------------------------------------------------------
 +		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude
 +		//--------------------------------------------------------------------------------------
 +		if ( mCurrentlySpeaking )
 +		{
 +			F32 min = 0.2f;
 +			F32 max = 0.7f;
 +			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
 +		
 +			// in case mSpeakingAmplitude > max....
 +			if ( fraction > 1.0f )
 +			{
 +				fraction = 1.0f;
 +			}
 +														
 +			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
 +																										
 +			for (int i=0; i<level+1; i++)
 +			{
 +				mSoundSymbol.mWaveActive			[i] = true;
 +				mSoundSymbol.mWaveOpacity			[i] = 1.0f;
 +				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
 +			}			
 +			
 +		} // if currently speaking
 +								
 +		//---------------------------------------------------
 +		// determine color
 +		//---------------------------------------------------
 +		F32 red		= 0.0f;
 +		F32 green	= 0.0f;
 +		F32 blue	= 0.0f;
 +        if ( mSpeakingAmplitude < RED_THRESHOLD )
 +        {
 +			if ( mSpeakingAmplitude < GREEN_THRESHOLD )
 +			{
 +				red		= BASE_BRIGHTNESS;
 +				green	= BASE_BRIGHTNESS;
 +				blue	= BASE_BRIGHTNESS;
 +			}
 +			else
 +			{
 +				//---------------------------------------------------
 +				// fade from gray to bright green
 +				//---------------------------------------------------
 +				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
 +				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
 +				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS );
 +				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
 +			}
 +        }
 +        else
 +        {
 +			//---------------------------------------------------
 +			// redish
 +			//---------------------------------------------------
 +			red		= 1.0f;
 +			green	= 0.2f;
 +			blue	= 0.2f;
 +        }
 +														
 +		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
 +		{
 +			if ( mSoundSymbol.mWaveActive[i] ) 
 +			{
 +				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
 +
 +				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
 +				
 +				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
 +				{
 +					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
 +					mSoundSymbol.mWaveOpacity			[i] = 0.0f;
 +					mSoundSymbol.mWaveActive			[i] = false;
 +				}
 +				
 +				//----------------------------------------------------------------------------------
 +				// This is where we calculate the expansion of the waves - that is, the
 +				// rate at which they are scaled greater than 1.0 so that they grow over time.
 +				//----------------------------------------------------------------------------------
 +				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
 +				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
 +				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
 +				
 +				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
 +				{
 +					mSoundSymbol.mWaveExpansion[i] = 1.0f;
 +				}			
 +								
 +				//----------------------------------------------------------------------------------
 +				// create geometry for the wave billboard textures
 +				//----------------------------------------------------------------------------------
 +				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i];
 +				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
 +
 +				LLVector3 l	= camera->getLeftAxis() * width;
 +				LLVector3 u	= camera->getUpAxis()   * height;
 +
 +				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
 +				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
 +				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
 +				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
 +							
 +				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
 +				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
 +
 +				
 +				//---------------------------------------------------
 +				// now, render the mofo
 +				//---------------------------------------------------
 +				gGL.begin( LLRender::TRIANGLE_STRIP );
 +					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
 +					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
 +					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
 +				gGL.end();
 +
 +				gGL.begin( LLRender::TRIANGLE_STRIP );
 +					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
 +					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
 +					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
 +				gGL.end();
 +				
 +			} //if ( mSoundSymbol.mWaveActive[i] ) 
 +			
 +		}// for loop
 +											
 +	}//if ( mSoundSymbol.mActive ) 
 +
 +}//---------------------------------------------------
 +
 +//---------------------------------------------------
 +void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
 +{
 +	mVoiceSourceWorldPosition	= p;
 +
 +}//---------------------------------------------------
 +#endif // XXX_STINSON_CHUI_REWORK
 +
 +//---------------------------------------------------
 +VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
 +{
 +	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
 +	
 +	//-----------------------------------------------------------------------------------------
 +	// Within the range of gesticulation amplitudes, the sound signal is split into
 +	// three equal amplitude regimes, each specifying one of three gesticulation levels.
 +	//-----------------------------------------------------------------------------------------
 +	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
 +	
 +			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
 +	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
 +	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
 +
 +	return gesticulationLevel;
 +
 +}//---------------------------------------------------
 +
 +
 +
 +//------------------------------------
 +// Destructor
 +//------------------------------------
 +LLVoiceVisualizer::~LLVoiceVisualizer()
 +{
 +}//----------------------------------------------
 +
 +
 +#ifdef XXX_STINSON_CHUI_REWORK
 +//---------------------------------------------------
 +// "packData" is inherited from HUDEffect
 +//---------------------------------------------------
 +void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
 +{
 +	// Pack the default data
 +	LLHUDEffect::packData(mesgsys);
 +
 +	// TODO -- pack the relevant data for voice effects
 +	// we'll come up with some cool configurations....TBD
 +	//U8 packed_data[41];
 +	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
 +	U8 packed_data = 0;
 +	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
 +}
 +
 +
 +//---------------------------------------------------
 +// "unpackData" is inherited from HUDEffect
 +//---------------------------------------------------
 +void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
 +{
 +	// TODO -- find the speaker, unpack binary data, set the properties of this effect
 +	/*
 +	LLHUDEffect::unpackData(mesgsys, blocknum);
 +	LLUUID source_id;
 +	LLUUID target_id;
 +	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
 +	if (size != 1)
 +	{
 +		llwarns << "Voice effect with bad size " << size << llendl;
 +		return;
 +	}
 +	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
 +	*/
 +}
 +
 +
 +//------------------------------------------------------------------
 +// this method is inherited from HUD Effect
 +//------------------------------------------------------------------
 +void LLVoiceVisualizer::markDead()
 +{
 +	mCurrentlySpeaking		= false;
 +	mVoiceEnabled			= false;
 +	mSoundSymbol.mActive	= false;
 +
 +	LLHUDEffect::markDead();
 +}//------------------------------------------------------------------
 +
 +#endif // XXX_STINSON_CHUI_REWORK
 diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h index e434c7f3f1..6258de163d 100644 --- a/indra/newview/llvoicevisualizer.h +++ b/indra/newview/llvoicevisualizer.h @@ -42,7 +42,11 @@  #ifndef LL_VOICE_VISUALIZER_H  #define LL_VOICE_VISUALIZER_H +#ifdef XXX_STINSON_CHUI_REWORK  #include "llhudeffect.h" +#else // XXX_STINSON_CHUI_REWORK +#include "llpointer.h" +#endif // XXX_STINSON_CHUI_REWORK  //-----------------------------------------------------------------------------------------------  // The values of voice gesticulation represent energy levels for avatar animation, based on  @@ -60,34 +64,45 @@ enum VoiceGesticulationLevel  	NUM_VOICE_GESTICULATION_LEVELS  }; +#ifdef XXX_STINSON_CHUI_REWORK  const static int NUM_VOICE_SYMBOL_WAVES = 7; +#endif // XXX_STINSON_CHUI_REWORK  //----------------------------------------------------  // LLVoiceVisualizer class   //---------------------------------------------------- +#ifdef XXX_STINSON_CHUI_REWORK  class LLVoiceVisualizer : public LLHUDEffect +#else // XXX_STINSON_CHUI_REWORK +class LLVoiceVisualizer : public LLRefCount +#endif // XXX_STINSON_CHUI_REWORK  {  	//---------------------------------------------------  	// public methods   	//---------------------------------------------------  	public: -		LLVoiceVisualizer ( const U8 type );	//constructor +#ifdef XXX_STINSON_CHUI_REWORK +		LLVoiceVisualizer( const U8 type );	//constructor +#else // XXX_STINSON_CHUI_REWORK +		LLVoiceVisualizer();	//constructor +#endif // XXX_STINSON_CHUI_REWORK  		~LLVoiceVisualizer();					//destructor -		 -		friend class LLHUDObject; +#ifdef XXX_STINSON_CHUI_REWORK  		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head  		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level   		void					setMaxGesticulationAmplitude( F32 );					// the upper range of meaningful amplitude for setting gesticulation level  +#endif // XXX_STINSON_CHUI_REWORK  		void					setStartSpeaking();										// tell me when the av starts speaking +#ifdef XXX_STINSON_CHUI_REWORK  		void					setVoiceEnabled( bool );								// tell me whether or not the user is voice enabled +#endif // XXX_STINSON_CHUI_REWORK  		void					setSpeakingAmplitude( F32 );							// tell me how loud the av is speaking (ranges from 0 to 1)  		void					setStopSpeaking();										// tell me when the av stops speaking  		bool					getCurrentlySpeaking();									// the get for the above set  		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech -		static void				setPreferences( ); -		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats  		void					lipSyncOohAah( F32& ooh, F32& aah ); +#ifdef XXX_STINSON_CHUI_REWORK  		void					render();												// inherited from HUD Effect  		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect  		void 					unpackData(LLMessageSystem *mesgsys, S32 blocknum);		// inherited from HUD Effect @@ -103,12 +118,17 @@ class LLVoiceVisualizer : public LLHUDEffect  		//----------------------------------------------------------------------------------------------  		void setMaxGesticulationAmplitude();   		void setMinGesticulationAmplitude();  +#endif // XXX_STINSON_CHUI_REWORK  	//---------------------------------------------------  	// private members   	//---------------------------------------------------  	private: -	 +		static bool				handleVoiceVisualizerPrefsChanged(const LLSD& newvalue); +		static void				setPreferences( ); +		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats + +#ifdef XXX_STINSON_CHUI_REWORK  		struct SoundSymbol  		{  			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ]; @@ -119,15 +139,20 @@ class LLVoiceVisualizer : public LLHUDEffect  			bool					mActive;  			LLVector3				mPosition;  		}; +#endif // XXX_STINSON_CHUI_REWORK  		LLFrameTimer			mTimer;							// so I can ask the current time in seconds  		F64						mStartTime;						// time in seconds when speaking started +#ifdef XXX_STINSON_CHUI_REWORK  		F64						mCurrentTime;					// current time in seconds, captured every step  		F64						mPreviousTime;					// copy of "current time" from last frame  		SoundSymbol				mSoundSymbol;					// the sound symbol that appears over the avatar's head  		bool					mVoiceEnabled;					// if off, no rendering should happen +#endif // XXX_STINSON_CHUI_REWORK  		bool					mCurrentlySpeaking;				// is the user currently speaking? +#ifdef XXX_STINSON_CHUI_REWORK  		LLVector3				mVoiceSourceWorldPosition;		// give this to me every step - I need it to update the sound symbol +#endif // XXX_STINSON_CHUI_REWORK  		F32						mSpeakingAmplitude;				// this should be set as often as possible when the user is speaking  		F32						mMaxGesticulationAmplitude;		// this is the upper-limit of the envelope of detectable gesticulation leves  		F32						mMinGesticulationAmplitude;		// this is the lower-limit of the envelope of detectable gesticulation leves diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a64655960f..6900a82ea8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4664,11 +4664,6 @@ void LLPipeline::rebuildPools()  		}  		max_count--;  	} - -	if (isAgentAvatarValid()) -	{ -		gAgentAvatarp->rebuildHUD(); -	}  }  void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) @@ -6184,7 +6179,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)  }  void LLPipeline::resetVertexBuffers() -{ +{	  	mResetVertexBuffers = true;  } diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml index d6d8431150..45afe6b70b 100644 --- a/indra/newview/skins/default/xui/en/floater_people.xml +++ b/indra/newview/skins/default/xui/en/floater_people.xml @@ -7,20 +7,20 @@    height="570"    help_topic="sidebar_people"    min_height="440" -  min_width="333" +  min_width="390"    layout="topleft"    name="floater_people"    save_rect="true"    single_instance="true"    reuse_instance="true"    title="PEOPLE" -  width="333"> +  width="390">      <panel_container        default_panel_name="panel_people"        follows="all"        height="570"        name="main_panel" -      width="333"> +      width="390">        <panel          class="panel_people"          name="panel_people" @@ -31,11 +31,5 @@          filename="panel_group_info_sidetray.xml"          label="Group Profile"          font="SansSerifBold"/> -      <panel -        class="panel_block_list_sidetray" -        name="panel_block_list_sidetray" -        filename="panel_block_list_sidetray.xml" -        label="Blocked Residents & Objects" -        font="SansSerifBold"/>      </panel_container>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml new file mode 100644 index 0000000000..9346295d5b --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- +  Not can_close / no title to avoid window chrome +  Single instance - only have one at a time, recycle it each spawn +--> +<floater + legacy_header_height="25" + bevel_style="in" + bg_opaque_image="Inspector_Background" + can_close="false" + can_minimize="false" + height="90" + layout="topleft" + name="floater_voice_volume" + single_instance="true" + sound_flags="0" + title="VOICE VOLUME" + visible="true" + width="245"> +    <text +     follows="top|left|right" +     font="SansSerifSmall" +     height="21" +     left="10" +     name="avatar_name" +     parse_urls="false" +     top="35" +     text_color="White" +     translate="false" +     use_ellipses="true" +     value="TestString PleaseIgnore" +     width="225" /> +    <slider +     follows="top|left" +     height="23" +     increment="0.01" +     left="1" +     max_val="0.95" +     min_val="0.05" +     name="volume_slider" +     show_text="false" +     tool_tip="Voice volume" +     top_pad="0" +     value="0.5" +     width="200" /> +    <button +     follows="top|left" +     height="16" +     image_disabled="Audio_Off" +     image_disabled_selected="AudioMute_Off" +     image_hover_selected="AudioMute_Over" +     image_selected="AudioMute_Off" +     image_unselected="Audio_Off" +     is_toggle="true" +     left_pad="0" +     top_delta="4" +     name="mute_btn" +     width="16" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index bc3bcd331b..c3481e6d4c 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -9,7 +9,7 @@   bg_opaque_image="Inspector_Background"   can_close="false"   can_minimize="false" - height="164" + height="130"   layout="topleft"   name="inspect_avatar"   single_instance="true" @@ -94,32 +94,17 @@       use_ellipses="true"       width="220">This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot      </text> -    <slider -     follows="top|left" -     height="23" -     increment="0.01" -     left="1" -     max_val="0.95" -     min_val="0.05" -     name="volume_slider" -     show_text="false" -     tool_tip="Voice volume" -     top_pad="0" -     value="0.5" -     width="200" /> -    <button +    <text       follows="top|left"       height="16" -     image_disabled="Audio_Off" -     image_disabled_selected="AudioMute_Off" -     image_hover_selected="AudioMute_Over" -     image_selected="AudioMute_Off" -     image_unselected="Audio_Off" -     is_toggle="true" -     left_pad="0" -     top_delta="4" -     name="mute_btn" -     width="16" /> +     left="8" +     name="avatar_profile_link" +     font="SansSerifSmall" +     text_color="White" +     top_pad="5" +     translate="false" +     value="[[LINK] View full profile]" +     width="175" />      <avatar_icon       follows="top|left"       height="38" @@ -130,83 +115,4 @@       name="avatar_icon"       top="10"       width="38" /> -<!-- Overlapping buttons for default actions -    llinspectavatar.cpp makes visible the most likely default action  ---> -    <button -     follows="top|left" -     height="20" -     label="Add Friend" -     left="8" -     top="135" -     name="add_friend_btn" -     width="90" /> -    <button -     follows="top|left" -     height="20" -     label="IM" -     left_delta="0" -     top_delta="0" -     name="im_btn" -     width="80" -     commit_callback.function="InspectAvatar.IM"/> -	<button -     follows="top|left" -     height="20" -     label="Profile" -     layout="topleft" -     name="view_profile_btn" -     left_delta="96" -     top_delta="0" -     tab_stop="false" -     width="80" /> -      <!--  gear buttons here --> -  <menu_button -     follows="top|left" -     height="20" -     layout="topleft" -     image_overlay="OptionsMenu_Off" -     menu_filename="menu_inspect_avatar_gear.xml" -     name="gear_btn" -     right="-5" -     top_delta="0" -     width="35" /> -	<menu_button -     follows="top|left" -     height="20" -     image_overlay="OptionsMenu_Off" -     menu_filename="menu_inspect_self_gear.xml" -     name="gear_self_btn" -     right="-5" -     top_delta="0" -     width="35" /> -  <panel  -    follows="top|left"  -    top="164"  -    left="0"  -    height="60"  -    width="228"  -    visible="false" -    background_visible="true" -    name="moderator_panel" -    background_opaque="true"  -    bg_opaque_color="MouseGray"> -    <button -      name="disable_voice" -      label="Disable Voice" -      top="20" -      width="95" -      height="20" -      left="10" -      commit_callback.function="InspectAvatar.DisableVoice"/> -    <button -      name="enable_voice" -      label="Enable Voice" -      top="20" -      width="95" -      height="20" -      left="10" -      visible="false"  -      commit_callback.function="InspectAvatar.EnableVoice"/> -  </panel>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml index fce7414d80..eca9e7f3c9 100644 --- a/indra/newview/skins/default/xui/en/menu_group_plus.xml +++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml @@ -1,5 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu name="menu_group_plus" +<toggleable_menu name="menu_group_plus"       left="0" bottom="0" visible="false"       mouse_opaque="false">    <menu_item_call name="item_join" label="Join Group..."> @@ -8,4 +8,4 @@    <menu_item_call name="item_new" label="New Group...">      <menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />    </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml deleted file mode 100644 index 76b188220d..0000000000 --- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml +++ /dev/null @@ -1,143 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<toggleable_menu -         create_jump_keys="true" -         layout="topleft" -         mouse_opaque="false" -         visible="false" -         name="Gear Menu"> -  <menu_item_call -   label="View Profile" -   enabled="true"  -   name="view_profile"> -    <menu_item_call.on_click -     function="InspectAvatar.ViewProfile"/> -  </menu_item_call> -  <menu_item_call -   label="Add Friend" -   name="add_friend"> -    <menu_item_call.on_click -     function="InspectAvatar.AddFriend"/> -    <menu_item_call.on_enable -     function="InspectAvatar.Gear.Enable"/> -  </menu_item_call> -  <menu_item_call -   label="IM" -   name="im"> -    <menu_item_call.on_click -     function="InspectAvatar.IM"/> -  </menu_item_call> -  <menu_item_call -   label="Call" -   enabled="true" -   name="call"> -    <menu_item_call.on_click -     function="InspectAvatar.Call"/> -    <menu_item_call.on_enable -     function="InspectAvatar.Gear.EnableCall"/> -  </menu_item_call> -  <menu_item_call -   label="Teleport" -   name="teleport"> -    <menu_item_call.on_click -     function="InspectAvatar.Teleport"/> -    <menu_item_call.on_enable -     function="InspectAvatar.Gear.EnableTeleportOffer"/> -  </menu_item_call> -  <menu_item_call -   label="Invite to Group" -   name="invite_to_group"> -    <menu_item_call.on_click -     function="InspectAvatar.InviteToGroup"/> -  </menu_item_call> -  <menu_item_separator /> -  <menu_item_call -   label="Block" -   name="block"> -    <menu_item_call.on_click -     function="InspectAvatar.ToggleMute"/> -    <menu_item_call.on_visible -     function="InspectAvatar.EnableMute" /> -  </menu_item_call> -  <menu_item_call -   label="Unblock" -   name="unblock"> -    <menu_item_call.on_click -     function="InspectAvatar.ToggleMute"/> -    <menu_item_call.on_visible -     function="InspectAvatar.EnableUnmute" /> -  </menu_item_call> -  <menu_item_call -   label="Report" -   name="report"> -    <menu_item_call.on_click -     function="InspectAvatar.Report"/> -  </menu_item_call>   -  <menu_item_call -   label="Freeze" -   name="freeze"> -    <menu_item_call.on_click -     function="InspectAvatar.Freeze"/> -    <menu_item_call.on_visible -     function="InspectAvatar.VisibleFreeze"/> -  </menu_item_call> -  <menu_item_call -   label="Eject" -   name="eject"> -    <menu_item_call.on_click -     function="InspectAvatar.Eject"/> -    <menu_item_call.on_visible -     function="InspectAvatar.VisibleEject"/> -  </menu_item_call> -  <menu_item_call -   label="Kick" -   name="kick"> -    <menu_item_call.on_click -     function="InspectAvatar.Kick"/> -    <menu_item_call.on_visible -     function="InspectAvatar.EnableGod"/> -  </menu_item_call> -  <menu_item_call -  label="CSR" -  name="csr"> -    <menu_item_call.on_click -     function="InspectAvatar.CSR" /> -    <menu_item_call.on_visible -     function="InspectAvatar.EnableGod" /> -  </menu_item_call> -  <menu_item_call -   label="Debug Textures" -   name="debug"> -    <menu_item_call.on_click -     function="Avatar.Debug"/> -    <menu_item_call.on_visible -     function="IsGodCustomerService"/> -  </menu_item_call> -  <menu_item_call -   label="Find On Map" -   name="find_on_map"> -    <menu_item_call.on_click -     function="InspectAvatar.FindOnMap"/> -    <menu_item_call.on_visible -     function="InspectAvatar.VisibleFindOnMap"/> -  </menu_item_call> -  <menu_item_call -   label="Zoom In" -   name="zoom_in"> -    <menu_item_call.on_click -     function="InspectAvatar.ZoomIn"/> -    <menu_item_call.on_visible -     function="InspectAvatar.VisibleZoomIn"/> -  </menu_item_call>   -  <menu_item_call -   label="Pay" -   name="pay"> -    <menu_item_call.on_click -     function="InspectAvatar.Pay"/> -  </menu_item_call> -  <menu_item_call -   label="Share" -   name="share"> -    <menu_item_call.on_click -     function="InspectAvatar.Share"/> -  </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml deleted file mode 100644 index 5e7b16ed4a..0000000000 --- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml +++ /dev/null @@ -1,252 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<toggleable_menu - layout="topleft" - name="Self Pie"> -  <menu_item_call -   label="Sit Down" -   layout="topleft" -   name="Sit Down Here"> -    <menu_item_call.on_click -     function="Self.SitDown" -     parameter="" /> -    <menu_item_call.on_enable -     function="Self.EnableSitDown" /> -  </menu_item_call> -  <menu_item_call -   label="Stand Up" -   layout="topleft" -   name="Stand Up"> -    <menu_item_call.on_click -     function="Self.StandUp" -     parameter="" /> -    <menu_item_call.on_enable -     function="Self.EnableStandUp" /> -  </menu_item_call> -  <context_menu -   label="Take Off" -   layout="topleft" -   name="Take Off >"> -    <context_menu -     label="Clothes" -     layout="topleft" -     name="Clothes >"> -      <menu_item_call -       enabled="false" -       label="Shirt" -       layout="topleft" -       name="Shirt"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="shirt" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="shirt" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Pants" -       layout="topleft" -       name="Pants"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="pants" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="pants" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Skirt" -       layout="topleft" -       name="Skirt"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="skirt" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="skirt" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Shoes" -       layout="topleft" -       name="Shoes"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="shoes" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="shoes" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Socks" -       layout="topleft" -       name="Socks"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="socks" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="socks" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Jacket" -       layout="topleft" -       name="Jacket"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="jacket" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="jacket" /> -      </menu_item_call> -      <menu_item_call -       enabled="false" -       label="Gloves" -       layout="topleft" -       name="Gloves"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="gloves" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="gloves" /> -      </menu_item_call> -      <menu_item_call -            enabled="false" -            label="Undershirt" -            layout="topleft" -            name="Self Undershirt"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="undershirt" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="undershirt" /> -      </menu_item_call> -      <menu_item_call -        enabled="false" -        label="Underpants" -        layout="topleft" -        name="Self Underpants"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="underpants" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="underpants" /> -      </menu_item_call> -      <menu_item_call -        enabled="false" -        label="Tattoo" -        layout="topleft" -        name="Self Tattoo"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="tattoo" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="tattoo" /> -      </menu_item_call> -      <menu_item_call -        enabled="false" -        label="Alpha" -        layout="topleft" -        name="Self Alpha"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="alpha" /> -        <menu_item_call.on_enable -         function="Edit.EnableTakeOff" -         parameter="alpha" /> -      </menu_item_call> -      <menu_item_separator -       layout="topleft" /> -      <menu_item_call -       label="All Clothes" -       layout="topleft" -       name="All Clothes"> -        <menu_item_call.on_click -         function="Edit.TakeOff" -         parameter="all" /> -      </menu_item_call> -    </context_menu> -    <context_menu -     label="HUD" -     layout="topleft" -     name="Object Detach HUD" /> -    <context_menu -     label="Detach" -     layout="topleft" -     name="Object Detach" /> -    <menu_item_call -     label="Detach All" -     layout="topleft" -     name="Detach All"> -      <menu_item_call.on_click -       function="Self.RemoveAllAttachments" -       parameter="" /> -      <menu_item_call.on_enable -       function="Self.EnableRemoveAllAttachments" /> -    </menu_item_call> -  </context_menu> -  <menu_item_call -  label="Change Outfit" -  layout="topleft" -  name="Chenge Outfit"> -    <menu_item_call.on_click -     function="CustomizeAvatar" /> -    <menu_item_call.on_enable -     function="Edit.EnableCustomizeAvatar" /> -  </menu_item_call> -  <menu_item_call label="Edit My Outfit" -  layout="topleft" -  name="Edit Outfit"> -    <menu_item_call.on_click -     function="EditOutfit" /> -    <menu_item_call.on_enable -     function="Edit.EnableCustomizeAvatar" /> -  </menu_item_call> -  <menu_item_call label="Edit My Shape" -  layout="topleft" -  name="Edit My Shape"> -    <menu_item_call.on_click -     function="EditShape" /> -    <menu_item_call.on_enable -     function="Edit.EnableEditShape" /> -  </menu_item_call> -  <menu_item_call -    label="My Friends" -    layout="topleft" -    name="Friends..."> -    <menu_item_call.on_click -     function="SideTray.PanelPeopleTab" -     parameter="friends_panel" /> -  </menu_item_call> -  <menu_item_call -   label="My Groups" -   layout="topleft" -   name="Groups..."> -    <menu_item_call.on_click -     function="SideTray.PanelPeopleTab" -     parameter="groups_panel" /> -  </menu_item_call> -  <menu_item_call -    label="My Profile" -    layout="topleft" -    name="Profile..."> -    <menu_item_call.on_click -     function="ShowAgentProfile" -     parameter="agent" /> -  </menu_item_call> -  <menu_item_call -   label="Debug Textures" -       name="Debug..."> -    <menu_item_call.on_click -     function="Avatar.Debug" /> -    <menu_item_call.on_visible -     function="IsGodCustomerService"/> -  </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml index b452f96e7a..eab7b8c085 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml @@ -40,8 +40,4 @@       function="CheckControl"       parameter="FriendsListShowPermissions" />    </menu_item_check> -  <menu_item_separator layout="topleft" /> -  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> -    <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" /> -  </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml index 8f89d37dbb..3a450258fa 100644 --- a/indra/newview/skins/default/xui/en/menu_people_groups.xml +++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml @@ -1,5 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu name="menu_group_plus" +<toggleable_menu name="menu_group_plus"   left="0" bottom="0" visible="false"   mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">    <menu_item_call @@ -54,4 +54,4 @@       function="People.Groups.Enable"       parameter="leave" />    </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml index c710fe3b9b..73f79f1e70 100644 --- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml @@ -14,13 +14,4 @@         function="CheckControl"         parameter="GroupListShowIcons" />    </menu_item_check> -  <menu_item_call -   label="Leave Selected Group" -   layout="topleft" -   name="Leave Selected Group"> -      <menu_item_call.on_click -       function="People.Group.Minus.Action"/> -      <menu_item_call.on_enable -       function="People.Group.Minus.Enable"/> -  </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml new file mode 100644 index 0000000000..da88ca9f4d --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_group_plus" + left="0" bottom="0" visible="false" + mouse_opaque="false"> +    <menu_item_check +       label="Sort by Recent Speakers" +       name="sort_by_recent_speakers"> +      <menu_item_check.on_click +         function="People.Nearby.ViewSort.Action" +       parameter="sort_by_recent_speakers"/> +      <menu_item_check.on_check +         function="People.Nearby.ViewSort.CheckItem" +         parameter="sort_by_recent_speakers"/> +    </menu_item_check> +    <menu_item_check +       label="Sort by Name" +       name="sort_name"> +      <menu_item_check.on_click +         function="People.Nearby.ViewSort.Action" +         parameter="sort_name"/> +      <menu_item_check.on_check +         function="People.Nearby.ViewSort.CheckItem" +         parameter="sort_name"/> +    </menu_item_check> +    <menu_item_check +       label="Sort by Distance" +       name="sort_distance"> +      <menu_item_check.on_click +         function="People.Nearby.ViewSort.Action" +         parameter="sort_distance"/> +      <menu_item_check.on_check +         function="People.Nearby.ViewSort.CheckItem" +         parameter="sort_distance"/> +    </menu_item_check> +    <menu_item_separator layout="topleft" /> +    <menu_item_check name="view_icons" label="View People Icons"> +        <menu_item_check.on_click +         function="People.Nearby.ViewSort.Action" +         parameter="view_icons" /> +        <menu_item_check.on_check +         function="CheckControl" +         parameter="NearbyListShowIcons" /> +    </menu_item_check> +    <menu_item_check name ="view_map" label="View Map"> +        <menu_item_check.on_check +         function="CheckControl" +         parameter="NearbyListShowMap" /> +        <menu_item_check.on_click +         function="ToggleControl" +         parameter="NearbyListShowMap" /> +    </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml deleted file mode 100644 index 614dd693c5..0000000000 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<toggleable_menu -     name="menu_group_plus" -     left="0" bottom="0" visible="false" -     mouse_opaque="false"> -  <menu_item_check -     label="Sort by Recent Speakers" -     name="sort_by_recent_speakers"> -    <menu_item_check.on_click -       function="People.Nearby.ViewSort.Action" -       parameter="sort_by_recent_speakers"/> -    <menu_item_check.on_check -       function="People.Nearby.ViewSort.CheckItem" -       parameter="sort_by_recent_speakers"/> -  </menu_item_check> -  <menu_item_check -     label="Sort by Name" -     name="sort_name"> -    <menu_item_check.on_click -       function="People.Nearby.ViewSort.Action" -       parameter="sort_name"/> -    <menu_item_check.on_check -       function="People.Nearby.ViewSort.CheckItem" -       parameter="sort_name"/> -  </menu_item_check> -  <menu_item_check -     label="Sort by Distance" -     name="sort_distance"> -    <menu_item_check.on_click -       function="People.Nearby.ViewSort.Action" -       parameter="sort_distance"/> -    <menu_item_check.on_check -       function="People.Nearby.ViewSort.CheckItem" -       parameter="sort_distance"/> -  </menu_item_check> -  <menu_item_separator layout="topleft" /> -  <menu_item_check name="view_icons" label="View People Icons"> -    <menu_item_check.on_click -     function="People.Nearby.ViewSort.Action" -     parameter="view_icons" /> -    <menu_item_check.on_check -     function="CheckControl" -     parameter="NearbyListShowIcons" /> -  </menu_item_check> -  <menu_item_check name ="view_map" label="View Map"> -    <menu_item_check.on_check -      function="CheckControl" -      parameter="NearbyListShowMap" /> -    <menu_item_check.on_click -      function="ToggleControl" -      parameter="NearbyListShowMap" /> -  </menu_item_check> -  <menu_item_separator layout="topleft" /> -  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> -    <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" /> -  </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml index 485a5a658c..1dbc90dd2b 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml @@ -32,8 +32,4 @@       function="CheckControl"       parameter="RecentListShowIcons" />    </menu_item_check> -  <menu_item_separator layout="topleft" /> -  <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> -    <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" /> -  </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 59dd17ea9d..d35cebbd16 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2904,6 +2904,7 @@ Would you like to trust this authority?     icon="alertmodal.tga"     name="GrantedModifyRights"     persist="true" +   log_to_im="true"        type="notify">  [NAME] has given you permission to edit their objects.    </notification> @@ -2912,6 +2913,7 @@ Would you like to trust this authority?     icon="alertmodal.tga"     name="RevokedModifyRights"     persist="true" +   log_to_im="true"        type="notify">  Your privilege to modify [NAME]'s objects has been revoked    </notification> @@ -5161,6 +5163,8 @@ The string [STRING_NAME] is missing from strings.xml    <notification     icon="notifytip.tga"     name="IMSystemMessageTip" +   log_to_im="true"    +   log_to_chat="false"        type="notifytip">  [MESSAGE]    </notification> @@ -5205,6 +5209,7 @@ Topic: [SUBJECT], Message: [MESSAGE]    <notification     icon="notifytip.tga"     name="FriendOnline" +   log_to_chat="false"     type="notifytip">      <tag>friendship</tag>  <nolink>[NAME]</nolink> is Online @@ -5213,6 +5218,7 @@ Topic: [SUBJECT], Message: [MESSAGE]    <notification     icon="notifytip.tga"     name="FriendOffline" +   log_to_chat="false"     type="notifytip">      <tag>friendship</tag>  <nolink>[NAME]</nolink> is Offline @@ -5459,6 +5465,8 @@ You don't have permission to copy this.    <notification     icon="notifytip.tga"     name="InventoryAccepted" +   log_to_im="true"    +   log_to_chat="false"     type="notifytip">  [NAME] received your inventory offer.    </notification> @@ -5466,6 +5474,8 @@ You don't have permission to copy this.    <notification     icon="notifytip.tga"     name="InventoryDeclined" +   log_to_im="true"    +   log_to_chat="false"     type="notifytip">  [NAME] declined your inventory offer.    </notification> @@ -5547,6 +5557,7 @@ Please select at least one type of content to search (General, Moderate, or Adul    <notification     icon="notify.tga"     name="PaymentReceived" +   log_to_im="true"        persist="true"     type="notify">      <tag>funds</tag> @@ -5556,6 +5567,7 @@ Please select at least one type of content to search (General, Moderate, or Adul    <notification     icon="notify.tga"     name="PaymentSent" +   log_to_im="true"        persist="true"     type="notify">      <tag>funds</tag> @@ -5700,6 +5712,7 @@ The objects on the selected parcel that are NOT owned by you have been returned    <notification     icon="notify.tga"     name="ServerObjectMessage" +   log_to_im="true"        persist="true"     type="notify">  Message from [NAME]: @@ -6070,6 +6083,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="UserGiveItem" +   log_to_im ="true"     type="offer">  [NAME_SLURL] has given you this [OBJECTTYPE]:  [ITEM_SLURL] @@ -6125,6 +6139,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="TeleportOffered" +   log_to_im="true"     type="offer">  [NAME_SLURL] has offered to teleport you to their location: @@ -6145,6 +6160,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="TeleportOfferSent" +   log_to_im="true"        type="offer">  	Teleport offer sent to [TO_NAME]    </notification> @@ -6172,6 +6188,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="OfferFriendship" +   log_to_im="true"     type="offer">      <tag>friendship</tag>      <tag>confirm</tag> @@ -6195,6 +6212,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="FriendshipOffered" +   log_to_im="true"        type="offer">      <tag>friendship</tag>  	You have offered friendship to [TO_NAME] @@ -6224,6 +6242,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="FriendshipAccepted" +   log_to_im="true"        type="offer">      <tag>friendship</tag>  <nolink>[NAME]</nolink> accepted your friendship offer. @@ -6232,6 +6251,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th    <notification     icon="notify.tga"     name="FriendshipDeclined" +   log_to_im="true"        persist="true"     type="notify">      <tag>friendship</tag> @@ -6241,6 +6261,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th      <notification     icon="notify.tga"     name="FriendshipAcceptedByMe" +   log_to_im="true"        type="offer">      <tag>friendship</tag>  Friendship offer accepted. @@ -6249,6 +6270,7 @@ Friendship offer accepted.    <notification     icon="notify.tga"     name="FriendshipDeclinedByMe" +   log_to_im="true"        type="offer">      <tag>friendship</tag>  Friendship offer declined. diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml index 7c67fd7f83..3577d2f457 100644 --- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -4,6 +4,8 @@   follows="left|top|right|bottom"   height="305"   layout="topleft" + left="0" + right="-1"   name="block_list_panel"   help_topic="blocked_list"   min_height="350" @@ -28,7 +30,7 @@       layout="topleft"       left_pad="10"       name="title_text" -     text_color="White" +     text_color="white"       top="5"       width="250">          Block List @@ -41,6 +43,7 @@       name="blocked"       tool_tip="List of currently blocked Residents"       top="30" +  	 right="-1"       width="270">          <scroll_list.columns           name="item_name" /> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 98c7c49ff4..abfb9c7a36 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       name="no_filtered_friends_msg">           Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].      </string> -    <string -     name="people_filter_label" -     value="Filter People" /> -    <string -     name="groups_filter_label" -     value="Filter Groups" />       <!--       *WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes.       They are not defined as translatable in VLT. See EXT-5931 @@ -60,21 +54,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  	<string  	 name="AltMiniMapToolTipMsg"  	 value="[REGION](Double-click to teleport, shift-drag to pan)"/> -	<filter_editor -     follows="left|top|right" -     height="23" -     layout="topleft" -     left="10" -     label="Filter" -     max_length_chars="300" -     name="filter_input" -     text_color="Black" -     text_pad_left="10" -     top="3" -     width="303" />      <tab_container +     bottom="-10"       follows="all" -     height="383"       layout="topleft"       left="3"       name="tabs" @@ -82,31 +64,116 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       tab_min_width="70"       tab_height="30"       tab_position="top" -     top_pad="10" +     top="0"       halign="center" -     width="319"> -     	<panel +     right="-5"> + +<!-- ================================= NEARBY tab =========================== --> + +        <panel           background_opaque="true"           background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray" +         bottom="-1"           follows="all" -         height="383"           label="NEARBY"           layout="topleft"           left="0"           help_topic="people_nearby_tab"           name="nearby_panel" -         top="0" -         width="313"> +         right="-1" +         top="0"> +            <panel +             follows="left|top|right" +             height="27" +             label="bottom_panel" +             layout="topleft" +             left="0" +             name="nearby_buttons_panel" +             right="-1" +             top="0"> +                <filter_editor +                 follows="left|top|right" +                 height="23" +                 layout="topleft" +                 left="6" +                 label="Filter People" +                 max_length_chars="300" +                 name="nearby_filter_input" +                 text_color="Black" +                 text_pad_left="10" +                 top="4" +                 width="178" /> +                <button +                 commit_callback.function="People.Gear" +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="OptionsMenu_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="7" +                 name="gear_btn" +                 top="3" +                 width="31" /> +                <menu_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="Inv_Underpants" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 menu_filename="menu_people_nearby_view.xml" +                 menu_position="bottomleft" +                 name="nearby_view_btn" +                 top_delta="0" +                 width="31" /> +                <button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="AddItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 name="add_friend_btn" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.AddFriend" /> +                </button> +                <dnd_button +                 enabled="false" +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="TrashItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 left_pad="2" +                 layout="topleft" +                 name="nearby_del_btn" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.DelFriend" /> +                 </dnd_button> +            </panel>           <layout_stack             clip="false"             follows="all" -           height="355" +           height="410"             layout="topleft" +           left="0"             mouse_opaque="false"             orientation="vertical" -           width="313"> +           right="-1" +           top_pad="0">             <layout_panel               height="142"               layout="topleft" @@ -123,16 +190,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M                 left="3"                 mouse_opaque="false"                 name="Net Map" -               top="4" -               width="305"/> +               right="-1" +               top="4" />             </layout_panel>             <layout_panel               height="213"               layout="topleft"               min_dim="100"               mouse_opaque="false" -             user_resize="true" -             width="313"> +             right="-1" +             user_resize="true">               <avatar_list                 allow_select="true"                 follows="all" @@ -143,84 +210,118 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M                 keep_one_selected="false"                 multi_select="true"                 name="avatar_list" -               top="2" -               width="306" /> +               right="-1" +               top="2" />             </layout_panel>           </layout_stack> -         <panel -             background_visible="true" -             follows="left|right|bottom" -             height="27" -             label="bottom_panel" -             layout="topleft" -             left="3" -             name="bottom_panel" -             top_pad="0" -             width="313"> -             <menu_button -             follows="bottom|left" -             height="25" -             image_hover_unselected="Toolbar_Left_Over" -             image_overlay="OptionsMenu_Off" -             image_selected="Toolbar_Left_Selected" -             image_unselected="Toolbar_Left_Off" -             layout="topleft" -             left="0" -             name="nearby_view_sort_btn" -             tool_tip="Options" -             top="1" -             width="31" /> -             <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -             	 image_overlay="AddItem_Off" -                 image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 left_pad="1" -                 name="add_friend_btn" -                 tool_tip="Add selected Resident to your friends List" -                 width="31"> -               <commit_callback -                  function="People.addFriend" /> -             </button> -             <icon -             follows="bottom|left|right" -             height="25" -             image_name="Toolbar_Right_Off" -             layout="topleft" -             left_pad="1" -             name="dummy_icon" -             width="243" -             /> -            </panel>          </panel> + +<!-- ================================= FRIENDS tab ========================== --> +          <panel           background_opaque="true"         background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray" +         bottom="-1"           follows="all" -         height="383"           label="MY FRIENDS"           layout="topleft"           left="0"           help_topic="people_friends_tab"           name="friends_panel" -         top="0" -         width="313"> +         right="-1" +         top="0"> +            <panel +             follows="left|top|right" +             height="27" +             label="bottom_panel" +             layout="topleft" +             left="0" +             name="friends_buttons_panel" +             right="-1" +             top="0"> +                <filter_editor +                 follows="left|top|right" +                 height="23" +                 layout="topleft" +                 left="6" +                 label="Filter People" +                 max_length_chars="300" +                 name="friends_filter_input" +                 text_color="Black" +                 text_pad_left="10" +                 top="4" +                 width="177" /> +                <button +                 commit_callback.function="People.Gear" +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="OptionsMenu_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="8" +                 name="gear_btn" +                 top="3" +                 width="31" /> +                <menu_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="Inv_Underpants" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 menu_filename="menu_people_friends_view.xml" +                 menu_position="bottomleft" +                 name="friends_view_btn" +                 top_delta="0" +                 width="31" /> +                <button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="AddItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 name="friends_add_btn" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.AddFriendWizard" /> +                </button> +                <dnd_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="TrashItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 left_pad="2" +                 layout="topleft" +                 name="friends_del_btn" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.DelFriend" /> +                </dnd_button> +            </panel>              <accordion         		 background_visible="true"         		 bg_alpha_color="DkGray2"         		 bg_opaque_color="DkGray2"               follows="all" -             height="356" +             height="408"               layout="topleft"               left="3"               name="friends_accordion" -             top="0" -             width="307"> +             right="-2" +             top_pad="2">                  <accordion_tab                   layout="topleft"                   height="172" @@ -257,247 +358,131 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M                           width="307" />                  </accordion_tab>              </accordion> -            <panel -             background_visible="true" -             follows="left|right|bottom" -             height="27" -             label="bottom_panel" -             layout="topleft" -             left="3" -             name="bottom_panel" -             top_pad="0" -             width="313"> -              -             	  <layout_stack -				   animate="false" -				   border_size="0" -				   follows="left|right|bottom" -				   height="25" -				   layout="topleft" -				   orientation="horizontal" -				   top_pad="1" -				   left="0" -				   name="bottom_panel" -				   width="308"> -				      <layout_panel -				       auto_resize="false" -				       height="25" -				       layout="topleft" -				       name="options_gear_btn_panel" -				       width="32"> -				          <menu_button -				           follows="bottom|left" -				           tool_tip="Show additional options" -				           height="25" -				           image_hover_unselected="Toolbar_Left_Over" -				           image_overlay="OptionsMenu_Off" -				           image_selected="Toolbar_Left_Selected" -				           image_unselected="Toolbar_Left_Off" -				           layout="topleft" -				           left="0" -				           name="friends_viewsort_btn" -				           top="0" -				           width="31" /> -				      </layout_panel> -				      <layout_panel -				       auto_resize="false" -				       height="25" -				       layout="topleft" -				       name="add_btn_panel" -				       width="32"> -				          <button -				           follows="bottom|left" -				           height="25" -				           image_hover_unselected="Toolbar_Middle_Over" -				           image_overlay="AddItem_Off" -				           image_selected="Toolbar_Middle_Selected" -				           image_unselected="Toolbar_Middle_Off" -				           layout="topleft" -				           left="0" -				           name="add_btn" -				           tool_tip="Offer friendship to a Resident" -				           top="0" -				           width="31" /> -				      </layout_panel> -				      <layout_panel -				       auto_resize="true" -				       height="25" -				       layout="topleft" -				       name="dummy_panel" -				       width="210"> -				          <icon -				           follows="bottom|left|right" -				           height="25" -				           image_name="Toolbar_Middle_Off" -				           layout="topleft" -				           left="0" -				           top="0" -				           name="dummy_icon" -				           width="210" /> -				      </layout_panel> -				      <layout_panel -				       auto_resize="false" -				       height="25" -				       layout="topleft" -				       name="trash_btn_panel" -				       width="31"> -				          <dnd_button -				           follows="bottom|left" -				           height="25" -				           image_hover_unselected="Toolbar_Right_Over" -				           image_overlay="TrashItem_Off" -				           image_selected="Toolbar_Right_Selected" -				           image_unselected="Toolbar_Right_Off" -				           left="0" -				           layout="topleft" -				           name="del_btn" -				           tool_tip="Remove selected person from your Friends list" -				           top="0" -				           width="31"/> -				      </layout_panel> -				  </layout_stack><!-- -              -               <button -               follows="bottom|left" -               tool_tip="Options" -               height="25" -               image_hover_unselected="Toolbar_Left_Over" -               image_overlay="OptionsMenu_Off" -               image_selected="Toolbar_Left_Selected" -               image_unselected="Toolbar_Left_Off" -               layout="topleft" -               left="0" -               name="friends_viewsort_btn" -               top="1" -               width="31" /> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -             	 image_overlay="AddItem_Off" -             	 image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 left_pad="1" -                 name="add_btn" -                 tool_tip="Offer friendship to a Resident" -                 width="31" /> -                <icon -             	 follows="bottom|left|right" -             	 height="25" -             	 image_name="Toolbar_Middle_Off" -             	 layout="topleft" -             	 left_pad="1" -             	 name="dummy_icon" -             	 width="209" -             /> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Right_Over" -                 image_overlay="TrashItem_Off" -                 image_selected="Toolbar_Right_Selected" -                 image_unselected="Toolbar_Right_Off" -                 layout="topleft" -                 left_pad="1" -                 name="del_btn" -                 tool_tip="Remove selected person from your Friends list" -                 width="31" /> -            --></panel>              <text               follows="all"               height="450"               left="13"               name="no_friends_help_text" -             top="10" -             width="293" +             right="-13" +             top="37"               wrap="true" />          </panel> + +<!-- ================================= GROUPS tab =========================== --> +          <panel           background_opaque="true"         background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray" +         bottom="-1"           follows="all" -         height="383"           label="MY GROUPS"           layout="topleft"           left="0"           help_topic="people_groups_tab"           name="groups_panel" -         top="0" -         width="313"> +         right="-1" +         top="0">      <!--       *NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931       Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()      --> -            <group_list -             allow_select="true"  -             follows="all" -             height="356" -             layout="topleft" -             left="3" -             name="group_list" -             top="0" -             width="307" />              <panel -             background_visible="true" -             follows="left|right|bottom" +             follows="left|top|right"               height="27"               label="bottom_panel"               layout="topleft"               left="0" -             name="bottom_panel" -             top_pad="0" -             width="313"> -               <menu_button -               follows="bottom|left" -               tool_tip="Options" -               height="25" -               image_hover_unselected="Toolbar_Left_Over" -               image_overlay="OptionsMenu_Off" -               image_selected="Toolbar_Left_Selected" -               image_unselected="Toolbar_Left_Off" -               layout="topleft" -               left="3" -               name="groups_viewsort_btn" -               top="1" -               width="31" /> -                <button -                 follows="bottom|left" +             name="groups_buttons_panel" +             right="-1" +             top="0"> +                <filter_editor +                 follows="left|top|right" +                 height="23" +                 layout="topleft" +                 left="6" +                 label="Filter Groups" +                 max_length_chars="300" +                 name="groups_filter_input" +                 text_color="Black" +                 text_pad_left="10" +                 top="4" +                 width="177" /> +                <menu_button +                 follows="right"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="AddItem_Off" +                 image_overlay="OptionsMenu_Off"                   image_selected="Toolbar_Middle_Selected"                   image_unselected="Toolbar_Middle_Off"                   layout="topleft" -                 left_pad="1" -                 name="plus_btn" -                 tool_tip="Join group/Create new group" +                 left_pad="8" +                 menu_filename="menu_people_groups.xml" +                 menu_position="bottomleft" +                 name="groups_gear_btn" +                 top="3"                   width="31" /> -                <button -                 follows="bottom|left" +                <menu_button +                 follows="right"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="Activate_Checkmark" +                 image_overlay="Inv_Underpants"                   image_selected="Toolbar_Middle_Selected"                   image_unselected="Toolbar_Middle_Off"                   layout="topleft" -                 left_pad="1" -                 name="activate_btn" -                 tool_tip="Activate selected group" +                 left_pad="2" +                 menu_filename="menu_people_groups_view.xml" +                 menu_position="bottomleft" +                 name="groups_view_btn" +                 top_delta="0"                   width="31" /> -                 <icon -             	 follows="bottom|left|right" -             	 height="25" -             	 image_name="Toolbar_Right_Off" -             	 layout="topleft" -             	 left_pad="1" -             	 name="dummy_icon" -             	 width="212" -             /> +                <menu_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="AddItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 menu_filename="menu_group_plus.xml" +                 menu_position="bottomleft" +                 name="plus_btn" +                 top_delta="0" +                 width="31"> +                    <validate_callback +                     function="People.Group.Plus.Validate" /> +                </menu_button> +                <dnd_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="TrashItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 left_pad="2" +                 layout="topleft" +                 name="minus_btn" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.Group.Minus" /> +                </dnd_button>              </panel> +            <group_list +             allow_select="true"  +             follows="all" +             height="406" +             layout="topleft" +             left="3" +             name="group_list" +             right="-2" +             top_pad="4" />          </panel> + +<!-- ================================= RECENT tab =========================== --> +          <panel           background_opaque="true"         background_visible="true" @@ -510,265 +495,128 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M           left="0"           help_topic="people_recent_tab"           name="recent_panel" -         top="0" -         width="313"> -            <avatar_list -             allow_select="true" -             follows="all" -             height="356" -             layout="topleft" -             left="3" -             multi_select="true" -             name="avatar_list" -             show_last_interaction_time="true" -             top="0" -             width="307" /> +         right="-1" +         top="0">              <panel -             background_visible="true" -             follows="left|right|bottom" +             follows="left|top|right"               height="27"               label="bottom_panel"               layout="topleft" -             left="3" -             name="bottom_panel" -             top_pad="0" -             width="313"> -               <menu_button -               follows="bottom|left" -               tool_tip="Options" -               height="25" -               image_hover_unselected="Toolbar_Left_Over" -               image_overlay="OptionsMenu_Off" -               image_selected="Toolbar_Left_Selected" -               image_unselected="Toolbar_Left_Off" -               layout="topleft" -               name="recent_viewsort_btn" -               top="1" -               width="31" /> -              <button -                 follows="bottom|left" +             left="0" +             name="recent_buttons_panel" +             right="-1" +             top="0"> +                <filter_editor +                 follows="left|top|right" +                 height="23" +                 layout="topleft" +                 left="6" +                 label="Filter People" +                 max_length_chars="300" +                 name="recent_filter_input" +                 text_color="Black" +                 text_pad_left="10" +                 top="4" +                 width="177" /> +                <button +                 commit_callback.function="People.Gear" +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="OptionsMenu_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="8" +                 name="gear_btn" +                 top="3" +                 width="31" /> +                <menu_button +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="Inv_Underpants" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="2" +                 menu_filename="menu_people_recent_view.xml" +                 menu_position="bottomleft" +                 name="recent_view_btn" +                 top_delta="0" +                 width="31" /> +                <button +                 follows="right"                   height="25"                   image_hover_unselected="Toolbar_Middle_Over"                   image_overlay="AddItem_Off"                   image_selected="Toolbar_Middle_Selected"                   image_unselected="Toolbar_Middle_Off"                   layout="topleft" -                 left_pad="1" +                 left_pad="2"                   name="add_friend_btn" -                 tool_tip="Add selected Resident to your friends List" +                 top_delta="0" +                 width="31"> +                    <commit_callback +                     function="People.AddFriend" /> +                </button> +                <dnd_button +                 enabled="false" +                 follows="right" +                 height="25" +                 image_hover_unselected="Toolbar_Middle_Over" +                 image_overlay="TrashItem_Off" +                 image_selected="Toolbar_Middle_Selected" +                 image_unselected="Toolbar_Middle_Off" +                 left_pad="2" +                 layout="topleft" +                 name="recent_del_btn" +                 top_delta="0"                   width="31"> -                <commit_callback -                   function="People.addFriend" /> -              </button> -              <icon -             	 follows="bottom|left|right" -             	 height="25" -             	 image_name="Toolbar_Right_Off" -             	 layout="topleft" -             	 left_pad="1" -             	 name="dummy_icon" -             	 width="244" -             /> +                    <commit_callback +                     function="People.DelFriend" /> +                 </dnd_button>              </panel> +            <avatar_list +             allow_select="true" +             follows="all" +             height="351" +             layout="topleft" +             left="3" +             multi_select="true" +             name="avatar_list" +             show_last_interaction_time="true" +             right="-2" +             top_pad="4" />          </panel> -    </tab_container> -    <panel -     follows="bottom|left|right" -     height="23" -     layout="topleft" -     left="8" -     top_pad="4" -     name="button_bar" -     width="313"> -<!--********************************Profile; IM; Call, Share, Teleport********************************--> 	 -     	<layout_stack -     	follows="bottom|left|right" -		height="23" -		layout="topleft" -		name="bottom_bar_ls" -		left="0" -		orientation="horizontal" -		top_pad="0" -		width="313"> +<!-- ================================= BLOCKED tab ========================== --> -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left="0" -			name="view_profile_btn_lp" -		    auto_resize="true" -			width="68"> -				<button -		         follows="bottom|left|right" -		         height="23" -		         label="Profile" -		         layout="topleft" -		         left="1" -		         name="view_profile_btn" -		         tool_tip="Show picture, groups, and other Residents information" -		         top="0" -		         width="67" />	 -			</layout_panel> -			 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			name="im_btn_lp" -		    auto_resize="true" -			width="41"> -				<button -		         follows="bottom|left|right" -		         left="1" -		         height="23" -		         label="IM" -		         layout="topleft" -		         name="im_btn" -		         tool_tip="Open instant message session" -		         top="0" -		         width="40" />			 -			</layout_panel> -			 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			name="call_btn_lp" -		    auto_resize="true" -			width="52"> -				<button -		         follows="bottom|left|right" -		         left="1" -		         height="23" -		         label="Call" -		         layout="topleft" -		         name="call_btn" -		         tool_tip="Call this Resident" -		         top="0" -		         width="51" />		 -			</layout_panel> -			 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			name="share_btn_lp" -		    auto_resize="true" -			width="66"> -				<button -		         follows="bottom|left|right" -		         left="1" -		         height="23" -		         label="Share" -		         layout="topleft" -		         name="share_btn" -		         tool_tip="Share an inventory item" -		         top="0" -		         width="65" />	 -			</layout_panel> -			 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			name="teleport_btn_lp" -		    auto_resize="true" -			width="77"> -				<button -		         follows="bottom|left|right" -		         left="1" -		         height="23" -		         label="Teleport" -		         layout="topleft" -		         name="teleport_btn" -		         tool_tip="Offer teleport" -		         top="0" -		         width="76" />		 -			</layout_panel> -		</layout_stack> -		 -<!--********************************Group Profile; Group Chat; Group Call buttons************************-->			 -		<layout_stack -     	follows="bottom|left|right" -		height="23" -		layout="topleft" -		mouse_opaque="false" -		name="bottom_bar_ls1" -		left="0" -		orientation="horizontal" -		top="0" -		width="313">	 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left="0"			 -			mouse_opaque="false" -			name="group_info_btn_lp" -		    auto_resize="true" -			width="108"> -				<button -		        follows="bottom|left|right" -		        left="1" -		        height="23" -		        label="Group Profile" -		        layout="topleft" -				mouse_opaque="false" -		        name="group_info_btn" -		        tool_tip="Show group information" -		        top="0" -		        width="107" />		 -			</layout_panel> -			 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			mouse_opaque="false" -			name="chat_btn_lp" -		    auto_resize="true" -			width="101"> -				<button -		        follows="bottom|left|right" -		        left="1" -		        height="23" -		        label="Group Chat" -		        layout="topleft" -				mouse_opaque="false" -		        name="chat_btn" -		        tool_tip="Open chat session" -		        top="0" -		        width="100" />			 -			</layout_panel> -		 -			<layout_panel -			follows="bottom|left|right" -			height="23" -			layout="bottomleft" -			left_pad="3" -			mouse_opaque="false" -			name="group_call_btn_lp" -		    auto_resize="true" -			width="96"> -				<button -				follows="bottom|left|right" -				left="1" -				height="23" -         		label="Group Call" -         		layout="topleft" -				mouse_opaque="false" -         		name="group_call_btn" -         		tool_tip="Call this group" -		        top="0" -         		width="95" />			 -			</layout_panel>		 -		</layout_stack> -    </panel> +        <panel +         background_opaque="true" +         background_visible="true" +         bg_alpha_color="DkGray" +         bg_opaque_color="DkGray" +         follows="all" +         height="383" +         label="BLOCKED" +         layout="topleft" +         left="0" +         help_topic="people_blocked_tab" +         name="blocked_panel" +         right="-1" +         top="0"> +          <panel +           class="panel_block_list_sidetray" +           height="383" +           name="panel_block_list_sidetray" +           filename="panel_block_list_sidetray.xml" +           follows="all" +           label="Blocked Residents & Objects" +           left="0" +           font="SansSerifBold" +           top="0" +           right="-1" /> +        </panel> +    </tab_container>  </panel>  | 
