PageRenderTime 347ms CodeModel.GetById 177ms app.highlight 152ms RepoModel.GetById 2ms app.codeStats 1ms

/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

Large files files are truncated, but you can click here to view the full file

  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
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llpaneleditwearable.h"
 30#include "llpanel.h"
 31#include "llwearable.h"
 32#include "lluictrl.h"
 33#include "llscrollingpanellist.h"
 34#include "llvisualparam.h"
 35#include "lltoolmorph.h"
 36#include "llviewerjointmesh.h"
 37#include "lltrans.h"
 38#include "llbutton.h"
 39#include "llsliderctrl.h"
 40#include "llagent.h"
 41#include "llvoavatarself.h"
 42#include "lltexteditor.h"
 43#include "lltextbox.h"
 44#include "llaccordionctrl.h"
 45#include "llaccordionctrltab.h"
 46#include "llagentwearables.h"
 47#include "llscrollingpanelparam.h"
 48#include "llradiogroup.h"
 49#include "llnotificationsutil.h"
 50
 51#include "llcolorswatch.h"
 52#include "lltexturectrl.h"
 53#include "lltextureentry.h"
 54#include "llviewercontrol.h"    // gSavedSettings
 55#include "llviewertexturelist.h"
 56#include "llagentcamera.h"
 57#include "llmorphview.h"
 58
 59#include "llcommandhandler.h"
 60#include "lltextutil.h"
 61#include "llappearancemgr.h"
 62
 63// register panel with appropriate XML
 64static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
 65
 66// subparts of the UI for focus, camera position, etc.
 67enum ESubpart {
 68        SUBPART_SHAPE_HEAD = 1, // avoid 0
 69        SUBPART_SHAPE_EYES,
 70        SUBPART_SHAPE_EARS,
 71        SUBPART_SHAPE_NOSE,
 72        SUBPART_SHAPE_MOUTH,
 73        SUBPART_SHAPE_CHIN,
 74        SUBPART_SHAPE_TORSO,
 75        SUBPART_SHAPE_LEGS,
 76        SUBPART_SHAPE_WHOLE,
 77        SUBPART_SHAPE_DETAIL,
 78        SUBPART_SKIN_COLOR,
 79        SUBPART_SKIN_FACEDETAIL,
 80        SUBPART_SKIN_MAKEUP,
 81        SUBPART_SKIN_BODYDETAIL,
 82        SUBPART_HAIR_COLOR,
 83        SUBPART_HAIR_STYLE,
 84        SUBPART_HAIR_EYEBROWS,
 85        SUBPART_HAIR_FACIAL,
 86        SUBPART_EYES,
 87        SUBPART_SHIRT,
 88        SUBPART_PANTS,
 89        SUBPART_SHOES,
 90        SUBPART_SOCKS,
 91        SUBPART_JACKET,
 92        SUBPART_GLOVES,
 93        SUBPART_UNDERSHIRT,
 94        SUBPART_UNDERPANTS,
 95        SUBPART_SKIRT,
 96        SUBPART_ALPHA,
 97        SUBPART_TATTOO,
 98        SUBPART_PHYSICS_BREASTS_UPDOWN,
 99        SUBPART_PHYSICS_BREASTS_INOUT,
100        SUBPART_PHYSICS_BREASTS_LEFTRIGHT,
101        SUBPART_PHYSICS_BELLY_UPDOWN,
102        SUBPART_PHYSICS_BUTT_UPDOWN,
103        SUBPART_PHYSICS_BUTT_LEFTRIGHT,
104        SUBPART_PHYSICS_ADVANCED,
105 };
106
107using namespace LLVOAvatarDefines;
108
109typedef std::vector<ESubpart> subpart_vec_t;
110
111// Locally defined classes
112
113class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary>
114{
115        //--------------------------------------------------------------------
116        // Constructors and Destructors
117        //--------------------------------------------------------------------
118public:
119        LLEditWearableDictionary();
120        virtual ~LLEditWearableDictionary();
121        
122        //--------------------------------------------------------------------
123        // Wearable Types
124        //--------------------------------------------------------------------
125public:
126        struct WearableEntry : public LLDictionaryEntry
127        {
128                WearableEntry(LLWearableType::EType type,
129                                          const std::string &title,
130                                          const std::string &desc_title,
131                                          U8 num_color_swatches,  // number of 'color_swatches'
132                                          U8 num_texture_pickers, // number of 'texture_pickers'
133                                          U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts
134
135
136                const LLWearableType::EType mWearableType;
137                const std::string   mTitle;
138                const std::string       mDescTitle;
139                subpart_vec_t           mSubparts;
140                texture_vec_t           mColorSwatchCtrls;
141                texture_vec_t           mTextureCtrls;
142        };
143
144        struct Wearables : public LLDictionary<LLWearableType::EType, WearableEntry>
145        {
146                Wearables();
147        } mWearables;
148
149        const WearableEntry*    getWearable(LLWearableType::EType type) const { return mWearables.lookup(type); }
150
151        //--------------------------------------------------------------------
152        // Subparts
153        //--------------------------------------------------------------------
154public:
155        struct SubpartEntry : public LLDictionaryEntry
156        {
157                SubpartEntry(ESubpart part,
158                                         const std::string &joint,
159                                         const std::string &edit_group,
160                                         const std::string &param_list,
161                                         const std::string &accordion_tab,
162                                         const LLVector3d  &target_offset,
163                                         const LLVector3d  &camera_offset,
164                                         const ESex        &sex);
165
166                ESubpart                        mSubpart;
167                std::string                     mTargetJoint;
168                std::string                     mEditGroup;
169                std::string                     mParamList;
170                std::string                     mAccordionTab;
171                LLVector3d                      mTargetOffset;
172                LLVector3d                      mCameraOffset;
173                ESex                            mSex;
174        };
175
176        struct Subparts : public LLDictionary<ESubpart, SubpartEntry>
177        {
178                Subparts();
179        } mSubparts;
180
181        const SubpartEntry*  getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); }
182
183        //--------------------------------------------------------------------
184        // Picker Control Entries
185        //--------------------------------------------------------------------
186public:
187        struct PickerControlEntry : public LLDictionaryEntry
188        {
189                PickerControlEntry(ETextureIndex tex_index,
190                                                   const std::string name,
191                                                   const LLUUID default_image_id = LLUUID::null,
192                                                   const bool allow_no_texture = false);
193                ETextureIndex           mTextureIndex;
194                const std::string       mControlName;
195                const LLUUID            mDefaultImageId;
196                const bool                      mAllowNoTexture;
197        };
198
199        struct ColorSwatchCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
200        {
201                ColorSwatchCtrls();
202        } mColorSwatchCtrls;
203
204        struct TextureCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
205        {
206                TextureCtrls();
207        } mTextureCtrls;
208
209        const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); }
210        const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); }
211};
212
213LLEditWearableDictionary::LLEditWearableDictionary()
214{
215
216}
217
218//virtual 
219LLEditWearableDictionary::~LLEditWearableDictionary()
220{
221}
222
223LLEditWearableDictionary::Wearables::Wearables()
224{
225        // note the subpart that is listed first is treated as "default", regardless of what order is in enum.
226        // Please match the order presented in XUI. -Nyx
227        // this will affect what camera angle is shown when first editing a wearable
228        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));
229        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));
230        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));
231        addEntry(LLWearableType::WT_EYES,               new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES));
232        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));
233        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));
234        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));
235        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));
236        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));
237        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));
238        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));
239        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));
240        addEntry(LLWearableType::WT_SKIRT,              new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT));
241        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));
242        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));
243        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));
244}
245
246LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type,
247                                          const std::string &title,
248                                          const std::string &desc_title,
249                                          U8 num_color_swatches,
250                                          U8 num_texture_pickers,
251                                          U8 num_subparts, ... ) :
252        LLDictionaryEntry(title),
253        mWearableType(type),
254        mTitle(title),
255        mDescTitle(desc_title)
256{
257        va_list argp;
258        va_start(argp, num_subparts);
259
260        for (U8 i = 0; i < num_color_swatches; ++i)
261        {
262                ETextureIndex index = (ETextureIndex)va_arg(argp,int);
263                mColorSwatchCtrls.push_back(index);
264        }
265
266        for (U8 i = 0; i < num_texture_pickers; ++i)
267        {
268                ETextureIndex index = (ETextureIndex)va_arg(argp,int);
269                mTextureCtrls.push_back(index);
270        }
271
272        for (U8 i = 0; i < num_subparts; ++i)
273        {
274                ESubpart part = (ESubpart)va_arg(argp,int);
275                mSubparts.push_back(part);
276        }
277}
278
279LLEditWearableDictionary::Subparts::Subparts()
280{
281        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));
282        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));
283        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));
284        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));
285        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));
286        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));
287        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));
288        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));
289        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));
290
291        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));
292        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));
293        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));
294        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));
295
296        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));
297        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));
298        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));
299        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));
300
301        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));
302
303        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));
304        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));
305        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));
306        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));
307        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));
308        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));
309        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));
310        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));
311        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));
312        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));
313        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));
314        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));
315        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));
316        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));
317        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));
318        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));
319        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));
320        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));
321}
322
323LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part,
324                                         const std::string &joint,
325                                         const std::string &edit_group,
326                                         const std::string &param_list,
327                                         const std::string &accordion_tab,
328                                         const LLVector3d  &target_offset,
329                                         const LLVector3d  &camera_offset,
330                                         const ESex        &sex) :
331        LLDictionaryEntry(edit_group),
332        mSubpart(part),
333        mTargetJoint(joint),
334        mEditGroup(edit_group),
335        mParamList(param_list),
336        mAccordionTab(accordion_tab),
337        mTargetOffset(target_offset),
338        mCameraOffset(camera_offset),
339        mSex(sex)
340{
341}
342
343LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls()
344{
345        addEntry ( TEX_UPPER_SHIRT,  new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" ));
346        addEntry ( TEX_LOWER_PANTS,  new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" ));
347        addEntry ( TEX_LOWER_SHOES,  new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" ));
348        addEntry ( TEX_LOWER_SOCKS,  new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" ));
349        addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" ));
350        addEntry ( TEX_SKIRT,  new PickerControlEntry (TEX_SKIRT, "Color/Tint" ));
351        addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" ));
352        addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" ));
353        addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" ));
354        addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" ));
355}
356
357LLEditWearableDictionary::TextureCtrls::TextureCtrls()
358{
359        addEntry ( TEX_HEAD_BODYPAINT,  new PickerControlEntry (TEX_HEAD_BODYPAINT,  "Head", LLUUID::null, TRUE ));
360        addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Body", LLUUID::null, TRUE ));
361        addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Body", LLUUID::null, TRUE ));
362        addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE ));
363        addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE ));
364        addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE ));
365        addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE ));
366        addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE ));
367        addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE ));
368        addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
369        addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
370        addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE ));
371        addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE ));
372        addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
373        addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
374        addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
375        addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
376        addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
377        addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
378        addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
379        addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE ));
380        addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE ));
381        addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE ));
382}
383
384LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index,
385                                         const std::string name,
386                                         const LLUUID default_image_id,
387                                         const bool allow_no_texture) :
388        LLDictionaryEntry(name),
389        mTextureIndex(tex_index),
390        mControlName(name),
391        mDefaultImageId(default_image_id),
392        mAllowNoTexture(allow_no_texture)
393{
394}
395
396/**
397 * Class to prevent hack in LLButton's constructor and use paddings declared in xml.
398 */
399class LLLabledBackButton : public LLButton
400{
401public:
402        struct Params : public LLInitParam::Block<Params, LLButton::Params>
403        {
404                Params() {}
405        };
406protected:
407        friend class LLUICtrlFactory;
408        LLLabledBackButton(const Params&);
409};
410
411static LLDefaultChildRegistry::Register<LLLabledBackButton> labeled_back_btn("labeled_back_button");
412
413LLLabledBackButton::LLLabledBackButton(const Params& params)
414: LLButton(params)
415{
416        // override hack in LLButton's constructor to use paddings have been set in xml
417        setLeftHPad(params.pad_left);
418        setRightHPad(params.pad_right);
419}
420
421// Helper functions.
422static const texture_vec_t null_texture_vec;
423
424// Specializations of this template function return a vector of texture indexes of particular control type
425// (i.e. LLColorSwatchCtrl or LLTextureCtrl) which are contained in given WearableEntry.
426template <typename T>
427const texture_vec_t&
428get_pickers_indexes(const LLEditWearableDictionary::WearableEntry *wearable_entry) { return null_texture_vec; }
429
430// Specializations of this template function return picker control entry for particular control type.
431template <typename T>
432const LLEditWearableDictionary::PickerControlEntry*
433get_picker_entry (const ETextureIndex index) { return NULL; }
434
435typedef boost::function<void(LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry*)> function_t;
436
437typedef struct PickerControlEntryNamePredicate
438{
439        PickerControlEntryNamePredicate(const std::string name) : mName (name) {};
440        bool operator()(const LLEditWearableDictionary::PickerControlEntry* entry) const
441        {
442                return (entry && entry->mName == mName);
443        }
444private:
445        const std::string mName;
446} PickerControlEntryNamePredicate;
447
448// A full specialization of get_pickers_indexes for LLColorSwatchCtrl
449template <>
450const texture_vec_t&
451get_pickers_indexes<LLColorSwatchCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
452{
453        if (!wearable_entry)
454        {
455                llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl;
456                return null_texture_vec;
457        }
458        return wearable_entry->mColorSwatchCtrls;
459}
460
461// A full specialization of get_pickers_indexes for LLTextureCtrl
462template <>
463const texture_vec_t&
464get_pickers_indexes<LLTextureCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
465{
466        if (!wearable_entry)
467        {
468                llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl;
469                return null_texture_vec;
470        }
471        return wearable_entry->mTextureCtrls;
472}
473
474// A full specialization of get_picker_entry for LLColorSwatchCtrl
475template <>
476const LLEditWearableDictionary::PickerControlEntry*
477get_picker_entry<LLColorSwatchCtrl> (const ETextureIndex index)
478{
479        return LLEditWearableDictionary::getInstance()->getColorSwatch(index);
480}
481
482// A full specialization of get_picker_entry for LLTextureCtrl
483template <>
484const LLEditWearableDictionary::PickerControlEntry*
485get_picker_entry<LLTextureCtrl> (const ETextureIndex index)
486{
487        return LLEditWearableDictionary::getInstance()->getTexturePicker(index);
488}
489
490template <typename CtrlType, class Predicate>
491const LLEditWearableDictionary::PickerControlEntry*
492find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred)
493{
494        const LLEditWearableDictionary::WearableEntry *wearable_entry
495                = LLEditWearableDictionary::getInstance()->getWearable(type);
496        if (!wearable_entry)
497        {
498                llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
499                return NULL;
500        }
501        const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
502        for (texture_vec_t::const_iterator
503                         iter = indexes.begin(),
504                         iter_end = indexes.end();
505                 iter != iter_end; ++iter)
506        {
507                const ETextureIndex te = *iter;
508                const LLEditWearableDictionary::PickerControlEntry*     entry
509                        = get_picker_entry<CtrlType>(te);
510                if (!entry)
511                {
512                        llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
513                        continue;
514                }
515                if (pred(entry))
516                {
517                        return entry;
518                }
519        }
520        return NULL;
521}
522
523template <typename CtrlType>
524void
525for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun)
526{
527        if (!panel)
528        {
529                llwarns << "the panel wasn't passed for wearable of type: " << type << llendl;
530                return;
531        }
532        const LLEditWearableDictionary::WearableEntry *wearable_entry
533                = LLEditWearableDictionary::getInstance()->getWearable(type);
534        if (!wearable_entry)
535        {
536                llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
537                return;
538        }
539        const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
540        for (texture_vec_t::const_iterator
541                         iter = indexes.begin(),
542                         iter_end = indexes.end();
543                 iter != iter_end; ++iter)
544        {
545                const ETextureIndex te = *iter;
546                const LLEditWearableDictionary::PickerControlEntry*     entry
547                        = get_picker_entry<CtrlType>(te);
548                if (!entry)
549                {
550                        llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
551                        continue;
552                }
553                fun (panel, entry);
554        }
555}
556
557// The helper functions for pickers management
558static void init_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
559{
560        LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
561        if (color_swatch_ctrl)
562        {
563                // Can't get the color from the wearable here, since the wearable may not be set when this is called.
564                color_swatch_ctrl->setOriginal(LLColor4::white);
565        }
566}
567
568static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
569{
570        LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
571        if (texture_ctrl)
572        {
573                texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId);
574                texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
575                // Don't allow (no copy) or (notransfer) textures to be selected.
576                texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
577                texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
578        }
579}
580
581static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
582{
583        LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
584        if (color_swatch_ctrl)
585        {
586                color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex));
587                color_swatch_ctrl->closeFloaterColorPicker();
588        }
589}
590
591static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
592{
593        LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
594        if (texture_ctrl)
595        {
596                LLUUID new_id;
597                LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex);
598                if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) )
599                {
600                        new_id = lto->getID();
601                }
602                else
603                {
604                        new_id = LLUUID::null;
605                }
606                LLUUID old_id = texture_ctrl->getImageAssetID();
607                if (old_id != new_id)
608                {
609                        // texture has changed, close the floater to avoid DEV-22461
610                        texture_ctrl->closeDependentFloater();
611                }
612                texture_ctrl->setImageAssetID(new_id);
613        }
614}
615
616static void set_enabled_color_swatch_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
617{
618        LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
619        if (color_swatch_ctrl)
620        {
621                color_swatch_ctrl->setEnabled(enabled);
622        }
623}
624
625static void set_enabled_texture_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
626{
627        LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
628        if (texture_ctrl)
629        {
630                texture_ctrl->setEnabled(enabled);
631        }
632}
633
634// LLPanelEditWearable
635
636LLPanelEditWearable::LLPanelEditWearable()
637        : LLPanel()
638        , mWearablePtr(NULL)
639        , mWearableItem(NULL)
640{
641        mCommitCallbackRegistrar.add("ColorSwatch.Commit", boost::bind(&LLPanelEditWearable::onColorSwatchCommit, this, _1));
642        mCommitCallbackRegistrar.add("TexturePicker.Commit", boost::bind(&LLPanelEditWearable::onTexturePickerCommit, this, _1));
643}
644
645//virtual
646LLPanelEditWearable::~LLPanelEditWearable()
647{
648
649}
650
651bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value)
652{
653        updateMetricLayout( new_value.asBoolean() );
654        updateTypeSpecificControls(LLWearableType::WT_SHAPE);
655        return true;
656}
657
658void LLPanelEditWearable::updateMetricLayout(BOOL new_value)
659{
660        LLUIString current_metric, replacment_metric;
661        current_metric = new_value ? mMeters : mFeet;
662        replacment_metric = new_value ? mFeet : mMeters;
663        mHeigthValue.setArg( "[METRIC1]", current_metric.getString() );
664        mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]"));
665}
666
667void LLPanelEditWearable::updateAvatarHeightLabel()
668{
669        mTxtAvatarHeight->setText(LLStringUtil::null);
670        LLStyle::Params param;
671        param.color = mAvatarHeigthLabelColor;
672        mTxtAvatarHeight->appendText(mHeigth, false, param);
673        param.color = mAvatarHeigthValueLabelColor;
674        mTxtAvatarHeight->appendText(mHeigthValue, false, param);
675        param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator
676        mTxtAvatarHeight->appendText(" / ", false, param);
677        mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
678}
679
680void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
681{
682        if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
683        {
684                accordion_ctrl->expandDefaultTab();
685        }
686}
687
688void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel)
689{
690        if (bodypart_panel != NULL)
691        {
692                LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion");
693
694                if (accordion_ctrl != NULL)
695                {
696                        bodypart_panel->setVisibleCallback(
697                                        boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl));
698                }
699                else
700                {
701                        llwarns << "accordion_ctrl is NULL" << llendl;
702                }
703        }
704        else
705        {
706                llwarns << "bodypart_panel is NULL" << llendl;
707        }
708}
709
710// virtual 
711BOOL LLPanelEditWearable::postBuild()
712{
713        // buttons
714        mBtnRevert = getChild<LLButton>("revert_button");
715        mBtnRevert->setClickedCallback(boost::bind(&LLPanelEditWearable::onRevertButtonClicked, this));
716
717        mBtnBack = getChild<LLButton>("back_btn");
718        mBackBtnLabel = mBtnBack->getLabelUnselected();
719        mBtnBack->setLabel(LLStringUtil::null);
720        // handled at appearance panel level?
721        //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
722
723        mNameEditor = getChild<LLLineEditor>("description");
724
725        mPanelTitle = getChild<LLTextBox>("edit_wearable_title");
726        mDescTitle = getChild<LLTextBox>("description_text");
727
728        getChild<LLRadioGroup>("sex_radio")->setCommitCallback(boost::bind(&LLPanelEditWearable::onCommitSexChange, this));
729        getChild<LLButton>("save_as_button")->setCommitCallback(boost::bind(&LLPanelEditWearable::onSaveAsButtonClicked, this));
730
731        // The following panels will be shown/hidden based on what wearable we're editing
732        // body parts
733        mPanelShape = getChild<LLPanel>("edit_shape_panel");
734        mPanelSkin = getChild<LLPanel>("edit_skin_panel");
735        mPanelEyes = getChild<LLPanel>("edit_eyes_panel");
736        mPanelHair = getChild<LLPanel>("edit_hair_panel");
737
738        // Setting the visibility callback is applied only to the bodyparts panel
739        // because currently they are the only ones whose 'wearable_accordion' has
740        // multiple accordion tabs (see EXT-8164 for details).
741        setWearablePanelVisibilityChangeCallback(mPanelShape);
742        setWearablePanelVisibilityChangeCallback(mPanelSkin);
743        setWearablePanelVisibilityChangeCallback(mPanelEyes);
744        setWearablePanelVisibilityChangeCallback(mPanelHair);
745
746        //clothes
747        mPanelShirt = getChild<LLPanel>("edit_shirt_panel");
748        mPanelPants = getChild<LLPanel>("edit_pants_panel");
749        mPanelShoes = getChild<LLPanel>("edit_shoes_panel");
750        mPanelSocks = getChild<LLPanel>("edit_socks_panel");
751        mPanelJacket = getChild<LLPanel>("edit_jacket_panel");
752        mPanelGloves = getChild<LLPanel>("edit_gloves_panel");
753        mPanelUndershirt = getChild<LLPanel>("edit_undershirt_panel");
754        mPanelUnderpants = getChild<LLPanel>("edit_underpants_panel");
755        mPanelSkirt = getChild<LLPanel>("edit_skirt_panel");
756        mPanelAlpha = getChild<LLPanel>("edit_alpha_panel");
757        mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel");
758        mPanelPhysics = getChild<LLPanel>("edit_physics_panel");
759
760        mTxtAvatarHeight = mPanelShape->getChild<LLTextBox>("avatar_height");
761
762        mWearablePtr = NULL;
763
764        configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
765        configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
766        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
767        configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
768        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
769
770        // configure tab expanded callbacks
771        for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index)
772        {
773                LLWearableType::EType type = (LLWearableType::EType) type_index;
774                const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
775                if (!wearable_entry)
776                {
777                        llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
778                        continue;
779                }
780                U8 num_subparts = wearable_entry->mSubparts.size();
781        
782                for (U8 index = 0; index < num_subparts; ++index)
783                {
784                        // dive into data structures to get the panel we need
785                        ESubpart subpart_e = wearable_entry->mSubparts[index];
786                        const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
787        
788                        if (!subpart_entry)
789                        {
790                                llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl;
791                                continue;
792                        }
793        
794                        const std::string accordion_tab = subpart_entry->mAccordionTab;
795        
796                        LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab);
797        
798                        if (!tab)
799                        {
800                                llwarns << "could not get llaccordionctrltab from UI with name: " << accordion_tab << llendl;
801                                continue;
802                        }
803        
804                        // initialize callback to ensure camera view changes appropriately.
805                        tab->setDropDownStateChangedCallback(boost::bind(&LLPanelEditWearable::onTabExpandedCollapsed,this,_2,index));
806                }
807
808                // initialize texture and color picker controls
809                for_each_picker_ctrl_entry <LLColorSwatchCtrl> (getPanel(type), type, boost::bind(init_color_swatch_ctrl, this, _1, _2));
810                for_each_picker_ctrl_entry <LLTextureCtrl>     (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2));
811        }
812
813        // init all strings
814        mMeters         = mPanelShape->getString("meters");
815        mFeet           = mPanelShape->getString("feet");
816        mHeigth         = mPanelShape->getString("height") + " ";
817        mHeigthValue    = "[HEIGHT] [METRIC1]";
818        mReplacementMetricUrl   = "[URL_METRIC2]";
819
820        std::string color = mPanelShape->getString("heigth_label_color");
821        mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
822        color = mPanelShape->getString("heigth_value_label_color");
823        mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green);
824        gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2));
825        updateMetricLayout(gSavedSettings.getBOOL("HeightUnits"));
826
827        return TRUE;
828}
829
830// virtual 
831// LLUICtrl
832BOOL LLPanelEditWearable::isDirty() const
833{
834        BOOL isDirty = FALSE;
835        if (mWearablePtr)
836        {
837                if (mWearablePtr->isDirty() ||
838                        mWearableItem->getName().compare(mNameEditor->getText()) != 0)
839                {
840                        isDirty = TRUE;
841                }
842        }
843        return isDirty;
844}
845//virtual
846void LLPanelEditWearable::draw()
847{
848        updateVerbs();
849        if (getWearable() && getWearable()->getType() == LLWearableType::WT_SHAPE)
850        {
851                //updating avatar height
852                updateTypeSpecificControls(LLWearableType::WT_SHAPE);
853        }
854
855        LLPanel::draw();
856}
857
858void LLPanelEditWearable::setVisible(BOOL visible)
859{
860        if (!visible)
861        {
862                showWearable(mWearablePtr, FALSE);
863        }
864        LLPanel::setVisible(visible);
865}
866
867void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
868{
869        showWearable(mWearablePtr, FALSE, disable_camera_switch);
870        mWearablePtr = wearable;
871        showWearable(mWearablePtr, TRUE, disable_camera_switch);
872}
873
874
875//static 
876void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
877{
878        LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
879        panel->revertChanges();
880}
881
882void LLPanelEditWearable::onSaveAsButtonClicked()
883{
884        LLSD args;
885        args["DESC"] = mNameEditor->getText();
886
887        LLNotificationsUtil::add("SaveWearableAs", args, LLSD(), boost::bind(&LLPanelEditWearable::saveAsCallback, this, _1, _2));
888}
889
890void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& response)
891{
892        S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
893        if (0 == option)
894        {
895                std::string wearable_name = response["message"].asString();
896                LLStringUtil::trim(wearable_name);
897                if( !wearable_name.empty() )
898                {
899                        mNameEditor->setText(wearable_name);
900                        saveChanges(true);
901                }
902        }
903}
904
905void LLPanelEditWearable::onCommitSexChange()
906{
907        if (!isAgentAvatarValid()) return;
908
909        LLWearableType::EType type = mWearablePtr->getType();
910        U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
911
912        if( !gAgentWearables.isWearableModifiable(type, index))
913        {
914                return;
915        }
916
917        LLViewerVisualParam* param = static_cast<LLViewerVisualParam*>(gAgentAvatarp->getVisualParam( "male" ));
918        if( !param )
919        {
920                return;
921        }
922
923        bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
924        LLWearable*     wearable = gAgentWearables.getWearable(type, index);
925        if (wearable)
926        {
927                wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE);
928        }
929        param->setWeight( is_new_sex_male, FALSE );
930
931        gAgentAvatarp->updateSexDependentLayerSets( FALSE );
932
933        gAgentAvatarp->updateVisualParams();
934
935        updateScrollingPanelUI();
936}
937
938void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
939{
940        const LLTextureCtrl* texture_ctrl = dynamic_cast<const LLTextureCtrl*>(ctrl);
941        if (!texture_ctrl)
942        {
943                llwarns << "got commit signal from not LLTextureCtrl." << llendl;
944                return;
945        }
946
947        if (getWearable())
948        {
949                LLWearableType::EType type = getWearable()->getType();
950                const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName());
951                const LLEditWearableDictionary::PickerControlEntry* entry
952                        = find_picker_ctrl_entry_if<LLTextureCtrl, PickerControlEntryNamePredicate>(type, name_pred);
953                if (entry)
954                {
955                        // Set the new version
956                        LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
957                        if( image->getID() == IMG_DEFAULT )
958                        {
959                                image = LLViewer

Large files files are truncated, but you can click here to view the full file