Showing the changes to interface/src/Menu.cpp (1 of 645 files). Show all
Unified · Split
| @@ -1,9 +1,12 @@ | |||
| 1 | // | 1 | // |
| 2 | // Menu.cpp | 2 | // Menu.cpp |
| 3 | // hifi | 3 | // interface/src |
| 4 | // | 4 | // |
| 5 | // Created by Stephen Birarda on 8/12/13. | 5 | // Created by Stephen Birarda on 8/12/13. |
| 6 | // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. | 6 | // Copyright 2013 High Fidelity, Inc. |
| 7 | // | ||
| 8 | // Distributed under the Apache License, Version 2.0. | ||
| 9 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||
| 7 | // | 10 | // |
| 8 | 11 | ||
| 9 | #include <cstdlib> | 12 | #include <cstdlib> |
| @@ -22,14 +25,12 @@ · 12 unmodified lines | |||
| 22 | #include <QMessageBox> | 25 | #include <QMessageBox> |
| 23 | #include <QShortcut> | 26 | #include <QShortcut> |
| 24 | #include <QSlider> | 27 | #include <QSlider> |
| 25 | #include <QStandardPaths> | ||
| 26 | #include <QUuid> | 28 | #include <QUuid> |
| 27 | #include <QHBoxLayout> | 29 | #include <QHBoxLayout> |
| 28 | 30 | ||
| 29 | #include <AccountManager.h> | 31 | #include <AccountManager.h> |
| 30 | #include <XmppClient.h> | 32 | #include <XmppClient.h> |
| 31 | #include <UUID.h> | 33 | #include <UUID.h> |
| 32 | #include <FileDownloader.h> | ||
| 33 | 34 | ||
| 34 | #include "Application.h" | 35 | #include "Application.h" |
| 35 | #include "Menu.h" | 36 | #include "Menu.h" |
| @@ -37,7 +38,7 @@ · 1 unmodified line | |||
| 37 | #include "Util.h" | 38 | #include "Util.h" |
| 38 | #include "ui/InfoView.h" | 39 | #include "ui/InfoView.h" |
| 39 | #include "ui/MetavoxelEditor.h" | 40 | #include "ui/MetavoxelEditor.h" |
| 40 | #include "ui/ModelBrowser.h" | 41 | #include "ui/ModelsBrowser.h" |
| 41 | 42 | ||
| 42 | 43 | ||
| 43 | Menu* Menu::_instance = NULL; | 44 | Menu* Menu::_instance = NULL; |
| @@ -77,6 +78,9 @@ Menu::Menu() : · 33 unmodified lines | |||
| 77 | _lodToolsDialog(NULL), | 78 | _lodToolsDialog(NULL), |
| 78 | _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM), | 79 | _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM), |
| 79 | _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), | 80 | _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), |
| 81 | _automaticAvatarLOD(true), | ||
| 82 | _avatarLODDecreaseFPS(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS), | ||
| 83 | _avatarLODIncreaseFPS(ADJUST_LOD_UP_FPS), | ||
| 80 | _avatarLODDistanceMultiplier(DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER), | 84 | _avatarLODDistanceMultiplier(DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER), |
| 81 | _boundaryLevelAdjust(0), | 85 | _boundaryLevelAdjust(0), |
| 82 | _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS), | 86 | _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS), |
| @@ -84,7 +88,9 @@ Menu::Menu() : · 1 unmodified line | |||
| 84 | _lastAvatarDetailDrop(usecTimestampNow()), | 88 | _lastAvatarDetailDrop(usecTimestampNow()), |
| 85 | _fpsAverage(FIVE_SECONDS_OF_FRAMES), | 89 | _fpsAverage(FIVE_SECONDS_OF_FRAMES), |
| 86 | _fastFPSAverage(ONE_SECOND_OF_FRAMES), | 90 | _fastFPSAverage(ONE_SECOND_OF_FRAMES), |
| 87 | _loginAction(NULL) | 91 | _loginAction(NULL), |
| 92 | _preferencesDialog(NULL), | ||
| 93 | _snapshotsLocation() | ||
| 88 | { | 94 | { |
| 89 | Application *appInstance = Application::getInstance(); | 95 | Application *appInstance = Application::getInstance(); |
| 90 | 96 | ||
| @@ -163,6 +169,15 @@ Menu::Menu() : · 72 unmodified lines | |||
| 163 | 169 | ||
| 164 | QMenu* editMenu = addMenu("Edit"); | 170 | QMenu* editMenu = addMenu("Edit"); |
| 165 | 171 | ||
| 172 | QUndoStack* undoStack = Application::getInstance()->getUndoStack(); | ||
| 173 | QAction* undoAction = undoStack->createUndoAction(editMenu); | ||
| 174 | undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); | ||
| 175 | addActionToQMenuAndActionHash(editMenu, undoAction); | ||
| 176 | |||
| 177 | QAction* redoAction = undoStack->createRedoAction(editMenu); | ||
| 178 | redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); | ||
| 179 | addActionToQMenuAndActionHash(editMenu, redoAction); | ||
| 180 | |||
| 166 | addActionToQMenuAndActionHash(editMenu, | 181 | addActionToQMenuAndActionHash(editMenu, |
| 167 | MenuOption::Preferences, | 182 | MenuOption::Preferences, |
| 168 | Qt::CTRL | Qt::Key_Comma, | 183 | Qt::CTRL | Qt::Key_Comma, |
| @@ -180,19 +195,19 @@ Menu::Menu() : · 11 unmodified lines | |||
| 180 | 195 | ||
| 181 | QMenu* toolsMenu = addMenu("Tools"); | 196 | QMenu* toolsMenu = addMenu("Tools"); |
| 182 | addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); | 197 | addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); |
| 198 | addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S, this, SLOT(showScriptEditor())); | ||
| 183 | 199 | ||
| 200 | #ifdef HAVE_QXMPP | ||
| 184 | _chatAction = addActionToQMenuAndActionHash(toolsMenu, | 201 | _chatAction = addActionToQMenuAndActionHash(toolsMenu, |
| 185 | MenuOption::Chat, | 202 | MenuOption::Chat, |
| 186 | Qt::Key_Return, | 203 | 0, |
| 187 | this, | 204 | this, |
| 188 | SLOT(showChat())); | 205 | SLOT(showChat())); |
| 189 | #ifdef HAVE_QXMPP | 206 | |
| 190 | const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient(); | 207 | const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient(); |
| 191 | toggleChat(); | 208 | toggleChat(); |
| 192 | connect(&xmppClient, SIGNAL(connected()), this, SLOT(toggleChat())); | 209 | connect(&xmppClient, SIGNAL(connected()), this, SLOT(toggleChat())); |
| 193 | connect(&xmppClient, SIGNAL(disconnected()), this, SLOT(toggleChat())); | 210 | connect(&xmppClient, SIGNAL(disconnected()), this, SLOT(toggleChat())); |
| 194 | #else | ||
| 195 | _chatAction->setEnabled(false); | ||
| 196 | #endif | 211 | #endif |
| 197 | 212 | ||
| 198 | QMenu* viewMenu = addMenu("View"); | 213 | QMenu* viewMenu = addMenu("View"); |
| @@ -242,10 +257,12 @@ Menu::Menu() : · 43 unmodified lines | |||
| 242 | addDisabledActionAndSeparator(viewMenu, "Stats"); | 257 | addDisabledActionAndSeparator(viewMenu, "Stats"); |
| 243 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); | 258 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); |
| 244 | addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); | 259 | addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); |
| 245 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Oscilloscope, 0, false); | ||
| 246 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); | 260 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); |
| 247 | addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); | 261 | addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); |
| 248 | addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, this, SLOT(octreeStatsDetails())); | 262 | addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, this, SLOT(octreeStatsDetails())); |
| 263 | addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::AudioScope, 0, false, | ||
| 264 | appInstance->getAudio(), | ||
| 265 | SLOT(toggleScope())); | ||
| 249 | 266 | ||
| 250 | QMenu* developerMenu = addMenu("Developer"); | 267 | QMenu* developerMenu = addMenu("Developer"); |
| 251 | 268 | ||
| @@ -263,7 +280,7 @@ Menu::Menu() : · 11 unmodified lines | |||
| 263 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true); | 280 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true); |
| 264 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, true); | 281 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, true); |
| 265 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true); | 282 | addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true); |
| 266 | 283 | addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); | |
| 267 | 284 | ||
| 268 | QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); | 285 | QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); |
| 269 | 286 | ||
| @@ -276,15 +293,15 @@ Menu::Menu() : · 6 unmodified lines | |||
| 276 | 293 | ||
| 277 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); | 294 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); |
| 278 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); | 295 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); |
| 279 | addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); | ||
| 280 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); | 296 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); |
| 281 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD); | 297 | addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD); |
| 282 | 298 | ||
| 283 | QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); | 299 | QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); |
| 284 | 300 | ||
| 285 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); | 301 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); |
| 286 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderSkeletonCollisionProxies); | 302 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderSkeletonCollisionShapes); |
| 287 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderHeadCollisionProxies); | 303 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderHeadCollisionShapes); |
| 304 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderBoundingCollisionShapes); | ||
| 288 | 305 | ||
| 289 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, false); | 306 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, false); |
| 290 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, | 307 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, |
| @@ -293,11 +310,17 @@ Menu::Menu() : · 2 unmodified lines | |||
| 293 | true, | 310 | true, |
| 294 | appInstance->getFaceshift(), | 311 | appInstance->getFaceshift(), |
| 295 | SLOT(setTCPEnabled(bool))); | 312 | SLOT(setTCPEnabled(bool))); |
| 313 | #ifdef HAVE_FACEPLUS | ||
| 314 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Faceplus, 0, true, | ||
| 315 | appInstance->getFaceplus(), SLOT(updateEnabled())); | ||
| 316 | #endif | ||
| 317 | |||
| 296 | #ifdef HAVE_VISAGE | 318 | #ifdef HAVE_VISAGE |
| 297 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Visage, 0, true, | 319 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Visage, 0, true, |
| 298 | appInstance->getVisage(), SLOT(updateEnabled())); | 320 | appInstance->getVisage(), SLOT(updateEnabled())); |
| 299 | #endif | 321 | #endif |
| 300 | 322 | ||
| 323 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true); | ||
| 301 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); | 324 | addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); |
| 302 | 325 | ||
| 303 | QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options"); | 326 | QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options"); |
| @@ -331,8 +354,8 @@ Menu::Menu() : · 27 unmodified lines | |||
| 331 | 354 | ||
| 332 | 355 | ||
| 333 | QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools"); | 356 | QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools"); |
| 334 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P); | 357 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings); |
| 335 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S); | 358 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings); |
| 336 | 359 | ||
| 337 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, | 360 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, |
| 338 | MenuOption::CullSharedFaces, | 361 | MenuOption::CullSharedFaces, |
| @@ -343,7 +366,7 @@ Menu::Menu() : · 4 unmodified lines | |||
| 343 | 366 | ||
| 344 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, | 367 | addCheckableActionToQMenuAndActionHash(renderDebugMenu, |
| 345 | MenuOption::ShowCulledSharedFaces, | 368 | MenuOption::ShowCulledSharedFaces, |
| 346 | Qt::CTRL | Qt::SHIFT | Qt::Key_X, | 369 | 0, |
| 347 | false, | 370 | false, |
| 348 | appInstance->getVoxels(), | 371 | appInstance->getVoxels(), |
| 349 | SLOT(showCulledSharedFaces())); | 372 | SLOT(showCulledSharedFaces())); |
| @@ -366,6 +389,63 @@ Menu::Menu() : · 16 unmodified lines | |||
| 366 | false, | 389 | false, |
| 367 | appInstance->getAudio(), | 390 | appInstance->getAudio(), |
| 368 | SLOT(toggleToneInjection())); | 391 | SLOT(toggleToneInjection())); |
| 392 | addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScopePause, | ||
| 393 | Qt::CTRL | Qt::Key_P, | ||
| 394 | false, | ||
| 395 | appInstance->getAudio(), | ||
| 396 | SLOT(toggleScopePause())); | ||
| 397 | |||
| 398 | QMenu* spatialAudioMenu = audioDebugMenu->addMenu("Spatial Audio"); | ||
| 399 | |||
| 400 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessing, | ||
| 401 | Qt::CTRL | Qt::SHIFT | Qt::Key_M, | ||
| 402 | false, | ||
| 403 | appInstance->getAudio(), | ||
| 404 | SLOT(toggleAudioSpatialProcessing())); | ||
| 405 | |||
| 406 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingIncludeOriginal, | ||
| 407 | Qt::CTRL | Qt::SHIFT | Qt::Key_O, | ||
| 408 | true); | ||
| 409 | |||
| 410 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSeparateEars, | ||
| 411 | Qt::CTRL | Qt::SHIFT | Qt::Key_E, | ||
| 412 | true); | ||
| 413 | |||
| 414 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingPreDelay, | ||
| 415 | Qt::CTRL | Qt::SHIFT | Qt::Key_D, | ||
| 416 | true); | ||
| 417 | |||
| 418 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingStereoSource, | ||
| 419 | Qt::CTRL | Qt::SHIFT | Qt::Key_S, | ||
| 420 | true); | ||
| 421 | |||
| 422 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingHeadOriented, | ||
| 423 | Qt::CTRL | Qt::SHIFT | Qt::Key_H, | ||
| 424 | true); | ||
| 425 | |||
| 426 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingWithDiffusions, | ||
| 427 | Qt::CTRL | Qt::SHIFT | Qt::Key_W, | ||
| 428 | true); | ||
| 429 | |||
| 430 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingRenderPaths, | ||
| 431 | Qt::CTRL | Qt::SHIFT | Qt::Key_R, | ||
| 432 | true); | ||
| 433 | |||
| 434 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces, | ||
| 435 | Qt::CTRL | Qt::SHIFT | Qt::Key_X, | ||
| 436 | true); | ||
| 437 | |||
| 438 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingProcessLocalAudio, | ||
| 439 | Qt::CTRL | Qt::SHIFT | Qt::Key_A, | ||
| 440 | true); | ||
| 441 | |||
| 442 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingDontDistanceAttenuate, | ||
| 443 | Qt::CTRL | Qt::SHIFT | Qt::Key_Y, | ||
| 444 | false); | ||
| 445 | |||
| 446 | addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate, | ||
| 447 | Qt::CTRL | Qt::SHIFT | Qt::Key_U, | ||
| 448 | false); | ||
| 369 | 449 | ||
| 370 | addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, | 450 | addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, |
| 371 | Qt::CTRL | Qt::SHIFT | Qt::Key_V, | 451 | Qt::CTRL | Qt::SHIFT | Qt::Key_V, |
| @@ -399,7 +479,14 @@ void Menu::loadSettings(QSettings* settings) { · 27 unmodified lines | |||
| 399 | _maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM); | 479 | _maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM); |
| 400 | _maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS); | 480 | _maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS); |
| 401 | _voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE); | 481 | _voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE); |
| 482 | _automaticAvatarLOD = settings->value("automaticAvatarLOD", true).toBool(); | ||
| 483 | _avatarLODDecreaseFPS = loadSetting(settings, "avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS); | ||
| 484 | _avatarLODIncreaseFPS = loadSetting(settings, "avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS); | ||
| 485 | _avatarLODDistanceMultiplier = loadSetting(settings, "avatarLODDistanceMultiplier", | ||
| 486 | DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER); | ||
| 402 | _boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0); | 487 | _boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0); |
| 488 | _snapshotsLocation = settings->value("snapshotsLocation", | ||
| 489 | QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).toString(); | ||
| 403 | 490 | ||
| 404 | settings->beginGroup("View Frustum Offset Camera"); | 491 | settings->beginGroup("View Frustum Offset Camera"); |
| 405 | // in case settings is corrupt or missing loadSetting() will check for NaN | 492 | // in case settings is corrupt or missing loadSetting() will check for NaN |
| @@ -438,7 +525,12 @@ void Menu::saveSettings(QSettings* settings) { · 32 unmodified lines | |||
| 438 | settings->setValue("maxVoxels", _maxVoxels); | 525 | settings->setValue("maxVoxels", _maxVoxels); |
| 439 | settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond); | 526 | settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond); |
| 440 | settings->setValue("voxelSizeScale", _voxelSizeScale); | 527 | settings->setValue("voxelSizeScale", _voxelSizeScale); |
| 528 | settings->setValue("automaticAvatarLOD", _automaticAvatarLOD); | ||
| 529 | settings->setValue("avatarLODDecreaseFPS", _avatarLODDecreaseFPS); | ||
| 530 | settings->setValue("avatarLODIncreaseFPS", _avatarLODIncreaseFPS); | ||
| 531 | settings->setValue("avatarLODDistanceMultiplier", _avatarLODDistanceMultiplier); | ||
| 441 | settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust); | 532 | settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust); |
| 533 | settings->setValue("snapshotsLocation", _snapshotsLocation); | ||
| 442 | settings->beginGroup("View Frustum Offset Camera"); | 534 | settings->beginGroup("View Frustum Offset Camera"); |
| 443 | settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw); | 535 | settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw); |
| 444 | settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch); | 536 | settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch); |
| @@ -621,6 +713,41 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, · 176 unmodified lines | |||
| 621 | return action; | 713 | return action; |
| 622 | } | 714 | } |
| 623 | 715 | ||
| 716 | QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, | ||
| 717 | QAction* action, | ||
| 718 | const QString& actionName, | ||
| 719 | const QKeySequence& shortcut, | ||
| 720 | QAction::MenuRole role, | ||
| 721 | int menuItemLocation) { | ||
| 722 | QAction* actionBefore = NULL; | ||
| 723 | |||
| 724 | if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { | ||
| 725 | actionBefore = destinationMenu->actions()[menuItemLocation]; | ||
| 726 | } | ||
| 727 | |||
| 728 | if (!actionName.isEmpty()) { | ||
| 729 | action->setText(actionName); | ||
| 730 | } | ||
| 731 | |||
| 732 | if (shortcut != 0) { | ||
| 733 | action->setShortcut(shortcut); | ||
| 734 | } | ||
| 735 | |||
| 736 | if (role != QAction::NoRole) { | ||
| 737 | action->setMenuRole(role); | ||
| 738 | } | ||
| 739 | |||
| 740 | if (!actionBefore) { | ||
| 741 | destinationMenu->addAction(action); | ||
| 742 | } else { | ||
| 743 | destinationMenu->insertAction(actionBefore, action); | ||
| 744 | } | ||
| 745 | |||
| 746 | _actionHash.insert(action->text(), action); | ||
| 747 | |||
| 748 | return action; | ||
| 749 | } | ||
| 750 | |||
| 624 | QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, | 751 | QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, |
| 625 | const QString& actionName, | 752 | const QString& actionName, |
| 626 | const QKeySequence& shortcut, | 753 | const QKeySequence& shortcut, |
| @@ -633,6 +760,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, · 6 unmodified lines | |||
| 633 | QAction::NoRole, menuItemLocation); | 760 | QAction::NoRole, menuItemLocation); |
| 634 | action->setCheckable(true); | 761 | action->setCheckable(true); |
| 635 | action->setChecked(checked); | 762 | action->setChecked(checked); |
| 763 | connect(action, SIGNAL(changed()), Application::getInstance(), SLOT(bumpSettings())); | ||
| 636 | 764 | ||
| 637 | return action; | 765 | return action; |
| 638 | } | 766 | } |
| @@ -657,7 +785,12 @@ bool Menu::isOptionChecked(const QString& menuOption) { · 18 unmodified lines | |||
| 657 | } | 785 | } |
| 658 | 786 | ||
| 659 | void Menu::triggerOption(const QString& menuOption) { | 787 | void Menu::triggerOption(const QString& menuOption) { |
| 660 | _actionHash.value(menuOption)->trigger(); | 788 | QAction* action = _actionHash.value(menuOption); |
| 789 | if (action) { | ||
| 790 | action->trigger(); | ||
| 791 | } else { | ||
| 792 | qDebug() << "NULL Action for menuOption '" << menuOption << "'"; | ||
| 793 | } | ||
| 661 | } | 794 | } |
| 662 | 795 | ||
| 663 | QAction* Menu::getActionForOption(const QString& menuOption) { | 796 | QAction* Menu::getActionForOption(const QString& menuOption) { |
| @@ -716,176 +849,31 @@ void Menu::loginForCurrentDomain() { · 52 unmodified lines | |||
| 716 | } | 849 | } |
| 717 | 850 | ||
| 718 | void Menu::editPreferences() { | 851 | void Menu::editPreferences() { |
| 719 | Application* applicationInstance = Application::getInstance(); | 852 | if (!_preferencesDialog) { |
| 720 | ModelBrowser headBrowser(Head); | 853 | _preferencesDialog = new PreferencesDialog(Application::getInstance()->getWindow()); |
| 721 | ModelBrowser skeletonBrowser(Skeleton); | 854 | _preferencesDialog->show(); |
| 722 | 855 | } else { | |
| 723 | const QString BROWSE_BUTTON_TEXT = "Browse"; | 856 | _preferencesDialog->close(); |
| 724 | |||
| 725 | QDialog dialog(applicationInstance->getWindow()); | ||
| 726 | dialog.setWindowTitle("Interface Preferences"); | ||
| 727 | |||
| 728 | QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); | ||
| 729 | dialog.setLayout(layout); | ||
| 730 | |||
| 731 | QFormLayout* form = new QFormLayout(); | ||
| 732 | layout->addLayout(form, 1); | ||
| 733 | |||
| 734 | |||
| 735 | QHBoxLayout headModelLayout; | ||
| 736 | QString faceURLString = applicationInstance->getAvatar()->getHead()->getFaceModel().getURL().toString(); | ||
| 737 | QLineEdit headURLEdit(faceURLString); | ||
| 738 | QPushButton headBrowseButton(BROWSE_BUTTON_TEXT); | ||
| 739 | connect(&headBrowseButton, SIGNAL(clicked()), &headBrowser, SLOT(browse())); | ||
| 740 | connect(&headBrowser, SIGNAL(selected(QString)), &headURLEdit, SLOT(setText(QString))); | ||
| 741 | headURLEdit.setMinimumWidth(QLINE_MINIMUM_WIDTH); | ||
| 742 | headURLEdit.setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString()); | ||
| 743 | headModelLayout.addWidget(&headURLEdit); | ||
| 744 | headModelLayout.addWidget(&headBrowseButton); | ||
| 745 | form->addRow("Head URL:", &headModelLayout); | ||
| 746 | |||
| 747 | QHBoxLayout skeletonModelLayout; | ||
| 748 | QString skeletonURLString = applicationInstance->getAvatar()->getSkeletonModel().getURL().toString(); | ||
| 749 | QLineEdit skeletonURLEdit(skeletonURLString); | ||
| 750 | QPushButton SkeletonBrowseButton(BROWSE_BUTTON_TEXT); | ||
| 751 | connect(&SkeletonBrowseButton, SIGNAL(clicked()), &skeletonBrowser, SLOT(browse())); | ||
| 752 | connect(&skeletonBrowser, SIGNAL(selected(QString)), &skeletonURLEdit, SLOT(setText(QString))); | ||
| 753 | skeletonURLEdit.setMinimumWidth(QLINE_MINIMUM_WIDTH); | ||
| 754 | skeletonURLEdit.setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); | ||
| 755 | skeletonModelLayout.addWidget(&skeletonURLEdit); | ||
| 756 | skeletonModelLayout.addWidget(&SkeletonBrowseButton); | ||
| 757 | form->addRow("Skeleton URL:", &skeletonModelLayout); | ||
| 758 | |||
| 759 | |||
| 760 | QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); | ||
| 761 | QLineEdit* displayNameEdit = new QLineEdit(displayNameString); | ||
| 762 | displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); | ||
| 763 | form->addRow("Display name:", displayNameEdit); | ||
| 764 | |||
| 765 | QSlider* pupilDilation = new QSlider(Qt::Horizontal); | ||
| 766 | pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum()); | ||
| 767 | form->addRow("Pupil Dilation:", pupilDilation); | ||
| 768 | |||
| 769 | QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); | ||
| 770 | faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); | ||
| 771 | form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); | ||
| 772 | |||
| 773 | QSpinBox* fieldOfView = new QSpinBox(); | ||
| 774 | fieldOfView->setMaximum(180.f); | ||
| 775 | fieldOfView->setMinimum(1.f); | ||
| 776 | fieldOfView->setValue(_fieldOfView); | ||
| 777 | form->addRow("Vertical Field of View (Degrees):", fieldOfView); | ||
| 778 | |||
| 779 | QDoubleSpinBox* leanScale = new QDoubleSpinBox(); | ||
| 780 | leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); | ||
| 781 | form->addRow("Lean Scale:", leanScale); | ||
| 782 | |||
| 783 | QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); | ||
| 784 | avatarScale->setValue(applicationInstance->getAvatar()->getScale()); | ||
| 785 | form->addRow("Avatar Scale:", avatarScale); | ||
| 786 | |||
| 787 | QSpinBox* audioJitterBufferSamples = new QSpinBox(); | ||
| 788 | audioJitterBufferSamples->setMaximum(10000); | ||
| 789 | audioJitterBufferSamples->setMinimum(-10000); | ||
| 790 | audioJitterBufferSamples->setValue(_audioJitterBufferSamples); | ||
| 791 | form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); | ||
| 792 | |||
| 793 | QSpinBox* maxVoxels = new QSpinBox(); | ||
| 794 | const int MAX_MAX_VOXELS = 5000000; | ||
| 795 | const int MIN_MAX_VOXELS = 0; | ||
| 796 | const int STEP_MAX_VOXELS = 50000; | ||
| 797 | maxVoxels->setMaximum(MAX_MAX_VOXELS); | ||
| 798 | maxVoxels->setMinimum(MIN_MAX_VOXELS); | ||
| 799 | maxVoxels->setSingleStep(STEP_MAX_VOXELS); | ||
| 800 | maxVoxels->setValue(_maxVoxels); | ||
| 801 | form->addRow("Maximum Voxels:", maxVoxels); | ||
| 802 | |||
| 803 | QSpinBox* maxVoxelsPPS = new QSpinBox(); | ||
| 804 | const int MAX_MAX_VOXELS_PPS = 6000; | ||
| 805 | const int MIN_MAX_VOXELS_PPS = 60; | ||
| 806 | const int STEP_MAX_VOXELS_PPS = 10; | ||
| 807 | maxVoxelsPPS->setMaximum(MAX_MAX_VOXELS_PPS); | ||
| 808 | maxVoxelsPPS->setMinimum(MIN_MAX_VOXELS_PPS); | ||
| 809 | maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); | ||
| 810 | maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); | ||
| 811 | form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); | ||
| 812 | |||
| 813 | QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); | ||
| 814 | dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); | ||
| 815 | dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); | ||
| 816 | layout->addWidget(buttons); | ||
| 817 | |||
| 818 | int ret = dialog.exec(); | ||
| 819 | if (ret == QDialog::Accepted) { | ||
| 820 | bool shouldDispatchIdentityPacket = false; | ||
| 821 | |||
| 822 | if (headURLEdit.text() != faceURLString && !headURLEdit.text().isEmpty()) { | ||
| 823 | // change the faceModelURL in the profile, it will also update this user's BlendFace | ||
| 824 | applicationInstance->getAvatar()->setFaceModelURL(QUrl(headURLEdit.text())); | ||
| 825 | shouldDispatchIdentityPacket = true; | ||
| 826 | } | ||
| 827 | |||
| 828 | if (skeletonURLEdit.text() != skeletonURLString && !skeletonURLEdit.text().isEmpty()) { | ||
| 829 | // change the skeletonModelURL in the profile, it will also update this user's Body | ||
| 830 | applicationInstance->getAvatar()->setSkeletonModelURL(QUrl(skeletonURLEdit.text())); | ||
| 831 | shouldDispatchIdentityPacket = true; | ||
| 832 | } | ||
| 833 | |||
| 834 | QString displayNameStr(displayNameEdit->text()); | ||
| 835 | |||
| 836 | if (displayNameStr != displayNameString) { | ||
| 837 | applicationInstance->getAvatar()->setDisplayName(displayNameStr); | ||
| 838 | shouldDispatchIdentityPacket = true; | ||
| 839 | } | ||
| 840 | |||
| 841 | if (shouldDispatchIdentityPacket) { | ||
| 842 | applicationInstance->getAvatar()->sendIdentityPacket(); | ||
| 843 | } | ||
| 844 | |||
| 845 | applicationInstance->getAvatar()->getHead()->setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); | ||
| 846 | |||
| 847 | _maxVoxels = maxVoxels->value(); | ||
| 848 | applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); | ||
| 849 | |||
| 850 | _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); | ||
| 851 | |||
| 852 | applicationInstance->getAvatar()->setLeanScale(leanScale->value()); | ||
| 853 | applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); | ||
| 854 | |||
| 855 | _audioJitterBufferSamples = audioJitterBufferSamples->value(); | ||
| 856 | |||
| 857 | if (_audioJitterBufferSamples != 0) { | ||
| 858 | applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); | ||
| 859 | } | ||
| 860 | |||
| 861 | _fieldOfView = fieldOfView->value(); | ||
| 862 | applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); | ||
| 863 | |||
| 864 | _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); | ||
| 865 | } | 857 | } |
| 866 | QMetaObject::invokeMethod(applicationInstance->getAudio(), "reset", Qt::QueuedConnection); | ||
| 867 | |||
| 868 | sendFakeEnterEvent(); | ||
| 869 | } | 858 | } |
| 870 | 859 | ||
| 871 | void Menu::goToDomain(const QString newDomain) { | 860 | void Menu::goToDomain(const QString newDomain) { |
| 872 | if (NodeList::getInstance()->getDomainInfo().getHostname() != newDomain) { | 861 | if (NodeList::getInstance()->getDomainHandler().getHostname() != newDomain) { |
| 873 | |||
| 874 | // send a node kill request, indicating to other clients that they should play the "disappeared" effect | 862 | // send a node kill request, indicating to other clients that they should play the "disappeared" effect |
| 875 | Application::getInstance()->getAvatar()->sendKillAvatar(); | 863 | Application::getInstance()->getAvatar()->sendKillAvatar(); |
| 876 | 864 | ||
| 877 | // give our nodeList the new domain-server hostname | 865 | // give our nodeList the new domain-server hostname |
| 878 | NodeList::getInstance()->getDomainInfo().setHostname(newDomain); | 866 | NodeList::getInstance()->getDomainHandler().setHostname(newDomain); |
| 879 | } | 867 | } |
| 880 | } | 868 | } |
| 881 | 869 | ||
| 882 | void Menu::goToDomainDialog() { | 870 | void Menu::goToDomainDialog() { |
| 883 | 871 | ||
| 884 | QString currentDomainHostname = NodeList::getInstance()->getDomainInfo().getHostname(); | 872 | QString currentDomainHostname = NodeList::getInstance()->getDomainHandler().getHostname(); |
| 885 | 873 | ||
| 886 | if (NodeList::getInstance()->getDomainInfo().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { | 874 | if (NodeList::getInstance()->getDomainHandler().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { |
| 887 | // add the port to the currentDomainHostname string if it is custom | 875 | // add the port to the currentDomainHostname string if it is custom |
| 888 | currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainInfo().getPort())); | 876 | currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainHandler().getPort())); |
| 889 | } | 877 | } |
| 890 | 878 | ||
| 891 | QInputDialog domainDialog(Application::getInstance()->getWindow()); | 879 | QInputDialog domainDialog(Application::getInstance()->getWindow()); |
| @@ -918,19 +906,58 @@ bool Menu::goToDestination(QString destination) { · 26 unmodified lines | |||
| 918 | return LocationManager::getInstance().goToDestination(destination); | 906 | return LocationManager::getInstance().goToDestination(destination); |
| 919 | } | 907 | } |
| 920 | 908 | ||
| 909 | void Menu::goTo(QString destination) { | ||
| 910 | LocationManager::getInstance().goTo(destination); | ||
| 911 | } | ||
| 912 | |||
| 921 | void Menu::goTo() { | 913 | void Menu::goTo() { |
| 922 | 914 | ||
| 923 | QInputDialog gotoDialog(Application::getInstance()->getWindow()); | 915 | QInputDialog gotoDialog(Application::getInstance()->getWindow()); |
| 924 | gotoDialog.setWindowTitle("Go to"); | 916 | gotoDialog.setWindowTitle("Go to"); |
| 925 | gotoDialog.setLabelText("Destination:"); | 917 | gotoDialog.setLabelText("Destination or URL:\n @user, #place, hifi://domain/location/orientation"); |
| 926 | QString destination = QString(); | 918 | QString destination = QString(); |
| 919 | |||
| 927 | gotoDialog.setTextValue(destination); | 920 | gotoDialog.setTextValue(destination); |
| 928 | gotoDialog.setWindowFlags(Qt::Sheet); | 921 | gotoDialog.setWindowFlags(Qt::Sheet); |
| 929 | gotoDialog.resize(gotoDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, gotoDialog.size().height()); | 922 | gotoDialog.resize(gotoDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, gotoDialog.size().height()); |
| 930 | 923 | ||
| 931 | int dialogReturn = gotoDialog.exec(); | 924 | int dialogReturn = gotoDialog.exec(); |
| 932 | if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { | 925 | if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { |
| 933 | goToUser(gotoDialog.textValue()); | 926 | QString desiredDestination = gotoDialog.textValue(); |
| 927 | |||
| 928 | if (desiredDestination.startsWith(CUSTOM_URL_SCHEME + "//")) { | ||
| 929 | QStringList urlParts = desiredDestination.remove(0, CUSTOM_URL_SCHEME.length() + 2).split('/', QString::SkipEmptyParts); | ||
| 930 | |||
| 931 | if (urlParts.count() > 1) { | ||
| 932 | // if url has 2 or more parts, the first one is domain name | ||
| 933 | QString domain = urlParts[0]; | ||
| 934 | |||
| 935 | // second part is either a destination coordinate or | ||
| 936 | // a place name | ||
| 937 | QString destination = urlParts[1]; | ||
| 938 | |||
| 939 | // any third part is an avatar orientation. | ||
| 940 | QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); | ||
| 941 | |||
| 942 | goToDomain(domain); | ||
| 943 | |||
| 944 | // goto either @user, #place, or x-xx,y-yy,z-zz | ||
| 945 | // style co-ordinate. | ||
| 946 | goTo(destination); | ||
| 947 | |||
| 948 | if (!orientation.isEmpty()) { | ||
| 949 | // location orientation | ||
| 950 | goToOrientation(orientation); | ||
| 951 | } | ||
| 952 | } else if (urlParts.count() == 1) { | ||
| 953 | // location coordinates or place name | ||
| 954 | QString destination = urlParts[0]; | ||
| 955 | goTo(destination); | ||
| 956 | } | ||
| 957 | |||
| 958 | } else { | ||
| 959 | goToUser(gotoDialog.textValue()); | ||
| 960 | } | ||
| 934 | } | 961 | } |
| 935 | sendFakeEnterEvent(); | 962 | sendFakeEnterEvent(); |
| 936 | } | 963 | } |
| @@ -966,7 +993,6 @@ void Menu::goToLocation() { · 29 unmodified lines | |||
| 966 | QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x), | 993 | QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x), |
| 967 | QString::number(avatarPos.y), QString::number(avatarPos.z)); | 994 | QString::number(avatarPos.y), QString::number(avatarPos.z)); |
| 968 | 995 | ||
| 969 | |||
| 970 | QInputDialog coordinateDialog(Application::getInstance()->getWindow()); | 996 | QInputDialog coordinateDialog(Application::getInstance()->getWindow()); |
| 971 | coordinateDialog.setWindowTitle("Go to Location"); | 997 | coordinateDialog.setWindowTitle("Go to Location"); |
| 972 | coordinateDialog.setLabelText("Coordinate as x,y,z:"); | 998 | coordinateDialog.setLabelText("Coordinate as x,y,z:"); |
| @@ -1040,7 +1066,7 @@ void Menu::nameLocation() { · 67 unmodified lines | |||
| 1040 | connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); | 1066 | connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); |
| 1041 | NamedLocation* location = new NamedLocation(locationName, | 1067 | NamedLocation* location = new NamedLocation(locationName, |
| 1042 | myAvatar->getPosition(), myAvatar->getOrientation(), | 1068 | myAvatar->getPosition(), myAvatar->getOrientation(), |
| 1043 | NodeList::getInstance()->getDomainInfo().getHostname()); | 1069 | NodeList::getInstance()->getDomainHandler().getHostname()); |
| 1044 | manager->createNamedLocation(location); | 1070 | manager->createNamedLocation(location); |
| 1045 | } | 1071 | } |
| 1046 | } | 1072 | } |
| @@ -1107,29 +1133,25 @@ void Menu::showMetavoxelEditor() { · 60 unmodified lines | |||
| 1107 | _MetavoxelEditor->raise(); | 1133 | _MetavoxelEditor->raise(); |
| 1108 | } | 1134 | } |
| 1109 | 1135 | ||
| 1110 | void Menu::showChat() { | 1136 | void Menu::showScriptEditor() { |
| 1111 | if (!_chatAction->isEnabled()) { | 1137 | if(!_ScriptEditor || !_ScriptEditor->isVisible()) { |
| 1112 | // Don't do anything if chat is disabled (No | 1138 | _ScriptEditor = new ScriptEditorWindow(); |
| 1113 | // QXMPP library or xmpp is disconnected). | ||
| 1114 | return; | ||
| 1115 | } | 1139 | } |
| 1140 | _ScriptEditor->raise(); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | void Menu::showChat() { | ||
| 1116 | QMainWindow* mainWindow = Application::getInstance()->getWindow(); | 1144 | QMainWindow* mainWindow = Application::getInstance()->getWindow(); |
| 1117 | if (!_chatWindow) { | 1145 | if (!_chatWindow) { |
| 1118 | mainWindow->addDockWidget(Qt::NoDockWidgetArea, _chatWindow = new ChatWindow()); | 1146 | mainWindow->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow()); |
| 1119 | } | 1147 | } |
| 1120 | if (!_chatWindow->toggleViewAction()->isChecked()) { | 1148 | if (!_chatWindow->toggleViewAction()->isChecked()) { |
| 1121 | int width = _chatWindow->width(); | 1149 | const QRect& windowGeometry = mainWindow->geometry(); |
| 1122 | int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0); | 1150 | _chatWindow->move(windowGeometry.topRight().x() - _chatWindow->width(), |
| 1123 | _chatWindow->move(mainWindow->width(), y); | 1151 | windowGeometry.topRight().y() + (windowGeometry.height() / 2) - (_chatWindow->height() / 2)); |
| 1152 | |||
| 1124 | _chatWindow->resize(0, _chatWindow->height()); | 1153 | _chatWindow->resize(0, _chatWindow->height()); |
| 1125 | _chatWindow->toggleViewAction()->trigger(); | 1154 | _chatWindow->toggleViewAction()->trigger(); |
| 1126 | |||
| 1127 | QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow); | ||
| 1128 | slideAnimation->setStartValue(_chatWindow->geometry()); | ||
| 1129 | slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(), | ||
| 1130 | width, _chatWindow->height())); | ||
| 1131 | slideAnimation->setDuration(250); | ||
| 1132 | slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); | ||
| 1133 | } | 1155 | } |
| 1134 | } | 1156 | } |
| 1135 | 1157 | ||
| @@ -1220,22 +1242,24 @@ void Menu::autoAdjustLOD(float currentFPS) { · 84 unmodified lines | |||
| 1220 | quint64 now = usecTimestampNow(); | 1242 | quint64 now = usecTimestampNow(); |
| 1221 | 1243 | ||
| 1222 | const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000; | 1244 | const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000; |
| 1223 | if (_fastFPSAverage.getAverage() < ADJUST_LOD_DOWN_FPS) { | 1245 | if (_automaticAvatarLOD) { |
| 1224 | if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) { | 1246 | if (_fastFPSAverage.getAverage() < _avatarLODDecreaseFPS) { |
| 1225 | // attempt to lower the detail in proportion to the fps difference | 1247 | if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) { |
| 1226 | float targetFps = (ADJUST_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f; | 1248 | // attempt to lower the detail in proportion to the fps difference |
| 1227 | float averageFps = _fastFPSAverage.getAverage(); | 1249 | float targetFps = (_avatarLODDecreaseFPS + _avatarLODIncreaseFPS) * 0.5f; |
| 1228 | const float MAXIMUM_MULTIPLIER_SCALE = 2.0f; | 1250 | float averageFps = _fastFPSAverage.getAverage(); |
| 1229 | _avatarLODDistanceMultiplier *= (averageFps < EPSILON) ? MAXIMUM_MULTIPLIER_SCALE : | 1251 | const float MAXIMUM_MULTIPLIER_SCALE = 2.0f; |
| 1230 | qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps); | 1252 | _avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier * |
| 1231 | _lastAvatarDetailDrop = now; | 1253 | (averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE : |
| 1254 | qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps))); | ||
| 1255 | _lastAvatarDetailDrop = now; | ||
| 1256 | } | ||
| 1257 | } else if (_fastFPSAverage.getAverage() > _avatarLODIncreaseFPS) { | ||
| 1258 | // let the detail level creep slowly upwards | ||
| 1259 | const float DISTANCE_DECREASE_RATE = 0.05f; | ||
| 1260 | _avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, | ||
| 1261 | _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); | ||
| 1232 | } | 1262 | } |
| 1233 | } else if (_fastFPSAverage.getAverage() > ADJUST_LOD_UP_FPS) { | ||
| 1234 | // let the detail level creep slowly upwards | ||
| 1235 | const float DISTANCE_DECREASE_RATE = 0.02f; | ||
| 1236 | const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f; | ||
| 1237 | _avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER, | ||
| 1238 | _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); | ||
| 1239 | } | 1263 | } |
| 1240 | 1264 | ||
| 1241 | bool changed = false; | 1265 | bool changed = false; |
| @@ -1561,3 +1585,10 @@ void Menu::removeMenuItem(const QString& menu, const QString& menuitem) { · 319 unmodified lines | |||
| 1561 | QMenuBar::repaint(); | 1585 | QMenuBar::repaint(); |
| 1562 | }; | 1586 | }; |
| 1563 | 1587 | ||
| 1588 | QString Menu::getSnapshotsLocation() const { | ||
| 1589 | if (_snapshotsLocation.isNull() || _snapshotsLocation.isEmpty() || QDir(_snapshotsLocation).exists() == false) { | ||
| 1590 | return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); | ||
| 1591 | } | ||
| 1592 | return _snapshotsLocation; | ||
| 1593 | } | ||
| 1594 | |||