PageRenderTime 30ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloatercamera.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 585 lines | 436 code | 94 blank | 55 comment | 79 complexity | f1096c385d2404045cd04f2a63c4396a MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloatercamera.cpp
  3. * @brief Container for camera control buttons (zoom, pan, orbit)
  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 "llfloatercamera.h"
  28. // Library includes
  29. #include "llfloaterreg.h"
  30. // Viewer includes
  31. #include "llagentcamera.h"
  32. #include "lljoystickbutton.h"
  33. #include "llviewercontrol.h"
  34. #include "llviewercamera.h"
  35. #include "lltoolmgr.h"
  36. #include "lltoolfocus.h"
  37. #include "llslider.h"
  38. #include "llfirstuse.h"
  39. #include "llhints.h"
  40. static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item");
  41. const F32 NUDGE_TIME = 0.25f; // in seconds
  42. const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
  43. // Constants
  44. const F32 CAMERA_BUTTON_DELAY = 0.0f;
  45. #define ORBIT "cam_rotate_stick"
  46. #define PAN "cam_track_stick"
  47. #define ZOOM "zoom"
  48. #define PRESETS "preset_views_list"
  49. #define CONTROLS "controls"
  50. bool LLFloaterCamera::sFreeCamera = false;
  51. bool LLFloaterCamera::sAppearanceEditing = false;
  52. // Zoom the camera in and out
  53. class LLPanelCameraZoom
  54. : public LLPanel
  55. {
  56. LOG_CLASS(LLPanelCameraZoom);
  57. public:
  58. LLPanelCameraZoom();
  59. /* virtual */ BOOL postBuild();
  60. /* virtual */ void draw();
  61. protected:
  62. void onZoomPlusHeldDown();
  63. void onZoomMinusHeldDown();
  64. void onSliderValueChanged();
  65. void onCameraTrack();
  66. void onCameraRotate();
  67. F32 getOrbitRate(F32 time);
  68. private:
  69. LLButton* mPlusBtn;
  70. LLButton* mMinusBtn;
  71. LLSlider* mSlider;
  72. };
  73. LLPanelCameraItem::Params::Params()
  74. : icon_over("icon_over"),
  75. icon_selected("icon_selected"),
  76. picture("picture"),
  77. text("text"),
  78. selected_picture("selected_picture"),
  79. mousedown_callback("mousedown_callback")
  80. {
  81. }
  82. LLPanelCameraItem::LLPanelCameraItem(const LLPanelCameraItem::Params& p)
  83. : LLPanel(p)
  84. {
  85. LLIconCtrl::Params icon_params = p.picture;
  86. mPicture = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
  87. addChild(mPicture);
  88. icon_params = p.icon_over;
  89. mIconOver = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
  90. addChild(mIconOver);
  91. icon_params = p.icon_selected;
  92. mIconSelected = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
  93. addChild(mIconSelected);
  94. icon_params = p.selected_picture;
  95. mPictureSelected = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
  96. addChild(mPictureSelected);
  97. LLTextBox::Params text_params = p.text;
  98. mText = LLUICtrlFactory::create<LLTextBox>(text_params);
  99. addChild(mText);
  100. if (p.mousedown_callback.isProvided())
  101. {
  102. setCommitCallback(initCommitCallback(p.mousedown_callback));
  103. }
  104. }
  105. void set_view_visible(LLView* parent, const std::string& name, bool visible)
  106. {
  107. parent->getChildView(name)->setVisible(visible);
  108. }
  109. BOOL LLPanelCameraItem::postBuild()
  110. {
  111. setMouseEnterCallback(boost::bind(set_view_visible, this, "hovered_icon", true));
  112. setMouseLeaveCallback(boost::bind(set_view_visible, this, "hovered_icon", false));
  113. setMouseDownCallback(boost::bind(&LLPanelCameraItem::onAnyMouseClick, this));
  114. setRightMouseDownCallback(boost::bind(&LLPanelCameraItem::onAnyMouseClick, this));
  115. return TRUE;
  116. }
  117. void LLPanelCameraItem::onAnyMouseClick()
  118. {
  119. if (mCommitSignal) (*mCommitSignal)(this, LLSD());
  120. }
  121. void LLPanelCameraItem::setValue(const LLSD& value)
  122. {
  123. if (!value.isMap()) return;;
  124. if (!value.has("selected")) return;
  125. getChildView("selected_icon")->setVisible( value["selected"]);
  126. getChildView("picture")->setVisible( !value["selected"]);
  127. getChildView("selected_picture")->setVisible( value["selected"]);
  128. }
  129. static LLRegisterPanelClassWrapper<LLPanelCameraZoom> t_camera_zoom_panel("camera_zoom_panel");
  130. //-------------------------------------------------------------------------------
  131. // LLPanelCameraZoom
  132. //-------------------------------------------------------------------------------
  133. LLPanelCameraZoom::LLPanelCameraZoom()
  134. : mPlusBtn( NULL ),
  135. mMinusBtn( NULL ),
  136. mSlider( NULL )
  137. {
  138. mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this));
  139. mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this));
  140. mCommitCallbackRegistrar.add("Slider.value_changed", boost::bind(&LLPanelCameraZoom::onSliderValueChanged, this));
  141. mCommitCallbackRegistrar.add("Camera.track", boost::bind(&LLPanelCameraZoom::onCameraTrack, this));
  142. mCommitCallbackRegistrar.add("Camera.rotate", boost::bind(&LLPanelCameraZoom::onCameraRotate, this));
  143. }
  144. BOOL LLPanelCameraZoom::postBuild()
  145. {
  146. mPlusBtn = getChild <LLButton> ("zoom_plus_btn");
  147. mMinusBtn = getChild <LLButton> ("zoom_minus_btn");
  148. mSlider = getChild <LLSlider> ("zoom_slider");
  149. return LLPanel::postBuild();
  150. }
  151. void LLPanelCameraZoom::draw()
  152. {
  153. mSlider->setValue(gAgentCamera.getCameraZoomFraction());
  154. LLPanel::draw();
  155. }
  156. void LLPanelCameraZoom::onZoomPlusHeldDown()
  157. {
  158. F32 val = mSlider->getValueF32();
  159. F32 inc = mSlider->getIncrement();
  160. mSlider->setValue(val - inc);
  161. F32 time = mPlusBtn->getHeldDownTime();
  162. gAgentCamera.unlockView();
  163. gAgentCamera.setOrbitInKey(getOrbitRate(time));
  164. }
  165. void LLPanelCameraZoom::onZoomMinusHeldDown()
  166. {
  167. F32 val = mSlider->getValueF32();
  168. F32 inc = mSlider->getIncrement();
  169. mSlider->setValue(val + inc);
  170. F32 time = mMinusBtn->getHeldDownTime();
  171. gAgentCamera.unlockView();
  172. gAgentCamera.setOrbitOutKey(getOrbitRate(time));
  173. }
  174. void LLPanelCameraZoom::onCameraTrack()
  175. {
  176. // EXP-202 when camera panning activated, remove the hint
  177. LLFirstUse::viewPopup( false );
  178. }
  179. void LLPanelCameraZoom::onCameraRotate()
  180. {
  181. // EXP-202 when camera rotation activated, remove the hint
  182. LLFirstUse::viewPopup( false );
  183. }
  184. F32 LLPanelCameraZoom::getOrbitRate(F32 time)
  185. {
  186. if( time < NUDGE_TIME )
  187. {
  188. F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
  189. return rate;
  190. }
  191. else
  192. {
  193. return 1;
  194. }
  195. }
  196. void LLPanelCameraZoom::onSliderValueChanged()
  197. {
  198. F32 zoom_level = mSlider->getValueF32();
  199. gAgentCamera.setCameraZoomFraction(zoom_level);
  200. }
  201. void activate_camera_tool()
  202. {
  203. LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
  204. };
  205. //
  206. // Member functions
  207. //
  208. /*static*/ bool LLFloaterCamera::inFreeCameraMode()
  209. {
  210. LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
  211. if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
  212. {
  213. return true;
  214. }
  215. return false;
  216. }
  217. void LLFloaterCamera::resetCameraMode()
  218. {
  219. LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
  220. if (!floater_camera) return;
  221. floater_camera->switchMode(CAMERA_CTRL_MODE_PAN);
  222. }
  223. void LLFloaterCamera::onAvatarEditingAppearance(bool editing)
  224. {
  225. sAppearanceEditing = editing;
  226. LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
  227. if (!floater_camera) return;
  228. floater_camera->handleAvatarEditingAppearance(editing);
  229. }
  230. void LLFloaterCamera::handleAvatarEditingAppearance(bool editing)
  231. {
  232. //camera presets (rear, front, etc.)
  233. getChildView("preset_views_list")->setEnabled(!editing);
  234. getChildView("presets_btn")->setEnabled(!editing);
  235. //camera modes (object view, mouselook view)
  236. getChildView("camera_modes_list")->setEnabled(!editing);
  237. getChildView("avatarview_btn")->setEnabled(!editing);
  238. }
  239. void LLFloaterCamera::update()
  240. {
  241. ECameraControlMode mode = determineMode();
  242. if (mode != mCurrMode) setMode(mode);
  243. }
  244. void LLFloaterCamera::toPrevMode()
  245. {
  246. switchMode(mPrevMode);
  247. }
  248. /*static*/ void LLFloaterCamera::onLeavingMouseLook()
  249. {
  250. LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
  251. if (floater_camera)
  252. {
  253. floater_camera->updateItemsSelection();
  254. if(floater_camera->inFreeCameraMode())
  255. {
  256. activate_camera_tool();
  257. }
  258. }
  259. }
  260. LLFloaterCamera* LLFloaterCamera::findInstance()
  261. {
  262. return LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
  263. }
  264. void LLFloaterCamera::onOpen(const LLSD& key)
  265. {
  266. LLFirstUse::viewPopup();
  267. mZoom->onOpen(key);
  268. // Returns to previous mode, see EXT-2727(View tool should remember state).
  269. // In case floater was just hidden and it isn't reset the mode
  270. // just update state to current one. Else go to previous.
  271. if ( !mClosed )
  272. updateState();
  273. else
  274. toPrevMode();
  275. mClosed = FALSE;
  276. }
  277. void LLFloaterCamera::onClose(bool app_quitting)
  278. {
  279. //We don't care of camera mode if app is quitting
  280. if(app_quitting)
  281. return;
  282. // When mCurrMode is in CAMERA_CTRL_MODE_PAN
  283. // switchMode won't modify mPrevMode, so force it here.
  284. // It is needed to correctly return to previous mode on open, see EXT-2727.
  285. if (mCurrMode == CAMERA_CTRL_MODE_PAN)
  286. mPrevMode = CAMERA_CTRL_MODE_PAN;
  287. switchMode(CAMERA_CTRL_MODE_PAN);
  288. mClosed = TRUE;
  289. }
  290. LLFloaterCamera::LLFloaterCamera(const LLSD& val)
  291. : LLFloater(val),
  292. mClosed(FALSE),
  293. mCurrMode(CAMERA_CTRL_MODE_PAN),
  294. mPrevMode(CAMERA_CTRL_MODE_PAN)
  295. {
  296. LLHints::registerHintTarget("view_popup", getHandle());
  297. mCommitCallbackRegistrar.add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2));
  298. }
  299. // virtual
  300. BOOL LLFloaterCamera::postBuild()
  301. {
  302. updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
  303. mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
  304. mZoom = findChild<LLPanelCameraZoom>(ZOOM);
  305. mTrack = getChild<LLJoystickCameraTrack>(PAN);
  306. assignButton2Mode(CAMERA_CTRL_MODE_MODES, "avatarview_btn");
  307. assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn");
  308. assignButton2Mode(CAMERA_CTRL_MODE_PRESETS, "presets_btn");
  309. update();
  310. // ensure that appearance mode is handled while building. See EXT-7796.
  311. handleAvatarEditingAppearance(sAppearanceEditing);
  312. return LLFloater::postBuild();
  313. }
  314. void LLFloaterCamera::fillFlatlistFromPanel (LLFlatListView* list, LLPanel* panel)
  315. {
  316. // copying child list and then iterating over a copy, because list itself
  317. // is changed in process
  318. const child_list_t child_list = *panel->getChildList();
  319. child_list_t::const_reverse_iterator iter = child_list.rbegin();
  320. child_list_t::const_reverse_iterator end = child_list.rend();
  321. for ( ; iter != end; ++iter)
  322. {
  323. LLView* view = *iter;
  324. LLPanel* item = dynamic_cast<LLPanel*>(view);
  325. if (panel)
  326. list->addItem(item);
  327. }
  328. }
  329. ECameraControlMode LLFloaterCamera::determineMode()
  330. {
  331. if (sAppearanceEditing)
  332. {
  333. // this is the only enabled camera mode while editing agent appearance.
  334. return CAMERA_CTRL_MODE_PAN;
  335. }
  336. LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool();
  337. if (curr_tool == LLToolCamera::getInstance())
  338. {
  339. return CAMERA_CTRL_MODE_FREE_CAMERA;
  340. }
  341. if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
  342. {
  343. return CAMERA_CTRL_MODE_PRESETS;
  344. }
  345. return CAMERA_CTRL_MODE_PAN;
  346. }
  347. void clear_camera_tool()
  348. {
  349. LLToolMgr* tool_mgr = LLToolMgr::getInstance();
  350. if (tool_mgr->usingTransientTool() &&
  351. tool_mgr->getCurrentTool() == LLToolCamera::getInstance())
  352. {
  353. tool_mgr->clearTransientTool();
  354. }
  355. }
  356. void LLFloaterCamera::setMode(ECameraControlMode mode)
  357. {
  358. if (mode != mCurrMode)
  359. {
  360. mPrevMode = mCurrMode;
  361. mCurrMode = mode;
  362. }
  363. updateState();
  364. }
  365. void LLFloaterCamera::switchMode(ECameraControlMode mode)
  366. {
  367. setMode(mode);
  368. switch (mode)
  369. {
  370. case CAMERA_CTRL_MODE_MODES:
  371. if(sFreeCamera)
  372. {
  373. switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
  374. }
  375. break;
  376. case CAMERA_CTRL_MODE_PAN:
  377. sFreeCamera = false;
  378. clear_camera_tool();
  379. break;
  380. case CAMERA_CTRL_MODE_FREE_CAMERA:
  381. sFreeCamera = true;
  382. activate_camera_tool();
  383. break;
  384. case CAMERA_CTRL_MODE_PRESETS:
  385. if(sFreeCamera)
  386. {
  387. switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
  388. }
  389. break;
  390. default:
  391. //normally we won't occur here
  392. llassert_always(FALSE);
  393. }
  394. }
  395. void LLFloaterCamera::onClickBtn(ECameraControlMode mode)
  396. {
  397. // check for a click on active button
  398. if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE);
  399. switchMode(mode);
  400. }
  401. void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name)
  402. {
  403. LLButton* button = getChild<LLButton>(button_name);
  404. button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode));
  405. mMode2Button[mode] = button;
  406. }
  407. void LLFloaterCamera::updateState()
  408. {
  409. getChildView(ZOOM)->setVisible(CAMERA_CTRL_MODE_PAN == mCurrMode);
  410. bool show_presets = (CAMERA_CTRL_MODE_PRESETS == mCurrMode) || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
  411. && CAMERA_CTRL_MODE_PRESETS == mPrevMode);
  412. getChildView(PRESETS)->setVisible(show_presets);
  413. bool show_camera_modes = CAMERA_CTRL_MODE_MODES == mCurrMode || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
  414. && CAMERA_CTRL_MODE_MODES == mPrevMode);
  415. getChildView("camera_modes_list")->setVisible( show_camera_modes);
  416. updateItemsSelection();
  417. if (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode)
  418. {
  419. return;
  420. }
  421. //updating buttons
  422. std::map<ECameraControlMode, LLButton*>::const_iterator iter = mMode2Button.begin();
  423. for (; iter != mMode2Button.end(); ++iter)
  424. {
  425. iter->second->setToggleState(iter->first == mCurrMode);
  426. }
  427. }
  428. void LLFloaterCamera::updateItemsSelection()
  429. {
  430. ECameraPreset preset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
  431. LLSD argument;
  432. argument["selected"] = preset == CAMERA_PRESET_REAR_VIEW;
  433. getChild<LLPanelCameraItem>("rear_view")->setValue(argument);
  434. argument["selected"] = preset == CAMERA_PRESET_GROUP_VIEW;
  435. getChild<LLPanelCameraItem>("group_view")->setValue(argument);
  436. argument["selected"] = preset == CAMERA_PRESET_FRONT_VIEW;
  437. getChild<LLPanelCameraItem>("front_view")->setValue(argument);
  438. argument["selected"] = gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK;
  439. getChild<LLPanelCameraItem>("mouselook_view")->setValue(argument);
  440. argument["selected"] = mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA;
  441. getChild<LLPanelCameraItem>("object_view")->setValue(argument);
  442. }
  443. void LLFloaterCamera::onClickCameraItem(const LLSD& param)
  444. {
  445. std::string name = param.asString();
  446. if ("mouselook_view" == name)
  447. {
  448. gAgentCamera.changeCameraToMouselook();
  449. }
  450. else if ("object_view" == name)
  451. {
  452. LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
  453. if (camera_floater)
  454. camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
  455. }
  456. else
  457. {
  458. switchToPreset(name);
  459. }
  460. LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
  461. if (camera_floater)
  462. {
  463. camera_floater->updateItemsSelection();
  464. camera_floater->fromFreeToPresets();
  465. }
  466. }
  467. /*static*/
  468. void LLFloaterCamera::switchToPreset(const std::string& name)
  469. {
  470. sFreeCamera = false;
  471. clear_camera_tool();
  472. if ("rear_view" == name)
  473. {
  474. gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
  475. }
  476. else if ("group_view" == name)
  477. {
  478. gAgentCamera.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
  479. }
  480. else if ("front_view" == name)
  481. {
  482. gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
  483. }
  484. }
  485. void LLFloaterCamera::fromFreeToPresets()
  486. {
  487. if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS)
  488. {
  489. switchMode(CAMERA_CTRL_MODE_PRESETS);
  490. }
  491. }