diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloateravatarpicker.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llfloateravatarpicker.cpp')
-rw-r--r-- | linden/indra/newview/llfloateravatarpicker.cpp | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloateravatarpicker.cpp b/linden/indra/newview/llfloateravatarpicker.cpp new file mode 100644 index 0000000..c95ac6b --- /dev/null +++ b/linden/indra/newview/llfloateravatarpicker.cpp | |||
@@ -0,0 +1,393 @@ | |||
1 | /** | ||
2 | * @file llfloateravatarpicker.cpp | ||
3 | * | ||
4 | * Copyright (c) 2003-2007, Linden Research, Inc. | ||
5 | * | ||
6 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
7 | * to you under the terms of the GNU General Public License, version 2.0 | ||
8 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
9 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
10 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
11 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
12 | * | ||
13 | * There are special exceptions to the terms and conditions of the GPL as | ||
14 | * it is applied to this Source Code. View the full text of the exception | ||
15 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
16 | * online at http://secondlife.com/developers/opensource/flossexception | ||
17 | * | ||
18 | * By copying, modifying or distributing this software, you acknowledge | ||
19 | * that you have read and understood your obligations described above, | ||
20 | * and agree to abide by those obligations. | ||
21 | * | ||
22 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
23 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
24 | * COMPLETENESS OR PERFORMANCE. | ||
25 | */ | ||
26 | |||
27 | #include "llviewerprecompiledheaders.h" | ||
28 | |||
29 | #include "llfloateravatarpicker.h" | ||
30 | |||
31 | #include "message.h" | ||
32 | |||
33 | #include "llbutton.h" | ||
34 | #include "llfocusmgr.h" | ||
35 | #include "llinventoryview.h" | ||
36 | #include "llinventorymodel.h" | ||
37 | #include "lllineeditor.h" | ||
38 | #include "llscrolllistctrl.h" | ||
39 | #include "lltextbox.h" | ||
40 | #include "llvieweruictrlfactory.h" | ||
41 | #include "viewer.h" | ||
42 | |||
43 | const S32 MIN_WIDTH = 200; | ||
44 | const S32 MIN_HEIGHT = 340; | ||
45 | const LLRect FLOATER_RECT(0, 380, 240, 0); | ||
46 | const char FLOATER_TITLE[] = "Choose Person"; | ||
47 | |||
48 | // static | ||
49 | LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL; | ||
50 | |||
51 | |||
52 | LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, | ||
53 | void* userdata, | ||
54 | BOOL allow_multiple, | ||
55 | BOOL closeOnSelect) | ||
56 | { | ||
57 | if (!sInstance) | ||
58 | { | ||
59 | sInstance = new LLFloaterAvatarPicker(); | ||
60 | sInstance->mCallback = callback; | ||
61 | sInstance->mCallbackUserdata = userdata; | ||
62 | sInstance->mCloseOnSelect = FALSE; | ||
63 | |||
64 | sInstance->open(); | ||
65 | sInstance->center(); | ||
66 | sInstance->setAllowMultiple(allow_multiple); | ||
67 | } | ||
68 | else | ||
69 | { | ||
70 | sInstance->open(); | ||
71 | sInstance->mCallback = callback; | ||
72 | sInstance->mCallbackUserdata = userdata; | ||
73 | sInstance->setAllowMultiple(allow_multiple); | ||
74 | } | ||
75 | |||
76 | sInstance->mCloseOnSelect = closeOnSelect; | ||
77 | return sInstance; | ||
78 | } | ||
79 | |||
80 | // Default constructor | ||
81 | LLFloaterAvatarPicker::LLFloaterAvatarPicker() : | ||
82 | LLFloater("avatarpicker", FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT), | ||
83 | mResultsReturned(FALSE), | ||
84 | mCallback(NULL), | ||
85 | mCallbackUserdata(NULL) | ||
86 | { | ||
87 | gUICtrlFactory->buildFloater(this, "floater_avatar_picker.xml", NULL); | ||
88 | } | ||
89 | |||
90 | BOOL LLFloaterAvatarPicker::postBuild() | ||
91 | { | ||
92 | childSetKeystrokeCallback("Edit", editKeystroke, this); | ||
93 | |||
94 | childSetAction("Find", onBtnFind, this); | ||
95 | childDisable("Find"); | ||
96 | |||
97 | mListNames = LLViewerUICtrlFactory::getScrollListByName(this, "Names"); | ||
98 | childSetDoubleClickCallback("Names",onBtnAdd); | ||
99 | childSetCommitCallback("Names", onList, this); | ||
100 | childDisable("Names"); | ||
101 | |||
102 | childSetAction("Select", onBtnAdd, this); | ||
103 | childDisable("Select"); | ||
104 | |||
105 | childSetAction("Close", onBtnClose, this); | ||
106 | |||
107 | childSetFocus("Edit"); | ||
108 | |||
109 | if (mListNames) | ||
110 | { | ||
111 | LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null ); | ||
112 | row->addColumn("No results", LLFontGL::sSansSerif); | ||
113 | mListNames->addItem(row); | ||
114 | } | ||
115 | |||
116 | mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("Inventory Panel", WIDGET_TYPE_INVENTORY_PANEL); | ||
117 | if(mInventoryPanel) | ||
118 | { | ||
119 | mInventoryPanel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD); | ||
120 | mInventoryPanel->setFollowsAll(); | ||
121 | mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); | ||
122 | mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); | ||
123 | mInventoryPanel->setSelectCallback(LLFloaterAvatarPicker::onSelectionChange, this); | ||
124 | } | ||
125 | |||
126 | setAllowMultiple(FALSE); | ||
127 | |||
128 | return TRUE; | ||
129 | } | ||
130 | |||
131 | // Destroys the object | ||
132 | LLFloaterAvatarPicker::~LLFloaterAvatarPicker() | ||
133 | { | ||
134 | gFocusMgr.releaseFocusIfNeeded( this ); | ||
135 | |||
136 | sInstance = NULL; | ||
137 | } | ||
138 | |||
139 | void LLFloaterAvatarPicker::onBtnFind(void* userdata) | ||
140 | { | ||
141 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
142 | if(self) self->find(); | ||
143 | } | ||
144 | |||
145 | void LLFloaterAvatarPicker::onBtnAdd(void* userdata) | ||
146 | { | ||
147 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
148 | |||
149 | if(self->mCallback) | ||
150 | { | ||
151 | self->mCallback(self->mAvatarNames, self->mAvatarIDs, self->mCallbackUserdata); | ||
152 | } | ||
153 | if (self->mInventoryPanel) | ||
154 | { | ||
155 | self->mInventoryPanel->setSelection(LLUUID::null, FALSE); | ||
156 | } | ||
157 | if (self->mListNames) | ||
158 | { | ||
159 | self->mListNames->deselectAllItems(TRUE); | ||
160 | } | ||
161 | if(self->mCloseOnSelect) | ||
162 | { | ||
163 | self->mCloseOnSelect = FALSE; | ||
164 | self->close(); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | void LLFloaterAvatarPicker::onBtnClose(void* userdata) | ||
169 | { | ||
170 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
171 | if(self) self->close(); | ||
172 | } | ||
173 | |||
174 | void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata) | ||
175 | { | ||
176 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
177 | if (!self) | ||
178 | { | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | self->mAvatarIDs.clear(); | ||
183 | self->mAvatarNames.clear(); | ||
184 | |||
185 | if (!self->mListNames) | ||
186 | { | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | std::vector<LLScrollListItem*> items = self->mListNames->getAllSelected(); | ||
191 | std::vector<LLScrollListItem*>::iterator itor; | ||
192 | for (itor = items.begin(); itor != items.end(); ++itor) | ||
193 | { | ||
194 | self->mAvatarNames.push_back((*itor)->getColumn(0)->getText()); | ||
195 | self->mAvatarIDs.push_back((*itor)->getUUID()); | ||
196 | self->childSetEnabled("Select", TRUE); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) | ||
201 | { | ||
202 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data; | ||
203 | if (!self) | ||
204 | { | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | self->mAvatarIDs.clear(); | ||
209 | self->mAvatarNames.clear(); | ||
210 | |||
211 | self->childSetEnabled("Select", FALSE); | ||
212 | |||
213 | if (!self->mListNames) | ||
214 | { | ||
215 | return; | ||
216 | } | ||
217 | |||
218 | std::deque<LLFolderViewItem*>::const_iterator item_it; | ||
219 | for (item_it = items.begin(); item_it != items.end(); ++item_it) | ||
220 | { | ||
221 | LLFolderViewEventListener* listenerp = (*item_it)->getListener(); | ||
222 | if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) | ||
223 | { | ||
224 | LLInventoryItem* item = gInventory.getItem(listenerp->getUUID()); | ||
225 | |||
226 | if (item) | ||
227 | { | ||
228 | self->mAvatarIDs.push_back(item->getCreatorUUID()); | ||
229 | self->mAvatarNames.push_back(listenerp->getName()); | ||
230 | self->childSetEnabled("Select", TRUE); | ||
231 | self->mListNames->deselectAllItems(); | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | |||
238 | void LLFloaterAvatarPicker::find() | ||
239 | { | ||
240 | const LLString& text = childGetValue("Edit").asString(); | ||
241 | |||
242 | mQueryID.generate(); | ||
243 | |||
244 | LLMessageSystem* msg = gMessageSystem; | ||
245 | |||
246 | msg->newMessage("AvatarPickerRequest"); | ||
247 | msg->nextBlock("AgentData"); | ||
248 | msg->addUUID("AgentID", agent_get_id()); | ||
249 | msg->addUUID("SessionID", agent_get_session_id()); | ||
250 | msg->addUUID("QueryID", mQueryID); // not used right now | ||
251 | msg->nextBlock("Data"); | ||
252 | msg->addString("Name", text); | ||
253 | |||
254 | agent_send_reliable_message(); | ||
255 | |||
256 | if (mListNames) | ||
257 | { | ||
258 | mListNames->deleteAllItems(); | ||
259 | |||
260 | LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null ); | ||
261 | row->addColumn("Searching...", LLFontGL::sSansSerif); | ||
262 | mListNames->addItem(row); | ||
263 | } | ||
264 | |||
265 | childSetEnabled("Select", FALSE); | ||
266 | mResultsReturned = FALSE; | ||
267 | } | ||
268 | |||
269 | void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) | ||
270 | { | ||
271 | mAllowMultiple = allow_multiple; | ||
272 | if (mInventoryPanel) | ||
273 | { | ||
274 | mInventoryPanel->setAllowMultiSelect(mAllowMultiple); | ||
275 | } | ||
276 | if (mListNames) | ||
277 | { | ||
278 | mListNames->setAllowMultipleSelection(mAllowMultiple); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | // static | ||
283 | void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**) | ||
284 | { | ||
285 | LLUUID agent_id; | ||
286 | LLUUID query_id; | ||
287 | LLUUID avatar_id; | ||
288 | char first_name[DB_FIRST_NAME_BUF_SIZE]; | ||
289 | char last_name[DB_LAST_NAME_BUF_SIZE]; | ||
290 | |||
291 | msg->getUUID("AgentData", "AgentID", agent_id); | ||
292 | msg->getUUID("AgentData", "QueryID", query_id); | ||
293 | |||
294 | // Not for us | ||
295 | if (agent_id != agent_get_id()) return; | ||
296 | |||
297 | // Dialog already closed | ||
298 | LLFloaterAvatarPicker *self = sInstance; | ||
299 | if (!self) return; | ||
300 | |||
301 | // these are not results from our last request | ||
302 | if (query_id != self->mQueryID) | ||
303 | { | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | if (!self->mResultsReturned) | ||
308 | { | ||
309 | // clear "Searching" label on first results | ||
310 | if (self->mListNames) | ||
311 | { | ||
312 | self->mListNames->deleteAllItems(); | ||
313 | } | ||
314 | } | ||
315 | self->mResultsReturned = TRUE; | ||
316 | |||
317 | if (self->mListNames) | ||
318 | { | ||
319 | BOOL found_one = FALSE; | ||
320 | S32 num_new_rows = msg->getNumberOfBlocks("Data"); | ||
321 | for (S32 i = 0; i < num_new_rows; i++) | ||
322 | { | ||
323 | msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i); | ||
324 | msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, first_name, i); | ||
325 | msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, DB_LAST_NAME_BUF_SIZE, last_name, i); | ||
326 | |||
327 | LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, avatar_id ); | ||
328 | |||
329 | if (avatar_id.isNull()) | ||
330 | { | ||
331 | self->childSetTextArg("NotFound", "[TEXT]", self->childGetText("Edit")); | ||
332 | LLString msg = self->childGetValue("NotFound").asString(); | ||
333 | row->addColumn(msg, LLFontGL::sSansSerif); | ||
334 | self->mListNames->setEnabled(FALSE); | ||
335 | } | ||
336 | else | ||
337 | { | ||
338 | LLString buffer = LLString(first_name) + " " + last_name; | ||
339 | row->addColumn(buffer, LLFontGL::sSansSerif); | ||
340 | self->mListNames->setEnabled(TRUE); | ||
341 | found_one = TRUE; | ||
342 | } | ||
343 | self->mListNames->addItem(row); | ||
344 | } | ||
345 | |||
346 | if (found_one) | ||
347 | { | ||
348 | self->mListNames->selectFirstItem(); | ||
349 | self->onList(self->mListNames, self); | ||
350 | self->mListNames->setFocus(TRUE); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
355 | //static | ||
356 | void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) | ||
357 | { | ||
358 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data; | ||
359 | if (caller->getText().size() >= 3) | ||
360 | { | ||
361 | self->childSetEnabled("Find",TRUE); | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | self->childSetEnabled("Find",FALSE); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | // virtual | ||
370 | BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | ||
371 | { | ||
372 | if (key == KEY_RETURN | ||
373 | && mask == MASK_NONE) | ||
374 | { | ||
375 | if (childHasFocus("Edit")) | ||
376 | { | ||
377 | onBtnFind(this); | ||
378 | return TRUE; | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | onBtnAdd(this); | ||
383 | return TRUE; | ||
384 | } | ||
385 | } | ||
386 | else if (key == KEY_ESCAPE && mask == MASK_NONE) | ||
387 | { | ||
388 | close(); | ||
389 | return TRUE; | ||
390 | } | ||
391 | |||
392 | return LLFloater::handleKeyHere(key, mask, called_from_parent); | ||
393 | } | ||