Commit 093998c2 authored by Filipe Azevedo's avatar Filipe Azevedo

QAbstractListItemModel based emoji model

This bring better performances for low power devices and allow better
 and easier filtering from a proxy.
parent 51d47c02
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef EMOJIMODEL_H
#define EMOJIMODEL_H
#include <QObject>
#include <QVariant>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
#include <QVector>
struct Emoji {
Emoji(const QString& u, const QString& s) : unicode(u), shortname(s) {}
Emoji() {}
class Emoji
{
Q_GADGET
QString unicode;
QString shortname;
Q_PROPERTY(const QString &unicode READ unicode CONSTANT)
Q_PROPERTY(const QString &shortName READ shortName CONSTANT)
Q_PROPERTY(Emoji::Group group READ group CONSTANT)
Q_GADGET
Q_PROPERTY(QString unicode MEMBER unicode)
Q_PROPERTY(QString shortname MEMBER shortname)
public:
enum class Group {
Invalid = -1,
People,
Nature,
Food,
Activity,
Travel,
Objects,
Symbols,
Flags
};
Q_ENUM(Group)
Emoji(const QString& u = {}, const QString& s = {}, Emoji::Group g = Emoji::Group::Invalid)
: m_unicode(u)
, m_shortName(s)
, m_group(g) {
}
inline const QString &unicode() const { return m_unicode; }
inline const QString &shortName() const { return m_shortName; }
inline Emoji::Group group() const { return m_group; }
private:
QString m_unicode;
QString m_shortName;
Emoji::Group m_group;
};
Q_DECLARE_METATYPE(Emoji)
class EmojiModel : public QAbstractListModel
{
Q_OBJECT
public:
enum class Roles {
Unicode = Qt::UserRole,
ShortName,
Group,
Emoji,
};
using QAbstractListModel::QAbstractListModel;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
};
class EmojiModel : public QObject {
Q_OBJECT
Q_PROPERTY(QVariantMap model READ getModel CONSTANT)
public:
Q_INVOKABLE QVariantMap getModel();
Q_INVOKABLE QVariantList filterModel(const QString& filter);
private:
static const QVariantList people;
static const QVariantList nature;
static const QVariantList food;
static const QVariantList activity;
static const QVariantList travel;
static const QVariantList objects;
static const QVariantList symbols;
static const QVariantList flags;
class EmojiProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(Emoji::Group group READ group WRITE setGroup NOTIFY groupChanged)
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
Emoji::Group group() const;
void setGroup(Emoji::Group group);
signals:
void groupChanged();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
private:
Emoji::Group m_group = Emoji::Group::Invalid;
};
Q_DECLARE_METATYPE(Emoji)
#endif // EMOJIMODEL_H
......@@ -168,7 +168,6 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qRegisterMetaType<QXmppClient::State>("QXmppClient::State");
qRegisterMetaType<MessageType>("MessageType");
qRegisterMetaType<DisconnectionReason>("DisconnectionReason");
qRegisterMetaType<EmojiModel*>("EmojiModel");
qRegisterMetaType<TransferJob*>("TransferJob*");
qRegisterMetaType<Utils*>("Utils*");
......@@ -262,6 +261,11 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
#endif
qmlRegisterType<StatusBar>("StatusBar", 0, 1, "StatusBar");
qmlRegisterType<EmojiModel>("EmojiModel", 0, 1, "EmojiModel");
qmlRegisterType<EmojiProxyModel>("EmojiModel", 0, 1, "EmojiProxyModel");
qmlRegisterUncreatableType<QAbstractItemModel>("EmojiModel", 0, 1, "QAbstractItemModel", "Used by proxy models");
qmlRegisterUncreatableType<Emoji>("EmojiModel", 0, 1, "Emoji", "Used by emoji models");
qmlRegisterUncreatableMetaObject(Enums::staticMetaObject, APPLICATION_ID,
1, 0, "Enums", "Can't create object; only enums defined!");
......
......@@ -278,8 +278,9 @@ Kirigami.ScrollablePage {
id: emojiPicker
emojiModel: EmojiModel {
id: emojiModel
model: EmojiProxyModel {
group: Emoji.Group.People
sourceModel: EmojiModel {}
}
textArea: messageField
......
......@@ -33,89 +33,111 @@ import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.0 as Kirigami
import EmojiModel 0.1
Popup {
property var emojiModel
property var textArea
property string emojiCategory: "people"
ColumnLayout {
anchors.fill: parent
GridView {
Layout.fillWidth: true
Layout.fillHeight: true
cellWidth: Kirigami.Units.gridUnit * 2.5
cellHeight: Kirigami.Units.gridUnit * 2.5
boundsBehavior: Flickable.DragOverBounds
clip: true
model: emojiModel.model[emojiCategory]
delegate: ItemDelegate {
width: Kirigami.Units.gridUnit * 2
height: Kirigami.Units.gridUnit * 2
contentItem: Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: 20
text: modelData.unicode
}
hoverEnabled: true
ToolTip.text: modelData.shortname
ToolTip.visible: hovered
onClicked: textArea.insert(textArea.cursorPosition, modelData.unicode)
}
ScrollBar.vertical: ScrollBar {}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 2
color: Kirigami.Theme.highlightColor
}
Row {
Repeater {
model: ListModel {
ListElement { label: "😏"; category: "people" }
ListElement { label: "🌲"; category: "nature" }
ListElement { label: "🍛"; category: "food"}
ListElement { label: "🚁"; category: "activity" }
ListElement { label: "🚅"; category: "travel" }
ListElement { label: "💡"; category: "objects" }
ListElement { label: "🔣"; category: "symbols" }
ListElement { label: "🏁"; category: "flags" }
}
delegate: ItemDelegate {
width: Kirigami.Units.gridUnit * 2
height: Kirigami.Units.gridUnit * 2
contentItem: Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: 20
text: label
}
hoverEnabled: true
ToolTip.text: category
ToolTip.visible: hovered
onClicked: emojiCategory = category
}
}
}
}
id: root
property TextArea textArea
property alias model: view.model
ColumnLayout {
anchors.fill: parent
GridView {
id: view
Layout.fillWidth: true
Layout.fillHeight: true
cellWidth: Kirigami.Units.gridUnit * 2.5
cellHeight: Kirigami.Units.gridUnit * 2.5
boundsBehavior: Flickable.DragOverBounds
clip: true
delegate: ItemDelegate {
width: Kirigami.Units.gridUnit * 2
height: Kirigami.Units.gridUnit * 2
contentItem: Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: 20
text: model.unicode
}
hoverEnabled: true
ToolTip.text: model.shortName
ToolTip.visible: hovered
onClicked: textArea.insert(textArea.cursorPosition, model.unicode)
}
ScrollBar.vertical: ScrollBar {}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 2
color: Kirigami.Theme.highlightColor
}
Row {
Repeater {
model: ListModel {
ListElement { label: "😏"; group: Emoji.Group.People }
ListElement { label: "🌲"; group: Emoji.Group.Nature }
ListElement { label: "🍛"; group: Emoji.Group.Food }
ListElement { label: "🚁"; group: Emoji.Group.Activity }
ListElement { label: "🚅"; group: Emoji.Group.Travel }
ListElement { label: "💡"; group: Emoji.Group.Objects }
ListElement { label: "🔣"; group: Emoji.Group.Symbols }
ListElement { label: "🏁"; group: Emoji.Group.Flags }
}
delegate: ItemDelegate {
width: Kirigami.Units.gridUnit * 2
height: Kirigami.Units.gridUnit * 2
contentItem: Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: 20
text: model.label
}
hoverEnabled: true
ToolTip.text: {
switch (model.group) {
case Emoji.Group.People:
return qsTr('People');
case Emoji.Group.Nature:
return qsTr('Nature');
case Emoji.Group.Food:
return qsTr('Food');
case Emoji.Group.Activity:
return qsTr('Activity');
case Emoji.Group.Travel:
return qsTr('Travel');
case Emoji.Group.Objects:
return qsTr('Objects');
case Emoji.Group.Symbols:
return qsTr('Symbols');
case Emoji.Group.Flags:
return qsTr('Flags');
}
}
ToolTip.visible: hovered
highlighted: root.model.group === model.group
onClicked: root.model.group = model.group
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment