mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Move emoji picker to qml
This commit is contained in:
parent
2bec5d083c
commit
82c441dddd
17 changed files with 18 additions and 8507 deletions
|
@ -241,12 +241,7 @@ set(SRC_FILES
|
|||
src/dialogs/RoomSettings.cpp
|
||||
|
||||
# Emoji
|
||||
src/emoji/Category.cpp
|
||||
src/emoji/EmojiModel.cpp
|
||||
src/emoji/ItemDelegate.cpp
|
||||
src/emoji/Panel.cpp
|
||||
src/emoji/PickButton.cpp
|
||||
src/emoji/Provider.cpp
|
||||
src/emoji/Provider_new.cpp
|
||||
|
||||
|
||||
|
@ -455,11 +450,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/dialogs/RoomSettings.h
|
||||
|
||||
# Emoji
|
||||
src/emoji/Category.h
|
||||
src/emoji/EmojiModel.h
|
||||
src/emoji/ItemDelegate.h
|
||||
src/emoji/Panel.h
|
||||
src/emoji/PickButton.h
|
||||
src/emoji/Provider.h
|
||||
|
||||
# Timeline
|
||||
|
|
|
@ -88,8 +88,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
Connections {
|
||||
onInsertText: textArea.insert(textArea.cursorPosition, text);
|
||||
|
||||
onInsertText: textArea.insert(textArea.cursorPosition, text)
|
||||
target: TimelineManager.timeline.input
|
||||
}
|
||||
|
||||
|
@ -110,6 +109,8 @@ Rectangle {
|
|||
}
|
||||
|
||||
ImageButton {
|
||||
id: emojiButton
|
||||
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
|
||||
hoverEnabled: true
|
||||
width: 22
|
||||
|
@ -119,6 +120,9 @@ Rectangle {
|
|||
Layout.bottomMargin: 8
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Emoji")
|
||||
onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) {
|
||||
textArea.insert(textArea.cursorPosition, emoji);
|
||||
})
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
|
|
|
@ -72,7 +72,9 @@ Page {
|
|||
|
||||
MenuItem {
|
||||
text: qsTr("React")
|
||||
onClicked: emojiPopup.show(messageContextMenu.parent, messageContextMenu.eventId)
|
||||
onClicked: emojiPopup.show(messageContextMenu.parent, function(emoji) {
|
||||
TimelineManager.queueReactionMessage(messageContextMenu.eventId, emoji);
|
||||
})
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
|
|
|
@ -12,5 +12,7 @@ ImageButton {
|
|||
property string event_id
|
||||
|
||||
image: ":/icons/icons/ui/smile.png"
|
||||
onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.show(emojiButton, event_id)
|
||||
onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.show(emojiButton, function(emoji) {
|
||||
TimelineManager.queueReactionMessage(event_id, emoji);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import im.nheko.EmojiModel 1.0
|
|||
Popup {
|
||||
id: emojiPopup
|
||||
|
||||
property string event_id
|
||||
property var callback
|
||||
property var colors
|
||||
property alias model: gridView.model
|
||||
property var textArea
|
||||
|
@ -18,14 +18,14 @@ Popup {
|
|||
property real highlightSat: colors.highlight.hslSaturation
|
||||
property real highlightLight: colors.highlight.hslLightness
|
||||
|
||||
function show(showAt, event_id) {
|
||||
console.debug("Showing emojiPicker for " + event_id);
|
||||
function show(showAt, callback) {
|
||||
console.debug("Showing emojiPicker");
|
||||
if (showAt) {
|
||||
parent = showAt;
|
||||
x = Math.round((showAt.width - width) / 2);
|
||||
y = showAt.height;
|
||||
}
|
||||
emojiPopup.event_id = event_id;
|
||||
emojiPopup.callback = callback;
|
||||
open();
|
||||
}
|
||||
|
||||
|
@ -70,9 +70,9 @@ Popup {
|
|||
ToolTip.visible: hovered
|
||||
// TODO: maybe add favorites at some point?
|
||||
onClicked: {
|
||||
console.debug("Picked " + model.unicode + "in response to " + emojiPopup.event_id);
|
||||
console.debug("Picked " + model.unicode);
|
||||
emojiPopup.close();
|
||||
TimelineManager.queueReactionMessage(emojiPopup.event_id, model.unicode);
|
||||
callback(model.unicode);
|
||||
}
|
||||
|
||||
// give the emoji a little oomf
|
||||
|
|
|
@ -486,54 +486,19 @@ TextInputWidget::TextInputWidget(QWidget *parent)
|
|||
sendMessageBtn_->setIcon(send_message_icon);
|
||||
sendMessageBtn_->setIconSize(QSize(ButtonHeight, ButtonHeight));
|
||||
|
||||
emojiBtn_ = new emoji::PickButton(this);
|
||||
emojiBtn_->setToolTip(tr("Emoji"));
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
// macOS has a native emoji picker.
|
||||
emojiBtn_->hide();
|
||||
#endif
|
||||
|
||||
QIcon emoji_icon;
|
||||
emoji_icon.addFile(":/icons/icons/ui/smile.png");
|
||||
emojiBtn_->setIcon(emoji_icon);
|
||||
emojiBtn_->setIconSize(QSize(ButtonHeight, ButtonHeight));
|
||||
|
||||
topLayout_->addWidget(sendFileBtn_);
|
||||
topLayout_->addWidget(input_);
|
||||
topLayout_->addWidget(emojiBtn_);
|
||||
topLayout_->addWidget(sendMessageBtn_);
|
||||
|
||||
setLayout(topLayout_);
|
||||
|
||||
connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit);
|
||||
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
|
||||
connect(emojiBtn_,
|
||||
SIGNAL(emojiSelected(const QString &)),
|
||||
this,
|
||||
SLOT(addSelectedEmoji(const QString &)));
|
||||
|
||||
connect(input_, &FilteredTextEdit::startedTyping, this, &TextInputWidget::startedTyping);
|
||||
|
||||
connect(input_, &FilteredTextEdit::stoppedTyping, this, &TextInputWidget::stoppedTyping);
|
||||
}
|
||||
|
||||
void
|
||||
TextInputWidget::addSelectedEmoji(const QString &emoji)
|
||||
{
|
||||
QTextCursor cursor = input_->textCursor();
|
||||
|
||||
QTextCharFormat charfmt;
|
||||
input_->setCurrentCharFormat(charfmt);
|
||||
|
||||
input_->insertPlainText(emoji);
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
|
||||
input_->setCurrentCharFormat(charfmt);
|
||||
|
||||
input_->show();
|
||||
}
|
||||
|
||||
void
|
||||
TextInputWidget::stopTyping()
|
||||
{
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <QWidget>
|
||||
|
||||
#include "dialogs/PreviewUploadOverlay.h"
|
||||
#include "emoji/PickButton.h"
|
||||
#include "popups/SuggestionsPopup.h"
|
||||
|
||||
struct SearchResult;
|
||||
|
@ -155,9 +154,6 @@ public:
|
|||
public slots:
|
||||
void focusLineEdit() { input_->setFocus(); }
|
||||
|
||||
private slots:
|
||||
void addSelectedEmoji(const QString &emoji);
|
||||
|
||||
signals:
|
||||
void heightChanged(int height);
|
||||
|
||||
|
@ -183,7 +179,5 @@ private:
|
|||
|
||||
FlatButton *sendFileBtn_;
|
||||
FlatButton *sendMessageBtn_;
|
||||
emoji::PickButton *emojiBtn_;
|
||||
|
||||
QColor borderColor_;
|
||||
};
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QLabel>
|
||||
#include <QListView>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QStyleOption>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "emoji/Category.h"
|
||||
|
||||
using namespace emoji;
|
||||
|
||||
Category::Category(QString category, std::vector<Emoji> emoji, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
mainLayout_ = new QVBoxLayout(this);
|
||||
mainLayout_->setMargin(0);
|
||||
mainLayout_->setSpacing(0);
|
||||
|
||||
emojiListView_ = new QListView();
|
||||
itemModel_ = new QStandardItemModel(this);
|
||||
|
||||
delegate_ = new ItemDelegate(this);
|
||||
data_ = new Emoji;
|
||||
|
||||
emojiListView_->setItemDelegate(delegate_);
|
||||
emojiListView_->setModel(itemModel_);
|
||||
emojiListView_->setViewMode(QListView::IconMode);
|
||||
emojiListView_->setFlow(QListView::LeftToRight);
|
||||
emojiListView_->setResizeMode(QListView::Adjust);
|
||||
emojiListView_->setMouseTracking(true);
|
||||
emojiListView_->verticalScrollBar()->setEnabled(false);
|
||||
emojiListView_->horizontalScrollBar()->setEnabled(false);
|
||||
|
||||
const int cols = 7;
|
||||
const int rows = emoji.size() / 7 + 1;
|
||||
|
||||
const int emojiSize = 48;
|
||||
const int gridSize = emojiSize + 4;
|
||||
// TODO: Be precise here. Take the parent into consideration.
|
||||
emojiListView_->setFixedSize(cols * gridSize + 20, rows * gridSize);
|
||||
emojiListView_->setGridSize(QSize(gridSize, gridSize));
|
||||
emojiListView_->setDragEnabled(false);
|
||||
emojiListView_->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
for (const auto &e : emoji) {
|
||||
data_->unicode = e.unicode;
|
||||
|
||||
auto item = new QStandardItem;
|
||||
item->setSizeHint(QSize(emojiSize, emojiSize));
|
||||
|
||||
QVariant unicode(data_->unicode);
|
||||
item->setData(unicode.toString(), Qt::UserRole);
|
||||
|
||||
itemModel_->appendRow(item);
|
||||
}
|
||||
|
||||
QFont font;
|
||||
font.setWeight(QFont::Medium);
|
||||
|
||||
category_ = new QLabel(category, this);
|
||||
category_->setFont(font);
|
||||
|
||||
mainLayout_->addWidget(category_);
|
||||
mainLayout_->addWidget(emojiListView_);
|
||||
|
||||
connect(emojiListView_, &QListView::clicked, this, &Category::clickIndex);
|
||||
}
|
||||
|
||||
void
|
||||
Category::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "ItemDelegate.h"
|
||||
|
||||
class QLabel;
|
||||
class QListView;
|
||||
class QStandardItemModel;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace emoji {
|
||||
|
||||
class Category : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(
|
||||
QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor)
|
||||
|
||||
public:
|
||||
Category(QString category, std::vector<Emoji> emoji, QWidget *parent = nullptr);
|
||||
QColor hoverBackgroundColor() const { return hoverBackgroundColor_; }
|
||||
void setHoverBackgroundColor(QColor color) { hoverBackgroundColor_ = color; }
|
||||
|
||||
signals:
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void clickIndex(const QModelIndex &index)
|
||||
{
|
||||
emit emojiSelected(index.data(Qt::UserRole).toString());
|
||||
};
|
||||
|
||||
private:
|
||||
QVBoxLayout *mainLayout_;
|
||||
|
||||
QStandardItemModel *itemModel_;
|
||||
QListView *emojiListView_;
|
||||
|
||||
emoji::Emoji *data_;
|
||||
emoji::ItemDelegate *delegate_;
|
||||
|
||||
QLabel *category_;
|
||||
|
||||
QColor hoverBackgroundColor_;
|
||||
};
|
||||
} // namespace emoji
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QPainter>
|
||||
#include <QSettings>
|
||||
|
||||
#include "emoji/ItemDelegate.h"
|
||||
|
||||
using namespace emoji;
|
||||
|
||||
ItemDelegate::ItemDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
data_ = new Emoji;
|
||||
}
|
||||
|
||||
ItemDelegate::~ItemDelegate() { delete data_; }
|
||||
|
||||
void
|
||||
ItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
painter->save();
|
||||
|
||||
QStyleOptionViewItem viewOption(option);
|
||||
|
||||
auto emoji = index.data(Qt::UserRole).toString();
|
||||
|
||||
QSettings settings;
|
||||
|
||||
QFont font;
|
||||
QString userFontFamily = settings.value("user/emoji_font_family", "emoji").toString();
|
||||
if (!userFontFamily.isEmpty()) {
|
||||
font.setFamily(userFontFamily);
|
||||
} else {
|
||||
font.setFamily("emoji");
|
||||
}
|
||||
|
||||
font.setPixelSize(36);
|
||||
painter->setFont(font);
|
||||
if (option.state & QStyle::State_MouseOver) {
|
||||
painter->setBackgroundMode(Qt::OpaqueMode);
|
||||
QColor hoverColor = parent()->property("hoverBackgroundColor").value<QColor>();
|
||||
painter->setBackground(hoverColor);
|
||||
}
|
||||
painter->drawText(viewOption.rect, Qt::AlignCenter, emoji);
|
||||
|
||||
painter->restore();
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QStandardItemModel>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include "Provider.h"
|
||||
|
||||
namespace emoji {
|
||||
|
||||
class ItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ItemDelegate(QObject *parent = nullptr);
|
||||
~ItemDelegate() override;
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
Emoji *data_;
|
||||
};
|
||||
} // namespace emoji
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "ui/DropShadow.h"
|
||||
#include "ui/FlatButton.h"
|
||||
|
||||
#include "emoji/Category.h"
|
||||
#include "emoji/Panel.h"
|
||||
|
||||
using namespace emoji;
|
||||
|
||||
Panel::Panel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, shadowMargin_{2}
|
||||
, width_{370}
|
||||
, height_{350}
|
||||
, categoryIconSize_{20}
|
||||
{
|
||||
setAttribute(Qt::WA_ShowWithoutActivating, true);
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
|
||||
|
||||
auto mainWidget = new QWidget(this);
|
||||
mainWidget->setMaximumSize(width_, height_);
|
||||
|
||||
auto topLayout = new QVBoxLayout(this);
|
||||
topLayout->addWidget(mainWidget);
|
||||
topLayout->setMargin(shadowMargin_);
|
||||
topLayout->setSpacing(0);
|
||||
|
||||
auto contentLayout = new QVBoxLayout(mainWidget);
|
||||
contentLayout->setMargin(0);
|
||||
contentLayout->setSpacing(0);
|
||||
|
||||
auto emojiCategories = new QFrame(mainWidget);
|
||||
|
||||
auto categoriesLayout = new QHBoxLayout(emojiCategories);
|
||||
categoriesLayout->setSpacing(0);
|
||||
categoriesLayout->setMargin(0);
|
||||
|
||||
QIcon icon;
|
||||
|
||||
auto peopleCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/people.png");
|
||||
peopleCategory->setIcon(icon);
|
||||
peopleCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto natureCategory_ = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/nature.png");
|
||||
natureCategory_->setIcon(icon);
|
||||
natureCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto foodCategory_ = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/foods.png");
|
||||
foodCategory_->setIcon(icon);
|
||||
foodCategory_->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto activityCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/activity.png");
|
||||
activityCategory->setIcon(icon);
|
||||
activityCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto travelCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/travel.png");
|
||||
travelCategory->setIcon(icon);
|
||||
travelCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto objectsCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/objects.png");
|
||||
objectsCategory->setIcon(icon);
|
||||
objectsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto symbolsCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/symbols.png");
|
||||
symbolsCategory->setIcon(icon);
|
||||
symbolsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
auto flagsCategory = new FlatButton(emojiCategories);
|
||||
icon.addFile(":/icons/icons/emoji-categories/flags.png");
|
||||
flagsCategory->setIcon(icon);
|
||||
flagsCategory->setIconSize(QSize(categoryIconSize_, categoryIconSize_));
|
||||
|
||||
categoriesLayout->addWidget(peopleCategory);
|
||||
categoriesLayout->addWidget(natureCategory_);
|
||||
categoriesLayout->addWidget(foodCategory_);
|
||||
categoriesLayout->addWidget(activityCategory);
|
||||
categoriesLayout->addWidget(travelCategory);
|
||||
categoriesLayout->addWidget(objectsCategory);
|
||||
categoriesLayout->addWidget(symbolsCategory);
|
||||
categoriesLayout->addWidget(flagsCategory);
|
||||
|
||||
scrollArea_ = new QScrollArea(this);
|
||||
scrollArea_->setWidgetResizable(true);
|
||||
scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
auto scrollWidget = new QWidget(this);
|
||||
auto scrollLayout = new QVBoxLayout(scrollWidget);
|
||||
|
||||
scrollLayout->setMargin(0);
|
||||
scrollLayout->setSpacing(0);
|
||||
scrollArea_->setWidget(scrollWidget);
|
||||
|
||||
auto peopleEmoji =
|
||||
new Category(tr("Smileys & People"), emoji_provider_.people, scrollWidget);
|
||||
scrollLayout->addWidget(peopleEmoji);
|
||||
|
||||
auto natureEmoji =
|
||||
new Category(tr("Animals & Nature"), emoji_provider_.nature, scrollWidget);
|
||||
scrollLayout->addWidget(natureEmoji);
|
||||
|
||||
auto foodEmoji = new Category(tr("Food & Drink"), emoji_provider_.food, scrollWidget);
|
||||
scrollLayout->addWidget(foodEmoji);
|
||||
|
||||
auto activityEmoji = new Category(tr("Activity"), emoji_provider_.activity, scrollWidget);
|
||||
scrollLayout->addWidget(activityEmoji);
|
||||
|
||||
auto travelEmoji =
|
||||
new Category(tr("Travel & Places"), emoji_provider_.travel, scrollWidget);
|
||||
scrollLayout->addWidget(travelEmoji);
|
||||
|
||||
auto objectsEmoji = new Category(tr("Objects"), emoji_provider_.objects, scrollWidget);
|
||||
scrollLayout->addWidget(objectsEmoji);
|
||||
|
||||
auto symbolsEmoji = new Category(tr("Symbols"), emoji_provider_.symbols, scrollWidget);
|
||||
scrollLayout->addWidget(symbolsEmoji);
|
||||
|
||||
auto flagsEmoji = new Category(tr("Flags"), emoji_provider_.flags, scrollWidget);
|
||||
scrollLayout->addWidget(flagsEmoji);
|
||||
|
||||
contentLayout->addWidget(scrollArea_);
|
||||
contentLayout->addWidget(emojiCategories);
|
||||
|
||||
connect(peopleEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(peopleCategory, &QPushButton::clicked, [this, peopleEmoji]() {
|
||||
this->showCategory(peopleEmoji);
|
||||
});
|
||||
|
||||
connect(natureEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(natureCategory_, &QPushButton::clicked, [this, natureEmoji]() {
|
||||
this->showCategory(natureEmoji);
|
||||
});
|
||||
|
||||
connect(foodEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(foodCategory_, &QPushButton::clicked, [this, foodEmoji]() {
|
||||
this->showCategory(foodEmoji);
|
||||
});
|
||||
|
||||
connect(activityEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(activityCategory, &QPushButton::clicked, [this, activityEmoji]() {
|
||||
this->showCategory(activityEmoji);
|
||||
});
|
||||
|
||||
connect(travelEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(travelCategory, &QPushButton::clicked, [this, travelEmoji]() {
|
||||
this->showCategory(travelEmoji);
|
||||
});
|
||||
|
||||
connect(objectsEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(objectsCategory, &QPushButton::clicked, [this, objectsEmoji]() {
|
||||
this->showCategory(objectsEmoji);
|
||||
});
|
||||
|
||||
connect(symbolsEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(symbolsCategory, &QPushButton::clicked, [this, symbolsEmoji]() {
|
||||
this->showCategory(symbolsEmoji);
|
||||
});
|
||||
|
||||
connect(flagsEmoji, &Category::emojiSelected, this, &Panel::emojiSelected);
|
||||
connect(flagsCategory, &QPushButton::clicked, [this, flagsEmoji]() {
|
||||
this->showCategory(flagsEmoji);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Panel::showCategory(const Category *category)
|
||||
{
|
||||
auto posToGo = category->mapToParent(QPoint()).y();
|
||||
auto current = scrollArea_->verticalScrollBar()->value();
|
||||
|
||||
if (current == posToGo)
|
||||
return;
|
||||
|
||||
// HACK
|
||||
// We want the top of the category to be visible, so scroll to the top first and then to the
|
||||
// category
|
||||
if (current > posToGo)
|
||||
this->scrollArea_->ensureVisible(0, 0, 0, 0);
|
||||
|
||||
posToGo += scrollArea_->height();
|
||||
this->scrollArea_->ensureVisible(0, posToGo, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Panel::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
|
||||
DropShadow::draw(p,
|
||||
shadowMargin_,
|
||||
4.0,
|
||||
QColor(120, 120, 120, 92),
|
||||
QColor(255, 255, 255, 0),
|
||||
0.0,
|
||||
1.0,
|
||||
0.6,
|
||||
width(),
|
||||
height());
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "Provider.h"
|
||||
|
||||
namespace emoji {
|
||||
|
||||
class Category;
|
||||
|
||||
class Panel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Panel(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void mouseLeft();
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent *event) override
|
||||
{
|
||||
emit leaving();
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
signals:
|
||||
void leaving();
|
||||
|
||||
private:
|
||||
void showCategory(const Category *category);
|
||||
|
||||
Provider emoji_provider_;
|
||||
|
||||
QScrollArea *scrollArea_;
|
||||
|
||||
int shadowMargin_;
|
||||
|
||||
// Panel dimensions.
|
||||
int width_;
|
||||
int height_;
|
||||
|
||||
int categoryIconSize_;
|
||||
};
|
||||
} // namespace emoji
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "emoji/Panel.h"
|
||||
#include "emoji/PickButton.h"
|
||||
|
||||
using namespace emoji;
|
||||
|
||||
// Number of milliseconds after which the panel will be hidden
|
||||
// if the mouse cursor is not on top of the widget.
|
||||
constexpr int HIDE_TIMEOUT = 300;
|
||||
|
||||
PickButton::PickButton(QWidget *parent)
|
||||
: FlatButton(parent)
|
||||
, panel_{nullptr}
|
||||
{
|
||||
connect(&hideTimer_, &QTimer::timeout, this, &PickButton::hidePanel);
|
||||
connect(this, &QPushButton::clicked, this, [this]() {
|
||||
if (panel_ && panel_->isVisible()) {
|
||||
hidePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
showPanel();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
PickButton::hidePanel()
|
||||
{
|
||||
if (panel_ && !panel_->underMouse()) {
|
||||
hideTimer_.stop();
|
||||
panel_->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PickButton::showPanel()
|
||||
{
|
||||
if (panel_.isNull()) {
|
||||
panel_ = QSharedPointer<Panel>(new Panel(this));
|
||||
connect(panel_.data(), &Panel::emojiSelected, this, &PickButton::emojiSelected);
|
||||
connect(panel_.data(), &Panel::leaving, this, [this]() { panel_->hide(); });
|
||||
}
|
||||
|
||||
if (panel_->isVisible())
|
||||
return;
|
||||
|
||||
QPoint pos(rect().x(), rect().y());
|
||||
pos = this->mapToGlobal(pos);
|
||||
|
||||
auto panel_size = panel_->sizeHint();
|
||||
|
||||
auto x = pos.x() - panel_size.width() + horizontal_distance_;
|
||||
auto y = pos.y() - panel_size.height() - vertical_distance_;
|
||||
|
||||
panel_->move(x, y);
|
||||
panel_->show();
|
||||
}
|
||||
|
||||
void
|
||||
PickButton::leaveEvent(QEvent *e)
|
||||
{
|
||||
hideTimer_.start(HIDE_TIMEOUT);
|
||||
FlatButton::leaveEvent(e);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QEvent>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui/FlatButton.h"
|
||||
|
||||
namespace emoji {
|
||||
|
||||
class Panel;
|
||||
|
||||
class PickButton : public FlatButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PickButton(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void emojiSelected(const QString &emoji);
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
private:
|
||||
void showPanel();
|
||||
void hidePanel();
|
||||
|
||||
// Vertical distance from panel's bottom.
|
||||
int vertical_distance_ = 10;
|
||||
|
||||
// Horizontal distance from panel's bottom right corner.
|
||||
int horizontal_distance_ = 70;
|
||||
|
||||
QSharedPointer<Panel> panel_;
|
||||
QTimer hideTimer_;
|
||||
};
|
||||
} // namespace emoji
|
File diff suppressed because it is too large
Load diff
|
@ -59,14 +59,6 @@ class Provider
|
|||
public:
|
||||
// all emoji for QML purposes
|
||||
static const QVector<Emoji> emoji;
|
||||
static const std::vector<Emoji> people;
|
||||
static const std::vector<Emoji> nature;
|
||||
static const std::vector<Emoji> food;
|
||||
static const std::vector<Emoji> activity;
|
||||
static const std::vector<Emoji> travel;
|
||||
static const std::vector<Emoji> objects;
|
||||
static const std::vector<Emoji> symbols;
|
||||
static const std::vector<Emoji> flags;
|
||||
};
|
||||
|
||||
} // namespace emoji
|
||||
|
|
Loading…
Reference in a new issue