History

Merge branch master

Mohammed Nafees committed 12 years ago

Commit 29d64372 parents dd74ea6 d441e6a645 files · +22419 −7869Browse files

Showing the changes to interface/src/Menu.cpp (1 of 645 files). Show all

Unified · Split

interface/src/Menu.cpp+240−209
@@ -1,9 +1,12 @@
1//1//
2// Menu.cpp2// Menu.cpp
3// hifi3// 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
43Menu* Menu::_instance = NULL;44Menu* 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_QXMPP206
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#endif211#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_VISAGE318#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#endif321#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 NaN492 // 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
716QAction* 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
624QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,751QAction* 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
659void Menu::triggerOption(const QString& menuOption) {787void 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
663QAction* Menu::getActionForOption(const QString& menuOption) {796QAction* Menu::getActionForOption(const QString& menuOption) {
@@ -716,176 +849,31 @@ void Menu::loginForCurrentDomain() { · 52 unmodified lines
716}849}
717 850
718void Menu::editPreferences() {851void 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
871void Menu::goToDomain(const QString newDomain) {860void 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" effect862 // 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 hostname865 // 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
882void Menu::goToDomainDialog() {870void 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 custom875 // 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
909void Menu::goTo(QString destination) {
910 LocationManager::getInstance().goTo(destination);
911}
912
921void Menu::goTo() {913void 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
1110void Menu::showChat() {1136void Menu::showScriptEditor() {
1111 if (!_chatAction->isEnabled()) {1137 if(!_ScriptEditor || !_ScriptEditor->isVisible()) {
1112 // Don't do anything if chat is disabled (No1138 _ScriptEditor = new ScriptEditorWindow();
1113 // QXMPP library or xmpp is disconnected).
1114 return;
1115 }1139 }
1140 _ScriptEditor->raise();
1141}
1142
1143void 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 difference1247 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
1588QString 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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t