opaque/EmojiDrawer.qml

404 lines
15 KiB
QML

import QtGraphicalEffects 1.0
import QtQuick 2.13
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
import Qt.labs.folderlistmodel 2.13
import QtQml.Models 2.13
import "fonts/MutantStandard.js" as Mutant
import "controls"
import "theme"
Item {
id: root
implicitHeight: 0
height: implicitHeight
property int size: 24
property int requestedHeight: size * 8
property string morph: "clw"
property string color: "v1"
property bool narrowMode: width < (txtSearch.width + root.size * 14 + btnX.width)
signal picked(string shortcode)
signal slideopen()
signal slideclosed()
visible: height != 0
Rectangle {
color: Theme.backgroundPaneColor
anchors.fill: parent
}
PropertyAnimation {
id: animClose;
target: root;
properties: "implicitHeight";
to: 0;
duration: 400;
}
PropertyAnimation {
id: animOpen;
target: root;
properties: "implicitHeight";
to: requestedHeight;
duration: 400;
}
Button {
id: btnX
anchors.top: parent.top
anchors.right: parent.right
text: "x"
onClicked: animClose.start()
}
ColumnLayout {
anchors.fill: parent
RowLayout {
TextField {
id: txtSearch
//: Search...
placeholderText: qsTr("search")
onTextChanged: {
if (text == "") emojiModel.model = folder_expressions
else emojiModel.model = folder_search
emojiModel.updatefilters()
}
}
ImageButton {
id: btnEmojiExpressionsGroup
visible: !root.narrowMode
//: Expressions
tooltip: qsTr("emojicat-expressions")
source: gcd.assetPath + "mutstd/smile.webp"
size: root.size
onClicked: emojiModel.model = folder_expressions
}
ImageButton {
visible: !root.narrowMode
//: Activities
tooltip: qsTr("emojicat-activities")
source: gcd.assetPath + "mutstd/artist_r1.webp"
size: root.size
onClicked: emojiModel.model = folder_activities_clothing
}
ImageButton {
visible: !root.narrowMode
//: Food, drink & herbs
tooltip: qsTr("emojicat-food")
source: gcd.assetPath + "mutstd/red_apple.webp"
size: root.size
onClicked: emojiModel.model = folder_food_drink_herbs
}
ImageButton {
visible: !root.narrowMode
//: Gender, relationships & sexuality
tooltip: qsTr("emojicat-gender")
size: root.size
source: gcd.assetPath + "mutstd/pride_100.webp"
onClicked: emojiModel.model = folder_gsr
}
ImageButton {
visible: !root.narrowMode
//: Nature and effects
tooltip: qsTr("emojicat-nature")
source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp"
size: root.size
onClicked: emojiModel.model = folder_nature
}
ImageButton {
visible: !root.narrowMode
//: Objects
tooltip: qsTr("emojicat-objects")
source: gcd.assetPath + "mutstd/crystal_ball.webp"
size: root.size
onClicked: emojiModel.model = folder_objects
}
ImageButton {
visible: !root.narrowMode
//: People and animals
tooltip: qsTr("emojicat-people")
source: gcd.assetPath + "mutstd/crow.webp"
size: root.size
onClicked: emojiModel.model = folder_people
}
ImageButton {
visible: !root.narrowMode
//: Symbols
tooltip: qsTr("emojicat-symbols")
source: gcd.assetPath + "mutstd/purple_heart.webp"
size: root.size
onClicked: emojiModel.model = folder_symbols
}
ImageButton {
visible: !root.narrowMode
//: Travel & places
tooltip: qsTr("emojicat-travel")
source: gcd.assetPath + "mutstd/airplane.webp"
size: root.size
onClicked: emojiModel.model = folder_travel_places
}
ImageButton {
visible: !root.narrowMode
//: Miscellaneous
tooltip: qsTr("emojicat-misc")
source: gcd.assetPath + "mutstd/hash_char.webp"
size: root.size
onClicked: emojiModel.model = folder_utils
}
ImageButton {
visible: !root.narrowMode
id: btnUndefinedGroup
// (no tooltip; this is a catchall group meant to detect unclassified emoji during development)
//TODO: remove this category upon finalizing the Emoji Drawer
source: gcd.assetPath + "mutstd/undefined_character.webp"
size: root.size
onClicked: emojiModel.model = folder_other
}
Item {
visible: root.narrowMode
height: root.size
width: root.size
Image {
id: imgCatRot
anchors.centerIn: parent
source: cats[index].source
property int index: 0
property var cats: [
{source: gcd.assetPath + "mutstd/smile.webp", model: folder_expressions},
{source: gcd.assetPath + "mutstd/artist_r1.webp", model: folder_activities_clothing},
{source: gcd.assetPath + "mutstd/red_apple.webp", model: folder_food_drink_herbs},
{source: gcd.assetPath + "mutstd/pride_100.webp", model: folder_gsr},
{source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp", model: folder_nature},
{source: gcd.assetPath + "mutstd/crystal_ball.webp", model: folder_objects},
{source: gcd.assetPath + "mutstd/crow.webp", model: folder_people},
{source: gcd.assetPath + "mutstd/purple_heart.webp", model: folder_symbols},
{source: gcd.assetPath + "mutstd/airplane.webp", model: folder_travel_places},
{source: gcd.assetPath + "mutstd/hash_char.webp", model: folder_utils},
{source: gcd.assetPath + "mutstd/undefined_character.webp", model: folder_other}
]
height: root.size * (maCatRot.pressed ? 0.8 : 1.0)
width: root.size * (maCatRot.pressed ? 0.8 : 1.0)
ToolTip.visible: maCatRot.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-cats-android") : qsTr("cycle-cats-desktop")
MouseArea {
id: maCatRot
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgCatRot.index = 0
} else {
imgCatRot.index = (imgCatRot.index + 1) % imgCatRot.cats.length
}
emojiModel.model = imgCatRot.cats[imgCatRot.index].model
//root.morph = Mutant.standard.morphs[imgMorph.index]
//emojiModel.updatefilters()
}
}
}
}
Item {
height: root.size
width: root.size
Image {
id: imgMorph
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/hand_"+Mutant.standard.morphs[index]+"_"+root.color+".webp"
property int index: 0
height: root.size
width: root.size
ToolTip.visible: maMorph.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-morphs-android") : qsTr("cycle-morphs-desktop")
MouseArea {
id: maMorph
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgMorph.index = 0//TODO: saved morph
} else {
imgMorph.index = (imgMorph.index + 1) % Mutant.standard.morphs.length
}
root.morph = Mutant.standard.morphs[imgMorph.index]
emojiModel.updatefilters()
}
}
}
}
Item {
height: root.size
width: root.size
Image {
id: imgColor
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/color_modifier_"+Mutant.standard.colorByIndex(index, root.morph)+".webp"
property int index: 0
height: root.size
width: root.size
ToolTip.visible: ma.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-colours-android") : qsTr("cycle-colours-desktop")
MouseArea {
id: ma
anchors.fill: parent;
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: function(mouse){
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgColor.index = 0//todo: saved color
} else {
imgColor.index = (imgColor.index + 1) % Mutant.standard.numColors(root.morph)
}
root.color = Mutant.standard.colorByIndex(imgColor.index, root.morph)
emojiModel.updatefilters()
}
}
}
}
}
GridView {
Layout.fillWidth: true
Layout.fillHeight: true
height: root.size * 3
cellWidth: root.size
cellHeight: root.size
clip: true
ScrollBar.vertical: ScrollBar {}
maximumFlickVelocity: 1250
boundsBehavior: GridView.StopAtBounds
model: emojiModel
}
}
ListModel { id: folder_activities_clothing }
ListModel { id: folder_expressions }
ListModel { id: folder_food_drink_herbs }
ListModel { id: folder_gsr }
ListModel { id: folder_nature }
ListModel { id: folder_objects }
ListModel { id: folder_people }
ListModel { id: folder_symbols }
ListModel { id: folder_travel_places }
ListModel { id: folder_utils }
ListModel { id: folder_other }
ListModel { id: folder_search }
DelegateModel {
id: emojiModel
model: folder_expressions
delegate: Item {
width: root.size
height: root.size
Image {
id: img
//source: "file://" + gcd.binaryPath + "/assets/mutstd/" + code + ".webp"
source: gcd.assetPath + "mutstd/" + code + ".webp"
width: root.size * (mouseArea.pressed ? 0.7 : 0.8)
height: width
anchors.centerIn: parent
property string shortcode: code
ToolTip.visible: mouseArea.containsMouse
ToolTip.text: desc + "\n:" + shortcode + ":"
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: root.picked(img.shortcode)
}
}
}
Component.onCompleted: updatefilters()
function clearall() {
folder_activities_clothing.clear()
folder_expressions.clear()
folder_food_drink_herbs.clear()
folder_gsr.clear()
folder_nature.clear()
folder_objects.clear()
folder_people.clear()
folder_symbols.clear()
folder_travel_places.clear()
folder_utils.clear()
folder_other.clear()
folder_search.clear()
}
function updatefilters() {
clearall()
for (var i in Mutant.standard.manifest) {
if (typeof Mutant.standard.manifest[i].morph !== "undefined" && Mutant.standard.manifest[i].morph != root.morph)
continue;
if (typeof Mutant.standard.manifest[i].color !== "undefined" && Mutant.standard.manifest[i].color != root.color)
continue;
if (txtSearch.text != "" && !(Mutant.standard.manifest[i].code.includes(txtSearch.text) || Mutant.standard.manifest[i].desc.includes(txtSearch.text))) {
continue;
}
var model = folder_other
if (txtSearch.text == "") {
switch(Mutant.standard.manifest[i].cat) {
case "activities_clothing": model = folder_activities_clothing; break;
case "expressions": model = folder_expressions; break;
case "symbols": model = folder_symbols; break;
case "food_drink_herbs": model = folder_food_drink_herbs; break;
case "gsr": model = folder_gsr; break;
case "nature": model = folder_nature; break;
case "objects": model = folder_objects; break;
case "people": model = folder_people; break;
case "travel_places": model = folder_travel_places; break;
case "utils": model = folder_utils; break;
}
} else {
model = folder_search
}
model.append({
cat: Mutant.standard.manifest[i].cat,
code: Mutant.standard.manifest[i].code,
color: Mutant.standard.manifest[i].color,
morph: Mutant.standard.manifest[i].morph,
desc: Mutant.standard.manifest[i].desc
})
}
}
}
onSlideopen: animOpen.start()
onSlideclosed: animClose.start()
}