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

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file llsidepanelappearance.cpp
  3.  * @brief Side Bar "Appearance" panel
  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 "llsidepanelappearance.h"
  34. #include "llaccordionctrltab.h"
  35. #include "llagent.h"
  36. #include "llagentwearables.h"
  37. #include "llappearancemgr.h"
  38. #include "llinventorypanel.h"
  39. #include "llfiltereditor.h"
  40. #include "llfloaterreg.h"
  41. #include "llfloaterworldmap.h"
  42. #include "llfoldervieweventlistener.h"
  43. #include "llpaneleditwearable.h"
  44. #include "llpaneloutfitsinventory.h"
  45. #include "lltextbox.h"
  46. #include "lluictrlfactory.h"
  47. #include "llviewerregion.h"
  48. #include "llvoavatarself.h"
  49. #include "llwearable.h"
  50. static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
  51. class LLCurrentlyWornFetchObserver : public LLInventoryFetchObserver
  52. {
  53. public:
  54. LLCurrentlyWornFetchObserver(LLSidepanelAppearance *panel) :
  55. mPanel(panel)
  56. {}
  57. ~LLCurrentlyWornFetchObserver() {}
  58. virtual void done()
  59. {
  60. mPanel->inventoryFetched();
  61. gInventory.removeObserver(this);
  62. delete this;
  63. }
  64. private:
  65. LLSidepanelAppearance *mPanel;
  66. };
  67. class LLWatchForOutfitRenameObserver : public LLInventoryObserver
  68. {
  69. public:
  70. LLWatchForOutfitRenameObserver(LLSidepanelAppearance *panel) :
  71. mPanel(panel)
  72. {}
  73. virtual void changed(U32 mask);
  74. private:
  75. LLSidepanelAppearance *mPanel;
  76. };
  77. void LLWatchForOutfitRenameObserver::changed(U32 mask)
  78. {
  79. if (mask & LABEL)
  80. {
  81. mPanel->refreshCurrentOutfitName();
  82. }
  83. }
  84. LLSidepanelAppearance::LLSidepanelAppearance() :
  85. LLPanel(),
  86. mFilterSubString(LLStringUtil::null),
  87. mFilterEditor(NULL),
  88. mLookInfo(NULL),
  89. mCurrOutfitPanel(NULL)
  90. {
  91. }
  92. LLSidepanelAppearance::~LLSidepanelAppearance()
  93. {
  94. gInventory.removeObserver(mOutfitRenameWatcher);
  95. delete mOutfitRenameWatcher;
  96. }
  97. // virtual
  98. BOOL LLSidepanelAppearance::postBuild()
  99. {
  100. mOpenOutfitBtn = getChild<LLButton>("openoutfit_btn");
  101. mOpenOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onOpenOutfitButtonClicked, this));
  102. mEditAppearanceBtn = getChild<LLButton>("editappearance_btn");
  103. mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this));
  104. mEditBtn = getChild<LLButton>("edit_btn");
  105. mEditBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditButtonClicked, this));
  106. mNewOutfitBtn = getChild<LLButton>("newlook_btn");
  107. mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
  108. mNewOutfitBtn->setEnabled(false);
  109. mFilterEditor = getChild<LLFilterEditor>("Filter");
  110. if (mFilterEditor)
  111. {
  112. mFilterEditor->setCommitCallback(boost::bind(&LLSidepanelAppearance::onFilterEdit, this, _2));
  113. }
  114. mPanelOutfitsInventory = dynamic_cast<LLPanelOutfitsInventory *>(getChild<LLPanel>("panel_outfits_inventory"));
  115. mPanelOutfitsInventory->setParent(this);
  116. mLookInfo = dynamic_cast<LLPanelLookInfo*>(getChild<LLPanel>("panel_look_info"));
  117. if (mLookInfo)
  118. {
  119. LLButton* back_btn = mLookInfo->getChild<LLButton>("back_btn");
  120. if (back_btn)
  121. {
  122. back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onBackButtonClicked, this));
  123. }
  124. }
  125. mEditWearable = dynamic_cast<LLPanelEditWearable*>(getChild<LLPanel>("panel_edit_wearable"));
  126. if (mEditWearable)
  127. {
  128. LLButton* edit_wearable_back_btn = mEditWearable->getChild<LLButton>("back_btn");
  129. if (edit_wearable_back_btn)
  130. {
  131. edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this));
  132. }
  133. }
  134. mCurrentLookName = getChild<LLTextBox>("currentlook_name");
  135. mOutfitDirtyTag = getChild<LLTextBox>("currentlook_title");
  136. mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook");
  137. mOutfitRenameWatcher = new LLWatchForOutfitRenameObserver(this);
  138. gInventory.addObserver(mOutfitRenameWatcher);
  139. return TRUE;
  140. }
  141. // virtual
  142. void LLSidepanelAppearance::onOpen(const LLSD& key)
  143. {
  144. fetchInventory();
  145. refreshCurrentOutfitName();
  146. updateVerbs();
  147. if (mPanelOutfitsInventory)
  148. {
  149. mPanelOutfitsInventory->onOpen(key);
  150. }
  151. if(key.size() == 0)
  152. return;
  153. toggleLookInfoPanel(TRUE);
  154. updateVerbs();
  155. mLookInfoType = key["type"].asString();
  156. if (mLookInfoType == "look")
  157. {
  158. LLInventoryCategory *pLook = gInventory.getCategory(key["id"].asUUID());
  159. if (pLook)
  160. mLookInfo->displayLookInfo(pLook);
  161. }
  162. }
  163. void LLSidepanelAppearance::onFilterEdit(const std::string& search_string)
  164. {
  165. if (mFilterSubString != search_string)
  166. {
  167. mFilterSubString = search_string;
  168. // Searches are case-insensitive
  169. LLStringUtil::toUpper(mFilterSubString);
  170. LLStringUtil::trimHead(mFilterSubString);
  171. mPanelOutfitsInventory->onSearchEdit(mFilterSubString);
  172. }
  173. }
  174. void LLSidepanelAppearance::onOpenOutfitButtonClicked()
  175. {
  176. const LLViewerInventoryItem *outfit_link = LLAppearanceManager::getInstance()->getBaseOutfitLink();
  177. if (!outfit_link)
  178. return;
  179. if (!outfit_link->getIsLinkType())
  180. return;
  181. LLAccordionCtrlTab* tab_outfits = mPanelOutfitsInventory->findChild<LLAccordionCtrlTab>("tab_outfits");
  182. if (tab_outfits)
  183. {
  184. tab_outfits->changeOpenClose(FALSE);
  185. LLInventoryPanel *inventory_panel = tab_outfits->findChild<LLInventoryPanel>("outfitslist_tab");
  186. if (inventory_panel)
  187. {
  188. LLFolderView *folder = inventory_panel->getRootFolder();
  189. LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID());
  190. if (outfit_folder)
  191. {
  192. outfit_folder->setOpen(!outfit_folder->isOpen());
  193. folder->setSelectionFromRoot(outfit_folder,TRUE);
  194. folder->scrollToShowSelection();
  195. }
  196. }
  197. }
  198. }
  199. void LLSidepanelAppearance::onEditAppearanceButtonClicked()
  200. {
  201. if (gAgentWearables.areWearablesLoaded())
  202. {
  203. gAgent.changeCameraToCustomizeAvatar();
  204. }
  205. }
  206. void LLSidepanelAppearance::onEditButtonClicked()
  207. {
  208. toggleLookInfoPanel(FALSE);
  209. toggleWearableEditPanel(TRUE, NULL);
  210. /*if (mLookInfo->getVisible())
  211.   {
  212.   }
  213.   else
  214.   {
  215.   mPanelOutfitsInventory->onEdit();
  216.   }*/
  217. }
  218. void LLSidepanelAppearance::onNewOutfitButtonClicked()
  219. {
  220. if (!mLookInfo->getVisible())
  221. {
  222. mPanelOutfitsInventory->onSave();
  223. }
  224. }
  225. void LLSidepanelAppearance::onBackButtonClicked()
  226. {
  227. toggleLookInfoPanel(FALSE);
  228. }
  229. void LLSidepanelAppearance::onEditWearBackClicked()
  230. {
  231. mEditWearable->saveChanges();
  232. toggleWearableEditPanel(FALSE, NULL);
  233. toggleLookInfoPanel(TRUE);
  234. }
  235. void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible)
  236. {
  237. if (!mLookInfo)
  238. return;
  239. mLookInfo->setVisible(visible);
  240. if (mPanelOutfitsInventory) mPanelOutfitsInventory->setVisible(!visible);
  241. mFilterEditor->setVisible(!visible);
  242. mEditBtn->setVisible(!visible);
  243. mNewOutfitBtn->setVisible(!visible);
  244. mCurrOutfitPanel->setVisible(!visible);
  245. }
  246. void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable)
  247. {
  248. if (!wearable)
  249. {
  250. wearable = gAgentWearables.getWearable(WT_SHAPE, 0);
  251. }
  252. if (!mEditWearable || !wearable)
  253. {
  254. return;
  255. }
  256. mEditWearable->setVisible(visible);
  257. mFilterEditor->setVisible(!visible);
  258. mPanelOutfitsInventory->setVisible(!visible);
  259. }
  260. void LLSidepanelAppearance::updateVerbs()
  261. {
  262. bool is_look_info_visible = mLookInfo->getVisible();
  263. if (mPanelOutfitsInventory && !is_look_info_visible)
  264. {
  265. const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
  266. mEditBtn->setEnabled(is_correct_type);
  267. }
  268. else
  269. {
  270. mEditBtn->setEnabled(FALSE);
  271. }
  272. }
  273. void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
  274. {
  275. mOutfitDirtyTag->setVisible(LLAppearanceManager::getInstance()->isOutfitDirty());
  276. if (name == "")
  277. {
  278. std::string outfit_name;
  279. if (LLAppearanceManager::getInstance()->getBaseOutfitName(outfit_name))
  280. {
  281. mCurrentLookName->setText(outfit_name);
  282. return;
  283. }
  284. mCurrentLookName->setText(getString("No Outfit"));
  285. mOpenOutfitBtn->setEnabled(FALSE);
  286. }
  287. else
  288. {
  289. mCurrentLookName->setText(name);
  290. // Can't just call update verbs since the folder link may not have been created yet.
  291. mOpenOutfitBtn->setEnabled(TRUE);
  292. }
  293. }
  294. //static
  295. void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data)
  296. {
  297. LLSidepanelAppearance *panel = (LLSidepanelAppearance*) data;
  298. panel->toggleLookInfoPanel(FALSE);
  299. panel->toggleWearableEditPanel(TRUE, wearable);
  300. }
  301. // Fetch currently worn items and only enable the New Look button after everything's been
  302. // fetched.  Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks.
  303. void LLSidepanelAppearance::fetchInventory()
  304. {
  305. mNewOutfitBtn->setEnabled(false);
  306. LLInventoryFetchObserver::item_ref_t ids;
  307. LLUUID item_id;
  308. for(S32 type = (S32)WT_SHAPE; type < (S32)WT_COUNT; ++type)
  309. {
  310. // MULTI_WEARABLE:
  311. item_id = gAgentWearables.getWearableItemID((EWearableType)type,0);
  312. if(item_id.notNull())
  313. {
  314. ids.push_back(item_id);
  315. }
  316. }
  317. LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
  318. if( avatar )
  319. {
  320. for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin(); 
  321.  iter != avatar->mAttachmentPoints.end(); ++iter)
  322. {
  323. LLViewerJointAttachment* attachment = iter->second;
  324. if (!attachment) continue;
  325. for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
  326.  attachment_iter != attachment->mAttachedObjects.end();
  327.  ++attachment_iter)
  328. {
  329. LLViewerObject* attached_object = (*attachment_iter);
  330. if (!attached_object) continue;
  331. const LLUUID& item_id = attached_object->getItemID();
  332. if (item_id.isNull()) continue;
  333. ids.push_back(item_id);
  334. }
  335. }
  336. }
  337. LLCurrentlyWornFetchObserver *fetch_worn = new LLCurrentlyWornFetchObserver(this);
  338. fetch_worn->fetchItems(ids);
  339. // If no items to be fetched, done will never be triggered.
  340. // TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
  341. if (fetch_worn->isEverythingComplete())
  342. {
  343. fetch_worn->done();
  344. }
  345. else
  346. {
  347. gInventory.addObserver(fetch_worn);
  348. }
  349. }
  350. void LLSidepanelAppearance::inventoryFetched()
  351. {
  352. mNewOutfitBtn->setEnabled(true);
  353. }