llpanellookinfo.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:14k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file llpanellookinfo.cpp
  3.  * @brief Displays place information in Side Tray.
  4.  *
  5.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2009-2010, 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 "llpanellookinfo.h"
  34. // *TODO: reorder includes to match the coding standard
  35. #include "llagent.h"
  36. #include "llagentwearables.h"
  37. #include "llappearancemgr.h"
  38. #include "llinventory.h"
  39. #include "llviewercontrol.h"
  40. #include "llui.h"
  41. #include "llfloater.h"
  42. #include "llfloaterreg.h"
  43. #include "llinventoryfunctions.h"
  44. #include "llinventorypanel.h"
  45. #include "llviewerwindow.h"
  46. #include "llviewerinventory.h"
  47. #include "llbutton.h"
  48. #include "llcombobox.h"
  49. #include "llfiltereditor.h"
  50. #include "llfloaterinventory.h"
  51. #include "llinventorybridge.h"
  52. #include "llinventorymodel.h"
  53. #include "lluiconstants.h"
  54. #include "llscrolllistctrl.h"
  55. #include "lltextbox.h"
  56. #include "lluictrlfactory.h"
  57. #include "llsdutil.h"
  58. #include "llsidepanelappearance.h"
  59. #include "llwearablelist.h"
  60. static LLRegisterPanelClassWrapper<LLPanelLookInfo> t_look("panel_look_info");
  61. const U64 WEARABLE_MASK = (1LL << LLInventoryType::IT_WEARABLE);
  62. const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LLInventoryType::IT_OBJECT);
  63. const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
  64. class LLInventoryLookObserver : public LLInventoryObserver
  65. {
  66. public:
  67. LLInventoryLookObserver(LLPanelLookInfo *panel) : mPanel(panel) {}
  68. virtual ~LLInventoryLookObserver() 
  69. {
  70. if (gInventory.containsObserver(this))
  71. {
  72. gInventory.removeObserver(this);
  73. }
  74. }
  75. virtual void changed(U32 mask)
  76. {
  77. if (mask & (LLInventoryObserver::ADD | LLInventoryObserver::REMOVE))
  78. {
  79. mPanel->updateLookInfo();
  80. }
  81. }
  82. protected:
  83. LLPanelLookInfo *mPanel;
  84. };
  85. class LLLookFetchObserver : public LLInventoryFetchDescendentsObserver
  86. {
  87. public:
  88. LLLookFetchObserver(LLPanelLookInfo *panel) :
  89. mPanel(panel)
  90. {}
  91. LLLookFetchObserver() {}
  92. virtual void done()
  93. {
  94. mPanel->lookFetched();
  95. if(gInventory.containsObserver(this))
  96. {
  97. gInventory.removeObserver(this);
  98. }
  99. }
  100. private:
  101. LLPanelLookInfo *mPanel;
  102. };
  103. LLPanelLookInfo::LLPanelLookInfo()
  104. : LLPanel(), mLookID(), mFetchLook(NULL), mSearchFilter(NULL),
  105. mLookContents(NULL), mInventoryItemsPanel(NULL), mAddToLookBtn(NULL),
  106. mRemoveFromLookBtn(NULL), mLookObserver(NULL), mNumItemsInLook(0)
  107. {
  108. mSavedFolderState = new LLSaveFolderState();
  109. mSavedFolderState->setApply(FALSE);
  110. mFetchLook = new LLLookFetchObserver(this);
  111. mLookObserver = new LLInventoryLookObserver(this);
  112. gInventory.addObserver(mLookObserver);
  113. mLookItemTypes.reserve(NUM_LOOK_ITEM_TYPES);
  114. for (U32 i = 0; i < NUM_LOOK_ITEM_TYPES; i++)
  115. {
  116. mLookItemTypes.push_back(LLLookItemType());
  117. }
  118. // TODO: make these strings translatable
  119. mLookItemTypes[LIT_ALL] = LLLookItemType("All Items", ALL_ITEMS_MASK);
  120. mLookItemTypes[LIT_WEARABLE] = LLLookItemType("Shape & Clothing", WEARABLE_MASK);
  121. mLookItemTypes[LIT_ATTACHMENT] = LLLookItemType("Attachments", ATTACHMENT_MASK);
  122. }
  123. LLPanelLookInfo::~LLPanelLookInfo()
  124. {
  125. delete mSavedFolderState;
  126. if (gInventory.containsObserver(mFetchLook))
  127. {
  128. gInventory.removeObserver(mFetchLook);
  129. }
  130. delete mFetchLook;
  131. if (gInventory.containsObserver(mLookObserver))
  132. {
  133. gInventory.removeObserver(mLookObserver);
  134. }
  135. delete mLookObserver;
  136. }
  137. BOOL LLPanelLookInfo::postBuild()
  138. {
  139. // gInventory.isInventoryUsable() no longer needs to be tested per Richard's fix for race conditions between inventory and panels
  140. mLookName = getChild<LLTextBox>("curr_look_name"); 
  141. /*
  142. mLookContents->setDoubleClickCallback(onDoubleClickSpeaker, this);
  143. mLookContents->setCommitOnSelectionChange(TRUE);
  144. mLookContents->setCommitCallback(boost::bind(&LLPanelActiveSpeakers::handleSpeakerSelect, this, _2));
  145. mLookContents->setSortChangedCallback(boost::bind(&LLPanelActiveSpeakers::onSortChanged, this));
  146. mLookContents->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
  147. */
  148. mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
  149. mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);
  150. mInventoryItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
  151. // mInventoryItemsPanel->setSelectCallback(boost::bind(&LLPanelLookInfo::onInventorySelectionChange, this, _1, _2));
  152. // mInventoryItemsPanel->getRootFolder()->setReshapeCallback(boost::bind(&LLPanelLookInfo::onInventorySelectionChange, this, _1, _2));
  153. LLComboBox* type_filter = getChild<LLComboBox>("inventory_filter");
  154. type_filter->setCommitCallback(boost::bind(&LLPanelLookInfo::onTypeFilterChanged, this, _1));
  155. type_filter->removeall();
  156. for (U32 i = 0; i < mLookItemTypes.size(); ++i)
  157. {
  158. type_filter->add(mLookItemTypes[i].displayName);
  159. }
  160. type_filter->setCurrentByIndex(LIT_ALL);
  161. mSearchFilter = getChild<LLFilterEditor>("look_item_filter");
  162. mSearchFilter->setCommitCallback(boost::bind(&LLPanelLookInfo::onSearchEdit, this, _2));
  163. /* Removing add to look inline button (not part of mvp for viewer 2)
  164. LLButton::Params add_params;
  165. add_params.name("add_to_look");
  166. add_params.click_callback.function(boost::bind(&LLPanelLookInfo::onAddToLookClicked, this));
  167. add_params.label("+");
  168. mAddToLookBtn = LLUICtrlFactory::create<LLButton>(add_params);
  169. mAddToLookBtn->setEnabled(FALSE);
  170. mAddToLookBtn->setVisible(FALSE); */
  171. childSetAction("add_item_btn", boost::bind(&LLPanelLookInfo::onAddToLookClicked, this), this);
  172. mUpBtn = getChild<LLButton>("up_btn");
  173. mUpBtn->setEnabled(TRUE);
  174. mUpBtn->setClickedCallback(boost::bind(&LLPanelLookInfo::onUpClicked, this));
  175. mLookContents = getChild<LLScrollListCtrl>("look_items_list");
  176. mLookContents->sortByColumn("look_item_sort", TRUE);
  177. mLookContents->setCommitCallback(boost::bind(&LLPanelLookInfo::onLookItemSelectionChange, this));
  178. /*
  179. LLButton::Params remove_params;
  180. remove_params.name("remove_from_look");
  181. remove_params.click_callback.function(boost::bind(&LLPanelLookInfo::onRemoveFromLookClicked, this));
  182. remove_params.label("-"); */
  183. //mRemoveFromLookBtn = LLUICtrlFactory::create<LLButton>(remove_params);
  184. mRemoveFromLookBtn = getChild<LLButton>("remove_from_look_btn");
  185. mRemoveFromLookBtn->setEnabled(FALSE);
  186. mRemoveFromLookBtn->setVisible(FALSE);
  187. //childSetAction("remove_from_look_btn", boost::bind(&LLPanelLookInfo::onRemoveFromLookClicked, this), this);
  188. mRemoveFromLookBtn->setCommitCallback(boost::bind(&LLPanelLookInfo::onRemoveFromLookClicked, this));
  189. //getChild<LLPanel>("look_info_group_bar")->addChild(mRemoveFromLookBtn); remove_item_btn
  190. childSetAction("remove_item_btn", boost::bind(&LLPanelLookInfo::onRemoveFromLookClicked, this), this);
  191. return TRUE;
  192. }
  193. void LLPanelLookInfo::onTypeFilterChanged(LLUICtrl* ctrl)
  194. {
  195. LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl);
  196. llassert(type_filter);
  197. if (type_filter)
  198. {
  199. U32 curr_filter_type = type_filter->getCurrentIndex();
  200. mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask);
  201. }
  202. mSavedFolderState->setApply(TRUE);
  203. mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  204. LLOpenFoldersWithSelection opener;
  205. mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(opener);
  206. mInventoryItemsPanel->getRootFolder()->scrollToShowSelection();
  207. gInventory.startBackgroundFetch();
  208. }
  209. void LLPanelLookInfo::onSearchEdit(const std::string& string)
  210. {
  211. if (mSearchString != string)
  212. {
  213. mSearchString = string;
  214. // Searches are case-insensitive
  215. LLStringUtil::toUpper(mSearchString);
  216. LLStringUtil::trimHead(mSearchString);
  217. }
  218. if (mSearchString == "")
  219. {
  220. mInventoryItemsPanel->setFilterSubString(LLStringUtil::null);
  221. // re-open folders that were initially open
  222. mSavedFolderState->setApply(TRUE);
  223. mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  224. LLOpenFoldersWithSelection opener;
  225. mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(opener);
  226. mInventoryItemsPanel->getRootFolder()->scrollToShowSelection();
  227. }
  228. gInventory.startBackgroundFetch();
  229. if (mInventoryItemsPanel->getFilterSubString().empty() && mSearchString.empty())
  230. {
  231. // current filter and new filter empty, do nothing
  232. return;
  233. }
  234. // save current folder open state if no filter currently applied
  235. if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty())
  236. {
  237. mSavedFolderState->setApply(FALSE);
  238. mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
  239. }
  240. // set new filter string
  241. mInventoryItemsPanel->setFilterSubString(mSearchString);
  242. }
  243. void LLPanelLookInfo::onAddToLookClicked(void)
  244. {
  245. LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
  246. LLFolderViewEventListener* listenerp  = curr_item->getListener();
  247. link_inventory_item(gAgent.getID(), listenerp->getUUID(), mLookID, listenerp->getName(),
  248. LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
  249. updateLookInfo();
  250. }
  251. void LLPanelLookInfo::onRemoveFromLookClicked(void)
  252. {
  253. LLUUID id_to_remove = mLookContents->getSelectionInterface()->getCurrentID();
  254. LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
  255. if (item_to_remove)
  256. {
  257. // returns null if not a wearable (attachment, etc).
  258. const LLWearable* wearable_to_remove = gAgentWearables.getWearableFromAssetID(item_to_remove->getAssetUUID());
  259. if (!wearable_to_remove || gAgentWearables.canWearableBeRemoved( wearable_to_remove ))
  260. {  
  261. gInventory.purgeObject( id_to_remove );
  262. updateLookInfo();
  263. mRemoveFromLookBtn->setEnabled(FALSE);
  264. if (mRemoveFromLookBtn->getVisible())
  265. {
  266. mRemoveFromLookBtn->setVisible(FALSE);
  267. }
  268. }
  269. }
  270. }
  271. void LLPanelLookInfo::onUpClicked(void)
  272. {
  273. LLUUID inv_id = mLookContents->getSelectionInterface()->getCurrentID();
  274. if (inv_id.isNull())
  275. {
  276. //nothing selected, do nothing
  277. return;
  278. }
  279. LLViewerInventoryItem *link_item = gInventory.getItem(inv_id);
  280. if (!link_item)
  281. {
  282. llwarns << "could not find inventory item based on currently worn link." << llendl;
  283. return;
  284. }
  285. LLUUID asset_id = link_item->getAssetUUID();
  286. if (asset_id.isNull())
  287. {
  288. llwarns << "inventory link has null Asset ID. could not get object reference" << llendl;
  289. }
  290. static const std::string empty = "";
  291. LLWearableList::instance().getAsset(asset_id,
  292. empty, // don't care about wearable name
  293. link_item->getActualType(),
  294. LLSidepanelAppearance::editWearable,
  295. (void*)getParentUICtrl());
  296. }
  297. void LLPanelLookInfo::onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
  298. {
  299. LLFolderViewItem* current_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
  300. if (!current_item)
  301. {
  302. return;
  303. }
  304. /* Removing add to look inline button (not part of mvp for viewer 2)
  305. LLRect btn_rect(current_item->getLocalRect().mRight - 50,
  306. current_item->getLocalRect().mTop,
  307. current_item->getLocalRect().mRight - 30,
  308. current_item->getLocalRect().mBottom);
  309. mAddToLookBtn->setRect(btn_rect);
  310. mAddToLookBtn->setEnabled(TRUE);
  311. if (!mAddToLookBtn->getVisible())
  312. {
  313. mAddToLookBtn->setVisible(TRUE);
  314. }
  315. current_item->addChild(mAddToLookBtn); */
  316. }
  317. void LLPanelLookInfo::onLookItemSelectionChange(void)
  318. {
  319. S32 left_offset = -4;
  320. S32 top_offset = -10;
  321. LLRect rect = mLookContents->getLastSelectedItem()->getRect();
  322. LLRect btn_rect(
  323. left_offset + rect.mRight - 50,
  324. top_offset  + rect.mTop,
  325. left_offset + rect.mRight - 30,
  326. top_offset  + rect.mBottom);
  327. mRemoveFromLookBtn->setRect(btn_rect);
  328. mRemoveFromLookBtn->setEnabled(TRUE);
  329. if (!mRemoveFromLookBtn->getVisible())
  330. {
  331. mRemoveFromLookBtn->setVisible(TRUE);
  332. }
  333. //mLookContents->addChild(mRemoveFromLookBtn);
  334. }
  335. void LLPanelLookInfo::changed(U32 mask)
  336. {
  337. }
  338. void LLPanelLookInfo::lookFetched(void)
  339. {
  340. LLInventoryModel::cat_array_t cat_array;
  341. LLInventoryModel::item_array_t item_array;
  342. // collectDescendentsIf takes non-const reference:
  343. LLFindCOFValidItems is_cof_valid;
  344. gInventory.collectDescendentsIf(mLookID,
  345. cat_array,
  346. item_array,
  347. LLInventoryModel::EXCLUDE_TRASH,
  348. is_cof_valid);
  349. for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
  350.  iter != item_array.end();
  351.  iter++)
  352. {
  353. const LLViewerInventoryItem *item = (*iter);
  354. LLSD row;
  355. row["id"] = item->getUUID();
  356. LLSD& columns = row["columns"];
  357. columns[0]["column"] = "look_item";
  358. columns[0]["type"] = "text";
  359. columns[0]["value"] = item->getName();
  360. columns[1]["column"] = "look_item_sort";
  361. columns[1]["type"] = "text"; // TODO: multi-wearable sort "type" should go here.
  362. columns[1]["value"] = "BAR"; // TODO: Multi-wearable sort index should go here
  363. mLookContents->addElement(row);
  364. }
  365. if (mLookContents->getItemCount() != mNumItemsInLook)
  366. {
  367. mNumItemsInLook = mLookContents->getItemCount();
  368. LLAppearanceManager::instance().updateCOF(mLookID);
  369. }
  370. }
  371. void LLPanelLookInfo::updateLookInfo()
  372. {
  373. if (getVisible())
  374. {
  375. mLookContents->clearRows();
  376. LLInventoryFetchDescendentsObserver::folder_ref_t folders;
  377. folders.push_back(mLookID);
  378. mFetchLook->fetchDescendents(folders);
  379. if (mFetchLook->isEverythingComplete())
  380. {
  381. mFetchLook->done();
  382. }
  383. else
  384. {
  385. gInventory.addObserver(mFetchLook);
  386. }
  387. }
  388. }
  389. void LLPanelLookInfo::displayLookInfo(const LLInventoryCategory* pLook)
  390. {
  391. if (!pLook)
  392. {
  393. return;
  394. }
  395. if (!getVisible())
  396. {
  397. setVisible(TRUE);
  398. }
  399. if (mLookID != pLook->getUUID())
  400. {
  401. mLookID = pLook->getUUID();
  402. mLookName->setText("Look: " + pLook->getName());
  403. updateLookInfo();
  404. }
  405. }
  406. void LLPanelLookInfo::reset()
  407. {
  408. mLookID.setNull();
  409. }