mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
Moved a timer from JS to QML; progress circle on Emote Indicator
This commit is contained in:
parent
fd287654f4
commit
b40d5658e3
8 changed files with 87 additions and 39 deletions
|
@ -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
|
||||||
|
|
Binary file not shown.
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue