mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
278 lines
No EOL
11 KiB
QML
278 lines
No EOL
11 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 "qrc:////qml//hifi//simplifiedUI//simplifiedConstants" 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/"
|
|
// Sprite sheet used for the smaller icons
|
|
readonly property string emojiSpriteBaseURL: "../../resources/images/emojis/"
|
|
// 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
|
|
|
|
|
|
/*
|
|
This is what the individual view will be. It's a bit complicated, but it works. Might not be worth
|
|
refactoring, but might want to check with Zach if he has an issue with below.
|
|
Here is reasoning / logic:
|
|
|
|
The icons displayed are implemented with a sprite sheet from the previous HTML version.
|
|
QML seems to have something that lets you play spritesheet animations, but it doesn't have something
|
|
that is like background-position for css.
|
|
|
|
The way I had to recreate it was to use an Image that has no set size / height and to make sure nothing is transformed
|
|
to fit a container.
|
|
|
|
Then I have to put that in a rectangle that acts like a mask. The x,y position of the image on the emoji meta data is what
|
|
is used to move the image x and y itself. The emoji images per sprite shell are 36 x 36. In grid view, there are no spacing
|
|
options besides making the cell width and grid have fake extra padding. I can't make that rectangle that is the mask to be larger than 36 by 36.
|
|
What worked the best was to make another container rectangle the width of the cell, then positioned the emoji mask rectangle to be centered in that.
|
|
|
|
The gridview has a function to handle the highlighting which is nice because it comes with an animation already that looks good out the box.
|
|
This covers the whole 40X40 cell space.
|
|
|
|
*/
|
|
Component {
|
|
id: emojiDelegate
|
|
Item {
|
|
width: grid.cellWidth; height: grid.cellHeight
|
|
Column {
|
|
Rectangle {
|
|
width: 40
|
|
height: 40
|
|
color: Qt.rgba(1, 1, 1, 0.0)
|
|
Rectangle {
|
|
id: imageContainer
|
|
anchors.centerIn: parent
|
|
clip: true;
|
|
z:1
|
|
width: 36
|
|
height: 36
|
|
anchors.leftMargin: 2
|
|
anchors.topMargin: 2
|
|
x: 1
|
|
y: -1
|
|
color: Qt.rgba(1, 1, 1, 0.0)
|
|
Image {
|
|
source: emojiSpriteBaseURL + normal.source
|
|
z: 2
|
|
fillMode: Image.Pad
|
|
x: -normal.frame.x
|
|
y: -normal.frame.y
|
|
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;
|
|
}
|
|
onExited: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
GridView {
|
|
id: grid
|
|
anchors.fill: parent
|
|
anchors.centerIn: parent
|
|
anchors.leftMargin: 0
|
|
anchors.rightMargin: 0
|
|
width: 480
|
|
height: 415
|
|
cellWidth: 40
|
|
cellHeight: 40
|
|
model: mainModel
|
|
delegate: emojiDelegate
|
|
focus: true
|
|
highlight: Rectangle { color: Qt.rgba(1, 1, 1, 0.4); radius: 0 }
|
|
}
|
|
}
|
|
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));
|
|
}
|
|
}
|
|
} |