From 9e88a6ed8d6b11abfcf975eb68dbc5736fe03989 Mon Sep 17 00:00:00 2001 From: Liv Date: Fri, 25 Aug 2017 17:48:35 -0700 Subject: [PATCH 01/19] Initial attempt at changing first run behavior --- interface/src/Application.cpp | 50 +++-------------------------------- 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dce95e6f8f..e8bf8ca260 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2812,26 +2812,18 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { handControllerType = Oculus; } - // Check tutorial content versioning - bool hasTutorialContent = contentVersion >= MIN_CONTENT_VERSION.at(handControllerType); - // Check HMD use (may be technically available without being in use) bool hasHMD = PluginUtils::isHMDAvailable(); bool isUsingHMD = _displayPlugin->isHmd(); bool isUsingHMDAndHandControllers = hasHMD && hasHandControllers && isUsingHMD; - Setting::Handle tutorialComplete{ "tutorialComplete", false }; Setting::Handle firstRun{ Settings::firstRun, true }; const QString HIFI_SKIP_TUTORIAL_COMMAND_LINE_KEY = "--skipTutorial"; // Skips tutorial/help behavior, and does NOT clear firstRun setting. bool skipTutorial = arguments().contains(HIFI_SKIP_TUTORIAL_COMMAND_LINE_KEY); - bool isTutorialComplete = tutorialComplete.get(); - bool shouldGoToTutorial = isUsingHMDAndHandControllers && hasTutorialContent && !isTutorialComplete && !skipTutorial; qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMDAndHandControllers; - qCDebug(interfaceapp) << "Tutorial version:" << contentVersion << ", sufficient:" << hasTutorialContent << - ", complete:" << isTutorialComplete << ", should go:" << shouldGoToTutorial; // when --url in command line, teleport to location const QString HIFI_URL_COMMAND_LINE_KEY = "--url"; @@ -2841,39 +2833,15 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { addressLookupString = arguments().value(urlIndex + 1); } - const QString TUTORIAL_PATH = "/tutorial_begin"; - - static const QString SENT_TO_TUTORIAL = "tutorial"; static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location"; static const QString SENT_TO_ENTRY = "entry"; static const QString SENT_TO_SANDBOX = "sandbox"; QString sentTo; - if (shouldGoToTutorial) { - if (sandboxIsRunning) { - qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; - DependencyManager::get()->goToLocalSandbox(TUTORIAL_PATH); - sentTo = SENT_TO_TUTORIAL; - } else { - qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; - if (firstRun.get()) { - showHelp(); - } - if (addressLookupString.isEmpty()) { - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; - } else { - DependencyManager::get()->loadSettings(addressLookupString); - sentTo = SENT_TO_PREVIOUS_LOCATION; - } - } - } else { - // If this is a first run we short-circuit the address passed in - if (firstRun.get() && !skipTutorial) { + if (firstRun.get()) { showHelp(); - if (isUsingHMDAndHandControllers) { if (sandboxIsRunning) { qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; DependencyManager::get()->goToLocalSandbox(); @@ -2883,16 +2851,12 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { DependencyManager::get()->goToEntry(); sentTo = SENT_TO_ENTRY; } - } else { - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; - } + } else { qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); DependencyManager::get()->loadSettings(addressLookupString); sentTo = SENT_TO_PREVIOUS_LOCATION; } - } UserActivityLogger::getInstance().logAction("startup_sent_to", { { "sent_to", sentTo }, @@ -2901,18 +2865,10 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { { "has_hand_controllers", hasHandControllers }, { "is_using_hmd", isUsingHMD }, { "is_using_hmd_and_hand_controllers", isUsingHMDAndHandControllers }, - { "content_version", contentVersion }, - { "is_tutorial_complete", isTutorialComplete }, - { "has_tutorial_content", hasTutorialContent }, - { "should_go_to_tutorial", shouldGoToTutorial } + { "content_version", contentVersion } }); _connectionMonitor.init(); - - // After all of the constructor is completed, then set firstRun to false. - if (!skipTutorial) { - firstRun.set(false); - } } bool Application::importJSONFromURL(const QString& urlString) { From 7ee2ac736efff731da57859c6dd61e3040cea321 Mon Sep 17 00:00:00 2001 From: Liv Date: Tue, 29 Aug 2017 14:55:59 -0700 Subject: [PATCH 02/19] Remove unused skipTutorial code --- interface/src/Application.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e8bf8ca260..80752ae7df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2819,10 +2819,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { Setting::Handle firstRun{ Settings::firstRun, true }; - const QString HIFI_SKIP_TUTORIAL_COMMAND_LINE_KEY = "--skipTutorial"; - // Skips tutorial/help behavior, and does NOT clear firstRun setting. - bool skipTutorial = arguments().contains(HIFI_SKIP_TUTORIAL_COMMAND_LINE_KEY); - qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMDAndHandControllers; // when --url in command line, teleport to location From 758fc5388234af4a409ef935d29822327543a046 Mon Sep 17 00:00:00 2001 From: Liv Date: Wed, 30 Aug 2017 09:23:33 -0700 Subject: [PATCH 03/19] Remove unneeded handcontrollertype code from handle first run checks --- interface/src/Application.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 80752ae7df..3fafd8a58b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2803,13 +2803,8 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // Get controller availability bool hasHandControllers = false; - HandControllerType handControllerType = Vive; - if (PluginUtils::isViveControllerAvailable()) { + if (PluginUtils::isViveControllerAvailable() || PluginUtils::isOculusTouchControllerAvailable()) { hasHandControllers = true; - handControllerType = Vive; - } else if (PluginUtils::isOculusTouchControllerAvailable()) { - hasHandControllers = true; - handControllerType = Oculus; } // Check HMD use (may be technically available without being in use) From 930d59c53e642b8c33b4ec81e8edcc80a4b9d16c Mon Sep 17 00:00:00 2001 From: Liv Date: Tue, 5 Sep 2017 17:50:25 -0700 Subject: [PATCH 04/19] add back first run to false and fix formatting --- interface/src/Application.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3fafd8a58b..748dc287ef 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2833,15 +2833,16 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (firstRun.get()) { showHelp(); - if (sandboxIsRunning) { - qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; - DependencyManager::get()->goToLocalSandbox(); - sentTo = SENT_TO_SANDBOX; - } else { - qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; - } + if (sandboxIsRunning) { + qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; + DependencyManager::get()->goToLocalSandbox(); + sentTo = SENT_TO_SANDBOX; + } else { + qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; + DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; + } + firstRun.set(false); } else { qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); From 832e4aa5ebb1c007a1a9543d13671fc032148081 Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 8 Sep 2017 09:51:10 +0200 Subject: [PATCH 05/19] Introducong tablet audio events --- .../resources/qml/hifi/tablet/TabletRoot.qml | 3 ++- interface/resources/sounds/Button01.wav | Bin 0 -> 53646 bytes interface/resources/sounds/Button02.wav | Bin 0 -> 111602 bytes interface/resources/sounds/Button03.wav | Bin 0 -> 80394 bytes interface/resources/sounds/Button04.wav | Bin 0 -> 22432 bytes interface/resources/sounds/Button05.wav | Bin 0 -> 31348 bytes interface/resources/sounds/Button06.wav | Bin 0 -> 26898 bytes interface/resources/sounds/Button07.wav | Bin 0 -> 26898 bytes interface/resources/sounds/Collapse.wav | Bin 0 -> 156186 bytes interface/resources/sounds/Expand.wav | Bin 0 -> 89310 bytes interface/resources/sounds/Tab01.wav | Bin 0 -> 31348 bytes interface/resources/sounds/Tab02.wav | Bin 0 -> 80390 bytes interface/resources/sounds/Tab03.wav | Bin 0 -> 67018 bytes .../ui/src/ui/TabletScriptingInterface.cpp | 17 +++++++++++++++++ libraries/ui/src/ui/TabletScriptingInterface.h | 8 +++++++- 15 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 interface/resources/sounds/Button01.wav create mode 100644 interface/resources/sounds/Button02.wav create mode 100644 interface/resources/sounds/Button03.wav create mode 100644 interface/resources/sounds/Button04.wav create mode 100644 interface/resources/sounds/Button05.wav create mode 100644 interface/resources/sounds/Button06.wav create mode 100644 interface/resources/sounds/Button07.wav create mode 100644 interface/resources/sounds/Collapse.wav create mode 100644 interface/resources/sounds/Expand.wav create mode 100644 interface/resources/sounds/Tab01.wav create mode 100644 interface/resources/sounds/Tab02.wav create mode 100644 interface/resources/sounds/Tab03.wav diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 5084377273..36ea16d882 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" @@ -145,7 +146,7 @@ Item { SoundEffect { id: buttonClickSound volume: 0.1 - source: "../../../sounds/Gamemaster-Audio-button-click.wav" + source: "" } function playButtonClickSound() { diff --git a/interface/resources/sounds/Button01.wav b/interface/resources/sounds/Button01.wav new file mode 100644 index 0000000000000000000000000000000000000000..e1c8111c6f21ef0ef009ed245bff6ea3fedbb148 GIT binary patch literal 53646 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 literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Button02.wav b/interface/resources/sounds/Button02.wav new file mode 100644 index 0000000000000000000000000000000000000000..f4bac99e38d6dda8906c094b9d02dddcef2bd862 GIT binary patch literal 111602 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 IyipbZ54QRGo&W#< literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Button03.wav b/interface/resources/sounds/Button03.wav new file mode 100644 index 0000000000000000000000000000000000000000..1eb28b7daf5fb54d62ba9704918bd7f25e57e073 GIT binary patch literal 80394 zcmeI%Yit}>*$41v)^;62+J;I5DXPTQEm2!_yfb^>?RtabT{nw-lkGH75m@7y*<_o& zb$1*)m7tX<5+HF=TMz;S2nA7~p8{V>s9J$aB>I7f3I*EofvPGMg&Y5%0?2gY&7KVodX@w3C-kmR2oZt;aq)>n!JVQjU2dJBN z6Om;&#;H9D0RR91000000002M`=8ikyJxIy^Yw0R>Xye9?pm_{n00FBQt6w?b7B7D z?Fdl7E7lS%uMhm0UmS;VKRJ&ri6!x-cvHM2UJ`#2e-eKXe-O`#XT@*DZ^apLM*K|t zOngIpLp&xP6F1Y%^hf$5MU;qgkuFl5>J*|7-Anhy1pVBEh<)t5@L$ux6Ns{DYq$e%A9hya<}p}y-mNMU(hr3 z482Kj(m&~+^dvp$oy(*2D1Dc{>-FCxlRiVAq5J4Q@7$}RD$cv--Cofvz9qipjoX*S zmql5W#W%$_#Z%%b@jLN5@uYZC{963lJLYlzoA{gfyZF0!RlMrGzan1oj{hP4;l1;m ze3(8=x6-Y2JKauuX)j$%*V0bfNt}KiT}QiVw|9Ka>T8GZ^&$F@SC-$o{4Uz%)!};l zxrchZ_0UCK)J@%MYlhbZuZ6?x40{Nl25-OG1gV{)x^I+p8^ z+vR@ni_f8#de_c{(>PzgxDN9c?P?#F#j@82e&@dNOQy-bNnDp>@cGJ@jLq+|J((xl z+YZ?V^Y@YQn8d%4(*%gc8BpS8d!DaW*9&gW=_j+%lo4noNbK;zMPCO?#Ci}Da zv$x;Od&#`#%J$JdZ=dlSCB7%VC+-#ZinHRZ zc!Hjw7nB#2uLiyv_;ldYft-?4xIes){R!n0%IB2NDZh7r@9taPxBQ!>-z+`UdZ_iV zcv##>H_{Wz6H2f<*nPPBaQAlt-w8yOsG?3mc`K<@*+sqR$w ztIDg&>+b9B!%Gh@J-zt!;_}k+($`yGZ=H3|x_gzq$|K#6bU)qmbkAbfV%N*c%gO;d zKwWN^d;7}mD+?_p2_>PN44e#%1;zs0=P%Khh@TVOByJMi#)ug4 zp2a*bo)>q}9p3YZvvk&bpQ0&mz5GP{L=;6)92dvMkHn9}d2!yGcb-d!9Gas!%2VE3 zA1{g*#pB{}@u+xI{9OE8@Vel+=VuCWic^6K6r&h@j6UYA6MhcB&n9>s@G}6$Yw9EP z5&9^7)QidU&n}1yUb(l#Ti$*=uTf6tXBXGg^&6f`@EVlQ8yFwU@_fB9PWKLoyt2H{ z&;60lCivRn>rP%*{%cUiWHKJ(zH{61n&$m~?!RnHrps%a>+rGco4gkJo$K*SrZN63 zpKHkLne(|mj~|Z_zjNO?U6%33;ynL3a$N2+Kj-1tvOVq>m*v=u(`6p>5`AMR`OCap zo7;LX>2%Hj0Phv}jsgGx000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z000000000000000000000Qg`UDNIf8Bcj6C@OWWpGPjqA!kV5?wWO-Yrgbf?N7AvB zswL8zMzi*Ub5G!dIZ}RuR&CY}w*Mcst&$PUSIwGbH-bY$!LX+L%XYFp!aTsybT}nT zDe~Y0Dp#1A*hS=x!+|-+sa1oK(vi`T`>r9%>|dyqgD31pvs9}N^y&RtU(n`pFIA5Y z^c|WWR+D}EvpX{f4i6t09m!^jk{VBATXYAzjmS zUqLU&D>yYhI6AS~yQ!I}!q`xLX0(tSE8KN(dS+xitF>!gso0fc9V~1s*1X6f^#=*i}2QN{@%gTh>Bf~Lyp#=fp{fA~IMvvUE z*ZbwE8|HD_3C`L_OVxqCH_klO7c5x=eTQSC+Gu^qK2|z-f5V=-e{9;k|G1g5ydR>4 z^g^Xxu^l70P$^fN>4kwlgYO*D)n=NLLw!N7h;w|Pul>DxWOO1pRBPD5SbtnK^{5t1 zr26%^7LDn5@QpgiBu zety1xKGI)n91ZEIR4Sx}L*cO6u!?H)WYsYi)N1qQb`TjSXE)78sqU0&)gZ?;W@~fK zKwlp>v}X0ZD)rIPwWg}ge(x;%%~~b2VAMl;zZR-gLY-^&C+l`-(r(t~ z8m65;VOO1-JBOOI*Uz_OCpLzfw2K`BEmZ24?@_1L7b^AKrG}u=9)jG-s!=JK-u+_7 z7?!!#Zhfv%_9n|RLw4D&*j1+)();z$+8psTdE=fgRGW@bHSIz!yHKh3mr7PTsYhq^ zNHM9Vl6pc7C!@2fF>C3nZKYy%GHyoAcq9|rQhj}DS3~D&<{YP}S zv#J?3O*LXfY;`tS)cF=i)1qr3ebu&v9B-74ma0bCSB86Sm8^6z7LP}xaZ8PAVNvoYIF$X<5{v!$tnrKVGBob+YLwLN9uw=q>_luO=PuN#e~&FgNU zPcA(Fz^}=8>o;wfe3fLI#tGZXgf^tDcWTXQrPBJe>E^6v#7t8)lc|UrGm=Hsu!@$N zjOg+9*d{a?*H`V*vFDH3Ro^X^_h%gcmC^n)PKNSIT{=j!R&?f#hCO)Ht~yt|?@RRS z!CMcPs#a~jd7EruV~9&PWgauCM{O$`k`-mb<|>&Ge-)KWTQl0}{~xm#wo(zJ7@1Wy zGZI&AyO>a85hJOZ#pEnz&+olBd-5w&kHzeS5z*9`nKD&NkMdVrGNneMTGBMMWFj69 z%hic%@V#~o%30jr4`2Hm`u#nNe1B;fjv?3V)qSJ3uhfk{lk%r`>(8pZTd*6Y6Sg(n zs8zQ4J)CLsO`Crvw)OKyrW)UXZ5?i6Ev>)1Obf60w8 za-(T$u3@bGv2o=aFz$VBG=0J-&)Hc$9!W;MCf1VH&#a)!y#KygD4EialIwR17B@ zPNfpLMy)Ob$@YCk)>~emCeFUwn^#S{Q~vYUZD+1mm3bR_?ay!bY%P1rTL<3G?3SwS zJYVe1b-fv#D&22q+nc(V&fgNmDE}|U^r}W=<6yp<>5v2C>$CraEHmwtoU%Vn{tY!) zc6=q<Mc_Y7O+w_wCRA4}kvcHvj+t literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Button04.wav b/interface/resources/sounds/Button04.wav new file mode 100644 index 0000000000000000000000000000000000000000..cd76d0174cf7bfd5589dc26ba7f58793778a5456 GIT binary patch literal 22432 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 V%C#f9hyK$KF6-l-WzU}2zX7KrVm1H( literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Button06.wav b/interface/resources/sounds/Button06.wav new file mode 100644 index 0000000000000000000000000000000000000000..30a097ce456369195b2791ebe83fe4d20d0a0c57 GIT binary patch literal 26898 zcmeHP4RBml^*`_JW|w2`j?(R)q zHk&jlC=UPkyG-wU_uljSoqO)*zRb`YX>VVc09fC8ZCgB*x7PuH03zIY5CC2i!3yUA zfFkGReQjXEgb5QSOqeiX!h{JECQO(x@xDM{-z&sviOMM%fd=TPvp1e|7~6AD9kt_0 zt4O?@KsMYb3s|5AYQR=bwNN|pOl4GO1uJVuJ>dRwy&@K|P)=jzG+IvleH_PGJMzh> zPuj#y8pcFrl(-((H2O_-yq(dOo{5*+5~%OwC;36Xoh~POCLgJs`atcB8pOl7I3M?g z_n*g=@|pTZG39aP{&DbrQ2hc}z;Xil^bWp*ui5Bvw7!c+JvzRKR;!nas|h-(Qf zfu*n%E`dwn3b+D31)qW&;08Dir(vJ4PuMPQ7vC1&7T*%z5@TXa91%u@+u?Q=lc(`% zdUNIor?KxM1Ug=z{2i-=6c^a~`aHu=Zlx#WvY0TOSu6 z7YBp^VLhyehw))dVG5I&#O=5pH{)hphwD(+b$y+_PVdk| zuz0X|cj4~B&Eq$Z9~e6@);`ug78#3-y)gE|m{gDoe$B6)z!SJ%+%IZY&3divTHDjM zr)`he97fUN?T<_dM%{CsAf@(SR>Ya&H6R#am#Uw)nc`LQv9SC6{0NWe(=NJ@$YyL58^}R^nLt3 z-i>$THr$36;YE1Ae!sp{U#fpW`-1jL@s(n>m@Td-t|&T+j$*QyEY@jt+J*Xs`c~YE ze}lh4tJo@j#_}0UjkU(Q%DT#Wf%O9G9?Krfm^da<-EG2c!fWsvJf5s20^O z(=XFk;0pXSd>Ux&42eVHO3O;iZp&`Vmn>hhG*}ueKNf#1E)$oD*9+GRC*dS)hRtm6 zJcNf>UrCeZ+gI=__*MMs#5}a49gpZo^sV|b%RVo;>HcS1ZNJ|R9K4vWJgVVAH=cpYAcG^E-7LF?>#ydL8i zM~dC&@$+~W-i7z#y?77a!`{OfX6yZX`uFtD>Yvpw(J#?0xY93I2qQ{(X2K zejUG#BRGOR*n=12#rUHBqP|bxr{AF8psTvdVsX2EyZ)s9r0zl&eha^aABGRZEpQ7E ze}~W^+$7v2>=pJ3_X_t4yM^6Cx6m!r33b9zI0|>do$xvM99#)kvh(2ud;uwb`*0tA z1HZvyPkT-$c49r&<6>NlZ|HC6C-f8gas9Y{Qa`EFdJJNawWYmr87u>~-@rrg61)UU zgeAf!gii>U3zrK^g{49fif{~$0oC6GH^C;@1XsaT@G$O( zupj%e1zT_>u0#hqa5*kV4|>>sNc+`g2k-#y#l3h3-of^S9Ol?MOke`j zm}dL`ZFn1g2fu^Az+bREg3dMSKdt2+=z$o-U=Rjj7=~dd>|{C3IV!&fu7P%FhX!bX z<**#;ppNyQ*5HfyB0FzrEFQzh@DY53tw-wPck#RUAU=ruaX;HD4&!0`3;qR9;z_no z(%DFTxfCvC{R%=5R>NwhMS3*fR>3OfV?ER}?T^AoVKFRb=Qo}0Z{nLsdoaz(XYd*P zGya*KeRTfO^I!3=Nc%d?7i#xU{3knq$(9xrowam6p9|*#jmHIW0bB?dva^@YUrO{& z~?-jUqHO!{LV?v;3I?E~Xa$`OdNR#FTpBpn_CVQg>*Ei-=KNE~v z+y|alq8bNr&(vS;*G!lT|9rtUXY2D^Q0W`TTx|c_sPv7$b5!%k7^li-<9N;l&dtH+ zOywM&$)3PnuHe4RNB6%8-nYuw&IP=06kGoN!T5cE zo{irCNP~XE(-~QrsGR@yCZ9OCf0ZC@u1h*bT{=%GRcaGI*EfDk;Mzw0*>nlS&2=la z>7DAyKk}RR+o(@Mj*dve2j_8&KBG+!r5|sQ1Nc!Y6QiWuLBNa z{cPa#aJGCVa4n9?HOW!UzEY3RH(pNf^jrzf$zjyw&qh?*6Ns1VRpwm3nl^#BxlUzn z1Z!-7k+)Kl_jNW+j!I2>H^LyvVASQ$T%W(sq)RYz8?`G@QmYQG!@=KqJ|E0S*Tnk^ zKE6CRVZww76DCZUFk!-k2@@tvm@r|&gb5QSK4|ES^z~l`0Fia=-H|oD;fnykBf0%f zsmbYX=yyxaZeO$Hc1r$cNrI?4lHVwP&|)xuv?`gXYA^lUr78*8-ja;==R@pop#ZCQzAh>EIm9!73*<2!% zZgIHlC5K(5xF^z^TO8N)w>z60t3nHdtJk-0=;{mw`+C~i!l7V$q_b_HueGbEvu&Wa zwZARoYmy`>=$cj@Y`rEN=^j`e=^qHU_4Idy+>Jq3Wm&L4($%)6JKQ$V-r0I}DBK=& zO)Z&hz{I?gBuOr}B)JU@Sq*F0*WcRJQ}(WJpf9p+P1`_MB)l$ibw~d|XLm>{S)Hlb znYlV5bK>fVgo3Ve;8wS7=nqje2fBMBS4Y;h_ILM&&NTIdt_p)G1d;A_17RA2$rUiw zV4}e^Gm3JEFPG^?teP3o(?D-qds}ZCMYFSeJ@uTts!~(Uq9by3#|$Q{D(EUjhB#@W z*-e-*@xcQO^mJ`F{~~ts49c->YTh1IHz(39j@J+VpTnL|S{&;ex}>hbHR_f`$F8i} zw`*O0Y}d9}Kw$^bNb^W)Fs0^Y`$#I8&NYv;IAppxG^caTRP1utS(E&>7Ds7c-O$xz zUz5qI_J;aKXUy%B?EXN#yHWBrxUZy(h2JGLxTHp>AXDROy`!DNH|Ye z&Bd~b!F(ct%f`lX8v7gD!Wyl8@cvYg2)ZpwMRZ|~H4Tfh5 zL8=sj@XoZHO2pWGu_}iWo6sHHkxjC}QerMOsixF)KId}RyIm7wM8m}5-W*Bi@^U(+ zM#7apVJ>`3OIdDKFQe>mt?1>A<)#=)TDRw|JOr_#J@aqx*}4EzLwZ2mUOF|oIIo|LD!VBNv9@IHcCtmo2)7x zU(D-uHo6aQ%#CZ*7Gjk7bQPYMiR{3X~xBN4XQ?XVvljJh- z{IHx=TQ{re{2A|k{(86liuH-Kk{Qme;0jYIW|oR=k<*)1CFJ6Uyr9w~=%TGCnV4Qt zDt|vl&nGwfe3Dyn%HBYOQ}Rk4r`IFN&c5E6k>x6J=Iq^77(|dmClN?RU!F zCZAK015sy_ClGL|p7Qz1E-xi#3})3>Gc(^`8k?F_pSv;U^tqLQ(=XBerOEGiMpfAz zjk~?FC(5n|kts}+OwyMx%Hgi& zTue@?A-ButbJO>~5<#hOvN)1{IGY*dL|os{WKwx@n5g<%Hms6#75~p@TdJHi<#kiMHrAIs zo2c$%^MHMron~69GjLbhvJve|>{3IeZ@M$rPa~0&?;@u2ipbPpp3QLZz!-csc1Vde z=M(v)v5fzOYE9-1Elc3H^O01tIVscE`Vpt1#^oK!yd%Uv^H;wemP)6R23=M3$)|W} z;;om5RC=_x(jsK7%QfXODUlk!aIlI}X>Yhav@qzJ_;$l>{ k*SuhcYhEzJH7}UqnipmZ*TUc`{?{Kht+Y6X9jij{Z_t@;vj6}9 literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Button07.wav b/interface/resources/sounds/Button07.wav new file mode 100644 index 0000000000000000000000000000000000000000..5d285ffa07052e264fd5083edbdc26907f84e3f5 GIT binary patch literal 26898 zcmeHP3vg6d8UF9x%>$^krBD?gEK8?==4S71Hv8&kF=Vr3HLpq1LMhX5ckkU~+kGUv z8xl~*P9IYdN6T2IC_42?P?_p5OvjF>)Bwe?I<~b{Y8hLUQf)0&D#>Q|-rqTA_a--+ zg^;RaTkm%m?%s3G|NZ~@|NlJp1kx1@1QtdCHa6bU9EoR4O8|fY7Vi2n0KCqE5v~CM zQOF1fn?Z*T9XfRA(4j+z4jnpl=+L3#Z2_iOt^_y-luHx>Ek9c<1~7n8Q^-59hk$V9 zF^`itiCN6z1Ww>Mj?*W3&tZ;gBYlZnB~(H+RKo&IA@5aCMKuterM!fj6v9Px5uK{7 z#10};Y9q0i)RCf&<4T_DxClSdBcn`ps=CQLsV6q7dMlt}$~#1#YQHK=Y$oz*A@#IV zkwf*#!eSx*AoddwS>n$(@lE_Y{vF@IH|X;MUZC~F7Si`BxC*X=>)^fcUU)yeAFhY% z;TpJxaua=||LgcVeZB|Y11-=3kH8}kU;+%oGVC$-7~5y)GaNGiz)$v#SE1tu1_$t1NXYdR@j*sJK@H4m+m*Su@sO*+^%XjDR&iCee zbKXhsq&aKOu9;Xf(Ldfl{@2uWg?WlHCk5-LVovl1uIbJbdan5+oc+zmvaELv`9%YUa z^O^0i9ah0AI@W*SKkzkt4gZLL#AA32zk*-ETk%%RDp@71q?Hr$33)s}p1(SOb$)qn zd9G%%X7cvz?b#C(Cnn+(@rf-HTPD6S@r{WM*$vsQ$*#%cx#PL7%U_p&fxo~?wvt_J zTx|Si#WyQPD@Q9=RIRA`aMg#a#wy1uKU(?G%0xw?;;Y858jl)|8eU;vVOOv#*g-Mm|+d9ffcZV&ZVE?PpPfHQGTPWR#q$ha=*MUzc2q}?#WzL zt}3@>a?9lD?CI=7*@v?Gviq_Zvlp}9oBZD7qq#?OOXMZ;A?1*gf)uP`SFw8ydku$; zhmChs+)?q9il0G zOl|!je2~VSfaKrr@%Q*c{2>nE5Z-_{;1T7B(x@~lKazhWua;NKd-Hqq%ksc z#`}$NW87#mnv4ex2Ms2J$*_~%$zEVCF#SwF^9H;D55NO7he^JZwSmN&HDt4&p)F1-n3C1jfXg*dy!_w#HCnNE(ucdkps&;)b}vZm=6p zv!~e%n<44Qeu4P{vyxfK9EGD0hdA5_H^O;5kH_&iejC4yyKond;0Q)BikopW1~7m% zSc8jj5x%Irs63)Pq6{fRid%6jvMkHT<>T^Rd9S=f-XRalgYv!dz4BrCuxwO}3Ym8# zw;#j@(E$#49-fCGW{8<&CK-v9STavuU|(QgW?yE>9QzjgEtdFvF}s*O%p9h1&qE%* z3*UvUu$9guvR?cee~pjgqd1DA_%-|*?!i6ydHg(n8b6JF*oQ6Hf-7+)zNx&aJgz*h zd{OzLvQ^niZC;_QP_9$1Q{Jb%PvI3_xlOrE`Lgn5<(zU(X~HJTc{N-O!!Qh|;1qBS z$B=pQ9p*dC6U-CLbIfxLS$oEqG3EesfVr2sm${X>mH7zs5oQ7=;5ZzI2jM}GKmr%I z=vqf|;7NQEe}F&0FX5N)llVytV;EbpmB#-=_#v#qD!iavP|hf4lxLM^m0u~pQhurY zQu(d&TZQBYgAC2z!7)}ULrqIV6JDbXKr9_pmwch zRx=-9KEPBn)ig(+hNs~W9HKHwNJ2Zbg9R*f{*%3ttWQti6Ldc9!+m%^-j5l~po9`` z#Etj~`~)^)Bf8OzcC@1nZRkJ;HedsO96yd*a0~7K06sv+{1iS#*S;mN1Z-e~4(Nb8 z;10M8?t&le#^y2R;j*g-^k!AO}v_-A|upTRL4!^3!(&M&gQ?#A8tIs6>nhxg$j=L5pK6qeF;um)XnuK-LAaZ<2lQFZdT~`-}J@zJM>_DLjSG;dA(`rVzWH$LH}hp2nB( zC43oQru!UO_sAYh_EB;^ApB&nCc3VLYiT^m-b==@43^O+i2>Pv7sF!OZxJk_CmwRn zA?F44TvB@8Ap1EfM3-8~y9zq6IiU6>Q28$P)S?_Mu}>{;1zLUr)s9lU6>b&tv9DCG zYLEKVLgm--&V@FfD&ERy)Ep~)&IMJcnqTFfrI?FTMX4?1eZDBwtzy1B?_{WB*5aK! zp8o~@6S=5kCQ5z!Zba!AOW)@MGJmz}t9pJaeQNt?`L(*$yCQAfe4&*s_gRMy9XfRA z(4j+z4jnpl=+L1I&|pJq2vD%t-wB!c$7=WRR*rXicpgI1NM>{4KNS66qftzTBvawd8?))ZJ`~zdm7t1i`I4bb_d&=ntR)V{`TO8mY&|$4j*5TnycH~ zTrI&X;%W){yq2Ql);DkJ@eyzKc60?d1lt>XI=XywrM}lvA~1s>*wNnWCo!0w0W$@r zI?NIyUiPWeWwsD)rb6UXZ&!1mxvQCYv$bO*89A}4OiMY5mf(h#ONh`WuchD_!buX% zq(g^}cORg)vu)G0%jwQDAcXIfGNzE!7fm#n&;R&mW>ZvbFmJ4HKq#MzQXCyulmokEBBpyqoJtGZfft(yXiL{4QTg)cfC39zkxv;KoYU?yL zB~y~AzShBot#;nzbk|xPyuIF9Lk<>B3tw;H9UO1<@Gg(ds`}jQTWB(wyeTo_>GB7P z>QZ8)!Q7w840tS-;o;%h;kw#ns?TC|yWJMvX0h40lo;XC+Y=dKgiEAX6-ZPbzmyKA zq63*|GGQXTLMS5|gPp;TCE-XykYs5^dE-6x$Xe2&xd5g+vABhk6FXe)G z!3F;92_YU0)AM3k4lz8XcVH+Lqrnox7AYphr9>uevDR8GQ!yf8qJH-T6X}eQ2une~ zZzMiY8;y#dP@QNK>mm{tafWQ16t-JAw>@O%tZva|t#gLLA&1RtnI%3Q+9I_-86G0K zgMMEmBDw_0CUW+OL*(2JSA=u$f{lwfB_}!J@VvcFrPPScqU=aT`=SXUrs+eh7Nep^ z5G1$5>Z;>x4k^M3PP>&0h4~N{aYU>_DB_j`w_8jOe6Es?xyFsq5Db^H{(G=Dupn9LGiTG%FuUdxQSX``l46pBuVO|aLyMc(b; z_=wHPNj6u63k#t-&gK$q1>ZV(l~*HnY3|{EDWN%H6~D&S6~D%*RJ7NnNz%zkW>`o` zjeSxgGv~R_S!*?|*%(cT$>H=`Rl`h*OREa^3yD5S^jTCvwW3tSYavTfEIPZPQ2)P( zp0nQNiijaQXN%ZvT%F766P#p%OKz111EiGsx0d6%6N-OhT> zEs0J}bVVYCC7K*w3dU%}%CROdbAA!)1h=bR1XxTXrXOMF&f!^MJ&@jOE{WRl8}+gbEsFx zbV%BsGdcWi9&sooOnupy`v69)_qTbr39%u`XXo7xs$r^Tn!b2Y_P2S`VId~@tQNc7 zO78y(1cl1!?rObij<%^Fk&)s9Npe4=ebo>Ys)Zpjn(P+h12L(K#He`bSibRc(&QNG zvpRx_jH*#XO&iNgH}wmNgcPGax-(KrO3skiHqRnRXM|LyCmNT?rS_H1<)S;HaVd~Y z#f6N|=5{;%spNo4r0UmnnbtfVCenNh4J*&zr2f&$78<8T)wUT{YugK!O*MDZJfIh| zvqTGR8tzhA8qx0P4#`)z)4g>2ED|C1Z}@ax9+~OPw-OH3F&dk-0}{iYOf(bI)~R2i z8e`&z*HT75u_;nWyp6&(iF`CQ zl1WH=7h8%kDUfPzIA}wmw#y&zE%aKZ?rv0>|1PGJ<-Z7B$-JPuYhKXZH81Gyniq6; c%?rA_=7r0-YoT|Y`qLjNAvTzY&Fg&dFFe$&E&u=k literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Collapse.wav b/interface/resources/sounds/Collapse.wav new file mode 100644 index 0000000000000000000000000000000000000000..7a169d506c3a03d4df9e458338f6f2a5edbf333d GIT binary patch literal 156186 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 literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Tab02.wav b/interface/resources/sounds/Tab02.wav new file mode 100644 index 0000000000000000000000000000000000000000..04ad9b909f441bf6e98ddcf123dd62267f436590 GIT binary patch literal 80390 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 ZIFz{t7F^{1*-x}3GBR~m>P3b0e*j4u2oV4P literal 0 HcmV?d00001 diff --git a/interface/resources/sounds/Tab03.wav b/interface/resources/sounds/Tab03.wav new file mode 100644 index 0000000000000000000000000000000000000000..db7545a365e33007580e08dc3f173b3a9a524296 GIT binary patch literal 67018 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 D@<6#Z literal 0 HcmV?d00001 diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index adff219e0f..6901666da0 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -22,12 +22,22 @@ #include "../InfoView.h" #include "ToolbarScriptingInterface.h" #include "Logging.h" +#include "SoundCache.h" + +#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"; +Setting::Handle tabletSoundsButtonClick("TabletSounds/buttonClick", "../../../sounds/Button06.wav"); +Setting::Handle tabletSoundsButtonHover("TabletSounds/buttonHover", "../../../sounds/Button04.wav"); +Setting::Handle tabletSoundsTabletOpen("TabletSounds/tabletOpen", "../../../sounds/Button07.wav"); +Setting::Handle tabletSoundsTabletHandsIn("TabletSounds/tabletHandsIn", "../../../sounds/Tab01.wav"); +Setting::Handle tabletSoundsTabletHandsOut("TabletSounds/tabletHandsOut", "../../../sounds/Tab02.wav"); + TabletScriptingInterface::TabletScriptingInterface() { + } TabletScriptingInterface::~TabletScriptingInterface() { @@ -61,6 +71,13 @@ TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { return tabletProxy; } +void TabletScriptingInterface::playSound(QString soundId) +{ + QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); + SharedSoundPointer _snapshotSound = DependencyManager::get()-> + getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); +} + void TabletScriptingInterface::setToolbarMode(bool toolbarMode) { Q_ASSERT(QThread::currentThread() == qApp->thread()); _toolbarMode = toolbarMode; diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 822bae839e..78c616b412 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -34,6 +34,10 @@ class TabletButtonProxy; class QmlWindowClass; class OffscreenQmlSurface; +namespace Tablet +{ + enum AudioEvents { ButtonClick, ButtonHover, TabletOpen, TabletHandsIn, TabletHandsOut }; +} /**jsdoc * @namespace Tablet */ @@ -41,7 +45,7 @@ class TabletScriptingInterface : public QObject, public Dependency { Q_OBJECT public: TabletScriptingInterface(); - ~TabletScriptingInterface(); + virtual ~TabletScriptingInterface(); void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; } @@ -53,6 +57,7 @@ public: */ Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId); + Q_INVOKABLE void playSound(QString soundId); void setToolbarMode(bool toolbarMode); void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface); @@ -308,6 +313,7 @@ protected: }; Q_DECLARE_METATYPE(TabletButtonProxy*); +Q_DECLARE_METATYPE(Tablet::AudioEvents); /**jsdoc * @typedef TabletButtonProxy.ButtonProperties From 7c1827d67232932afeab9230fa445e3ab98b7a40 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 14 Sep 2017 20:21:11 +0200 Subject: [PATCH 06/19] use AduioEvent instead of string --- libraries/ui/src/ui/TabletScriptingInterface.cpp | 3 +-- libraries/ui/src/ui/TabletScriptingInterface.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 6901666da0..80ea2f61f7 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -71,8 +71,7 @@ TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { return tabletProxy; } -void TabletScriptingInterface::playSound(QString soundId) -{ +void TabletScriptingInterface::playSound(Tablet::AudioEvents aevent) { QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); SharedSoundPointer _snapshotSound = DependencyManager::get()-> getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 78c616b412..ce54a5586d 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -57,7 +57,7 @@ public: */ Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId); - Q_INVOKABLE void playSound(QString soundId); + Q_INVOKABLE void playSound(Tablet::AudioEvents aevent); void setToolbarMode(bool toolbarMode); void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface); From e26118254fb5e70fe305c196215fe26e48c9aa0e Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 18 Sep 2017 19:40:06 +0200 Subject: [PATCH 07/19] Implemented Audio injector in Tablet scripting interface. Added missed sound events --- .../resources/qml/controls-uit/CheckBox.qml | 11 ++++ .../qml/controls-uit/RadioButton.qml | 11 ++++ .../qml/hifi/tablet/TabletButton.qml | 5 +- .../qml/hifi/tablet/TabletMenuView.qml | 10 +++- .../resources/qml/hifi/tablet/TabletRoot.qml | 1 + interface/src/Application.cpp | 3 ++ interface/src/ui/overlays/Web3DOverlay.cpp | 19 +++++++ .../ui/src/ui/TabletScriptingInterface.cpp | 50 +++++++++++++------ .../ui/src/ui/TabletScriptingInterface.h | 19 ++++--- 9 files changed, 105 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index b279b7ca8d..6eaa9f8923 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/RadioButton.qml b/interface/resources/qml/controls-uit/RadioButton.qml index ab11ec68b1..1b36641418 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/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml index 58091d9fab..ce99eff8a3 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 92e7f59524..cdfa501bd3 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuView.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuView.qml @@ -11,9 +11,11 @@ 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 @@ -74,10 +76,14 @@ FocusScope { MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: listView.currentIndex = index + onEntered: { + tabletInterface.playSound(TabletEnums.ButtonHover) + listView.currentIndex = index + } + onClicked: { + tabletInterface.playSound(TabletEnums.ButtonClick) root.selected(item) - tabletRoot.playButtonClickSound(); } } } diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 36ea16d882..f36f3912ec 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 TabletScriptingInterface 1.0 import "../../dialogs" import "../../controls" diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a2cd5b4c5..40503fa4a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1828,6 +1828,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()); } diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index eb8451e5c3..97996fd59c 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -167,6 +167,10 @@ void Web3DOverlay::buildWebSurface() { if (!self) { return; } + auto tabletScreenID = DependencyManager::get()->getCurrentTabletScreenID(); + if (overlayID == tabletScreenID) { //play only on Tablet border crossing + DependencyManager::get()->playSound(TabletScriptingInterface::TabletHandsOut); + } if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) { PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), event.getButton(), event.getButtons(), event.getKeyboardModifiers()); @@ -174,6 +178,19 @@ void Web3DOverlay::buildWebSurface() { } }); + QObject::connect(overlays, &Overlays::hoverEnterOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) { + Q_UNUSED(event) + auto self = weakSelf.lock(); + if (!self) { + return; + } + + auto tabletScreenID = DependencyManager::get()->getCurrentTabletScreenID(); + if (overlayID == tabletScreenID) { //play only on Tablet border crossing + DependencyManager::get()->playSound(TabletScriptingInterface::TabletHandsIn); + } + }); + QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); } @@ -245,6 +262,8 @@ void Web3DOverlay::loadSourceURL() { _webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); _webSurface->getSurfaceContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("Tablet", DependencyManager::get().data()); + // Tablet inteference with Tablet.qml. Need to avoid this in QML space + _webSurface->getSurfaceContext()->setContextProperty("tabletInterface", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("Assets", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("LODManager", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 367f58bc0f..358e3c3ec6 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -22,7 +22,8 @@ #include "../InfoView.h" #include "ToolbarScriptingInterface.h" #include "Logging.h" -#include "SoundCache.h" + +#include #include "SettingHandle.h" @@ -30,17 +31,18 @@ const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system"; const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; -Setting::Handle tabletSoundsButtonClick("TabletSounds/buttonClick", "../../../sounds/Button06.wav"); -Setting::Handle tabletSoundsButtonHover("TabletSounds/buttonHover", "../../../sounds/Button04.wav"); -Setting::Handle tabletSoundsTabletOpen("TabletSounds/tabletOpen", "../../../sounds/Button07.wav"); -Setting::Handle tabletSoundsTabletHandsIn("TabletSounds/tabletHandsIn", "../../../sounds/Tab01.wav"); -Setting::Handle tabletSoundsTabletHandsOut("TabletSounds/tabletHandsOut", "../../../sounds/Tab02.wav"); +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() { @@ -71,10 +73,27 @@ TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { return tabletProxy; } -void TabletScriptingInterface::playSound(Tablet::AudioEvents aevent) { - QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); - SharedSoundPointer _snapshotSound = DependencyManager::get()-> - getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); +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 = options.localOnly || sound->isAmbisonic(); // force localOnly when Ambisonic + + AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options); + } } void TabletScriptingInterface::setToolbarMode(bool toolbarMode) { @@ -337,9 +356,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 c06bd9bf2e..edbbb58dd8 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; @@ -34,19 +34,22 @@ class TabletButtonProxy; class QmlWindowClass; class OffscreenQmlSurface; -namespace Tablet -{ - enum AudioEvents { ButtonClick, ButtonHover, TabletOpen, TabletHandsIn, TabletHandsOut }; -} /**jsdoc * @namespace Tablet */ + class TabletScriptingInterface : public QObject, public Dependency { Q_OBJECT + + public: + enum TabletAudioEvents { ButtonClick, ButtonHover, TabletOpen, TabletHandsIn, TabletHandsOut, Last}; + Q_ENUM(TabletAudioEvents) + TabletScriptingInterface(); virtual ~TabletScriptingInterface(); + void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; } /**jsdoc @@ -57,7 +60,9 @@ public: */ Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId); - Q_INVOKABLE void playSound(Tablet::AudioEvents aevent); + void preloadSounds(); + Q_INVOKABLE void playSound(TabletAudioEvents aEvent); + void setToolbarMode(bool toolbarMode); void setQmlTabletRoot(QString tabletId, OffscreenQmlSurface* offscreenQmlSurface); @@ -81,6 +86,7 @@ private: void processTabletEvents(QObject* object, const QKeyEvent* event); ToolbarProxy* getSystemToolbarProxy(); + QMap _audioEvents; protected: std::map _tabletProxies; ToolbarScriptingInterface* _toolbarScriptingInterface { nullptr }; @@ -313,7 +319,6 @@ protected: }; Q_DECLARE_METATYPE(TabletButtonProxy*); -Q_DECLARE_METATYPE(Tablet::AudioEvents); /**jsdoc * @typedef TabletButtonProxy.ButtonProperties From b5f0c4d940ea38a99b91406056f408e5e324934c Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 25 Sep 2017 16:46:36 +0200 Subject: [PATCH 08/19] Added settings controls sounds --- interface/resources/qml/controls-uit/Button.qml | 11 +++++++++++ interface/resources/qml/controls-uit/GlyphButton.qml | 11 +++++++++++ .../qml/dialogs/preferences/ButtonPreference.qml | 12 +++++++++++- .../qml/dialogs/preferences/CheckBoxPreference.qml | 11 +++++++++++ interface/src/Application.cpp | 2 ++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 59f8a63238..20174b13c2 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" @@ -23,6 +24,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/GlyphButton.qml b/interface/resources/qml/controls-uit/GlyphButton.qml index ac353b5a52..24ef4afdff 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/dialogs/preferences/ButtonPreference.qml b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml index 06332bd1be..bb959f1bee 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..7c336d7829 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/src/Application.cpp b/interface/src/Application.cpp index ce615a4739..b9289be47c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2310,6 +2310,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()); From 1a2d38e31f681a5bf0bf24dde9a1c1be1bb942f2 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 25 Sep 2017 17:11:44 +0200 Subject: [PATCH 09/19] Removed sounds for tablet in and out, added sounds for stylus instead. Added logging for testing semi-pressed laser and keyboard sounds --- interface/resources/qml/controls-uit/Key.qml | 8 ++++++++ .../resources/qml/hifi/tablet/TabletRoot.qml | 3 +-- interface/src/ui/overlays/Web3DOverlay.cpp | 17 ----------------- .../ui/src/ui/TabletScriptingInterface.cpp | 1 + .../controllerModules/tabletStylusInput.js | 3 +++ 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index 0c888d1a0a..b6227fd28e 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 { } } + onHoveredChanged: { + if (hovered) { + 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/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index f36f3912ec..ba9d06eee3 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,7 +1,6 @@ import QtQuick 2.0 import Hifi 1.0 import QtQuick.Controls 1.4 -import TabletScriptingInterface 1.0 import "../../dialogs" import "../../controls" @@ -147,7 +146,7 @@ Item { SoundEffect { id: buttonClickSound volume: 0.1 - source: "" + source: "../../../sounds/Gamemaster-Audio-button-click.wav" } function playButtonClickSound() { diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index ed86b3c5cf..df34b93ac3 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -167,10 +167,6 @@ void Web3DOverlay::buildWebSurface() { if (!self) { return; } - auto tabletScreenID = DependencyManager::get()->getCurrentTabletScreenID(); - if (overlayID == tabletScreenID) { //play only on Tablet border crossing - DependencyManager::get()->playSound(TabletScriptingInterface::TabletHandsOut); - } if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) { PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), event.getButton(), event.getButtons(), event.getKeyboardModifiers()); @@ -178,19 +174,6 @@ void Web3DOverlay::buildWebSurface() { } }); - QObject::connect(overlays, &Overlays::hoverEnterOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) { - Q_UNUSED(event) - auto self = weakSelf.lock(); - if (!self) { - return; - } - - auto tabletScreenID = DependencyManager::get()->getCurrentTabletScreenID(); - if (overlayID == tabletScreenID) { //play only on Tablet border crossing - DependencyManager::get()->playSound(TabletScriptingInterface::TabletHandsIn); - } - }); - QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); } diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 358e3c3ec6..d1763a8318 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -93,6 +93,7 @@ void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) { options.localOnly = options.localOnly || sound->isAmbisonic(); // force localOnly when Ambisonic AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options); + qDebug() << "playing sound for event" << aEvent; } } diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 9d01ceef65..51ac9f69e6 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -157,6 +157,8 @@ Script.include("/~/system/libraries/controllers.js"); return; } + tabletInterface.playSound(3);//HandsIn + var X_ROT_NEG_90 = { x: -0.70710678, y: 0, z: 0, w: 0.70710678 }; var modelOrientation = Quat.multiply(this.stylusTip.orientation, X_ROT_NEG_90); var modelPositionOffset = Vec3.multiplyQbyV(modelOrientation, { x: 0, y: 0, z: MyAvatar.sensorToWorldScale * -WEB_STYLUS_LENGTH / 2 }); @@ -184,6 +186,7 @@ Script.include("/~/system/libraries/controllers.js"); if (!this.stylus) { return; } + tabletInterface.playSound(4);//HandsOut Overlays.deleteOverlay(this.stylus); this.stylus = null; }; From b190fac4f17668ff93f651cc7aa8a2a903b1f284 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 25 Sep 2017 19:45:51 +0200 Subject: [PATCH 10/19] Fix stylus --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b9289be47c..55f4f5f46b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6008,6 +6008,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(); From 083b52abafb2cf4b7ac06d5a97ded2995ce0f677 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 25 Sep 2017 21:15:05 +0200 Subject: [PATCH 11/19] CHeck containsMouse property for mouse area instead on hovered --- interface/resources/qml/controls-uit/Key.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index b6227fd28e..26a78b08f5 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -33,8 +33,8 @@ Item { } } - onHoveredChanged: { - if (hovered) { + onContainsMouseChanged: { + if (containsMouse) { tabletInterface.playSound(TabletEnums.ButtonHover) } } From 074362b22868c622f5b27943f07385d2cdb04cce Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 25 Sep 2017 23:10:26 +0200 Subject: [PATCH 12/19] Remove logging --- libraries/ui/src/ui/TabletScriptingInterface.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index d1763a8318..358e3c3ec6 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -93,7 +93,6 @@ void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) { options.localOnly = options.localOnly || sound->isAmbisonic(); // force localOnly when Ambisonic AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options); - qDebug() << "playing sound for event" << aEvent; } } From f1d5df59263daeb3b0e08817ecf4f89e4dd09dd4 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 12 Oct 2017 18:26:50 +0200 Subject: [PATCH 13/19] Restore lost-in-merge context property --- interface/src/ui/overlays/Web3DOverlay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 2d154f30a2..363c85b395 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -247,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"); From b965049651b96d35ef5da15987c833c30c7909b5 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 12 Oct 2017 18:39:26 +0200 Subject: [PATCH 14/19] Do not produce sound and highlight on disabled items and menu separators --- interface/resources/qml/hifi/tablet/TabletMenuView.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/hifi/tablet/TabletMenuView.qml b/interface/resources/qml/hifi/tablet/TabletMenuView.qml index a8914b9763..f76d896cf2 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuView.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuView.qml @@ -73,6 +73,7 @@ FocusScope { onImplicitWidthChanged: listView !== null ? listView.recalcSize() : 0 MouseArea { + enabled: name !== "" && item.enabled anchors.fill: parent hoverEnabled: true onEntered: { From da734b628c73404c733ec275ef35819f4d48fc9e Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 12 Oct 2017 18:54:40 +0200 Subject: [PATCH 15/19] Remove sound on stylus show and hide --- .../system/controllers/controllerModules/tabletStylusInput.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 6111bf6d8e..29fa878cb1 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -157,8 +157,6 @@ Script.include("/~/system/libraries/controllers.js"); return; } - tabletInterface.playSound(3);//HandsIn - var X_ROT_NEG_90 = { x: -0.70710678, y: 0, z: 0, w: 0.70710678 }; var modelOrientation = Quat.multiply(this.stylusTip.orientation, X_ROT_NEG_90); var modelPositionOffset = Vec3.multiplyQbyV(modelOrientation, { x: 0, y: 0, z: MyAvatar.sensorToWorldScale * -WEB_STYLUS_LENGTH / 2 }); @@ -186,7 +184,6 @@ Script.include("/~/system/libraries/controllers.js"); if (!this.stylus) { return; } - tabletInterface.playSound(4);//HandsOut Overlays.deleteOverlay(this.stylus); this.stylus = null; }; From 35b146b59a0c402a0293b159cfd6ddcae87feb4c Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 12 Oct 2017 19:01:38 +0200 Subject: [PATCH 16/19] Added sounds in Audio menu --- .../resources/qml/controls-uit/CheckBoxQQC2.qml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/resources/qml/controls-uit/CheckBoxQQC2.qml b/interface/resources/qml/controls-uit/CheckBoxQQC2.qml index 92bad04d01..3f165bfc09 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 From 2d010980b000f934db80ef7985f83fad1df2e259 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 12 Oct 2017 19:15:09 +0200 Subject: [PATCH 17/19] Removed special sound for Mute and replace it with hover and click sounds --- interface/resources/qml/hifi/audio/MicBar.qml | 12 +++++++++++- scripts/system/dialTone.js | 6 ------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/audio/MicBar.qml b/interface/resources/qml/hifi/audio/MicBar.qml index e757d7cadf..81903111c0 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/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 From fa349a694c7c19f826f216f38d46661157cf4a8b Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 20 Oct 2017 15:12:09 +0200 Subject: [PATCH 18/19] Code style fixes --- interface/resources/qml/controls-uit/Button.qml | 4 ++-- interface/resources/qml/controls-uit/CheckBox.qml | 4 ++-- interface/resources/qml/controls-uit/CheckBoxQQC2.qml | 4 ++-- interface/resources/qml/controls-uit/GlyphButton.qml | 4 ++-- interface/resources/qml/controls-uit/Key.qml | 4 ++-- interface/resources/qml/controls-uit/RadioButton.qml | 4 ++-- .../resources/qml/dialogs/preferences/ButtonPreference.qml | 4 ++-- .../qml/dialogs/preferences/CheckBoxPreference.qml | 4 ++-- interface/resources/qml/hifi/audio/MicBar.qml | 4 ++-- interface/resources/qml/hifi/tablet/TabletButton.qml | 4 ++-- interface/resources/qml/hifi/tablet/TabletMenuView.qml | 6 +++--- libraries/ui/src/ui/TabletScriptingInterface.cpp | 2 +- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 75a696eebd..c068fdcfaf 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -29,12 +29,12 @@ Original.Button { onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } style: ButtonStyle { diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index 6eaa9f8923..22b25671c3 100644 --- a/interface/resources/qml/controls-uit/CheckBox.qml +++ b/interface/resources/qml/controls-uit/CheckBox.qml @@ -31,12 +31,12 @@ Original.CheckBox { activeFocusOnPress: true onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } // TODO: doesnt works for QQC1. check with QQC2 // onHovered: { -// tabletInterface.playSound(TabletEnums.ButtonHover) +// tabletInterface.playSound(TabletEnums.ButtonHover); // } style: CheckBoxStyle { diff --git a/interface/resources/qml/controls-uit/CheckBoxQQC2.qml b/interface/resources/qml/controls-uit/CheckBoxQQC2.qml index 3f165bfc09..32d69cf339 100644 --- a/interface/resources/qml/controls-uit/CheckBoxQQC2.qml +++ b/interface/resources/qml/controls-uit/CheckBoxQQC2.qml @@ -36,12 +36,12 @@ CheckBox { hoverEnabled: true onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } diff --git a/interface/resources/qml/controls-uit/GlyphButton.qml b/interface/resources/qml/controls-uit/GlyphButton.qml index 24ef4afdff..bc7bc636fe 100644 --- a/interface/resources/qml/controls-uit/GlyphButton.qml +++ b/interface/resources/qml/controls-uit/GlyphButton.qml @@ -27,12 +27,12 @@ Original.Button { onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } style: ButtonStyle { diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index 26a78b08f5..eda9c03fa2 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -35,13 +35,13 @@ Item { onContainsMouseChanged: { if (containsMouse) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } onClicked: { mouse.accepted = true; - tabletInterface.playSound(TabletEnums.ButtonClick) + 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 1b36641418..65d36d2dcb 100644 --- a/interface/resources/qml/controls-uit/RadioButton.qml +++ b/interface/resources/qml/controls-uit/RadioButton.qml @@ -30,12 +30,12 @@ Original.RadioButton { readonly property int checkRadius: 2 onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } // TODO: doesnt works for QQC1. check with QQC2 // onHovered: { -// tabletInterface.playSound(TabletEnums.ButtonHover) +// tabletInterface.playSound(TabletEnums.ButtonHover); // } style: RadioButtonStyle { diff --git a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml index bb959f1bee..907d8ffd8d 100644 --- a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml +++ b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml @@ -25,13 +25,13 @@ Preference { id: button onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } onClicked: { preference.trigger() - tabletInterface.playSound(TabletEnums.ButtonClick) + 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 7c336d7829..8904896ab7 100644 --- a/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml +++ b/interface/resources/qml/dialogs/preferences/CheckBoxPreference.qml @@ -41,12 +41,12 @@ Preference { id: checkBox onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } anchors { diff --git a/interface/resources/qml/hifi/audio/MicBar.qml b/interface/resources/qml/hifi/audio/MicBar.qml index 81903111c0..b6699d6ceb 100644 --- a/interface/resources/qml/hifi/audio/MicBar.qml +++ b/interface/resources/qml/hifi/audio/MicBar.qml @@ -61,12 +61,12 @@ Rectangle { scrollGestureEnabled: false; onClicked: { Audio.muted = !Audio.muted; - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } drag.target: dragTarget; onContainsMouseChanged: { if (containsMouse) { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); } } } diff --git a/interface/resources/qml/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml index 0a8773db54..169c7acec1 100644 --- a/interface/resources/qml/hifi/tablet/TabletButton.qml +++ b/interface/resources/qml/hifi/tablet/TabletButton.qml @@ -131,12 +131,12 @@ Item { } tabletButton.clicked(); if (tabletRoot) { - tabletInterface.playSound(TabletEnums.ButtonClick) + tabletInterface.playSound(TabletEnums.ButtonClick); } } onEntered: { tabletButton.isEntered = true; - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); if (tabletButton.isActive) { tabletButton.state = "hover active state"; diff --git a/interface/resources/qml/hifi/tablet/TabletMenuView.qml b/interface/resources/qml/hifi/tablet/TabletMenuView.qml index f76d896cf2..4a4a6b7f87 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuView.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuView.qml @@ -77,13 +77,13 @@ FocusScope { anchors.fill: parent hoverEnabled: true onEntered: { - tabletInterface.playSound(TabletEnums.ButtonHover) + tabletInterface.playSound(TabletEnums.ButtonHover); listView.currentIndex = index } onClicked: { - tabletInterface.playSound(TabletEnums.ButtonClick) - root.selected(item) + tabletInterface.playSound(TabletEnums.ButtonClick); + root.selected(item); } } } diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 9c2ae9eba9..b9da230715 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -92,7 +92,7 @@ void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) { AudioInjectorOptions options; options.stereo = sound->isStereo(); options.ambisonic = sound->isAmbisonic(); - options.localOnly = options.localOnly || sound->isAmbisonic(); // force localOnly when Ambisonic + options.localOnly = true; AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound->getByteArray(), options); } From 908d601a430b9da36cf0b1202750e5eec9e4b2d8 Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 20 Oct 2017 20:00:11 +0200 Subject: [PATCH 19/19] Code style fixes #1 --- .../resources/qml/dialogs/preferences/ButtonPreference.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml index 907d8ffd8d..3a5c850031 100644 --- a/interface/resources/qml/dialogs/preferences/ButtonPreference.qml +++ b/interface/resources/qml/dialogs/preferences/ButtonPreference.qml @@ -30,7 +30,7 @@ Preference { } onClicked: { - preference.trigger() + preference.trigger(); tabletInterface.playSound(TabletEnums.ButtonClick); } width: 180