PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llpaneleditwearable.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1365 lines | 1082 code | 178 blank | 105 comment | 106 complexity | 77eb68e1dbc88912fff2dd1fdd86e847 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpaneleditwearable.cpp
  3. * @brief UI panel for editing of a particular wearable item.
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llpaneleditwearable.h"
  28. #include "llpanel.h"
  29. #include "llwearable.h"
  30. #include "lluictrl.h"
  31. #include "llscrollingpanellist.h"
  32. #include "llvisualparam.h"
  33. #include "lltoolmorph.h"
  34. #include "llviewerjointmesh.h"
  35. #include "lltrans.h"
  36. #include "llbutton.h"
  37. #include "llsliderctrl.h"
  38. #include "llagent.h"
  39. #include "llvoavatarself.h"
  40. #include "lltexteditor.h"
  41. #include "lltextbox.h"
  42. #include "llaccordionctrl.h"
  43. #include "llaccordionctrltab.h"
  44. #include "llagentwearables.h"
  45. #include "llscrollingpanelparam.h"
  46. #include "llradiogroup.h"
  47. #include "llnotificationsutil.h"
  48. #include "llcolorswatch.h"
  49. #include "lltexturectrl.h"
  50. #include "lltextureentry.h"
  51. #include "llviewercontrol.h" // gSavedSettings
  52. #include "llviewertexturelist.h"
  53. #include "llagentcamera.h"
  54. #include "llmorphview.h"
  55. #include "llcommandhandler.h"
  56. #include "lltextutil.h"
  57. #include "llappearancemgr.h"
  58. // register panel with appropriate XML
  59. static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
  60. // subparts of the UI for focus, camera position, etc.
  61. enum ESubpart {
  62. SUBPART_SHAPE_HEAD = 1, // avoid 0
  63. SUBPART_SHAPE_EYES,
  64. SUBPART_SHAPE_EARS,
  65. SUBPART_SHAPE_NOSE,
  66. SUBPART_SHAPE_MOUTH,
  67. SUBPART_SHAPE_CHIN,
  68. SUBPART_SHAPE_TORSO,
  69. SUBPART_SHAPE_LEGS,
  70. SUBPART_SHAPE_WHOLE,
  71. SUBPART_SHAPE_DETAIL,
  72. SUBPART_SKIN_COLOR,
  73. SUBPART_SKIN_FACEDETAIL,
  74. SUBPART_SKIN_MAKEUP,
  75. SUBPART_SKIN_BODYDETAIL,
  76. SUBPART_HAIR_COLOR,
  77. SUBPART_HAIR_STYLE,
  78. SUBPART_HAIR_EYEBROWS,
  79. SUBPART_HAIR_FACIAL,
  80. SUBPART_EYES,
  81. SUBPART_SHIRT,
  82. SUBPART_PANTS,
  83. SUBPART_SHOES,
  84. SUBPART_SOCKS,
  85. SUBPART_JACKET,
  86. SUBPART_GLOVES,
  87. SUBPART_UNDERSHIRT,
  88. SUBPART_UNDERPANTS,
  89. SUBPART_SKIRT,
  90. SUBPART_ALPHA,
  91. SUBPART_TATTOO,
  92. SUBPART_PHYSICS_BREASTS_UPDOWN,
  93. SUBPART_PHYSICS_BREASTS_INOUT,
  94. SUBPART_PHYSICS_BREASTS_LEFTRIGHT,
  95. SUBPART_PHYSICS_BELLY_UPDOWN,
  96. SUBPART_PHYSICS_BUTT_UPDOWN,
  97. SUBPART_PHYSICS_BUTT_LEFTRIGHT,
  98. SUBPART_PHYSICS_ADVANCED,
  99. };
  100. using namespace LLVOAvatarDefines;
  101. typedef std::vector<ESubpart> subpart_vec_t;
  102. // Locally defined classes
  103. class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary>
  104. {
  105. //--------------------------------------------------------------------
  106. // Constructors and Destructors
  107. //--------------------------------------------------------------------
  108. public:
  109. LLEditWearableDictionary();
  110. virtual ~LLEditWearableDictionary();
  111. //--------------------------------------------------------------------
  112. // Wearable Types
  113. //--------------------------------------------------------------------
  114. public:
  115. struct WearableEntry : public LLDictionaryEntry
  116. {
  117. WearableEntry(LLWearableType::EType type,
  118. const std::string &title,
  119. const std::string &desc_title,
  120. U8 num_color_swatches, // number of 'color_swatches'
  121. U8 num_texture_pickers, // number of 'texture_pickers'
  122. U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts
  123. const LLWearableType::EType mWearableType;
  124. const std::string mTitle;
  125. const std::string mDescTitle;
  126. subpart_vec_t mSubparts;
  127. texture_vec_t mColorSwatchCtrls;
  128. texture_vec_t mTextureCtrls;
  129. };
  130. struct Wearables : public LLDictionary<LLWearableType::EType, WearableEntry>
  131. {
  132. Wearables();
  133. } mWearables;
  134. const WearableEntry* getWearable(LLWearableType::EType type) const { return mWearables.lookup(type); }
  135. //--------------------------------------------------------------------
  136. // Subparts
  137. //--------------------------------------------------------------------
  138. public:
  139. struct SubpartEntry : public LLDictionaryEntry
  140. {
  141. SubpartEntry(ESubpart part,
  142. const std::string &joint,
  143. const std::string &edit_group,
  144. const std::string &param_list,
  145. const std::string &accordion_tab,
  146. const LLVector3d &target_offset,
  147. const LLVector3d &camera_offset,
  148. const ESex &sex);
  149. ESubpart mSubpart;
  150. std::string mTargetJoint;
  151. std::string mEditGroup;
  152. std::string mParamList;
  153. std::string mAccordionTab;
  154. LLVector3d mTargetOffset;
  155. LLVector3d mCameraOffset;
  156. ESex mSex;
  157. };
  158. struct Subparts : public LLDictionary<ESubpart, SubpartEntry>
  159. {
  160. Subparts();
  161. } mSubparts;
  162. const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); }
  163. //--------------------------------------------------------------------
  164. // Picker Control Entries
  165. //--------------------------------------------------------------------
  166. public:
  167. struct PickerControlEntry : public LLDictionaryEntry
  168. {
  169. PickerControlEntry(ETextureIndex tex_index,
  170. const std::string name,
  171. const LLUUID default_image_id = LLUUID::null,
  172. const bool allow_no_texture = false);
  173. ETextureIndex mTextureIndex;
  174. const std::string mControlName;
  175. const LLUUID mDefaultImageId;
  176. const bool mAllowNoTexture;
  177. };
  178. struct ColorSwatchCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
  179. {
  180. ColorSwatchCtrls();
  181. } mColorSwatchCtrls;
  182. struct TextureCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
  183. {
  184. TextureCtrls();
  185. } mTextureCtrls;
  186. const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); }
  187. const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); }
  188. };
  189. LLEditWearableDictionary::LLEditWearableDictionary()
  190. {
  191. }
  192. //virtual
  193. LLEditWearableDictionary::~LLEditWearableDictionary()
  194. {
  195. }
  196. LLEditWearableDictionary::Wearables::Wearables()
  197. {
  198. // note the subpart that is listed first is treated as "default", regardless of what order is in enum.
  199. // Please match the order presented in XUI. -Nyx
  200. // this will affect what camera angle is shown when first editing a wearable
  201. addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text",0,0,9, SUBPART_SHAPE_WHOLE, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS));
  202. addEntry(LLWearableType::WT_SKIN, new WearableEntry(LLWearableType::WT_SKIN,"edit_skin_title","skin_desc_text",0,3,4, TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL));
  203. addEntry(LLWearableType::WT_HAIR, new WearableEntry(LLWearableType::WT_HAIR,"edit_hair_title","hair_desc_text",0,1,4, TEX_HAIR, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL));
  204. addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES));
  205. addEntry(LLWearableType::WT_SHIRT, new WearableEntry(LLWearableType::WT_SHIRT,"edit_shirt_title","shirt_desc_text",1,1,1, TEX_UPPER_SHIRT, TEX_UPPER_SHIRT, SUBPART_SHIRT));
  206. addEntry(LLWearableType::WT_PANTS, new WearableEntry(LLWearableType::WT_PANTS,"edit_pants_title","pants_desc_text",1,1,1, TEX_LOWER_PANTS, TEX_LOWER_PANTS, SUBPART_PANTS));
  207. addEntry(LLWearableType::WT_SHOES, new WearableEntry(LLWearableType::WT_SHOES,"edit_shoes_title","shoes_desc_text",1,1,1, TEX_LOWER_SHOES, TEX_LOWER_SHOES, SUBPART_SHOES));
  208. addEntry(LLWearableType::WT_SOCKS, new WearableEntry(LLWearableType::WT_SOCKS,"edit_socks_title","socks_desc_text",1,1,1, TEX_LOWER_SOCKS, TEX_LOWER_SOCKS, SUBPART_SOCKS));
  209. addEntry(LLWearableType::WT_JACKET, new WearableEntry(LLWearableType::WT_JACKET,"edit_jacket_title","jacket_desc_text",1,2,1, TEX_UPPER_JACKET, TEX_UPPER_JACKET, TEX_LOWER_JACKET, SUBPART_JACKET));
  210. addEntry(LLWearableType::WT_GLOVES, new WearableEntry(LLWearableType::WT_GLOVES,"edit_gloves_title","gloves_desc_text",1,1,1, TEX_UPPER_GLOVES, TEX_UPPER_GLOVES, SUBPART_GLOVES));
  211. addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry(LLWearableType::WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1,1,1, TEX_UPPER_UNDERSHIRT, TEX_UPPER_UNDERSHIRT, SUBPART_UNDERSHIRT));
  212. addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry(LLWearableType::WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS));
  213. addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT));
  214. addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title","alpha_desc_text",0,5,1, TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA, SUBPART_ALPHA));
  215. addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",1,3,1, TEX_HEAD_TATTOO, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO));
  216. addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title","physics_desc_text",0,0,7, SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED));
  217. }
  218. LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type,
  219. const std::string &title,
  220. const std::string &desc_title,
  221. U8 num_color_swatches,
  222. U8 num_texture_pickers,
  223. U8 num_subparts, ... ) :
  224. LLDictionaryEntry(title),
  225. mWearableType(type),
  226. mTitle(title),
  227. mDescTitle(desc_title)
  228. {
  229. va_list argp;
  230. va_start(argp, num_subparts);
  231. for (U8 i = 0; i < num_color_swatches; ++i)
  232. {
  233. ETextureIndex index = (ETextureIndex)va_arg(argp,int);
  234. mColorSwatchCtrls.push_back(index);
  235. }
  236. for (U8 i = 0; i < num_texture_pickers; ++i)
  237. {
  238. ETextureIndex index = (ETextureIndex)va_arg(argp,int);
  239. mTextureCtrls.push_back(index);
  240. }
  241. for (U8 i = 0; i < num_subparts; ++i)
  242. {
  243. ESubpart part = (ESubpart)va_arg(argp,int);
  244. mSubparts.push_back(part);
  245. }
  246. }
  247. LLEditWearableDictionary::Subparts::Subparts()
  248. {
  249. addEntry(SUBPART_SHAPE_WHOLE, new SubpartEntry(SUBPART_SHAPE_WHOLE, "mPelvis", "shape_body","shape_body_param_list", "shape_body_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
  250. addEntry(SUBPART_SHAPE_HEAD, new SubpartEntry(SUBPART_SHAPE_HEAD, "mHead", "shape_head", "shape_head_param_list", "shape_head_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  251. addEntry(SUBPART_SHAPE_EYES, new SubpartEntry(SUBPART_SHAPE_EYES, "mHead", "shape_eyes", "shape_eyes_param_list", "shape_eyes_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  252. addEntry(SUBPART_SHAPE_EARS, new SubpartEntry(SUBPART_SHAPE_EARS, "mHead", "shape_ears", "shape_ears_param_list", "shape_ears_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  253. addEntry(SUBPART_SHAPE_NOSE, new SubpartEntry(SUBPART_SHAPE_NOSE, "mHead", "shape_nose", "shape_nose_param_list", "shape_nose_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  254. addEntry(SUBPART_SHAPE_MOUTH, new SubpartEntry(SUBPART_SHAPE_MOUTH, "mHead", "shape_mouth", "shape_mouth_param_list", "shape_mouth_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  255. addEntry(SUBPART_SHAPE_CHIN, new SubpartEntry(SUBPART_SHAPE_CHIN, "mHead", "shape_chin", "shape_chin_param_list", "shape_chin_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  256. addEntry(SUBPART_SHAPE_TORSO, new SubpartEntry(SUBPART_SHAPE_TORSO, "mTorso", "shape_torso", "shape_torso_param_list", "shape_torso_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
  257. addEntry(SUBPART_SHAPE_LEGS, new SubpartEntry(SUBPART_SHAPE_LEGS, "mPelvis", "shape_legs", "shape_legs_param_list", "shape_legs_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  258. addEntry(SUBPART_SKIN_COLOR, new SubpartEntry(SUBPART_SKIN_COLOR, "mHead", "skin_color", "skin_color_param_list", "skin_color_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  259. addEntry(SUBPART_SKIN_FACEDETAIL, new SubpartEntry(SUBPART_SKIN_FACEDETAIL, "mHead", "skin_facedetail", "skin_face_param_list", "skin_face_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  260. addEntry(SUBPART_SKIN_MAKEUP, new SubpartEntry(SUBPART_SKIN_MAKEUP, "mHead", "skin_makeup", "skin_makeup_param_list", "skin_makeup_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  261. addEntry(SUBPART_SKIN_BODYDETAIL, new SubpartEntry(SUBPART_SKIN_BODYDETAIL, "mPelvis", "skin_bodydetail", "skin_body_param_list", "skin_body_tab", LLVector3d(0.f, 0.f, -0.2f), LLVector3d(-2.5f, 0.5f, 0.5f),SEX_BOTH));
  262. addEntry(SUBPART_HAIR_COLOR, new SubpartEntry(SUBPART_HAIR_COLOR, "mHead", "hair_color", "hair_color_param_list", "hair_color_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH));
  263. addEntry(SUBPART_HAIR_STYLE, new SubpartEntry(SUBPART_HAIR_STYLE, "mHead", "hair_style", "hair_style_param_list", "hair_style_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH));
  264. addEntry(SUBPART_HAIR_EYEBROWS, new SubpartEntry(SUBPART_HAIR_EYEBROWS, "mHead", "hair_eyebrows", "hair_eyebrows_param_list", "hair_eyebrows_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  265. addEntry(SUBPART_HAIR_FACIAL, new SubpartEntry(SUBPART_HAIR_FACIAL, "mHead", "hair_facial", "hair_facial_param_list", "hair_facial_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_MALE));
  266. addEntry(SUBPART_EYES, new SubpartEntry(SUBPART_EYES, "mHead", "eyes", "eyes_main_param_list", "eyes_main_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH));
  267. addEntry(SUBPART_SHIRT, new SubpartEntry(SUBPART_SHIRT, "mTorso", "shirt", "shirt_main_param_list", "shirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
  268. addEntry(SUBPART_PANTS, new SubpartEntry(SUBPART_PANTS, "mPelvis", "pants", "pants_main_param_list", "pants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  269. addEntry(SUBPART_SHOES, new SubpartEntry(SUBPART_SHOES, "mPelvis", "shoes", "shoes_main_param_list", "shoes_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  270. addEntry(SUBPART_SOCKS, new SubpartEntry(SUBPART_SOCKS, "mPelvis", "socks", "socks_main_param_list", "socks_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  271. addEntry(SUBPART_JACKET, new SubpartEntry(SUBPART_JACKET, "mTorso", "jacket", "jacket_main_param_list", "jacket_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-2.f, 0.1f, 0.3f),SEX_BOTH));
  272. addEntry(SUBPART_SKIRT, new SubpartEntry(SUBPART_SKIRT, "mPelvis", "skirt", "skirt_main_param_list", "skirt_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  273. addEntry(SUBPART_GLOVES, new SubpartEntry(SUBPART_GLOVES, "mTorso", "gloves", "gloves_main_param_list", "gloves_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-1.f, 0.15f, 0.f),SEX_BOTH));
  274. addEntry(SUBPART_UNDERSHIRT, new SubpartEntry(SUBPART_UNDERSHIRT, "mTorso", "undershirt", "undershirt_main_param_list", "undershirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH));
  275. addEntry(SUBPART_UNDERPANTS, new SubpartEntry(SUBPART_UNDERPANTS, "mPelvis", "underpants", "underpants_main_param_list", "underpants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH));
  276. addEntry(SUBPART_ALPHA, new SubpartEntry(SUBPART_ALPHA, "mPelvis", "alpha", "alpha_main_param_list", "alpha_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
  277. addEntry(SUBPART_TATTOO, new SubpartEntry(SUBPART_TATTOO, "mPelvis", "tattoo", "tattoo_main_param_list", "tattoo_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH));
  278. addEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, "mTorso", "physics_breasts_updown", "physics_breasts_updown_param_list", "physics_breasts_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
  279. addEntry(SUBPART_PHYSICS_BREASTS_INOUT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_INOUT, "mTorso", "physics_breasts_inout", "physics_breasts_inout_param_list", "physics_breasts_inout_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
  280. addEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, "mTorso", "physics_breasts_leftright", "physics_breasts_leftright_param_list", "physics_breasts_leftright_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE));
  281. addEntry(SUBPART_PHYSICS_BELLY_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BELLY_UPDOWN, "mTorso", "physics_belly_updown", "physics_belly_updown_param_list", "physics_belly_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
  282. addEntry(SUBPART_PHYSICS_BUTT_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BUTT_UPDOWN, "mTorso", "physics_butt_updown", "physics_butt_updown_param_list", "physics_butt_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
  283. addEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BUTT_LEFTRIGHT, "mTorso", "physics_butt_leftright", "physics_butt_leftright_param_list", "physics_butt_leftright_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
  284. addEntry(SUBPART_PHYSICS_ADVANCED, new SubpartEntry(SUBPART_PHYSICS_ADVANCED, "mTorso", "physics_advanced", "physics_advanced_param_list", "physics_advanced_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH));
  285. }
  286. LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part,
  287. const std::string &joint,
  288. const std::string &edit_group,
  289. const std::string &param_list,
  290. const std::string &accordion_tab,
  291. const LLVector3d &target_offset,
  292. const LLVector3d &camera_offset,
  293. const ESex &sex) :
  294. LLDictionaryEntry(edit_group),
  295. mSubpart(part),
  296. mTargetJoint(joint),
  297. mEditGroup(edit_group),
  298. mParamList(param_list),
  299. mAccordionTab(accordion_tab),
  300. mTargetOffset(target_offset),
  301. mCameraOffset(camera_offset),
  302. mSex(sex)
  303. {
  304. }
  305. LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls()
  306. {
  307. addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" ));
  308. addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" ));
  309. addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" ));
  310. addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" ));
  311. addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" ));
  312. addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" ));
  313. addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" ));
  314. addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" ));
  315. addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" ));
  316. addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" ));
  317. }
  318. LLEditWearableDictionary::TextureCtrls::TextureCtrls()
  319. {
  320. addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head", LLUUID::null, TRUE ));
  321. addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Body", LLUUID::null, TRUE ));
  322. addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Body", LLUUID::null, TRUE ));
  323. addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE ));
  324. addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE ));
  325. addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE ));
  326. addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE ));
  327. addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE ));
  328. addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE ));
  329. addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
  330. addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
  331. addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE ));
  332. addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE ));
  333. addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
  334. addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
  335. addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
  336. addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
  337. addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
  338. addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
  339. addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
  340. addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE ));
  341. addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE ));
  342. addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE ));
  343. }
  344. LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index,
  345. const std::string name,
  346. const LLUUID default_image_id,
  347. const bool allow_no_texture) :
  348. LLDictionaryEntry(name),
  349. mTextureIndex(tex_index),
  350. mControlName(name),
  351. mDefaultImageId(default_image_id),
  352. mAllowNoTexture(allow_no_texture)
  353. {
  354. }
  355. /**
  356. * Class to prevent hack in LLButton's constructor and use paddings declared in xml.
  357. */
  358. class LLLabledBackButton : public LLButton
  359. {
  360. public:
  361. struct Params : public LLInitParam::Block<Params, LLButton::Params>
  362. {
  363. Params() {}
  364. };
  365. protected:
  366. friend class LLUICtrlFactory;
  367. LLLabledBackButton(const Params&);
  368. };
  369. static LLDefaultChildRegistry::Register<LLLabledBackButton> labeled_back_btn("labeled_back_button");
  370. LLLabledBackButton::LLLabledBackButton(const Params& params)
  371. : LLButton(params)
  372. {
  373. // override hack in LLButton's constructor to use paddings have been set in xml
  374. setLeftHPad(params.pad_left);
  375. setRightHPad(params.pad_right);
  376. }
  377. // Helper functions.
  378. static const texture_vec_t null_texture_vec;
  379. // Specializations of this template function return a vector of texture indexes of particular control type
  380. // (i.e. LLColorSwatchCtrl or LLTextureCtrl) which are contained in given WearableEntry.
  381. template <typename T>
  382. const texture_vec_t&
  383. get_pickers_indexes(const LLEditWearableDictionary::WearableEntry *wearable_entry) { return null_texture_vec; }
  384. // Specializations of this template function return picker control entry for particular control type.
  385. template <typename T>
  386. const LLEditWearableDictionary::PickerControlEntry*
  387. get_picker_entry (const ETextureIndex index) { return NULL; }
  388. typedef boost::function<void(LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry*)> function_t;
  389. typedef struct PickerControlEntryNamePredicate
  390. {
  391. PickerControlEntryNamePredicate(const std::string name) : mName (name) {};
  392. bool operator()(const LLEditWearableDictionary::PickerControlEntry* entry) const
  393. {
  394. return (entry && entry->mName == mName);
  395. }
  396. private:
  397. const std::string mName;
  398. } PickerControlEntryNamePredicate;
  399. // A full specialization of get_pickers_indexes for LLColorSwatchCtrl
  400. template <>
  401. const texture_vec_t&
  402. get_pickers_indexes<LLColorSwatchCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
  403. {
  404. if (!wearable_entry)
  405. {
  406. llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl;
  407. return null_texture_vec;
  408. }
  409. return wearable_entry->mColorSwatchCtrls;
  410. }
  411. // A full specialization of get_pickers_indexes for LLTextureCtrl
  412. template <>
  413. const texture_vec_t&
  414. get_pickers_indexes<LLTextureCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
  415. {
  416. if (!wearable_entry)
  417. {
  418. llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl;
  419. return null_texture_vec;
  420. }
  421. return wearable_entry->mTextureCtrls;
  422. }
  423. // A full specialization of get_picker_entry for LLColorSwatchCtrl
  424. template <>
  425. const LLEditWearableDictionary::PickerControlEntry*
  426. get_picker_entry<LLColorSwatchCtrl> (const ETextureIndex index)
  427. {
  428. return LLEditWearableDictionary::getInstance()->getColorSwatch(index);
  429. }
  430. // A full specialization of get_picker_entry for LLTextureCtrl
  431. template <>
  432. const LLEditWearableDictionary::PickerControlEntry*
  433. get_picker_entry<LLTextureCtrl> (const ETextureIndex index)
  434. {
  435. return LLEditWearableDictionary::getInstance()->getTexturePicker(index);
  436. }
  437. template <typename CtrlType, class Predicate>
  438. const LLEditWearableDictionary::PickerControlEntry*
  439. find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred)
  440. {
  441. const LLEditWearableDictionary::WearableEntry *wearable_entry
  442. = LLEditWearableDictionary::getInstance()->getWearable(type);
  443. if (!wearable_entry)
  444. {
  445. llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
  446. return NULL;
  447. }
  448. const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
  449. for (texture_vec_t::const_iterator
  450. iter = indexes.begin(),
  451. iter_end = indexes.end();
  452. iter != iter_end; ++iter)
  453. {
  454. const ETextureIndex te = *iter;
  455. const LLEditWearableDictionary::PickerControlEntry* entry
  456. = get_picker_entry<CtrlType>(te);
  457. if (!entry)
  458. {
  459. llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
  460. continue;
  461. }
  462. if (pred(entry))
  463. {
  464. return entry;
  465. }
  466. }
  467. return NULL;
  468. }
  469. template <typename CtrlType>
  470. void
  471. for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun)
  472. {
  473. if (!panel)
  474. {
  475. llwarns << "the panel wasn't passed for wearable of type: " << type << llendl;
  476. return;
  477. }
  478. const LLEditWearableDictionary::WearableEntry *wearable_entry
  479. = LLEditWearableDictionary::getInstance()->getWearable(type);
  480. if (!wearable_entry)
  481. {
  482. llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
  483. return;
  484. }
  485. const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
  486. for (texture_vec_t::const_iterator
  487. iter = indexes.begin(),
  488. iter_end = indexes.end();
  489. iter != iter_end; ++iter)
  490. {
  491. const ETextureIndex te = *iter;
  492. const LLEditWearableDictionary::PickerControlEntry* entry
  493. = get_picker_entry<CtrlType>(te);
  494. if (!entry)
  495. {
  496. llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
  497. continue;
  498. }
  499. fun (panel, entry);
  500. }
  501. }
  502. // The helper functions for pickers management
  503. static void init_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  504. {
  505. LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
  506. if (color_swatch_ctrl)
  507. {
  508. // Can't get the color from the wearable here, since the wearable may not be set when this is called.
  509. color_swatch_ctrl->setOriginal(LLColor4::white);
  510. }
  511. }
  512. static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  513. {
  514. LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
  515. if (texture_ctrl)
  516. {
  517. texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId);
  518. texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
  519. // Don't allow (no copy) or (notransfer) textures to be selected.
  520. texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
  521. texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
  522. }
  523. }
  524. static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  525. {
  526. LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
  527. if (color_swatch_ctrl)
  528. {
  529. color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex));
  530. color_swatch_ctrl->closeFloaterColorPicker();
  531. }
  532. }
  533. static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  534. {
  535. LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
  536. if (texture_ctrl)
  537. {
  538. LLUUID new_id;
  539. LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex);
  540. if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) )
  541. {
  542. new_id = lto->getID();
  543. }
  544. else
  545. {
  546. new_id = LLUUID::null;
  547. }
  548. LLUUID old_id = texture_ctrl->getImageAssetID();
  549. if (old_id != new_id)
  550. {
  551. // texture has changed, close the floater to avoid DEV-22461
  552. texture_ctrl->closeDependentFloater();
  553. }
  554. texture_ctrl->setImageAssetID(new_id);
  555. }
  556. }
  557. static void set_enabled_color_swatch_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  558. {
  559. LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
  560. if (color_swatch_ctrl)
  561. {
  562. color_swatch_ctrl->setEnabled(enabled);
  563. }
  564. }
  565. static void set_enabled_texture_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
  566. {
  567. LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
  568. if (texture_ctrl)
  569. {
  570. texture_ctrl->setEnabled(enabled);
  571. }
  572. }
  573. // LLPanelEditWearable
  574. LLPanelEditWearable::LLPanelEditWearable()
  575. : LLPanel()
  576. , mWearablePtr(NULL)
  577. , mWearableItem(NULL)
  578. {
  579. mCommitCallbackRegistrar.add("ColorSwatch.Commit", boost::bind(&LLPanelEditWearable::onColorSwatchCommit, this, _1));
  580. mCommitCallbackRegistrar.add("TexturePicker.Commit", boost::bind(&LLPanelEditWearable::onTexturePickerCommit, this, _1));
  581. }
  582. //virtual
  583. LLPanelEditWearable::~LLPanelEditWearable()
  584. {
  585. }
  586. bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value)
  587. {
  588. updateMetricLayout( new_value.asBoolean() );
  589. updateTypeSpecificControls(LLWearableType::WT_SHAPE);
  590. return true;
  591. }
  592. void LLPanelEditWearable::updateMetricLayout(BOOL new_value)
  593. {
  594. LLUIString current_metric, replacment_metric;
  595. current_metric = new_value ? mMeters : mFeet;
  596. replacment_metric = new_value ? mFeet : mMeters;
  597. mHeigthValue.setArg( "[METRIC1]", current_metric.getString() );
  598. mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]"));
  599. }
  600. void LLPanelEditWearable::updateAvatarHeightLabel()
  601. {
  602. mTxtAvatarHeight->setText(LLStringUtil::null);
  603. LLStyle::Params param;
  604. param.color = mAvatarHeigthLabelColor;
  605. mTxtAvatarHeight->appendText(mHeigth, false, param);
  606. param.color = mAvatarHeigthValueLabelColor;
  607. mTxtAvatarHeight->appendText(mHeigthValue, false, param);
  608. param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator
  609. mTxtAvatarHeight->appendText(" / ", false, param);
  610. mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
  611. }
  612. void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
  613. {
  614. if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
  615. {
  616. accordion_ctrl->expandDefaultTab();
  617. }
  618. }
  619. void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel)
  620. {
  621. if (bodypart_panel != NULL)
  622. {
  623. LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion");
  624. if (accordion_ctrl != NULL)
  625. {
  626. bodypart_panel->setVisibleCallback(
  627. boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl));
  628. }
  629. else
  630. {
  631. llwarns << "accordion_ctrl is NULL" << llendl;
  632. }
  633. }
  634. else
  635. {
  636. llwarns << "bodypart_panel is NULL" << llendl;
  637. }
  638. }
  639. // virtual
  640. BOOL LLPanelEditWearable::postBuild()
  641. {
  642. // buttons
  643. mBtnRevert = getChild<LLButton>("revert_button");
  644. mBtnRevert->setClickedCallback(boost::bind(&LLPanelEditWearable::onRevertButtonClicked, this));
  645. mBtnBack = getChild<LLButton>("back_btn");
  646. mBackBtnLabel = mBtnBack->getLabelUnselected();
  647. mBtnBack->setLabel(LLStringUtil::null);
  648. // handled at appearance panel level?
  649. //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
  650. mNameEditor = getChild<LLLineEditor>("description");
  651. mPanelTitle = getChild<LLTextBox>("edit_wearable_title");
  652. mDescTitle = getChild<LLTextBox>("description_text");
  653. getChild<LLRadioGroup>("sex_radio")->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange, this));
  654. getChild<LLButton>("save_as_button")->setCommitCallback(boost::bind(&LLPanelEditWearable::onSaveAsButtonClicked, this));
  655. // The following panels will be shown/hidden based on what wearable we're editing
  656. // body parts
  657. mPanelShape = getChild<LLPanel>("edit_shape_panel");
  658. mPanelSkin = getChild<LLPanel>("edit_skin_panel");
  659. mPanelEyes = getChild<LLPanel>("edit_eyes_panel");
  660. mPanelHair = getChild<LLPanel>("edit_hair_panel");
  661. // Setting the visibility callback is applied only to the bodyparts panel
  662. // because currently they are the only ones whose 'wearable_accordion' has
  663. // multiple accordion tabs (see EXT-8164 for details).
  664. setWearablePanelVisibilityChangeCallback(mPanelShape);
  665. setWearablePanelVisibilityChangeCallback(mPanelSkin);
  666. setWearablePanelVisibilityChangeCallback(mPanelEyes);
  667. setWearablePanelVisibilityChangeCallback(mPanelHair);
  668. //clothes
  669. mPanelShirt = getChild<LLPanel>("edit_shirt_panel");
  670. mPanelPants = getChild<LLPanel>("edit_pants_panel");
  671. mPanelShoes = getChild<LLPanel>("edit_shoes_panel");
  672. mPanelSocks = getChild<LLPanel>("edit_socks_panel");
  673. mPanelJacket = getChild<LLPanel>("edit_jacket_panel");
  674. mPanelGloves = getChild<LLPanel>("edit_gloves_panel");
  675. mPanelUndershirt = getChild<LLPanel>("edit_undershirt_panel");
  676. mPanelUnderpants = getChild<LLPanel>("edit_underpants_panel");
  677. mPanelSkirt = getChild<LLPanel>("edit_skirt_panel");
  678. mPanelAlpha = getChild<LLPanel>("edit_alpha_panel");
  679. mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel");
  680. mPanelPhysics = getChild<LLPanel>("edit_physics_panel");
  681. mTxtAvatarHeight = mPanelShape->getChild<LLTextBox>("avatar_height");
  682. mWearablePtr = NULL;
  683. configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
  684. configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
  685. configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
  686. configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
  687. configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
  688. // configure tab expanded callbacks
  689. for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index)
  690. {
  691. LLWearableType::EType type = (LLWearableType::EType) type_index;
  692. const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
  693. if (!wearable_entry)
  694. {
  695. llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
  696. continue;
  697. }
  698. U8 num_subparts = wearable_entry->mSubparts.size();
  699. for (U8 index = 0; index < num_subparts; ++index)
  700. {
  701. // dive into data structures to get the panel we need
  702. ESubpart subpart_e = wearable_entry->mSubparts[index];
  703. const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
  704. if (!subpart_entry)
  705. {
  706. llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl;
  707. continue;
  708. }
  709. const std::string accordion_tab = subpart_entry->mAccordionTab;
  710. LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab);
  711. if (!tab)
  712. {
  713. llwarns << "could not get llaccordionctrltab from UI with name: " << accordion_tab << llendl;
  714. continue;
  715. }
  716. // initialize callback to ensure camera view changes appropriately.
  717. tab->setDropDownStateChangedCallback(boost::bind(&LLPanelEditWearable::onTabExpandedCollapsed,this,_2,index));
  718. }
  719. // initialize texture and color picker controls
  720. for_each_picker_ctrl_entry <LLColorSwatchCtrl> (getPanel(type), type, boost::bind(init_color_swatch_ctrl, this, _1, _2));
  721. for_each_picker_ctrl_entry <LLTextureCtrl> (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2));
  722. }
  723. // init all strings
  724. mMeters = mPanelShape->getString("meters");
  725. mFeet = mPanelShape->getString("feet");
  726. mHeigth = mPanelShape->getString("height") + " ";
  727. mHeigthValue = "[HEIGHT] [METRIC1]";
  728. mReplacementMetricUrl = "[URL_METRIC2]";
  729. std::string color = mPanelShape->getString("heigth_label_color");
  730. mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
  731. color = mPanelShape->getString("heigth_value_label_color");
  732. mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
  733. gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2));
  734. updateMetricLayout(gSavedSettings.getBOOL("HeightUnits"));
  735. return TRUE;
  736. }
  737. // virtual
  738. // LLUICtrl
  739. BOOL LLPanelEditWearable::isDirty() const
  740. {
  741. BOOL isDirty = FALSE;
  742. if (mWearablePtr)
  743. {
  744. if (mWearablePtr->isDirty() ||
  745. mWearableItem->getName().compare(mNameEditor->getText()) != 0)
  746. {
  747. isDirty = TRUE;
  748. }
  749. }
  750. return isDirty;
  751. }
  752. //virtual
  753. void LLPanelEditWearable::draw()
  754. {
  755. updateVerbs();
  756. if (getWearable() && getWearable()->getType() == LLWearableType::WT_SHAPE)
  757. {
  758. //updating avatar height
  759. updateTypeSpecificControls(LLWearableType::WT_SHAPE);
  760. }
  761. LLPanel::draw();
  762. }
  763. void LLPanelEditWearable::setVisible(BOOL visible)
  764. {
  765. if (!visible)
  766. {
  767. showWearable(mWearablePtr, FALSE);
  768. }
  769. LLPanel::setVisible(visible);
  770. }
  771. void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
  772. {
  773. showWearable(mWearablePtr, FALSE, disable_camera_switch);
  774. mWearablePtr = wearable;
  775. showWearable(mWearablePtr, TRUE, disable_camera_switch);
  776. }
  777. //static
  778. void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
  779. {
  780. LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
  781. panel->revertChanges();
  782. }
  783. void LLPanelEditWearable::onSaveAsButtonClicked()
  784. {
  785. LLSD args;
  786. args["DESC"] = mNameEditor->getText();
  787. LLNotificationsUtil::add("SaveWearableAs", args, LLSD(), boost::bind(&LLPanelEditWearable::saveAsCallback, this, _1, _2));
  788. }
  789. void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& response)
  790. {
  791. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  792. if (0 == option)
  793. {
  794. std::string wearable_name = response["message"].asString();
  795. LLStringUtil::trim(wearable_name);
  796. if( !wearable_name.empty() )
  797. {
  798. mNameEditor->setText(wearable_name);
  799. saveChanges(true);
  800. }
  801. }
  802. }
  803. void LLPanelEditWearable::onCommitSexChange()
  804. {
  805. if (!isAgentAvatarValid()) return;
  806. LLWearableType::EType type = mWearablePtr->getType();
  807. U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
  808. if( !gAgentWearables.isWearableModifiable(type, index))
  809. {
  810. return;
  811. }
  812. LLViewerVisualParam* param = static_cast<LLViewerVisualParam*>(gAgentAvatarp->getVisualParam( "male" ));
  813. if( !param )
  814. {
  815. return;
  816. }
  817. bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
  818. LLWearable* wearable = gAgentWearables.getWearable(type, index);
  819. if (wearable)
  820. {
  821. wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE);
  822. }
  823. param->setWeight( is_new_sex_male, FALSE );
  824. gAgentAvatarp->updateSexDependentLayerSets( FALSE );
  825. gAgentAvatarp->updateVisualParams();
  826. updateScrollingPanelUI();
  827. }
  828. void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
  829. {
  830. const LLTextureCtrl* texture_ctrl = dynamic_cast<const LLTextureCtrl*>(ctrl);
  831. if (!texture_ctrl)
  832. {
  833. llwarns << "got commit signal from not LLTextureCtrl." << llendl;
  834. return;
  835. }
  836. if (getWearable())
  837. {
  838. LLWearableType::EType type = getWearable()->getType();
  839. const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName());
  840. const LLEditWearableDictionary::PickerControlEntry* entry
  841. = find_picker_ctrl_entry_if<LLTextureCtrl, PickerControlEntryNamePredicate>(type, name_pred);
  842. if (entry)
  843. {
  844. // Set the new version
  845. LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
  846. if( image->getID() == IMG_DEFAULT )
  847. {
  848. image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
  849. }
  850. if (getWearable())
  851. {
  852. U32 index = gAgentWearables.getWearableIndex(getWearable());
  853. gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index);
  854. LLVisualParamHint::requestHintUpdates();
  855. gAgentAvatarp->wearableUpdated(type, FALSE);
  856. }
  857. }
  858. else
  859. {
  860. llwarns << "could not get texture picker dictionary entry for wearable of type: " << type << llendl;
  861. }
  862. }
  863. }
  864. void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* ctrl)
  865. {
  866. if (getWearable())
  867. {
  868. LLWearableType::EType type = getWearable()->getType();
  869. const PickerControlEntryNamePredicate name_pred(ctrl->getName());
  870. const LLEditWearableDictionary::PickerControlEntry* entry
  871. = find_picker_ctrl_entry_if<LLColorSwatchCtrl, PickerControlEntryNamePredicate>(type, name_pred);
  872. if (entry)
  873. {
  874. const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex);
  875. const LLColor4& new_color = LLColor4(ctrl->getValue());
  876. if( old_color != new_color )
  877. {
  878. getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE);
  879. LLVisualParamHint::requestHintUpdates();
  880. gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
  881. }
  882. }
  883. else
  884. {
  885. llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl;
  886. }
  887. }
  888. }
  889. void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
  890. {
  891. LLPanel* panel = getPanel(type);
  892. if (!panel)
  893. return;
  894. bool is_modifiable = false;
  895. bool is_copyable = false;
  896. if(mWearableItem)
  897. {
  898. const LLPermissions& perm = mWearableItem->getPermissions();
  899. is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
  900. is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());
  901. }
  902. if (is_modifiable)
  903. {
  904. // Update picker controls
  905. for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(update_color_swatch_ctrl, this, _1, _2));
  906. for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(update_texture_ctrl, this, _1, _2));
  907. }
  908. else
  909. {
  910. // Disable controls
  911. for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(set_enabled_color_swatch_ctrl, false, _1, _2));
  912. for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(set_enabled_texture_ctrl, false, _1, _2));
  913. }
  914. }
  915. void LLPanelEditWearable::saveChanges(bool force_save_as)
  916. {
  917. if (!mWearablePtr || !isDirty())
  918. {
  919. // do nothing if no unsaved changes
  920. return;
  921. }
  922. U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
  923. std::string new_name = mNameEditor->getText();
  924. if (force_save_as)
  925. {
  926. // the name of the wearable has changed, re-save wearable with new name
  927. LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);
  928. gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE);
  929. mNameEditor->setText(mWearableItem->getName());
  930. }
  931. else
  932. {
  933. gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);
  934. }
  935. }
  936. void LLPanelEditWearable::revertChanges()
  937. {
  938. if (!mWearablePtr || !isDirty())
  939. {
  940. // no unsaved changes to revert
  941. return;
  942. }
  943. mWearablePtr->revertValues();
  944. mNameEditor->setText(mWearableItem->getName());
  945. updatePanelPickerControls(mWearablePtr->getType());
  946. updateTypeSpecificControls(mWearablePtr->getType());
  947. gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
  948. }
  949. void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch)
  950. {
  951. if (!wearable)
  952. {
  953. return;
  954. }
  955. mWearableItem = gInventory.getItem(mWearablePtr->getItemID());
  956. llassert(mWearableItem);
  957. LLWearableType::EType type = wearable->getType();
  958. LLPanel *targetPanel = NULL;
  959. std::string title;
  960. std::string description_title;
  961. const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
  962. if (!wearable_entry)
  963. {
  964. llwarns << "called LLPanelEditWearable::showWearable with an invalid wearable type! (" << type << ")" << llendl;
  965. return;
  966. }
  967. targetPanel = getPanel(type);
  968. title = getString(wearable_entry->mTitle);
  969. description_title = getString(wearable_entry->mDescTitle);
  970. // Update picker controls state
  971. for_each_picker_ctrl_entry <LLColorSwatchCtrl> (targetPanel, type, boost::bind(set_enabled_color_swatch_ctrl, show, _1, _2));
  972. for_each_picker_ctrl_entry <LLTextureCtrl> (targetPanel, type, boost::bind(set_enabled_texture_ctrl, show, _1, _2));
  973. targetPanel->setVisible(show);
  974. toggleTypeSpecificControls(type);
  975. if (show)
  976. {
  977. mPanelTitle->setText(title);
  978. mPanelTitle->setToolTip(title);
  979. mDescTitle->setText(description_title);
  980. // set name
  981. mNameEditor->setText(mWearableItem->getName());
  982. updatePanelPickerControls(type);
  983. updateTypeSpecificControls(type);
  984. // clear and rebuild visual param list
  985. U8 num_subparts = wearable_entry->mSubparts.size();
  986. for (U8 index = 0; index < num_subparts; ++index)
  987. {
  988. // dive into data structures to get the panel we need
  989. ESubpart subpart_e = wearable_entry->mSubparts[index];
  990. const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
  991. if (!subpart_entry)
  992. {
  993. llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl;
  994. continue;
  995. }
  996. const std::string scrolling_panel = subpart_entry->mParamList;
  997. const std::string accordion_tab = subpart_entry->mAccordionTab;
  998. LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel);
  999. LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab);
  1000. if (!panel_list)
  1001. {
  1002. llwarns << "could not get scrolling panel list: " << scrolling_panel << llendl;
  1003. continue;
  1004. }
  1005. if (!tab)
  1006. {
  1007. llwarns << "could not get llaccordionctrltab from UI with name: " << accordion_tab << llendl;
  1008. continue;
  1009. }
  1010. // Don't show female subparts if you're not female, etc.
  1011. if (!(gAgentAvatarp->getSex() & subpart_entry->mSex))
  1012. {
  1013. tab->setVisible(FALSE);
  1014. continue;
  1015. }
  1016. else
  1017. {
  1018. tab->setVisible(TRUE);
  1019. }
  1020. // what edit group do we want to extract params for?
  1021. const std::string edit_group = subpart_entry->mEditGroup;
  1022. // storage for ordered list of visual params
  1023. value_map_t sorted_params;
  1024. getSortedParams(sorted_params, edit_group);
  1025. LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint );
  1026. if (!jointp)
  1027. {
  1028. jointp = gAgentAvatarp->getJoint("mHead");
  1029. }
  1030. buildParamList(panel_list, sorted_params, tab, jointp);
  1031. updateScrollingPanelUI();
  1032. }
  1033. if (!disable_camera_switch)
  1034. {
  1035. showDefaultSubpart();
  1036. }
  1037. updateVerbs();
  1038. }
  1039. }
  1040. void LLPanelEditWearable::showDefaultSubpart()
  1041. {
  1042. changeCamera(3);
  1043. }
  1044. void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index)
  1045. {
  1046. bool expanded = param.asBoolean();
  1047. if (!mWearablePtr || !gAgentCamera.cameraCustomizeAvatar())
  1048. {
  1049. // we don't have a valid wearable we're editing, or we've left the wearable editor
  1050. return;
  1051. }
  1052. if (expanded)
  1053. {
  1054. changeCamera(index);
  1055. }
  1056. }
  1057. void LLPanelEditWearable::changeCamera(U8 subpart)
  1058. {
  1059. // Don't change the camera if this type doesn't have a camera switch.
  1060. // Useful for wearables like physics that don't have an associated physical body part.
  1061. if (LLWearableType::getDisableCameraSwitch(mWearablePtr->getType()))
  1062. {
  1063. return;
  1064. }
  1065. const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mWearablePtr->getType());
  1066. if (!wearable_entry)
  1067. {
  1068. llinfos << "could not get wearable dictionary entry for wearable type: " << mWearablePtr->getType() << llendl;
  1069. return;
  1070. }
  1071. if (subpart >= wearable_entry->mSubparts.size())
  1072. {
  1073. llinfos << "accordion tab expanded for invalid subpart. Wearable type: " << mWearablePtr->getType() << " subpart num: " << subpart << llendl;
  1074. return;
  1075. }
  1076. ESubpart subpart_e = wearable_entry->mSubparts[subpart];
  1077. const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
  1078. if (!subpart_entry)
  1079. {
  1080. llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl;
  1081. return;
  1082. }
  1083. // Update the camera
  1084. gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
  1085. gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
  1086. gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
  1087. if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
  1088. {
  1089. gMorphView->updateCamera();
  1090. }
  1091. }
  1092. void LLPanelEditWearable::updateScrollingPanelList()
  1093. {
  1094. updateScrollingPanelUI();
  1095. }
  1096. void LLPanelEditWearable::toggleTypeSpecificControls(LLWearableType::EType type)
  1097. {
  1098. // Toggle controls specific to shape editing panel.
  1099. {
  1100. bool is_shape = (type == LLWearableType::WT_SHAPE);
  1101. getChildView("sex_radio")->setVisible( is_shape);
  1102. getChildView("female_icon")->setVisible( is_shape);
  1103. getChildView("male_icon")->setVisible( is_shape);
  1104. }
  1105. }
  1106. void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)
  1107. {
  1108. const F32 ONE_METER = 1.0;
  1109. const F32 ONE_FOOT = 0.3048 * ONE_METER; // in meters
  1110. // Update controls specific to shape editing panel.
  1111. if (type == LLWearableType::WT_SHAPE)
  1112. {
  1113. // Update avatar height
  1114. F32 new_size = gAgentAvatarp->mBodySize.mV[VZ];
  1115. if (gSavedSettings.getBOOL("HeightUnits") == FALSE)
  1116. {
  1117. // convert meters to feet
  1118. new_size = new_size / ONE_FOOT;
  1119. }
  1120. std::string avatar_height_str = llformat("%.2f", new_size);
  1121. mHeigthValue.setArg("[HEIGHT]", avatar_height_str);
  1122. updateAvatarHeightLabel();
  1123. }
  1124. if (LLWearableType::WT_ALPHA == type)
  1125. {
  1126. updateAlphaCheckboxes();
  1127. initPreviousAlphaTextures();
  1128. }
  1129. }
  1130. void LLPanelEditWearable::updateScrollingPanelUI()
  1131. {
  1132. // do nothing if we don't have a valid wearable we're editing
  1133. if (mWearablePtr == NULL)
  1134. {
  1135. return;
  1136. }
  1137. LLWearableType::EType type = mWearablePtr->getType();
  1138. LLPanel *panel = getPanel(type);
  1139. if(panel && (mWearablePtr->getItemID().notNull()))
  1140. {
  1141. const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
  1142. llassert(wearable_entry);
  1143. if (!wearable_entry) return;
  1144. U8 num_subparts = wearable_entry->mSubparts.size();
  1145. LLScrollingPanelParam::sUpdateDelayFrames = 0;
  1146. for (U8 index = 0; index < num_subparts; ++index)
  1147. {
  1148. // dive into data structures to get the panel we need
  1149. ESubpart subpart_e = wearable_entry->mSubparts[index];
  1150. const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
  1151. const std::string scrolling_panel = subpart_entry->mParamList;
  1152. LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel);
  1153. if (!panel_list)
  1154. {
  1155. llwarns << "could not get scrolling panel list: " << scrolling_panel << llendl;
  1156. continue;
  1157. }
  1158. panel_list->updatePanels(TRUE);
  1159. }
  1160. }
  1161. }
  1162. LLPanel* LLPanelEditWearable::getPanel(LLWearableType::EType type)
  1163. {
  1164. switch (type)
  1165. {
  1166. case LLWearableType::WT_SHAPE:
  1167. return mPanelShape;
  1168. break;
  1169. case LLWearableType::WT_SKIN:
  1170. return mPanelSkin;
  1171. break;
  1172. case LLWearableType::WT_HAIR:
  1173. return mPanelHair;
  1174. break;
  1175. case LLWearableType::WT_EYES:
  1176. return mPanelEyes;
  1177. break;
  1178. case LLWearableType::WT_SHIRT:
  1179. return mPanelShirt;
  1180. break;
  1181. case LLWearableType::WT_PANTS:
  1182. return mPanelPants;
  1183. break;
  1184. case LLWearableType::WT_SHOES:
  1185. return mPanelShoes;
  1186. break;
  1187. case LLWearableType::WT_SOCKS: