PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llmoveview.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 723 lines | 512 code | 115 blank | 96 comment | 62 complexity | 7cd2999ce5a5991dae8226bd9414019f MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmoveview.cpp
  3. * @brief Container for movement buttons like forward, left, fly
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llmoveview.h"
  28. // Library includes
  29. #include "indra_constants.h"
  30. #include "llparcel.h"
  31. // Viewer includes
  32. #include "llagent.h"
  33. #include "llagentcamera.h"
  34. #include "llvoavatarself.h" // to check gAgentAvatarp->isSitting()
  35. #include "llbutton.h"
  36. #include "llfirstuse.h"
  37. #include "llfloaterreg.h"
  38. #include "llhints.h"
  39. #include "lljoystickbutton.h"
  40. #include "lluictrlfactory.h"
  41. #include "llviewerwindow.h"
  42. #include "llviewercontrol.h"
  43. #include "llselectmgr.h"
  44. #include "lltoolbarview.h"
  45. #include "llviewerparcelmgr.h"
  46. #include "llviewerregion.h"
  47. #include "lltooltip.h"
  48. //
  49. // Constants
  50. //
  51. const F32 MOVE_BUTTON_DELAY = 0.0f;
  52. const F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed
  53. const F32 NUDGE_TIME = 0.25f; // in seconds
  54. //
  55. // Member functions
  56. //
  57. // protected
  58. LLFloaterMove::LLFloaterMove(const LLSD& key)
  59. : LLFloater(key),
  60. mForwardButton(NULL),
  61. mBackwardButton(NULL),
  62. mTurnLeftButton(NULL),
  63. mTurnRightButton(NULL),
  64. mMoveUpButton(NULL),
  65. mMoveDownButton(NULL),
  66. mModeActionsPanel(NULL),
  67. mCurrentMode(MM_WALK)
  68. {
  69. }
  70. LLFloaterMove::~LLFloaterMove()
  71. {
  72. // Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458.
  73. setVisible(FALSE);
  74. // Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid.
  75. // Such situation was possible when LLFloaterReg returns "dead" instance of floater.
  76. // Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg.
  77. }
  78. // virtual
  79. BOOL LLFloaterMove::postBuild()
  80. {
  81. updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
  82. // Code that implements floater buttons toggling when user moves via keyboard is located in LLAgent::propagate()
  83. mForwardButton = getChild<LLJoystickAgentTurn>("forward btn");
  84. mForwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  85. mBackwardButton = getChild<LLJoystickAgentTurn>("backward btn");
  86. mBackwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  87. mSlideLeftButton = getChild<LLJoystickAgentSlide>("move left btn");
  88. mSlideLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  89. mSlideRightButton = getChild<LLJoystickAgentSlide>("move right btn");
  90. mSlideRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  91. mTurnLeftButton = getChild<LLButton>("turn left btn");
  92. mTurnLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  93. mTurnLeftButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnLeft, this));
  94. mTurnRightButton = getChild<LLButton>("turn right btn");
  95. mTurnRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  96. mTurnRightButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnRight, this));
  97. mMoveUpButton = getChild<LLButton>("move up btn");
  98. mMoveUpButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  99. mMoveUpButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveUp, this));
  100. mMoveDownButton = getChild<LLButton>("move down btn");
  101. mMoveDownButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
  102. mMoveDownButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveDown, this));
  103. mModeActionsPanel = getChild<LLPanel>("panel_modes");
  104. LLButton* btn;
  105. btn = getChild<LLButton>("mode_walk_btn");
  106. btn->setCommitCallback(boost::bind(&LLFloaterMove::onWalkButtonClick, this));
  107. btn = getChild<LLButton>("mode_run_btn");
  108. btn->setCommitCallback(boost::bind(&LLFloaterMove::onRunButtonClick, this));
  109. btn = getChild<LLButton>("mode_fly_btn");
  110. btn->setCommitCallback(boost::bind(&LLFloaterMove::onFlyButtonClick, this));
  111. initModeTooltips();
  112. initModeButtonMap();
  113. initMovementMode();
  114. LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus);
  115. return TRUE;
  116. }
  117. // *NOTE: we assume that setVisible() is called on floater close.
  118. // virtual
  119. void LLFloaterMove::setVisible(BOOL visible)
  120. {
  121. // Do nothing with Stand/Stop Flying panel in excessive calls of this method.
  122. if (getVisible() == visible)
  123. {
  124. LLFloater::setVisible(visible);
  125. return;
  126. }
  127. if (visible)
  128. {
  129. LLFirstUse::notMoving(false);
  130. // Attach the Stand/Stop Flying panel.
  131. LLPanelStandStopFlying* ssf_panel = LLPanelStandStopFlying::getInstance();
  132. ssf_panel->reparent(this);
  133. const LLRect& mode_actions_rect = mModeActionsPanel->getRect();
  134. ssf_panel->setOrigin(mode_actions_rect.mLeft, mode_actions_rect.mBottom);
  135. }
  136. else
  137. {
  138. // Detach the Stand/Stop Flying panel.
  139. LLPanelStandStopFlying::getInstance()->reparent(NULL);
  140. }
  141. LLFloater::setVisible(visible);
  142. }
  143. // static
  144. F32 LLFloaterMove::getYawRate( F32 time )
  145. {
  146. if( time < NUDGE_TIME )
  147. {
  148. F32 rate = YAW_NUDGE_RATE + time * (1 - YAW_NUDGE_RATE)/ NUDGE_TIME;
  149. return rate;
  150. }
  151. else
  152. {
  153. return 1.f;
  154. }
  155. }
  156. // static
  157. void LLFloaterMove::setFlyingMode(BOOL fly)
  158. {
  159. LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
  160. if (instance)
  161. {
  162. instance->setFlyingModeImpl(fly);
  163. LLVOAvatarSelf* avatar_object = gAgentAvatarp;
  164. bool is_sitting = avatar_object
  165. && (avatar_object->getRegion() != NULL)
  166. && (!avatar_object->isDead())
  167. && avatar_object->isSitting();
  168. instance->showModeButtons(!fly && !is_sitting);
  169. }
  170. if (fly)
  171. {
  172. LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
  173. }
  174. else
  175. {
  176. LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
  177. }
  178. }
  179. //static
  180. void LLFloaterMove::setAlwaysRunMode(bool run)
  181. {
  182. LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
  183. if (instance)
  184. {
  185. instance->setAlwaysRunModeImpl(run);
  186. }
  187. }
  188. void LLFloaterMove::setFlyingModeImpl(BOOL fly)
  189. {
  190. updateButtonsWithMovementMode(fly ? MM_FLY : (gAgent.getAlwaysRun() ? MM_RUN : MM_WALK));
  191. }
  192. void LLFloaterMove::setAlwaysRunModeImpl(bool run)
  193. {
  194. if (!gAgent.getFlying())
  195. {
  196. updateButtonsWithMovementMode(run ? MM_RUN : MM_WALK);
  197. }
  198. }
  199. //static
  200. void LLFloaterMove::setSittingMode(BOOL bSitting)
  201. {
  202. if (bSitting)
  203. {
  204. LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND);
  205. }
  206. else
  207. {
  208. LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND);
  209. // show "Stop Flying" button if needed. EXT-871
  210. if (gAgent.getFlying())
  211. {
  212. LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
  213. }
  214. }
  215. enableInstance(!bSitting);
  216. }
  217. // protected
  218. void LLFloaterMove::turnLeft()
  219. {
  220. F32 time = mTurnLeftButton->getHeldDownTime();
  221. gAgent.moveYaw( getYawRate( time ) );
  222. }
  223. // protected
  224. void LLFloaterMove::turnRight()
  225. {
  226. F32 time = mTurnRightButton->getHeldDownTime();
  227. gAgent.moveYaw( -getYawRate( time ) );
  228. }
  229. // protected
  230. void LLFloaterMove::moveUp()
  231. {
  232. // Jumps or flys up, depending on fly state
  233. gAgent.moveUp(1);
  234. }
  235. // protected
  236. void LLFloaterMove::moveDown()
  237. {
  238. // Crouches or flys down, depending on fly state
  239. gAgent.moveUp(-1);
  240. }
  241. //////////////////////////////////////////////////////////////////////////
  242. // Private Section:
  243. //////////////////////////////////////////////////////////////////////////
  244. void LLFloaterMove::onWalkButtonClick()
  245. {
  246. setMovementMode(MM_WALK);
  247. }
  248. void LLFloaterMove::onRunButtonClick()
  249. {
  250. setMovementMode(MM_RUN);
  251. }
  252. void LLFloaterMove::onFlyButtonClick()
  253. {
  254. setMovementMode(MM_FLY);
  255. }
  256. void LLFloaterMove::setMovementMode(const EMovementMode mode)
  257. {
  258. mCurrentMode = mode;
  259. gAgent.setFlying(MM_FLY == mode);
  260. // attempts to set avatar flying can not set it real flying in some cases.
  261. // For ex. when avatar fell down & is standing up.
  262. // So, no need to continue processing FLY mode. See EXT-1079
  263. if (MM_FLY == mode && !gAgent.getFlying())
  264. {
  265. return;
  266. }
  267. switch (mode)
  268. {
  269. case MM_RUN:
  270. gAgent.setAlwaysRun();
  271. gAgent.setRunning();
  272. break;
  273. case MM_WALK:
  274. gAgent.clearAlwaysRun();
  275. gAgent.clearRunning();
  276. break;
  277. default:
  278. //do nothing for other modes (MM_FLY)
  279. break;
  280. }
  281. // tell the simulator.
  282. gAgent.sendWalkRun(gAgent.getAlwaysRun());
  283. updateButtonsWithMovementMode(mode);
  284. bool bHideModeButtons = MM_FLY == mode
  285. || (isAgentAvatarValid() && gAgentAvatarp->isSitting());
  286. showModeButtons(!bHideModeButtons);
  287. }
  288. void LLFloaterMove::updateButtonsWithMovementMode(const EMovementMode newMode)
  289. {
  290. setModeTooltip(newMode);
  291. setModeButtonToggleState(newMode);
  292. setModeTitle(newMode);
  293. }
  294. void LLFloaterMove::initModeTooltips()
  295. {
  296. control_tooltip_map_t walkTipMap;
  297. walkTipMap.insert(std::make_pair(mForwardButton, getString("walk_forward_tooltip")));
  298. walkTipMap.insert(std::make_pair(mBackwardButton, getString("walk_back_tooltip")));
  299. walkTipMap.insert(std::make_pair(mSlideLeftButton, getString("walk_left_tooltip")));
  300. walkTipMap.insert(std::make_pair(mSlideRightButton, getString("walk_right_tooltip")));
  301. walkTipMap.insert(std::make_pair(mMoveUpButton, getString("jump_tooltip")));
  302. walkTipMap.insert(std::make_pair(mMoveDownButton, getString("crouch_tooltip")));
  303. mModeControlTooltipsMap[MM_WALK] = walkTipMap;
  304. control_tooltip_map_t runTipMap;
  305. runTipMap.insert(std::make_pair(mForwardButton, getString("run_forward_tooltip")));
  306. runTipMap.insert(std::make_pair(mBackwardButton, getString("run_back_tooltip")));
  307. runTipMap.insert(std::make_pair(mSlideLeftButton, getString("run_left_tooltip")));
  308. runTipMap.insert(std::make_pair(mSlideRightButton, getString("run_right_tooltip")));
  309. runTipMap.insert(std::make_pair(mMoveUpButton, getString("jump_tooltip")));
  310. runTipMap.insert(std::make_pair(mMoveDownButton, getString("crouch_tooltip")));
  311. mModeControlTooltipsMap[MM_RUN] = runTipMap;
  312. control_tooltip_map_t flyTipMap;
  313. flyTipMap.insert(std::make_pair(mForwardButton, getString("fly_forward_tooltip")));
  314. flyTipMap.insert(std::make_pair(mBackwardButton, getString("fly_back_tooltip")));
  315. flyTipMap.insert(std::make_pair(mSlideLeftButton, getString("fly_left_tooltip")));
  316. flyTipMap.insert(std::make_pair(mSlideRightButton, getString("fly_right_tooltip")));
  317. flyTipMap.insert(std::make_pair(mMoveUpButton, getString("fly_up_tooltip")));
  318. flyTipMap.insert(std::make_pair(mMoveDownButton, getString("fly_down_tooltip")));
  319. mModeControlTooltipsMap[MM_FLY] = flyTipMap;
  320. setModeTooltip(MM_WALK);
  321. }
  322. void LLFloaterMove::initModeButtonMap()
  323. {
  324. mModeControlButtonMap[MM_WALK] = getChild<LLButton>("mode_walk_btn");
  325. mModeControlButtonMap[MM_RUN] = getChild<LLButton>("mode_run_btn");
  326. mModeControlButtonMap[MM_FLY] = getChild<LLButton>("mode_fly_btn");
  327. }
  328. void LLFloaterMove::initMovementMode()
  329. {
  330. EMovementMode initMovementMode = gAgent.getAlwaysRun() ? MM_RUN : MM_WALK;
  331. if (gAgent.getFlying())
  332. {
  333. initMovementMode = MM_FLY;
  334. }
  335. setMovementMode(initMovementMode);
  336. if (isAgentAvatarValid())
  337. {
  338. showModeButtons(!gAgentAvatarp->isSitting());
  339. }
  340. }
  341. void LLFloaterMove::setModeTooltip(const EMovementMode mode)
  342. {
  343. llassert_always(mModeControlTooltipsMap.end() != mModeControlTooltipsMap.find(mode));
  344. control_tooltip_map_t controlsTipMap = mModeControlTooltipsMap[mode];
  345. control_tooltip_map_t::const_iterator it = controlsTipMap.begin();
  346. for (; it != controlsTipMap.end(); ++it)
  347. {
  348. LLView* ctrl = it->first;
  349. std::string tooltip = it->second;
  350. ctrl->setToolTip(tooltip);
  351. }
  352. }
  353. void LLFloaterMove::setModeTitle(const EMovementMode mode)
  354. {
  355. std::string title;
  356. switch(mode)
  357. {
  358. case MM_WALK:
  359. title = getString("walk_title");
  360. break;
  361. case MM_RUN:
  362. title = getString("run_title");
  363. break;
  364. case MM_FLY:
  365. title = getString("fly_title");
  366. break;
  367. default:
  368. // title should be provided for all modes
  369. llassert(false);
  370. break;
  371. }
  372. setTitle(title);
  373. }
  374. //static
  375. void LLFloaterMove::sUpdateFlyingStatus()
  376. {
  377. LLFloaterMove *floater = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
  378. if (floater) floater->mModeControlButtonMap[MM_FLY]->setEnabled(gAgent.canFly());
  379. }
  380. void LLFloaterMove::showModeButtons(BOOL bShow)
  381. {
  382. if (mModeActionsPanel->getVisible() == bShow)
  383. return;
  384. mModeActionsPanel->setVisible(bShow);
  385. }
  386. //static
  387. void LLFloaterMove::enableInstance(BOOL bEnable)
  388. {
  389. LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
  390. if (instance)
  391. {
  392. if (gAgent.getFlying())
  393. {
  394. instance->showModeButtons(FALSE);
  395. }
  396. else
  397. {
  398. instance->showModeButtons(bEnable);
  399. }
  400. }
  401. }
  402. void LLFloaterMove::onOpen(const LLSD& key)
  403. {
  404. if (gAgent.getFlying())
  405. {
  406. setFlyingMode(TRUE);
  407. showModeButtons(FALSE);
  408. }
  409. if (isAgentAvatarValid() && gAgentAvatarp->isSitting())
  410. {
  411. setSittingMode(TRUE);
  412. showModeButtons(FALSE);
  413. }
  414. sUpdateFlyingStatus();
  415. }
  416. void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode)
  417. {
  418. llassert_always(mModeControlButtonMap.end() != mModeControlButtonMap.find(mode));
  419. mode_control_button_map_t::const_iterator it = mModeControlButtonMap.begin();
  420. for (; it != mModeControlButtonMap.end(); ++it)
  421. {
  422. it->second->setToggleState(FALSE);
  423. }
  424. mModeControlButtonMap[mode]->setToggleState(TRUE);
  425. }
  426. /************************************************************************/
  427. /* LLPanelStandStopFlying */
  428. /************************************************************************/
  429. LLPanelStandStopFlying::LLPanelStandStopFlying() :
  430. mStandButton(NULL),
  431. mStopFlyingButton(NULL),
  432. mAttached(false)
  433. {
  434. // make sure we have the only instance of this class
  435. static bool b = true;
  436. llassert_always(b);
  437. b=false;
  438. }
  439. // static
  440. LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
  441. {
  442. static LLPanelStandStopFlying* panel = getStandStopFlyingPanel();
  443. return panel;
  444. }
  445. //static
  446. void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode)
  447. {
  448. LLPanelStandStopFlying* panel = getInstance();
  449. if (mode == SSFM_STAND)
  450. {
  451. LLFirstUse::sit();
  452. LLFirstUse::notMoving(false);
  453. }
  454. panel->mStandButton->setVisible(SSFM_STAND == mode);
  455. panel->mStopFlyingButton->setVisible(SSFM_STOP_FLYING == mode);
  456. //visibility of it should be updated after updating visibility of the buttons
  457. panel->setVisible(TRUE);
  458. }
  459. //static
  460. void LLPanelStandStopFlying::clearStandStopFlyingMode(EStandStopFlyingMode mode)
  461. {
  462. LLPanelStandStopFlying* panel = getInstance();
  463. switch(mode) {
  464. case SSFM_STAND:
  465. panel->mStandButton->setVisible(FALSE);
  466. break;
  467. case SSFM_STOP_FLYING:
  468. panel->mStopFlyingButton->setVisible(FALSE);
  469. break;
  470. default:
  471. llerrs << "Unexpected EStandStopFlyingMode is passed: " << mode << llendl;
  472. }
  473. }
  474. BOOL LLPanelStandStopFlying::postBuild()
  475. {
  476. mStandButton = getChild<LLButton>("stand_btn");
  477. mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this));
  478. mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE));
  479. mStandButton->setVisible(FALSE);
  480. LLHints::registerHintTarget("stand_btn", mStandButton->getHandle());
  481. mStopFlyingButton = getChild<LLButton>("stop_fly_btn");
  482. //mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE));
  483. mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this));
  484. mStopFlyingButton->setVisible(FALSE);
  485. return TRUE;
  486. }
  487. //virtual
  488. void LLPanelStandStopFlying::setVisible(BOOL visible)
  489. {
  490. //we dont need to show the panel if these buttons are not activated
  491. if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
  492. if (visible)
  493. {
  494. updatePosition();
  495. }
  496. // do not change parent visibility in case panel is attached into Move Floater: EXT-3632, EXT-4646
  497. if (!mAttached)
  498. {
  499. //change visibility of parent layout_panel to animate in/out. EXT-2504
  500. if (getParent()) getParent()->setVisible(visible);
  501. }
  502. // also change own visibility to avoid displaying the panel in mouselook (broken when EXT-2504 was implemented).
  503. // See EXT-4718.
  504. LLPanel::setVisible(visible);
  505. }
  506. BOOL LLPanelStandStopFlying::handleToolTip(S32 x, S32 y, MASK mask)
  507. {
  508. LLToolTipMgr::instance().unblockToolTips();
  509. if (mStandButton->getVisible())
  510. {
  511. LLToolTipMgr::instance().show(mStandButton->getToolTip());
  512. }
  513. else if (mStopFlyingButton->getVisible())
  514. {
  515. LLToolTipMgr::instance().show(mStopFlyingButton->getToolTip());
  516. }
  517. return LLPanel::handleToolTip(x, y, mask);
  518. }
  519. void LLPanelStandStopFlying::reparent(LLFloaterMove* move_view)
  520. {
  521. LLPanel* parent = dynamic_cast<LLPanel*>(getParent());
  522. if (!parent)
  523. {
  524. llwarns << "Stand/stop flying panel parent is unset, already attached?: " << mAttached << ", new parent: " << (move_view == NULL ? "NULL" : "Move Floater") << llendl;
  525. return;
  526. }
  527. if (move_view != NULL)
  528. {
  529. llassert(move_view != parent); // sanity check
  530. // Save our original container.
  531. if (!mOriginalParent.get())
  532. mOriginalParent = parent->getHandle();
  533. // Attach to movement controls.
  534. parent->removeChild(this);
  535. move_view->addChild(this);
  536. // Origin must be set by movement controls.
  537. mAttached = true;
  538. }
  539. else
  540. {
  541. if (!mOriginalParent.get())
  542. {
  543. llwarns << "Original parent of the stand / stop flying panel not found" << llendl;
  544. return;
  545. }
  546. // Detach from movement controls.
  547. parent->removeChild(this);
  548. mOriginalParent.get()->addChild(this);
  549. // update parent with self visibility (it is changed in setVisible()). EXT-4743
  550. mOriginalParent.get()->setVisible(getVisible());
  551. mAttached = false;
  552. updatePosition(); // don't defer until next draw() to avoid flicker
  553. }
  554. }
  555. //////////////////////////////////////////////////////////////////////////
  556. // Private Section
  557. //////////////////////////////////////////////////////////////////////////
  558. //static
  559. LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel()
  560. {
  561. LLPanelStandStopFlying* panel = new LLPanelStandStopFlying();
  562. panel->buildFromFile("panel_stand_stop_flying.xml");
  563. panel->setVisible(FALSE);
  564. //LLUI::getRootView()->addChild(panel);
  565. llinfos << "Build LLPanelStandStopFlying panel" << llendl;
  566. panel->updatePosition();
  567. return panel;
  568. }
  569. void LLPanelStandStopFlying::onStandButtonClick()
  570. {
  571. LLFirstUse::sit(false);
  572. LLSelectMgr::getInstance()->deselectAllForStandingUp();
  573. gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
  574. setFocus(FALSE); // EXT-482
  575. mStandButton->setVisible(FALSE); // force visibility changing to avoid seeing Stand & Move buttons at once.
  576. }
  577. void LLPanelStandStopFlying::onStopFlyingButtonClick()
  578. {
  579. gAgent.setFlying(FALSE);
  580. setFocus(FALSE); // EXT-482
  581. setVisible(FALSE);
  582. }
  583. /**
  584. * Updates position of the Stand & Stop Flying panel to be center aligned with Move button.
  585. */
  586. void LLPanelStandStopFlying::updatePosition()
  587. {
  588. if (mAttached) return;
  589. S32 y_pos = 0;
  590. S32 bottom_tb_center = 0;
  591. if (LLToolBar* toolbar_bottom = gToolBarView->getChild<LLToolBar>("toolbar_bottom"))
  592. {
  593. y_pos = toolbar_bottom->getRect().getHeight();
  594. bottom_tb_center = toolbar_bottom->getRect().getCenterX();
  595. }
  596. S32 left_tb_width = 0;
  597. if (LLToolBar* toolbar_left = gToolBarView->getChild<LLToolBar>("toolbar_left"))
  598. {
  599. left_tb_width = toolbar_left->getRect().getWidth();
  600. }
  601. if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container"))
  602. {
  603. panel_ssf_container->setOrigin(0, y_pos);
  604. }
  605. S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width;
  606. setOrigin( x_pos, 0);
  607. }
  608. // EOF