mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-28 01:09:19 +00:00
273 lines
No EOL
9.1 KiB
QML
273 lines
No EOL
9.1 KiB
QML
import QtQuick 2.7
|
|
import QtQuick.Layouts 1.3
|
|
|
|
import Common 1.0
|
|
import Common.Styles 1.0
|
|
import Linphone 1.0
|
|
import Units 1.0
|
|
import UtilsCpp 1.0
|
|
|
|
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
|
|
|
Item{
|
|
id: mainItem
|
|
property font customFont : SettingsModel.textMessageFont
|
|
signal emojiClicked(var emoji)
|
|
|
|
width: 500
|
|
height: mainLayout.height
|
|
|
|
property var emojis:{
|
|
"emoticons": [[0x1F600, 0x1F64F]]
|
|
, "misc": [ [0x1F300, 0x1F5FF],[0x2600, 0x26FF], [0x238C, 0x2426], [0x2440, 0x2449] ]
|
|
, "maps": [ [0x1F680, 0x1F6D7], [0x1F6E0, 0x1F6EC], [0x1F6F0, 0x1F6FC] ]
|
|
, "flags": [ [0x1F1E6, 0x1F1FF] ]
|
|
, "dingbats": [ [0x2700, 0x27B0] ]
|
|
, "picto": [ [0x1F900, 0x1F978], [0x1F980, 0x1F9CB], [0x1F9CD, 0x1F9FF] ]
|
|
, "asian": [ [0x1F018, 0x1F02B], [0x1F030, 0x1F093], [0x1F0A0, 0x1F0AE], [0x1F0B1, 0x1F0BF], [0x1F0C1, 0x1F0CF], [0x1F0D1, 0x1F0F5], [0x1F100, 0x1F10C], [0x1F110, 0x1F16C], [0x1F170, 0x1F1AC], [0x1F1E6, 0x1F202], [0x1F210, 0x1F23B], [0x1F240, 0x1F248], [0x1F250, 0x1F251], [0x1F260, 0x1F264] ]
|
|
, "marks": [ [0x2010, 0x2027], [0x2030, 0x205E], [0x2070, 0x209C], [0x20A0, 0x20BF]] //0x20BF], [0x20D0, 0x20EE] ]
|
|
}
|
|
|
|
function getArrayLength(iconArray){
|
|
return iconArray[1] - iconArray[0]
|
|
}
|
|
property int maxIndex: {
|
|
var count = 0
|
|
for( var i in emojis){
|
|
for(var j in emojis[i]){
|
|
count += getArrayLength(emojis[i][j])
|
|
}
|
|
}
|
|
console.log("Max items : " +count)
|
|
return count
|
|
}
|
|
function getEmojiCodeInArray(index, iconArray){
|
|
var length = getArrayLength(iconArray)
|
|
if( index < length )
|
|
return [iconArray[0] + index, index];
|
|
else {
|
|
return [-1, index - length]
|
|
}
|
|
|
|
}
|
|
function getEmojiCodeInMatrix(index, matrix, emojiIndex){
|
|
var result = [-1, index]
|
|
while(result[0]<0 && emojiIndex < matrix.length) result = getEmojiCodeInArray(result[1], matrix[emojiIndex++])
|
|
return result
|
|
}
|
|
|
|
function getEmojiCode(index){
|
|
var result = [-1, index]
|
|
result = getEmojiCodeInMatrix(result[1], emojis.emoticons, 0)
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.misc[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.maps[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.flags[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.dingbats[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.picto[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.asian[0])
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInArray(result[1], emojis.marks[0])
|
|
else return result[0]
|
|
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.misc, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.maps, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.flags, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.dingbats, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.picto, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.asian, 1)
|
|
else return result[0]
|
|
if(result[0]<0) result = getEmojiCodeInMatrix(result[1], emojis.marks, 1)
|
|
else return result[0]
|
|
|
|
return result[0]
|
|
}
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
cursorShape: Qt.ArrowCursor
|
|
}
|
|
ColumnLayout{
|
|
id: mainLayout
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.margins: 5
|
|
spacing: 0
|
|
Text{
|
|
Layout.bottomMargin: 5
|
|
Layout.fillWidth: true
|
|
//: 'Last used' : Emoji title for last used section.
|
|
text: qsTr('emojisLastUsed')
|
|
property font customFont : SettingsModel.textMessageFont
|
|
font.pointSize: Units.dp * customFont.pointSize
|
|
font.family: customFont.family
|
|
font.weight: Font.Bold
|
|
visible: gridPreferred.model.length > 0
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
onClicked: EmojisSettingsModel.clear()
|
|
}
|
|
}
|
|
GridLayout{
|
|
id: gridPreferred
|
|
Layout.fillWidth: true
|
|
Layout.preferredWidth: parent.width
|
|
Layout.preferredHeight: availableRows * emojiSize
|
|
|
|
property int emojiSize: EmojiPickerStyle.emojiSize + EmojiPickerStyle.emojiMargin // emoji + margin. margin is set here in order to avoid the use of spacing. This way, the height computation is easer to get.
|
|
property int availableColumns : width /emojiSize
|
|
property int availableRows : (model.length - 1) / availableColumns + 1
|
|
columns: availableColumns
|
|
columnSpacing: 0
|
|
rowSpacing: 0
|
|
property var model: EmojisSettingsModel.lastUseds// Use this model inderction becaus eof Repeater that don't refresh values when the model change (that comes from EmojiSettingsModel which is a list of int)
|
|
|
|
onModelChanged: {
|
|
emojisPreferredRepeater.model = 0 // Force reset model
|
|
emojisPreferredRepeater.model = model.length
|
|
}
|
|
Repeater{
|
|
id: emojisPreferredRepeater
|
|
model: parent.length
|
|
Text{
|
|
height: gridPreferred.emojiSize
|
|
width: gridPreferred.emojiSize
|
|
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
|
font.pointSize: Units.dp * 20
|
|
font.family: customFont.family
|
|
property int code: gridPreferred.model[index]
|
|
property string stringCodePoint: code >=0 ? String.fromCodePoint(code) : ''
|
|
text: UtilsCpp.encodeTextToQmlRichFormat(stringCodePoint)
|
|
|
|
textFormat: Text.RichText
|
|
visible: code >= 0
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
onClicked: {console.log("Emoji code : "+code+"(" +parseInt(code, 10).toString(16)+") => "+stringCodePoint);emojiClicked(stringCodePoint)}
|
|
}
|
|
}
|
|
}
|
|
Repeater{// Fill empty spaces if needed
|
|
model: Math.max(gridPreferred.availableColumns - gridPreferred.model.length, 0)
|
|
Item{ height: gridPreferred.emojiSize
|
|
width: gridPreferred.emojiSize
|
|
}
|
|
}
|
|
}
|
|
Text{
|
|
Layout.bottomMargin: 5
|
|
Layout.fillWidth: true
|
|
//: 'All' Emoji title for all items.
|
|
text: qsTr('emojisAll')
|
|
property font customFont : SettingsModel.textMessageFont
|
|
font.pointSize: Units.dp * customFont.pointSize
|
|
font.family: customFont.family
|
|
font.weight: Font.Bold
|
|
}
|
|
|
|
GridLayout{
|
|
id: grid
|
|
Layout.fillWidth: true
|
|
Layout.preferredWidth: parent.width
|
|
|
|
Layout.preferredHeight: availableRows * emojiSize
|
|
|
|
property int emojiSize: EmojiPickerStyle.emojiSize + EmojiPickerStyle.emojiMargin
|
|
property int availableColumns : width /emojiSize
|
|
property int availableRows : (grid.auxItemDisplayed + grid.auxItemsCount - 1) / availableColumns + 1
|
|
|
|
property int auxItemDisplayed:0
|
|
property int firstItemDisplayed: 0
|
|
property int auxItemsCount: 160
|
|
|
|
columns: availableColumns
|
|
columnSpacing: 0
|
|
rowSpacing: 0
|
|
|
|
Repeater{
|
|
id: emojisRepeater
|
|
model: grid.auxItemsCount // Repeat prioritized items.
|
|
Text{
|
|
height: grid.emojiSize
|
|
width: grid.emojiSize
|
|
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
|
font.pointSize: Units.dp * 20
|
|
font.family: customFont.family
|
|
property int code: mainItem.getEmojiCode(index)
|
|
property string stringCodePoint: code >=0 ? String.fromCodePoint(code) : ''
|
|
text: UtilsCpp.encodeTextToQmlRichFormat(stringCodePoint)
|
|
|
|
textFormat: Text.RichText
|
|
visible: code >=0 && grid.firstItemDisplayed == grid.auxItemsCount
|
|
Component.onCompleted: ++grid.firstItemDisplayed
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
onClicked: {console.log("Emoji code : "+code+"(" +parseInt(code, 10).toString(16)+") => "+stringCodePoint);
|
|
EmojisSettingsModel.addLastUsed(code);
|
|
emojiClicked(stringCodePoint)}
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer{
|
|
id: refreshItems
|
|
repeat: true
|
|
interval: 1000
|
|
running: grid.auxItemDisplayed<mainItem.maxIndex-grid.auxItemsCount
|
|
property int lastCount: 0
|
|
onTriggered: {
|
|
console.log("Loaded emojis : " +(grid.auxItemDisplayed - lastCount))
|
|
lastCount = grid.auxItemDisplayed
|
|
}
|
|
}
|
|
// Repeat loader items to load auxillary data without freezing gui or other items.
|
|
// Make a Loader of Repeater (to avoid multiple loader) doesn't seems to work (TODO: investigation needed)
|
|
Repeater{
|
|
model: mainItem.maxIndex - grid.auxItemsCount
|
|
Loader{
|
|
active: grid.firstItemDisplayed == grid.auxItemsCount
|
|
Connections{
|
|
target: refreshItems
|
|
onTriggered: if(status === Loader.Ready){
|
|
++grid.auxItemDisplayed
|
|
visible = true
|
|
target = null // signal optimization : one-call trigger.
|
|
}
|
|
}
|
|
visible: false
|
|
|
|
sourceComponent:
|
|
Text{
|
|
height: grid.emojiSize
|
|
width: grid.emojiSize
|
|
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
|
font.pointSize: Units.dp * 20
|
|
font.family: customFont.family
|
|
property int code: mainItem.getEmojiCode(index+grid.auxItemsCount)
|
|
property string stringCodePoint: code >=0 ? String.fromCodePoint(code) : ''
|
|
text: UtilsCpp.encodeTextToQmlRichFormat(stringCodePoint)
|
|
|
|
textFormat: Text.RichText
|
|
visible: code >= 0
|
|
MouseArea{
|
|
anchors.fill: parent
|
|
onClicked: {console.log("Emoji code : "+code+"(" +parseInt(code, 10).toString(16)+") => "+stringCodePoint);
|
|
EmojisSettingsModel.addLastUsed(code);
|
|
emojiClicked(stringCodePoint)}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
} |