/** * @file llfloatercamera.cpp * @brief Container for camera control buttons (zoom, pan, orbit) * * $LicenseInfo:firstyear=2001&license=viewergpl$ * * Copyright (c) 2001-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llfloatercamera.h" // Library includes #include "llfloaterreg.h" // Viewer includes #include "lljoystickbutton.h" #include "llfirsttimetipmanager.h" #include "llviewercontrol.h" #include "llbottomtray.h" #include "llagent.h" #include "lltoolmgr.h" #include "lltoolfocus.h" // Constants const F32 CAMERA_BUTTON_DELAY = 0.0f; #define ORBIT "cam_rotate_stick" #define PAN "cam_track_stick" #define CONTROLS "controls" void show_tip(LLFirstTimeTipsManager::EFirstTimeTipType tipType, LLView* anchorView) { LLFirstTimeTipsManager::showTipsFor(tipType, anchorView, LLFirstTimeTipsManager::TPA_POS_RIGHT_ALIGN_TOP); } // // Member functions // /*static*/ bool LLFloaterCamera::inFreeCameraMode() { LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) { return true; } return false; } bool LLFloaterCamera::inAvatarViewMode() { return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW; } void LLFloaterCamera::resetFreeCameraMode() { if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) { /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look In such case we are unable to determine that we will be into Mouse Look view */ if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW) { setMode(CAMERA_CTRL_MODE_ORBIT); } else { setMode(mPrevMode); } } } void LLFloaterCamera::update() { ECameraControlMode mode = determineMode(); if (mode != mCurrMode) setMode(mode); updatePosition(); show_tip(mMode2TipType[mode], this); } /*static*/ void LLFloaterCamera::updateIfNotInAvatarViewMode() { LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); if (floater_camera && !floater_camera->inAvatarViewMode()) { floater_camera->update(); } } void LLFloaterCamera::toPrevMode() { switchMode(mPrevMode); } /*static*/ void LLFloaterCamera::toPrevModeIfInAvatarViewMode() { LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); if (floater_camera && floater_camera->inAvatarViewMode()) { floater_camera->toPrevMode(); } } LLFloaterCamera* LLFloaterCamera::findInstance() { return LLFloaterReg::findTypedInstance("camera"); } /*static*/ void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param) { std::string name = param.asString(); if ("rear_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl); gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); } else if ("group_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP); gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW); } else if ("front_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT); gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW); } } void LLFloaterCamera::onOpen(const LLSD& key) { updatePosition(); } void LLFloaterCamera::updatePosition() { LLBottomTray* tray = LLBottomTray::getInstance(); if (!tray) return; LLButton* camera_button = tray->getChild("camera_btn"); //align centers of a button and a floater S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2; setOrigin(x, 0); } LLFloaterCamera::LLFloaterCamera(const LLSD& val) : LLFloater(val), mCurrMode(CAMERA_CTRL_MODE_ORBIT), mPrevMode(CAMERA_CTRL_MODE_ORBIT) { } // virtual BOOL LLFloaterCamera::postBuild() { setIsChrome(TRUE); mRotate = getChild(ORBIT); mZoom = getChild("zoom"); mTrack = getChild(PAN); initMode2TipTypeMap(); assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn"); assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn"); assignButton2Mode(CAMERA_CTRL_MODE_FREE_CAMERA, "freecamera_btn"); assignButton2Mode(CAMERA_CTRL_MODE_AVATAR_VIEW, "avatarview_btn"); update(); return TRUE; } ECameraControlMode LLFloaterCamera::determineMode() { LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool(); if (curr_tool == LLToolCamera::getInstance()) { return CAMERA_CTRL_MODE_FREE_CAMERA; } if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) { return CAMERA_CTRL_MODE_AVATAR_VIEW; } return CAMERA_CTRL_MODE_ORBIT; } void clear_camera_tool() { LLToolMgr* tool_mgr = LLToolMgr::getInstance(); if (tool_mgr->usingTransientTool() && tool_mgr->getCurrentTool() == LLToolCamera::getInstance()) { tool_mgr->clearTransientTool(); } } void LLFloaterCamera::setMode(ECameraControlMode mode) { if (mode != mCurrMode) { mPrevMode = mCurrMode; mCurrMode = mode; } updateState(); } void LLFloaterCamera::switchMode(ECameraControlMode mode) { setMode(mode); switch (mode) { case CAMERA_CTRL_MODE_ORBIT: clear_camera_tool(); break; case CAMERA_CTRL_MODE_PAN: clear_camera_tool(); break; case CAMERA_CTRL_MODE_FREE_CAMERA: LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); break; case CAMERA_CTRL_MODE_AVATAR_VIEW: gAgent.changeCameraToMouselook(); break; default: //normally we won't occur here llassert_always(FALSE); } } void LLFloaterCamera::onClickBtn(ECameraControlMode mode) { // check for a click on active button if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE); switchMode(mode); show_tip(mMode2TipType[mode], this); } void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name) { LLButton* button = getChild(button_name); button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode)); mMode2Button[mode] = button; } void LLFloaterCamera::initMode2TipTypeMap() { mMode2TipType[CAMERA_CTRL_MODE_ORBIT] = LLFirstTimeTipsManager::FTT_CAMERA_ORBIT_MODE; mMode2TipType[CAMERA_CTRL_MODE_PAN] = LLFirstTimeTipsManager::FTT_CAMERA_PAN_MODE; mMode2TipType[CAMERA_CTRL_MODE_FREE_CAMERA] = LLFirstTimeTipsManager::FTT_CAMERA_FREE_MODE; mMode2TipType[CAMERA_CTRL_MODE_AVATAR_VIEW] = LLFirstTimeTipsManager::FTT_AVATAR_FREE_MODE; } void LLFloaterCamera::updateState() { //updating buttons std::map::const_iterator iter = mMode2Button.begin(); for (; iter != mMode2Button.end(); ++iter) { iter->second->setToggleState(iter->first == mCurrMode); } //updating controls bool isOrbitMode = CAMERA_CTRL_MODE_ORBIT == mCurrMode; bool isPanMode = CAMERA_CTRL_MODE_PAN == mCurrMode; childSetVisible(ORBIT, isOrbitMode); childSetVisible(PAN, isPanMode); //hiding or showing the panel with controls by reshaping the floater bool showControls = isOrbitMode || isPanMode; if (showControls == childIsVisible(CONTROLS)) return; childSetVisible(CONTROLS, showControls); LLRect rect = getRect(); LLRect controls_rect; if (childGetRect(CONTROLS, controls_rect)) { static S32 height = controls_rect.getHeight(); S32 newHeight = rect.getHeight(); if (showControls) { newHeight += height; } else { newHeight -= height; } rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), newHeight); reshape(rect.getWidth(), rect.getHeight()); setRect(rect); } }