llfloatergesture.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /**
  2. * @file llfloatergesture.cpp
  3. * @brief Read-only list of gestures from your inventory.
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llfloatergesture.h"
  34. #include "llkeyboard.h"
  35. #include "llmultigesture.h"
  36. #include "llscrolllistctrl.h"
  37. #include "lluictrlfactory.h"
  38. #include "llfloaterinventory.h"
  39. #include "llfloaterperms.h"
  40. #include "llgesturemgr.h"
  41. #include "llpreviewgesture.h"
  42. //-----------------------------------------------------------------------------
  43. // Gesture manager observer
  44. //-----------------------------------------------------------------------------
  45. class LLFloaterGestureObserver final : public LLGestureManagerObserver
  46. {
  47. public:
  48. LLFloaterGestureObserver() {}
  49. ~LLFloaterGestureObserver() override {}
  50. LL_INLINE void changed() override
  51. {
  52. LLFloaterGesture::refreshAll();
  53. }
  54. };
  55. //-----------------------------------------------------------------------------
  56. // Gesture inventory callback
  57. //-----------------------------------------------------------------------------
  58. class GestureShowCallback : public LLInventoryCallback
  59. {
  60. public:
  61. GestureShowCallback(std::string& title)
  62. {
  63. mTitle = title;
  64. }
  65. void fire(const LLUUID &inv_item)
  66. {
  67. LLPreviewGesture::show(mTitle, inv_item, LLUUID::null);
  68. }
  69. private:
  70. std::string mTitle;
  71. };
  72. //-----------------------------------------------------------------------------
  73. // LLFloaterGesture class proper
  74. //-----------------------------------------------------------------------------
  75. LLFloaterGesture::LLFloaterGesture(const LLSD&)
  76. {
  77. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");
  78. mObserver = new LLFloaterGestureObserver;
  79. gGestureManager.addObserver(mObserver);
  80. }
  81. //virtual
  82. LLFloaterGesture::~LLFloaterGesture()
  83. {
  84. if (mObserver)
  85. {
  86. gGestureManager.removeObserver(mObserver);
  87. delete mObserver;
  88. mObserver = NULL;
  89. }
  90. }
  91. //virtual
  92. bool LLFloaterGesture::postBuild()
  93. {
  94. mGesturesList = getChild<LLScrollListCtrl>("gesture_list");
  95. mGesturesList->setCommitCallback(onCommitList);
  96. mGesturesList->setDoubleClickCallback(onClickPlay);
  97. mGesturesList->setCallbackUserData(this);
  98. #if 0 // Not used
  99. childSetAction("inventory_btn", onClickInventory, this);
  100. #endif
  101. childSetAction("new_gesture_btn", onClickNew, this);
  102. childSetAction("edit_btn", onClickEdit, this);
  103. childSetAction("play_btn", onClickPlay, this);
  104. childSetVisible("play_btn", true);
  105. childSetAction("stop_btn", onClickPlay, this);
  106. childSetVisible("stop_btn", false);
  107. setDefaultBtn("play_btn");
  108. buildGestureList();
  109. mGesturesList->setFocus(true);
  110. // Sort on name, ascending
  111. mGesturesList->sortByColumn(std::string("name"), true);
  112. mGesturesList->selectFirstItem();
  113. // Update button labels
  114. onCommitList(NULL, this);
  115. return true;
  116. }
  117. void LLFloaterGesture::buildGestureList()
  118. {
  119. // Remember any selected gesture and the scroll position in the list
  120. S32 scrollpos = mGesturesList->getScrollPos();
  121. LLScrollListItem* item = mGesturesList->getFirstSelected();
  122. LLUUID selected_id;
  123. if (item)
  124. {
  125. selected_id = mGesturesList->getValue().asUUID();
  126. }
  127. mGesturesList->deleteAllItems();
  128. bool found_selected_id = false;
  129. std::string font_style, key_string, buffer;
  130. for (LLGestureManager::item_map_t::iterator
  131. it = gGestureManager.mActive.begin(),
  132. end = gGestureManager.mActive.end();
  133. it != end; ++it)
  134. {
  135. const LLUUID& item_id = it->first;
  136. LLMultiGesture* gesture = it->second;
  137. if (item_id == selected_id)
  138. {
  139. found_selected_id = true;
  140. }
  141. // Note: Can have NULL item if inventory has not arrived yet.
  142. std::string item_name = "Loading...";
  143. LLInventoryItem* item = gInventory.getItem(item_id);
  144. if (item)
  145. {
  146. item_name = item->getName();
  147. }
  148. font_style = "NORMAL";
  149. LLSD element;
  150. element["id"] = item_id;
  151. if (gesture)
  152. {
  153. // If gesture is playing, bold it
  154. font_style = gesture->mPlaying ? "BOLD" : "NORMAL";
  155. element["columns"][0]["column"] = "trigger";
  156. element["columns"][0]["value"] = gesture->mTrigger;
  157. element["columns"][0]["font"] = "SANSSERIF";
  158. element["columns"][0]["font-style"] = font_style;
  159. if (gesture->mKey == KEY_NONE)
  160. {
  161. buffer = "---";
  162. key_string = "~~~"; // Alphabetize to end
  163. }
  164. else
  165. {
  166. key_string = LLKeyboard::stringFromKey(gesture->mKey);
  167. if (gesture->mMask & MASK_ALT)
  168. {
  169. buffer.append("ALT ");
  170. }
  171. if (gesture->mMask & MASK_CONTROL)
  172. {
  173. buffer.append("CTRL ");
  174. }
  175. if (gesture->mMask & MASK_SHIFT)
  176. {
  177. buffer.append("SHIFT ");
  178. }
  179. buffer.append(key_string);
  180. }
  181. element["columns"][1]["column"] = "shortcut";
  182. element["columns"][1]["value"] = buffer;
  183. element["columns"][1]["font"] = "SANSSERIF";
  184. element["columns"][1]["font-style"] = font_style;
  185. // Hidden column for sorting
  186. element["columns"][2]["column"] = "key";
  187. element["columns"][2]["value"] = key_string;
  188. element["columns"][2]["font"] = "SANSSERIF";
  189. element["columns"][2]["font-style"] = font_style;
  190. // Only add "playing" if we've got the name, less confusing. JC
  191. if (item && gesture->mPlaying)
  192. {
  193. item_name += " (Playing)";
  194. }
  195. element["columns"][3]["column"] = "name";
  196. element["columns"][3]["value"] = item_name;
  197. element["columns"][3]["font"] = "SANSSERIF";
  198. element["columns"][3]["font-style"] = font_style;
  199. }
  200. else
  201. {
  202. element["columns"][0]["column"] = "trigger";
  203. element["columns"][0]["value"] = "";
  204. element["columns"][0]["font"] = "SANSSERIF";
  205. element["columns"][0]["font-style"] = "NORMAL";
  206. element["columns"][0]["column"] = "trigger";
  207. element["columns"][0]["value"] = "---";
  208. element["columns"][0]["font"] = "SANSSERIF";
  209. element["columns"][0]["font-style"] = "NORMAL";
  210. element["columns"][2]["column"] = "key";
  211. element["columns"][2]["value"] = "~~~";
  212. element["columns"][2]["font"] = "SANSSERIF";
  213. element["columns"][2]["font-style"] = "NORMAL";
  214. element["columns"][3]["column"] = "name";
  215. element["columns"][3]["value"] = item_name;
  216. element["columns"][3]["font"] = "SANSSERIF";
  217. element["columns"][3]["font-style"] = "NORMAL";
  218. }
  219. mGesturesList->addElement(element, ADD_BOTTOM);
  220. }
  221. // Restore any selected item and scroll position in list
  222. if (found_selected_id)
  223. {
  224. mGesturesList->selectByID(selected_id);
  225. }
  226. if (scrollpos)
  227. {
  228. mGesturesList->setScrollPos(scrollpos);
  229. }
  230. else if (found_selected_id)
  231. {
  232. mGesturesList->scrollToShowSelected();
  233. }
  234. }
  235. //static
  236. void LLFloaterGesture::refreshAll()
  237. {
  238. LLFloaterGesture* self = findInstance();
  239. if (self)
  240. {
  241. self->buildGestureList();
  242. // Update button labels
  243. onCommitList(NULL, self);
  244. }
  245. }
  246. //static
  247. void LLFloaterGesture::onCommitList(LLUICtrl* ctrl, void* data)
  248. {
  249. LLFloaterGesture* self = (LLFloaterGesture*)data;
  250. if (!self) return;
  251. const LLUUID& item_id = self->mGesturesList->getValue().asUUID();
  252. if (gGestureManager.isGesturePlaying(item_id))
  253. {
  254. self->childSetVisible("play_btn", false);
  255. self->childSetVisible("stop_btn", true);
  256. }
  257. else
  258. {
  259. self->childSetVisible("play_btn", true);
  260. self->childSetVisible("stop_btn", false);
  261. }
  262. }
  263. //static
  264. void LLFloaterGesture::onClickPlay(void* data)
  265. {
  266. LLFloaterGesture* self = (LLFloaterGesture*)data;
  267. if (!self) return;
  268. const LLUUID& item_id = self->mGesturesList->getCurrentID();
  269. if (gGestureManager.isGesturePlaying(item_id))
  270. {
  271. gGestureManager.stopGesture(item_id);
  272. }
  273. else
  274. {
  275. gGestureManager.playGesture(item_id);
  276. }
  277. }
  278. //static
  279. void LLFloaterGesture::onClickNew(void* data)
  280. {
  281. std::string title("Gesture: New Gesture");
  282. LLPointer<LLInventoryCallback> cb = new GestureShowCallback(title);
  283. create_inventory_item(LLUUID::null, LLTransactionID::tnull,
  284. "New Gesture", "", LLAssetType::AT_GESTURE,
  285. LLInventoryType::IT_GESTURE, NO_INV_SUBTYPE,
  286. PERM_MOVE | LLFloaterPerms::getNextOwnerPerms(), cb);
  287. }
  288. //static
  289. void LLFloaterGesture::onClickEdit(void* data)
  290. {
  291. LLFloaterGesture* self = (LLFloaterGesture*)data;
  292. if (!self) return;
  293. const LLUUID& item_id = self->mGesturesList->getCurrentID();
  294. LLInventoryItem* item = gInventory.getItem(item_id);
  295. if (!item) return;
  296. std::string title("Gesture: ");
  297. title.append(item->getName());
  298. LLPreviewGesture* previewp = LLPreviewGesture::show(title, item_id,
  299. LLUUID::null);
  300. if (gFloaterViewp && previewp && !previewp->getHost())
  301. {
  302. previewp->setRect(gFloaterViewp->findNeighboringPosition(self,
  303. previewp));
  304. }
  305. }
  306. #if 0 // Not used
  307. //static
  308. void LLFloaterGesture::onClickInventory(void* data)
  309. {
  310. LLFloaterGesture* self = (LLFloaterGesture*)data;
  311. LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory();
  312. if (self && inv)
  313. {
  314. const LLUUID& item_id = self->mGesturesList->getCurrentID();
  315. inv->getPanel()->setSelection(item_id, true);
  316. }
  317. }
  318. #endif