matrixion/resources/qml/emoji/StickerPicker.qml

260 lines
9.8 KiB
QML
Raw Normal View History

// SPDX-FileCopyrightText: Nheko Contributors
2021-07-15 21:37:52 +03:00
//
// SPDX-License-Identifier: GPL-3.0-or-later
import "../"
2023-06-02 01:43:38 +03:00
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import im.nheko
2021-07-15 21:37:52 +03:00
Menu {
id: stickerPopup
property var callback
2023-05-25 20:07:13 +03:00
required property bool emoji
property real highlightHue: palette.highlight.hslHue
property real highlightLight: palette.highlight.hslLightness
2023-10-31 05:11:03 +03:00
property real highlightSat: palette.highlight.hslSaturation
property alias model: gridView.model
property string roomid
readonly property int sidebarAvatarSize: 24
2023-05-25 20:07:13 +03:00
readonly property int stickerDim: emoji ? 48 : 128
readonly property int stickerDimPad: stickerDim + Nheko.paddingSmall
readonly property int stickersPerRow: emoji ? 7 : 3
2023-10-31 05:11:03 +03:00
property var textArea
2021-07-15 21:37:52 +03:00
2021-07-19 18:45:55 +03:00
function show(showAt, roomid_, callback) {
2021-07-15 21:37:52 +03:00
console.debug("Showing sticker picker");
2021-07-19 18:45:55 +03:00
roomid = roomid_;
2021-07-15 21:37:52 +03:00
stickerPopup.callback = callback;
popup(showAt ? showAt : null);
}
2023-01-12 23:41:08 +03:00
bottomPadding: 0
2023-10-31 05:11:03 +03:00
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
focus: true
2023-01-12 23:41:08 +03:00
leftPadding: 0
2023-10-31 05:11:03 +03:00
margins: 2
modal: true
2023-01-12 23:41:08 +03:00
rightPadding: 0
topPadding: 0
width: sidebarAvatarSize + Nheko.paddingSmall + stickersPerRow * stickerDimPad + 20
2021-07-15 21:37:52 +03:00
Rectangle {
color: palette.window
2023-10-31 05:11:03 +03:00
height: columnView.implicitHeight + Nheko.paddingSmall * 2
width: sidebarAvatarSize + Nheko.paddingSmall + stickersPerRow * stickerDimPad + 20
2021-07-15 21:37:52 +03:00
GridLayout {
2021-07-15 21:37:52 +03:00
id: columnView
anchors.bottom: parent.bottom
anchors.left: parent.left
2023-10-31 05:11:03 +03:00
anchors.leftMargin: Nheko.paddingSmall
2021-07-15 21:37:52 +03:00
anchors.right: parent.right
2023-10-31 05:11:03 +03:00
anchors.rightMargin: Nheko.paddingSmall
columns: 2
rows: 2
2021-07-15 21:37:52 +03:00
// Search field
TextField {
id: emojiSearch
2023-10-31 05:11:03 +03:00
Layout.column: 1
2023-01-12 23:41:08 +03:00
Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - Nheko.paddingSmall
Layout.row: 0
2021-07-15 21:37:52 +03:00
background: null
placeholderText: qsTr("Search")
2023-10-31 05:11:03 +03:00
placeholderTextColor: palette.buttonText
2021-07-15 21:37:52 +03:00
rightPadding: clearSearch.width
2023-10-31 05:11:03 +03:00
selectByMouse: true
2021-07-15 21:37:52 +03:00
onTextChanged: searchTimer.restart()
onVisibleChanged: {
if (visible)
forceActiveFocus();
else
clear();
2021-07-15 21:37:52 +03:00
}
Timer {
id: searchTimer
interval: 350 // tweak as needed?
2023-10-31 05:11:03 +03:00
2021-07-15 21:37:52 +03:00
onTriggered: stickerPopup.model.searchString = emojiSearch.text
}
2023-01-12 23:41:08 +03:00
ImageButton {
2021-07-15 21:37:52 +03:00
id: clearSearch
2023-10-31 05:11:03 +03:00
focusPolicy: Qt.NoFocus
hoverEnabled: true
image: ":/icons/icons/ui/round-remove-button.svg"
2021-07-15 21:37:52 +03:00
visible: emojiSearch.text !== ''
2023-01-12 23:41:08 +03:00
2021-07-15 21:37:52 +03:00
onClicked: emojiSearch.clear()
2023-10-31 05:11:03 +03:00
2021-07-15 21:37:52 +03:00
anchors {
2023-01-12 23:41:08 +03:00
bottom: parent.bottom
2021-07-15 21:37:52 +03:00
right: parent.right
2023-01-12 23:41:08 +03:00
rightMargin: Nheko.paddingSmall
2023-10-31 05:11:03 +03:00
top: parent.top
2021-07-15 21:37:52 +03:00
}
}
}
2023-05-19 04:15:55 +03:00
// sticker grid
ListView {
2021-07-15 21:37:52 +03:00
id: gridView
2023-10-31 05:11:03 +03:00
property int cellHeight: stickerDimPad
Layout.column: 1
2023-05-25 20:07:13 +03:00
Layout.preferredHeight: cellHeight * (stickersPerRow + 0.5)
2023-01-12 23:41:08 +03:00
Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - Nheko.paddingSmall
2023-10-31 05:11:03 +03:00
Layout.row: 1
2021-07-15 21:37:52 +03:00
boundsBehavior: Flickable.StopAtBounds
clip: true
currentIndex: -1 // prevent sorting from stealing focus
2023-05-19 04:15:55 +03:00
2023-10-31 05:11:03 +03:00
model: roomid ? TimelineManager.completerFor(stickerPopup.emoji ? "emojigrid" : "stickergrid", roomid) : null
2023-05-19 04:15:55 +03:00
section.criteria: ViewSection.FullString
2023-10-31 05:11:03 +03:00
section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
section.property: "packname"
spacing: Nheko.paddingSmall
2023-10-31 05:11:03 +03:00
ScrollBar.vertical: ScrollBar {
id: emojiScroll
}
2021-07-15 21:37:52 +03:00
// Individual emoji
2023-05-19 04:15:55 +03:00
delegate: Row {
2023-10-31 05:11:03 +03:00
required property var row
2023-05-19 04:15:55 +03:00
spacing: Nheko.paddingSmall
2023-05-19 04:15:55 +03:00
Repeater {
model: row
delegate: AbstractButton {
2023-05-25 20:07:13 +03:00
id: del
required property var modelData
2023-05-26 00:26:39 +03:00
ToolTip.text: ":" + modelData.shortcode + ": - " + (modelData.unicode ? modelData.unicodeName : modelData.body)
ToolTip.visible: hovered
2023-10-31 05:11:03 +03:00
height: stickerDim
hoverEnabled: true
width: stickerDim
2023-10-31 05:11:03 +03:00
background: Rectangle {
anchors.fill: parent
color: hovered ? palette.highlight : 'transparent'
radius: 5
}
2023-05-25 20:07:13 +03:00
contentItem: DelegateChooser {
roleValue: del.modelData.unicode != undefined
DelegateChoice {
roleValue: true
Text {
font.family: Settings.emojiFont
font.pixelSize: 36
2023-10-31 05:11:03 +03:00
height: stickerDim
horizontalAlignment: Text.AlignHCenter
2023-05-25 20:07:13 +03:00
text: del.modelData.unicode.replace('\ufe0f', '')
2023-10-31 05:11:03 +03:00
verticalAlignment: Text.AlignVCenter
width: stickerDim
2023-05-25 20:07:13 +03:00
}
}
DelegateChoice {
roleValue: false
2023-10-31 05:11:03 +03:00
2023-05-25 20:07:13 +03:00
Image {
2023-10-31 05:11:03 +03:00
fillMode: Image.PreserveAspectFit
2023-05-25 20:07:13 +03:00
height: stickerDim
source: del.modelData.url.replace("mxc://", "image://MxcImage/") + "?scale"
2023-10-31 05:11:03 +03:00
width: stickerDim
2023-05-25 20:07:13 +03:00
}
}
}
2023-10-31 05:11:03 +03:00
// TODO: maybe add favorites at some point?
onClicked: {
console.debug("Picked " + modelData);
stickerPopup.close();
if (!stickerPopup.emoji) {
// return descriptor to calculate sticker to send
callback(modelData.descriptor);
} else if (modelData.unicode) {
// return the emoji unicode as both plain text and markdown
callback(modelData.unicode, modelData.unicode);
} else {
// return the emoji url as plain text and a markdown link as markdown
callback(modelData.url, modelData.markdown);
}
}
}
2021-07-15 21:37:52 +03:00
}
}
2023-10-31 05:11:03 +03:00
section.delegate: Rectangle {
required property string section
2021-07-15 21:37:52 +03:00
2023-10-31 05:11:03 +03:00
color: palette.alternateBase
height: childrenRect.height
width: gridView.width
2021-07-15 21:37:52 +03:00
2023-10-31 05:11:03 +03:00
Text {
anchors.left: parent.left
anchors.right: parent.right
font.bold: true
text: parent.section
}
}
2021-07-15 21:37:52 +03:00
}
ListView {
Layout.column: 0
Layout.fillHeight: true
2023-10-31 05:11:03 +03:00
Layout.preferredWidth: sidebarAvatarSize
Layout.rightMargin: Nheko.paddingSmall
2023-10-31 05:11:03 +03:00
Layout.row: 1
clip: true
model: gridView.model ? gridView.model.sections : null
spacing: Nheko.paddingSmall
delegate: Avatar {
2023-10-31 05:11:03 +03:00
ToolTip.delay: Nheko.tooltipDelay
ToolTip.text: modelData.name
ToolTip.visible: hovered
displayName: modelData.name
2023-10-31 05:11:03 +03:00
height: sidebarAvatarSize
hoverEnabled: true
roomid: modelData.name
2023-10-31 05:11:03 +03:00
textColor: modelData.url.startsWith("mxc://") ? palette.text : palette.buttonText
url: modelData.url.replace("mxc://", "image://MxcImage/")
width: sidebarAvatarSize
onClicked: gridView.positionViewAtIndex(modelData.firstRowWith, ListView.Beginning)
}
}
ImageButton {
Layout.column: 0
Layout.preferredHeight: sidebarAvatarSize
2023-10-31 05:11:03 +03:00
Layout.preferredWidth: sidebarAvatarSize
Layout.rightMargin: Nheko.paddingSmall
2023-10-31 05:11:03 +03:00
Layout.row: 0
ToolTip.delay: Nheko.tooltipDelay
ToolTip.text: qsTr("Change what packs are enabled, remove packs, or create new ones")
2023-10-31 05:11:03 +03:00
ToolTip.visible: hovered
hoverEnabled: true
image: ":/icons/icons/ui/settings.svg"
onClicked: TimelineManager.openImagePackSettings(stickerPopup.roomid)
}
2021-07-15 21:37:52 +03:00
}
}
}