diff options
Diffstat (limited to 'indra/newview/llpaneleditwearable.cpp')
-rw-r--r-- | indra/newview/llpaneleditwearable.cpp | 460 |
1 files changed, 443 insertions, 17 deletions
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index da74295f9e..3c112b8b5e 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 @@ -110,14 +118,17 @@ public: WearableEntry(EWearableType 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 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> @@ -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)); + addEntry(WT_SHAPE, new WearableEntry(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(WT_SKIN, new WearableEntry(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(WT_HAIR, new WearableEntry(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(WT_EYES, new WearableEntry(WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES)); + addEntry(WT_SHIRT, new WearableEntry(WT_SHIRT,"edit_shirt_title","shirt_desc_text",1,1,1, TEX_UPPER_SHIRT, TEX_UPPER_SHIRT, SUBPART_SHIRT)); + addEntry(WT_PANTS, new WearableEntry(WT_PANTS,"edit_pants_title","pants_desc_text",1,1,1, TEX_LOWER_PANTS, TEX_LOWER_PANTS, SUBPART_PANTS)); + addEntry(WT_SHOES, new WearableEntry(WT_SHOES,"edit_shoes_title","shoes_desc_text",1,1,1, TEX_LOWER_SHOES, TEX_LOWER_SHOES, SUBPART_SHOES)); + addEntry(WT_SOCKS, new WearableEntry(WT_SOCKS,"edit_socks_title","socks_desc_text",1,1,1, TEX_LOWER_SOCKS, TEX_LOWER_SOCKS, SUBPART_SOCKS)); + addEntry(WT_JACKET, new WearableEntry(WT_JACKET,"edit_jacket_title","jacket_desc_text",1,2,1, TEX_UPPER_JACKET, TEX_UPPER_JACKET, TEX_LOWER_JACKET, SUBPART_JACKET)); + addEntry(WT_GLOVES, new WearableEntry(WT_GLOVES,"edit_gloves_title","gloves_desc_text",1,1,1, TEX_UPPER_GLOVES, TEX_UPPER_GLOVES, SUBPART_GLOVES)); + addEntry(WT_UNDERSHIRT, new WearableEntry(WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1,1,1, TEX_UPPER_UNDERSHIRT, TEX_UPPER_UNDERSHIRT, SUBPART_UNDERSHIRT)); + addEntry(WT_UNDERPANTS, new WearableEntry(WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS)); + addEntry(WT_SKIRT, new WearableEntry(WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT)); + addEntry(WT_ALPHA, new WearableEntry(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(WT_TATTOO, new WearableEntry(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(EWearableType 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(EWearableType 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, EWearableType 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 @@ -341,6 +659,10 @@ BOOL LLPanelEditWearable::isDirty() const void LLPanelEditWearable::draw() { updateVerbs(); + if (getWearable()) + { + updatePanelPickerControls(getWearable()->getType()); + } LLPanel::draw(); } @@ -361,6 +683,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()) + { + EWearableType 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()) + { + EWearableType 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(EWearableType 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() { @@ -428,6 +846,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() @@ -493,6 +914,11 @@ 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(); } |