diff --git a/CMakeLists.txt b/CMakeLists.txt index 69ea0b7fd8..54505717d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,6 +179,10 @@ endif() add_subdirectory(tools) if (BUILD_TESTS) + # Turn on testing so that add_test works + # MUST be in the root cmake file for ctest to work + include(CTest) + enable_testing() add_subdirectory(tests) add_subdirectory(tests-manual) endif() diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index 3ca5cb0e54..36e5a065df 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -73,6 +73,8 @@ macro(SET_PACKAGING_PARAMETERS) add_definitions(-DDEV_BUILD) endif () + string(TIMESTAMP BUILD_TIME "%d/%m/%Y") + if (DEPLOY_PACKAGE) # for deployed packages always grab the serverless content set(DOWNLOAD_SERVERLESS_CONTENT ON) diff --git a/cmake/templates/BuildInfo.h.in b/cmake/templates/BuildInfo.h.in index b0af1c0524..904d17293b 100644 --- a/cmake/templates/BuildInfo.h.in +++ b/cmake/templates/BuildInfo.h.in @@ -26,4 +26,6 @@ namespace BuildInfo { const QString VERSION = "@BUILD_VERSION@"; const QString BUILD_BRANCH = "@BUILD_BRANCH@"; const QString BUILD_GLOBAL_SERVICES = "@BUILD_GLOBAL_SERVICES@"; + const QString BUILD_TIME = "@BUILD_TIME@"; } + diff --git a/interface/resources/images/about-highfidelity.png b/interface/resources/images/about-highfidelity.png new file mode 100644 index 0000000000..718ed7d525 Binary files /dev/null and b/interface/resources/images/about-highfidelity.png differ diff --git a/interface/resources/images/about-physics.png b/interface/resources/images/about-physics.png new file mode 100644 index 0000000000..62a7666da2 Binary files /dev/null and b/interface/resources/images/about-physics.png differ diff --git a/interface/resources/images/about-qt.png b/interface/resources/images/about-qt.png new file mode 100644 index 0000000000..90230ecbf5 Binary files /dev/null and b/interface/resources/images/about-qt.png differ diff --git a/interface/resources/qml/controls-uit/Slider.qml b/interface/resources/qml/controls-uit/Slider.qml index 5ddd97f3f6..2a5d4c137d 100644 --- a/interface/resources/qml/controls-uit/Slider.qml +++ b/interface/resources/qml/controls-uit/Slider.qml @@ -24,6 +24,7 @@ Slider { property alias minimumValue: slider.from property alias maximumValue: slider.to + property alias step: slider.stepSize property bool tickmarksEnabled: false height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control. diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 5f924834d9..a1b89e1529 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -149,17 +149,17 @@ FocusScope { } function isModalWindow(window) { - return window.modality !== Qt.NonModal; + return window.modality !== (typeof Qt !== 'undefined' ? Qt.NonModal : 0); } function getTopLevelWindows(predicate) { - return findMatchingChildren(desktop, function(child) { - return (isTopLevelWindow(child) && (!predicate || predicate(child))); + return d.findMatchingChildren(desktop, function(child) { + return (d.isTopLevelWindow(child) && (!predicate || predicate(child))); }); } function getDesktopWindow(item) { - return findParentMatching(item, isTopLevelWindow) + return d.findParentMatching(item, d.isTopLevelWindow) } function fixupZOrder(windows, basis, topWindow) { @@ -205,23 +205,23 @@ FocusScope { function raiseWindow(targetWindow) { var predicate; var zBasis; - if (isModalWindow(targetWindow)) { - predicate = isModalWindow; + if (d.isModalWindow(targetWindow)) { + predicate = d.isModalWindow; zBasis = zLevels.modal - } else if (isAlwaysOnTopWindow(targetWindow)) { + } else if (d.isAlwaysOnTopWindow(targetWindow)) { predicate = function(window) { - return (isAlwaysOnTopWindow(window) && !isModalWindow(window)); + return (d.isAlwaysOnTopWindow(window) && !d.isModalWindow(window)); } zBasis = zLevels.top } else { predicate = function(window) { - return (!isAlwaysOnTopWindow(window) && !isModalWindow(window)); + return (!d.isAlwaysOnTopWindow(window) && !d.isModalWindow(window)); } zBasis = zLevels.normal } - var windows = getTopLevelWindows(predicate); - fixupZOrder(windows, zBasis, targetWindow); + var windows = d.getTopLevelWindows(predicate); + d.fixupZOrder(windows, zBasis, targetWindow); } Component.onCompleted: { @@ -264,7 +264,7 @@ FocusScope { } function getRepositionChildren(predicate) { - return findMatchingChildren(desktop, function(child) { + return d.findMatchingChildren(desktop, function(child) { return (child.shouldReposition === true && (!predicate || predicate(child))); }); } diff --git a/interface/resources/qml/dialogs/PreferencesDialog.qml b/interface/resources/qml/dialogs/PreferencesDialog.qml index 0a97ab9241..fffd0e2ed9 100644 --- a/interface/resources/qml/dialogs/PreferencesDialog.qml +++ b/interface/resources/qml/dialogs/PreferencesDialog.qml @@ -26,7 +26,7 @@ ScrollingWindow { property var showCategories: [] minSize: Qt.vector2d(400, 500) - //HifiConstants { id: hifi } + HifiConstants { id: hifi } function saveAll() { for (var i = 0; i < sections.length; ++i) { @@ -96,9 +96,9 @@ ScrollingWindow { anchors { top: parent.top right: parent.right - rightMargin: 10//hifi.dimensions.contentMargin.x + rightMargin: hifi.dimensions.contentMargin.x } - spacing: 1//hifi.dimensions.contentSpacing.x + spacing: hifi.dimensions.contentSpacing.x HifiControls.Button { text: "Save changes" diff --git a/interface/resources/qml/dialogs/preferences/RadioButtonsPreference.qml b/interface/resources/qml/dialogs/preferences/RadioButtonsPreference.qml new file mode 100644 index 0000000000..77c94c2ae5 --- /dev/null +++ b/interface/resources/qml/dialogs/preferences/RadioButtonsPreference.qml @@ -0,0 +1,57 @@ +// +// RadioButtonsPreference.qml +// +// Created by Cain Kilgore on 20th July 2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 + +import "../../controls-uit" + +Preference { + id: root + + height: control.height + hifi.dimensions.controlInterlineHeight + + Component.onCompleted: { + repeater.itemAt(preference.value).checked = true + } + + function save() { + var value = 0; + for (var i = 0; i < repeater.count; i++) { + if (repeater.itemAt(i).checked) { + value = i; + break; + } + } + preference.value = value; + preference.save(); + } + + Row { + id: control + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + spacing: 5 + + Repeater { + id: repeater + model: preference.items.length + delegate: RadioButton { + text: preference.items[index] + anchors { + verticalCenter: parent.verticalCenter + } + colorScheme: hifi.colorSchemes.dark + } + } + } +} diff --git a/interface/resources/qml/dialogs/preferences/Section.qml b/interface/resources/qml/dialogs/preferences/Section.qml index 4a16036a69..0284af9d9c 100644 --- a/interface/resources/qml/dialogs/preferences/Section.qml +++ b/interface/resources/qml/dialogs/preferences/Section.qml @@ -74,6 +74,7 @@ Preference { property var comboBoxBuilder: Component { ComboBoxPreference { } } property var spinnerSliderBuilder: Component { SpinnerSliderPreference { } } property var primaryHandBuilder: Component { PrimaryHandPreference { } } + property var radioButtonsBuilder: Component { RadioButtonsPreference { } } property var preferences: [] property int checkBoxCount: 0 @@ -140,6 +141,10 @@ Preference { checkBoxCount++; builder = primaryHandBuilder; break; + case Preference.RadioButtons: + checkBoxCount++; + builder = radioButtonsBuilder; + break; }; if (builder) { diff --git a/interface/resources/qml/dialogs/preferences/SliderPreference.qml b/interface/resources/qml/dialogs/preferences/SliderPreference.qml index e9013bc17a..2bdda09fc3 100644 --- a/interface/resources/qml/dialogs/preferences/SliderPreference.qml +++ b/interface/resources/qml/dialogs/preferences/SliderPreference.qml @@ -53,6 +53,9 @@ Preference { Slider { id: slider value: preference.value + minimumValue: preference.min + maximumValue: preference.max + step: preference.step width: 130 anchors { right: parent.right diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 24111ad935..4d342fe775 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -36,6 +36,29 @@ OriginalDesktop.Desktop { } } + onHeightChanged: { + if (height > 100) { + adjustToolbarPosition(); + } + } + + function adjustToolbarPosition() { + var toolbar = getToolbar("com.highfidelity.interface.toolbar.system") + // check if Y position was changed, if toolbar height is assigned etc + // default position is adjusted to border width + var toolbarY = toolbar.settings.y > 6 ? + toolbar.settings.y : + desktop.height - (toolbar.height > 0 ? toolbar.height : 50) - 56 + + if (toolbar.settings.desktopHeight > 100 && desktop.height !== toolbar.settings.desktopHeight) { + toolbarY += desktop.height - toolbar.settings.desktopHeight + } + + toolbar.y = toolbarY + toolbar.settings.y = toolbarY + toolbar.settings.desktopHeight = desktop.height + } + Component { id: toolbarBuilder; Toolbar { } } // This used to create sysToolbar dynamically with a call to getToolbar() within onCompleted. // Beginning with QT 5.6, this stopped working, as anything added to toolbars too early got @@ -47,7 +70,6 @@ OriginalDesktop.Desktop { anchors.horizontalCenter: settings.constrainToolbarToCenterX ? desktop.horizontalCenter : undefined; // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings when not constrained. x: sysToolbar.x - y: 50 buttonModel: tablet.buttons; shown: tablet.toolbarMode; } diff --git a/interface/resources/qml/hifi/dialogs/AboutDialog.qml b/interface/resources/qml/hifi/dialogs/AboutDialog.qml new file mode 100644 index 0000000000..b8e6e89aec --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/AboutDialog.qml @@ -0,0 +1,32 @@ +// +// AssetDialog.qml +// +// Created by David Rowe on 18 Apr 2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.8 + +import "../../styles-uit" +import "../../windows" + +ScrollingWindow { + id: root + resizable: false + implicitWidth: 480 + implicitHeight: 706 + objectName: "aboutDialog" + destroyOnCloseButton: true + destroyOnHidden: true + visible: true + minSize: Qt.vector2d(480, 706) + title: "About" + + TabletAboutDialog { + width: pane.width + height: pane.height + } +} diff --git a/interface/resources/qml/hifi/dialogs/AvatarPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/AvatarPreferencesDialog.qml index 86f195612c..01b2690afb 100644 --- a/interface/resources/qml/hifi/dialogs/AvatarPreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/AvatarPreferencesDialog.qml @@ -7,7 +7,7 @@ PreferencesDialog { id: root objectName: "AvatarPreferencesDialog" title: "Avatar Settings" - showCategories: [ "Avatar Basics", "Avatar Tuning", "Avatar Camera" ] + showCategories: [ "Avatar Basics", "Avatar Tuning" ] property var settings: Settings { category: root.objectName property alias x: root.x diff --git a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml index 6f5798e2b2..cb4913f999 100644 --- a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml @@ -17,7 +17,7 @@ PreferencesDialog { id: root objectName: "GeneralPreferencesDialog" title: "General Settings" - showCategories: ["UI", "Snapshots", "Privacy", "HMD", "Game Controller", "Sixense Controllers", "Perception Neuron", "Kinect", "Leap Motion"] + showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"] property var settings: Settings { category: root.objectName property alias x: root.x diff --git a/interface/resources/qml/hifi/dialogs/GraphicsPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/GraphicsPreferencesDialog.qml new file mode 100644 index 0000000000..eaab5b8173 --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/GraphicsPreferencesDialog.qml @@ -0,0 +1,29 @@ +// +// AdvancedPreferencesDialog.qml +// +// Created by Brad Hefta-Gaub on 20 Jan 2018 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import Qt.labs.settings 1.0 + +import "../../dialogs" + +PreferencesDialog { + id: root + objectName: "GraphicsPreferencesDialog" + title: "Graphics Settings" + showCategories: ["Graphics Quality" ] + property var settings: Settings { + category: root.objectName + property alias x: root.x + property alias y: root.y + property alias width: root.width + property alias height: root.height + } +} + diff --git a/interface/resources/qml/hifi/dialogs/RunningScripts.qml b/interface/resources/qml/hifi/dialogs/RunningScripts.qml index 9e3ebcbab0..9a180a66f6 100644 --- a/interface/resources/qml/hifi/dialogs/RunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/RunningScripts.qml @@ -79,7 +79,7 @@ ScrollingWindow { interval: 1000 repeat: true running: false - onTriggered: developerMenuEnabled = MenuInterface.isMenuEnabled("Developer Menus"); + onTriggered: developerMenuEnabled = MenuInterface.isOptionChecked("Developer Menu"); } Component { @@ -98,7 +98,7 @@ ScrollingWindow { Component.onCompleted: { isHMD = HMD.active; updateRunningScripts(); - developerMenuEnabled = MenuInterface.isMenuEnabled("Developer Menus"); + developerMenuEnabled = MenuInterface.isOptionChecked("Developer Menu"); checkMenu.restart(); } diff --git a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml new file mode 100644 index 0000000000..579aa1cb1e --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml @@ -0,0 +1,122 @@ +// +// TabletAssetDialog.qml +// +// Created by David Rowe on 18 Apr 2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import "../../styles-uit" + +Rectangle { + width: 480 + height: 706 + + color: "#404040" + + Column { + x: 45 + y: 30 + spacing: 5 + + Image { + sourceSize.width: 295 + sourceSize.height: 75 + source: "../../../images/about-highfidelity.png" + } + Item { height: 30; width: 1 } + Column { + id: buildColumm + anchors.left: parent.left + anchors.leftMargin: 70 + RalewayRegular { + text: "Build " + HiFiAbout.buildVersion + size: 16 + color: "white" + } + RalewayRegular { + text: "Released " + HiFiAbout.buildDate + size: 16 + color: "white" + } + } + Item { height: 10; width: 1 } + RalewayRegular { + text: "An open-source virtual reality platform." + size: 20 + color: "white" + } + RalewayRegular { + textFormat: Text.StyledText + linkColor: "#00B4EF" + color: "white" + text: "www.highfidelity.com." + size: 20 + onLinkActivated: { + HiFiAbout.openUrl("https:/www.highfidelity.com"); + } + } + Item { height: 40; width: 1 } + Row { + spacing: 5 + Image { + sourceSize.width: 34 + sourceSize.height: 25 + source: "../../../images/about-qt.png" + MouseArea { + anchors.fill: parent + onClicked: { + HiFiAbout.openUrl("https://www.qt.io/"); + } + } + } + RalewayRegular { + color: "white" + text: "Built using Qt " + HiFiAbout.qtVersion + size: 12 + anchors.verticalCenter: parent.verticalCenter + } + Item { height: 1; width: 15 } + Image { + sourceSize.width: 70 + sourceSize.height: 26 + source: "../../../images/about-physics.png" + } + RalewayRegular { + color: "white" + text: "Physics powered by Bullet" + size: 12 + anchors.verticalCenter: parent.verticalCenter + } + } + Item { height: 20; width: 1 } + RalewayRegular { + textFormat: Text.StyledText + linkColor: "#00B4EF" + color: "white" + text: "Blockchain technology from Elements." + size: 14 + onLinkActivated: { + HiFiAbout.openUrl("https://elementsproject.org/elements/"); + } + } + RalewayRegular { + color: "white" + text: "© 2018 High Fidelity. All rights reserved." + size: 14 + } + RalewayRegular { + textFormat: Text.StyledText + color: "white" + linkColor: "#00B4EF" + text: "Distributed under the Apache License, Version 2.0.." + size: 14 + onLinkActivated: { + HiFiAbout.openUrl("http://www.apache.org/licenses/LICENSE-2.0.html"); + } + } + } +} diff --git a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml index 83f91c78c5..018c8f5737 100644 --- a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml @@ -65,7 +65,7 @@ Rectangle { interval: 1000 repeat: true running: false - onTriggered: developerMenuEnabled = MenuInterface.isMenuEnabled("Developer Menus"); + onTriggered: developerMenuEnabled = MenuInterface.isOptionChecked("Developer Menu"); } Component { @@ -84,7 +84,7 @@ Rectangle { Component.onCompleted: { isHMD = HMD.active; updateRunningScripts(); - developerMenuEnabled = MenuInterface.isMenuEnabled("Developer Menus"); + developerMenuEnabled = MenuInterface.isOptionChecked("Developer Menu"); checkMenu.restart(); } diff --git a/interface/resources/qml/hifi/tablet/CalibratingScreen.qml b/interface/resources/qml/hifi/tablet/CalibratingScreen.qml index 6c26bd87c5..e3115a5738 100644 --- a/interface/resources/qml/hifi/tablet/CalibratingScreen.qml +++ b/interface/resources/qml/hifi/tablet/CalibratingScreen.qml @@ -18,7 +18,7 @@ import "../../controls-uit" as HifiControls Rectangle { id: info - + anchors.fill: parent signal canceled() signal restart() diff --git a/interface/resources/qml/hifi/tablet/ControllerSettings.qml b/interface/resources/qml/hifi/tablet/ControllerSettings.qml index 0beb28977e..da8334f831 100644 --- a/interface/resources/qml/hifi/tablet/ControllerSettings.qml +++ b/interface/resources/qml/hifi/tablet/ControllerSettings.qml @@ -8,222 +8,286 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 +import Qt.labs.settings 1.0 import "../../styles-uit" import "../../controls" import "../../controls-uit" as HifiControls +import "../../dialogs" +import "../../dialogs/preferences" +import "tabletWindows" +import "../audio" -StackView { - id: stack - initialItem: inputConfiguration - property alias messageVisible: imageMessageBox.visible - property alias selectedPlugin: box.currentText - Rectangle { - id: inputConfiguration - anchors.fill: parent +Item { + id: controllerSettings + height: parent.height + width: parent.width - HifiConstants { id: hifi } + HifiConstants { id: hifi } - color: hifi.colors.baseGray + TabBar { + id: bar + spacing: 0 + anchors.top: controllerSettings.top + width: parent.width + height: 40 + z: 10 - property var pluginSettings: null - - HifiControls.ImageMessageBox { - id: imageMessageBox - anchors.fill: parent - z: 2000 - imageWidth: 442 - imageHeight: 670 - source: "../../../images/calibration-help.png" - } - - Rectangle { - width: inputConfiguration.width - height: 1 - color: hifi.colors.baseGrayShadow - x: -hifi.dimensions.contentMargin.x - } - - RalewayRegular { - id: header - text: "Controller Settings" - size: 22 - color: "white" - - anchors.top: inputConfiguration.top - anchors.left: inputConfiguration.left - anchors.leftMargin: 20 - anchors.topMargin: 20 - } - - - Separator { - id: headerSeparator - width: inputConfiguration.width - anchors.top: header.bottom - anchors.topMargin: 10 - } - - HiFiGlyphs { - id: sourceGlyph - text: hifi.glyphs.source - size: 36 - color: hifi.colors.blueHighlight - - anchors.top: headerSeparator.bottom - anchors.left: inputConfiguration.left - anchors.leftMargin: 40 - anchors.topMargin: 20 - } - - RalewayRegular { - id: configuration - text: "SELECT DEVICE" - size: 15 - color: hifi.colors.lightGrayText - - - anchors.top: headerSeparator.bottom - anchors.left: sourceGlyph.right - anchors.leftMargin: 10 - anchors.topMargin: 30 - } - - Row { - id: configRow - z: 999 - anchors.top: sourceGlyph.bottom - anchors.topMargin: 20 - anchors.left: sourceGlyph.left - anchors.leftMargin: 40 - spacing: 10 - HifiControls.ComboBox { - id: box - width: 160 - z: 999 - editable: true - colorScheme: hifi.colorSchemes.dark - model: inputPlugins() - label: "" - - onCurrentIndexChanged: { - changeSource(); - } - } - - HifiControls.CheckBox { - id: checkBox - colorScheme: hifi.colorSchemes.dark - text: "show all input devices" - - onClicked: { - inputPlugins(); - changeSource(); - } + TabButton { + height: parent.height + text: qsTr("Settings") + onClicked: { + stackView.clear(); + stackView.push(controllerPreferencesComponent); } } - - - Separator { - id: configurationSeparator - z: 0 - width: inputConfiguration.width - anchors.top: configRow.bottom - anchors.topMargin: 10 + TabButton { + height: parent.height + text: qsTr("Calibration") + onClicked: { + stackView.clear(); + stackView.push(inputConfigurationComponent); + } } + } - HiFiGlyphs { - id: sliderGlyph - text: hifi.glyphs.sliders - size: 36 - color: hifi.colors.blueHighlight + StackView { + id: stackView + anchors.top: bar.bottom + anchors.bottom: controllerSettings.bottom + anchors.left: controllerSettings.left + anchors.right: controllerSettings.right - anchors.top: configurationSeparator.bottom - anchors.left: inputConfiguration.left - anchors.leftMargin: 40 - anchors.topMargin: 20 - } + initialItem: controllerPreferencesComponent + } - RalewayRegular { - id: configurationHeader - text: "CONFIGURATION" - size: 15 - color: hifi.colors.lightGrayText + Component { + id: inputConfigurationComponent + StackView { + id: stack + initialItem: inputConfiguration + property alias messageVisible: imageMessageBox.visible + property alias selectedPlugin: box.currentText + Rectangle { + id: inputConfiguration + anchors.fill: parent + + HifiConstants { id: hifi } + + color: hifi.colors.baseGray + + property var pluginSettings: null + + HifiControls.ImageMessageBox { + id: imageMessageBox + anchors.fill: parent + z: 2000 + imageWidth: 442 + imageHeight: 670 + source: "../../../images/calibration-help.png" + } + + Rectangle { + width: inputConfiguration.width + height: 1 + color: hifi.colors.baseGrayShadow + x: -hifi.dimensions.contentMargin.x + } + + RalewayRegular { + id: header + text: "Control Settings" + size: 22 + color: "white" + + anchors.top: inputConfiguration.top + anchors.left: inputConfiguration.left + anchors.leftMargin: 20 + anchors.topMargin: 20 + } + + Separator { + id: headerSeparator + width: inputConfiguration.width + anchors.top: header.bottom + anchors.topMargin: 10 + } + + HiFiGlyphs { + id: sourceGlyph + text: hifi.glyphs.source + size: 36 + color: hifi.colors.blueHighlight + + anchors.top: headerSeparator.bottom + anchors.left: inputConfiguration.left + anchors.leftMargin: 40 + anchors.topMargin: 20 + } + + RalewayRegular { + id: configuration + text: "SELECT DEVICE" + size: 15 + color: hifi.colors.lightGrayText - anchors.top: configurationSeparator.bottom - anchors.left: sliderGlyph.right - anchors.leftMargin: 10 - anchors.topMargin: 30 - } + anchors.top: headerSeparator.bottom + anchors.left: sourceGlyph.right + anchors.leftMargin: 10 + anchors.topMargin: 30 + } - Loader { - id: loader - asynchronous: false + Row { + id: configRow + z: 999 + anchors.top: sourceGlyph.bottom + anchors.topMargin: 20 + anchors.left: sourceGlyph.left + anchors.leftMargin: 40 + spacing: 10 + HifiControls.ComboBox { + id: box + width: 160 + z: 999 + editable: true + colorScheme: hifi.colorSchemes.dark + model: inputPlugins() + label: "" - width: inputConfiguration.width - anchors.left: inputConfiguration.left - anchors.right: inputConfiguration.right - anchors.top: configurationHeader.bottom - anchors.topMargin: 10 - anchors.bottom: inputConfiguration.bottom + onCurrentIndexChanged: { + changeSource(); + } + } - source: InputConfiguration.configurationLayout(box.currentText); - onLoaded: { - if (loader.item.hasOwnProperty("pluginName")) { - if (box.currentText === "HTC Vive") { - loader.item.pluginName = "OpenVR"; - } else { - loader.item.pluginName = box.currentText; + HifiControls.CheckBox { + id: checkBox + colorScheme: hifi.colorSchemes.dark + text: "show all input devices" + + onClicked: { + inputPlugins(); + changeSource(); + } } } - if (loader.item.hasOwnProperty("displayInformation")) { - loader.item.displayConfiguration(); + + Separator { + id: configurationSeparator + z: 0 + width: inputConfiguration.width + anchors.top: configRow.bottom + anchors.topMargin: 10 } + + + HiFiGlyphs { + id: sliderGlyph + text: hifi.glyphs.sliders + size: 36 + color: hifi.colors.blueHighlight + + anchors.top: configurationSeparator.bottom + anchors.left: inputConfiguration.left + anchors.leftMargin: 40 + anchors.topMargin: 20 + } + + RalewayRegular { + id: configurationHeader + text: "CONFIGURATION" + size: 15 + color: hifi.colors.lightGrayText + + + anchors.top: configurationSeparator.bottom + anchors.left: sliderGlyph.right + anchors.leftMargin: 10 + anchors.topMargin: 30 + } + + Loader { + id: loader + asynchronous: false + + width: inputConfiguration.width + anchors.left: inputConfiguration.left + anchors.right: inputConfiguration.right + anchors.top: configurationHeader.bottom + anchors.topMargin: 10 + anchors.bottom: inputConfiguration.bottom + + source: InputConfiguration.configurationLayout(box.currentText); + onLoaded: { + if (loader.item.hasOwnProperty("pluginName")) { + if (box.currentText === "HTC Vive") { + loader.item.pluginName = "OpenVR"; + } else { + loader.item.pluginName = box.currentText; + } + } + + if (loader.item.hasOwnProperty("displayInformation")) { + loader.item.displayConfiguration(); + } + } + } + } + + + function inputPlugins() { + if (checkBox.checked) { + return InputConfiguration.inputPlugins(); + } else { + return InputConfiguration.activeInputPlugins(); + } + } + + function initialize() { + changeSource(); + } + + function changeSource() { + loader.source = ""; + var source = ""; + if (box.currentText == "Vive") { + source = InputConfiguration.configurationLayout("OpenVR"); + } else { + source = InputConfiguration.configurationLayout(box.currentText); + } + + loader.source = source; + if (source === "") { + box.label = "(not configurable)"; + } else { + box.label = ""; + } + } + + Timer { + id: timer + repeat: false + interval: 300 + onTriggered: initialize() + } + + Component.onCompleted: { + timer.start(); } } } - function inputPlugins() { - if (checkBox.checked) { - return InputConfiguration.inputPlugins(); - } else { - return InputConfiguration.activeInputPlugins(); + Component { + id: controllerPreferencesComponent + TabletPreferencesDialog { + anchors.fill: stackView + id: controllerPrefereneces + objectName: "TabletControllerPreferences" + showCategories: ["VR Movement", "Game Controller", "Sixense Controllers", "Perception Neuron", "Leap Motion"] } } - - function initialize() { - changeSource(); - } - - function changeSource() { - loader.source = ""; - var source = ""; - if (box.currentText == "Vive") { - source = InputConfiguration.configurationLayout("OpenVR"); - } else { - source = InputConfiguration.configurationLayout(box.currentText); - } - - loader.source = source; - if (source === "") { - box.label = "(not configurable)"; - } else { - box.label = ""; - } - } - - Timer { - id: timer - repeat: false - interval: 300 - onTriggered: initialize() - } - - Component.onCompleted: { - timer.start(); - } } diff --git a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml index 810f5bb43f..63801019b9 100644 --- a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml @@ -32,6 +32,6 @@ StackView { TabletPreferencesDialog { id: root objectName: "TabletGeneralPreferences" - showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Game Controller", "Sixense Controllers", "Perception Neuron", "Kinect", "Leap Motion"] + showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"] } } diff --git a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml index 3114c79bfe..8d600975ed 100644 --- a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml @@ -32,6 +32,6 @@ StackView { TabletPreferencesDialog { id: root objectName: "TabletGraphicsPreferences" - showCategories: ["Graphics"] + showCategories: ["Graphics Quality"] } } diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml index a5ef3d2686..646a0d2c77 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml @@ -19,6 +19,7 @@ Item { id: dialog width: parent.width height: parent.height + anchors.fill: parent HifiConstants { id: hifi } property var sections: [] @@ -158,14 +159,15 @@ Item { Rectangle { id: footer - height: 40 + height: dialog.height * 0.15 + anchors.bottom: dialog.bottom anchors { bottom: keyboard.top left: parent.left right: parent.right } - + color: hifi.colors.baseGray Row { diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml index 5036569031..15db58decc 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml @@ -82,6 +82,7 @@ Preference { property var comboBoxBuilder: Component { ComboBoxPreference { } } property var spinnerSliderBuilder: Component { SpinnerSliderPreference { } } property var primaryHandBuilder: Component { PrimaryHandPreference { } } + property var radioButtonsBuilder: Component { RadioButtonsPreference { } } property var preferences: [] property int checkBoxCount: 0 @@ -154,6 +155,10 @@ Preference { checkBoxCount++; builder = primaryHandBuilder; break; + case Preference.RadioButtons: + checkBoxCount++; + builder = radioButtonsBuilder; + break; }; if (builder) { diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 49aff06929..b32d9c7428 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -25,12 +25,24 @@ Window { property bool horizontal: true property real buttonSize: 50; + property alias settings: settings + Settings { + id: settings category: "toolbar/" + window.objectName property alias x: window.x - property alias y: window.y + property real y: 0 + property real desktopHeight: 0 //placeholder for desktop height } - + + onYChanged: { + //check if Y changed not due to Desktop size changed. ie. mouse manipulations + //otherwise it will be save by Desktop + if (desktop.height > 100 && desktop.height === settings.desktopHeight) { + settings.y = window.y + } + } + Component { id: buttonComponent ToolbarButton { diff --git a/interface/resources/qml/windows/Frame.qml b/interface/resources/qml/windows/Frame.qml index 98bfb52c38..271d4f2e07 100644 --- a/interface/resources/qml/windows/Frame.qml +++ b/interface/resources/qml/windows/Frame.qml @@ -43,7 +43,7 @@ Item { Text { id: debugZ - visible: DebugQML + visible: (typeof DebugQML !== 'undefined') ? DebugQML : false color: "red" text: (window ? "Z: " + window.z : "") + " " + qmlFile y: window ? window.height + 4 : 0 diff --git a/interface/src/AboutUtil.cpp b/interface/src/AboutUtil.cpp new file mode 100644 index 0000000000..5179897443 --- /dev/null +++ b/interface/src/AboutUtil.cpp @@ -0,0 +1,69 @@ +// +// AboutUtil.cpp +// interface/src +// +// Created by Vlad Stelmahovsky on 15/5/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include +#include + +#include "AboutUtil.h" +#include "BuildInfo.h" +#include +#include "DependencyManager.h" +#include "scripting/HMDScriptingInterface.h" +#include "Application.h" +#include + +AboutUtil::AboutUtil(QObject *parent) : QObject(parent) { + QLocale locale_; + m_DateConverted = QDate::fromString(BuildInfo::BUILD_TIME, "dd/MM/yyyy"). + toString(locale_.dateFormat(QLocale::ShortFormat)); +} + +AboutUtil *AboutUtil::getInstance() +{ + static AboutUtil instance; + return &instance; +} + +QString AboutUtil::buildDate() const +{ + return m_DateConverted; +} + +QString AboutUtil::buildVersion() const +{ + return BuildInfo::VERSION; +} + +QString AboutUtil::qtVersion() const +{ + return qVersion(); +} + +void AboutUtil::openUrl(const QString& url) const { + + auto tabletScriptingInterface = DependencyManager::get(); + auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + auto hmd = DependencyManager::get(); + auto offscreenUi = DependencyManager::get(); + + if (tablet->getToolbarMode()) { + offscreenUi->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { + newObject->setProperty("url", url); + }); + } else { + if (!hmd->getShouldShowTablet() && !qApp->isHMDMode()) { + offscreenUi->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { + newObject->setProperty("url", url); + }); + } else { + tablet->gotoWebScreen(url); + } + } +} diff --git a/interface/src/AboutUtil.h b/interface/src/AboutUtil.h new file mode 100644 index 0000000000..9b65b887b9 --- /dev/null +++ b/interface/src/AboutUtil.h @@ -0,0 +1,42 @@ +// +// AboutUtil.h +// interface/src +// +// Created by Vlad Stelmahovsky on 15/5/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +#ifndef hifi_AboutUtil_h +#define hifi_AboutUtil_h + +#include + +class AboutUtil : public QObject { + + Q_OBJECT + + Q_PROPERTY(QString buildDate READ buildDate CONSTANT) + Q_PROPERTY(QString buildVersion READ buildVersion CONSTANT) + Q_PROPERTY(QString qtVersion READ qtVersion CONSTANT) + + AboutUtil(QObject* parent = nullptr); +public: + static AboutUtil* getInstance(); + ~AboutUtil() {} + + QString buildDate() const; + QString buildVersion() const; + QString qtVersion() const; + +public slots: + void openUrl(const QString &url) const; +private: + + QString m_DateConverted; +}; + +#endif // hifi_AboutUtil_h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5aabca93b6..6a102f418b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -220,6 +220,8 @@ #include "webbrowser/WebBrowserSuggestionsEngine.h" #include +#include "AboutUtil.h" + #if defined(Q_OS_WIN) #include @@ -2741,7 +2743,7 @@ void Application::initializeRenderEngine() { } extern void setupPreferences(); -static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active); +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, int index, bool active = false); void Application::initializeUi() { // Build a shared canvas / context for the Chromium processes @@ -2899,9 +2901,11 @@ void Application::initializeUi() { std::stable_sort(displayPlugins.begin(), displayPlugins.end(), [](const DisplayPluginPointer& a, const DisplayPluginPointer& b)->bool { return a->getGrouping() < b->getGrouping(); }); + int dpIndex = 1; // concatenate the groupings into a single list in the order: standard, advanced, developer for(const auto& displayPlugin : displayPlugins) { - addDisplayPluginToMenu(displayPlugin, _displayPlugin == displayPlugin); + addDisplayPluginToMenu(displayPlugin, dpIndex, _displayPlugin == displayPlugin); + dpIndex++; } // after all plugins have been added to the menu, add a separator to the menu @@ -2993,6 +2997,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { surfaceContext->setContextProperty("Selection", DependencyManager::get().data()); surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get().data()); surfaceContext->setContextProperty("Wallet", DependencyManager::get().data()); + surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); @@ -3715,7 +3720,8 @@ void Application::keyPressEvent(QKeyEvent* event) { if (isShifted && isMeta) { Menu::getInstance()->triggerOption(MenuOption::Log); } else if (isMeta) { - Menu::getInstance()->triggerOption(MenuOption::AddressBar); + auto dialogsManager = DependencyManager::get(); + dialogsManager->toggleAddressBar(); } else if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::LodTools); } @@ -3748,13 +3754,16 @@ void Application::keyPressEvent(QKeyEvent* event) { AudioInjectorOptions options; options.localOnly = true; options.stereo = true; - - if (_snapshotSoundInjector) { - _snapshotSoundInjector->setOptions(options); - _snapshotSoundInjector->restart(); - } else { - QByteArray samples = _snapshotSound->getByteArray(); - _snapshotSoundInjector = AudioInjector::playSound(samples, options); + Setting::Handle notificationSounds{ MenuOption::NotificationSounds, true}; + Setting::Handle notificationSoundSnapshot{ MenuOption::NotificationSoundsSnapshot, true}; + if (notificationSounds.get() && notificationSoundSnapshot.get()) { + if (_snapshotSoundInjector) { + _snapshotSoundInjector->setOptions(options); + _snapshotSoundInjector->restart(); + } else { + QByteArray samples = _snapshotSound->getByteArray(); + _snapshotSoundInjector = AudioInjector::playSound(samples, options); + } } takeSnapshot(true); break; @@ -5121,7 +5130,7 @@ void Application::toggleOverlays() { void Application::setOverlaysVisible(bool visible) { auto menu = Menu::getInstance(); - menu->setIsOptionChecked(MenuOption::Overlays, true); + menu->setIsOptionChecked(MenuOption::Overlays, visible); } void Application::centerUI() { @@ -6606,6 +6615,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Wallet", DependencyManager::get().data()); scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance()); qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue); @@ -6923,12 +6933,7 @@ void Application::showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const if (onTablet) { toggleTabletUI(true); } - } - - if (!onTablet) { - DependencyManager::get()->show(widgetUrl, name); - } - if (tablet->getToolbarMode()) { + } else { DependencyManager::get()->show(widgetUrl, name); } } @@ -7550,7 +7555,6 @@ void Application::loadLODToolsDialog() { } } - void Application::loadEntityStatisticsDialog() { auto tabletScriptingInterface = DependencyManager::get(); auto tablet = dynamic_cast(tabletScriptingInterface->getTablet(SYSTEM_TABLET)); @@ -7889,7 +7893,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const { static const char* EXCLUSION_GROUP_KEY = "exclusionGroup"; -static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active) { +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, int index, bool active) { auto menu = Menu::getInstance(); QString name = displayPlugin->getName(); auto grouping = displayPlugin->getGrouping(); @@ -7916,7 +7920,7 @@ static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bo } auto parent = menu->getMenu(MenuOption::OutputMenu); auto action = menu->addActionToQMenuAndActionHash(parent, - name, 0, qApp, + name, QKeySequence(Qt::CTRL + (Qt::Key_0 + index)), qApp, SLOT(updateDisplayMode()), QAction::NoRole, Menu::UNSPECIFIED_POSITION, groupingMenu); @@ -8194,7 +8198,6 @@ void Application::readArgumentsFromLocalSocket() const { } void Application::showDesktop() { - Menu::getInstance()->setIsOptionChecked(MenuOption::Overlays, true); } CompositorHelper& Application::getApplicationCompositor() const { diff --git a/interface/src/CrashHandler.cpp b/interface/src/CrashHandler.cpp index f7d71de3fe..d3079b9bf4 100644 --- a/interface/src/CrashHandler.cpp +++ b/interface/src/CrashHandler.cpp @@ -35,6 +35,8 @@ bool CrashHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPromp QSettings settings; settings.beginGroup("Developer"); QVariant displayCrashOptions = settings.value(MenuOption::DisplayCrashOptions); + settings.endGroup(); + settings.beginGroup("Settings"); QVariant askToResetSettingsOption = settings.value(MenuOption::AskToResetSettings); settings.endGroup(); bool askToResetSettings = askToResetSettingsOption.isValid() && askToResetSettingsOption.toBool(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c22214a3ba..f55c389a1f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -10,7 +10,7 @@ // #include "Menu.h" - +#include #include #include #include @@ -51,6 +51,7 @@ #include "RenderShadowTask.h" #include "AntialiasingEffect.h" +#include "scripting/SettingsScriptingInterface.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" #endif @@ -81,9 +82,6 @@ Menu::Menu() { dialogsManager.data(), &DialogsManager::toggleLoginDialog); } - // File > Help - addActionToQMenuAndActionHash(fileMenu, MenuOption::Help, 0, qApp, SLOT(showHelp())); - // File > Quit addActionToQMenuAndActionHash(fileMenu, MenuOption::Quit, Qt::CTRL | Qt::Key_Q, qApp, SLOT(quit()), QAction::QuitRole); @@ -102,6 +100,22 @@ Menu::Menu() { redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); addActionToQMenuAndActionHash(editMenu, redoAction); + editMenu->addSeparator(); + + // Edit > Cut + addActionToQMenuAndActionHash(editMenu, "Cut", Qt::CTRL | Qt::Key_X); + + // Edit > Copy + addActionToQMenuAndActionHash(editMenu, "Copy", Qt::CTRL | Qt::Key_C); + + // Edit > Paste + addActionToQMenuAndActionHash(editMenu, "Paste", Qt::CTRL | Qt::Key_V); + + // Edit > Delete + addActionToQMenuAndActionHash(editMenu, "Delete", Qt::Key_Delete); + + editMenu->addSeparator(); + // Edit > Running Scripts auto action = addActionToQMenuAndActionHash(editMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J); connect(action, &QAction::triggered, [] { @@ -111,41 +125,9 @@ Menu::Menu() { qApp->showDialog(widgetUrl, tabletUrl, name); }); - // Edit > Open and Run Script from File... [advanced] - addActionToQMenuAndActionHash(editMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, - qApp, SLOT(loadDialog()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - - // Edit > Open and Run Script from Url... [advanced] - addActionToQMenuAndActionHash(editMenu, MenuOption::LoadScriptURL, - Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - - auto scriptEngines = DependencyManager::get(); - // Edit > Stop All Scripts... [advanced] - addActionToQMenuAndActionHash(editMenu, MenuOption::StopAllScripts, 0, - scriptEngines.data(), SLOT(stopAllScripts()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - - // Edit > Reload All Scripts... [advanced] - action = addActionToQMenuAndActionHash(editMenu, MenuOption::ReloadAllScripts, Qt::CTRL | Qt::Key_R, - nullptr, nullptr, - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - connect(action, &QAction::triggered, [] { - DependencyManager::get()->reloadAllScripts(); - DependencyManager::get()->clearCache(); - }); - - - // Edit > Console... [advanced] - addActionToQMenuAndActionHash(editMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J, - DependencyManager::get().data(), - SLOT(toggleConsole()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - editMenu->addSeparator(); - // Edit > My Asset Server + // Edit > Asset Browser auto assetServerAction = addActionToQMenuAndActionHash(editMenu, MenuOption::AssetServer, Qt::CTRL | Qt::SHIFT | Qt::Key_A, qApp, SLOT(showAssetServerWidget())); @@ -153,30 +135,20 @@ Menu::Menu() { QObject::connect(nodeList.data(), &NodeList::canWriteAssetsChanged, assetServerAction, &QAction::setEnabled); assetServerAction->setEnabled(nodeList->getThisNodeCanWriteAssets()); - // Edit > Package Model... [advanced] + // Edit > Package Model as .fst... addActionToQMenuAndActionHash(editMenu, MenuOption::PackageModel, 0, - qApp, SLOT(packageModel()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); + qApp, SLOT(packageModel())); + + // Edit > Reload All Content + addActionToQMenuAndActionHash(editMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches())); - // Edit > Reload All Content [advanced] - addActionToQMenuAndActionHash(editMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); - // Avatar menu ---------------------------------- MenuWrapper* avatarMenu = addMenu("Avatar"); auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getMyAvatar(); - // Avatar > Attachments... - action = addActionToQMenuAndActionHash(avatarMenu, MenuOption::Attachments); - connect(action, &QAction::triggered, [] { - qApp->showDialog(QString("hifi/dialogs/AttachmentsDialog.qml"), - QString("hifi/tablet/TabletAttachmentsDialog.qml"), "AttachmentsDialog"); - }); - - // Avatar > Size + // Avatar > Size MenuWrapper* avatarSizeMenu = avatarMenu->addMenu("Size"); - // Avatar > Size > Increase addActionToQMenuAndActionHash(avatarSizeMenu, MenuOption::IncreaseAvatarSize, @@ -201,16 +173,15 @@ Menu::Menu() { 0, // QML Qt::Key_Apostrophe, qApp, SLOT(resetSensors())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableAvatarCollisions, 0, true, - avatar.get(), SLOT(updateMotionBehaviorFromMenu())); + // Avatar > Attachments... + action = addActionToQMenuAndActionHash(avatarMenu, MenuOption::Attachments); + connect(action, &QAction::triggered, [] { + qApp->showDialog(QString("hifi/dialogs/AttachmentsDialog.qml"), + QString("hifi/tablet/TabletAttachmentsDialog.qml"), "AttachmentsDialog"); + }); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableFlying, 0, true, - avatar.get(), SLOT(setFlyingEnabled(bool))); - - // Avatar > AvatarBookmarks related menus -- Note: the AvatarBookmarks class adds its own submenus here. auto avatarBookmarks = DependencyManager::get(); avatarBookmarks->setupMenus(this, avatarMenu); - // Display menu ---------------------------------- // FIXME - this is not yet matching Alan's spec because it doesn't have // menus for "2D"/"3D" - we need to add support for detecting the appropriate @@ -249,19 +220,17 @@ Menu::Menu() { viewMirrorAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); - // View > Independent [advanced] + // View > Independent auto viewIndependentAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::IndependentMode, 0, - false, qApp, SLOT(cameraMenuChanged()), - UNSPECIFIED_POSITION, "Advanced")); + false, qApp, SLOT(cameraMenuChanged()))); viewIndependentAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); - // View > Entity Camera [advanced] + // View > Entity Camera auto viewEntityCameraAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CameraEntityMode, 0, - false, qApp, SLOT(cameraMenuChanged()), - UNSPECIFIED_POSITION, "Advanced")); + false, qApp, SLOT(cameraMenuChanged()))); viewEntityCameraAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); @@ -269,54 +238,54 @@ Menu::Menu() { // View > Center Player In View addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView, - 0, true, qApp, SLOT(rotationModeChanged()), - UNSPECIFIED_POSITION, "Advanced"); + 0, true, qApp, SLOT(rotationModeChanged())); - // View > Overlays addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Overlays, 0, true); // View > Enter First Person Mode in HMD addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPersonHMD, 0, true); + //TODO: Remove Navigation menu when these functions are included in GoTo menu // Navigate menu ---------------------------------- MenuWrapper* navigateMenu = addMenu("Navigate"); - // Navigate > Show Address Bar - addActionToQMenuAndActionHash(navigateMenu, MenuOption::AddressBar, Qt::CTRL | Qt::Key_L, - dialogsManager.data(), SLOT(toggleAddressBar())); - // Navigate > LocationBookmarks related menus -- Note: the LocationBookmarks class adds its own submenus here. auto locationBookmarks = DependencyManager::get(); locationBookmarks->setupMenus(this, navigateMenu); - // Navigate > Copy Address [advanced] + // Navigate > Copy Address auto addressManager = DependencyManager::get(); addActionToQMenuAndActionHash(navigateMenu, MenuOption::CopyAddress, 0, - addressManager.data(), SLOT(copyAddress()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); + addressManager.data(), SLOT(copyAddress())); - // Navigate > Copy Path [advanced] + // Navigate > Copy Path addActionToQMenuAndActionHash(navigateMenu, MenuOption::CopyPath, 0, - addressManager.data(), SLOT(copyPath()), - QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); + addressManager.data(), SLOT(copyPath())); // Settings menu ---------------------------------- MenuWrapper* settingsMenu = addMenu("Settings"); - // Settings > Advance Menus - addCheckableActionToQMenuAndActionHash(settingsMenu, "Advanced Menus", 0, false, this, SLOT(toggleAdvancedMenus())); - - // Settings > Developer Menus - addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menus", 0, false, this, SLOT(toggleDeveloperMenus())); - // Settings > General... - action = addActionToQMenuAndActionHash(settingsMenu, MenuOption::Preferences, Qt::CTRL | Qt::Key_Comma, nullptr, nullptr, QAction::PreferencesRole); + action = addActionToQMenuAndActionHash(settingsMenu, MenuOption::Preferences, Qt::CTRL | Qt::Key_G, nullptr, nullptr, QAction::PreferencesRole); connect(action, &QAction::triggered, [] { qApp->showDialog(QString("hifi/dialogs/GeneralPreferencesDialog.qml"), QString("hifi/tablet/TabletGeneralPreferences.qml"), "GeneralPreferencesDialog"); }); + // Settings > Controls... + action = addActionToQMenuAndActionHash(settingsMenu, "Controls..."); + connect(action, &QAction::triggered, [] { + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + auto hmd = DependencyManager::get(); + tablet->loadQMLSource("hifi/tablet/ControllerSettings.qml"); + + if (!hmd->getShouldShowTablet()) { + hmd->toggleShouldShowTablet(); + } + }); + + // Settings > Audio... action = addActionToQMenuAndActionHash(settingsMenu, "Audio..."); connect(action, &QAction::triggered, [] { static const QUrl widgetUrl("hifi/dialogs/Audio.qml"); @@ -325,6 +294,13 @@ Menu::Menu() { qApp->showDialog(widgetUrl, tabletUrl, name); }); + // Settings > Graphics... + action = addActionToQMenuAndActionHash(settingsMenu, "Graphics..."); + connect(action, &QAction::triggered, [] { + qApp->showDialog(QString("hifi/dialogs/GraphicsPreferencesDialog.qml"), + QString("hifi/tablet/TabletGraphicsPreferences.qml"), "GraphicsPreferencesDialog"); + }); + // Settings > Avatar... action = addActionToQMenuAndActionHash(settingsMenu, "Avatar..."); connect(action, &QAction::triggered, [] { @@ -332,35 +308,11 @@ Menu::Menu() { QString("hifi/tablet/TabletAvatarPreferences.qml"), "AvatarPreferencesDialog"); }); - // Settings > LOD... - action = addActionToQMenuAndActionHash(settingsMenu, "LOD..."); - connect(action, &QAction::triggered, [] { - qApp->showDialog(QString("hifi/dialogs/LodPreferencesDialog.qml"), - QString("hifi/tablet/TabletLodPreferences.qml"), "LodPreferencesDialog"); - }); + // Settings > Developer Menu + addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menu", 0, false, this, SLOT(toggleDeveloperMenus())); - action = addActionToQMenuAndActionHash(settingsMenu, "Controller Settings..."); - connect(action, &QAction::triggered, [] { - auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); - auto hmd = DependencyManager::get(); - tablet->loadQMLSource("hifi/tablet/ControllerSettings.qml"); - - if (!hmd->getShouldShowTablet()) { - hmd->toggleShouldShowTablet(); - } - }); - - // Settings > Control with Speech [advanced] -#if defined(Q_OS_MAC) || defined(Q_OS_WIN) - auto speechRecognizer = DependencyManager::get(); - QAction* speechRecognizerAction = addCheckableActionToQMenuAndActionHash(settingsMenu, MenuOption::ControlWithSpeech, - Qt::CTRL | Qt::SHIFT | Qt::Key_C, - speechRecognizer->getEnabled(), - speechRecognizer.data(), - SLOT(setEnabled(bool)), - UNSPECIFIED_POSITION, "Advanced"); - connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); -#endif + // Settings > Ask to Reset Settings + addCheckableActionToQMenuAndActionHash(settingsMenu, MenuOption::AskToResetSettings, 0, false); // Developer menu ---------------------------------- MenuWrapper* developerMenu = addMenu("Developer", "Developer"); @@ -408,7 +360,7 @@ Menu::Menu() { if (mainViewShadowTaskConfig) { if (action->isChecked()) { mainViewShadowTaskConfig->setPreset("Enabled"); - } else { + } else { mainViewShadowTaskConfig->setPreset("None"); } } @@ -761,12 +713,8 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowBulletConstraints, 0, false, qApp, SLOT(setShowBulletConstraints(bool))); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowBulletConstraintLimits, 0, false, qApp, SLOT(setShowBulletConstraintLimits(bool))); - // Developer > Ask to Reset Settings - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AskToResetSettings, 0, false); - // Developer > Display Crash Options addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::DisplayCrashOptions, 0, true); - // Developer > Crash >>> MenuWrapper* crashMenu = developerMenu->addMenu("Crash"); @@ -803,6 +751,37 @@ Menu::Menu() { action = addActionToQMenuAndActionHash(crashMenu, MenuOption::CrashNewFaultThreaded); connect(action, &QAction::triggered, qApp, []() { std::thread(crash::newFault).join(); }); + // Developer > Stats + addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats); + + // Settings > Enable Speech Control API +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + auto speechRecognizer = DependencyManager::get(); + QAction* speechRecognizerAction = addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::ControlWithSpeech, + Qt::CTRL | Qt::SHIFT | Qt::Key_C, + speechRecognizer->getEnabled(), + speechRecognizer.data(), + SLOT(setEnabled(bool)), + UNSPECIFIED_POSITION); + connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); +#endif + + // console + addActionToQMenuAndActionHash(developerMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J, + DependencyManager::get().data(), + SLOT(toggleConsole()), + QAction::NoRole, + UNSPECIFIED_POSITION); + + // Developer > API Debugger + action = addActionToQMenuAndActionHash(developerMenu, "API Debugger"); + connect(action, &QAction::triggered, [] { + auto scriptEngines = DependencyManager::get(); + QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation(); + defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/utilities/tools/currentAPI.js"); + scriptEngines->loadScript(defaultScriptsLoc.toString()); + }); + // Developer > Log... addActionToQMenuAndActionHash(developerMenu, MenuOption::Log, Qt::CTRL | Qt::SHIFT | Qt::Key_L, qApp, SLOT(toggleLogDialog())); @@ -817,25 +796,6 @@ Menu::Menu() { action = addActionToQMenuAndActionHash(developerMenu, "Script Log (HMD friendly)...", Qt::NoButton, qApp, SLOT(showScriptLogs())); - // Developer > Stats - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats); - - // Developer > Advanced Settings... - action = addActionToQMenuAndActionHash(developerMenu, "Advanced Preferences..."); - connect(action, &QAction::triggered, [] { - qApp->showDialog(QString("hifi/dialogs/AdvancedPreferencesDialog.qml"), - QString("hifi/tablet/AdvancedPreferencesDialog.qml"), "AdvancedPreferencesDialog"); - }); - - // Developer > API Debugger - action = addActionToQMenuAndActionHash(developerMenu, "API Debugger"); - connect(action, &QAction::triggered, [] { - auto scriptEngines = DependencyManager::get(); - QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation(); - defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/utilities/tools/currentAPI.js"); - scriptEngines->loadScript(defaultScriptsLoc.toString()); - }); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VerboseLogging, 0, false, qApp, SLOT(updateVerboseLogging())); @@ -864,6 +824,51 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true, NULL, NULL, UNSPECIFIED_POSITION, "Advanced"); #endif + + // Help/Application menu ---------------------------------- + MenuWrapper * helpMenu = addMenu("Help"); + + // Help > About High Fidelity + action = addActionToQMenuAndActionHash(helpMenu, "About High Fidelity"); + connect(action, &QAction::triggered, [] { + qApp->showDialog(QString("hifi/dialogs/AboutDialog.qml"), + QString("hifi/dialogs/TabletAboutDialog.qml"), "AboutDialog"); + }); + helpMenu->addSeparator(); + + // Help > HiFi Docs + action = addActionToQMenuAndActionHash(helpMenu, "Online Documentation"); + connect(action, &QAction::triggered, qApp, [] { + QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/")); + }); + + // Help > HiFi Forum + action = addActionToQMenuAndActionHash(helpMenu, "Online Forums"); + connect(action, &QAction::triggered, qApp, [] { + QDesktopServices::openUrl(QUrl("https://forums.highfidelity.com/")); + }); + + // Help > Scripting Reference + action = addActionToQMenuAndActionHash(helpMenu, "Online Script Reference"); + connect(action, &QAction::triggered, qApp, [] { + QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/api-reference")); + }); + + addActionToQMenuAndActionHash(helpMenu, "Controls Reference", 0, qApp, SLOT(showHelp())); + + helpMenu->addSeparator(); + + // Help > Release Notes + action = addActionToQMenuAndActionHash(helpMenu, "Release Notes"); + connect(action, &QAction::triggered, qApp, [] { + QDesktopServices::openUrl(QUrl("http://steamcommunity.com/games/390540/announcements/")); + }); + + // Help > Report a Bug! + action = addActionToQMenuAndActionHash(helpMenu, "Report a Bug!"); + connect(action, &QAction::triggered, qApp, [] { + QDesktopServices::openUrl(QUrl("mailto:support@highfidelity.com")); + }); } void Menu::addMenuItem(const MenuItemProperties& properties) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5ab6468799..8569911cbd 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -32,7 +32,7 @@ namespace MenuOption { const QString AnimDebugDrawAnimPose = "Debug Draw Animation"; const QString AnimDebugDrawDefaultPose = "Debug Draw Default Pose"; const QString AnimDebugDrawPosition= "Debug Draw Position"; - const QString AskToResetSettings = "Ask To Reset Settings"; + const QString AskToResetSettings = "Ask To Reset Settings on Start"; const QString AssetMigration = "ATP Asset Migration"; const QString AssetServer = "Asset Browser"; const QString Attachments = "Attachments..."; @@ -59,7 +59,7 @@ namespace MenuOption { const QString Collisions = "Collisions"; const QString Connexion = "Activate 3D Connexion Devices"; const QString Console = "Console..."; - const QString ControlWithSpeech = "Control With Speech"; + const QString ControlWithSpeech = "Enable Speech Control API"; const QString CopyAddress = "Copy Address to Clipboard"; const QString CopyPath = "Copy Path to Clipboard"; const QString CoupleEyelids = "Couple Eyelids"; @@ -122,7 +122,7 @@ namespace MenuOption { const QString LoadScript = "Open and Run Script File..."; const QString LoadScriptURL = "Open and Run Script from URL..."; const QString LodTools = "LOD Tools"; - const QString Login = "Login / Sign Up"; + const QString Login = "Login/Sign Up"; const QString Log = "Log"; const QString LogExtraTimings = "Log Extra Timing Details"; const QString LowVelocityFilter = "Low Velocity Filter"; @@ -137,8 +137,8 @@ namespace MenuOption { const QString OnlyDisplayTopTen = "Only Display Top Ten"; const QString OpenVrThreadedSubmit = "OpenVR Threaded Submit"; const QString OutputMenu = "Display"; - const QString Overlays = "Overlays"; - const QString PackageModel = "Package Model..."; + const QString Overlays = "Show Overlays"; + const QString PackageModel = "Package Model as .fst..."; const QString Pair = "Pair"; const QString PhysicsShowHulls = "Draw Collision Shapes"; const QString PhysicsShowOwned = "Highlight Simulation Ownership"; @@ -196,7 +196,7 @@ namespace MenuOption { const QString SimulateEyeTracking = "Simulate"; const QString SMIEyeTracking = "SMI Eye Tracking"; const QString SparseTextureManagement = "Enable Sparse Texture Management"; - const QString Stats = "Stats"; + const QString Stats = "Show Statistics"; const QString StopAllScripts = "Stop All Scripts"; const QString SuppressShortTimings = "Suppress Timings Less than 10ms"; const QString ThirdPerson = "Third Person"; @@ -217,6 +217,9 @@ namespace MenuOption { const QString Shadows = "Shadows"; const QString AntiAliasing = "Temporal Antialiasing (FXAA if disabled)"; const QString AmbientOcclusion = "Ambient Occlusion"; + const QString NotificationSounds = "play_notification_sounds"; + const QString NotificationSoundsSnapshot = "play_notification_sounds_snapshot"; + const QString NotificationSoundsTablet = "play_notification_sounds_tablet"; } #endif // hifi_Menu_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6c6f6d4d41..5fb4e80b80 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -67,8 +67,8 @@ using namespace std; const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f; -const float YAW_SPEED_DEFAULT = 75.0f; // degrees/sec -const float PITCH_SPEED_DEFAULT = 50.0f; // degrees/sec +const float YAW_SPEED_DEFAULT = 100.0f; // degrees/sec +const float PITCH_SPEED_DEFAULT = 75.0f; // degrees/sec const float MAX_BOOST_SPEED = 0.5f * DEFAULT_AVATAR_MAX_WALKING_SPEED; // action motor gets additive boost below this speed const float MIN_AVATAR_SPEED = 0.05f; @@ -2246,7 +2246,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { } float boomChange = getDriveKey(ZOOM); - _boomLength += 4.0f * _boomLength * boomChange + boomChange * boomChange; + _boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange; _boomLength = glm::clamp(_boomLength, ZOOM_MIN, ZOOM_MAX); } @@ -2654,7 +2654,6 @@ void MyAvatar::updateMotionBehaviorFromMenu() { } else { _motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; } - setCollisionsEnabled(menu->isOptionChecked(MenuOption::EnableAvatarCollisions)); setProperty("lookAtSnappingEnabled", menu->isOptionChecked(MenuOption::EnableLookAtSnapping)); } diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 63794da60f..fb49c4f4c4 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -86,7 +86,7 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : if (dialogsManager->getLodToolsDialog()) { watchWindow(dialogsManager->getLodToolsDialog()->windowHandle()); } - + connect(_switchModeButton, &QPushButton::clicked, [this]{ toggleHMDMode(); }); diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 71e5293f30..e2f2d9e011 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -130,4 +130,3 @@ void LodToolsDialog::closeEvent(QCloseEvent* event) { #endif } - diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index b2390a1cd7..3ae59661dc 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -52,4 +52,4 @@ private: QLabel* _feedback; }; -#endif // hifi_LodToolsDialog_h +#endif // hifi_LodToolsDialog_h \ No newline at end of file diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 6bb35fde41..3d3c432e92 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "Application.h" @@ -52,33 +53,100 @@ void setupPreferences() { preferences->addPreference(preference); } + // Graphics quality + static const QString GRAPHICS_QUALITY { "Graphics Quality" }; { - auto getter = [=]()->bool { return myAvatar->getSnapTurn(); }; - auto setter = [=](bool value) { myAvatar->setSnapTurn(value); }; - preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Snap turn when in HMD", getter, setter)); - } - { - auto getter = [=]()->bool { return myAvatar->getClearOverlayWhenMoving(); }; - auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); }; - preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when moving", getter, setter)); + static const float MAX_DESKTOP_FPS = 60; + static const float MAX_HMD_FPS = 90; + static const float MIN_FPS = 10; + static const float LOW = 0.25f; + static const float MEDIUM = 0.5f; + static const float HIGH = 0.75f; + auto getter = []()->float { + auto lodManager = DependencyManager::get(); + bool inHMD = qApp->isHMDMode(); + + float increaseFPS = 0; + if (inHMD) { + increaseFPS = lodManager->getHMDLODDecreaseFPS(); + } else { + increaseFPS = lodManager->getDesktopLODDecreaseFPS(); + } + float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; + float percentage = increaseFPS / maxFPS; + + if (percentage >= HIGH) { + return LOW; + } else if (percentage >= LOW) { + return MEDIUM; + } + return HIGH; + }; + + auto setter = [](float value) { + static const float THRASHING_DIFFERENCE = 10; + auto lodManager = DependencyManager::get(); + + bool isLowestValue = value == LOW; + bool isHMDMode = qApp->isHMDMode(); + + float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; + float desiredFPS = maxFPS - THRASHING_DIFFERENCE; + + if (!isLowestValue) { + float calculatedFPS = (maxFPS - (maxFPS * value)) - THRASHING_DIFFERENCE; + desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; + } + + if (isHMDMode) { + lodManager->setHMDLODDecreaseFPS(desiredFPS); + } else { + lodManager->setDesktopLODDecreaseFPS(desiredFPS); + } + }; + + auto wodSlider = new SliderPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); + wodSlider->setMin(0.25f); + wodSlider->setMax(0.75f); + wodSlider->setStep(0.25f); + preferences->addPreference(wodSlider); + + auto getterShadow = []()->bool { + auto menu = Menu::getInstance(); + return menu->isOptionChecked(MenuOption::Shadows); + }; + auto setterShadow = [](bool value) { + auto menu = Menu::getInstance(); + menu->setIsOptionChecked(MenuOption::Shadows, value); + }; + preferences->addPreference(new CheckPreference(GRAPHICS_QUALITY, "Show Shadows", getterShadow, setterShadow)); } // UI - static const QString UI_CATEGORY { "UI" }; + static const QString UI_CATEGORY { "User Interface" }; { auto getter = []()->bool { return qApp->getSettingConstrainToolbarPosition(); }; auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(value); }; preferences->addPreference(new CheckPreference(UI_CATEGORY, "Constrain Toolbar Position to Horizontal Center", getter, setter)); } + { - auto getter = []()->float { return qApp->getHMDTabletScale(); }; - auto setter = [](float value) { qApp->setHMDTabletScale(value); }; - auto preference = new SpinnerPreference(UI_CATEGORY, "HMD Tablet Scale %", getter, setter); + auto getter = []()->float { return qApp->getDesktopTabletScale(); }; + auto setter = [](float value) { qApp->setDesktopTabletScale(value); }; + auto preference = new SpinnerPreference(UI_CATEGORY, "Desktop Tablet Scale %", getter, setter); preference->setMin(20); preference->setMax(500); preferences->addPreference(preference); } + { + auto getter = []()->float { return qApp->getHMDTabletScale(); }; + auto setter = [](float value) { qApp->setHMDTabletScale(value); }; + auto preference = new SpinnerPreference(UI_CATEGORY, "VR Tablet Scale %", getter, setter); + preference->setMin(20); + preference->setMax(500); + preferences->addPreference(preference); + } { auto getter = []()->bool { return qApp->getPreferStylusOverLaser(); }; @@ -86,19 +154,24 @@ void setupPreferences() { preferences->addPreference(new CheckPreference(UI_CATEGORY, "Prefer Stylus Over Laser", getter, setter)); } - static const QString ADVANCED_UI_CATEGORY { "Advanced UI" }; { - auto getter = []()->float { return qApp->getDesktopTabletScale(); }; - auto setter = [](float value) { qApp->setDesktopTabletScale(value); }; - auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Desktop Tablet Scale %", getter, setter); - preference->setMin(20); - preference->setMax(500); - preferences->addPreference(preference); + static const QString RETICLE_ICON_NAME = { Cursor::Manager::getIconName(Cursor::Icon::RETICLE) }; + auto getter = []()->bool { return qApp->getPreferredCursor() == RETICLE_ICON_NAME; }; + auto setter = [](bool value) { qApp->setPreferredCursor(value ? RETICLE_ICON_NAME : QString()); }; + preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter)); } + + { + auto getter = [=]()->bool { return myAvatar->getClearOverlayWhenMoving(); }; + auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); }; + preferences->addPreference(new CheckPreference(UI_CATEGORY, "Clear overlays when moving", getter, setter)); + } + + static const QString VIEW_CATEGORY{ "View" }; { auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); }; auto setter = [=](float value) { myAvatar->setRealWorldFieldOfView(value); }; - auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Real world vertical field of view (angular size of monitor)", getter, setter); + auto preference = new SpinnerPreference(VIEW_CATEGORY, "Real world vertical field of view (angular size of monitor)", getter, setter); preference->setMin(1); preference->setMax(180); preferences->addPreference(preference); @@ -106,7 +179,7 @@ void setupPreferences() { { auto getter = []()->float { return qApp->getFieldOfView(); }; auto setter = [](float value) { qApp->setFieldOfView(value); }; - auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Vertical field of view", getter, setter); + auto preference = new SpinnerPreference(VIEW_CATEGORY, "Vertical field of view", getter, setter); preference->setMin(1); preference->setMax(180); preference->setStep(1); @@ -122,12 +195,6 @@ void setupPreferences() { preferences->addPreference(new CheckPreference(UI_CATEGORY, "Prefer Avatar Finger Over Stylus", getter, setter)); } */ - { - static const QString RETICLE_ICON_NAME = { Cursor::Manager::getIconName(Cursor::Icon::RETICLE) }; - auto getter = []()->bool { return qApp->getPreferredCursor() == RETICLE_ICON_NAME; }; - auto setter = [](bool value) { qApp->setPreferredCursor(value ? RETICLE_ICON_NAME : QString()); }; - preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter)); - } // Snapshots static const QString SNAPSHOTS { "Snapshots" }; @@ -156,27 +223,6 @@ void setupPreferences() { "this information you are helping to improve the product. ", getter, setter)); } - static const QString LOD_TUNING("Level of Detail Tuning"); - { - auto getter = []()->float { return DependencyManager::get()->getDesktopLODDecreaseFPS(); }; - auto setter = [](float value) { DependencyManager::get()->setDesktopLODDecreaseFPS(value); }; - auto preference = new SpinnerPreference(LOD_TUNING, "Minimum desktop FPS", getter, setter); - preference->setMin(0); - preference->setMax(120); - preference->setStep(1); - preferences->addPreference(preference); - } - - { - auto getter = []()->float { return DependencyManager::get()->getHMDLODDecreaseFPS(); }; - auto setter = [](float value) { DependencyManager::get()->setHMDLODDecreaseFPS(value); }; - auto preference = new SpinnerPreference(LOD_TUNING, "Minimum HMD FPS", getter, setter); - preference->setMin(0); - preference->setMax(120); - preference->setStep(1); - preferences->addPreference(preference); - } - static const QString AVATAR_TUNING { "Avatar Tuning" }; { auto getter = [=]()->QString { return myAvatar->getDominantHand(); }; @@ -196,26 +242,7 @@ void setupPreferences() { // which can't be changed across domain switches. Having these values loaded up when you load the Dialog each time // is a way around this, therefore they're not specified here but in the QML. } - { - auto getter = [=]()->float { return myAvatar->getUserHeight(); }; - auto setter = [=](float value) { myAvatar->setUserHeight(value); }; - auto preference = new SpinnerPreference(AVATAR_TUNING, "User height (meters)", getter, setter); - preference->setMin(1.0f); - preference->setMax(2.2f); - preference->setDecimals(3); - preference->setStep(0.001f); - preferences->addPreference(preference); - } - { - auto getter = []()->float { return DependencyManager::get()->getEyeClosingThreshold(); }; - auto setter = [](float value) { DependencyManager::get()->setEyeClosingThreshold(value); }; - preferences->addPreference(new SliderPreference(AVATAR_TUNING, "Camera binary eyelid threshold", getter, setter)); - } - { - auto getter = []()->float { return FaceTracker::getEyeDeflection(); }; - auto setter = [](float value) { FaceTracker::setEyeDeflection(value); }; - preferences->addPreference(new SliderPreference(AVATAR_TUNING, "Face tracker eye deflection", getter, setter)); - } + { auto getter = [=]()->QString { return myAvatar->getAnimGraphOverrideUrl().toString(); }; auto setter = [=](const QString& value) { myAvatar->setAnimGraphOverrideUrl(QUrl(value)); }; @@ -224,11 +251,65 @@ void setupPreferences() { preferences->addPreference(preference); } - static const QString AVATAR_CAMERA { "Avatar Camera" }; + { + auto getter = [=]()->bool { return myAvatar->getCollisionsEnabled(); }; + auto setter = [=](bool value) { myAvatar->setCollisionsEnabled(value); }; + auto preference = new CheckPreference(AVATAR_TUNING, "Enable Avatar collisions", getter, setter); + preferences->addPreference(preference); + } + + static const QString FACE_TRACKING{ "Face Tracking" }; + { + auto getter = []()->float { return DependencyManager::get()->getEyeClosingThreshold(); }; + auto setter = [](float value) { DependencyManager::get()->setEyeClosingThreshold(value); }; + preferences->addPreference(new SliderPreference(FACE_TRACKING, "Eye Closing Threshold", getter, setter)); + } + { + auto getter = []()->float { return FaceTracker::getEyeDeflection(); }; + auto setter = [](float value) { FaceTracker::setEyeDeflection(value); }; + preferences->addPreference(new SliderPreference(FACE_TRACKING, "Eye Deflection", getter, setter)); + } + + static const QString MOVEMENT{ "VR Movement" }; + { + + static const QString movementsControlChannel = QStringLiteral("Hifi-Advanced-Movement-Disabler"); + auto getter = [=]()->bool { return myAvatar->useAdvancedMovementControls(); }; + auto setter = [=](bool value) { myAvatar->setUseAdvancedMovementControls(value); }; + preferences->addPreference(new CheckPreference(MOVEMENT, + QStringLiteral("Advanced movement for hand controllers"), + getter, setter)); + } + { + auto getter = [=]()->bool { return myAvatar->getFlyingEnabled(); }; + auto setter = [=](bool value) { myAvatar->setFlyingEnabled(value); }; + preferences->addPreference(new CheckPreference(MOVEMENT, "Flying & jumping", getter, setter)); + } + { + auto getter = [=]()->int { return myAvatar->getSnapTurn() ? 0 : 1; }; + auto setter = [=](int value) { myAvatar->setSnapTurn(value == 0); }; + auto preference = new RadioButtonsPreference(MOVEMENT, "Snap turn / Smooth turn", getter, setter); + QStringList items; + items << "Snap turn" << "Smooth turn"; + preference->setItems(items); + preferences->addPreference(preference); + } + { + auto getter = [=]()->float { return myAvatar->getUserHeight(); }; + auto setter = [=](float value) { myAvatar->setUserHeight(value); }; + auto preference = new SpinnerPreference(MOVEMENT, "User real-world height (meters)", getter, setter); + preference->setMin(1.0f); + preference->setMax(2.2f); + preference->setDecimals(3); + preference->setStep(0.001f); + preferences->addPreference(preference); + } + + static const QString AVATAR_CAMERA{ "Mouse Sensitivity" }; { auto getter = [=]()->float { return myAvatar->getPitchSpeed(); }; auto setter = [=](float value) { myAvatar->setPitchSpeed(value); }; - auto preference = new SpinnerPreference(AVATAR_CAMERA, "Camera pitch speed (degrees/second)", getter, setter); + auto preference = new SpinnerPreference(AVATAR_CAMERA, "Pitch speed (degrees/second)", getter, setter); preference->setMin(1.0f); preference->setMax(360.0f); preferences->addPreference(preference); @@ -236,7 +317,7 @@ void setupPreferences() { { auto getter = [=]()->float { return myAvatar->getYawSpeed(); }; auto setter = [=](float value) { myAvatar->setYawSpeed(value); }; - auto preference = new SpinnerPreference(AVATAR_CAMERA, "Camera yaw speed (degrees/second)", getter, setter); + auto preference = new SpinnerPreference(AVATAR_CAMERA, "Yaw speed (degrees/second)", getter, setter); preference->setMin(1.0f); preference->setMax(360.0f); preferences->addPreference(preference); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index fcdac8c00c..c678e3d2a2 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -56,6 +56,8 @@ #include "ui/Snapshot.h" #include "SoundCache.h" #include "raypick/PointerScriptingInterface.h" +#include +#include "AboutUtil.h" static int MAX_WINDOW_SIZE = 4096; static const float METERS_TO_INCHES = 39.3701f; @@ -256,6 +258,9 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("Pointers", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("Web3DOverlay", this); _webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface()); + _webSurface->getSurfaceContext()->setContextProperty("desktop", DependencyManager::get()->getDesktop()); + _webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance()); // Override min fps for tablet UI, for silky smooth scrolling setMaxFPS(90); diff --git a/libraries/shared/src/Preferences.h b/libraries/shared/src/Preferences.h index 76d61fe3f6..931508e825 100644 --- a/libraries/shared/src/Preferences.h +++ b/libraries/shared/src/Preferences.h @@ -58,7 +58,8 @@ public: ComboBox, PrimaryHand, // Special casing for an unusual preference - Avatar + Avatar, + RadioButtons }; explicit Preference(QObject* parent = nullptr) : QObject(parent) {} @@ -353,6 +354,20 @@ public: Type getType() override { return PrimaryHand; } }; +class RadioButtonsPreference : public IntPreference { + Q_OBJECT + Q_PROPERTY(QStringList items READ getItems CONSTANT) +public: + RadioButtonsPreference(const QString& category, const QString& name, Getter getter, Setter setter) + : IntPreference(category, name, getter, setter) { } + Type getType() override { return RadioButtons; } + + const QStringList& getItems() { return _items; } + void setItems(const QStringList& items) { _items = items; } + +protected: + QStringList _items; +}; #endif diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index a079609bb7..9070d87a3c 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -441,7 +441,11 @@ void TabletProxy::emitWebEvent(const QVariant& msg) { void TabletProxy::onTabletShown() { if (_tabletShown) { - static_cast(parent())->playSound(TabletScriptingInterface::TabletOpen); + Setting::Handle notificationSounds{ QStringLiteral("play_notification_sounds"), true}; + Setting::Handle notificationSoundTablet{ QStringLiteral("play_notification_sounds_tablet"), true}; + if (notificationSounds.get() && notificationSoundTablet.get()) { + dynamic_cast(parent())->playSound(TabletScriptingInterface::TabletOpen); + } if (_showRunningScripts) { _showRunningScripts = false; pushOntoStack("hifi/dialogs/TabletRunningScripts.qml"); diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 71755e3abb..b0cbf0e246 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -19,14 +19,12 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/menu.js", "system/bubble.js", "system/snapshot.js", - "system/help.js", "system/pal.js", // "system/mod.js", // older UX, if you prefer "system/makeUserConnection.js", "system/tablet-goto.js", "system/marketplaces/marketplaces.js", "system/commerce/wallet.js", "system/edit.js", - "system/notifications.js", "system/dialTone.js", "system/firstPersonHMD.js", "system/tablet-ui/tabletUI.js", diff --git a/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js b/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js index e6c9b0aee0..a1b96ac607 100644 --- a/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js +++ b/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js @@ -11,156 +11,164 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/* jslint bitwise: true */ + +/* global Script, Quat, MyAvatar, HMD, Controller, Messages*/ + (function() { // BEGIN LOCAL_SCOPE -var mappingName, basicMapping, isChecked; + var TWO_SECONDS_INTERVAL = 2000; + var FLYING_MAPPING_NAME = 'Hifi-Flying-Dev-' + Math.random(); + var DRIVING_MAPPING_NAME = 'Hifi-Driving-Dev-' + Math.random(); -var TURN_RATE = 1000; -var MENU_ITEM_NAME = "Advanced Movement For Hand Controllers"; -var isDisabled = false; -var previousSetting = MyAvatar.useAdvancedMovementControls; -if (previousSetting === false) { - previousSetting = false; - isChecked = false; -} + var flyingMapping = null; + var drivingMapping = null; -if (previousSetting === true) { - previousSetting = true; - isChecked = true; -} + var TURN_RATE = 1000; + var isDisabled = false; -function addAdvancedMovementItemToSettingsMenu() { - Menu.addMenuItem({ - menuName: "Settings", - menuItemName: MENU_ITEM_NAME, - isCheckable: true, - isChecked: previousSetting - }); -} + var previousFlyingState = MyAvatar.getFlyingEnabled(); + var previousDrivingState = MyAvatar.useAdvancedMovementControls; -function rotate180() { - var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.angleAxis(180, { - x: 0, - y: 1, - z: 0 - })) - MyAvatar.orientation = newOrientation -} + function rotate180() { + var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.angleAxis(180, { + x: 0, + y: 1, + z: 0 + })); + MyAvatar.orientation = newOrientation; + } -var inFlipTurn = false; + var inFlipTurn = false; -function registerBasicMapping() { - mappingName = 'Hifi-AdvancedMovement-Dev-' + Math.random(); - basicMapping = Controller.newMapping(mappingName); - basicMapping.from(Controller.Standard.LY).to(function(value) { - if (isDisabled) { - return; - } - var stick = Controller.getValue(Controller.Standard.LS); - if (value === 1 && Controller.Hardware.OculusTouch !== undefined) { - rotate180(); - } else if (Controller.Hardware.Vive !== undefined) { - if (value > 0.75 && inFlipTurn === false) { - inFlipTurn = true; + function registerBasicMapping() { + + drivingMapping = Controller.newMapping(DRIVING_MAPPING_NAME); + drivingMapping.from(Controller.Standard.LY).to(function(value) { + if (isDisabled) { + return; + } + + if (value === 1 && Controller.Hardware.OculusTouch !== undefined) { rotate180(); - Script.setTimeout(function() { - inFlipTurn = false; - }, TURN_RATE) + } else if (Controller.Hardware.Vive !== undefined) { + if (value > 0.75 && inFlipTurn === false) { + inFlipTurn = true; + rotate180(); + Script.setTimeout(function() { + inFlipTurn = false; + }, TURN_RATE); + } } - } - return; - }); - basicMapping.from(Controller.Standard.RY).to(function(value) { - if (isDisabled) { return; - } - var stick = Controller.getValue(Controller.Standard.RS); - if (value === 1 && Controller.Hardware.OculusTouch !== undefined) { - rotate180(); - } else if (Controller.Hardware.Vive !== undefined) { - if (value > 0.75 && inFlipTurn === false) { - inFlipTurn = true; + }); + + flyingMapping = Controller.newMapping(FLYING_MAPPING_NAME); + flyingMapping.from(Controller.Standard.RY).to(function(value) { + if (isDisabled) { + return; + } + + if (value === 1 && Controller.Hardware.OculusTouch !== undefined) { rotate180(); - Script.setTimeout(function() { - inFlipTurn = false; - }, TURN_RATE) + } else if (Controller.Hardware.Vive !== undefined) { + if (value > 0.75 && inFlipTurn === false) { + inFlipTurn = true; + rotate180(); + Script.setTimeout(function() { + inFlipTurn = false; + }, TURN_RATE); + } + } + return; + }); + } + + function scriptEnding() { + Controller.disableMapping(FLYING_MAPPING_NAME); + Controller.disableMapping(DRIVING_MAPPING_NAME); + } + + Script.scriptEnding.connect(scriptEnding); + + registerBasicMapping(); + + Script.setTimeout(function() { + if (MyAvatar.useAdvanceMovementControls) { + Controller.disableMapping(DRIVING_MAPPING_NAME); + } else { + Controller.enableMapping(DRIVING_MAPPING_NAME); + } + + if (MyAvatar.getFyingEnabled()) { + Controller.disableMapping(FLYING_MAPPING_NAME); + } else { + Controller.enableMapping(FLYING_MAPPING_NAME); + } + }, 100); + + + HMD.displayModeChanged.connect(function(isHMDMode) { + if (isHMDMode) { + if (Controller.Hardware.Vive !== undefined || Controller.Hardware.OculusTouch !== undefined) { + if (MyAvatar.useAdvancedMovementControls) { + Controller.disableMapping(DRIVING_MAPPING_NAME); + } else { + Controller.enableMapping(DRIVING_MAPPING_NAME); + } + + if (MyAvatar.getFlyingEnabled()) { + Controller.disableMapping(FLYING_MAPPING_NAME); + } else { + Controller.enableMapping(FLYING_MAPPING_NAME); + } + } } - return; - }) -} + }); -function enableMappings() { - Controller.enableMapping(mappingName); -} + function update() { + if ((Controller.Hardware.Vive !== undefined || Controller.Hardware.OculusTouch !== undefined) && HMD.active) { + var flying = MyAvatar.getFlyingEnabled(); + var driving = MyAvatar.useAdvancedMovementControls; -function disableMappings() { - Controller.disableMapping(mappingName); -} + if (flying !== previousFlyingState) { + if (flying) { + Controller.disableMapping(FLYING_MAPPING_NAME); + } else { + Controller.enableMapping(FLYING_MAPPING_NAME); + } -function scriptEnding() { - Menu.removeMenuItem("Settings", MENU_ITEM_NAME); - disableMappings(); -} - - -function menuItemEvent(menuItem) { - if (menuItem == MENU_ITEM_NAME) { - isChecked = Menu.isOptionChecked(MENU_ITEM_NAME); - if (isChecked === true) { - MyAvatar.useAdvancedMovementControls = true; - disableMappings(); - } else if (isChecked === false) { - MyAvatar.useAdvancedMovementControls = false; - enableMappings(); - } - } -} - -addAdvancedMovementItemToSettingsMenu(); - -Script.scriptEnding.connect(scriptEnding); - -Menu.menuItemEvent.connect(menuItemEvent); - -registerBasicMapping(); - -Script.setTimeout(function() { - if (previousSetting === true) { - disableMappings(); - } else { - enableMappings(); - } -}, 100) - - -HMD.displayModeChanged.connect(function(isHMDMode) { - if (isHMDMode) { - if (Controller.Hardware.Vive !== undefined || Controller.Hardware.OculusTouch !== undefined) { - if (isChecked === true) { - disableMappings(); - } else if (isChecked === false) { - enableMappings(); + previousFlyingState = flying; } + if (driving !== previousDrivingState) { + if (driving) { + Controller.disableMapping(DRIVING_MAPPING_NAME); + } else { + Controller.enableMapping(DRIVING_MAPPING_NAME); + } + previousDrivingState = driving; + } + } + Script.setTimeout(update, TWO_SECONDS_INTERVAL); + } + + Script.setTimeout(update, TWO_SECONDS_INTERVAL); + + var HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL = 'Hifi-Advanced-Movement-Disabler'; + function handleMessage(channel, message, sender) { + if (channel === HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL) { + if (message === 'disable') { + isDisabled = true; + } else if (message === 'enable') { + isDisabled = false; + } } } -}); - -var HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL = 'Hifi-Advanced-Movement-Disabler'; -function handleMessage(channel, message, sender) { - if (channel == HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL) { - if (message == 'disable') { - isDisabled = true; - } else if (message == 'enable') { - isDisabled = false; - } - } -} - -Messages.subscribe(HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL); -Messages.messageReceived.connect(handleMessage); + Messages.subscribe(HIFI_ADVANCED_MOVEMENT_DISABLER_CHANNEL); + Messages.messageReceived.connect(handleMessage); }()); // END LOCAL_SCOPE diff --git a/scripts/system/edit.js b/scripts/system/edit.js index c0ba90e612..f549c7dd85 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1148,8 +1148,7 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "Edit", menuItemName: "Entities", - isSeparator: true, - grouping: "Advanced" + isSeparator: true }); if (!Menu.menuItemExists("Edit", "Delete")) { Menu.addMenuItem({ @@ -1159,7 +1158,6 @@ function setupModelMenus() { text: "delete" }, afterItem: "Entities", - grouping: "Advanced" }); modelMenuAddedDelete = true; } @@ -1167,15 +1165,13 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "Edit", menuItemName: "Parent Entity to Last", - afterItem: "Entities", - grouping: "Advanced" + afterItem: "Entities" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Unparent Entity", - afterItem: "Parent Entity to Last", - grouping: "Advanced" + afterItem: "Parent Entity to Last" }); Menu.addMenuItem({ @@ -1183,8 +1179,7 @@ function setupModelMenus() { menuItemName: MENU_CREATE_ENTITIES_GRABBABLE, afterItem: "Unparent Entity", isCheckable: true, - isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, true), - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, true) }); Menu.addMenuItem({ @@ -1192,87 +1187,75 @@ function setupModelMenus() { menuItemName: MENU_ALLOW_SELECTION_LARGE, afterItem: MENU_CREATE_ENTITIES_GRABBABLE, isCheckable: true, - isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, true), - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, true) }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_ALLOW_SELECTION_SMALL, afterItem: MENU_ALLOW_SELECTION_LARGE, isCheckable: true, - isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, true), - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, true) }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_ALLOW_SELECTION_LIGHTS, afterItem: MENU_ALLOW_SELECTION_SMALL, isCheckable: true, - isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, false), - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, false) }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities In Box", - afterItem: "Allow Selecting of Lights", - grouping: "Advanced" + afterItem: "Allow Selecting of Lights" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities Touching Box", - afterItem: "Select All Entities In Box", - grouping: "Advanced" + afterItem: "Select All Entities In Box" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Export Entities", - afterItem: "Entities", - grouping: "Advanced" + afterItem: "Entities" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Import Entities", - afterItem: "Export Entities", - grouping: "Advanced" + afterItem: "Export Entities" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Import Entities from URL", - afterItem: "Import Entities", - grouping: "Advanced" + afterItem: "Import Entities" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, - isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) === "true", - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) === "true" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, - isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) === "true", - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) === "true" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, afterItem: MENU_EASE_ON_FOCUS, isCheckable: true, - isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false", - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, afterItem: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, isCheckable: true, - isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false", - grouping: "Advanced" + isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false" }); Entities.setLightsArePickable(false); diff --git a/scripts/system/libraries/accountUtils.js b/scripts/system/libraries/accountUtils.js index 69092b30fc..9f0d690a5f 100644 --- a/scripts/system/libraries/accountUtils.js +++ b/scripts/system/libraries/accountUtils.js @@ -8,7 +8,7 @@ openLoginWindow = function openLoginWindow() { if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar", false)) || (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar", true))) { - Menu.triggerOption("Login / Sign Up"); + Menu.triggerOption("Login/Sign Up"); } else { tablet.loadQMLOnTop("dialogs/TabletLoginDialog.qml"); HMD.openTablet(); diff --git a/scripts/system/menu.js b/scripts/system/menu.js index c27dae6780..d669d3d918 100644 --- a/scripts/system/menu.js +++ b/scripts/system/menu.js @@ -9,17 +9,29 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/* jslint bitwise: true */ + +/* global Script, HMD, Tablet, Entities */ + var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png"; // var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png"; (function() { - var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - var button = tablet.addButton({ + var lastHMDStatus = false; + var buttonProperties = { icon: "icons/tablet-icons/menu-i.svg", activeIcon: "icons/tablet-icons/menu-a.svg", text: "MENU", sortOrder: 3 - }); + }; + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = null; + + if (HMD.active) { + button = tablet.addButton(buttonProperties); + button.clicked.connect(onClicked); + lastHMDStatus = true; + } var onMenuScreen = false; @@ -35,19 +47,37 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- } } + HMD.displayModeChanged.connect(function(isHMDMode) { + if (lastHMDStatus !== isHMDMode) { + if (isHMDMode) { + button = tablet.addButton(buttonProperties); + button.clicked.connect(onClicked); + } else if (button) { + button.clicked.disconnect(onClicked); + tablet.removeButton(button); + button = null; + } + lastHMDStatus = isHMDMode; + } + }); + function onScreenChanged(type, url) { onMenuScreen = type === "Menu"; - button.editProperties({isActive: onMenuScreen}); + if (button) { + button.editProperties({isActive: onMenuScreen}); + } } - button.clicked.connect(onClicked); tablet.screenChanged.connect(onScreenChanged); Script.scriptEnding.connect(function () { if (onMenuScreen) { tablet.gotoHomeScreen(); } - button.clicked.disconnect(onClicked); + + if (button) { + button.clicked.disconnect(onClicked); + } tablet.removeButton(button); tablet.screenChanged.disconnect(onScreenChanged); }); diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 5690c91c76..29089e6597 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -450,7 +450,7 @@ function takeSnapshot() { maybeDeleteSnapshotStories(); // update button states - resetOverlays = Menu.isOptionChecked("Overlays"); // For completeness. Certainly true if the button is visible to be clicked. + resetOverlays = Menu.isOptionChecked("Show Overlays"); // For completeness. Certainly true if the button is visible to be clicked. reticleVisible = Reticle.visible; Reticle.visible = false; if (!HMD.active) { @@ -470,7 +470,7 @@ function takeSnapshot() { // hide overlays if they are on if (resetOverlays) { - Menu.setIsOptionChecked("Overlays", false); + Menu.setIsOptionChecked("Show Overlays", false); } var snapActivateSound = SoundCache.getSound(Script.resourcesPath() + "sounds/snapshot/snap.wav"); @@ -527,7 +527,7 @@ function stillSnapshotTaken(pathStillSnapshot, notify) { Reticle.allowMouseCapture = true; // show overlays if they were on if (resetOverlays) { - Menu.setIsOptionChecked("Overlays", true); + Menu.setIsOptionChecked("Show Overlays", true); } Window.stillSnapshotTaken.disconnect(stillSnapshotTaken); if (!buttonConnected) { @@ -583,7 +583,7 @@ function processingGifStarted(pathStillSnapshot) { Reticle.allowMouseCapture = true; // show overlays if they were on if (resetOverlays) { - Menu.setIsOptionChecked("Overlays", true); + Menu.setIsOptionChecked("Show Overlays", true); } Settings.setValue("previousStillSnapPath", pathStillSnapshot); diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 9c994ed2ea..7afc9b30f4 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -12,9 +12,9 @@ Script.include("/~/system/libraries/utils.js"); if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position){ - position = position || 0; - return this.substr(position, searchString.length) === searchString; - }; + position = position || 0; + return this.substr(position, searchString.length) === searchString; + }; } var SETTING_KEY = "com.highfidelity.avatar.isSitting"; @@ -122,10 +122,20 @@ this.rolesToOverride = function() { return MyAvatar.getAnimationRoles().filter(function(role) { - return !(role.startsWith("right") || role.startsWith("left")); + return !(role.startsWith("right") || role.startsWith("left")); }); } + // Handler for user changing the avatar model while sitting. There's currently an issue with changing avatar models while override role animations are applied, + // so to avoid that problem, re-apply the role overrides once the model has finished changing. + this.modelURLChangeFinished = function () { + print("Sitter's model has FINISHED changing. Reapply anim role overrides."); + var roles = this.rolesToOverride(); + for (i in roles) { + MyAvatar.overrideRoleAnimation(roles[i], ANIMATION_URL, ANIMATION_FPS, true, ANIMATION_FIRST_FRAME, ANIMATION_LAST_FRAME); + } + } + this.sitDown = function() { if (this.checkSeatForAvatar()) { print("Someone is already sitting in that chair."); @@ -164,12 +174,14 @@ return { headType: 0 }; }, ["headType"]); Script.update.connect(this, this.update); + MyAvatar.onLoadComplete.connect(this, this.modelURLChangeFinished); } this.standUp = function() { print("Standing up (" + this.entityID + ")"); MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); + MyAvatar.onLoadComplete.disconnect(this, this.modelURLChangeFinished); if (MyAvatar.sessionUUID === this.getSeatUser()) { this.setSeatUser(null); @@ -331,7 +343,7 @@ } this.cleanupOverlay(); } - + this.clickDownOnEntity = function (id, event) { if (isInEditMode()) { return; @@ -340,4 +352,4 @@ this.sitDown(); } } -}); \ No newline at end of file +}); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bc11580979..37ca85a282 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,3 @@ - -# Turn on testing (so that add_test works) -enable_testing() - # add the test directories file(GLOB TEST_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM TEST_SUBDIRS "CMakeFiles" "mocha") diff --git a/tests/QTestExtensions.h b/tests/QTestExtensions.h index ac037d831b..c9235eeedb 100644 --- a/tests/QTestExtensions.h +++ b/tests/QTestExtensions.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "GLMTestUtils.h" // Implements several extensions to QtTest. @@ -37,7 +38,6 @@ // from scratch using QTest::qFail, for example). // - float getErrorDifference(const float& a, const float& b) { return fabsf(a - b); } @@ -69,7 +69,7 @@ QString QTest_generateCompareFailureMessage ( QString pad2 = QString(")").rightJustified(pad2_, ' '); QString msg; - QTextStream stream (&msg); + QTextStream stream(&msg); stream << failMessage << "\n\t" "Actual: (" << actual_expr << pad1 << ": " << actual << "\n\t" "Expected: (" << expected_expr << pad2 << ": " << expected << "\n\t"; @@ -100,7 +100,7 @@ QString QTest_generateCompareFailureMessage ( QString pad2 = QString("): ").rightJustified(pad2_, ' '); QString msg; - QTextStream stream (&msg); + QTextStream stream(&msg); stream << failMessage << "\n\t" "Actual: (" << actual_expr << pad1 << actual << "\n\t" "Expected: (" << expected_expr << pad2 << expected; @@ -134,10 +134,10 @@ void QTest_failWithCustomMessage ( // QFAIL_WITH_MESSAGE("Message " << thing << ";"); // } // -#define QFAIL_WITH_MESSAGE(...) \ -do { \ - QTest_failWithCustomMessage([&](QTextStream& stream) { stream << __VA_ARGS__; }, __LINE__, __FILE__); \ - return; \ +#define QFAIL_WITH_MESSAGE(...) \ +do { \ + QTest_failWithCustomMessage([&](QTextStream& stream) { stream << __VA_ARGS__; }, __LINE__, __FILE__); \ + return; \ } while(0) // Calls qFail using QTest_generateCompareFailureMessage. @@ -181,7 +181,7 @@ bool QTest_compareWithAbsError( actual, expected, actual_expr, expected_expr, line, file, [&] (QTextStream& stream) -> QTextStream& { return stream << "Err tolerance: " << getErrorDifference((actual), (expected)) << " > " << epsilon; - }); + }); return false; } return true; @@ -200,10 +200,10 @@ bool QTest_compareWithAbsError( // return stream << "glm::vec3 { " << v.x << ", " << v.y << ", " << v.z << " }" // } // -#define QCOMPARE_WITH_ABS_ERROR(actual, expected, epsilon) \ -do { \ - if (!QTest_compareWithAbsError((actual), (expected), #actual, #expected, __LINE__, __FILE__, epsilon)) \ - return; \ +#define QCOMPARE_WITH_ABS_ERROR(actual, expected, epsilon) \ +do { \ + if (!QTest_compareWithAbsError((actual), (expected), #actual, #expected, __LINE__, __FILE__, epsilon)) \ + return; \ } while(0) // Implements QCOMPARE using an explicit, externally defined test function. @@ -212,12 +212,12 @@ do { \ // // testFunc(const T & actual, const T & expected) -> bool: true (test succeeds) | false (test fails) // -#define QCOMPARE_WITH_FUNCTION(actual, expected, testFunc) \ -do { \ - if (!(testFunc((actual), (expected)))) { \ +#define QCOMPARE_WITH_FUNCTION(actual, expected, testFunc) \ +do { \ + if (!(testFunc((actual), (expected)))) { \ QTest_failWithMessage("Compared values are not the same", (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ - return; \ - } \ + return; \ + } \ } while (0) // Implements QCOMPARE using an explicit, externally defined test function. @@ -230,41 +230,40 @@ do { \ // }); // (fails if foo is not as fooish as expectedFoo) // -#define QCOMPARE_WITH_LAMBDA(actual, expected, testClosure) \ -do { \ - if (!(testClosure())) { \ +#define QCOMPARE_WITH_LAMBDA(actual, expected, testClosure) \ +do { \ + if (!(testClosure())) { \ QTest_failWithMessage("Compared values are not the same", (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ - return; \ - } \ + return; \ + } \ } while (0) // Same as QCOMPARE_WITH_FUNCTION, but with a custom fail message -#define QCOMPARE_WITH_FUNCTION_AND_MESSAGE(actual, expected, testfunc, failMessage) \ -do { \ - if (!(testFunc((actual), (expected)))) { \ - QTest_failWithMessage((failMessage), (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ - return; \ - } \ +#define QCOMPARE_WITH_FUNCTION_AND_MESSAGE(actual, expected, testfunc, failMessage) \ +do { \ + if (!(testFunc((actual), (expected)))) { \ + QTest_failWithMessage((failMessage), (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ + return; \ + } \ } while (0) // Same as QCOMPARE_WITH_FUNCTION, but with a custom fail message -#define QCOMPARE_WITH_LAMBDA_AND_MESSAGE(actual, expected, testClosure, failMessage) \ -do { \ - if (!(testClosure())) { \ - QTest_failWithMessage((failMessage), (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ - return; \ - } \ +#define QCOMPARE_WITH_LAMBDA_AND_MESSAGE(actual, expected, testClosure, failMessage) \ +do { \ + if (!(testClosure())) { \ + QTest_failWithMessage((failMessage), (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ + return; \ + } \ } while (0) #endif -#define QCOMPARE_WITH_EXPR(actual, expected, testExpr) \ - do { \ - if (!(testExpr)) { \ +#define QCOMPARE_WITH_EXPR(actual, expected, testExpr) \ + do { \ + if (!(testExpr)) { \ QTest_failWithMessage("Compared values are not the same", (actual), (expected), #actual, #expected, __LINE__, __FILE__); \ - } \ - } while(0) - + } \ + } while (0) struct ByteData { ByteData (const char* data, size_t length) @@ -273,25 +272,24 @@ struct ByteData { size_t length; }; -QTextStream & operator << (QTextStream& stream, const ByteData & wrapper) { +QTextStream& operator<<(QTextStream& stream, const ByteData& wrapper) { // Print bytes as hex stream << QByteArray::fromRawData(wrapper.data, (int)wrapper.length).toHex(); return stream; } -bool compareData (const char* data, const char* expectedData, size_t length) { +bool compareData(const char* data, const char* expectedData, size_t length) { return memcmp(data, expectedData, length) == 0; } #define COMPARE_DATA(actual, expected, length) \ - QCOMPARE_WITH_EXPR((ByteData ( actual, length )), (ByteData ( expected, length )), compareData(actual, expected, length)) - + QCOMPARE_WITH_EXPR((ByteData(actual, length)), (ByteData(expected, length)), compareData(actual, expected, length)) // Produces a relative error test for float usable QCOMPARE_WITH_LAMBDA. inline auto errorTest (float actual, float expected, float acceptableRelativeError) -> std::function { - return [actual, expected, acceptableRelativeError] () { + return [actual, expected, acceptableRelativeError]() { if (fabsf(expected) <= acceptableRelativeError) { return fabsf(actual - expected) < fabsf(acceptableRelativeError); } @@ -302,18 +300,16 @@ inline auto errorTest (float actual, float expected, float acceptableRelativeErr #define QCOMPARE_WITH_RELATIVE_ERROR(actual, expected, relativeError) \ QCOMPARE_WITH_LAMBDA(actual, expected, errorTest(actual, expected, relativeError)) - - inline QString getTestResource(const QString& relativePath) { static QDir dir; static std::once_flag once; - std::call_once(once, []{ + std::call_once(once, [] { QFileInfo fileInfo(__FILE__); auto parentDir = fileInfo.absoluteDir(); auto rootDir = parentDir.absoluteFilePath(".."); - dir = QDir::cleanPath(rootDir); + dir = QDir::cleanPath(rootDir); }); - + return QDir::cleanPath(dir.absoluteFilePath(relativePath)); } diff --git a/tests/animation/src/AnimTests.cpp b/tests/animation/src/AnimTests.cpp index 432129594a..d758cc7a27 100644 --- a/tests/animation/src/AnimTests.cpp +++ b/tests/animation/src/AnimTests.cpp @@ -24,7 +24,7 @@ QTEST_MAIN(AnimTests) -const float EPSILON = 0.001f; +const float TEST_EPSILON = 0.001f; void AnimTests::initTestCase() { DependencyManager::registerInheritance(); @@ -86,12 +86,12 @@ void AnimTests::testClipEvaulate() { AnimNode::Triggers triggers; clip.evaluate(vars, context, framesToSec(10.0f), triggers); - QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, EPSILON); + QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, TEST_EPSILON); // does it loop? triggers.clear(); clip.evaluate(vars, context, framesToSec(12.0f), triggers); - QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, EPSILON); // Note: frame 3 and not 4, because extra frame between start and end. + QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, TEST_EPSILON); // Note: frame 3 and not 4, because extra frame between start and end. // did we receive a loop trigger? QVERIFY(std::find(triggers.begin(), triggers.end(), "myClipNodeOnLoop") != triggers.end()); @@ -100,7 +100,7 @@ void AnimTests::testClipEvaulate() { triggers.clear(); clip.setLoopFlagVar("FalseVar"); clip.evaluate(vars, context, framesToSec(20.0f), triggers); - QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, EPSILON); + QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, TEST_EPSILON); // did we receive a done trigger? QVERIFY(std::find(triggers.begin(), triggers.end(), "myClipNodeOnDone") != triggers.end()); @@ -402,7 +402,7 @@ void AnimTests::testAnimPose() { glm::vec3(10.0f, 5.0f, -7.5f) }; - const float EPSILON = 0.001f; + const float TEST_EPSILON = 0.001f; for (auto& scale : scaleVec) { for (auto& rot : rotVec) { @@ -417,7 +417,7 @@ void AnimTests::testAnimPose() { AnimPose pose(scale, rot, trans); glm::mat4 poseMat = pose; - QCOMPARE_WITH_ABS_ERROR(rawMat, poseMat, EPSILON); + QCOMPARE_WITH_ABS_ERROR(rawMat, poseMat, TEST_EPSILON); } } } @@ -437,7 +437,7 @@ void AnimTests::testAnimPose() { // now build a new matrix from those parts. glm::mat4 poseMat = pose; - QCOMPARE_WITH_ABS_ERROR(rawMat, poseMat, EPSILON); + QCOMPARE_WITH_ABS_ERROR(rawMat, poseMat, TEST_EPSILON); } } } diff --git a/tests/shared/src/TransformTests.cpp b/tests/shared/src/TransformTests.cpp index ca55bbf873..085d02fd0f 100644 --- a/tests/shared/src/TransformTests.cpp +++ b/tests/shared/src/TransformTests.cpp @@ -29,7 +29,7 @@ const quat rot90 = glm::angleAxis((float)M_PI / 2.0f, yAxis); QTEST_MAIN(TransformTests) -const float EPSILON = 0.001f; +const float TEST_EPSILON = 0.001f; void TransformTests::getMatrix() { @@ -55,7 +55,7 @@ void TransformTests::getMatrix() { mat4 result_b; xform.getMatrix(result_b); - QCOMPARE_WITH_ABS_ERROR(result_a, result_b, EPSILON); + QCOMPARE_WITH_ABS_ERROR(result_a, result_b, TEST_EPSILON); } void TransformTests::getInverseMatrix() { @@ -92,7 +92,7 @@ void TransformTests::getInverseMatrix() { auto yb = transformPoint(result_b, yAxis); auto zb = transformPoint(result_b, zAxis); - QCOMPARE_WITH_ABS_ERROR(xa, xb, EPSILON); - QCOMPARE_WITH_ABS_ERROR(ya, yb, EPSILON); - QCOMPARE_WITH_ABS_ERROR(za, zb, EPSILON); + QCOMPARE_WITH_ABS_ERROR(xa, xb, TEST_EPSILON); + QCOMPARE_WITH_ABS_ERROR(ya, yb, TEST_EPSILON); + QCOMPARE_WITH_ABS_ERROR(za, zb, TEST_EPSILON); }