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);
}