12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259 |
- /**
- * @file llpaneleditwearable.cpp
- * @brief A LLPanel dedicated to the editing of wearables.
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llpaneleditwearable.h"
- #include "imageids.h"
- #include "llbutton.h"
- #include "llcheckboxctrl.h"
- #include "lliconctrl.h"
- #include "llnotifications.h"
- #include "llspinctrl.h"
- #include "lltextbox.h"
- #include "lluictrlfactory.h"
- #include "llvisualparam.h"
- #include "llxmltree.h"
- #include "llagent.h"
- #include "llagentwearables.h"
- #include "llappearancemgr.h"
- #include "llcolorswatch.h"
- #include "llfloatercustomize.h"
- #include "llinventoryicon.h"
- #include "llmorphview.h"
- #include "lltexturectrl.h"
- #include "llviewercontrol.h"
- #include "llviewerinventory.h"
- #include "llvisualparamhint.h"
- #include "llwearablelist.h"
- using namespace LLAvatarAppearanceDefines;
- LLPanelEditWearable::LLPanelEditWearable(LLWearableType::EType type)
- : LLPanel(LLWearableType::getTypeLabel(type)),
- mType(type),
- mLayer(0), // Use the first layer by default
- mSpinLayer(NULL),
- mButtonImport(NULL),
- mButtonCreateNew(NULL),
- mButtonSave(NULL),
- mButtonSaveAs(NULL),
- mButtonRevert(NULL),
- mButtonTakeOff(NULL),
- mSexRadio(NULL),
- mLockIcon(NULL),
- mWearableIcon(NULL),
- mNotWornInstructions(NULL),
- mNoModifyInstructions(NULL),
- mTitle(NULL),
- mTitleNoModify(NULL),
- mTitleNotWorn(NULL),
- mTitleLoading(NULL),
- mPath(NULL)
- {
- mWearable = gAgentWearables.getViewerWearable(type, mLayer);
- }
- bool LLPanelEditWearable::postBuild()
- {
- mSpinLayer = getChild<LLSpinCtrl>("layer", true, false);
- if (mSpinLayer)
- {
- if ((gSavedSettings.getBool("NoMultiplePhysics") &&
- mType == LLWearableType::WT_PHYSICS) ||
- (gSavedSettings.getBool("NoMultipleShoes") &&
- mType == LLWearableType::WT_SHOES) ||
- (gSavedSettings.getBool("NoMultipleSkirts") &&
- mType == LLWearableType::WT_SKIRT))
- {
- mSpinLayer->setVisible(false);
- mSpinLayer = NULL;
- }
- else
- {
- setMaxLayers();
- mSpinLayer->set((F32)mLayer);
- mSpinLayer->setCommitCallback(onCommitLayer);
- mSpinLayer->setCallbackUserData(this);
- }
- }
- mLockIcon = getChild<LLIconCtrl>("lock", true, false);
- mWearableIcon = getChild<LLIconCtrl>("icon", true, false);
- if (mWearableIcon)
- {
- LLAssetType::EType asset_type = LLWearableType::getAssetType(mType);
- std::string icon_name =
- LLInventoryIcon::getIconName(asset_type,
- LLInventoryType::IT_WEARABLE,
- mType, false);
- mWearableIcon->setValue(icon_name);
- }
- mNotWornInstructions = getChild<LLTextBox>("not worn instructions",
- true, false);
- mNoModifyInstructions = getChild<LLTextBox>("no modify instructions",
- true, false);
- mTitle = getChild<LLTextBox>("title", true, false);
- mTitleNoModify = getChild<LLTextBox>("title_no_modify", true, false);
- mTitleNotWorn = getChild<LLTextBox>("title_not_worn", true, false);
- mTitleLoading = getChild<LLTextBox>("title_loading", true, false);
- mPath = getChild<LLTextBox>("path", true, false);
- mButtonImport = getChild<LLButton>("import", true, false);
- if (mButtonImport)
- {
- mButtonImport->setClickedCallback(onBtnImport, this);
- }
- mButtonCreateNew = getChild<LLButton>("Create New", true, false);
- if (mButtonCreateNew)
- {
- mButtonCreateNew->setClickedCallback(onBtnCreateNew, this);
- }
- // If PG, cannot take off underclothing or shirt
- mCanTakeOff = LLWearableType::getAssetType(mType) ==
- LLAssetType::AT_CLOTHING;
- #if LL_TEEN_WERABLE_RESTRICTIONS
-
- mCanTakeOff &= !(gAgent.isTeen() &&
- (mType == LLWearableType::WT_UNDERSHIRT ||
- mType == LLWearableType::WT_UNDERPANTS));
- #endif
- mButtonTakeOff = getChild<LLButton>("Take Off", true, false);
- if (mButtonTakeOff)
- {
- mButtonTakeOff->setVisible(mCanTakeOff);
- mButtonTakeOff->setClickedCallback(onBtnTakeOff, this);
- }
- mButtonSave = getChild<LLButton>("Save", true, false);
- if (mButtonSave)
- {
- mButtonSave->setClickedCallback(onBtnSave, this);
- }
- mButtonSaveAs = getChild<LLButton>("Save As", true, false);
- if (mButtonSaveAs)
- {
- mButtonSaveAs->setClickedCallback(onBtnSaveAs, this);
- }
- mButtonRevert = getChild<LLButton>("Revert", true, false);
- if (mButtonRevert)
- {
- mButtonRevert->setClickedCallback(onBtnRevert, this);
- }
- mSexRadio = getChild<LLUICtrl>("sex radio", true, false);
- if (mSexRadio)
- {
- mSexRadio->setCommitCallback(onCommitSexChange);
- mSexRadio->setCallbackUserData(this);
- }
- return true;
- }
- LLPanelEditWearable::~LLPanelEditWearable()
- {
- std::for_each(mSubpartList.begin(), mSubpartList.end(),
- DeletePairedPointer());
- mSubpartList.clear();
- // Clear colorswatch commit callbacks that point to this object.
- for (std::map<std::string, S32>::iterator iter = mColorList.begin();
- iter != mColorList.end(); ++iter)
- {
- childSetCommitCallback(iter->first.c_str(), NULL, NULL);
- }
- }
- void LLPanelEditWearable::addSubpart(const std::string& name, ESubpart id,
- LLSubpart* part)
- {
- if (!name.empty())
- {
- childSetAction(name.c_str(), &LLPanelEditWearable::onBtnSubpart,
- (void*)id);
- part->mButtonName = name;
- }
- mSubpartList[id] = part;
- }
- //static
- void LLPanelEditWearable::onBtnSubpart(void* userdata)
- {
- if (!gFloaterCustomizep) return;
- LLPanelEditWearable* self = gFloaterCustomizep->getCurrentWearablePanel();
- if (!self) return;
- ESubpart subpart = (ESubpart) (intptr_t)userdata;
- self->setSubpart(subpart);
- }
- void LLPanelEditWearable::setSubpart(ESubpart subpart)
- {
- mCurrentSubpart = subpart;
- for (std::map<ESubpart, LLSubpart*>::iterator iter = mSubpartList.begin();
- iter != mSubpartList.end(); ++iter)
- {
- LLButton* btnp = getChild<LLButton>(iter->second->mButtonName.c_str(),
- true, false);
- if (btnp)
- {
- btnp->setToggleState(subpart == iter->first);
- }
- }
- LLSubpart* partp = get_ptr_in_map(mSubpartList, (ESubpart)subpart);
- if (partp && isAgentAvatarValid())
- {
- // Update the thumbnails we display
- LLFloaterCustomize::param_map sorted_params;
- ESex avatar_sex = gAgentAvatarp->getSex();
- LLViewerInventoryItem* itemp =
- gAgentWearables.getWearableInventoryItem(mType, mLayer);
- U32 perm_mask = 0x0;
- bool is_complete = false;
- if (itemp)
- {
- perm_mask = itemp->getPermissions().getMaskOwner();
- is_complete = itemp->isFinished();
- if (!is_complete)
- {
- // Trigger a force-fetching. HB
- itemp->fetchFromServer();
- }
- }
- setUIPermissions(perm_mask, is_complete);
- bool editable = (perm_mask & PERM_MODIFY) && is_complete;
- std::string param_name;
- for (LLViewerVisualParam* prmp =
- (LLViewerVisualParam*)gAgentAvatarp->getFirstVisualParam();
- prmp;
- prmp = (LLViewerVisualParam*)gAgentAvatarp->getNextVisualParam())
- {
- if (!prmp || prmp->getID() == -1 || !prmp->isTweakable() ||
- prmp->getEditGroup() != partp->mEditGroup ||
- !(prmp->getSex() & avatar_sex))
- {
- continue;
- }
- // Exclude wrinkles since the baking code was removed for them...
- // We still allow them for the skin (face wrinkles) in OpenSim
- // since they can still render in non-SSB grids (the Cool VL Viewer
- // does allow to bake them).
- param_name = prmp->getName();
- LLStringUtil::toLower(param_name);
- if (param_name.find("wrinkles") != std::string::npos &&
- (!LLTexLayerSet::sAllowFaceWrinkles || prmp->getID() != 163))
- {
- continue;
- }
- // Check for duplicates
- llassert(sorted_params.find(-prmp->getDisplayOrder()) ==
- sorted_params.end());
- // Negative getDisplayOrder() to make lowest order the highest
- // priority
- sorted_params.emplace(-prmp->getDisplayOrder(),
- LLFloaterCustomize::editable_param(editable,
- prmp));
- }
- LLJoint* jointp = gAgentAvatarp->getJoint(partp->mTargetJointKey);
- gFloaterCustomizep->generateVisualParamHints(this, NULL, sorted_params,
- mWearable,
- partp->mVisualHint,
- jointp);
- gFloaterCustomizep->updateScrollingPanelUI();
- // Update the camera
- gMorphViewp->setCameraTargetJoint(jointp);
- gMorphViewp->setCameraTargetOffset(partp->mTargetOffset);
- gMorphViewp->setCameraOffset(partp->mCameraOffset);
- if (gSavedSettings.getBool("AppearanceCameraMovement"))
- {
- gAgent.setFocusOnAvatar(false, gAgent.getCameraAnimating());
- gMorphViewp->updateCamera();
- }
- }
- }
- //static
- void LLPanelEditWearable::onBtnTakeOff(void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (self && gAgentWearables.getViewerWearable(self->mType, self->mLayer))
- {
- gAgentWearables.removeWearable(self->mType, false, self->mLayer);
- }
- }
- //static
- void LLPanelEditWearable::onBtnSave(void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!self) return;
- gAgentWearables.saveWearable(self->mType, self->mLayer);
- }
- //static
- void LLPanelEditWearable::onBtnSaveAs(void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!self) return;
- LLViewerWearable* wearable;
- wearable = gAgentWearables.getViewerWearable(self->mType, self->mLayer);
- if (wearable)
- {
- LLWearableSaveAsDialog* save_as_dialog;
- save_as_dialog = new LLWearableSaveAsDialog(wearable->getName(),
- onSaveAsCommit, self);
- save_as_dialog->startModal();
- // LLWearableSaveAsDialog deletes itself.
- }
- }
- //static
- void LLPanelEditWearable::onSaveAsCommit(LLWearableSaveAsDialog* save_as_dialog,
- void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (self && isAgentAvatarValid())
- {
- gAgentWearables.saveWearableAs(self->mType, self->mLayer,
- save_as_dialog->getItemName());
- }
- }
- //static
- void LLPanelEditWearable::onBtnRevert(void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!self) return;
- gAgentWearables.revertWearable(self->mType, self->mLayer);
- }
- //static
- void LLPanelEditWearable::onBtnCreateNew(void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (self && isAgentAvatarValid())
- {
- // Create a new wearable in the default folder for the wearable's asset
- // type.
- LLViewerWearable* wearable =
- LLWearableList::getInstance()->createNewWearable(self->mType,
- gAgentAvatarp);
- LLAssetType::EType asset_type = wearable->getAssetType();
- // Regular UI, items get created in normal folder
- LLUUID folder_id =
- gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type));
- LLPointer<LLInventoryCallback> cb = new LLWearOnAvatarCallback(false);
- create_inventory_item(folder_id, wearable->getTransactionID(),
- wearable->getName(), wearable->getDescription(),
- asset_type, LLInventoryType::IT_WEARABLE,
- (U8)wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
- cb);
- }
- }
- bool LLPanelEditWearable::textureIsInvisible(ETextureIndex te)
- {
- if (isAgentAvatarValid() &&
- gAgentWearables.getViewerWearable(mType, getWearableIndex()))
- {
- const LLTextureEntry* current_te = gAgentAvatarp->getTE(te);
- return (current_te && current_te->getID() == IMG_INVISIBLE);
- }
- return false;
- }
- void LLPanelEditWearable::addInvisibilityCheckbox(ETextureIndex te,
- const std::string& name)
- {
- childSetCommitCallback(name.c_str(), onInvisibilityCommit, this);
- mInvisibilityList[name] = te;
- }
- //static
- void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*)ctrl;
- if (!self || !checkbox_ctrl || !self->mWearable || !isAgentAvatarValid())
- {
- return;
- }
- ETextureIndex te =
- (ETextureIndex)(self->mInvisibilityList[ctrl->getName()]);
- bool new_invis_state = checkbox_ctrl->get();
- if (new_invis_state)
- {
- LLLocalTextureObject* lto = self->mWearable->getLocalTextureObject(te);
- self->mPreviousTextureList[te] = lto->getID();
- LLViewerTexture* image =
- LLViewerTextureManager::getFetchedTexture(IMG_INVISIBLE);
- gAgentAvatarp->setLocalTexture(te, image, false, self->mLayer);
- gAgentAvatarp->wearableUpdated(self->mType, false);
- }
- else
- {
- // Try to restore previous texture, if any.
- LLUUID prev_id = self->mPreviousTextureList[(S32)te];
- if (prev_id.isNull() || prev_id == IMG_INVISIBLE)
- {
- prev_id = LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID"));
- }
- if (prev_id.notNull())
- {
- LLViewerTexture* image =
- LLViewerTextureManager::getFetchedTexture(prev_id);
- if (image)
- {
- gAgentAvatarp->setLocalTexture(te, image, false, self->mLayer);
- gAgentAvatarp->wearableUpdated(self->mType, false);
- }
- }
- }
- }
- void LLPanelEditWearable::addColorSwatch(ETextureIndex te,
- const std::string& name)
- {
- childSetCommitCallback(name.c_str(), LLPanelEditWearable::onColorCommit, this);
- mColorList[name] = te;
- }
- //static
- void LLPanelEditWearable::onColorCommit(LLUICtrl* ctrl, void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- LLColorSwatchCtrl* color_ctrl = (LLColorSwatchCtrl*)ctrl;
- if (self && color_ctrl && isAgentAvatarValid() && self->mWearable)
- {
- std::map<std::string, S32>::const_iterator cl_itr =
- self->mColorList.find(ctrl->getName());
- if (cl_itr != self->mColorList.end())
- {
- ETextureIndex te = (ETextureIndex)cl_itr->second;
- LLColor4 old_color = self->mWearable->getClothesColor(te);
- const LLColor4& new_color = color_ctrl->get();
- if (old_color != new_color)
- {
- // Set the new version
- self->mWearable->setClothesColor(te, new_color, true);
- #if 0
- gAgentAvatarp->setClothesColor(te, new_color, true);
- #endif
- LLVisualParamHint::requestHintUpdates();
- gAgentAvatarp->wearableUpdated(self->mType, false);
- }
- }
- }
- }
- void LLPanelEditWearable::initPreviousTextureList()
- {
- initPreviousTextureListEntry(TEX_LOWER_ALPHA);
- initPreviousTextureListEntry(TEX_UPPER_ALPHA);
- initPreviousTextureListEntry(TEX_HEAD_ALPHA);
- initPreviousTextureListEntry(TEX_EYES_ALPHA);
- initPreviousTextureListEntry(TEX_LOWER_ALPHA);
- }
- void LLPanelEditWearable::initPreviousTextureListEntry(ETextureIndex te)
- {
- if (mWearable)
- {
- LLUUID id;
- LLLocalTextureObject* lto = mWearable->getLocalTextureObject(te);
- if (lto)
- {
- id = lto->getID();
- }
- mPreviousTextureList[te] = id;
- }
- }
- void LLPanelEditWearable::addTextureDropTarget(ETextureIndex te,
- const std::string& name,
- const LLUUID& default_image_id,
- bool allow_no_texture)
- {
- childSetCommitCallback(name.c_str(), onTextureCommit, this);
- LLTextureCtrl* tex_ctrl = getChild<LLTextureCtrl>(name.c_str(), true,
- false);
- if (tex_ctrl)
- {
- tex_ctrl->setDefaultImageAssetID(default_image_id);
- tex_ctrl->setAllowNoTexture(allow_no_texture);
- // Do not allow (no copy) or (no transfer) textures to be selected.
- tex_ctrl->setImmediateFilterPermMask(PERM_NONE);
- tex_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
- }
- mTextureList[name] = te;
- if (mType == LLWearableType::WT_ALPHA)
- {
- initPreviousTextureListEntry(te);
- }
- }
- //static
- void LLPanelEditWearable::onTextureCommit(LLUICtrl* ctrl, void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl;
- if (self && ctrl && isAgentAvatarValid())
- {
- ETextureIndex te =
- (ETextureIndex)(self->mTextureList[ctrl->getName()]);
- // Set the new version
- LLViewerTexture* image =
- LLViewerTextureManager::getFetchedTexture(tex_ctrl->getImageAssetID());
- if (image->getID().isNull() || image->getID() == IMG_DEFAULT)
- {
- image =
- LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
- }
- self->mTextureList[ctrl->getName()] = te;
- if (self->mWearable)
- {
- gAgentAvatarp->setLocalTexture(te, image, false, self->mLayer);
- LLVisualParamHint::requestHintUpdates();
- gAgentAvatarp->wearableUpdated(self->mType, false);
- }
- if (self->mType == LLWearableType::WT_ALPHA &&
- image->getID() != IMG_INVISIBLE)
- {
- self->mPreviousTextureList[te] = image->getID();
- }
- }
- }
- ESubpart LLPanelEditWearable::getDefaultSubpart()
- {
- switch (mType)
- {
- case LLWearableType::WT_SHAPE:
- return SUBPART_SHAPE_WHOLE;
- case LLWearableType::WT_SKIN:
- return SUBPART_SKIN_COLOR;
- case LLWearableType::WT_HAIR:
- return SUBPART_HAIR_COLOR;
- case LLWearableType::WT_EYES:
- return SUBPART_EYES;
- case LLWearableType::WT_SHIRT:
- return SUBPART_SHIRT;
- case LLWearableType::WT_PANTS:
- return SUBPART_PANTS;
- case LLWearableType::WT_SHOES:
- return SUBPART_SHOES;
- case LLWearableType::WT_SOCKS:
- return SUBPART_SOCKS;
- case LLWearableType::WT_JACKET:
- return SUBPART_JACKET;
- case LLWearableType::WT_GLOVES:
- return SUBPART_GLOVES;
- case LLWearableType::WT_UNDERSHIRT:
- return SUBPART_UNDERSHIRT;
- case LLWearableType::WT_UNDERPANTS:
- return SUBPART_UNDERPANTS;
- case LLWearableType::WT_SKIRT:
- return SUBPART_SKIRT;
- case LLWearableType::WT_ALPHA:
- return SUBPART_ALPHA;
- case LLWearableType::WT_TATTOO:
- return SUBPART_TATTOO;
- case LLWearableType::WT_UNIVERSAL:
- return SUBPART_UNIVERSAL;
- case LLWearableType::WT_PHYSICS:
- return SUBPART_PHYSICS_BELLY_UPDOWN;
- default:
- llwarns << "Unknown sub-part type: " << mType << llendl;
- llassert(false);
- return SUBPART_SHAPE_WHOLE;
- }
- }
- void LLPanelEditWearable::draw()
- {
- if (!gFloaterCustomizep || gFloaterCustomizep->isMinimized() ||
- !isAgentAvatarValid())
- {
- return;
- }
- bool has_wearable = mWearable != NULL;
- bool is_dirty = isDirty();
- bool is_modifiable = false;
- bool is_copyable = false;
- bool is_complete = false;
- LLViewerInventoryItem* itemp = NULL;
- if (has_wearable)
- {
- itemp = gAgentWearables.getWearableInventoryItem(mType, mLayer);
- if (itemp)
- {
- const LLPermissions& perm = itemp->getPermissions();
- is_modifiable = perm.allowModifyBy(gAgentID, gAgent.getGroupID());
- is_copyable = perm.allowCopyBy(gAgentID, gAgent.getGroupID());
- is_complete = itemp->isFinished();
- }
- }
- setMaxLayers();
- if (mButtonSave)
- {
- mButtonSave->setEnabled(is_modifiable && is_complete && has_wearable &&
- is_dirty);
- mButtonSave->setVisible(has_wearable || !mButtonCreateNew);
- }
- if (mButtonSaveAs)
- {
- mButtonSaveAs->setEnabled(is_copyable && is_complete && has_wearable);
- mButtonSaveAs->setVisible(has_wearable || !mButtonCreateNew);
- }
- if (mButtonRevert)
- {
- mButtonRevert->setEnabled(has_wearable && is_dirty);
- mButtonRevert->setVisible(has_wearable || !mButtonCreateNew);
- }
- if (mButtonTakeOff)
- {
- mButtonTakeOff->setEnabled(has_wearable);
- mButtonTakeOff->setVisible(mCanTakeOff && has_wearable);
- }
- if (mButtonCreateNew)
- {
- mButtonCreateNew->setVisible(!has_wearable);
- }
- if (mNotWornInstructions)
- {
- mNotWornInstructions->setVisible(!has_wearable);
- }
- if (mNoModifyInstructions)
- {
- mNoModifyInstructions->setVisible(has_wearable && !is_modifiable);
- }
- for (std::map<ESubpart, LLSubpart*>::iterator iter = mSubpartList.begin(),
- end = mSubpartList.end();
- iter != end; ++iter)
- {
- std::string btn_name = iter->second->mButtonName;
- LLButton* button = getChild<LLButton>(btn_name.c_str(), true, false);
- if (button)
- {
- button->setVisible(has_wearable);
- if (has_wearable && is_complete && is_modifiable)
- {
- button->setEnabled(iter->second->mSex &
- gAgentAvatarp->getSex());
- }
- else
- {
- button->setEnabled(false);
- }
- }
- }
- if (mLockIcon)
- {
- mLockIcon->setVisible(!is_modifiable);
- }
- if (mTitle)
- {
- mTitle->setVisible(false);
- }
- if (mTitleNoModify)
- {
- mTitleNoModify->setVisible(false);
- }
- if (mTitleNotWorn)
- {
- mTitleNotWorn->setVisible(false);
- }
- if (mTitleLoading)
- {
- mTitleLoading->setVisible(false);
- }
- if (mPath)
- {
- mPath->setVisible(false);
- }
- if (has_wearable && !is_modifiable)
- {
- if (mTitleNoModify)
- {
- mTitleNoModify->setVisible(true);
- // *TODO:Translate
- mTitleNoModify->setTextArg("[DESC]", itemp ? itemp->getName()
- : mWearable->getName());
- }
- hideTextureControls();
- }
- else if (has_wearable && !is_complete)
- {
- if (mTitleLoading)
- {
- mTitleLoading->setVisible(true);
- // *TODO:Translate
- mTitleLoading->setTextArg("[DESC]",
- LLWearableType::getTypeLabel(mType));
- }
- if (mPath)
- {
- std::string path;
- const LLUUID& item_id = gAgentWearables.getWearableItemID(mType,
- mLayer);
- gInventory.appendPath(item_id, path);
- mPath->setVisible(true);
- mPath->setTextArg("[PATH]", path);
- }
- hideTextureControls();
- }
- else if (has_wearable && is_modifiable)
- {
- if (mTitle)
- {
- mTitle->setVisible(true);
- mTitle->setTextArg("[DESC]", itemp ? itemp->getName()
- : mWearable->getName());
- }
- if (mPath)
- {
- std::string path;
- const LLUUID& item_id = gAgentWearables.getWearableItemID(mType,
- mLayer);
- gInventory.appendPath(item_id, path);
- mPath->setVisible(true);
- mPath->setTextArg("[PATH]", path);
- }
- for (std::map<std::string, S32>::iterator iter = mTextureList.begin(),
- end = mTextureList.end();
- iter != end; ++iter)
- {
- std::string name = iter->first;
- LLTextureCtrl* tex_ctrl = getChild<LLTextureCtrl>(name.c_str(),
- true, false);
- if (tex_ctrl)
- {
- tex_ctrl->setVisible(is_copyable && is_modifiable &&
- is_complete);
- ETextureIndex te = (ETextureIndex)iter->second;
- LLLocalTextureObject* lto =
- mWearable->getLocalTextureObject(te);
- LLUUID new_id;
- if (lto && lto->getID() != IMG_DEFAULT_AVATAR)
- {
- new_id = lto->getID();
- }
- if (tex_ctrl->getImageAssetID() != new_id)
- {
- // Texture has changed, close the floater to avoid
- // DEV-22461
- tex_ctrl->closeFloater();
- }
- tex_ctrl->setImageAssetID(new_id);
- }
- }
- for (std::map<std::string, S32>::iterator iter = mColorList.begin(),
- end = mColorList.end();
- iter != end; ++iter)
- {
- std::string name = iter->first;
- LLColorSwatchCtrl* ctrl = getChild<LLColorSwatchCtrl>(name.c_str(),
- true, false);
- if (ctrl)
- {
- ctrl->setVisible(is_modifiable && is_complete);
- ctrl->setEnabled(is_modifiable && is_complete);
- ETextureIndex te = (ETextureIndex)iter->second;
- ctrl->set(mWearable->getClothesColor(te));
- }
- }
- for (std::map<std::string, S32>::iterator
- iter = mInvisibilityList.begin(),
- end = mInvisibilityList.end();
- iter != end; ++iter)
- {
- std::string name = iter->first;
- LLCheckBoxCtrl* ctrl = getChild<LLCheckBoxCtrl>(name.c_str(), true,
- false);
- if (ctrl)
- {
- ctrl->setVisible(is_copyable && is_modifiable && is_complete);
- ctrl->setEnabled(is_copyable && is_modifiable && is_complete);
- ETextureIndex te = (ETextureIndex)iter->second;
- ctrl->set(!gAgentAvatarp->isTextureVisible(te, mWearable));
- }
- }
- }
- else
- {
- if (mTitleNotWorn)
- {
- mTitleNotWorn->setVisible(true);
- // *TODO:Translate
- mTitleNotWorn->setTextArg("[DESC]",
- LLWearableType::getTypeLabel(mType));
- }
- hideTextureControls();
- }
- #if 0
- if (mWearableIcon)
- {
- mWearableIcon->setVisible(has_wearable);
- }
- #endif
- LLPanel::draw();
- }
- void LLPanelEditWearable::hideTextureControls()
- {
- for (std::map<std::string, S32>::iterator iter = mTextureList.begin(),
- end = mTextureList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(), false);
- }
- for (std::map<std::string, S32>::iterator iter = mColorList.begin(),
- end = mColorList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(), false);
- }
- for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin(),
- end = mInvisibilityList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(), false);
- }
- }
- void LLPanelEditWearable::setMaxLayers()
- {
- if (mSpinLayer)
- {
- mSpinLayer->setMaxValue((F32)gAgentWearables.getWearableCount(mType));
- }
- }
- void LLPanelEditWearable::setWearable(LLViewerWearable* wearable,
- U32 perm_mask, bool is_complete)
- {
- mWearable = wearable;
- if (wearable)
- {
- mLayer = 0;
- gAgentWearables.getWearableIndex(wearable, mLayer);
- if (mSpinLayer)
- {
- setMaxLayers();
- mSpinLayer->set((F32)mLayer);
- }
- if (mType == LLWearableType::WT_ALPHA)
- {
- initPreviousTextureList();
- }
- }
- setUIPermissions(perm_mask, is_complete);
- }
- void LLPanelEditWearable::switchToDefaultSubpart()
- {
- setSubpart(getDefaultSubpart());
- }
- void LLPanelEditWearable::setVisible(bool visible)
- {
- LLPanel::setVisible(visible);
- if (!visible)
- {
- for (std::map<std::string, S32>::iterator iter = mColorList.begin(),
- end = mColorList.end();
- iter != end; ++iter)
- {
- // This forces any open color pickers to cancel their selection
- childSetEnabled(iter->first.c_str(), false);
- }
- }
- }
- bool LLPanelEditWearable::isDirty() const
- {
- LLViewerWearable* wearable = gAgentWearables.getViewerWearable(mType,
- mLayer);
- return wearable && wearable->isDirty();
- }
- //static
- void LLPanelEditWearable::onCommitSexChange(LLUICtrl*, void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!self || !self->mWearable) return;
- if (!isAgentAvatarValid() || !gFloaterCustomizep)
- {
- return;
- }
- if (!gAgentWearables.isWearableModifiable(self->mType, self->mLayer))
- {
- return;
- }
- ESex new_sex = gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE;
- LLViewerVisualParam* param =
- (LLViewerVisualParam*)gAgentAvatarp->getVisualParam("male");
- if (!param)
- {
- return;
- }
- self->mWearable->setVisualParamWeight(param->getID(), new_sex == SEX_MALE,
- true);
- self->mWearable->writeToAvatar(gAgentAvatarp);
- gAgentAvatarp->updateSexDependentLayerSets(true);
- gAgentAvatarp->updateVisualParams();
- gFloaterCustomizep->clearScrollingPanelList();
- // Assumes that we're in the "Shape" Panel.
- self->setSubpart(SUBPART_SHAPE_WHOLE);
- }
- // Helper for the callback below
- void error_message(std::string message)
- {
- LLSD args;
- args["MESSAGE"] = message;
- gNotifications.add("GenericAlert", args);
- }
- //static
- void LLPanelEditWearable::importCallback(HBFileSelector::ELoadFilter type,
- std::string& filename,
- void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!gFloaterCustomizep || !self || !self->mWearable || filename.empty() ||
- !isAgentAvatarValid())
- {
- return;
- }
- llinfos << "Selected import file: " << filename << llendl;
- LLXmlTree xml_tree;
- if (!xml_tree.parseFile(filename, false))
- {
- error_message("Can't read the xml file, aborting.");
- return;
- }
- // Check the file format and version
- LLXmlTreeNode* root = xml_tree.getRoot();
- if (!root)
- {
- error_message("No root node found in xml file, aborting.");
- return;
- }
- if (!root->hasName("linden_genepool"))
- {
- error_message("Not an avatar dump, aborting.");
- return;
- }
- std::string version;
- static LLStdStringHandle version_string =
- LLXmlTree::addAttributeString("version");
- if (!root->getFastAttributeString(version_string, version) ||
- version != "1.0")
- {
- error_message("Invalid or missing avatar dump version, aborting.");
- return;
- }
- LLXmlTreeNode* node = root->getChildByName("archetype");
- if (!node)
- {
- error_message("Missing archetype node in avatar dump, aborting.");
- return;
- }
- // Read the file and place the params' id and value in a map
- S32 id;
- F32 value;
- static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
- static LLStdStringHandle value_string =
- LLXmlTree::addAttributeString("value");
- std::map<S32, F32> params_map;
- for (LLXmlTreeNode* child = node->getChildByName("param"); child;
- child = node->getNextNamedChild())
- {
- if (child->getFastAttributeS32(id_string, id) &&
- child->getFastAttributeF32(value_string, value))
- {
- params_map.emplace(id, value);
- }
- }
- // Now set the visual params that correspond to our type
- bool sex_changed = false;
- std::map<S32, F32>::const_iterator it;
- std::map<S32, F32>::const_iterator end = params_map.end();
- for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param;
- param = gAgentAvatarp->getNextVisualParam())
- {
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- if (viewer_param->getWearableType() == self->mType &&
- viewer_param->isTweakable())
- {
- id = viewer_param->getID();
- it = params_map.find(id);
- if (it != end)
- {
- value = it->second;
- if (viewer_param->getName() == "male")
- {
- ESex sex = gSavedSettings.getU32("AvatarSex") ? SEX_MALE
- : SEX_FEMALE;
- ESex new_sex = value > 0.5f ? SEX_MALE : SEX_FEMALE;
- if (new_sex != sex)
- {
- gSavedSettings.setU32("AvatarSex",
- new_sex == SEX_MALE);
- sex_changed = true;
- }
- }
- llinfos << "Setting param id " << id << " to value "
- << value << llendl;
- self->mWearable->setVisualParamWeight(id, value, true);
- }
- }
- }
- self->mWearable->writeToAvatar(gAgentAvatarp);
- if (sex_changed)
- {
- gAgentAvatarp->updateSexDependentLayerSets(true);
- gAgentAvatarp->updateVisualParams();
- gFloaterCustomizep->clearScrollingPanelList();
- // Assumes that we're in the "Shape" Panel.
- self->setSubpart(SUBPART_SHAPE_WHOLE);
- }
- else
- {
- gAgentAvatarp->updateVisualParams();
- gFloaterCustomizep->updateScrollingPanelUI();
- }
- }
- //static
- void LLPanelEditWearable::onBtnImport(void* userdata)
- {
- HBFileSelector::loadFile(HBFileSelector::FFLOAD_XML, importCallback,
- userdata);
- }
- //static
- void LLPanelEditWearable::onCommitLayer(LLUICtrl*, void* userdata)
- {
- LLPanelEditWearable* self = (LLPanelEditWearable*)userdata;
- if (!self || !self->mSpinLayer || !gFloaterCustomizep) return;
- U32 index = (U32)self->mSpinLayer->get();
- LLViewerWearable* wearable =
- gAgentWearables.getViewerWearable(self->mType, index);
- if (wearable)
- {
- gFloaterCustomizep->updateWearableType(self->mType, wearable);
- }
- else
- {
- self->setWearable(NULL, PERM_ALL, true);
- LLFloaterCustomize::setCurrentWearableType(self->mType);
- gFloaterCustomizep->updateScrollingPanelUI();
- }
- }
- void LLPanelEditWearable::setUIPermissions(U32 perm_mask, bool is_complete)
- {
- bool is_copyable = (perm_mask & PERM_COPY) != 0;
- bool is_modifiable = (perm_mask & PERM_MODIFY) != 0;
- if (mButtonImport)
- {
- mButtonImport->setEnabled(is_modifiable && is_complete);
- }
- if (mButtonSave)
- {
- mButtonSave->setEnabled(is_modifiable && is_complete);
- }
- if (mButtonSaveAs)
- {
- mButtonSaveAs->setEnabled(is_copyable && is_complete);
- }
- if (mSexRadio)
- {
- mSexRadio->setEnabled(is_modifiable && is_complete);
- }
- for (std::map<std::string, S32>::iterator iter = mTextureList.begin(),
- end = mTextureList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(),
- is_copyable && is_modifiable && is_complete);
- }
- for (std::map<std::string, S32>::iterator iter = mColorList.begin(),
- end = mColorList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(), is_modifiable && is_complete);
- }
- for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin(),
- end = mInvisibilityList.end();
- iter != end; ++iter)
- {
- childSetVisible(iter->first.c_str(),
- is_copyable && is_modifiable && is_complete);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- LLWearableSaveAsDialog::LLWearableSaveAsDialog(const std::string& desc,
- void (*commit_cb)(LLWearableSaveAsDialog*,
- void*),
- void* userdata)
- : LLModalDialog(LLStringUtil::null, 240, 100),
- mCommitCallback(commit_cb),
- mCallbackUserData(userdata)
- {
- LLUICtrlFactory::getInstance()->buildFloater(this,
- "floater_wearable_save_as.xml");
- childSetAction("Save", LLWearableSaveAsDialog::onSave, this);
- childSetAction("Cancel", LLWearableSaveAsDialog::onCancel, this);
- childSetTextArg("name ed", "[DESC]", desc);
- }
- //virtual
- void LLWearableSaveAsDialog::startModal()
- {
- LLModalDialog::startModal();
- LLLineEditor* edit = getChild<LLLineEditor>("name ed", true, false);
- if (edit)
- {
- edit->setFocus(true);
- edit->selectAll();
- }
- }
- //static
- void LLWearableSaveAsDialog::onSave(void* userdata)
- {
- LLWearableSaveAsDialog* self = (LLWearableSaveAsDialog*)userdata;
- self->mItemName = self->childGetValue("name ed").asString();
- LLStringUtil::trim(self->mItemName);
- if (!self->mItemName.empty())
- {
- if (self->mCommitCallback)
- {
- self->mCommitCallback(self, self->mCallbackUserData);
- }
- self->close(); // Destroys this object
- }
- }
- //static
- void LLWearableSaveAsDialog::onCancel(void* userdata)
- {
- LLWearableSaveAsDialog* self = (LLWearableSaveAsDialog*)userdata;
- self->close(); // Destroys this object
- }
|