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