diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llchatbar.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llfloatergesture.cpp | 255 | ||||
| -rw-r--r-- | indra/newview/llfloatergesture.h | 12 | ||||
| -rw-r--r-- | indra/newview/llgesturemgr.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/llgesturemgr.h | 30 | ||||
| -rw-r--r-- | indra/newview/llnearbychatbar.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_gesture.xml | 10 | 
7 files changed, 235 insertions, 113 deletions
| diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 4523267edd..442dc660cd 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -210,8 +210,9 @@ void LLChatBar::refreshGestures()  		// collect list of unique gestures  		std::map <std::string, BOOL> unique; -		LLGestureManager::item_map_t::iterator it; -		for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) +		LLGestureManager::item_map_t::const_iterator it; +		const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures(); +		for (it = active_gestures.begin(); it != active_gestures.end(); ++it)  		{  			LLMultiGesture* gesture = (*it).second;  			if (gesture) diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c114eed4a2..ca0ba96a08 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -89,6 +89,52 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)  	//LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");  } +void LLFloaterGesture::done() +{ +	//this method can be called twice: for GestureFolder and once after loading all sudir of GestureFolder +	if (gInventory.isCategoryComplete(mGestureFolderID)) +	{ +		LL_DEBUGS("Gesture")<< "mGestureFolderID loaded" << LL_ENDL; +		// we load only gesture folder without childred. +		LLInventoryModel::cat_array_t* categories; +		LLInventoryModel::item_array_t* items; +		folder_ref_t unloaded_folders; +		LL_DEBUGS("Gesture")<< "Get subdirs of Gesture Folder...." << LL_ENDL; +		gInventory.getDirectDescendentsOf(mGestureFolderID, categories, items); +		if (categories->empty()) +		{ +			gInventory.removeObserver(this); +			LL_INFOS("Gesture")<< "Gesture dos NOT contains sub-directories."<< LL_ENDL; +			return; +		} +		LL_DEBUGS("Gesture")<< "There are " << categories->size() << " Folders "<< LL_ENDL; +		for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); it != categories->end(); it++) +		{ +			if (!gInventory.isCategoryComplete(it->get()->getUUID())) +			{ +				unloaded_folders.push_back(it->get()->getUUID()); +				LL_DEBUGS("Gesture")<< it->get()->getName()<< " Folder added to fetchlist"<< LL_ENDL; +			} + +		} +		if (!unloaded_folders.empty()) +		{ +			LL_DEBUGS("Gesture")<< "Fetching subdirectories....." << LL_ENDL; +			fetchDescendents(unloaded_folders); +		} +		else +		{ +			LL_DEBUGS("Gesture")<< "All Gesture subdirectories have been loaded."<< LL_ENDL; +			gInventory.removeObserver(this); +			buildGestureList(); +		} +	} +	else +	{ +		LL_WARNS("Gesture")<< "Gesture list was NOT loaded"<< LL_ENDL; +	} +} +  // virtual  LLFloaterGesture::~LLFloaterGesture()  { @@ -121,7 +167,14 @@ BOOL LLFloaterGesture::postBuild()  	childSetVisible("play_btn", true);  	childSetVisible("stop_btn", false);  	setDefaultBtn("play_btn"); -	 +	mGestureFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE, false); + +	folder_ref_t folders; +	folders.push_back(mGestureFolderID); +	//perform loading Gesture directory anyway to make sure that all subdirectory are loaded too. See method done() for details. +	gInventory.addObserver(this); +	fetchDescendents(folders); +  	buildGestureList();  	childSetFocus("gesture_list"); @@ -171,101 +224,125 @@ void LLFloaterGesture::buildGestureList()  	if (! (list && scroll)) return; -	// attempt to preserve scroll position through re-builds -	// since we do re-build any time anything dirties -	S32 current_scroll_pos = scroll->getScrollPos(); -	 +	LLUUID selected_item = list->getCurrentID(); +	LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL;  	list->operateOnAll(LLCtrlListInterface::OP_DELETE); -	LLGestureManager::item_map_t::iterator it; -	for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) +	LLGestureManager::item_map_t::const_iterator it; +	const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures(); +	for (it = active_gestures.begin(); it != active_gestures.end(); ++it)  	{ -		const LLUUID& item_id = (*it).first; -		LLMultiGesture* gesture = (*it).second; +		addGesture(it->first,it->second, list); +	} +	if (gInventory.isCategoryComplete(mGestureFolderID)) +	{ +		LLIsType is_gesture(LLAssetType::AT_GESTURE); +		LLInventoryModel::cat_array_t categories; +		LLInventoryModel::item_array_t items; +		gInventory.collectDescendentsIf(mGestureFolderID, categories, items, +				LLInventoryModel::EXCLUDE_TRASH, is_gesture); -		// Note: Can have NULL item if inventory hasn't arrived yet. -		std::string item_name = getString("loading"); -		LLInventoryItem* item = gInventory.getItem(item_id); -		if (item) +		for (LLInventoryModel::item_array_t::iterator it = items.begin(); it!= items.end(); ++it)  		{ -			item_name = item->getName(); +			LLInventoryItem* item = it->get(); +			if (active_gestures.find(item->getUUID()) == active_gestures.end()) +			{ +				// if gesture wasn't loaded yet, we can display only name +				addGesture(item->getUUID(), NULL, list); +			}  		} +	} +	// attempt to preserve scroll position through re-builds +	// since we do re-build any time anything dirties +	if(list->selectByValue(LLSD(selected_item))) +	{ +		scroll->scrollToShowSelected(); +	} +} -		std::string font_style = "NORMAL"; -		// If gesture is playing, bold it +void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list ) +{ +	// Note: Can have NULL item if inventory hasn't arrived yet. +	static std::string item_name = getString("loading"); +	LLInventoryItem* item = gInventory.getItem(item_id); +	if (item) +	{ +		item_name = item->getName(); +	} + +	static std::string font_style = "NORMAL"; +	// If gesture is playing, bold it -		LLSD element; -		element["id"] = item_id; +	LLSD element; +	element["id"] = item_id; -		if (gesture) +	if (gesture) +	{ +		if (gesture->mPlaying)  		{ -			if (gesture->mPlaying) -			{ -				font_style = "BOLD"; -			} +			font_style = "BOLD"; +		} -			element["columns"][0]["column"] = "trigger"; -			element["columns"][0]["value"] = gesture->mTrigger; -			element["columns"][0]["font"]["name"] = "SANSSERIF"; -			element["columns"][0]["font"]["style"] = font_style; +		element["columns"][0]["column"] = "trigger"; +		element["columns"][0]["value"] = gesture->mTrigger; +		element["columns"][0]["font"]["name"] = "SANSSERIF"; +		element["columns"][0]["font"]["style"] = font_style; -			std::string key_string = LLKeyboard::stringFromKey(gesture->mKey); -			std::string buffer; +		std::string key_string = LLKeyboard::stringFromKey(gesture->mKey); +		std::string buffer; -			if (gesture->mKey == KEY_NONE) -			{ -				buffer = "---"; -				key_string = "~~~";		// alphabetize to end -			} -			else -			{ -				buffer = LLKeyboard::stringFromAccelerator( gesture->mMask, gesture->mKey ); -			} +		if (gesture->mKey == KEY_NONE) +		{ +			buffer = "---"; +			key_string = "~~~"; // alphabetize to end +		} +		else +		{ +			buffer = LLKeyboard::stringFromAccelerator(gesture->mMask, +					gesture->mKey); +		} -			element["columns"][1]["column"] = "shortcut"; -			element["columns"][1]["value"] = buffer; -			element["columns"][1]["font"]["name"] = "SANSSERIF"; -			element["columns"][1]["font"]["style"] = font_style; +		element["columns"][1]["column"] = "shortcut"; +		element["columns"][1]["value"] = buffer; +		element["columns"][1]["font"]["name"] = "SANSSERIF"; +		element["columns"][1]["font"]["style"] = font_style; -			// hidden column for sorting -			element["columns"][2]["column"] = "key"; -			element["columns"][2]["value"] = key_string; -			element["columns"][2]["font"]["name"] = "SANSSERIF"; -			element["columns"][2]["font"]["style"] = font_style; +		// hidden column for sorting +		element["columns"][2]["column"] = "key"; +		element["columns"][2]["value"] = key_string; +		element["columns"][2]["font"]["name"] = "SANSSERIF"; +		element["columns"][2]["font"]["style"] = font_style; -			// Only add "playing" if we've got the name, less confusing. JC -			if (item && gesture->mPlaying) -			{ -				item_name += " " + getString("playing"); -			} -			element["columns"][3]["column"] = "name"; -			element["columns"][3]["value"] = item_name; -			element["columns"][3]["font"]["name"] = "SANSSERIF"; -			element["columns"][3]["font"]["style"] = font_style; -		} -		else +		// Only add "playing" if we've got the name, less confusing. JC +		if (item && gesture->mPlaying)  		{ -			element["columns"][0]["column"] = "trigger"; -			element["columns"][0]["value"] = ""; -			element["columns"][0]["font"]["name"] = "SANSSERIF"; -			element["columns"][0]["font"]["style"] = font_style; -			element["columns"][0]["column"] = "trigger"; -			element["columns"][0]["value"] = "---"; -			element["columns"][0]["font"]["name"] = "SANSSERIF"; -			element["columns"][0]["font"]["style"] = font_style; -			element["columns"][2]["column"] = "key"; -			element["columns"][2]["value"] = "~~~"; -			element["columns"][2]["font"]["name"] = "SANSSERIF"; -			element["columns"][2]["font"]["style"] = font_style; -			element["columns"][3]["column"] = "name"; -			element["columns"][3]["value"] = item_name; -			element["columns"][3]["font"]["name"] = "SANSSERIF"; -			element["columns"][3]["font"]["style"] = font_style; +			item_name += " " + getString("playing");  		} -		list->addElement(element, ADD_BOTTOM); +		element["columns"][3]["column"] = "name"; +		element["columns"][3]["value"] = item_name; +		element["columns"][3]["font"]["name"] = "SANSSERIF"; +		element["columns"][3]["font"]["style"] = font_style;  	} -	 -	scroll->setScrollPos(current_scroll_pos); +	else +	{ +		element["columns"][0]["column"] = "trigger"; +		element["columns"][0]["value"] = ""; +		element["columns"][0]["font"]["name"] = "SANSSERIF"; +		element["columns"][0]["font"]["style"] = font_style; +		element["columns"][0]["column"] = "trigger"; +		element["columns"][0]["value"] = "---"; +		element["columns"][0]["font"]["name"] = "SANSSERIF"; +		element["columns"][0]["font"]["style"] = font_style; +		element["columns"][2]["column"] = "key"; +		element["columns"][2]["value"] = "~~~"; +		element["columns"][2]["font"]["name"] = "SANSSERIF"; +		element["columns"][2]["font"]["style"] = font_style; +		element["columns"][3]["column"] = "name"; +		element["columns"][3]["value"] = item_name; +		element["columns"][3]["font"]["name"] = "SANSSERIF"; +		element["columns"][3]["font"]["style"] = font_style; +	} +	list->addElement(element, ADD_BOTTOM);  }  void LLFloaterGesture::onClickInventory() @@ -284,14 +361,21 @@ void LLFloaterGesture::onClickPlay()  	LLCtrlListInterface *list = childGetListInterface("gesture_list");  	if (!list) return;  	const LLUUID& item_id = list->getCurrentID(); +	if(item_id.isNull()) return; -	if (LLGestureManager::instance().isGesturePlaying(item_id)) +	LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL; +	if(!LLGestureManager::instance().isGestureActive(item_id))  	{ -		LLGestureManager::instance().stopGesture(item_id); +		// we need to inform server about gesture activating to be consistent with LLPreviewGesture. +		BOOL inform_server = TRUE; +		BOOL deactivate_similar = FALSE; +		LLGestureManager::instance().activateGestureWithAsset(item_id, gInventory.getItem(item_id)->getAssetUUID(), inform_server, deactivate_similar); +		LL_DEBUGS("Gesture")<< "Activating gesture with inventory ID: " << item_id <<LL_ENDL; +		LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));  	}  	else  	{ -		LLGestureManager::instance().playGesture(item_id); +		playGesture(item_id);  	}  } @@ -345,3 +429,14 @@ void LLFloaterGesture::onCommitList()  		childSetVisible("stop_btn", false);  	}  } +void LLFloaterGesture::playGesture(LLUUID item_id) +{ +	if (LLGestureManager::instance().isGesturePlaying(item_id)) +	{ +		LLGestureManager::instance().stopGesture(item_id); +	} +	else +	{ +		LLGestureManager::instance().playGesture(item_id); +	} +} diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index 9c1ab27cb0..9d047bf1cf 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -38,7 +38,7 @@  #define LL_LLFLOATERGESTURE_H  #include "llfloater.h" - +#include "llinventorymodel.h"  #include "lldarray.h"  class LLScrollContainer; @@ -51,31 +51,35 @@ class LLGestureOptions;  class LLScrollListCtrl;  class LLFloaterGestureObserver;  class LLFloaterGestureInventoryObserver; +class LLMultiGesture;  class LLFloaterGesture -:	public LLFloater +:	public LLFloater, LLInventoryFetchDescendentsObserver  { +	LOG_CLASS(LLFloaterGesture);  public:  	LLFloaterGesture(const LLSD& key);  	virtual ~LLFloaterGesture();  	virtual BOOL postBuild(); - +	virtual void done ();  	void refreshAll();  protected:  	// Reads from the gesture manager's list of active gestures  	// and puts them in this list.  	void buildGestureList(); - +	void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);  	void onClickInventory();  	void onClickEdit();  	void onClickPlay();  	void onClickNew();  	void onCommitList(); +	void playGesture(LLUUID item_id);  protected:  	LLUUID mSelectedID; +	LLUUID mGestureFolderID;  	LLFloaterGestureObserver* mObserver;  }; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 59274c8638..8e774dc199 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -37,7 +37,6 @@  // system  #include <functional>  #include <algorithm> -#include <boost/tokenizer.hpp>  // library  #include "lldatapacker.h" @@ -206,6 +205,9 @@ struct LLLoadInfo  // If inform_server is true, will send a message upstream to update  // the user_gesture_active table. +/** + * It will load a gesture from remote storage + */  void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id,  												const LLUUID& asset_id,  												BOOL inform_server, @@ -921,8 +923,8 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,  	delete info;  	info = NULL; - -	LLGestureManager::instance().mLoadingCount--; +	LLGestureManager& self = LLGestureManager::instance(); +	self.mLoadingCount--;  	if (0 == status)  	{ @@ -944,15 +946,15 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,  		{  			if (deactivate_similar)  			{ -				LLGestureManager::instance().deactivateSimilarGestures(gesture, item_id); +				self.deactivateSimilarGestures(gesture, item_id);  				// Display deactivation message if this was the last of the bunch. -				if (LLGestureManager::instance().mLoadingCount == 0 -					&& LLGestureManager::instance().mDeactivateSimilarNames.length() > 0) +				if (self.mLoadingCount == 0 +					&& self.mDeactivateSimilarNames.length() > 0)  				{  					// we're done with this set of deactivations  					LLSD args; -					args["NAMES"] = LLGestureManager::instance().mDeactivateSimilarNames; +					args["NAMES"] = self.mDeactivateSimilarNames;  					LLNotifications::instance().add("DeactivatedGesturesTrigger", args);  				}  			} @@ -965,9 +967,9 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,  			else  			{  				// Watch this item and set gesture name when item exists in inventory -				LLGestureManager::instance().watchItem(item_id); +				self.watchItem(item_id);  			} -			LLGestureManager::instance().mActive[item_id] = gesture; +			self.mActive[item_id] = gesture;  			// Everything has been successful.  Add to the active list.  			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -989,14 +991,21 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,  				gAgent.sendReliableMessage();  			} +			callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id); +			 +			if(i_cb != self.mCallbackMap.end()) +			{ +				i_cb->second(gesture); +				self.mCallbackMap.erase(i_cb); +			} -			LLGestureManager::instance().notifyObservers(); +			self.notifyObservers();  		}  		else  		{  			llwarns << "Unable to load gesture" << llendl; -			LLGestureManager::instance().mActive.erase(item_id); +			self.mActive.erase(item_id);  			delete gesture;  			gesture = NULL; diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 947773d66d..7c3b742780 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -57,6 +57,12 @@ public:  class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventoryCompletionObserver  {  public: + +	typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t; +	// Maps inventory item_id to gesture +	typedef std::map<LLUUID, LLMultiGesture*> item_map_t; +	typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t; +  	LLGestureManager();  	~LLGestureManager(); @@ -97,6 +103,7 @@ public:  	BOOL isGesturePlaying(const LLUUID& item_id); +	const item_map_t& getActiveGestures() const { return mActive; }  	// Force a gesture to be played, for example, if it is being  	// previewed.  	void playGesture(LLMultiGesture* gesture); @@ -106,7 +113,15 @@ public:  	// Also remove from playing list  	void stopGesture(LLMultiGesture* gesture);  	void stopGesture(const LLUUID& item_id); - +	/** +	 * Add cb into callbackMap. +	 * Note: +	 * Manager will call cb after gesture will be loaded and will remove cb automatically.  +	 */ +	void setGestureLoadedCallback(LLUUID inv_item_id, gesture_loaded_callback_t cb) +	{ +		mCallbackMap[inv_item_id] = cb; +	}  	// Trigger the first gesture that matches this key.  	// Returns TRUE if it finds a gesture bound to that key.  	BOOL triggerGesture(KEY key, MASK mask); @@ -144,13 +159,7 @@ protected:  						   LLAssetType::EType type,  						   void* user_data, S32 status, LLExtStat ext_status); -public: -	BOOL mValid; -	std::vector<LLMultiGesture*> mPlaying; - -	// Maps inventory item_id to gesture -	typedef std::map<LLUUID, LLMultiGesture*> item_map_t; - +private:  	// Active gestures.  	// NOTE: The gesture pointer CAN BE NULL.  This means that  	// there is a gesture with that item_id, but the asset data @@ -159,8 +168,11 @@ public:  	S32 mLoadingCount;  	std::string mDeactivateSimilarNames; - +	  	std::vector<LLGestureManagerObserver*> mObservers; +	callback_map_t mCallbackMap; +	std::vector<LLMultiGesture*> mPlaying;	 +	BOOL mValid;  };  #endif diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 3993431311..236eaf8f0f 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -98,9 +98,10 @@ void LLGestureComboBox::refreshGestures()  	clearRows();  	mGestures.clear(); -	LLGestureManager::item_map_t::iterator it; +	LLGestureManager::item_map_t::const_iterator it; +	const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();  	LLSD::Integer idx(0); -	for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) +	for (it = active_gestures.begin(); it != active_gestures.end(); ++it)  	{  		LLMultiGesture* gesture = (*it).second;  		if (gesture) diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index b23482655c..a3ac878202 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -84,21 +84,21 @@                   top_delta="0"                   width="18" />                  <button -                 follows="bottom|left" +                 follows="bottom|right"                   font="SansSerifBigBold"                   height="18"                   image_selected="TrashItem_Press"                   image_unselected="TrashItem_Off"                   image_disabled="TrashItem_Disabled"                   layout="topleft" -                 left_pad="230"                   name="del_btn" +                 right="-5"                   tool_tip="Delete this gesture"                   top_delta="0"                   width="18" />              </panel>      <button -     follows="bottom|right" +     follows="left|bottom"       height="23"       label="Edit"       layout="topleft" @@ -107,7 +107,7 @@       top_pad="5"       width="83" />      <button -     follows="bottom|right" +     follows="left|bottom"       height="23"       label="Play"       layout="topleft" @@ -116,7 +116,7 @@       top_delta="0"       width="83" />      <button -     follows="bottom|right" +     follows="left|bottom"       height="23"       label="Stop"       layout="topleft" | 
