diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 5acc31dfd0..c068fdcfaf 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -11,6 +11,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 as Original import QtQuick.Controls.Styles 1.4 +import TabletScriptingInterface 1.0 import "../styles-uit" @@ -26,6 +27,16 @@ Original.Button { HifiConstants { id: hifi } + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + style: ButtonStyle { background: Rectangle { diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index b279b7ca8d..22b25671c3 100644 --- a/interface/resources/qml/controls-uit/CheckBox.qml +++ b/interface/resources/qml/controls-uit/CheckBox.qml @@ -14,6 +14,8 @@ import QtQuick.Controls.Styles 1.4 import "../styles-uit" +import TabletScriptingInterface 1.0 + Original.CheckBox { id: checkBox @@ -28,6 +30,15 @@ Original.CheckBox { readonly property int checkRadius: 2 activeFocusOnPress: true + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + +// TODO: doesnt works for QQC1. check with QQC2 +// onHovered: { +// tabletInterface.playSound(TabletEnums.ButtonHover); +// } + style: CheckBoxStyle { indicator: Rectangle { id: box diff --git a/interface/resources/qml/controls-uit/CheckBoxQQC2.qml b/interface/resources/qml/controls-uit/CheckBoxQQC2.qml index 92bad04d01..32d69cf339 100644 --- a/interface/resources/qml/controls-uit/CheckBoxQQC2.qml +++ b/interface/resources/qml/controls-uit/CheckBoxQQC2.qml @@ -13,6 +13,7 @@ import QtQuick.Controls 2.2 import "../styles-uit" import "../controls-uit" as HiFiControls +import TabletScriptingInterface 1.0 CheckBox { id: checkBox @@ -32,6 +33,17 @@ CheckBox { readonly property int checkSize: Math.max(boxSize - 8, 10) readonly property int checkRadius: isRound ? checkSize / 2 : 2 focusPolicy: Qt.ClickFocus + hoverEnabled: true + + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } indicator: Rectangle { id: box diff --git a/interface/resources/qml/controls-uit/GlyphButton.qml b/interface/resources/qml/controls-uit/GlyphButton.qml index ac353b5a52..bc7bc636fe 100644 --- a/interface/resources/qml/controls-uit/GlyphButton.qml +++ b/interface/resources/qml/controls-uit/GlyphButton.qml @@ -12,6 +12,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 as Original import QtQuick.Controls.Styles 1.4 +import TabletScriptingInterface 1.0 import "../styles-uit" @@ -24,6 +25,16 @@ Original.Button { width: 120 height: 28 + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + style: ButtonStyle { background: Rectangle { diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index 0c888d1a0a..eda9c03fa2 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -1,4 +1,5 @@ import QtQuick 2.0 +import TabletScriptingInterface 1.0 Item { id: keyItem @@ -32,8 +33,15 @@ Item { } } + onContainsMouseChanged: { + if (containsMouse) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } + onClicked: { mouse.accepted = true; + tabletInterface.playSound(TabletEnums.ButtonClick); webEntity.synthesizeKeyPress(glyph); webEntity.synthesizeKeyPress(glyph, mirrorText); diff --git a/interface/resources/qml/controls-uit/RadioButton.qml b/interface/resources/qml/controls-uit/RadioButton.qml index ab11ec68b1..65d36d2dcb 100644 --- a/interface/resources/qml/controls-uit/RadioButton.qml +++ b/interface/resources/qml/controls-uit/RadioButton.qml @@ -15,6 +15,8 @@ import QtQuick.Controls.Styles 1.4 import "../styles-uit" import "../controls-uit" as HifiControls +import TabletScriptingInterface 1.0 + Original.RadioButton { id: radioButton HifiConstants { id: hifi } @@ -27,6 +29,15 @@ Original.RadioButton { readonly property int checkSize: 10 readonly property int checkRadius: 2 + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + +// TODO: doesnt works for QQC1. check with QQC2 +// onHovered: { +// tabletInterface.playSound(TabletEnums.ButtonHover); +// } + style: RadioButtonStyle { indicator: Rectangle { id: box diff --git a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml index 06332bd1be..3a5c850031 100644 --- a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml +++ b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml @@ -9,6 +9,7 @@ // import QtQuick 2.5 +import TabletScriptingInterface 1.0 import "../../controls-uit" @@ -22,7 +23,16 @@ Preference { Button { id: button - onClicked: preference.trigger() + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + preference.trigger(); + tabletInterface.playSound(TabletEnums.ButtonClick); + } width: 180 anchors.bottom: parent.bottom } diff --git a/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml b/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml index f8f992735c..8904896ab7 100644 --- a/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml +++ b/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml @@ -9,6 +9,7 @@ // import QtQuick 2.5 +import TabletScriptingInterface 1.0 import "../../controls-uit" @@ -38,6 +39,16 @@ Preference { CheckBox { id: checkBox + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick); + } + anchors { top: spacer.bottom left: parent.left diff --git a/interface/resources/qml/hifi/audio/MicBar.qml b/interface/resources/qml/hifi/audio/MicBar.qml index e757d7cadf..b6699d6ceb 100644 --- a/interface/resources/qml/hifi/audio/MicBar.qml +++ b/interface/resources/qml/hifi/audio/MicBar.qml @@ -14,6 +14,8 @@ import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 +import TabletScriptingInterface 1.0 + Rectangle { readonly property var level: Audio.inputLevel; @@ -57,8 +59,16 @@ Rectangle { hoverEnabled: true; scrollGestureEnabled: false; - onClicked: { Audio.muted = !Audio.muted; } + onClicked: { + Audio.muted = !Audio.muted; + tabletInterface.playSound(TabletEnums.ButtonClick); + } drag.target: dragTarget; + onContainsMouseChanged: { + if (containsMouse) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } } QtObject { diff --git a/interface/resources/qml/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml index 98a73eb0fd..169c7acec1 100644 --- a/interface/resources/qml/hifi/tablet/TabletButton.qml +++ b/interface/resources/qml/hifi/tablet/TabletButton.qml @@ -1,5 +1,6 @@ import QtQuick 2.0 import QtGraphicalEffects 1.0 +import TabletScriptingInterface 1.0 Item { id: tabletButton @@ -130,11 +131,13 @@ Item { } tabletButton.clicked(); if (tabletRoot) { - tabletRoot.playButtonClickSound(); + tabletInterface.playSound(TabletEnums.ButtonClick); } } onEntered: { tabletButton.isEntered = true; + tabletInterface.playSound(TabletEnums.ButtonHover); + if (tabletButton.isActive) { tabletButton.state = "hover active state"; } else { diff --git a/interface/resources/qml/hifi/tablet/TabletMenuView.qml b/interface/resources/qml/hifi/tablet/TabletMenuView.qml index ecfb653923..4a4a6b7f87 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuView.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuView.qml @@ -9,9 +9,13 @@ // import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import TabletScriptingInterface 1.0 import "../../styles-uit" import "." + FocusScope { id: root implicitHeight: background.height @@ -69,12 +73,17 @@ FocusScope { onImplicitWidthChanged: listView !== null ? listView.recalcSize() : 0 MouseArea { + enabled: name !== "" && item.enabled anchors.fill: parent hoverEnabled: true - onEntered: listView.currentIndex = index + onEntered: { + tabletInterface.playSound(TabletEnums.ButtonHover); + listView.currentIndex = index + } + onClicked: { - root.selected(item) - tabletRoot.playButtonClickSound(); + tabletInterface.playSound(TabletEnums.ButtonClick); + root.selected(item); } } } diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 5084377273..ba9d06eee3 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 import Hifi 1.0 import QtQuick.Controls 1.4 + import "../../dialogs" import "../../controls" diff --git a/interface/resources/sounds/Button01.wav b/interface/resources/sounds/Button01.wav new file mode 100644 index 0000000000..e1c8111c6f Binary files /dev/null and b/interface/resources/sounds/Button01.wav differ diff --git a/interface/resources/sounds/Button02.wav b/interface/resources/sounds/Button02.wav new file mode 100644 index 0000000000..f4bac99e38 Binary files /dev/null and b/interface/resources/sounds/Button02.wav differ diff --git a/interface/resources/sounds/Button03.wav b/interface/resources/sounds/Button03.wav new file mode 100644 index 0000000000..1eb28b7daf Binary files /dev/null and b/interface/resources/sounds/Button03.wav differ diff --git a/interface/resources/sounds/Button04.wav b/interface/resources/sounds/Button04.wav new file mode 100644 index 0000000000..cd76d0174c Binary files /dev/null and b/interface/resources/sounds/Button04.wav differ diff --git a/interface/resources/sounds/Button05.wav b/interface/resources/sounds/Button05.wav new file mode 100644 index 0000000000..72d2622e9d Binary files /dev/null and b/interface/resources/sounds/Button05.wav differ diff --git a/interface/resources/sounds/Button06.wav b/interface/resources/sounds/Button06.wav new file mode 100644 index 0000000000..30a097ce45 Binary files /dev/null and b/interface/resources/sounds/Button06.wav differ diff --git a/interface/resources/sounds/Button07.wav b/interface/resources/sounds/Button07.wav new file mode 100644 index 0000000000..5d285ffa07 Binary files /dev/null and b/interface/resources/sounds/Button07.wav differ diff --git a/interface/resources/sounds/Collapse.wav b/interface/resources/sounds/Collapse.wav new file mode 100644 index 0000000000..7a169d506c Binary files /dev/null and b/interface/resources/sounds/Collapse.wav differ diff --git a/interface/resources/sounds/Expand.wav b/interface/resources/sounds/Expand.wav new file mode 100644 index 0000000000..7f7710e7f6 Binary files /dev/null and b/interface/resources/sounds/Expand.wav differ diff --git a/interface/resources/sounds/Tab01.wav b/interface/resources/sounds/Tab01.wav new file mode 100644 index 0000000000..38cf7decc4 Binary files /dev/null and b/interface/resources/sounds/Tab01.wav differ diff --git a/interface/resources/sounds/Tab02.wav b/interface/resources/sounds/Tab02.wav new file mode 100644 index 0000000000..04ad9b909f Binary files /dev/null and b/interface/resources/sounds/Tab02.wav differ diff --git a/interface/resources/sounds/Tab03.wav b/interface/resources/sounds/Tab03.wav new file mode 100644 index 0000000000..db7545a365 Binary files /dev/null and b/interface/resources/sounds/Tab03.wav differ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ebb95a3e89..0b99ce5004 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1847,6 +1847,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _rayPickManager.setPrecisionPicking(rayPickID, value); }); + // Preload Tablet sounds + DependencyManager::get()->preloadSounds(); + qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); } @@ -2324,6 +2327,8 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); surfaceContext->setContextProperty("Tablet", DependencyManager::get().data()); + // Tablet inteference with Tablet.qml. Need to avoid this in QML space + surfaceContext->setContextProperty("tabletInterface", DependencyManager::get().data()); surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); surfaceContext->setContextProperty("FaceTracker", DependencyManager::get().data()); @@ -5812,6 +5817,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue, wrapperFromScriptValue); qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue, wrapperFromScriptValue); + // Tablet inteference with Tablet.qml. Need to avoid this in QML space + scriptEngine->registerGlobalObject("tabletInterface", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Tablet", DependencyManager::get().data()); auto toolbarScriptingInterface = DependencyManager::get().data(); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 526890b9c1..363c85b395 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -63,7 +63,6 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f; const QString Web3DOverlay::TYPE = "web3d"; const QString Web3DOverlay::QML = "Web3DOverlay.qml"; - Web3DOverlay::Web3DOverlay() : _dpi(DPI) { _touchDevice.setCapabilities(QTouchDevice::Position); _touchDevice.setType(QTouchDevice::TouchScreen); @@ -248,6 +247,9 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../"); + // Tablet inteference with Tablet.qml. Need to avoid this in QML space + _webSurface->getSurfaceContext()->setContextProperty("tabletInterface", DependencyManager::get().data()); + tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data()); // mark the TabletProxy object as cpp ownership. QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 4e625c2494..b9da230715 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -23,16 +23,28 @@ #include "ToolbarScriptingInterface.h" #include "Logging.h" +#include + +#include "SettingHandle.h" + // FIXME move to global app properties const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system"; const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; const QString TabletScriptingInterface::QML = "hifi/tablet/TabletRoot.qml"; +static Setting::Handle tabletSoundsButtonClick("TabletSounds", QStringList { "/sounds/Button06.wav", + "/sounds/Button04.wav", + "/sounds/Button07.wav", + "/sounds/Tab01.wav", + "/sounds/Tab02.wav" }); + TabletScriptingInterface::TabletScriptingInterface() { + qmlRegisterType("TabletScriptingInterface", 1, 0, "TabletEnums"); } TabletScriptingInterface::~TabletScriptingInterface() { + tabletSoundsButtonClick.set(tabletSoundsButtonClick.get()); } ToolbarProxy* TabletScriptingInterface::getSystemToolbarProxy() { @@ -63,6 +75,29 @@ TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { return tabletProxy; } +void TabletScriptingInterface::preloadSounds() { + //preload audio events + const QStringList &audioSettings = tabletSoundsButtonClick.get(); + for (int i = 0; i < TabletAudioEvents::Last; i++) { + QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + audioSettings.at(i)); + SharedSoundPointer sound = DependencyManager::get()-> + getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); + _audioEvents.insert(static_cast(i), sound); + } +} + +void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) { + SharedSoundPointer sound = _audioEvents[aEvent]; + if (sound) { + AudioInjectorOptions options; + options.stereo = sound->isStereo(); + options.ambisonic = sound->isAmbisonic(); + options.localOnly = true; + + AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options); + } +} + void TabletScriptingInterface::setToolbarMode(bool toolbarMode) { Q_ASSERT(QThread::currentThread() == qApp->thread()); _toolbarMode = toolbarMode; @@ -323,9 +358,12 @@ void TabletProxy::emitWebEvent(const QVariant& msg) { } void TabletProxy::onTabletShown() { - if (_tabletShown && _showRunningScripts) { - _showRunningScripts = false; - pushOntoStack("../../hifi/dialogs/TabletRunningScripts.qml"); + if (_tabletShown) { + static_cast(parent())->playSound(TabletScriptingInterface::TabletOpen); + if (_showRunningScripts) { + _showRunningScripts = false; + pushOntoStack("../../hifi/dialogs/TabletRunningScripts.qml"); + } } } diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 386bce45a8..bd195fdd20 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -23,7 +23,7 @@ #include #include #include - +#include "SoundCache.h" #include class ToolbarProxy; @@ -40,8 +40,11 @@ class OffscreenQmlSurface; class TabletScriptingInterface : public QObject, public Dependency { Q_OBJECT public: + enum TabletAudioEvents { ButtonClick, ButtonHover, TabletOpen, TabletHandsIn, TabletHandsOut, Last}; + Q_ENUM(TabletAudioEvents) + TabletScriptingInterface(); - ~TabletScriptingInterface(); + virtual ~TabletScriptingInterface(); static const QString QML; void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; } @@ -54,6 +57,9 @@ public: */ Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId); + void preloadSounds(); + Q_INVOKABLE void playSound(TabletAudioEvents aEvent); + void setToolbarMode(bool toolbarMode); void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface); @@ -77,6 +83,7 @@ private: void processTabletEvents(QObject* object, const QKeyEvent* event); ToolbarProxy* getSystemToolbarProxy(); + QMap _audioEvents; protected: std::map _tabletProxies; ToolbarScriptingInterface* _toolbarScriptingInterface { nullptr }; diff --git a/scripts/system/dialTone.js b/scripts/system/dialTone.js index 7b693aa2de..7c0a5b250d 100644 --- a/scripts/system/dialTone.js +++ b/scripts/system/dialTone.js @@ -33,10 +33,4 @@ Audio.disconnected.connect(function(){ Audio.playSound(disconnectSound, soundOptions); }); -Audio.mutedChanged.connect(function () { - if (Audio.muted) { - Audio.playSound(micMutedSound, soundOptions); - } -}); - }()); // END LOCAL_SCOPE