View of /trunk/linden/indra/newview/llfloaterclothing.cpp
Parent Directory
|
Revision Log
Revision 61 -
(download)
(annotate)
Wed Nov 19 01:37:16 2008 UTC (4 years, 6 months ago) by mjm
File size: 10191 byte(s)
Wed Nov 19 01:37:16 2008 UTC (4 years, 6 months ago) by mjm
File size: 10191 byte(s)
Copy Linden relase 1.21 to trunk for further patching.
/**
* @file llfloaterclothing.cpp
* @author James Cook
* @brief Read-only list of clothing from your inventory.
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
* Copyright (c) 2004-2008, 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 "llfloaterclothing.h"
#include "lldir.h"
#include "llinventory.h"
#include "llagent.h"
#include "llinventorymodel.h"
#include "llinventoryview.h"
#include "llkeyboard.h"
#include "llscrollbar.h"
#include "llscrolllistctrl.h"
#include "lluictrlfactory.h"
#include "llviewerinventory.h"
#include "llvoavatar.h"
#include "llviewercontrol.h"
const std::string LOADING_STRING("Loading...");
// static
LLFloaterClothing* LLFloaterClothing::sInstance = NULL;
LLFloaterClothingObserver* LLFloaterClothing::sObserver = NULL;
class LLFloaterClothingObserver : public LLInventoryObserver
{
public:
LLFloaterClothingObserver() {}
virtual ~LLFloaterClothingObserver() {}
virtual void changed(U32 mask)
{
LLFloaterClothing::refreshAll();
}
};
//---------------------------------------------------------------------------
// LLFloaterClothing
//---------------------------------------------------------------------------
LLFloaterClothing::LLFloaterClothing()
: LLFloater(std::string("floater_clothing"), std::string("FloaterClothingRect"), LLStringUtil::null),
mSelectedID(),
mAllowSelection(FALSE)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_clothing.xml");
sInstance = this;
sObserver = new LLFloaterClothingObserver;
gInventory.addObserver(sObserver);
childSetAction("take_off_btn", onClickTakeOff, this);
childSetAction("wear_btn", onClickWear, this);
childSetDoubleClickCallback("clothing_list", onClickWear);
childSetCommitCallback("clothing_list", onCommitList, this);
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("clothing_list");
if (list)
{
list->addCommentText(LOADING_STRING);
}
setDefaultBtn("wear_btn");
gInventory.startBackgroundFetch();
}
// virtual
LLFloaterClothing::~LLFloaterClothing()
{
gInventory.removeObserver(sObserver);
delete sObserver;
sObserver = NULL;
sInstance = NULL;
}
// virtual
void LLFloaterClothing::onClose(bool app_quitting)
{
gSavedSettings.setBOOL("ClothingBtnState", FALSE);
LLFloater::onClose(app_quitting);
}
// static
void LLFloaterClothing::show(void*)
{
if (sInstance)
{
sInstance->setVisibleAndFrontmost();
}
else
{
LLFloaterClothing *self = new LLFloaterClothing();
self->buildClothingList();
if (self->mAllowSelection)
{
LLCtrlSelectionInterface* iface = self->childGetSelectionInterface("clothing_list");
if (iface) iface->selectFirstItem();
}
self->childSetFocus("clothing_list");
self->mSelectedID = LLUUID::null;
// Update button labels
onCommitList(NULL, self);
}
gSavedSettings.setBOOL("ClothingBtnState", TRUE);
}
// static
void LLFloaterClothing::toggleVisibility()
{
if(sInstance && sInstance->getVisible())
{
sInstance->close();
}
else
{
show();
}
}
// static
void LLFloaterClothing::refreshAll()
{
if (sInstance)
{
sInstance->buildClothingList();
LLCtrlListInterface* list = sInstance->childGetListInterface("clothing_list");
if (list)
{
if (!sInstance->mAllowSelection)
{
// no selection, no commit on change
list->operateOnSelection(LLCtrlListInterface::OP_DESELECT);
}
else if (sInstance->mSelectedID.isNull())
{
list->selectFirstItem();
}
else
{
if (list->setCurrentByID(sInstance->mSelectedID))
{
LLCtrlScrollInterface *scroll = sInstance->childGetScrollInterface("clothing_list");
if (scroll)
{
scroll->scrollToShowSelected();
}
}
else
{
list->selectFirstItem();
}
}
// Update button labels
onCommitList(NULL, sInstance);
}
}
}
class LLIsClothing : public LLInventoryCollectFunctor
{
public:
LLIsClothing() {}
virtual ~LLIsClothing() {}
virtual bool operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
if (item)
{
LLAssetType::EType at = item->getType();
if (at == LLAssetType::AT_CLOTHING
|| at == LLAssetType::AT_BODYPART)
{
U32 flags = item->getFlags();
switch(flags)
{
case WT_SHAPE:
case WT_SKIN:
case WT_HAIR:
case WT_EYES:
return FALSE;
case WT_SHIRT:
case WT_PANTS:
case WT_SKIRT:
case WT_UNDERSHIRT:
case WT_UNDERPANTS:
return TRUE;
default:
return TRUE;
}
}
}
return FALSE;
}
};
void LLFloaterClothing::buildClothingList()
{
//llinfos << "buildClothingList" << llendl;
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("clothing_list");
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLIsClothing is_clothing;
gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_clothing);
S32 count = items.count();
for(S32 i = 0; i < count; ++i)
{
LLInventoryItem* item = items.get(i);
LLSD row;
row["id"] = item->getUUID();
BOOL item_is_multi = FALSE;
if ( item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
{
item_is_multi = TRUE;
}
std::string icon_name = get_item_icon_name(item->getType(),
item->getInventoryType(),
item->getFlags(), item_is_multi); // flags = wearable type
row["columns"][0]["column"] = "icon";
row["columns"][0]["type"] = "icon";
row["columns"][0]["value"] = icon_name;
std::string text = item->getName();
std::string style = "NORMAL";
if( gAgent.isWearingItem( item->getUUID() ) )
{
text.append(" (worn)");
style = "BOLD";
}
row["columns"][1]["column"] = "name";
row["columns"][1]["value"] = text;
row["columns"][1]["font"] = "SANSSERIFSMALL";
row["columns"][1]["font-style"] = style;
// hidden column for sorting
U32 flags = item->getFlags(); // flags = wearable type
enum EWearableType wearable_type = (enum EWearableType)flags;
const std::string& wearable_label = LLWearable::typeToTypeLabel(wearable_type);
//line->addColumn(wearable_label, FONT, -1); // invisible
row["columns"][2]["column"] = "sort";
row["columns"][2]["value"] = wearable_label;
list->addElement(row);
}
if (count > 0)
{
mAllowSelection = TRUE;
}
else if (LLInventoryModel::backgroundFetchActive())
{
// We're loading
list->addCommentText(LOADING_STRING);
mAllowSelection = FALSE;
}
else
{
// Weird case, we're done loading but have no clothing
list->addCommentText(std::string("No clothing found.")); // *TODO: Translate
mAllowSelection = FALSE;
}
}
// static
void LLFloaterClothing::onClickWear(void* data)
{
LLFloaterClothing* self = (LLFloaterClothing*)data;
const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
LLViewerInventoryItem* inv_item = gInventory.getItem(item_id);
if (!inv_item)
{
llwarns << "Can't find inventory item to wear" << llendl;
return;
}
wear_inventory_item_on_avatar(inv_item);
}
BOOL wearable_can_take_off(EWearableType wearable_type)
{
switch(wearable_type)
{
default:
case WT_SHAPE:
case WT_SKIN:
case WT_HAIR:
case WT_EYES:
return FALSE;
case WT_SHIRT:
case WT_PANTS:
case WT_SHOES:
case WT_SOCKS:
case WT_JACKET:
case WT_GLOVES:
case WT_SKIRT:
return TRUE;
case WT_UNDERSHIRT:
case WT_UNDERPANTS:
// can't take off underpants with PG accounts
return (!gAgent.isTeen());
}
}
// static
void LLFloaterClothing::onClickTakeOff(void* data)
{
LLFloaterClothing* self = (LLFloaterClothing*)data;
const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
LLInventoryItem* inv_item = gInventory.getItem(item_id);
if (!inv_item)
{
llwarns << "Can't find inventory item to wear" << llendl;
return;
}
LLVOAvatar* avatar = gAgent.getAvatarObject();
if( !avatar ) return;
EWearableType wearable_type = (EWearableType)inv_item->getFlags();
// Can only take off certain types
if (!wearable_can_take_off(wearable_type)) return;
LLWearable* wearable = gAgent.getWearable(wearable_type);
if( !wearable ) return;
gAgent.removeWearable(wearable_type);
}
// static
void LLFloaterClothing::onCommitList(LLUICtrl* ctrl, void* data)
{
LLFloaterClothing* self = (LLFloaterClothing*)data;
const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
self->mSelectedID = item_id;
LLVOAvatar* avatar = gAgent.getAvatarObject();
if( !avatar ) return;
if(gAgent.isWearingItem( item_id ) )
{
// If already wearing, can't wear again
self->childDisable("wear_btn");
LLInventoryItem* inv_item = gInventory.getItem(item_id);
if (!inv_item) return;
EWearableType wearable_type = (EWearableType)inv_item->getFlags();
BOOL can_take_off = wearable_can_take_off(wearable_type);
self->childSetEnabled("take_off_btn", can_take_off);
}
else
{
// Can always wear something you're not wearing now
self->childEnable("wear_btn");
self->childEnable("take_off_btn");
}
}
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

