diff options
author | Joseph Donofry <joedonofry@gmail.com> | 2020-05-13 00:35:26 -0400 |
---|---|---|
committer | Joseph Donofry <joedonofry@gmail.com> | 2020-05-13 00:36:41 -0400 |
commit | ee4dcef90f285f49ee27fec13afb486d93781b8b (patch) | |
tree | e6e4313098ef2c2fa4841fa7d6310825b08c0c4b /resources | |
parent | Initial support for sending reactions (diff) | |
download | nheko-ee4dcef90f285f49ee27fec13afb486d93781b8b.tar.xz |
Add new QML-based emoji picker (work in progress)
This is necessary to support having a picker within QML. Eventually, this should replace the existing widget-based one.
Diffstat (limited to 'resources')
-rw-r--r-- | resources/qml/TimelineRow.qml | 6 | ||||
-rw-r--r-- | resources/qml/emoji/EmojiButton.qml | 27 | ||||
-rw-r--r-- | resources/qml/emoji/EmojiPicker.qml | 176 | ||||
-rw-r--r-- | resources/res.qrc | 2 |
4 files changed, 208 insertions, 3 deletions
diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index de71fb69..afde7a2a 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -6,6 +6,7 @@ import QtQuick.Window 2.2 import im.nheko 1.0 import "./delegates" +import "./emoji" MouseArea { anchors.left: parent.left @@ -71,17 +72,16 @@ MouseArea { Layout.preferredHeight: 16 width: 16 } - ImageButton { + EmojiButton { visible: timelineSettings.buttons Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 id: reactButton hoverEnabled: true - image: ":/icons/icons/ui/smile.png" ToolTip.visible: hovered ToolTip.text: qsTr("React") - onClicked: chat.model.reactAction(model.id) +// onClicked: chat.model.reactAction(model.id) } ImageButton { visible: timelineSettings.buttons diff --git a/resources/qml/emoji/EmojiButton.qml b/resources/qml/emoji/EmojiButton.qml new file mode 100644 index 00000000..51d5628c --- /dev/null +++ b/resources/qml/emoji/EmojiButton.qml @@ -0,0 +1,27 @@ +import QtQuick 2.10 +import QtQuick.Controls 2.1 +import im.nheko 1.0 +import im.nheko.EmojiModel 1.0 + +import "../" + +ImageButton { + property var colors: currentActivePalette + + image: ":/icons/icons/ui/smile.png" + id: emojiButton + onClicked: emojiPopup.open() + + EmojiPicker { + id: emojiPopup + x: Math.round((emojiButton.width - width) / 2) + y: emojiButton.height + width: 7 * 52 + height: 6 * 52 + colors: emojiButton.colors + model: EmojiProxyModel { + category: Emoji.Category.People + sourceModel: EmojiModel {} + } + } +} \ No newline at end of file diff --git a/resources/qml/emoji/EmojiPicker.qml b/resources/qml/emoji/EmojiPicker.qml new file mode 100644 index 00000000..6d04edf8 --- /dev/null +++ b/resources/qml/emoji/EmojiPicker.qml @@ -0,0 +1,176 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.9 +import QtQuick.Layouts 1.3 + +import im.nheko 1.0 +import im.nheko.EmojiModel 1.0 + +import "../" + +Popup { + property var colors + property alias model: gridView.model + property var textArea + property string emojiCategory: "people" + + id: emojiPopup + + margins: 0 + + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + + ColumnLayout { + anchors.fill: parent + + // Search field + TextField { + id: emojiSearch + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: parent.width - 4 + visible: emojiPopup.model.category === Emoji.Category.Search + placeholderText: qsTr("Search") + selectByMouse: true + rightPadding: clearSearch.width + + Timer { + id: searchTimer + interval: 350 // tweak as needed? + onTriggered: emojiPopup.model.filter = emojiSearch.text + } + + ToolButton { + id: clearSearch + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + // clear the default hover effects. + background: Item {} + visible: emojiSearch.text !== '' + icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? colors.highlight : colors.buttonText) + focusPolicy: Qt.NoFocus + onClicked: emojiSearch.clear() + } + + onTextChanged: searchTimer.restart() + onVisibleChanged: if (visible) forceActiveFocus() + } + + // emoji grid + GridView { + id: gridView + + Layout.fillWidth: true + Layout.fillHeight: true + + cellWidth: 52 + cellHeight: 52 + + boundsBehavior: Flickable.DragOverBounds + + clip: true + + // Individual emoji + delegate: AbstractButton { + width: 48 + height: 48 + + contentItem: Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.pointSize: 36 + text: model.unicode + } + + background: Rectangle { + anchors.fill: parent + color: hovered ? colors.highlight : 'transparent' + radius: 5 + } + + hoverEnabled: true + ToolTip.text: model.shortName + ToolTip.visible: hovered + // TODO: emit a signal and maybe add favorites at some point? + //onClicked: textArea.insert(textArea.cursorPosition, modelData.unicode) + } + + ScrollBar.vertical: ScrollBar {} + } + + // Separator + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 2 + + color: emojiPopup.colors.highlight + } + + // Category picker row + Row { + Repeater { + model: ListModel { + // TODO: Would like to get 'simple' icons for the categories + ListElement { label: "😏"; category: Emoji.Category.People } + ListElement { label: "🌲"; category: Emoji.Category.Nature } + ListElement { label: "🍛"; category: Emoji.Category.Food } + ListElement { label: "🚁"; category: Emoji.Category.Activity } + ListElement { label: "🚅"; category: Emoji.Category.Travel } + ListElement { label: "💡"; category: Emoji.Category.Objects } + ListElement { label: "🔣"; category: Emoji.Category.Symbols } + ListElement { label: "🏁"; category: Emoji.Category.Flags } + ListElement { label: "🔍"; category: Emoji.Category.Search } + } + + delegate: AbstractButton { + width: 40 + height: 40 + + contentItem: Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font.pointSize: 30 + text: model.label + } + + background: Rectangle { + anchors.fill: parent + color: emojiPopup.model.category === model.category ? colors.highlight : 'transparent' + radius: 5 + } + + hoverEnabled: true + ToolTip.text: { + switch (model.category) { + case Emoji.Category.People: + return qsTr('People'); + case Emoji.Category.Nature: + return qsTr('Nature'); + case Emoji.Category.Food: + return qsTr('Food'); + case Emoji.Category.Activity: + return qsTr('Activity'); + case Emoji.Category.Travel: + return qsTr('Travel'); + case Emoji.Category.Objects: + return qsTr('Objects'); + case Emoji.Category.Symbols: + return qsTr('Symbols'); + case Emoji.Category.Flags: + return qsTr('Flags'); + case Emoji.Category.Search: + return qsTr('Search'); + } + } + ToolTip.visible: hovered + + onClicked: emojiPopup.model.category = model.category + } + } + } + } +} diff --git a/resources/res.qrc b/resources/res.qrc index 64a5b3cb..a48d0410 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -120,6 +120,8 @@ <file>qml/Reactions.qml</file> <file>qml/ScrollHelper.qml</file> <file>qml/TimelineRow.qml</file> + <file>qml/emoji/EmojiButton.qml</file> + <file>qml/emoji/EmojiPicker.qml</file> <file>qml/delegates/MessageDelegate.qml</file> <file>qml/delegates/TextMessage.qml</file> <file>qml/delegates/NoticeMessage.qml</file> |