llfloateravatarpicker.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:14k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfloateravatarpicker.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2003-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. #include "llviewerprecompiledheaders.h"
  32. #include "llfloateravatarpicker.h"
  33. // Viewer includes
  34. #include "llagent.h"
  35. #include "llcallingcard.h"
  36. #include "llfocusmgr.h"
  37. #include "llfloaterreg.h"
  38. #include "llviewercontrol.h"
  39. #include "llworld.h"
  40. // Linden libraries
  41. #include "llbutton.h"
  42. #include "lllineeditor.h"
  43. #include "llscrolllistctrl.h"
  44. #include "llscrolllistitem.h"
  45. #include "llscrolllistcell.h"
  46. #include "lltabcontainer.h"
  47. #include "lluictrlfactory.h"
  48. #include "message.h"
  49. LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
  50.    BOOL allow_multiple,
  51.    BOOL closeOnSelect)
  52. {
  53. // *TODO: Use a key to allow this not to be an effective singleton
  54. LLFloaterAvatarPicker* floater = 
  55. LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
  56. floater->mSelectionCallback = callback;
  57. floater->setAllowMultiple(allow_multiple);
  58. floater->mNearMeListComplete = FALSE;
  59. floater->mCloseOnSelect = closeOnSelect;
  60. if (!closeOnSelect)
  61. {
  62. // Use Select/Close
  63. std::string select_string = floater->getString("Select");
  64. std::string close_string = floater->getString("Close");
  65. floater->getChild<LLButton>("ok_btn")->setLabel(select_string);
  66. floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
  67. }
  68. return floater;
  69. }
  70. // Default constructor
  71. LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
  72.   : LLFloater(key),
  73. mNumResultsReturned(0),
  74. mNearMeListComplete(FALSE),
  75. mCloseOnSelect(FALSE)
  76. {
  77. //  LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml");
  78. mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
  79. }
  80. BOOL LLFloaterAvatarPicker::postBuild()
  81. {
  82. getChild<LLLineEditor>("Edit")->setKeystrokeCallback( boost::bind(&LLFloaterAvatarPicker::editKeystroke, this, _1, _2),NULL);
  83. childSetAction("Find", boost::bind(&LLFloaterAvatarPicker::onBtnFind, this));
  84. childDisable("Find");
  85. childSetAction("Refresh", boost::bind(&LLFloaterAvatarPicker::onBtnRefresh, this));
  86. getChild<LLUICtrl>("near_me_range")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onRangeAdjust, this));
  87. LLScrollListCtrl* searchresults = getChild<LLScrollListCtrl>("SearchResults");
  88. searchresults->setDoubleClickCallback( boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this));
  89. searchresults->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this));
  90. childDisable("SearchResults");
  91. LLScrollListCtrl* nearme = getChild<LLScrollListCtrl>("NearMe");
  92. nearme->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this));
  93. nearme->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this));
  94. LLScrollListCtrl* friends = getChild<LLScrollListCtrl>("Friends");
  95. friends->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this));
  96. getChild<LLUICtrl>("Friends")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this));
  97. childSetAction("ok_btn", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this));
  98. childDisable("ok_btn");
  99. childSetAction("cancel_btn", boost::bind(&LLFloaterAvatarPicker::onBtnClose, this));
  100. childSetFocus("Edit");
  101. LLPanel* search_panel = getChild<LLPanel>("SearchPanel");
  102. if (search_panel)
  103. {
  104. // Start searching when Return is pressed in the line editor.
  105. search_panel->setDefaultBtn("Find");
  106. }
  107. getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("no_results"));
  108. getChild<LLTabContainer>("ResidentChooserTabs")->setCommitCallback(
  109. boost::bind(&LLFloaterAvatarPicker::onTabChanged, this));
  110. setAllowMultiple(FALSE);
  111. center();
  112. populateFriend();
  113. return TRUE;
  114. }
  115. void LLFloaterAvatarPicker::setOkBtnEnableCb(validate_callback_t cb)
  116. {
  117. mOkButtonValidateSignal.connect(cb);
  118. }
  119. void LLFloaterAvatarPicker::onTabChanged()
  120. {
  121. childSetEnabled("ok_btn", isSelectBtnEnabled());
  122. }
  123. // Destroys the object
  124. LLFloaterAvatarPicker::~LLFloaterAvatarPicker()
  125. {
  126. gFocusMgr.releaseFocusIfNeeded( this );
  127. }
  128. void LLFloaterAvatarPicker::onBtnFind()
  129. {
  130. find();
  131. }
  132. static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector<std::string>& avatar_names, std::vector<LLUUID>& avatar_ids)
  133. {
  134. std::vector<LLScrollListItem*> items = from->getAllSelected();
  135. for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); iter != items.end(); ++iter)
  136. {
  137. LLScrollListItem* item = *iter;
  138. if (item->getUUID().notNull())
  139. {
  140. avatar_names.push_back(item->getColumn(0)->getValue().asString());
  141. avatar_ids.push_back(item->getUUID());
  142. }
  143. }
  144. }
  145. void LLFloaterAvatarPicker::onBtnSelect()
  146. {
  147. // If select btn not enabled then do not callback
  148. if (!isSelectBtnEnabled())
  149. return;
  150. if(mSelectionCallback)
  151. {
  152. std::string acvtive_panel_name;
  153. LLScrollListCtrl* list =  NULL;
  154. LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs");
  155. if(active_panel)
  156. {
  157. acvtive_panel_name = active_panel->getName();
  158. }
  159. if(acvtive_panel_name == "SearchPanel")
  160. {
  161. list = getChild<LLScrollListCtrl>("SearchResults");
  162. }
  163. else if(acvtive_panel_name == "NearMePanel")
  164. {
  165. list = getChild<LLScrollListCtrl>("NearMe");
  166. }
  167. else if (acvtive_panel_name == "FriendsPanel")
  168. {
  169. list = getChild<LLScrollListCtrl>("Friends");
  170. }
  171. if(list)
  172. {
  173. std::vector<std::string> avatar_names;
  174. std::vector<LLUUID> avatar_ids;
  175. getSelectedAvatarData(list, avatar_names, avatar_ids);
  176. mSelectionCallback(avatar_names, avatar_ids);
  177. }
  178. }
  179. getChild<LLScrollListCtrl>("SearchResults")->deselectAllItems(TRUE);
  180. getChild<LLScrollListCtrl>("NearMe")->deselectAllItems(TRUE);
  181. getChild<LLScrollListCtrl>("Friends")->deselectAllItems(TRUE);
  182. if(mCloseOnSelect)
  183. {
  184. mCloseOnSelect = FALSE;
  185. closeFloater();
  186. }
  187. }
  188. void LLFloaterAvatarPicker::onBtnRefresh()
  189. {
  190. getChild<LLScrollListCtrl>("NearMe")->deleteAllItems();
  191. getChild<LLScrollListCtrl>("NearMe")->setCommentText(getString("searching"));
  192. mNearMeListComplete = FALSE;
  193. }
  194. void LLFloaterAvatarPicker::onBtnClose()
  195. {
  196. closeFloater();
  197. }
  198. void LLFloaterAvatarPicker::onRangeAdjust()
  199. {
  200. onBtnRefresh();
  201. }
  202. void LLFloaterAvatarPicker::onList()
  203. {
  204. childSetEnabled("ok_btn", isSelectBtnEnabled());
  205. }
  206. void LLFloaterAvatarPicker::populateNearMe()
  207. {
  208. BOOL all_loaded = TRUE;
  209. BOOL empty = TRUE;
  210. LLScrollListCtrl* near_me_scroller = getChild<LLScrollListCtrl>("NearMe");
  211. near_me_scroller->deleteAllItems();
  212. std::vector<LLUUID> avatar_ids;
  213. LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
  214. for(U32 i=0; i<avatar_ids.size(); i++)
  215. {
  216. LLUUID& av = avatar_ids[i];
  217. if(av == gAgent.getID()) continue;
  218. LLSD element;
  219. element["id"] = av; // value
  220. std::string fullname;
  221. if(!gCacheName->getFullName(av, fullname))
  222. {
  223. element["columns"][0]["value"] = LLCacheName::getDefaultName();
  224. all_loaded = FALSE;
  225. }
  226. else
  227. {
  228. element["columns"][0]["value"] = fullname;
  229. }
  230. near_me_scroller->addElement(element);
  231. empty = FALSE;
  232. }
  233. if (empty)
  234. {
  235. childDisable("NearMe");
  236. childDisable("ok_btn");
  237. near_me_scroller->setCommentText(getString("no_one_near"));
  238. }
  239. else 
  240. {
  241. childEnable("NearMe");
  242. childEnable("ok_btn");
  243. near_me_scroller->selectFirstItem();
  244. onList();
  245. near_me_scroller->setFocus(TRUE);
  246. }
  247. if (all_loaded)
  248. {
  249. mNearMeListComplete = TRUE;
  250. }
  251. }
  252. void LLFloaterAvatarPicker::populateFriend()
  253. {
  254. LLScrollListCtrl* friends_scroller = getChild<LLScrollListCtrl>("Friends");
  255. friends_scroller->deleteAllItems();
  256. LLCollectAllBuddies collector;
  257. LLAvatarTracker::instance().applyFunctor(collector);
  258. LLCollectAllBuddies::buddy_map_t::iterator it;
  259. for(it = collector.mOnline.begin(); it!=collector.mOnline.end(); it++)
  260. {
  261. friends_scroller->addStringUUIDItem(it->first, it->second);
  262. }
  263. for(it = collector.mOffline.begin(); it!=collector.mOffline.end(); it++)
  264. {
  265. friends_scroller->addStringUUIDItem(it->first, it->second);
  266. }
  267. friends_scroller->sortByColumnIndex(0, TRUE);
  268. }
  269. void LLFloaterAvatarPicker::draw()
  270. {
  271. LLFloater::draw();
  272. if (!mNearMeListComplete && childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("NearMePanel"))
  273. {
  274. populateNearMe();
  275. }
  276. }
  277. BOOL LLFloaterAvatarPicker::visibleItemsSelected() const
  278. {
  279. LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs");
  280. if(active_panel == getChild<LLPanel>("SearchPanel"))
  281. {
  282. return getChild<LLScrollListCtrl>("SearchResults")->getFirstSelectedIndex() >= 0;
  283. }
  284. else if(active_panel == getChild<LLPanel>("NearMePanel"))
  285. {
  286. return getChild<LLScrollListCtrl>("NearMe")->getFirstSelectedIndex() >= 0;
  287. }
  288. else if(active_panel == getChild<LLPanel>("FriendsPanel"))
  289. {
  290. return getChild<LLScrollListCtrl>("Friends")->getFirstSelectedIndex() >= 0;
  291. }
  292. return FALSE;
  293. }
  294. void LLFloaterAvatarPicker::find()
  295. {
  296. std::string text = childGetValue("Edit").asString();
  297. mQueryID.generate();
  298. LLMessageSystem* msg = gMessageSystem;
  299. msg->newMessage("AvatarPickerRequest");
  300. msg->nextBlock("AgentData");
  301. msg->addUUID("AgentID", gAgent.getID());
  302. msg->addUUID("SessionID", gAgent.getSessionID());
  303. msg->addUUID("QueryID", mQueryID); // not used right now
  304. msg->nextBlock("Data");
  305. msg->addString("Name", text);
  306. gAgent.sendReliableMessage();
  307. getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();
  308. getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching"));
  309. childSetEnabled("ok_btn", FALSE);
  310. mNumResultsReturned = 0;
  311. }
  312. void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)
  313. {
  314. getChild<LLScrollListCtrl>("SearchResults")->setAllowMultipleSelection(allow_multiple);
  315. getChild<LLScrollListCtrl>("NearMe")->setAllowMultipleSelection(allow_multiple);
  316. getChild<LLScrollListCtrl>("Friends")->setAllowMultipleSelection(allow_multiple);
  317. }
  318. // static 
  319. void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)
  320. {
  321. LLUUID agent_id;
  322. LLUUID query_id;
  323. LLUUID avatar_id;
  324. std::string first_name;
  325. std::string last_name;
  326. msg->getUUID("AgentData", "AgentID", agent_id);
  327. msg->getUUID("AgentData", "QueryID", query_id);
  328. // Not for us
  329. if (agent_id != gAgent.getID()) return;
  330. LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
  331. // these are not results from our last request
  332. if (query_id != floater->mQueryID)
  333. {
  334. return;
  335. }
  336. LLScrollListCtrl* search_results = floater->getChild<LLScrollListCtrl>("SearchResults");
  337. // clear "Searching" label on first results
  338. if (floater->mNumResultsReturned++ == 0)
  339. {
  340. search_results->deleteAllItems();
  341. }
  342. BOOL found_one = FALSE;
  343. S32 num_new_rows = msg->getNumberOfBlocks("Data");
  344. for (S32 i = 0; i < num_new_rows; i++)
  345. {
  346. msg->getUUIDFast(  _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
  347. msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i);
  348. msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i);
  349. std::string avatar_name;
  350. if (avatar_id.isNull())
  351. {
  352. LLStringUtil::format_map_t map;
  353. map["[TEXT]"] = floater->childGetText("Edit");
  354. avatar_name = floater->getString("not_found", map);
  355. search_results->setEnabled(FALSE);
  356. floater->childDisable("ok_btn");
  357. }
  358. else
  359. {
  360. avatar_name = first_name + " " + last_name;
  361. search_results->setEnabled(TRUE);
  362. found_one = TRUE;
  363. }
  364. LLSD element;
  365. element["id"] = avatar_id; // value
  366. element["columns"][0]["value"] = avatar_name;
  367. search_results->addElement(element);
  368. }
  369. if (found_one)
  370. {
  371. floater->childEnable("ok_btn");
  372. search_results->selectFirstItem();
  373. floater->onList();
  374. search_results->setFocus(TRUE);
  375. }
  376. }
  377. //static
  378. void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)
  379. {
  380. childSetEnabled("Find", caller->getText().size() >= 3);
  381. }
  382. // virtual
  383. BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask)
  384. {
  385. if (key == KEY_RETURN && mask == MASK_NONE)
  386. {
  387. if (childHasFocus("Edit"))
  388. {
  389. onBtnFind();
  390. }
  391. else
  392. {
  393. onBtnSelect();
  394. }
  395. return TRUE;
  396. }
  397. else if (key == KEY_ESCAPE && mask == MASK_NONE)
  398. {
  399. closeFloater();
  400. return TRUE;
  401. }
  402. return LLFloater::handleKeyHere(key, mask);
  403. }
  404. bool LLFloaterAvatarPicker::isSelectBtnEnabled()
  405. {
  406. bool ret_val = visibleItemsSelected();
  407. if ( ret_val && mOkButtonValidateSignal.num_slots() )
  408. {
  409. std::string acvtive_panel_name;
  410. LLScrollListCtrl* list =  NULL;
  411. LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs");
  412. if(active_panel)
  413. {
  414. acvtive_panel_name = active_panel->getName();
  415. }
  416. if(acvtive_panel_name == "SearchPanel")
  417. {
  418. list = getChild<LLScrollListCtrl>("SearchResults");
  419. }
  420. else if(acvtive_panel_name == "NearMePanel")
  421. {
  422. list = getChild<LLScrollListCtrl>("NearMe");
  423. }
  424. else if (acvtive_panel_name == "FriendsPanel")
  425. {
  426. list = getChild<LLScrollListCtrl>("Friends");
  427. }
  428. if(list)
  429. {
  430. std::vector<LLUUID> avatar_ids;
  431. std::vector<std::string> avatar_names;
  432. getSelectedAvatarData(list, avatar_names, avatar_ids);
  433. return mOkButtonValidateSignal(avatar_ids);
  434. }
  435. }
  436. return ret_val;
  437. }