diff options
author | Denis Serdjuk <dserduk@productengine.com> | 2009-11-13 15:51:22 +0200 |
---|---|---|
committer | Denis Serdjuk <dserduk@productengine.com> | 2009-11-13 15:51:22 +0200 |
commit | 0ec8d0aacf47913ab8fd30d8424fa7146f135d15 (patch) | |
tree | 99de401149285fe306e3d5d65a4133b6317978bf | |
parent | 61556f1acf36a1a8fc459fd17a8c0a4a74cc6eeb (diff) |
implemented major task EXT-1897 Ctl + G Gestures floater should show ALL gestures from inventory, not just Active Gestures
refactoring of gesture's manager
--HG--
branch : product-engine
-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" |