summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llchatbar.cpp5
-rw-r--r--indra/newview/llfloatergesture.cpp255
-rw-r--r--indra/newview/llfloatergesture.h12
-rw-r--r--indra/newview/llgesturemgr.cpp31
-rw-r--r--indra/newview/llgesturemgr.h30
-rw-r--r--indra/newview/llnearbychatbar.cpp5
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml10
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"