Moved a timer from JS to QML; progress circle on Emote Indicator

This commit is contained in:
Zach Fox 2019-08-19 15:12:48 -07:00
parent fd287654f4
commit b40d5658e3
8 changed files with 87 additions and 39 deletions

View file

@ -2,6 +2,7 @@ module hifi.simplifiedUI.simplifiedControls
Button 1.0 Button.qml Button 1.0 Button.qml
CheckBox 1.0 CheckBox.qml CheckBox 1.0 CheckBox.qml
InputPeak 1.0 InputPeak.qml InputPeak 1.0 InputPeak.qml
ProgressCircle 1.0 ProgressCircle.qml
RadioButton 1.0 RadioButton.qml RadioButton 1.0 RadioButton.qml
Slider 1.0 Slider.qml Slider 1.0 Slider.qml
Switch 1.0 Switch.qml Switch 1.0 Switch.qml

View file

@ -46,13 +46,12 @@ var UTF_CODE = 0;
// Plays the specified sound at the specified position, volume, and localOnly // Plays the specified sound at the specified position, volume, and localOnly
// Only plays a sound if it is downloaded. // Only plays a sound if it is downloaded.
// Only plays one sound at a time. // Only plays one sound at a time.
var soundUrl = Script.resolvePath('./resources/sounds/emojiPopSound.wav'); var emojiCreateSound = SoundCache.getSound(Script.resolvePath('resources/sounds/emojiPopSound1.wav'));
var popSound = SoundCache.getSound(soundUrl); var emojiDestroySound = SoundCache.getSound(Script.resolvePath('resources/sounds/emojiPopSound2.wav'));
var injector; var injector;
var DEFAULT_VOLUME = 0.01; var DEFAULT_VOLUME = 0.01;
var local = false; var local = false;
function playSound(sound, volume, position, localOnly) { function playSound(sound, volume, position, localOnly) {
sound = sound || popSound;
volume = volume || DEFAULT_VOLUME; volume = volume || DEFAULT_VOLUME;
position = position || MyAvatar.position; position = position || MyAvatar.position;
localOnly = localOnly || local; localOnly = localOnly || local;
@ -342,7 +341,7 @@ function playPopAnimation() {
} else { } else {
// Start with the pop sound on the out // Start with the pop sound on the out
currentPopScale = finalInPopScale ? finalInPopScale : MAX_POP_SCALE; currentPopScale = finalInPopScale ? finalInPopScale : MAX_POP_SCALE;
playSound(); playSound(emojiDestroySound);
} }
} }
@ -375,7 +374,7 @@ function playPopAnimation() {
if (currentPopStep === POP_ANIMATION_STEPS) { if (currentPopStep === POP_ANIMATION_STEPS) {
if (popType === "in") { if (popType === "in") {
finalInPopScale = currentPopScale; finalInPopScale = currentPopScale;
playSound(); playSound(emojiCreateSound);
dimensions = [ dimensions = [
Math.max(dimensions.x, emojiMaxDimensions.x), Math.max(dimensions.x, emojiMaxDimensions.x),
Math.max(dimensions.y, emojiMaxDimensions.y), Math.max(dimensions.y, emojiMaxDimensions.y),

View file

@ -17,7 +17,6 @@ import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
import "../../resources/modules/emojiList.js" as EmojiList import "../../resources/modules/emojiList.js" as EmojiList
import "../../resources/modules/customEmojiList.js" as CustomEmojiList import "../../resources/modules/customEmojiList.js" as CustomEmojiList
import "./ProgressCircle"
Rectangle { Rectangle {
id: root id: root
@ -103,8 +102,8 @@ Rectangle {
Image { Image {
id: mainEmojiLowOpacity id: mainEmojiLowOpacity
width: 180 width: mainEmojiImage.width
height: 180 height: mainEmojiImage.height
anchors.centerIn: parent anchors.centerIn: parent
source: mainEmojiImage.source source: mainEmojiImage.source
opacity: 0.5 opacity: 0.5
@ -125,7 +124,7 @@ Rectangle {
} }
// The overlay used during the pie timeout // The overlay used during the pie timeout
ProgressCircle { SimplifiedControls.ProgressCircle {
id: progressCircle id: progressCircle
animationDuration: 7000 // Must match `TOTAL_EMOJI_DURATION_MS` in `simplifiedEmoji.js` animationDuration: 7000 // Must match `TOTAL_EMOJI_DURATION_MS` in `simplifiedEmoji.js`
anchors.centerIn: mainEmojiImage anchors.centerIn: mainEmojiImage

View file

@ -152,10 +152,10 @@ function toggleReaction(reaction) {
if (reactionEnding) { if (reactionEnding) {
endReactionWrapper(reaction); endReactionWrapper(reaction);
updateEmoteIndicatorIcon("images/emote_Icon.svg", true); updateEmoteIndicatorIcon("images/emote_Icon.svg");
} else { } else {
beginReactionWrapper(reaction); beginReactionWrapper(reaction);
updateEmoteIndicatorIcon("images/" + reaction + "_Icon.svg", true); updateEmoteIndicatorIcon("images/" + reaction + "_Icon.svg");
} }
} }
@ -279,11 +279,11 @@ function onMessageFromEmoteAppBar(message) {
switch (message.method) { switch (message.method) {
case "positive": case "positive":
triggerReactionWrapper("positive"); triggerReactionWrapper("positive");
updateEmoteIndicatorIcon("images/" + message.method + "_Icon.svg", true); updateEmoteIndicatorIcon("images/" + message.method + "_Icon.svg");
break; break;
case "negative": case "negative":
triggerReactionWrapper("negative"); triggerReactionWrapper("negative");
updateEmoteIndicatorIcon("images/" + message.method + "_Icon.svg", true); updateEmoteIndicatorIcon("images/" + message.method + "_Icon.svg");
break; break;
case "raiseHand": case "raiseHand":
case "applaud": case "applaud":
@ -312,13 +312,12 @@ function getEmojiURLFromCode(code) {
return "../../emojiApp/resources/images/emojis/52px/" + emojiFilename; return "../../emojiApp/resources/images/emojis/52px/" + emojiFilename;
} }
function updateEmoteIndicatorIcon(iconURL, colorOverlayVisible) { function updateEmoteIndicatorIcon(iconURL) {
emoteAppBarWindow.sendToQml({ emoteAppBarWindow.sendToQml({
"source": "simplifiedEmote.js", "source": "simplifiedEmote.js",
"method": "updateEmoteIndicator", "method": "updateEmoteIndicator",
"data": { "data": {
"iconURL": iconURL, "iconURL": iconURL
"colorOverlayVisible": colorOverlayVisible
} }
}); });
} }
@ -530,23 +529,12 @@ function shutdown() {
// #region EMOJI_UTILITY // #region EMOJI_UTILITY
var EMOJI_52_BASE_URL = "../../resources/images/emojis/52px/"; var EMOJI_52_BASE_URL = "../../resources/images/emojis/52px/";
// This duration must match the timeframe over which simplifiedEmoji.qml displays an emoji over the user's head
var EMOJI_DURATION_MS = 7000;
var restoreEmoteIndicatorIconTimeout;
function selectedEmoji(code) { function selectedEmoji(code) {
emojiAPI.addEmoji(code); emojiAPI.addEmoji(code);
// this URL needs to be relative to SimplifiedEmoteIndicator.qml // this URL needs to be relative to SimplifiedEmoteIndicator.qml
var emojiURL = getEmojiURLFromCode(code); var emojiURL = getEmojiURLFromCode(code);
updateEmoteIndicatorIcon(emojiURL, false); updateEmoteIndicatorIcon(emojiURL);
if (restoreEmoteIndicatorIconTimeout) {
Script.clearTimeout(restoreEmoteIndicatorIconTimeout);
}
restoreEmoteIndicatorIconTimeout = Script.setTimeout(function () {
updateEmoteIndicatorIcon("images/emote_Icon.svg", true);
restoreEmoteIndicatorIconTimeout = null;
}, EMOJI_DURATION_MS);
} }

View file

@ -15,6 +15,7 @@ import QtGraphicalEffects 1.0
import stylesUit 1.0 as HifiStylesUit import stylesUit 1.0 as HifiStylesUit
import TabletScriptingInterface 1.0 import TabletScriptingInterface 1.0
import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
Rectangle { Rectangle {
id: root id: root
@ -32,6 +33,8 @@ Rectangle {
emoteButtonsRepeater.itemAt(3).hovered || emoteButtonsRepeater.itemAt(3).hovered ||
emoteButtonsRepeater.itemAt(4).hovered || emoteButtonsRepeater.itemAt(4).hovered ||
emoteButtonsRepeater.itemAt(5).hovered) ? expandedWidth : originalWidth; emoteButtonsRepeater.itemAt(5).hovered) ? expandedWidth : originalWidth;
readonly property int totalEmojiDurationMS: 7000 // Must match `TOTAL_EMOJI_DURATION_MS` in `simplifiedEmoji.js`
readonly property string emoteIconSource: "images/emote_Icon.svg"
onRequestedWidthChanged: { onRequestedWidthChanged: {
root.requestNewWidth(root.requestedWidth); root.requestNewWidth(root.requestedWidth);
@ -54,14 +57,77 @@ Rectangle {
height: parent.height height: parent.height
width: root.originalWidth width: root.originalWidth
Image {
id: emoteIndicatorLowOpacity
width: emoteIndicator.width
height: emoteIndicator.height
anchors.centerIn: parent
source: emoteIndicator.source
opacity: 0.5
fillMode: Image.PreserveAspectFit
// All "reactions" have associated icon filenames that contain "Icon.svg"; emojis don't.
visible: emoteIndicator.source.toString().indexOf("Icon.svg") === -1
mipmap: true
}
Image { Image {
id: emoteIndicator id: emoteIndicator
width: 30 width: 30
height: 30 height: 30
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
source: "images/emote_Icon.svg" source: root.emoteIconSource
mipmap: true mipmap: true
visible: false
onSourceChanged: {
// All "reactions" have associated icon filenames that contain "Icon.svg"; emojis don't.
progressCircle.endAnimation = false;
progressCircle.arcEnd = 360;
progressCircle.endAnimation = true;
var sourceIsEmojiImage = source.toString().indexOf("Icon.svg") === -1;
// This kicks off the progress circle animation
if (sourceIsEmojiImage) {
progressCircle.arcEnd = 0;
restoreEmoteIconTimer.restart();
} else {
restoreEmoteIconTimer.stop();
}
}
}
Timer {
id: restoreEmoteIconTimer
running: false
repeat: false
interval: root.totalEmojiDurationMS
onTriggered: {
emoteIndicator.source = root.emoteIconSource;
}
}
// The overlay used during the pie timeout
SimplifiedControls.ProgressCircle {
id: progressCircle
animationDuration: root.totalEmojiDurationMS
anchors.centerIn: emoteIndicator
size: emoteIndicator.width * 2
opacity: 0.5
colorCircle: "#FFFFFF"
colorBackground: "#E6E6E6"
showBackground: false
isPie: true
arcBegin: 0
arcEnd: 360
visible: false
}
OpacityMask {
anchors.fill: emoteIndicator
source: emoteIndicator
maskSource: progressCircle
} }
ColorOverlay { ColorOverlay {
@ -69,7 +135,8 @@ Rectangle {
anchors.fill: emoteIndicator anchors.fill: emoteIndicator
source: emoteIndicator source: emoteIndicator
color: "#ffffff" color: "#ffffff"
opacity: 1 // All "reactions" have associated icon filenames that contain "Icon.svg"; emojis don't.
opacity: emoteIndicator.source.toString().indexOf("Icon.svg") > -1 ? 1.0 : 0.0
} }
MouseArea { MouseArea {
@ -188,15 +255,9 @@ Rectangle {
case "updateEmoteIndicator": case "updateEmoteIndicator":
print("CHANGING INDICATOR TO: ", JSON.stringify(message)); print("CHANGING INDICATOR TO: ", JSON.stringify(message));
if (message.data.iconURL) { if (message.data.iconURL) {
var imageURL = message.data.iconURL; emoteIndicator.source = message.data.iconURL;
emoteIndicator.source = imageURL; } else {
if (message.data.colorOverlayVisible) { console.log("SimplifiedEmoteIndicator.qml: Error! `updateEmoteIndicator()` called without a new `iconURL`!");
print("SET OPACITY TO 1");
emoteIndicatorColorOverlay.opacity = 1;
} else {
print("SET OPACITY TO 0");
emoteIndicatorColorOverlay.opacity = 0;
}
} }
break; break;