summaryrefslogtreecommitdiff
path: root/indra/newview/llpaneleditwearable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpaneleditwearable.cpp')
-rw-r--r--indra/newview/llpaneleditwearable.cpp541
1 files changed, 498 insertions, 43 deletions
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index da74295f9e..557fb399be 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -51,6 +51,12 @@
#include "llagentwearables.h"
#include "llscrollingpanelparam.h"
+#include "llcolorswatch.h"
+#include "lltexturectrl.h"
+#include "lltextureentry.h"
+#include "llviewercontrol.h" // gSavedSettings
+#include "llviewertexturelist.h"
+
// register panel with appropriate XML
static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
@@ -88,6 +94,8 @@ enum ESubpart {
SUBPART_TATTOO
};
+using namespace LLVOAvatarDefines;
+
typedef std::vector<ESubpart> subpart_vec_t;
// Locally defined classes
@@ -107,25 +115,28 @@ public:
public:
struct WearableEntry : public LLDictionaryEntry
{
- WearableEntry(EWearableType type,
+ WearableEntry(LLWearableType::EType type,
const std::string &title,
const std::string &desc_title,
- U8 num_subparts, ... ); // number of subparts followed by a list of ESubparts
+ U8 num_color_swatches, // number of 'color_swatches'
+ U8 num_texture_pickers, // number of 'texture_pickers'
+ U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts
- const EWearableType mWearableType;
+ const LLWearableType::EType mWearableType;
const std::string mTitle;
const std::string mDescTitle;
subpart_vec_t mSubparts;
-
+ texture_vec_t mColorSwatchCtrls;
+ texture_vec_t mTextureCtrls;
};
- struct Wearables : public LLDictionary<EWearableType, WearableEntry>
+ struct Wearables : public LLDictionary<LLWearableType::EType, WearableEntry>
{
Wearables();
} mWearables;
- const WearableEntry* getWearable(EWearableType type) const { return mWearables.lookup(type); }
+ const WearableEntry* getWearable(LLWearableType::EType type) const { return mWearables.lookup(type); }
//--------------------------------------------------------------------
// Subparts
@@ -158,6 +169,35 @@ public:
} mSubparts;
const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); }
+
+ //--------------------------------------------------------------------
+ // Picker Control Entries
+ //--------------------------------------------------------------------
+public:
+ struct PickerControlEntry : public LLDictionaryEntry
+ {
+ PickerControlEntry(ETextureIndex tex_index,
+ const std::string name,
+ const LLUUID default_image_id = LLUUID::null,
+ const bool allow_no_texture = false);
+ ETextureIndex mTextureIndex;
+ const std::string mControlName;
+ const LLUUID mDefaultImageId;
+ const bool mAllowNoTexture;
+ };
+
+ struct ColorSwatchCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
+ {
+ ColorSwatchCtrls();
+ } mColorSwatchCtrls;
+
+ struct TextureCtrls : public LLDictionary<ETextureIndex, PickerControlEntry>
+ {
+ TextureCtrls();
+ } mTextureCtrls;
+
+ const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); }
+ const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); }
};
LLEditWearableDictionary::LLEditWearableDictionary()
@@ -172,26 +212,28 @@ LLEditWearableDictionary::~LLEditWearableDictionary()
LLEditWearableDictionary::Wearables::Wearables()
{
- addEntry(WT_SHAPE, new WearableEntry(WT_SHAPE,"edit_shape_title","shape_desc_text",9, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_WHOLE));
- addEntry(WT_SKIN, new WearableEntry(WT_SKIN,"edit_skin_title","skin_desc_text",4, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL));
- addEntry(WT_HAIR, new WearableEntry(WT_HAIR,"edit_hair_title","hair_desc_text",4, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL));
- addEntry(WT_EYES, new WearableEntry(WT_EYES,"edit_eyes_title","eyes_desc_text",1, SUBPART_EYES));
- addEntry(WT_SHIRT, new WearableEntry(WT_SHIRT,"edit_shirt_title","shirt_desc_text",1, SUBPART_SHIRT));
- addEntry(WT_PANTS, new WearableEntry(WT_PANTS,"edit_pants_title","pants_desc_text",1, SUBPART_PANTS));
- addEntry(WT_SHOES, new WearableEntry(WT_SHOES,"edit_shoes_title","shoes_desc_text",1, SUBPART_SHOES));
- addEntry(WT_SOCKS, new WearableEntry(WT_SOCKS,"edit_socks_title","socks_desc_text",1, SUBPART_SOCKS));
- addEntry(WT_JACKET, new WearableEntry(WT_JACKET,"edit_jacket_title","jacket_desc_text",1, SUBPART_JACKET));
- addEntry(WT_GLOVES, new WearableEntry(WT_GLOVES,"edit_gloves_title","gloves_desc_text",1, SUBPART_GLOVES));
- addEntry(WT_UNDERSHIRT, new WearableEntry(WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1, SUBPART_UNDERSHIRT));
- addEntry(WT_UNDERPANTS, new WearableEntry(WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1, SUBPART_UNDERPANTS));
- addEntry(WT_SKIRT, new WearableEntry(WT_SKIRT,"edit_skirt_title","skirt_desc_text",1, SUBPART_SKIRT));
- addEntry(WT_ALPHA, new WearableEntry(WT_ALPHA,"edit_alpha_title","alpha_desc_text",1, SUBPART_ALPHA));
- addEntry(WT_TATTOO, new WearableEntry(WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",1, SUBPART_TATTOO));
-}
-
-LLEditWearableDictionary::WearableEntry::WearableEntry(EWearableType type,
+ addEntry(LLWearableType::WT_SHAPE, new WearableEntry(LLWearableType::WT_SHAPE,"edit_shape_title","shape_desc_text",0,0,9, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_WHOLE));
+ 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));
+ 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));
+ addEntry(LLWearableType::WT_EYES, new WearableEntry(LLWearableType::WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES));
+ 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));
+ 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));
+ 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));
+ 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));
+ 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));
+ 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));
+ 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));
+ 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));
+ addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT));
+ 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));
+ addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",0,3,1, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO));
+}
+
+LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type,
const std::string &title,
const std::string &desc_title,
+ U8 num_color_swatches,
+ U8 num_texture_pickers,
U8 num_subparts, ... ) :
LLDictionaryEntry(title),
mWearableType(type),
@@ -201,6 +243,18 @@ LLEditWearableDictionary::WearableEntry::WearableEntry(EWearableType type,
va_list argp;
va_start(argp, num_subparts);
+ for (U8 i = 0; i < num_color_swatches; ++i)
+ {
+ ETextureIndex index = (ETextureIndex)va_arg(argp,int);
+ mColorSwatchCtrls.push_back(index);
+ }
+
+ for (U8 i = 0; i < num_texture_pickers; ++i)
+ {
+ ETextureIndex index = (ETextureIndex)va_arg(argp,int);
+ mTextureCtrls.push_back(index);
+ }
+
for (U8 i = 0; i < num_subparts; ++i)
{
ESubpart part = (ESubpart)va_arg(argp,int);
@@ -265,6 +319,268 @@ LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part,
{
}
+LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls()
+{
+ addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" ));
+ addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" ));
+ addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" ));
+ addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" ));
+ addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" ));
+ addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" ));
+ addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" ));
+ addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" ));
+ addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" ));
+}
+
+LLEditWearableDictionary::TextureCtrls::TextureCtrls()
+{
+ addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE ));
+ addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Tattoos", LLUUID::null, TRUE ));
+ addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Tattoos", LLUUID::null, TRUE ));
+ addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE ));
+ addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE ));
+ addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE ));
+ addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE ));
+ addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE ));
+ addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE ));
+ addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE ));
+ addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
+ addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
+ addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
+ addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
+ addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE ));
+ addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE ));
+ addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE ));
+ addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE ));
+}
+
+LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index,
+ const std::string name,
+ const LLUUID default_image_id,
+ const bool allow_no_texture) :
+ LLDictionaryEntry(name),
+ mTextureIndex(tex_index),
+ mControlName(name),
+ mDefaultImageId(default_image_id),
+ mAllowNoTexture(allow_no_texture)
+{
+}
+
+// Helper functions.
+static const texture_vec_t null_texture_vec;
+
+// Specializations of this template function return a vector of texture indexes of particular control type
+// (i.e. LLColorSwatchCtrl or LLTextureCtrl) which are contained in given WearableEntry.
+template <typename T>
+const texture_vec_t&
+get_pickers_indexes(const LLEditWearableDictionary::WearableEntry *wearable_entry) { return null_texture_vec; }
+
+// Specializations of this template function return picker control entry for particular control type.
+template <typename T>
+const LLEditWearableDictionary::PickerControlEntry*
+get_picker_entry (const ETextureIndex index) { return NULL; }
+
+typedef boost::function<void(LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry*)> function_t;
+
+typedef struct PickerControlEntryNamePredicate
+{
+ PickerControlEntryNamePredicate(const std::string name) : mName (name) {};
+ bool operator()(const LLEditWearableDictionary::PickerControlEntry* entry) const
+ {
+ return (entry && entry->mName == mName);
+ }
+private:
+ const std::string mName;
+} PickerControlEntryNamePredicate;
+
+// A full specialization of get_pickers_indexes for LLColorSwatchCtrl
+template <>
+const texture_vec_t&
+get_pickers_indexes<LLColorSwatchCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
+{
+ if (!wearable_entry)
+ {
+ llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl;
+ return null_texture_vec;
+ }
+ return wearable_entry->mColorSwatchCtrls;
+}
+
+// A full specialization of get_pickers_indexes for LLTextureCtrl
+template <>
+const texture_vec_t&
+get_pickers_indexes<LLTextureCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry)
+{
+ if (!wearable_entry)
+ {
+ llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl;
+ return null_texture_vec;
+ }
+ return wearable_entry->mTextureCtrls;
+}
+
+// A full specialization of get_picker_entry for LLColorSwatchCtrl
+template <>
+const LLEditWearableDictionary::PickerControlEntry*
+get_picker_entry<LLColorSwatchCtrl> (const ETextureIndex index)
+{
+ return LLEditWearableDictionary::getInstance()->getColorSwatch(index);
+}
+
+// A full specialization of get_picker_entry for LLTextureCtrl
+template <>
+const LLEditWearableDictionary::PickerControlEntry*
+get_picker_entry<LLTextureCtrl> (const ETextureIndex index)
+{
+ return LLEditWearableDictionary::getInstance()->getTexturePicker(index);
+}
+
+template <typename CtrlType, class Predicate>
+const LLEditWearableDictionary::PickerControlEntry*
+find_picker_ctrl_entry_if(LLWearableType::EType type, const Predicate pred)
+{
+ const LLEditWearableDictionary::WearableEntry *wearable_entry
+ = LLEditWearableDictionary::getInstance()->getWearable(type);
+ if (!wearable_entry)
+ {
+ llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
+ return NULL;
+ }
+ const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
+ for (texture_vec_t::const_iterator
+ iter = indexes.begin(),
+ iter_end = indexes.end();
+ iter != iter_end; ++iter)
+ {
+ const ETextureIndex te = *iter;
+ const LLEditWearableDictionary::PickerControlEntry* entry
+ = get_picker_entry<CtrlType>(te);
+ if (!entry)
+ {
+ llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
+ continue;
+ }
+ if (pred(entry))
+ {
+ return entry;
+ }
+ }
+ return NULL;
+}
+
+template <typename CtrlType>
+void
+for_each_picker_ctrl_entry(LLPanel* panel, LLWearableType::EType type, function_t fun)
+{
+ if (!panel)
+ {
+ llwarns << "the panel wasn't passed for wearable of type: " << type << llendl;
+ return;
+ }
+ const LLEditWearableDictionary::WearableEntry *wearable_entry
+ = LLEditWearableDictionary::getInstance()->getWearable(type);
+ if (!wearable_entry)
+ {
+ llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl;
+ return;
+ }
+ const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry);
+ for (texture_vec_t::const_iterator
+ iter = indexes.begin(),
+ iter_end = indexes.end();
+ iter != iter_end; ++iter)
+ {
+ const ETextureIndex te = *iter;
+ const LLEditWearableDictionary::PickerControlEntry* entry
+ = get_picker_entry<CtrlType>(te);
+ if (!entry)
+ {
+ llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl;
+ continue;
+ }
+ fun (panel, entry);
+ }
+}
+
+// The helper functions for pickers management
+static void init_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
+ if (color_swatch_ctrl)
+ {
+ color_swatch_ctrl->setOriginal(self->getWearable()->getClothesColor(entry->mTextureIndex));
+ }
+}
+
+static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
+ if (texture_ctrl)
+ {
+ texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId);
+ texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
+ // Don't allow (no copy) or (notransfer) textures to be selected.
+ texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
+ }
+}
+
+static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
+ if (color_swatch_ctrl)
+ {
+ color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex));
+ }
+}
+
+static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
+ if (texture_ctrl)
+ {
+ LLUUID new_id;
+ LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex);
+ if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) )
+ {
+ new_id = lto->getID();
+ }
+ else
+ {
+ new_id = LLUUID::null;
+ }
+ LLUUID old_id = texture_ctrl->getImageAssetID();
+ if (old_id != new_id)
+ {
+ // texture has changed, close the floater to avoid DEV-22461
+ texture_ctrl->closeDependentFloater();
+ }
+ texture_ctrl->setImageAssetID(new_id);
+ }
+}
+
+static void set_enabled_color_swatch_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName);
+ if (color_swatch_ctrl)
+ {
+ color_swatch_ctrl->setEnabled(enabled);
+ }
+}
+
+static void set_enabled_texture_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry)
+{
+ LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName);
+ if (texture_ctrl)
+ {
+ texture_ctrl->setEnabled(enabled);
+ }
+}
// LLPanelEditWearable
@@ -273,6 +589,8 @@ LLPanelEditWearable::LLPanelEditWearable()
, mWearablePtr(NULL)
, mWearableItem(NULL)
{
+ mCommitCallbackRegistrar.add("ColorSwatch.Commit", boost::bind(&LLPanelEditWearable::onColorSwatchCommit, this, _1));
+ mCommitCallbackRegistrar.add("TexturePicker.Commit", boost::bind(&LLPanelEditWearable::onTexturePickerCommit, this, _1));
}
//virtual
@@ -317,6 +635,8 @@ BOOL LLPanelEditWearable::postBuild()
mPanelAlpha = getChild<LLPanel>("edit_alpha_panel");
mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel");
+ mTxtAvatarHeight = mPanelShape->getChild<LLTextBox>("avatar_height");
+
mWearablePtr = NULL;
return TRUE;
@@ -341,6 +661,12 @@ BOOL LLPanelEditWearable::isDirty() const
void LLPanelEditWearable::draw()
{
updateVerbs();
+ if (getWearable())
+ {
+ LLWearableType::EType type = getWearable()->getType();
+ updatePanelPickerControls(type);
+ updateTypeSpecificControls(type);
+ }
LLPanel::draw();
}
@@ -361,6 +687,102 @@ void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
panel->revertChanges();
}
+void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
+{
+ const LLTextureCtrl* texture_ctrl = dynamic_cast<const LLTextureCtrl*>(ctrl);
+ if (!texture_ctrl)
+ {
+ llwarns << "got commit signal from not LLTextureCtrl." << llendl;
+ return;
+ }
+
+ if (getWearable())
+ {
+ LLWearableType::EType type = getWearable()->getType();
+ const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName());
+ const LLEditWearableDictionary::PickerControlEntry* entry
+ = find_picker_ctrl_entry_if<LLTextureCtrl, PickerControlEntryNamePredicate>(type, name_pred);
+ if (entry)
+ {
+ // Set the new version
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
+ if( image->getID().isNull() )
+ {
+ image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
+ }
+ if (getWearable())
+ {
+ U32 index = gAgentWearables.getWearableIndex(getWearable());
+ gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index);
+ LLVisualParamHint::requestHintUpdates();
+ gAgentAvatarp->wearableUpdated(type, FALSE);
+ }
+ }
+ else
+ {
+ llwarns << "could not get texture picker dictionary entry for wearable of type: " << type << llendl;
+ }
+ }
+}
+
+void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* ctrl)
+{
+ if (getWearable())
+ {
+ LLWearableType::EType type = getWearable()->getType();
+ const PickerControlEntryNamePredicate name_pred(ctrl->getName());
+ const LLEditWearableDictionary::PickerControlEntry* entry
+ = find_picker_ctrl_entry_if<LLColorSwatchCtrl, PickerControlEntryNamePredicate>(type, name_pred);
+ if (entry)
+ {
+ const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex);
+ const LLColor4& new_color = LLColor4(ctrl->getValue());
+ if( old_color != new_color )
+ {
+ getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE);
+ LLVisualParamHint::requestHintUpdates();
+ gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
+ }
+ }
+ else
+ {
+ llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl;
+ }
+ }
+}
+
+void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
+{
+ LLPanel* panel = getPanel(type);
+ if (!panel)
+ return;
+
+ bool is_modifiable = false;
+ bool is_complete = false;
+ bool is_copyable = false;
+
+ if(mWearableItem)
+ {
+ const LLPermissions& perm = mWearableItem->getPermissions();
+ is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
+ is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());
+ is_complete = mWearableItem->isFinished();
+ }
+
+ if (is_modifiable && is_complete)
+ {
+ // Update picker controls
+ for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(update_color_swatch_ctrl, this, _1, _2));
+ for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(update_texture_ctrl, this, _1, _2));
+ }
+
+ if (!is_modifiable || !is_complete || !is_copyable)
+ {
+ // Disable controls
+ for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(set_enabled_color_swatch_ctrl, false, _1, _2));
+ for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(set_enabled_texture_ctrl, false, _1, _2));
+ }
+}
void LLPanelEditWearable::saveChanges()
{
@@ -405,7 +827,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
mWearableItem = gInventory.getItem(mWearablePtr->getItemID());
llassert(mWearableItem);
- EWearableType type = wearable->getType();
+ LLWearableType::EType type = wearable->getType();
LLPanel *targetPanel = NULL;
std::string title;
std::string description_title;
@@ -428,6 +850,9 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
mDescTitle->setText(description_title);
}
+ // Update picker controls state
+ for_each_picker_ctrl_entry <LLColorSwatchCtrl> (targetPanel, type, boost::bind(set_enabled_color_swatch_ctrl, show, _1, _2));
+ for_each_picker_ctrl_entry <LLTextureCtrl> (targetPanel, type, boost::bind(set_enabled_texture_ctrl, show, _1, _2));
}
void LLPanelEditWearable::initializePanel()
@@ -438,11 +863,14 @@ void LLPanelEditWearable::initializePanel()
return;
}
- EWearableType type = mWearablePtr->getType();
+ LLWearableType::EType type = mWearablePtr->getType();
// set name
mTextEditor->setText(mWearablePtr->getName());
+ // toggle wearable type-specific controls
+ toggleTypeSpecificControls(type);
+
// clear and rebuild visual param list
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
if (!wearable_entry)
@@ -493,9 +921,36 @@ void LLPanelEditWearable::initializePanel()
updateScrollingPanelUI();
}
+
+ // initialize texture and color picker controls
+ for_each_picker_ctrl_entry <LLColorSwatchCtrl> (getPanel(type), type, boost::bind(init_color_swatch_ctrl, this, _1, _2));
+ for_each_picker_ctrl_entry <LLTextureCtrl> (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2));
+
updateVerbs();
}
+void LLPanelEditWearable::toggleTypeSpecificControls(LLWearableType::EType type)
+{
+ // Toggle controls specific to shape editing panel.
+ {
+ bool is_shape = (type == LLWearableType::WT_SHAPE);
+ childSetVisible("sex_radio", is_shape);
+ childSetVisible("female_icon", is_shape);
+ childSetVisible("male_icon", is_shape);
+ }
+}
+
+void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)
+{
+ // Update controls specific to shape editing panel.
+ if (type == LLWearableType::WT_SHAPE)
+ {
+ // Update avatar height
+ std::string avatar_height_str = llformat("%.2f", gAgentAvatarp->mBodySize.mV[VZ]);
+ mTxtAvatarHeight->setTextArg("[HEIGHT]", avatar_height_str);
+ }
+}
+
void LLPanelEditWearable::updateScrollingPanelUI()
{
// do nothing if we don't have a valid wearable we're editing
@@ -504,7 +959,7 @@ void LLPanelEditWearable::updateScrollingPanelUI()
return;
}
- EWearableType type = mWearablePtr->getType();
+ LLWearableType::EType type = mWearablePtr->getType();
LLPanel *panel = getPanel(type);
if(panel && (mWearablePtr->getItemID().notNull()))
@@ -534,67 +989,67 @@ void LLPanelEditWearable::updateScrollingPanelUI()
}
}
-LLPanel* LLPanelEditWearable::getPanel(EWearableType type)
+LLPanel* LLPanelEditWearable::getPanel(LLWearableType::EType type)
{
switch (type)
{
- case WT_SHAPE:
+ case LLWearableType::WT_SHAPE:
return mPanelShape;
break;
- case WT_SKIN:
+ case LLWearableType::WT_SKIN:
return mPanelSkin;
break;
- case WT_HAIR:
+ case LLWearableType::WT_HAIR:
return mPanelHair;
break;
- case WT_EYES:
+ case LLWearableType::WT_EYES:
return mPanelEyes;
break;
- case WT_SHIRT:
+ case LLWearableType::WT_SHIRT:
return mPanelShirt;
break;
- case WT_PANTS:
+ case LLWearableType::WT_PANTS:
return mPanelPants;
break;
- case WT_SHOES:
+ case LLWearableType::WT_SHOES:
return mPanelShoes;
break;
- case WT_SOCKS:
+ case LLWearableType::WT_SOCKS:
return mPanelSocks;
break;
- case WT_JACKET:
+ case LLWearableType::WT_JACKET:
return mPanelJacket;
break;
- case WT_GLOVES:
+ case LLWearableType::WT_GLOVES:
return mPanelGloves;
break;
- case WT_UNDERSHIRT:
+ case LLWearableType::WT_UNDERSHIRT:
return mPanelUndershirt;
break;
- case WT_UNDERPANTS:
+ case LLWearableType::WT_UNDERPANTS:
return mPanelUnderpants;
break;
- case WT_SKIRT:
+ case LLWearableType::WT_SKIRT:
return mPanelSkirt;
break;
- case WT_ALPHA:
+ case LLWearableType::WT_ALPHA:
return mPanelAlpha;
break;
- case WT_TATTOO:
+ case LLWearableType::WT_TATTOO:
return mPanelTattoo;
break;
default: