aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterclothing.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llfloaterclothing.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to 'linden/indra/newview/llfloaterclothing.cpp')
-rw-r--r--linden/indra/newview/llfloaterclothing.cpp423
1 files changed, 0 insertions, 423 deletions
diff --git a/linden/indra/newview/llfloaterclothing.cpp b/linden/indra/newview/llfloaterclothing.cpp
deleted file mode 100644
index b86acba..0000000
--- a/linden/indra/newview/llfloaterclothing.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
1/**
2 * @file llfloaterclothing.cpp
3 * @author James Cook
4 * @brief Read-only list of clothing from your inventory.
5 *
6 * $LicenseInfo:firstyear=2004&license=viewergpl$
7 *
8 * Copyright (c) 2004-2009, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
17 *
18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 * $/LicenseInfo$
31 */
32
33#include "llviewerprecompiledheaders.h"
34
35#include "llfloaterclothing.h"
36
37#include "lldir.h"
38#include "llinventory.h"
39
40#include "llagent.h"
41#include "llinventorymodel.h"
42#include "llinventoryview.h"
43#include "llkeyboard.h"
44#include "llscrollbar.h"
45#include "llscrolllistctrl.h"
46#include "lluictrlfactory.h"
47#include "llviewerinventory.h"
48#include "llvoavatar.h"
49#include "llviewercontrol.h"
50
51const std::string LOADING_STRING("Loading...");
52
53// static
54LLFloaterClothing* LLFloaterClothing::sInstance = NULL;
55LLFloaterClothingObserver* LLFloaterClothing::sObserver = NULL;
56
57class LLFloaterClothingObserver : public LLInventoryObserver
58{
59public:
60 LLFloaterClothingObserver() {}
61 virtual ~LLFloaterClothingObserver() {}
62
63 virtual void changed(U32 mask)
64 {
65 LLFloaterClothing::refreshAll();
66 }
67};
68
69//---------------------------------------------------------------------------
70// LLFloaterClothing
71//---------------------------------------------------------------------------
72LLFloaterClothing::LLFloaterClothing()
73: LLFloater(std::string("floater_clothing"), std::string("FloaterClothingRect"), LLStringUtil::null),
74 mSelectedID(),
75 mAllowSelection(FALSE)
76{
77 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_clothing.xml");
78
79 sInstance = this;
80
81 sObserver = new LLFloaterClothingObserver;
82 gInventory.addObserver(sObserver);
83
84 childSetAction("take_off_btn", onClickTakeOff, this);
85 childSetAction("wear_btn", onClickWear, this);
86
87 childSetDoubleClickCallback("clothing_list", onClickWear);
88 childSetCommitCallback("clothing_list", onCommitList, this);
89
90 LLScrollListCtrl* list = getChild<LLScrollListCtrl>("clothing_list");
91 if (list)
92 {
93 list->addCommentText(LOADING_STRING);
94 }
95
96 setDefaultBtn("wear_btn");
97
98 gInventory.startBackgroundFetch();
99}
100
101// virtual
102LLFloaterClothing::~LLFloaterClothing()
103{
104 gInventory.removeObserver(sObserver);
105 delete sObserver;
106 sObserver = NULL;
107
108 sInstance = NULL;
109}
110
111
112// virtual
113void LLFloaterClothing::onClose(bool app_quitting)
114{
115 gSavedSettings.setBOOL("ClothingBtnState", FALSE);
116
117 LLFloater::onClose(app_quitting);
118}
119
120
121// static
122void LLFloaterClothing::show(void*)
123{
124 if (sInstance)
125 {
126 sInstance->setVisibleAndFrontmost();
127 }
128 else
129 {
130 LLFloaterClothing *self = new LLFloaterClothing();
131
132 self->buildClothingList();
133
134 if (self->mAllowSelection)
135 {
136 LLCtrlSelectionInterface* iface = self->childGetSelectionInterface("clothing_list");
137 if (iface) iface->selectFirstItem();
138 }
139 self->childSetFocus("clothing_list");
140
141 self->mSelectedID = LLUUID::null;
142
143 // Update button labels
144 onCommitList(NULL, self);
145 }
146
147 gSavedSettings.setBOOL("ClothingBtnState", TRUE);
148}
149
150// static
151void LLFloaterClothing::toggleVisibility()
152{
153 if(sInstance && sInstance->getVisible())
154 {
155 sInstance->close();
156 }
157 else
158 {
159 show();
160 }
161}
162
163// static
164void LLFloaterClothing::refreshAll()
165{
166 if (sInstance)
167 {
168 sInstance->buildClothingList();
169
170 LLCtrlListInterface* list = sInstance->childGetListInterface("clothing_list");
171 if (list)
172 {
173 if (!sInstance->mAllowSelection)
174 {
175 // no selection, no commit on change
176 list->operateOnSelection(LLCtrlListInterface::OP_DESELECT);
177 }
178 else if (sInstance->mSelectedID.isNull())
179 {
180 list->selectFirstItem();
181 }
182 else
183 {
184 if (list->setCurrentByID(sInstance->mSelectedID))
185 {
186 LLCtrlScrollInterface *scroll = sInstance->childGetScrollInterface("clothing_list");
187 if (scroll)
188 {
189 scroll->scrollToShowSelected();
190 }
191 }
192 else
193 {
194 list->selectFirstItem();
195 }
196 }
197
198 // Update button labels
199 onCommitList(NULL, sInstance);
200 }
201 }
202}
203
204class LLIsClothing : public LLInventoryCollectFunctor
205{
206public:
207 LLIsClothing() {}
208 virtual ~LLIsClothing() {}
209 virtual bool operator()(LLInventoryCategory* cat,
210 LLInventoryItem* item)
211 {
212 if (item)
213 {
214 LLAssetType::EType at = item->getType();
215 if (at == LLAssetType::AT_CLOTHING
216 || at == LLAssetType::AT_BODYPART)
217 {
218 U32 flags = item->getFlags();
219 switch(flags)
220 {
221 case WT_SHAPE:
222 case WT_SKIN:
223 case WT_HAIR:
224 case WT_EYES:
225 return FALSE;
226 case WT_SHIRT:
227 case WT_PANTS:
228 case WT_SKIRT:
229 case WT_UNDERSHIRT:
230 case WT_UNDERPANTS:
231 return TRUE;
232 default:
233 return TRUE;
234 }
235 }
236 }
237 return FALSE;
238 }
239};
240
241
242
243void LLFloaterClothing::buildClothingList()
244{
245 //llinfos << "buildClothingList" << llendl;
246
247 LLScrollListCtrl* list = getChild<LLScrollListCtrl>("clothing_list");
248
249 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
250
251 LLInventoryModel::cat_array_t cats;
252 LLInventoryModel::item_array_t items;
253
254 LLIsClothing is_clothing;
255 gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
256 cats,
257 items,
258 LLInventoryModel::EXCLUDE_TRASH,
259 is_clothing);
260
261 S32 count = items.count();
262 for(S32 i = 0; i < count; ++i)
263 {
264 LLInventoryItem* item = items.get(i);
265
266 LLSD row;
267 row["id"] = item->getUUID();
268
269 BOOL item_is_multi = FALSE;
270 if ( item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
271 {
272 item_is_multi = TRUE;
273 }
274
275 std::string icon_name = get_item_icon_name(item->getType(),
276 item->getInventoryType(),
277 item->getFlags(), item_is_multi); // flags = wearable type
278 row["columns"][0]["column"] = "icon";
279 row["columns"][0]["type"] = "icon";
280 row["columns"][0]["value"] = icon_name;
281
282 std::string text = item->getName();
283 std::string style = "NORMAL";
284 if( gAgent.isWearingItem( item->getUUID() ) )
285 {
286 text.append(" (worn)");
287 style = "BOLD";
288 }
289 row["columns"][1]["column"] = "name";
290 row["columns"][1]["value"] = text;
291 row["columns"][1]["font"] = "SANSSERIFSMALL";
292 row["columns"][1]["font-style"] = style;
293
294 // hidden column for sorting
295 U32 flags = item->getFlags(); // flags = wearable type
296 enum EWearableType wearable_type = (enum EWearableType)flags;
297 const std::string& wearable_label = LLWearable::typeToTypeLabel(wearable_type);
298 //line->addColumn(wearable_label, FONT, -1); // invisible
299 row["columns"][2]["column"] = "sort";
300 row["columns"][2]["value"] = wearable_label;
301
302 list->addElement(row);
303 }
304
305 if (count > 0)
306 {
307 mAllowSelection = TRUE;
308 }
309 else if (LLInventoryModel::backgroundFetchActive())
310 {
311 // We're loading
312 list->addCommentText(LOADING_STRING);
313 mAllowSelection = FALSE;
314 }
315 else
316 {
317 // Weird case, we're done loading but have no clothing
318 list->addCommentText(std::string("No clothing found.")); // *TODO: Translate
319 mAllowSelection = FALSE;
320 }
321}
322
323// static
324void LLFloaterClothing::onClickWear(void* data)
325{
326 LLFloaterClothing* self = (LLFloaterClothing*)data;
327
328 const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
329
330 LLViewerInventoryItem* inv_item = gInventory.getItem(item_id);
331 if (!inv_item)
332 {
333 llwarns << "Can't find inventory item to wear" << llendl;
334 return;
335 }
336
337 wear_inventory_item_on_avatar(inv_item);
338}
339
340BOOL wearable_can_take_off(EWearableType wearable_type)
341{
342 switch(wearable_type)
343 {
344 default:
345 case WT_SHAPE:
346 case WT_SKIN:
347 case WT_HAIR:
348 case WT_EYES:
349 return FALSE;
350 case WT_SHIRT:
351 case WT_PANTS:
352 case WT_SHOES:
353 case WT_SOCKS:
354 case WT_JACKET:
355 case WT_GLOVES:
356 case WT_SKIRT:
357 return TRUE;
358 case WT_UNDERSHIRT:
359 case WT_UNDERPANTS:
360 // can't take off underpants with PG accounts
361 return (!gAgent.isTeen());
362 }
363}
364
365// static
366void LLFloaterClothing::onClickTakeOff(void* data)
367{
368 LLFloaterClothing* self = (LLFloaterClothing*)data;
369
370 const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
371
372 LLInventoryItem* inv_item = gInventory.getItem(item_id);
373 if (!inv_item)
374 {
375 llwarns << "Can't find inventory item to wear" << llendl;
376 return;
377 }
378
379 LLVOAvatar* avatar = gAgent.getAvatarObject();
380 if( !avatar ) return;
381
382 EWearableType wearable_type = (EWearableType)inv_item->getFlags();
383
384 // Can only take off certain types
385 if (!wearable_can_take_off(wearable_type)) return;
386
387 LLWearable* wearable = gAgent.getWearable(wearable_type);
388 if( !wearable ) return;
389
390 gAgent.removeWearable(wearable_type);
391}
392
393
394// static
395void LLFloaterClothing::onCommitList(LLUICtrl* ctrl, void* data)
396{
397 LLFloaterClothing* self = (LLFloaterClothing*)data;
398
399 const LLUUID& item_id = self->childGetValue("clothing_list").asUUID();
400 self->mSelectedID = item_id;
401
402 LLVOAvatar* avatar = gAgent.getAvatarObject();
403 if( !avatar ) return;
404
405 if(gAgent.isWearingItem( item_id ) )
406 {
407 // If already wearing, can't wear again
408 self->childDisable("wear_btn");
409
410 LLInventoryItem* inv_item = gInventory.getItem(item_id);
411 if (!inv_item) return;
412
413 EWearableType wearable_type = (EWearableType)inv_item->getFlags();
414 BOOL can_take_off = wearable_can_take_off(wearable_type);
415 self->childSetEnabled("take_off_btn", can_take_off);
416 }
417 else
418 {
419 // Can always wear something you're not wearing now
420 self->childEnable("wear_btn");
421 self->childEnable("take_off_btn");
422 }
423}