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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpanelpick.cpp
  3.  * @brief LLPanelPick class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * 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. // Display of a "Top Pick" used both for the global top picks in the 
  33. // Find directory, and also for each individual user's picks in their
  34. // profile.
  35. #include "llviewerprecompiledheaders.h"
  36. #include "llpanelpick.h"
  37. #include "message.h"
  38. #include "llparcel.h"
  39. #include "llbutton.h"
  40. #include "llfloaterreg.h"
  41. #include "lliconctrl.h"
  42. #include "lllineeditor.h"
  43. #include "llpanel.h"
  44. #include "llscrollcontainer.h"
  45. #include "lltexteditor.h"
  46. #include "llagent.h"
  47. #include "llagentpicksinfo.h"
  48. #include "llavatarpropertiesprocessor.h"
  49. #include "llfloaterworldmap.h"
  50. #include "lltexturectrl.h"
  51. #include "lluiconstants.h"
  52. #include "llviewerparcelmgr.h"
  53. #include "llviewerregion.h"
  54. #include "llworldmap.h"
  55. #define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
  56. #define XML_PANEL_PICK_INFO "panel_pick_info.xml"
  57. #define XML_NAME "pick_name"
  58. #define XML_DESC "pick_desc"
  59. #define XML_SNAPSHOT "pick_snapshot"
  60. #define XML_LOCATION "pick_location"
  61. #define XML_BTN_ON_TXTR "edit_icon"
  62. #define XML_BTN_SAVE "save_changes_btn"
  63. #define SAVE_BTN_LABEL "[WHAT]"
  64. #define LABEL_PICK = "Pick"
  65. #define LABEL_CHANGES = "Changes"
  66. std::string SET_LOCATION_NOTICE("(will update after save)");
  67. //////////////////////////////////////////////////////////////////////////
  68. //////////////////////////////////////////////////////////////////////////
  69. //////////////////////////////////////////////////////////////////////////
  70. //static
  71. LLPanelPickInfo* LLPanelPickInfo::create()
  72. {
  73. LLPanelPickInfo* panel = new LLPanelPickInfo();
  74. LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_PICK_INFO);
  75. return panel;
  76. }
  77. LLPanelPickInfo::LLPanelPickInfo()
  78.  : LLPanel()
  79.  , LLAvatarPropertiesObserver()
  80.  , LLRemoteParcelInfoObserver()
  81.  , mAvatarId(LLUUID::null)
  82.  , mSnapshotCtrl(NULL)
  83.  , mPickId(LLUUID::null)
  84.  , mParcelId(LLUUID::null)
  85.  , mRequestedId(LLUUID::null)
  86.  , mScrollingPanelMinHeight(0)
  87.  , mScrollingPanelWidth(0)
  88.  , mScrollingPanel(NULL)
  89.  , mScrollContainer(NULL)
  90. {
  91. }
  92. LLPanelPickInfo::~LLPanelPickInfo()
  93. {
  94. LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
  95. if (mParcelId.notNull())
  96. {
  97. LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
  98. }
  99. }
  100. void LLPanelPickInfo::onOpen(const LLSD& key)
  101. {
  102. LLUUID avatar_id = key["avatar_id"];
  103. if(avatar_id.isNull())
  104. {
  105. return;
  106. }
  107. if(getAvatarId().notNull())
  108. {
  109. LLAvatarPropertiesProcessor::getInstance()->removeObserver(
  110. getAvatarId(), this);
  111. }
  112. setAvatarId(avatar_id);
  113. resetData();
  114. resetControls();
  115. setPickId(key["pick_id"]);
  116. setPickName(key["pick_name"]);
  117. setPickDesc(key["pick_desc"]);
  118. setSnapshotId(key["snapshot_id"]);
  119. LLAvatarPropertiesProcessor::getInstance()->addObserver(
  120. getAvatarId(), this);
  121. LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
  122. getAvatarId(), getPickId());
  123. }
  124. BOOL LLPanelPickInfo::postBuild()
  125. {
  126. mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
  127. childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick"));
  128. childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
  129. childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
  130. childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
  131. mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
  132. mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
  133. mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
  134. mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
  135. return TRUE;
  136. }
  137. void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
  138. {
  139. LLPanel::reshape(width, height, called_from_parent);
  140. if (!mScrollContainer || !mScrollingPanel)
  141. return;
  142. static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
  143. S32 scroll_height = mScrollContainer->getRect().getHeight();
  144. if (mScrollingPanelMinHeight >= scroll_height)
  145. {
  146. mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
  147. }
  148. else
  149. {
  150. mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
  151. }
  152. }
  153. void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
  154. {
  155. if(APT_PICK_INFO != type)
  156. {
  157. return;
  158. }
  159. LLPickData* pick_info = static_cast<LLPickData*>(data);
  160. if(!pick_info 
  161. || pick_info->creator_id != getAvatarId() 
  162. || pick_info->pick_id != getPickId())
  163. {
  164. return;
  165. }
  166. mParcelId = pick_info->parcel_id;
  167. setSnapshotId(pick_info->snapshot_id);
  168. setPickName(pick_info->name);
  169. setPickDesc(pick_info->desc);
  170. setPosGlobal(pick_info->pos_global);
  171. // Send remote parcel info request to get parcel name and sim (region) name.
  172. sendParcelInfoRequest();
  173. // *NOTE dzaporozhan
  174. // We want to keep listening to APT_PICK_INFO because user may 
  175. // edit the Pick and we have to update Pick info panel.
  176. // revomeObserver is called from onClickBack
  177. }
  178. void LLPanelPickInfo::sendParcelInfoRequest()
  179. {
  180. if (mParcelId != mRequestedId)
  181. {
  182. LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
  183. LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
  184. mRequestedId = mParcelId;
  185. }
  186. }
  187. void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
  188. {
  189. getChild<LLButton>("back_btn")->setClickedCallback(cb);
  190. }
  191. void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
  192. {
  193. setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
  194. parcel_data.sim_name, getPosGlobal()));
  195. // We have received parcel info for the requested ID so clear it now.
  196. mRequestedId.setNull();
  197. if (mParcelId.notNull())
  198. {
  199. LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
  200. }
  201. }
  202. void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
  203. {
  204. getChild<LLButton>("edit_btn")->setClickedCallback(cb);
  205. }
  206. // PROTECTED AREA
  207. void LLPanelPickInfo::resetControls()
  208. {
  209. if(getAvatarId() == gAgent.getID())
  210. {
  211. childSetEnabled("edit_btn", TRUE);
  212. childSetVisible("edit_btn", TRUE);
  213. }
  214. else
  215. {
  216. childSetEnabled("edit_btn", FALSE);
  217. childSetVisible("edit_btn", FALSE);
  218. }
  219. }
  220. void LLPanelPickInfo::resetData()
  221. {
  222. setPickName(LLStringUtil::null);
  223. setPickDesc(LLStringUtil::null);
  224. setPickLocation(LLStringUtil::null);
  225. setPickId(LLUUID::null);
  226. setSnapshotId(LLUUID::null);
  227. mPosGlobal.clearVec();
  228. mParcelId.setNull();
  229. mRequestedId.setNull();
  230. }
  231. // static
  232. std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
  233. {
  234. std::string location_text;
  235. location_text.append(owner_name);
  236. if (!original_name.empty())
  237. {
  238. if (!location_text.empty()) location_text.append(", ");
  239. location_text.append(original_name);
  240. }
  241. if (!sim_name.empty())
  242. {
  243. if (!location_text.empty()) location_text.append(", ");
  244. location_text.append(sim_name);
  245. }
  246. if (!location_text.empty()) location_text.append(" ");
  247. if (!pos_global.isNull())
  248. {
  249. S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
  250. S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
  251. S32 region_z = llround((F32)pos_global.mdV[VZ]);
  252. location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
  253. }
  254. return location_text;
  255. }
  256. void LLPanelPickInfo::setSnapshotId(const LLUUID& id) 
  257. mSnapshotCtrl->setImageAssetID(id);
  258. mSnapshotCtrl->setValid(TRUE);
  259. }
  260. void LLPanelPickInfo::setPickName(const std::string& name)
  261. {
  262. childSetValue(XML_NAME, name);
  263. }
  264. void LLPanelPickInfo::setPickDesc(const std::string& desc)
  265. {
  266. childSetValue(XML_DESC, desc);
  267. }
  268. void LLPanelPickInfo::setPickLocation(const std::string& location)
  269. {
  270. childSetValue(XML_LOCATION, location);
  271. }
  272. void LLPanelPickInfo::onClickMap()
  273. {
  274. LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
  275. LLFloaterReg::showInstance("world_map", "center");
  276. }
  277. void LLPanelPickInfo::onClickTeleport()
  278. {
  279. if (!getPosGlobal().isExactlyZero())
  280. {
  281. gAgent.teleportViaLocation(getPosGlobal());
  282. LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
  283. }
  284. }
  285. void LLPanelPickInfo::onClickBack()
  286. {
  287. LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
  288. }
  289. //////////////////////////////////////////////////////////////////////////
  290. //////////////////////////////////////////////////////////////////////////
  291. //////////////////////////////////////////////////////////////////////////
  292. //static
  293. LLPanelPickEdit* LLPanelPickEdit::create()
  294. {
  295. LLPanelPickEdit* panel = new LLPanelPickEdit();
  296. LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_EDIT_PICK);
  297. return panel;
  298. }
  299. LLPanelPickEdit::LLPanelPickEdit()
  300.  : LLPanelPickInfo()
  301.  , mLocationChanged(false)
  302.  , mNeedData(true)
  303.  , mNewPick(false)
  304. {
  305. }
  306. LLPanelPickEdit::~LLPanelPickEdit()
  307. {
  308. }
  309. void LLPanelPickEdit::onOpen(const LLSD& key)
  310. {
  311. LLUUID pick_id = key["pick_id"];
  312. mNeedData = true;
  313. // creating new Pick
  314. if(pick_id.isNull())
  315. {
  316. mNewPick = true;
  317. setAvatarId(gAgent.getID());
  318. resetData();
  319. resetControls();
  320. setPosGlobal(gAgent.getPositionGlobal());
  321. LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
  322. std::string pick_name, pick_desc, region_name;
  323. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  324. if(parcel)
  325. {
  326. parcel_id = parcel->getID();
  327. pick_name = parcel->getName();
  328. pick_desc = parcel->getDesc();
  329. snapshot_id = parcel->getSnapshotID();
  330. }
  331. LLViewerRegion* region = gAgent.getRegion();
  332. if(region)
  333. {
  334. region_name = region->getName();
  335. }
  336. setParcelID(parcel_id);
  337. childSetValue("pick_name", pick_name.empty() ? region_name : pick_name);
  338. childSetValue("pick_desc", pick_desc);
  339. setSnapshotId(snapshot_id);
  340. setPickLocation(createLocationText(SET_LOCATION_NOTICE, pick_name, region_name, getPosGlobal()));
  341. enableSaveButton(true);
  342. }
  343. // editing existing pick
  344. else
  345. {
  346. mNewPick = false;
  347. LLPanelPickInfo::onOpen(key);
  348. enableSaveButton(false);
  349. }
  350. resetDirty();
  351. }
  352. void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
  353. {
  354. if(!pick_data)
  355. {
  356. return;
  357. }
  358. mNeedData = false;
  359. setParcelID(pick_data->parcel_id);
  360. childSetValue("pick_name", pick_data->name);
  361. childSetValue("pick_desc", pick_data->desc);
  362. setSnapshotId(pick_data->snapshot_id);
  363. setPosGlobal(pick_data->pos_global);
  364. setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
  365. pick_data->sim_name, pick_data->pos_global));
  366. }
  367. BOOL LLPanelPickEdit::postBuild()
  368. {
  369. LLPanelPickInfo::postBuild();
  370. mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
  371. LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
  372. line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
  373. LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
  374. text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
  375. childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
  376. childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
  377. initTexturePickerMouseEvents();
  378. return TRUE;
  379. }
  380. void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
  381. {
  382. getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
  383. }
  384. void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
  385. {
  386. getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
  387. }
  388. void LLPanelPickEdit::resetDirty()
  389. {
  390. LLPanelPickInfo::resetDirty();
  391. getChild<LLLineEditor>("pick_name")->resetDirty();
  392. getChild<LLTextEditor>("pick_desc")->resetDirty();
  393. mSnapshotCtrl->resetDirty();
  394. mLocationChanged = false;
  395. }
  396. BOOL LLPanelPickEdit::isDirty() const
  397. {
  398. if( mNewPick
  399. || LLPanelPickInfo::isDirty()
  400. || mLocationChanged
  401. || mSnapshotCtrl->isDirty()
  402. || getChild<LLLineEditor>("pick_name")->isDirty()
  403. || getChild<LLTextEditor>("pick_desc")->isDirty())
  404. {
  405. return TRUE;
  406. }
  407. return FALSE;
  408. }
  409. // PROTECTED AREA
  410. void LLPanelPickEdit::sendUpdate()
  411. {
  412. LLPickData pick_data;
  413. // If we don't have a pick id yet, we'll need to generate one,
  414. // otherwise we'll keep overwriting pick_id 00000 in the database.
  415. if (getPickId().isNull()) 
  416. {
  417. getPickId().generate();
  418. }
  419. pick_data.agent_id = gAgent.getID();
  420. pick_data.session_id = gAgent.getSessionID();
  421. pick_data.pick_id = getPickId();
  422. pick_data.creator_id = gAgent.getID();;
  423. //legacy var  need to be deleted
  424. pick_data.top_pick = FALSE; 
  425. pick_data.parcel_id = mParcelId;
  426. pick_data.name = childGetValue(XML_NAME).asString();
  427. pick_data.desc = childGetValue(XML_DESC).asString();
  428. pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
  429. pick_data.pos_global = getPosGlobal();
  430. pick_data.sort_order = 0;
  431. pick_data.enabled = TRUE;
  432. LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
  433. if(mNewPick)
  434. {
  435. // Assume a successful create pick operation, make new number of picks
  436. // available immediately. Actual number of picks will be requested in 
  437. // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
  438. LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
  439. }
  440. }
  441. void LLPanelPickEdit::onSnapshotChanged()
  442. {
  443. enableSaveButton(true);
  444. }
  445. void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
  446. {
  447. enableSaveButton(isDirty());
  448. }
  449. void LLPanelPickEdit::resetData()
  450. {
  451. LLPanelPickInfo::resetData();
  452. mLocationChanged = false;
  453. }
  454. void LLPanelPickEdit::enableSaveButton(bool enable)
  455. {
  456. childSetEnabled(XML_BTN_SAVE, enable);
  457. }
  458. void LLPanelPickEdit::onClickSetLocation()
  459. {
  460. // Save location for later use.
  461. setPosGlobal(gAgent.getPositionGlobal());
  462. std::string parcel_name, region_name;
  463. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  464. if (parcel)
  465. {
  466. mParcelId = parcel->getID();
  467. parcel_name = parcel->getName();
  468. }
  469. LLViewerRegion* region = gAgent.getRegion();
  470. if(region)
  471. {
  472. region_name = region->getName();
  473. }
  474. setPickLocation(createLocationText(SET_LOCATION_NOTICE, parcel_name, region_name, getPosGlobal()));
  475. mLocationChanged = true;
  476. enableSaveButton(TRUE);
  477. }
  478. void LLPanelPickEdit::onClickSave()
  479. {
  480. sendUpdate();
  481. mLocationChanged = false;
  482. LLSD params;
  483. params["action"] = "save_new_pick";
  484. notifyParent(params);
  485. }
  486. void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
  487. {
  488. if(mNeedData)
  489. {
  490. LLPanelPickInfo::processProperties(data, type);
  491. }
  492. }
  493. // PRIVATE AREA
  494. void LLPanelPickEdit::initTexturePickerMouseEvents()
  495. {
  496. text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
  497. mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
  498. mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
  499. text_icon->setVisible(FALSE);
  500. }
  501. void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
  502. {
  503.         text_icon->setVisible(TRUE);
  504. }
  505. void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
  506. {
  507. text_icon->setVisible(FALSE);
  508. }