overte-thingvellir/scripts/simplifiedUI/simplifiedEmote/emojiApp/ui/qml/SimplifiedEmoji.qml
2019-08-15 10:58:13 -07:00

231 lines
No EOL
7.8 KiB
QML

//
// SimplifiedEmoji.qml
//
// Created by Milad Nazeri on 2019-08-03
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.12
import QtQuick.Controls 2.4
import QtGraphicalEffects 1.12
import stylesUit 1.0 as HifiStylesUit
import TabletScriptingInterface 1.0
import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
import "../../resources/modules/emojiList.js" as EmojiList
import "./ProgressCircle"
Rectangle {
id: root
color: simplifiedUI.colors.darkBackground
anchors.fill: parent
// Used for the indicator picture
readonly property string emojiBaseURL: "../../resources/images/emojis/png1024/"
readonly property string emoji36BaseURL: "../../resources/images/emojis/png36/"
// Capture the selected code to handle which emoji to show
property string currentCode: ""
// if this is true, then hovering doesn't allow showing other icons
property bool isSelected: false
// Update the selected emoji image whenever the code property is changed.
onCurrentCodeChanged: {
mainEmojiImage.source = emojiBaseURL + currentCode + ".png";
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
focus: true
ListModel {
id: mainModel
}
Component.onCompleted: {
root.forceActiveFocus();
/*
MILAD NOTE:
The emoji list we have is a node transformed list of all the UTF emojis with meta info.
To cut down on the list, this is a good place to start as they will be 90% of the emojis anyone would
want to use.
To save some space, we should probably remove any images from the current ones that aren't the below emojis.
Let's make a separate ticket for this as this is going to need a little work in the current node app. Not much
but I didn't want to focus on it for this sprint.
I can also prune that large emoji json as well to have only the ones we want listed. That can be added to that
ticket as well. This is something I can probably knock out on the plane to Italy becaues I don't want those large
files to be in the repo or loading that big config.json file.
*/
EmojiList.emojiList
.filter( emoji => {
return emoji.mainCategory === "Smileys & Emotion" ||
emoji.mainCategory === "People & Body" ||
emoji.mainCategory === "Animals & Nature" ||
emoji.mainCategory === "Food & Drink";
})
// Convert the filtered list to seed our QML Model used for our view
.forEach(function(item, index){
item.code = { utf: item.code[0] }
item.keywords = { keywords: item.keywords }
mainModel.append(item);
});
// Deleting this might remove any emoji that is shown when you open the app
// Keeping in case the spec design might prefer this instead
root.currentCode = mainModel.get(0).code.utf;
}
Rectangle {
id: emojiIndicatorContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 200
clip: true
color: simplifiedUI.colors.darkBackground
Image {
id: mainEmojiImage
width: 180
height: 180
anchors.centerIn: parent
source: ""
fillMode: Image.PreserveAspectFit
visible: false
}
Image {
id: mainEmojiLowOpacity
width: 180
height: 180
anchors.centerIn: parent
source: mainEmojiImage.source
opacity: 0.5
fillMode: Image.PreserveAspectFit
visible: true
}
// The overlay used during the pie timeout
ProgressCircle {
property int arcChangeSize: 15
id: progressCircle
anchors.centerIn: mainEmojiImage
size: mainEmojiImage.width * 2
opacity: 0.5
colorCircle: "#FFFFFF"
colorBackground: "#E6E6E6"
showBackground: false
isPie: true
arcBegin: 0
arcEnd: 0
visible: false
}
OpacityMask {
anchors.fill: mainEmojiImage
source: mainEmojiImage
maskSource: progressCircle
}
Timer {
id: arcTimer
interval: 5000
repeat: true
running: false
onTriggered: {
progressCircle.arcEnd = ((progressCircle.arcEnd - progressCircle.arcChangeSize) > 0) ? (progressCircle.arcEnd - progressCircle.arcChangeSize) : 0;
}
}
}
Rectangle {
id: emojiIconListContainer
anchors.top: emojiIndicatorContainer.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
clip: true
color: simplifiedUI.colors.darkBackground
Component {
id: emojiDelegate
Image {
width: 36
height: 36
source: emoji36BaseURL + mainModel.get(index).code.utf + ".png"
fillMode: Image.Pad
MouseArea {
hoverEnabled: enabled
anchors.fill: parent
onEntered: {
grid.currentIndex = index
// don't allow a hover image change of the main emoji image
if (root.isSelected) {
return;
}
// Updates the selected image
root.currentCode = mainModel.get(index).code.utf;
}
onClicked: {
sendToScript({
"source": "SimplifiedEmoji.qml",
"method": "selectedEmoji",
"code": code.utf
});
root.isSelected = true;
root.currentCode = mainModel.get(index).code.utf;
}
}
}
}
GridView {
id: grid
anchors.fill: parent
anchors.leftMargin: 14
anchors.rightMargin: 14
cellWidth: 40
cellHeight: 40
model: mainModel
delegate: emojiDelegate
cacheBuffer: 400
focus: true
highlight: Rectangle { color: Qt.rgba(1, 1, 1, 0.4); radius: 0 }
}
SimplifiedControls.VerticalScrollBar {
parent: grid
anchors.rightMargin: -grid.anchors.rightMargin + 2
}
}
signal sendToScript(var message);
function fromScript(message) {
if (message.source !== "simplifiedEmoji.js") {
return;
}
switch(message.method) {
case "beginCountdownTimer":
var degreesInCircle = 360;
progressCircle.arcEnd = degreesInCircle;
arcTimer.interval = message.data.interval;
progressCircle.arcChangeSize = degreesInCircle / (message.data.duration / arcTimer.interval);
arcTimer.start();
root.isSelected = true;
break;
case "clearCountdownTimer":
progressCircle.arcEnd = 0;
arcTimer.stop();
root.isSelected = false;
break;
default:
console.log("Message not recognized from simplifiedEmoji.js", JSON.stringify(message));
}
}
}