Initial version of Visual Outfit Browser
parent
1be6320933
commit
6a02f5bbce
|
|
@ -168,7 +168,6 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
|
|||
LLUI::removePopup(view);
|
||||
}
|
||||
|
||||
|
||||
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
|
||||
{
|
||||
// notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ void LLLayoutStack::removeChild(LLView* view)
|
|||
if (embedded_panelp)
|
||||
{
|
||||
mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
|
||||
delete embedded_panelp;
|
||||
//delete embedded_panelp;
|
||||
updateFractionalSizes();
|
||||
mNeedsLayout = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -414,6 +414,7 @@ set(viewer_SOURCE_FILES
|
|||
llnotificationscripthandler.cpp
|
||||
llnotificationstorage.cpp
|
||||
llnotificationtiphandler.cpp
|
||||
lloutfitgallery.cpp
|
||||
lloutfitslist.cpp
|
||||
lloutfitobserver.cpp
|
||||
lloutputmonitorctrl.cpp
|
||||
|
|
@ -1024,6 +1025,7 @@ set(viewer_HEADER_FILES
|
|||
llnotificationhandler.h
|
||||
llnotificationmanager.h
|
||||
llnotificationstorage.h
|
||||
lloutfitgallery.h
|
||||
lloutfitslist.h
|
||||
lloutfitobserver.h
|
||||
lloutputmonitorctrl.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,699 @@
|
|||
/**
|
||||
* @file lloutfitgallery.cpp
|
||||
* @author Pavlo Kryvych
|
||||
* @brief Visual gallery of agent's outfits for My Appearance side panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2015, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h" // must be first include
|
||||
#include "lloutfitgallery.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// llcommon
|
||||
#include "llcommonutils.h"
|
||||
#include "llvfile.h"
|
||||
|
||||
#include "llappearancemgr.h"
|
||||
#include "lleconomy.h"
|
||||
#include "llerror.h"
|
||||
#include "llfilepicker.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lllocalbitmaps.h"
|
||||
#include "llviewermenufile.h"
|
||||
#include "llwearableitemslist.h"
|
||||
|
||||
|
||||
static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
|
||||
static LLOutfitGallery* gOutfitGallery = NULL;
|
||||
|
||||
LLOutfitGallery::LLOutfitGallery()
|
||||
: LLOutfitListBase(),
|
||||
mTexturesObserver(NULL)
|
||||
{
|
||||
// mGearMenu = new LLOutfitGalleryGearMenu(this);
|
||||
}
|
||||
|
||||
BOOL LLOutfitGallery::postBuild()
|
||||
{
|
||||
BOOL rv = LLOutfitListBase::postBuild();
|
||||
return rv;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onOpen(const LLSD& info)
|
||||
{
|
||||
LLOutfitListBase::onOpen(info);
|
||||
rebuildGallery();
|
||||
loadPhotos();
|
||||
}
|
||||
|
||||
#define LAYOUT_STACK_HEIGHT 180
|
||||
#define GALLERY_VERTICAL_GAP 10
|
||||
#define GALLERY_HORIZONTAL_GAP 10
|
||||
#define GALLERY_ITEM_WIDTH 150
|
||||
#define GALLERY_ITEM_HEIGHT 175
|
||||
#define GALLERY_ITEM_HGAP 16
|
||||
#define ITEMS_IN_ROW 3
|
||||
#define LAYOUT_STACK_WIDTH 166 * ITEMS_IN_ROW//498
|
||||
#define GALLERY_WIDTH 163 * ITEMS_IN_ROW//485//290
|
||||
|
||||
void LLOutfitGallery::rebuildGallery()
|
||||
{
|
||||
LLView::child_list_t child_list(*getChild<LLPanel>("gallery_panel")->getChildList());
|
||||
BOOST_FOREACH(LLView* view, child_list)
|
||||
{
|
||||
LLLayoutStack* lstack = dynamic_cast<LLLayoutStack*>(view);
|
||||
if (lstack != NULL)
|
||||
{
|
||||
LLView::child_list_t panel_list(*lstack->getChildList());
|
||||
BOOST_FOREACH(LLView* panel, panel_list)
|
||||
{
|
||||
//LLLayoutPanel* lpanel = dynamic_cast<LLLayoutPanel*>(panel);
|
||||
//if (!lpanel)
|
||||
// continue;
|
||||
LLView::child_list_t panel_children(*panel->getChildList());
|
||||
if (panel_children.size() > 0)
|
||||
{
|
||||
//Assume OutfitGalleryItem is the only one child of layout panel
|
||||
LLView* view_item = panel_children.back();
|
||||
LLOutfitGalleryItem* gallery_item = dynamic_cast<LLOutfitGalleryItem*>(view_item);
|
||||
if (gallery_item != NULL)
|
||||
panel->removeChild(gallery_item);
|
||||
}
|
||||
lstack->removeChild(panel);
|
||||
//delete panel;
|
||||
}
|
||||
getChild<LLPanel>("gallery_panel")->removeChild(lstack);
|
||||
delete lstack;
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLPanel>("gallery_panel")->removeChild(view);
|
||||
}
|
||||
}
|
||||
uuid_vec_t cats;
|
||||
getCurrentCategories(cats);
|
||||
int n = cats.size();
|
||||
int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
|
||||
getChild<LLPanel>("gallery_panel")->reshape(
|
||||
GALLERY_WIDTH, row_count * (LAYOUT_STACK_HEIGHT + GALLERY_VERTICAL_GAP));
|
||||
int vgap = 0;
|
||||
uuid_vec_t::reverse_iterator rit = cats.rbegin();
|
||||
for (int i = row_count - 1; i >= 0; i--)
|
||||
{
|
||||
LLLayoutStack* stack = buildLayoutStak(0, (row_count - 1 - i) * LAYOUT_STACK_HEIGHT + vgap);
|
||||
getChild<LLPanel>("gallery_panel")->addChild(stack);
|
||||
int items_in_cur_row = (n % ITEMS_IN_ROW) == 0 ? ITEMS_IN_ROW : (i == row_count - 1 ? n % ITEMS_IN_ROW : ITEMS_IN_ROW);
|
||||
int hgap = 0;
|
||||
for (int j = 0; j < items_in_cur_row && rit != cats.rend(); j++)
|
||||
{
|
||||
LLLayoutPanel* lpanel = buildLayoutPanel(j * GALLERY_ITEM_WIDTH + hgap);
|
||||
LLOutfitGalleryItem* item = mOutfitMap[*rit];
|
||||
lpanel->addChild(item);
|
||||
stack->addChild(lpanel);
|
||||
rit++;
|
||||
hgap += GALLERY_HORIZONTAL_GAP;
|
||||
}
|
||||
vgap += GALLERY_VERTICAL_GAP;
|
||||
}
|
||||
}
|
||||
|
||||
LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
|
||||
{
|
||||
LLOutfitGalleryItem::Params giparams;
|
||||
LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams);
|
||||
LLRect girect = LLRect(0, GALLERY_ITEM_HEIGHT - GALLERY_ITEM_HEIGHT,
|
||||
GALLERY_ITEM_WIDTH, 0);
|
||||
//gitem->setRect(girect);
|
||||
gitem->reshape(GALLERY_ITEM_WIDTH, GALLERY_ITEM_HEIGHT);
|
||||
gitem->setVisible(true);
|
||||
gitem->setFollowsLeft();
|
||||
gitem->setFollowsTop();
|
||||
gitem->setOutfitName(name);
|
||||
return gitem;
|
||||
}
|
||||
|
||||
LLLayoutPanel* LLOutfitGallery::buildLayoutPanel(int left)
|
||||
{
|
||||
LLLayoutPanel::Params lpparams;
|
||||
int top = 0;
|
||||
LLLayoutPanel* lpanel = LLUICtrlFactory::create<LLLayoutPanel>(lpparams);
|
||||
LLRect rect = LLRect(left, top + GALLERY_ITEM_HEIGHT, left + GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, top);
|
||||
lpanel->setRect(rect);
|
||||
lpanel->reshape(GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, GALLERY_ITEM_HEIGHT);
|
||||
lpanel->setVisible(true);
|
||||
lpanel->setFollowsLeft();
|
||||
lpanel->setFollowsTop();
|
||||
return lpanel;
|
||||
}
|
||||
|
||||
LLLayoutStack* LLOutfitGallery::buildLayoutStak(int left, int top)
|
||||
{
|
||||
LLLayoutStack::Params sparams;
|
||||
LLLayoutStack* stack = LLUICtrlFactory::create<LLLayoutStack>(sparams);
|
||||
LLRect rect = LLRect(left, top + LAYOUT_STACK_HEIGHT, left + LAYOUT_STACK_WIDTH, top);
|
||||
stack->setRect(rect);
|
||||
stack->reshape(LAYOUT_STACK_WIDTH, LAYOUT_STACK_HEIGHT);
|
||||
stack->setVisible(true);
|
||||
stack->setFollowsLeft();
|
||||
stack->setFollowsTop();
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
||||
LLOutfitGallery::~LLOutfitGallery()
|
||||
{
|
||||
if (gInventory.containsObserver(mTexturesObserver))
|
||||
{
|
||||
gInventory.removeObserver(mTexturesObserver);
|
||||
}
|
||||
delete mTexturesObserver;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::setFilterSubString(const std::string& string)
|
||||
{
|
||||
//TODO: Implement filtering
|
||||
|
||||
sFilterSubString = string;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
|
||||
{
|
||||
if (mOutfitMap[base_id])
|
||||
{
|
||||
mOutfitMap[base_id]->setOutfitWorn(true);
|
||||
}
|
||||
if (mOutfitMap[prev_id])
|
||||
{
|
||||
mOutfitMap[prev_id]->setOutfitWorn(false);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
|
||||
{
|
||||
}
|
||||
|
||||
void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur)
|
||||
{
|
||||
for (outfit_map_t::const_iterator iter = mOutfitMap.begin();
|
||||
iter != mOutfitMap.end();
|
||||
iter++)
|
||||
{
|
||||
if ((*iter).second != NULL)
|
||||
{
|
||||
vcur.push_back((*iter).first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
|
||||
if (!cat) return;
|
||||
|
||||
std::string name = cat->getName();
|
||||
LLOutfitGalleryItem* item = buildGalleryItem(name);
|
||||
mOutfitMap.insert(LLOutfitGallery::outfit_map_value_t(cat_id, item));
|
||||
item->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this,
|
||||
_1, _2, _3, cat_id));
|
||||
LLWearableItemsList* list = NULL;
|
||||
item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ñhangeOutfitSelection, this, list, cat_id));
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
|
||||
{
|
||||
outfit_map_t::iterator outfits_iter = mOutfitMap.find(cat_id);
|
||||
if (outfits_iter != mOutfitMap.end())
|
||||
{
|
||||
//const LLUUID& outfit_id = outfits_iter->first;
|
||||
LLOutfitGalleryItem* item = outfits_iter->second;
|
||||
|
||||
// An outfit is removed from the list. Do the following:
|
||||
// 2. Remove the outfit from selection.
|
||||
//deselectOutfit(outfit_id);
|
||||
|
||||
// 3. Remove category UUID to accordion tab mapping.
|
||||
mOutfitMap.erase(outfits_iter);
|
||||
|
||||
// 4. Remove outfit from gallery.
|
||||
rebuildGallery();
|
||||
|
||||
// kill removed item
|
||||
if (item != NULL)
|
||||
{
|
||||
item->die();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitGallery::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name)
|
||||
{
|
||||
outfit_map_t::iterator outfit_iter = mOutfitMap.find(cat->getUUID());
|
||||
if (outfit_iter != mOutfitMap.end())
|
||||
{
|
||||
// Update name of outfit in gallery
|
||||
LLOutfitGalleryItem* item = outfit_iter->second;
|
||||
if (item)
|
||||
{
|
||||
item->setOutfitName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
|
||||
{
|
||||
if (mOutfitMenu && cat_id.notNull())
|
||||
{
|
||||
uuid_vec_t selected_uuids;
|
||||
selected_uuids.push_back(cat_id);
|
||||
mOutfitMenu->show(ctrl, selected_uuids, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
|
||||
{
|
||||
if (mSelectedOutfitUUID == category_id)
|
||||
return;
|
||||
if (mOutfitMap[mSelectedOutfitUUID])
|
||||
{
|
||||
mOutfitMap[mSelectedOutfitUUID]->setSelected(FALSE);
|
||||
}
|
||||
if (mOutfitMap[category_id])
|
||||
{
|
||||
mOutfitMap[category_id]->setSelected(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLOutfitGallery::hasItemSelected()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLOutfitGallery::canWearSelected()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLOutfitListGearMenuBase* LLOutfitGallery::createGearMenu()
|
||||
{
|
||||
return new LLOutfitGalleryGearMenu(this);
|
||||
}
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_item");
|
||||
|
||||
LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
|
||||
: LLPanel(p),
|
||||
mTexturep(NULL)
|
||||
{
|
||||
buildFromFile("panel_outfit_gallery_item.xml");
|
||||
}
|
||||
|
||||
LLOutfitGalleryItem::~LLOutfitGalleryItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL LLOutfitGalleryItem::postBuild()
|
||||
{
|
||||
setDefaultImage();
|
||||
|
||||
mOutfitNameText = getChild<LLTextBox>("outfit_name");
|
||||
mOutfitWornText = getChild<LLTextBox>("outfit_worn_text");
|
||||
setOutfitWorn(false);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::draw()
|
||||
{
|
||||
LLPanel::draw();
|
||||
|
||||
// In case texture is not set, don't draw it over default image
|
||||
if (!mTexturep)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Border
|
||||
LLRect border = getChildView("preview_outfit")->getRect();
|
||||
//gl_rect_2d(border, LLColor4::black, FALSE);
|
||||
|
||||
|
||||
// Interior
|
||||
LLRect interior = border;
|
||||
//interior.stretch(-1);
|
||||
|
||||
// If the floater is focused, don't apply its alpha to the texture (STORM-677).
|
||||
const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
if (mTexturep)
|
||||
{
|
||||
if (mTexturep->getComponents() == 4)
|
||||
{
|
||||
gl_rect_2d_checkerboard(interior, alpha);
|
||||
}
|
||||
|
||||
gl_draw_scaled_image(interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
|
||||
|
||||
// Pump the priority
|
||||
mTexturep->addTextureStats((F32)(interior.getWidth() * interior.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::setOutfitName(std::string name)
|
||||
{
|
||||
mOutfitNameText->setText(name);
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::setOutfitWorn(bool value)
|
||||
{
|
||||
//LLStringUtil::format_map_t string_args;
|
||||
//std::string worn_text = getString("worn_text", string_args);
|
||||
|
||||
if (value)
|
||||
{
|
||||
mOutfitWornText->setValue("(worn)");
|
||||
}
|
||||
else
|
||||
{
|
||||
mOutfitWornText->setValue("");
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::setSelected(bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
mOutfitWornText->setValue("(selected)");
|
||||
}
|
||||
else
|
||||
{
|
||||
mOutfitWornText->setValue("");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
setFocus(TRUE);
|
||||
return LLUICtrl::handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
|
||||
{
|
||||
mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
|
||||
mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
}
|
||||
|
||||
void LLOutfitGalleryItem::setDefaultImage()
|
||||
{
|
||||
/*
|
||||
LLUUID imageAssetID("e417f443-a199-bac1-86b0-0530e177fb54");
|
||||
mTexturep = LLViewerTextureManager::getFetchedTexture(imageAssetID);
|
||||
mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
*/
|
||||
mTexturep = NULL;
|
||||
}
|
||||
|
||||
LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
|
||||
: LLOutfitListGearMenuBase(olist)
|
||||
{
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
|
||||
{
|
||||
if (!mMenu) return;
|
||||
mMenu->setItemVisible("expand", FALSE);
|
||||
mMenu->setItemVisible("collapse", FALSE);
|
||||
mMenu->setItemVisible("upload_foto", TRUE);
|
||||
mMenu->setItemVisible("load_assets", TRUE);
|
||||
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onUploadFoto()
|
||||
{
|
||||
LLUUID selected_outfit_id = getSelectedOutfitID();
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && selected_outfit_id.notNull())
|
||||
{
|
||||
gallery->uploadPhoto(selected_outfit_id);
|
||||
}
|
||||
if (selected_outfit_id.notNull())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onLoadAssets()
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery != NULL)
|
||||
{
|
||||
gallery->loadPhotos();
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::loadPhotos()
|
||||
{
|
||||
//Iterate over inventory
|
||||
LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::EType::FT_TEXTURE);
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(textures);
|
||||
if (!category)
|
||||
return;
|
||||
|
||||
if (mTexturesObserver == NULL)
|
||||
{
|
||||
mTexturesObserver = new LLInventoryCategoriesObserver();
|
||||
gInventory.addObserver(mTexturesObserver);
|
||||
}
|
||||
|
||||
// Start observing changes in "My Outfits" category.
|
||||
mTexturesObserver->addCategory(textures,
|
||||
boost::bind(&LLOutfitGallery::refreshTextures, this, textures));
|
||||
|
||||
category->fetch();
|
||||
refreshTextures(textures);
|
||||
}
|
||||
|
||||
void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
// Collect all sub-categories of a given category.
|
||||
LLIsType is_texture(LLAssetType::AT_TEXTURE);
|
||||
gInventory.collectDescendentsIf(
|
||||
category_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_texture);
|
||||
|
||||
//Find textures which contain outfit UUID string in description
|
||||
LLInventoryModel::item_array_t uploaded_item_array;
|
||||
BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
|
||||
{
|
||||
std::string desc = item->getDescription();
|
||||
|
||||
LLUUID outfit_id(desc);
|
||||
|
||||
//Check whether description contains correct UUID of outfit
|
||||
if (outfit_id.isNull())
|
||||
continue;
|
||||
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
|
||||
{
|
||||
uploaded_item_array.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
uuid_vec_t vadded;
|
||||
uuid_vec_t vremoved;
|
||||
|
||||
// Create added and removed items vectors.
|
||||
computeDifferenceOfTextures(uploaded_item_array, vadded, vremoved);
|
||||
|
||||
BOOST_FOREACH(LLUUID item_id, vadded)
|
||||
{
|
||||
LLViewerInventoryItem* added_item = gInventory.getItem(item_id);
|
||||
LLUUID asset_id = added_item->getAssetUUID();
|
||||
std::string desc = added_item->getDescription();
|
||||
LLUUID outfit_id(desc);
|
||||
mOutfitMap[outfit_id]->setImageAssetId(asset_id);
|
||||
mTextureMap[outfit_id] = added_item;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(LLUUID item_id, vremoved)
|
||||
{
|
||||
LLViewerInventoryItem* rm_item = gInventory.getItem(item_id);
|
||||
std::string desc = rm_item->getDescription();
|
||||
LLUUID outfit_id(desc);
|
||||
mOutfitMap[outfit_id]->setDefaultImage();
|
||||
mTextureMap.erase(outfit_id);
|
||||
}
|
||||
|
||||
/*
|
||||
LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
|
||||
for ( ; it != item_array.end(); it++)
|
||||
{
|
||||
LLViewerInventoryItem* item = (*it);
|
||||
LLUUID asset_id = item->getAssetUUID();
|
||||
|
||||
std::string desc = item->getDescription();
|
||||
|
||||
LLUUID outfit_id(desc);
|
||||
|
||||
//Check whether description contains correct UUID of outfit
|
||||
if (outfit_id.isNull())
|
||||
continue;
|
||||
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
|
||||
{
|
||||
outfit_it->second->setImageAssetId(asset_id);
|
||||
mTextureMap[outfit_id] = item;
|
||||
}
|
||||
|
||||
|
||||
//LLUUID* item_idp = new LLUUID();
|
||||
|
||||
//gOutfitGallery = this;
|
||||
//const BOOL high_priority = TRUE;
|
||||
//gAssetStorage->getAssetData(asset_id,
|
||||
// LLAssetType::AT_TEXTURE,
|
||||
// onLoadComplete,
|
||||
// (void**)item_idp,
|
||||
// high_priority);
|
||||
//
|
||||
////mAssetStatus = PREVIEW_ASSET_LOADING;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LL_WARNS() << "asset_uuid: " << asset_uuid.asString() << LL_ENDL;
|
||||
|
||||
LLUUID* outfit_id = (LLUUID*)user_data;
|
||||
if (!user_data)
|
||||
return;
|
||||
LL_WARNS() << "outfit_id: " << outfit_id->asString() << LL_ENDL;
|
||||
|
||||
outfit_map_t::iterator it = gOutfitGallery->mOutfitMap.find(*outfit_id);
|
||||
if (it != gOutfitGallery->mOutfitMap.end() && !it->first.isNull())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
|
||||
{
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool add_successful = false;
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
|
||||
{
|
||||
std::string filename = picker.getFirstFile();
|
||||
LLLocalBitmap* unit = new LLLocalBitmap(filename);
|
||||
if (unit->getValid())
|
||||
{
|
||||
add_successful = true;
|
||||
LLAssetStorage::LLStoreAssetCallback callback = NULL;
|
||||
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
|
||||
void *nruserdata = NULL;
|
||||
nruserdata = (void *)&outfit_id;
|
||||
|
||||
LL_WARNS() << "selected_outfit_id: " << outfit_id.asString() << LL_ENDL;
|
||||
|
||||
//LLViewerInventoryItem *outfit = gInventory.getItem(selected_outfit_id);
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
|
||||
if (!outfit_cat) return;
|
||||
|
||||
checkRemovePhoto(outfit_id);
|
||||
|
||||
LLStringUtil::format_map_t foto_string_args;
|
||||
foto_string_args["OUTFIT_NAME"] = outfit_cat->getName();
|
||||
std::string display_name = getString("outfit_foto_string", foto_string_args);
|
||||
|
||||
upload_new_resource(filename, // file
|
||||
display_name,
|
||||
outfit_id.asString(),
|
||||
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
display_name, callback, expected_upload_cost, nruserdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
|
||||
{
|
||||
//remove existing photo of outfit from inventory
|
||||
texture_map_t::iterator texture_it = mTextureMap.find(outfit_id);
|
||||
if (texture_it != mTextureMap.end()) {
|
||||
gInventory.removeItem(texture_it->second->getUUID());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitGallery::computeDifferenceOfTextures(
|
||||
const LLInventoryModel::item_array_t& vtextures,
|
||||
uuid_vec_t& vadded,
|
||||
uuid_vec_t& vremoved)
|
||||
{
|
||||
uuid_vec_t vnew;
|
||||
// Creating a vector of newly collected sub-categories UUIDs.
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = vtextures.begin();
|
||||
iter != vtextures.end();
|
||||
iter++)
|
||||
{
|
||||
vnew.push_back((*iter)->getUUID());
|
||||
}
|
||||
|
||||
uuid_vec_t vcur;
|
||||
// Creating a vector of currently uploaded texture UUIDs.
|
||||
for (texture_map_t::const_iterator iter = mTextureMap.begin();
|
||||
iter != mTextureMap.end();
|
||||
iter++)
|
||||
{
|
||||
vcur.push_back((*iter).second->getUUID());
|
||||
}
|
||||
// getCurrentCategories(vcur);
|
||||
|
||||
LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* @file lloutfitgallery.h
|
||||
* @author Pavlo Kryvych
|
||||
* @brief Visual gallery of agent's outfits for My Appearance side panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2015, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLOUTFITGALLERYCTRL_H
|
||||
#define LL_LLOUTFITGALLERYCTRL_H
|
||||
|
||||
#include "llextendedstatus.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "lllayoutstack.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llpanelappearancetab.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class LLVFS;
|
||||
class LLOutfitGalleryItem;
|
||||
class LLOutfitListGearMenuBase;
|
||||
class LLOutfitGalleryGearMenu;
|
||||
|
||||
class LLOutfitGallery : public LLOutfitListBase
|
||||
{
|
||||
public:
|
||||
friend class LLOutfitGalleryGearMenu;
|
||||
LLOutfitGallery();
|
||||
virtual ~LLOutfitGallery();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& info);
|
||||
|
||||
/*virtual*/ void setFilterSubString(const std::string& string);
|
||||
|
||||
/*virtual*/ void getCurrentCategories(uuid_vec_t& vcur);
|
||||
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
|
||||
/*virtual*/ void updateRemovedCategory(LLUUID cat_id);
|
||||
/*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
|
||||
|
||||
/*virtual*/ bool hasItemSelected();
|
||||
/*virtual*/ bool canWearSelected();
|
||||
|
||||
/*virtual*/ bool getHasExpandableFolders() { return FALSE; }
|
||||
|
||||
void refreshTextures(const LLUUID& category_id);
|
||||
void computeDifferenceOfTextures(const LLInventoryModel::item_array_t& vtextures, uuid_vec_t& vadded, uuid_vec_t& vremoved);
|
||||
|
||||
protected:
|
||||
/*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
|
||||
/*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
|
||||
/*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
|
||||
/*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
|
||||
|
||||
/*virtual*/ void onCollapseAllFolders() {}
|
||||
/*virtual*/ void onExpandAllFolders() {}
|
||||
/*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
|
||||
|
||||
private:
|
||||
void rebuildGallery();
|
||||
void loadPhotos();
|
||||
void uploadPhoto(LLUUID outfit_id);
|
||||
bool checkRemovePhoto(LLUUID outfit_id);
|
||||
void setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id);
|
||||
|
||||
static void onLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
LLOutfitGalleryItem* buildGalleryItem(std::string name);
|
||||
LLLayoutPanel* buildLayoutPanel(int left);
|
||||
LLLayoutStack* buildLayoutStak(int left, int top);
|
||||
|
||||
LLView* mView;
|
||||
std::vector<LLLayoutStack*> mLayouts;
|
||||
std::vector<LLLayoutPanel*> mPanels;
|
||||
std::vector<LLOutfitGalleryItem*> mItems;
|
||||
|
||||
typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t;
|
||||
typedef outfit_map_t::value_type outfit_map_value_t;
|
||||
outfit_map_t mOutfitMap;
|
||||
typedef std::map<LLUUID, LLViewerInventoryItem*> texture_map_t;
|
||||
typedef texture_map_t::value_type texture_map_value_t;
|
||||
texture_map_t mTextureMap;
|
||||
|
||||
LLInventoryCategoriesObserver* mTexturesObserver;
|
||||
|
||||
};
|
||||
|
||||
//static LLOutfitGallery* gOutfitGallery;
|
||||
|
||||
class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase
|
||||
{
|
||||
public:
|
||||
friend class LLOutfitGallery;
|
||||
LLOutfitGalleryGearMenu(LLOutfitListBase* olist);
|
||||
|
||||
protected:
|
||||
/*virtual*/ void onUpdateItemsVisibility();
|
||||
|
||||
private:
|
||||
/*virtual*/ void onUploadFoto();
|
||||
/*virtual*/ void onLoadAssets();
|
||||
};
|
||||
|
||||
class LLOutfitGalleryItem : public LLPanel
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
|
||||
{};
|
||||
|
||||
LLOutfitGalleryItem(const Params& p);
|
||||
virtual ~LLOutfitGalleryItem();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
||||
void setDefaultImage();
|
||||
void setImageAssetId(LLUUID asset_id);
|
||||
void setOutfitName(std::string name);
|
||||
void setOutfitWorn(bool value);
|
||||
void setSelected(bool value);
|
||||
private:
|
||||
LLPointer<LLViewerTexture> mTexturep;
|
||||
LLTextBox* mOutfitNameText;
|
||||
LLTextBox* mOutfitWornText;
|
||||
};
|
||||
|
||||
#endif // LL_LLOUTFITGALLERYCTRL_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -32,11 +32,14 @@
|
|||
|
||||
// newview
|
||||
#include "llinventorymodel.h"
|
||||
#include "lllistcontextmenu.h"
|
||||
#include "llpanelappearancetab.h"
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "llviewermenu.h"
|
||||
|
||||
class LLAccordionCtrlTab;
|
||||
class LLInventoryCategoriesObserver;
|
||||
class LLOutfitListGearMenu;
|
||||
class LLOutfitListGearMenuBase;
|
||||
class LLWearableItemsList;
|
||||
class LLListContextMenu;
|
||||
|
||||
|
|
@ -57,6 +60,134 @@ public:
|
|||
/*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const;
|
||||
};
|
||||
|
||||
class LLOutfitListBase : public LLPanelAppearanceTab
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void(const LLUUID&)> selection_change_callback_t;
|
||||
typedef boost::signals2::signal<void(const LLUUID&)> selection_change_signal_t;
|
||||
|
||||
LLOutfitListBase();
|
||||
virtual ~LLOutfitListBase();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& info);
|
||||
|
||||
void refreshList(const LLUUID& category_id);
|
||||
void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
|
||||
// highlights currently worn outfit in list and unhighlights previously worn
|
||||
void highlightBaseOutfit();
|
||||
void ñhangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
|
||||
|
||||
|
||||
virtual void getCurrentCategories(uuid_vec_t& vcur) = 0;
|
||||
virtual void updateAddedCategory(LLUUID cat_id) = 0;
|
||||
virtual void updateRemovedCategory(LLUUID cat_id) = 0;
|
||||
virtual void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) = 0;
|
||||
virtual void sortOutfits();
|
||||
|
||||
void removeSelected();
|
||||
void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
|
||||
const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
|
||||
boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
|
||||
void outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
|
||||
|
||||
virtual bool isActionEnabled(const LLSD& userdata);
|
||||
virtual void performAction(std::string action);
|
||||
virtual bool hasItemSelected() = 0;
|
||||
virtual bool canWearSelected() = 0;
|
||||
|
||||
void signalSelectionOutfitUUID(const LLUUID& category_id);
|
||||
|
||||
void collapseAllFolders();
|
||||
virtual void onCollapseAllFolders() = 0;
|
||||
|
||||
void expandAllFolders();
|
||||
virtual void onExpandAllFolders() = 0;
|
||||
|
||||
virtual bool getHasExpandableFolders() = 0;
|
||||
|
||||
protected:
|
||||
virtual LLOutfitListGearMenuBase* createGearMenu() = 0;
|
||||
virtual void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) = 0;
|
||||
virtual void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) = 0;
|
||||
virtual void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) = 0;
|
||||
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
|
||||
virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0;
|
||||
|
||||
bool mIsInitialized;
|
||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
LLUUID mSelectedOutfitUUID;
|
||||
// id of currently highlited outfit
|
||||
LLUUID mHighlightedOutfitUUID;
|
||||
selection_change_signal_t mSelectionChangeSignal;
|
||||
LLListContextMenu* mOutfitMenu;
|
||||
LLOutfitListGearMenuBase* mGearMenu;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLOutfitContextMenu : public LLListContextMenu
|
||||
{
|
||||
public:
|
||||
|
||||
LLOutfitContextMenu(LLOutfitListBase* outfit_list)
|
||||
: LLListContextMenu(),
|
||||
mOutfitList(outfit_list)
|
||||
{}
|
||||
protected:
|
||||
/* virtual */ LLContextMenu* createMenu();
|
||||
|
||||
bool onEnable(LLSD::String param);
|
||||
|
||||
bool onVisible(LLSD::String param);
|
||||
|
||||
static void editOutfit();
|
||||
|
||||
static void renameOutfit(const LLUUID& outfit_cat_id);
|
||||
|
||||
private:
|
||||
LLOutfitListBase* mOutfitList;
|
||||
};
|
||||
|
||||
class LLOutfitListGearMenuBase
|
||||
{
|
||||
public:
|
||||
LLOutfitListGearMenuBase(LLOutfitListBase* olist);
|
||||
|
||||
void updateItemsVisibility();
|
||||
|
||||
LLToggleableMenu* getMenu();
|
||||
|
||||
protected:
|
||||
virtual void onUpdateItemsVisibility();
|
||||
virtual void onUploadFoto();
|
||||
virtual void onLoadAssets();
|
||||
const LLUUID& getSelectedOutfitID();
|
||||
|
||||
LLOutfitListBase* mOutfitList;
|
||||
LLToggleableMenu* mMenu;
|
||||
private:
|
||||
|
||||
LLViewerInventoryCategory* getSelectedOutfit();
|
||||
|
||||
void onWear();
|
||||
void onAdd();
|
||||
void onTakeOff();
|
||||
void onRename();
|
||||
void onCreate(const LLSD& data);
|
||||
bool onEnable(LLSD::String param);
|
||||
bool onVisible(LLSD::String param);
|
||||
};
|
||||
|
||||
class LLOutfitListGearMenu : public LLOutfitListGearMenuBase
|
||||
{
|
||||
public:
|
||||
LLOutfitListGearMenu(LLOutfitListBase* olist);
|
||||
|
||||
protected:
|
||||
/*virtual*/ void onUpdateItemsVisibility();
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLOutfitsList
|
||||
*
|
||||
|
|
@ -66,11 +197,9 @@ public:
|
|||
*
|
||||
* Starts fetching necessary inventory content on first opening.
|
||||
*/
|
||||
class LLOutfitsList : public LLPanelAppearanceTab
|
||||
class LLOutfitsList : public LLOutfitListBase
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (const LLUUID&)> selection_change_callback_t;
|
||||
typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t;
|
||||
|
||||
LLOutfitsList();
|
||||
virtual ~LLOutfitsList();
|
||||
|
|
@ -79,74 +208,72 @@ public:
|
|||
|
||||
/*virtual*/ void onOpen(const LLSD& info);
|
||||
|
||||
void refreshList(const LLUUID& category_id);
|
||||
|
||||
//virtual void refreshList(const LLUUID& category_id);
|
||||
|
||||
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
|
||||
/*virtual*/ void updateRemovedCategory(LLUUID cat_id);
|
||||
|
||||
// highlits currently worn outfit tab text and unhighlights previously worn
|
||||
void highlightBaseOutfit();
|
||||
/*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
|
||||
|
||||
void performAction(std::string action);
|
||||
//void performAction(std::string action);
|
||||
|
||||
void removeSelected();
|
||||
|
||||
void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
|
||||
|
||||
/*virtual*/ void setFilterSubString(const std::string& string);
|
||||
|
||||
/*virtual*/ bool isActionEnabled(const LLSD& userdata);
|
||||
|
||||
const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
|
||||
|
||||
/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
|
||||
|
||||
boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
|
||||
|
||||
// Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
|
||||
// Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
|
||||
void wearSelectedItems();
|
||||
|
||||
/**
|
||||
* Returns true if there is a selection inside currently selected outfit
|
||||
*/
|
||||
bool hasItemSelected();
|
||||
/*virtual*/ bool hasItemSelected();
|
||||
|
||||
/**
|
||||
Collapses all outfit accordions.
|
||||
*/
|
||||
void collapse_all_folders();
|
||||
/*virtual*/ void onCollapseAllFolders();
|
||||
/**
|
||||
Expands all outfit accordions.
|
||||
*/
|
||||
void expand_all_folders();
|
||||
void onExpandAllFolders();
|
||||
|
||||
/*virtual*/ bool getHasExpandableFolders() { return TRUE; }
|
||||
|
||||
protected:
|
||||
LLOutfitListGearMenuBase* createGearMenu();
|
||||
|
||||
private:
|
||||
|
||||
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/**
|
||||
* Wrapper for LLCommonUtils::computeDifference. @see LLCommonUtils::computeDifference
|
||||
*/
|
||||
void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
|
||||
//void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
|
||||
|
||||
void getCurrentCategories(uuid_vec_t& vcur);
|
||||
|
||||
/**
|
||||
* Updates tab displaying outfit identified by category_id.
|
||||
*/
|
||||
void updateOutfitTab(const LLUUID& category_id);
|
||||
/*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
|
||||
|
||||
/*virtual*/ void sortOutfits();
|
||||
|
||||
/*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
|
||||
|
||||
/**
|
||||
* Resets previous selection and stores newly selected list and outfit id.
|
||||
*/
|
||||
void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
|
||||
/*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
|
||||
|
||||
/**
|
||||
*Resets items selection inside outfit
|
||||
*/
|
||||
void resetItemSelection(LLWearableItemsList* list, const LLUUID& category_id);
|
||||
|
||||
/**
|
||||
* Saves newly selected outfit ID.
|
||||
*/
|
||||
void setSelectedOutfitUUID(const LLUUID& category_id);
|
||||
|
||||
/**
|
||||
* Removes the outfit from selection.
|
||||
*/
|
||||
|
|
@ -182,15 +309,16 @@ private:
|
|||
*/
|
||||
bool canWearSelected();
|
||||
|
||||
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
|
||||
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
|
||||
void onCOFChanged();
|
||||
|
||||
void onSelectionChange(LLUICtrl* ctrl);
|
||||
void onListSelectionChange(LLUICtrl* ctrl);
|
||||
|
||||
/*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
|
||||
|
||||
static void onOutfitRename(const LLSD& notification, const LLSD& response);
|
||||
|
||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
//LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||
|
||||
LLAccordionCtrl* mAccordion;
|
||||
LLPanel* mListCommands;
|
||||
|
|
@ -199,11 +327,6 @@ private:
|
|||
typedef wearables_lists_map_t::value_type wearables_lists_map_value_t;
|
||||
wearables_lists_map_t mSelectedListsMap;
|
||||
|
||||
LLUUID mSelectedOutfitUUID;
|
||||
// id of currently highlited outfit
|
||||
LLUUID mHighlightedOutfitUUID;
|
||||
selection_change_signal_t mSelectionChangeSignal;
|
||||
|
||||
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
|
||||
typedef outfits_map_t::value_type outfits_map_value_t;
|
||||
outfits_map_t mOutfitsMap;
|
||||
|
|
@ -212,10 +335,9 @@ private:
|
|||
// Used to monitor COF changes for updating items worn state. See EXT-8636.
|
||||
uuid_vec_t mCOFLinkedItems;
|
||||
|
||||
LLOutfitListGearMenu* mGearMenu;
|
||||
LLListContextMenu* mOutfitMenu;
|
||||
//LLOutfitListGearMenu* mGearMenu;
|
||||
|
||||
bool mIsInitialized;
|
||||
//bool mIsInitialized;
|
||||
/**
|
||||
* True if there is a selection inside currently selected outfit
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "lloutfitgallery.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llpanelwearing.h"
|
||||
#include "llsaveoutfitcombobtn.h"
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
#include "llviewerfoldertype.h"
|
||||
|
||||
static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
|
||||
static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";
|
||||
static const std::string COF_TAB_NAME = "cof_tab";
|
||||
|
||||
static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
|
||||
|
|
@ -268,12 +270,16 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
|
|||
|
||||
void LLPanelOutfitsInventory::initTabPanels()
|
||||
{
|
||||
//TODO: Add LLOutfitGallery change callback
|
||||
mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME);
|
||||
mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
|
||||
|
||||
mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME);
|
||||
mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
|
||||
|
||||
mOutfitGalleryPanel = findChild<LLOutfitGallery>(OUTFIT_GALLERY_TAB_NAME);
|
||||
mOutfitGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
|
||||
|
||||
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
|
||||
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@
|
|||
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLOutfitGallery;
|
||||
class LLOutfitsList;
|
||||
class LLOutfitListGearMenu;
|
||||
class LLOutfitListGearMenuBase;
|
||||
class LLPanelAppearanceTab;
|
||||
class LLPanelWearing;
|
||||
class LLMenuGL;
|
||||
|
|
@ -76,6 +77,7 @@ protected:
|
|||
private:
|
||||
LLPanelAppearanceTab* mActivePanel;
|
||||
LLOutfitsList* mMyOutfitsPanel;
|
||||
LLOutfitGallery* mOutfitGalleryPanel;
|
||||
LLPanelWearing* mCurrentOutfitPanel;
|
||||
|
||||
// tab panels //
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
#include "llradiogroup.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lllocalbitmaps.h"
|
||||
#include "llerror.h"
|
||||
|
||||
static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
|
||||
static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
|
||||
|
|
@ -573,6 +574,7 @@ void LLFloaterTexturePicker::draw()
|
|||
mTexturep = NULL;
|
||||
if(mImageAssetID.notNull())
|
||||
{
|
||||
LL_WARNS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
|
||||
mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
|
||||
mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -804,4 +804,5 @@ with the same filename but different name
|
|||
<texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
|
||||
<texture name="NavBar Separator" file_name="navbar/separator.png"/>
|
||||
|
||||
<texture name="Outfit_Default_Foto" fileName="icons/pop_up_caution.png"/>
|
||||
</textures>
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@
|
|||
width="400"
|
||||
height="400"
|
||||
follows="top|left"/>
|
||||
<view_border
|
||||
<!--view_border
|
||||
bevel_style="in"
|
||||
height="21"
|
||||
layout="topleft"
|
||||
|
|
@ -414,7 +414,7 @@
|
|||
top_pad="0"
|
||||
right="-10"
|
||||
follows="left|top|right"
|
||||
left_delta="0"/>
|
||||
left_delta="0"/>-->
|
||||
<text
|
||||
type="string"
|
||||
font="SansSerifSmall"
|
||||
|
|
|
|||
|
|
@ -39,8 +39,22 @@
|
|||
function="Gear.OnVisible"
|
||||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Upload foto"
|
||||
layout="topleft"
|
||||
name="upload_foto">
|
||||
<on_click
|
||||
function="Gear.UploadFoto" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Load assets"
|
||||
layout="topleft"
|
||||
name="load_assets">
|
||||
<on_click
|
||||
function="Gear.LoadAssets" />
|
||||
</menu_item_call>
|
||||
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<!-- copied (with minor modifications) from menu_inventory_add.xml -->
|
||||
<!-- *TODO: generate dynamically? -->
|
||||
<menu
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
background_visible="true"
|
||||
bg_alpha_color="DkGray"
|
||||
border="false"
|
||||
follows="all"
|
||||
height="430"
|
||||
name="Outfit Gallery"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0"
|
||||
width="312">
|
||||
<string name="outfit_foto_string">
|
||||
Foto of "[OUTFIT_NAME]" outfit
|
||||
</string>
|
||||
<scroll_container
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="400"
|
||||
width="312"
|
||||
min_width="312"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
top="0"
|
||||
name="gallery_scroll_panel"
|
||||
opaque="false"
|
||||
top_pad="0">
|
||||
<panel
|
||||
background_visible="true"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="560"
|
||||
width="312"
|
||||
layout="topleft"
|
||||
top="0"
|
||||
left="4"
|
||||
top_pad="0"
|
||||
visible="true"
|
||||
name="gallery_panel">
|
||||
<!--outfit_gallery_item
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="preview_outfit1"
|
||||
height="175"
|
||||
width="150"
|
||||
follows="left|top"/-->
|
||||
<!--layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="0" name="top_gallery_stack" orientation="horizontal">
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
<layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="190" name="top_gallery_stack" orientation="horizontal">
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
<layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="380" name="top_gallery_stack" orientation="horizontal">
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
|
||||
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
|
||||
</layout_panel>
|
||||
</layout_stack-->
|
||||
</panel>
|
||||
</scroll_container>
|
||||
<panel
|
||||
background_visible="true"
|
||||
follows="bottom|left|right"
|
||||
height="28"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
top_pad="0"
|
||||
visible="true"
|
||||
name="bottom_panel"
|
||||
width="312">
|
||||
<menu_button
|
||||
follows="bottom|left"
|
||||
tool_tip="Show additional options"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Left_Over"
|
||||
image_overlay="OptionsMenu_Off"
|
||||
image_selected="Toolbar_Left_Selected"
|
||||
image_unselected="Toolbar_Left_Off"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="options_gear_btn"
|
||||
top="1"
|
||||
width="31" />
|
||||
<icon
|
||||
follows="bottom|left|right"
|
||||
height="25"
|
||||
image_name="Toolbar_Middle_Off"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="dummy_icon"
|
||||
width="243"/>
|
||||
<button
|
||||
follows="bottom|right"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Right_Over"
|
||||
image_overlay="TrashItem_Off"
|
||||
image_selected="Toolbar_Right_Selected"
|
||||
image_unselected="Toolbar_Right_Off"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="trash_btn"
|
||||
tool_tip="Delete selected outfit"
|
||||
width="31"/>
|
||||
</panel>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
background_visible="true"
|
||||
bg_alpha_color="DkGray"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="left|top"
|
||||
height="169"
|
||||
width="149"
|
||||
name="Outfit Gallery Item"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0"
|
||||
>
|
||||
<icon
|
||||
left="0"
|
||||
top="0"
|
||||
layout="topleft"
|
||||
name="preview_outfit"
|
||||
height="149"
|
||||
width="149"
|
||||
follows="left|top"
|
||||
visible="true"
|
||||
image_name="Popup_Caution"
|
||||
/>
|
||||
<text
|
||||
length="1"
|
||||
follows="left|top"
|
||||
left="1"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
name="outfit_name"
|
||||
top="150"
|
||||
width="150">
|
||||
Summer hipster, Pierce
|
||||
</text>
|
||||
<text
|
||||
length="1"
|
||||
follows="left|top"
|
||||
left="1"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
name="outfit_worn_text"
|
||||
top="160"
|
||||
width="150">
|
||||
(worn)
|
||||
</text>
|
||||
|
||||
</panel>
|
||||
|
|
@ -32,6 +32,17 @@
|
|||
halign="center"
|
||||
top="8"
|
||||
width="315">
|
||||
<panel
|
||||
class="outfit_gallery"
|
||||
filename="panel_outfit_gallery.xml"
|
||||
height="520"
|
||||
name="outfit_gallery_tab"
|
||||
background_visible="true"
|
||||
help_topic="outfit_gallery_tab"
|
||||
follows="all"
|
||||
label="OUTFIT GALLERY"
|
||||
layout="topleft"
|
||||
width="315" />
|
||||
<panel
|
||||
class="outfits_list"
|
||||
filename="panel_outfits_list.xml"
|
||||
|
|
|
|||
Loading…
Reference in New Issue