798 lines · 34.3 KB · C++
RawDownload
////  Menu.cpp//  hifi////  Created by Stephen Birarda on 8/12/13.//  Copyright (c) 2013 HighFidelity, Inc. All rights reserved.// #include <cstdlib> #include <QMenuBar>#include <QBoxLayout>#include <QColorDialog>#include <QDialogButtonBox>#include <QDoubleSpinBox>#include <QFileDialog>#include <QFormLayout>#include <QLineEdit>#include <QMainWindow>#include <QStandardPaths> #include "Application.h"#include "fvupdater.h"#include "PairingHandler.h"#include "Menu.h"#include "Util.h" Menu* Menu::_instance = NULL; Menu* Menu::getInstance() {    if (!_instance) {        qDebug("First call to Menu::getInstance() - initing menu.\n");                _instance = new Menu();    }            return _instance;} const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f}; Menu::Menu() :    _actionHash(),    _audioJitterBufferSamples(0),    _bandwidthDialog(NULL),    _fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES),    _frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),    _viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),    _voxelModeActionsGroup(NULL),    _voxelStatsDialog(NULL){    Application *appInstance = Application::getInstance();        QMenu* fileMenu = addMenu("File");    (addActionToQMenuAndActionHash(fileMenu,                                   MenuOption::Quit,                                   Qt::CTRL | Qt::Key_Q,                                   appInstance,                                   SLOT(quit())))->setMenuRole(QAction::QuitRole);        (addActionToQMenuAndActionHash(fileMenu,                                   MenuOption::Preferences,                                   Qt::CTRL | Qt::Key_Comma,                                   this,                                   SLOT(editPreferences())))->setMenuRole(QAction::PreferencesRole);    #if defined(Q_OS_MAC) && defined(QT_NO_DEBUG)    // show "Check for Updates" in the menu    (addActionToQMenuAndActionHash(fileMenu, MenuOption::CheckForUpdates, 0, this, SLOT(checkForUpdates())))->setMenuRole(QAction::ApplicationSpecificRole);#endif        QMenu* pairMenu = addMenu("Pair");    addActionToQMenuAndActionHash(pairMenu, MenuOption::Pair, 0, PairingHandler::getInstance(), SLOT(sendPairRequest()));            QMenu* optionsMenu = addMenu("Options");        addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::Mirror, Qt::Key_H);    addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::GyroLook, 0, true);    addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::HeadMouse);    addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::TransmitterDrive, 0, true);    addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true);    addCheckableActionToQMenuAndActionHash(optionsMenu, MenuOption::TestPing, 0, true);        addCheckableActionToQMenuAndActionHash(optionsMenu,                                           MenuOption::Fullscreen,                                           Qt::Key_F,                                           false,                                           appInstance,                                           SLOT(setFullscreen(bool)));        addCheckableActionToQMenuAndActionHash(optionsMenu,                                           MenuOption::Webcam,                                           0,                                           false,                                           appInstance->getWebcam(),                                           SLOT(setEnabled(bool)));        addCheckableActionToQMenuAndActionHash(optionsMenu,                                           MenuOption::SkeletonTracking,                                           0,                                           false,                                           appInstance->getWebcam(),                                           SLOT(setSkeletonTrackingOn(bool)));        addCheckableActionToQMenuAndActionHash(optionsMenu,                                           MenuOption::Collisions,                                           0,                                           true,                                           appInstance->getAvatar(),                                           SLOT(setWantCollisionsOn(bool)));        addActionToQMenuAndActionHash(optionsMenu,                                  MenuOption::WebcamMode,                                  0,                                  appInstance->getWebcam()->getGrabber(),                                  SLOT(cycleVideoSendMode()));    addCheckableActionToQMenuAndActionHash(optionsMenu,                                           MenuOption::WebcamTexture,                                           0,                                           false,                                           appInstance->getWebcam()->getGrabber(),                                           SLOT(setDepthOnly(bool)));        addActionToQMenuAndActionHash(optionsMenu,                                  MenuOption::GoHome,                                  Qt::CTRL | Qt::Key_G,                                  appInstance->getAvatar(),                                  SLOT(goHome()));        QMenu* audioMenu = addMenu("Audio");    addCheckableActionToQMenuAndActionHash(audioMenu, MenuOption::EchoAudio);        QMenu* renderMenu = addMenu("Render");    addCheckableActionToQMenuAndActionHash(renderMenu,                                           MenuOption::Voxels,                                           Qt::SHIFT | Qt::Key_V,                                           true,                                           appInstance,                                           SLOT(setRenderVoxels(bool)));    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::VoxelTextures);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::Stars, 0, true);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::GroundPlane, 0, true);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::Avatars, 0, true);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::AvatarAsBalls);        addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::VoxelMode,                                  0,                                  appInstance->getAvatar()->getVoxels(),                                  SLOT(cycleMode()));        addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::FaceMode,                                  0,                                  &appInstance->getAvatar()->getHead().getFace(),                                  SLOT(cycleRenderMode()));        addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::GlowMode,                                  0,                                  appInstance->getGlowEffect(),                                  SLOT(cycleRenderMode()));        addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::AmbientOcclusion);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::FrameTimer);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::LookAtVectors);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::LookAtIndicator, 0, true);    addCheckableActionToQMenuAndActionHash(renderMenu, MenuOption::FirstPerson, Qt::Key_P, true);        addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::IncreaseAvatarSize,                                  Qt::Key_Plus,                                  appInstance->getAvatar(),                                  SLOT(increaseSize()));    addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::DecreaseAvatarSize,                                  Qt::Key_Minus,                                  appInstance->getAvatar(),                                  SLOT(decreaseSize()));    addActionToQMenuAndActionHash(renderMenu,                                  MenuOption::ResetAvatarSize,                                  0,                                  appInstance->getAvatar(),                                  SLOT(resetSize()));        QMenu* toolsMenu = addMenu("Tools");    addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::Stats, Qt::Key_Slash);    addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L);    addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::Oscilloscope, 0, true);    addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::Bandwidth, 0, true);    addActionToQMenuAndActionHash(toolsMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails()));    addActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails()));            QMenu* voxelMenu = addMenu("Voxels");    _voxelModeActionsGroup = new QActionGroup(this);    _voxelModeActionsGroup->setExclusive(false);        QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelAddMode, Qt::Key_V);    _voxelModeActionsGroup->addAction(addVoxelMode);        QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelDeleteMode, Qt::Key_R);    _voxelModeActionsGroup->addAction(deleteVoxelMode);        QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelColorMode, Qt::Key_B);    _voxelModeActionsGroup->addAction(colorVoxelMode);        QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelSelectMode, Qt::Key_O);    _voxelModeActionsGroup->addAction(selectVoxelMode);        QAction* getColorMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelGetColorMode, Qt::Key_G);    _voxelModeActionsGroup->addAction(getColorMode);        // connect each of the voxel mode actions to the updateVoxelModeActionsSlot    foreach (QAction* action, _voxelModeActionsGroup->actions()) {        connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions()));    }     QAction* voxelPaintColor = addActionToQMenuAndActionHash(voxelMenu,                                                             MenuOption::VoxelPaintColor,                                                             Qt::META | Qt::Key_C,                                                             this,                                                             SLOT(chooseVoxelPaintColor()));        Application::getInstance()->getSwatch()->setAction(voxelPaintColor);        QColor paintColor(128, 128, 128);    voxelPaintColor->setData(paintColor);    voxelPaintColor->setIcon(Swatch::createIcon(paintColor));        addActionToQMenuAndActionHash(voxelMenu,                                  MenuOption::DecreaseVoxelSize,                                  QKeySequence::ZoomOut,                                  appInstance,                                  SLOT(decreaseVoxelSize()));    addActionToQMenuAndActionHash(voxelMenu,                                  MenuOption::IncreaseVoxelSize,                                  QKeySequence::ZoomIn,                                  appInstance,                                  SLOT(increaseVoxelSize()));    addActionToQMenuAndActionHash(voxelMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors()));        addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::DestructiveAddVoxel);        addActionToQMenuAndActionHash(voxelMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));    addActionToQMenuAndActionHash(voxelMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels()));    addActionToQMenuAndActionHash(voxelMenu,                                  MenuOption::ImportVoxelsClipboard,                                  Qt::SHIFT | Qt::CTRL | Qt::Key_I,                                  appInstance,                                  SLOT(importVoxelsToClipboard()));    addActionToQMenuAndActionHash(voxelMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels()));    addActionToQMenuAndActionHash(voxelMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels()));    addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels()));        QMenu* debugMenu = addMenu("Debug");     QMenu* frustumMenu = debugMenu->addMenu("View Frustum Debugging Tools");    addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);        addActionToQMenuAndActionHash(frustumMenu,                                  MenuOption::FrustumRenderMode,                                  Qt::SHIFT | Qt::Key_R,                                  this,                                  SLOT(cycleFrustumRenderMode()));    updateFrustumRenderModeAction();        addActionToQMenuAndActionHash(debugMenu, MenuOption::RunTimingTests, 0, this, SLOT(runTests()));    addActionToQMenuAndActionHash(debugMenu,                                  MenuOption::TreeStats,                                  Qt::SHIFT | Qt::Key_S,                                  appInstance->getVoxels(),                                  SLOT(collectStatsForTreesAndVBOs()));        QMenu* renderDebugMenu = debugMenu->addMenu("Render Debugging Tools");    addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings);        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::KillLocalVoxels,                                  Qt::CTRL | Qt::Key_K,                                  appInstance, SLOT(doKillLocalVoxels()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::RandomizeVoxelColors,                                  Qt::CTRL | Qt::Key_R,                                  appInstance->getVoxels(),                                  SLOT(randomizeVoxelColors()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorRandomly,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeRandom()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorEveryOtherVoxel,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeRandomEveryOther()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorByDistance,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeDistanceFromView()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorOutOfView,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeInView()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorOccluded,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeOccluded()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorOccludedV2,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeOccludedV2()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::FalseColorBySource,                                  0,                                  appInstance->getVoxels(),                                  SLOT(falseColorizeBySource()));        addActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::ShowTrueColors,                                  Qt::CTRL | Qt::Key_T,                                  appInstance->getVoxels(),                                  SLOT(trueColorize()));        addCheckableActionToQMenuAndActionHash(debugMenu,                                           MenuOption::SendVoxelColors,                                           0,                                           true,                                           appInstance->getAvatar(),                                           SLOT(setWantColor(bool)));        addCheckableActionToQMenuAndActionHash(debugMenu,                                           MenuOption::LowRes,                                           0,                                           true,                                           appInstance->getAvatar(),                                           SLOT(setWantLowResMoving(bool)));        addCheckableActionToQMenuAndActionHash(debugMenu,                                           MenuOption::DeltaSending,                                           0,                                           true,                                           appInstance->getAvatar(),                                           SLOT(setWantDelta(bool)));        addCheckableActionToQMenuAndActionHash(debugMenu,                                           MenuOption::OcclusionCulling,                                           Qt::SHIFT | Qt::Key_C,                                           true,                                           appInstance->getAvatar(),                                           SLOT(setWantOcclusionCulling(bool)));        addCheckableActionToQMenuAndActionHash(debugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O);    addCheckableActionToQMenuAndActionHash(debugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);    addCheckableActionToQMenuAndActionHash(debugMenu, MenuOption::SimulateLeapHand);    addCheckableActionToQMenuAndActionHash(debugMenu, MenuOption::TestRaveGlove);        QMenu* audioDebugMenu = debugMenu->addMenu("Audio Debugging Tools");    addActionToQMenuAndActionHash(audioDebugMenu,                                  MenuOption::ListenModeNormal,                                  Qt::CTRL | Qt::Key_1,                                  appInstance,                                  SLOT(setListenModeNormal()));    addActionToQMenuAndActionHash(audioDebugMenu,                                  MenuOption::ListenModePoint,                                  Qt::CTRL | Qt::Key_2,                                  appInstance,                                  SLOT(setListenModePoint()));    addActionToQMenuAndActionHash(audioDebugMenu,                                  MenuOption::ListenModeSingleSource,                                  Qt::CTRL | Qt::Key_3,                                  appInstance,                                  SLOT(setListenModeSingleSource()));        QMenu* settingsMenu = addMenu("Settings");    addCheckableActionToQMenuAndActionHash(settingsMenu, MenuOption::SettingsAutosave, 0, true);    addActionToQMenuAndActionHash(settingsMenu, MenuOption::SettingsLoad, 0, this, SLOT(loadSettings()));    addActionToQMenuAndActionHash(settingsMenu, MenuOption::SettingsSave, 0, this, SLOT(saveSettings()));    addActionToQMenuAndActionHash(settingsMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));    addActionToQMenuAndActionHash(settingsMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));} void Menu::loadSettings(QSettings* settings) {    if (!settings) {        settings = Application::getInstance()->getSettings();    }        _gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);    _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);    _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);        settings->beginGroup("View Frustum Offset Camera");    // in case settings is corrupt or missing loadSetting() will check for NaN    _viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f);    _viewFrustumOffset.pitch = loadSetting(settings, "viewFrustumOffsetPitch", 0.0f);    _viewFrustumOffset.roll = loadSetting(settings, "viewFrustumOffsetRoll", 0.0f);    _viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f);    _viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f);    settings->endGroup();        scanMenuBar(&loadAction, settings);    Application::getInstance()->getAvatar()->loadData(settings);    Application::getInstance()->getSwatch()->loadData(settings);} void Menu::saveSettings(QSettings* settings) {    if (!settings) {        settings = Application::getInstance()->getSettings();    }        settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);    settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);    settings->setValue("fieldOfView", _fieldOfView);    settings->beginGroup("View Frustum Offset Camera");    settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);    settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);    settings->setValue("viewFrustumOffsetRoll", _viewFrustumOffset.roll);    settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance);    settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up);    settings->endGroup();        scanMenuBar(&saveAction, settings);    Application::getInstance()->getAvatar()->saveData(settings);    Application::getInstance()->getSwatch()->saveData(settings);        // ask the NodeList to save its data    NodeList::getInstance()->saveData(settings);} void Menu::importSettings() {    QString locationDir(QStandardPaths::displayName(QStandardPaths::DesktopLocation));    QString fileName = QFileDialog::getOpenFileName(Application::getInstance()->getWindow(),                                                    tr("Open .ini config file"),                                                    locationDir,                                                    tr("Text files (*.ini)"));    if (fileName != "") {        QSettings tmp(fileName, QSettings::IniFormat);        loadSettings(&tmp);    }} void Menu::exportSettings() {    QString locationDir(QStandardPaths::displayName(QStandardPaths::DesktopLocation));    QString fileName = QFileDialog::getSaveFileName(Application::getInstance()->getWindow(),                                                    tr("Save .ini config file"),                                                    locationDir,                                                    tr("Text files (*.ini)"));    if (fileName != "") {        QSettings tmp(fileName, QSettings::IniFormat);        saveSettings(&tmp);        tmp.sync();    }} void Menu::checkForUpdates() {    qDebug() << "Checking if there are available updates.\n";    // if this is a release OS X build use fervor to check for an update    FvUpdater::sharedUpdater()->SetFeedURL("http://s3.highfidelity.io/appcast.xml");    FvUpdater::sharedUpdater()->CheckForUpdatesSilent();} void Menu::loadAction(QSettings* set, QAction* action) {    if (action->isChecked() != set->value(action->text(), action->isChecked()).toBool()) {        action->trigger();    }} void Menu::saveAction(QSettings* set, QAction* action) {    set->setValue(action->text(),  action->isChecked());} void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) {    QList<QMenu*> menus = this->findChildren<QMenu *>();        for (QList<QMenu *>::const_iterator it = menus.begin(); menus.end() != it; ++it) {        scanMenu(*it, modifySetting, set);    }} void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {    QList<QAction*> actions = menu->actions();        set->beginGroup(menu->title());    for (QList<QAction *>::const_iterator it = actions.begin(); actions.end() != it; ++it) {        if ((*it)->menu()) {            scanMenu((*it)->menu(), modifySetting, set);

Lines 1–500 of 798.