Merge pull request #12895 from vladest/menu-updates

Menu Cleanup and Reorganization
This commit is contained in:
John Conklin II 2018-05-22 13:21:08 -07:00 committed by GitHub
commit 52a05680e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 1258 additions and 642 deletions

View file

@ -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)

View file

@ -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@";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -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.

View file

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

View file

@ -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"

View file

@ -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
}
}
}
}

View file

@ -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) {

View file

@ -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

View file

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

View file

@ -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
}
}

View file

@ -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

View file

@ -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

View file

@ -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
}
}

View file

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

View file

@ -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: "<a href=\"https:/www.highfidelity.com\">www.highfidelity.com</a>."
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 <a href=\"https://elementsproject.org/elements/\">Elements</a>."
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 <a href=\"http://www.apache.org/licenses/LICENSE-2.0.html\">Apache License, Version 2.0.</a>."
size: 14
onLinkActivated: {
HiFiAbout.openUrl("http://www.apache.org/licenses/LICENSE-2.0.html");
}
}
}
}

View file

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

View file

@ -18,7 +18,7 @@ import "../../controls-uit" as HifiControls
Rectangle {
id: info
anchors.fill: parent
signal canceled()
signal restart()

View file

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

View file

@ -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"]
}
}

View file

@ -32,6 +32,6 @@ StackView {
TabletPreferencesDialog {
id: root
objectName: "TabletGraphicsPreferences"
showCategories: ["Graphics"]
showCategories: ["Graphics Quality"]
}
}

View file

@ -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 {

View file

@ -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) {

View file

@ -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 {

View file

@ -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

View file

@ -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 <QDate>
#include <QLocale>
#include "AboutUtil.h"
#include "BuildInfo.h"
#include <ui/TabletScriptingInterface.h>
#include "DependencyManager.h"
#include "scripting/HMDScriptingInterface.h"
#include "Application.h"
#include <OffscreenQmlDialog.h>
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<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
auto hmd = DependencyManager::get<HMDScriptingInterface>();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
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);
}
}
}

42
interface/src/AboutUtil.h Normal file
View file

@ -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 <QObject>
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

View file

@ -220,6 +220,8 @@
#include "webbrowser/WebBrowserSuggestionsEngine.h"
#include <DesktopPreviewProvider.h>
#include "AboutUtil.h"
#if defined(Q_OS_WIN)
#include <VersionHelpers.h>
@ -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<SelectionScriptingInterface>().data());
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
surfaceContext->setContextProperty("Wallet", DependencyManager::get<WalletScriptingInterface>().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>();
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<bool> notificationSounds{ MenuOption::NotificationSounds, true};
Setting::Handle<bool> 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<ContextOverlayInterface>().data());
scriptEngine->registerGlobalObject("Wallet", DependencyManager::get<WalletScriptingInterface>().data());
scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get<AddressManager>().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<OffscreenUi>()->show(widgetUrl, name);
}
if (tablet->getToolbarMode()) {
} else {
DependencyManager::get<OffscreenUi>()->show(widgetUrl, name);
}
}
@ -7550,7 +7555,6 @@ void Application::loadLODToolsDialog() {
}
}
void Application::loadEntityStatisticsDialog() {
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(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 {

View file

@ -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();

View file

@ -10,7 +10,7 @@
//
#include "Menu.h"
#include <QDesktopServices>
#include <QFileDialog>
#include <QMenuBar>
#include <QShortcut>
@ -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<ScriptEngines>();
// 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<ScriptEngines>()->reloadAllScripts();
DependencyManager::get<OffscreenUi>()->clearCache();
});
// Edit > Console... [advanced]
addActionToQMenuAndActionHash(editMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J,
DependencyManager::get<StandAloneJSConsole>().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<AvatarManager>();
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>();
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>();
locationBookmarks->setupMenus(this, navigateMenu);
// Navigate > Copy Address [advanced]
// Navigate > Copy Address
auto addressManager = DependencyManager::get<AddressManager>();
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<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
auto hmd = DependencyManager::get<HMDScriptingInterface>();
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<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
auto hmd = DependencyManager::get<HMDScriptingInterface>();
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<SpeechRecognizer>();
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<SpeechRecognizer>();
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<StandAloneJSConsole>().data(),
SLOT(toggleConsole()),
QAction::NoRole,
UNSPECIFIED_POSITION);
// Developer > API Debugger
action = addActionToQMenuAndActionHash(developerMenu, "API Debugger");
connect(action, &QAction::triggered, [] {
auto scriptEngines = DependencyManager::get<ScriptEngines>();
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<ScriptEngines>();
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) {

View file

@ -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

View file

@ -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<float>(_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));
}

View file

@ -86,7 +86,7 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
if (dialogsManager->getLodToolsDialog()) {
watchWindow(dialogsManager->getLodToolsDialog()->windowHandle());
}
connect(_switchModeButton, &QPushButton::clicked, [this]{
toggleHMDMode();
});

View file

@ -130,4 +130,3 @@ void LodToolsDialog::closeEvent(QCloseEvent* event) {
#endif
}

View file

@ -52,4 +52,4 @@ private:
QLabel* _feedback;
};
#endif // hifi_LodToolsDialog_h
#endif // hifi_LodToolsDialog_h

View file

@ -14,6 +14,7 @@
#include <ScriptEngines.h>
#include <OffscreenUi.h>
#include <Preferences.h>
#include <RenderShadowTask.h>
#include <display-plugins/CompositorHelper.h>
#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<LODManager>();
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<LODManager>();
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<LODManager>()->getDesktopLODDecreaseFPS(); };
auto setter = [](float value) { DependencyManager::get<LODManager>()->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<LODManager>()->getHMDLODDecreaseFPS(); };
auto setter = [](float value) { DependencyManager::get<LODManager>()->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<DdeFaceTracker>()->getEyeClosingThreshold(); };
auto setter = [](float value) { DependencyManager::get<DdeFaceTracker>()->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<DdeFaceTracker>()->getEyeClosingThreshold(); };
auto setter = [](float value) { DependencyManager::get<DdeFaceTracker>()->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);

View file

@ -56,6 +56,8 @@
#include "ui/Snapshot.h"
#include "SoundCache.h"
#include "raypick/PointerScriptingInterface.h"
#include <display-plugins/CompositorHelper.h>
#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<PointerScriptingInterface>().data());
_webSurface->getSurfaceContext()->setContextProperty("Web3DOverlay", this);
_webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
_webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
_webSurface->getSurfaceContext()->setContextProperty("desktop", DependencyManager::get<OffscreenUi>()->getDesktop());
_webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance());
// Override min fps for tablet UI, for silky smooth scrolling
setMaxFPS(90);

View file

@ -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

View file

@ -441,7 +441,11 @@ void TabletProxy::emitWebEvent(const QVariant& msg) {
void TabletProxy::onTabletShown() {
if (_tabletShown) {
static_cast<TabletScriptingInterface*>(parent())->playSound(TabletScriptingInterface::TabletOpen);
Setting::Handle<bool> notificationSounds{ QStringLiteral("play_notification_sounds"), true};
Setting::Handle<bool> notificationSoundTablet{ QStringLiteral("play_notification_sounds_tablet"), true};
if (notificationSounds.get() && notificationSoundTablet.get()) {
dynamic_cast<TabletScriptingInterface*>(parent())->playSound(TabletScriptingInterface::TabletOpen);
}
if (_showRunningScripts) {
_showRunningScripts = false;
pushOntoStack("hifi/dialogs/TabletRunningScripts.qml");

View file

@ -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",

View file

@ -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

View file

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

View file

@ -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();

View file

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

View file

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

View file

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