Add full emoji support
|
@ -71,6 +71,11 @@ endif()
|
||||||
set(SRC_FILES
|
set(SRC_FILES
|
||||||
src/ChatPage.cc
|
src/ChatPage.cc
|
||||||
src/Deserializable.cc
|
src/Deserializable.cc
|
||||||
|
src/EmojiCategory.cc
|
||||||
|
src/EmojiItemDelegate.cc
|
||||||
|
src/EmojiPanel.cc
|
||||||
|
src/EmojiPickButton.cc
|
||||||
|
src/EmojiProvider.cc
|
||||||
src/HistoryView.cc
|
src/HistoryView.cc
|
||||||
src/HistoryViewItem.cc
|
src/HistoryViewItem.cc
|
||||||
src/HistoryViewManager.cc
|
src/HistoryViewManager.cc
|
||||||
|
@ -116,6 +121,10 @@ qt5_wrap_ui (UI_HEADERS
|
||||||
|
|
||||||
qt5_wrap_cpp(MOC_HEADERS
|
qt5_wrap_cpp(MOC_HEADERS
|
||||||
include/ChatPage.h
|
include/ChatPage.h
|
||||||
|
include/EmojiCategory.h
|
||||||
|
include/EmojiItemDelegate.h
|
||||||
|
include/EmojiPanel.h
|
||||||
|
include/EmojiPickButton.h
|
||||||
include/HistoryView.h
|
include/HistoryView.h
|
||||||
include/HistoryViewItem.h
|
include/HistoryViewItem.h
|
||||||
include/HistoryViewManager.h
|
include/HistoryViewManager.h
|
||||||
|
|
62
include/EmojiCategory.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMOJI_CATEGORY_H
|
||||||
|
#define EMOJI_CATEGORY_H
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "EmojiItemDelegate.h"
|
||||||
|
#include "EmojiProvider.h"
|
||||||
|
|
||||||
|
class EmojiCategory : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
EmojiCategory(QString category, QList<Emoji> emoji, QWidget *parent = nullptr);
|
||||||
|
~EmojiCategory();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void emojiSelected(const QString &emoji);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
inline void clickIndex(const QModelIndex &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVBoxLayout *mainLayout_;
|
||||||
|
|
||||||
|
QStandardItemModel *itemModel_;
|
||||||
|
QListView *emojiListView_;
|
||||||
|
|
||||||
|
Emoji *data_;
|
||||||
|
EmojiItemDelegate *delegate_;
|
||||||
|
|
||||||
|
QLabel *category_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void EmojiCategory::clickIndex(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
emit emojiSelected(index.data(Qt::UserRole).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EMOJI_CATEGORY_H
|
41
include/EmojiItemDelegate.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMOJI_ITEM_DELEGATE_H
|
||||||
|
#define EMOJI_ITEM_DELEGATE_H
|
||||||
|
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
#include "EmojiProvider.h"
|
||||||
|
|
||||||
|
class EmojiItemDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EmojiItemDelegate(QObject *parent = nullptr);
|
||||||
|
~EmojiItemDelegate();
|
||||||
|
|
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Emoji *data_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMOJI_ITEM_DELEGATE_H
|
60
include/EmojiPanel.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMOJI_PANEL_H
|
||||||
|
#define EMOJI_PANEL_H
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QGraphicsOpacityEffect>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "EmojiCategory.h"
|
||||||
|
#include "EmojiProvider.h"
|
||||||
|
|
||||||
|
class EmojiPanel : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
EmojiPanel(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void fadeOut();
|
||||||
|
void fadeIn();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void mouseLeft();
|
||||||
|
void emojiSelected(const QString &emoji);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void leaveEvent(QEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void showEmojiCategory(const EmojiCategory *category);
|
||||||
|
|
||||||
|
QPropertyAnimation *animation_;
|
||||||
|
QGraphicsOpacityEffect *opacity_;
|
||||||
|
|
||||||
|
EmojiProvider emoji_provider_;
|
||||||
|
|
||||||
|
QScrollArea *scroll_area_;
|
||||||
|
|
||||||
|
const int category_icon_size_ = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMOJI_PANEL_H
|
50
include/EmojiPickButton.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMOJI_PICK_BUTTON_H
|
||||||
|
#define EMOJI_PICK_BUTTON_H
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "EmojiPanel.h"
|
||||||
|
#include "FlatButton.h"
|
||||||
|
|
||||||
|
class EmojiPickButton : public FlatButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit EmojiPickButton(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void emojiSelected(const QString &emoji);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void enterEvent(QEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Vertical distance from panel's bottom.
|
||||||
|
int vertical_distance_ = 10;
|
||||||
|
|
||||||
|
// Horizontal distance from panel's bottom right corner.
|
||||||
|
int horizontal_distance_ = 70;
|
||||||
|
|
||||||
|
EmojiPanel *panel_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMOJI_PICK_BUTTON_H
|
45
include/EmojiProvider.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMOJI_PROVIDER_H
|
||||||
|
#define EMOJI_PROVIDER_H
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QList>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
struct Emoji {
|
||||||
|
// Unicode code.
|
||||||
|
QString unicode;
|
||||||
|
// Keyboard shortcut e.g :emoji:
|
||||||
|
QString shortname;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EmojiProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const QList<Emoji> people;
|
||||||
|
static const QList<Emoji> nature;
|
||||||
|
static const QList<Emoji> food;
|
||||||
|
static const QList<Emoji> activity;
|
||||||
|
static const QList<Emoji> travel;
|
||||||
|
static const QList<Emoji> objects;
|
||||||
|
static const QList<Emoji> symbols;
|
||||||
|
static const QList<Emoji> flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMOJI_PROVIDER_H
|
|
@ -19,12 +19,24 @@
|
||||||
#define TEXT_INPUT_WIDGET_H
|
#define TEXT_INPUT_WIDGET_H
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
|
#include <QTextEdit>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "EmojiPickButton.h"
|
||||||
#include "FlatButton.h"
|
#include "FlatButton.h"
|
||||||
|
|
||||||
|
class FilteredTextEdit : public QTextEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit FilteredTextEdit(QWidget *parent = nullptr);
|
||||||
|
void keyPressEvent(QKeyEvent *event);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void enterPressed();
|
||||||
|
};
|
||||||
|
|
||||||
class TextInputWidget : public QWidget
|
class TextInputWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -36,6 +48,9 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void onSendButtonClicked();
|
void onSendButtonClicked();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void addSelectedEmoji(const QString &emoji);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendTextMessage(QString msg);
|
void sendTextMessage(QString msg);
|
||||||
|
|
||||||
|
@ -44,10 +59,11 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHBoxLayout *top_layout_;
|
QHBoxLayout *top_layout_;
|
||||||
QLineEdit *input_;
|
FilteredTextEdit *input_;
|
||||||
|
|
||||||
FlatButton *send_file_button_;
|
FlatButton *send_file_button_;
|
||||||
FlatButton *send_message_button_;
|
FlatButton *send_message_button_;
|
||||||
|
EmojiPickButton *emoji_button_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXT_INPUT_WIDGET_H
|
#endif // TEXT_INPUT_WIDGET_H
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum {
|
enum {
|
||||||
IconPadding = 12
|
IconPadding = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
void checkStateSet() override;
|
void checkStateSet() override;
|
||||||
|
|
1
resources/emoji.json
Normal file
BIN
resources/icons/emoji-categories/activity.png
Normal file
After Width: | Height: | Size: 659 B |
25
resources/icons/emoji-categories/activity.svg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata4213"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4211" /><g
|
||||||
|
id="g4205"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path4207"
|
||||||
|
d="M12,0C5.373,0,0,5.372,0,12c0,6.627,5.373,12,12,12c6.628,0,12-5.373,12-12C24,5.372,18.628,0,12,0 M21.949,11H17.05c0.224-2.527,1.232-4.773,1.968-6.113C20.634,6.481,21.712,8.618,21.949,11 M13,11V2.051 c1.623,0.162,3.13,0.719,4.432,1.564C16.574,5.106,15.276,7.835,15.04,11H13z M11,11H8.961C8.723,7.835,7.425,5.106,6.568,3.615 C7.871,2.77,9.377,2.213,11,2.051V11z M11,13v8.949c-1.623-0.162-3.129-0.718-4.432-1.564C7.425,18.893,8.723,16.164,8.961,13H11z M15.04,13c0.236,3.164,1.534,5.893,2.392,7.385c-1.302,0.847-2.809,1.402-4.432,1.564V13H15.04z M4.982,4.887 C5.718,6.227,6.726,8.473,6.951,11h-4.9C2.289,8.618,3.367,6.481,4.982,4.887 M2.051,13h4.9c-0.226,2.527-1.233,4.771-1.969,6.113 C3.367,17.52,2.289,15.383,2.051,13 M19.018,19.113c-0.735-1.342-1.744-3.586-1.968-6.113h4.899 C21.712,15.383,20.634,17.52,19.018,19.113"
|
||||||
|
fill="#010202" /></g></svg>
|
After Width: | Height: | Size: 1.7 KiB |
30
resources/icons/emoji-categories/diversity.svg
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
id="svg2"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
height="32"
|
||||||
|
width="32"
|
||||||
|
version="1.1">
|
||||||
|
<metadata
|
||||||
|
id="metadata10">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<path
|
||||||
|
id="path4"
|
||||||
|
d="M14 8c0-1.105 0.895-2 2-2s2 0.895 2 2c0 1.105-0.895 2-2 2s-2-0.895-2-2zM16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM16 26c-1.105 0-2-0.895-2-2s0.895-2 2-2c1.105 0 2 0.895 2 2s-0.895 2-2 2zM16 16c-3.59 0-6.5 2.91-6.5 6.5s2.91 6.5 6.5 6.5c-7.18 0-13-5.82-13-13s5.82-13 13-13c3.59 0 6.5 2.91 6.5 6.5s-2.91 6.5-6.5 6.5z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/emoji-categories/flags.png
Normal file
After Width: | Height: | Size: 472 B |
29
resources/icons/emoji-categories/flags.svg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata6641"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs6639" /><g
|
||||||
|
id="g6631"><polygon
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="polygon6633"
|
||||||
|
points="0,0 6.084,24 8,24 1.916,0 "
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path6635"
|
||||||
|
d="M21,5h-4l-1-4H4l3,12h3l1,4h2h11L21,5z M6.563,3h7.875l2,8H8.563L6.563,3z M15.395,13l-2.856,1.904 L12.063,13H15.395z M19,13l-1.5-6h1.938l2,8H16L19,13z"
|
||||||
|
fill="#010202" /></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/emoji-categories/foods.png
Normal file
After Width: | Height: | Size: 599 B |
25
resources/icons/emoji-categories/foods.svg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata4164"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4162" /><g
|
||||||
|
id="g4156"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path4158"
|
||||||
|
d="M17,4.978c-1.838,0-2.876,0.396-3.68,0.934c0.513-1.172,1.768-2.934,4.68-2.934c0.552,0,1-0.448,1-1 s-0.448-1-1-1c-2.921,0-4.629,1.365-5.547,2.512c-0.064,0.078-0.119,0.162-0.18,0.244c-0.543-1.896-1.475-3.711-3.066-3.711 C8.579,0.022,7.85,0.306,7,0.978C5.027,2.54,5.329,3.902,6.492,4.999C3.609,5.222,0,7.352,0,12.969c0,4.582,4.961,11.009,9,11.009 c1.975,0,2.371-0.486,3-1c0.629,0.514,1.025,1,3,1c4.039,0,9-6.418,9-11C24,7.025,19.945,4.978,17,4.978 M8.242,2.546 c0.641-0.508,0.943-0.523,0.965-0.523c0.426,0.169,0.975,1.405,1.357,3.055c-1.527-0.629-2.741-1.352-2.98-1.846 C7.643,3.12,7.825,2.876,8.242,2.546 M15,21.978c-1.08,0-1.21-0.109-1.559-0.402l-0.176-0.146 c-0.367-0.302-0.816-0.452-1.266-0.452s-0.898,0.15-1.266,0.452l-0.176,0.146C10.21,21.868,10.08,21.978,9,21.978 c-2.813,0-7-5.389-7-9.009c0-5.823,4.488-5.991,5-5.991c1.939,0,2.484,0.471,3.387,1.251c0.107,0.092,0.215,0.185,0.323,0.276 C11.083,8.82,11.541,8.978,12,8.978s0.917-0.157,1.29-0.473c0.108-0.092,0.216-0.185,0.323-0.276 c0.902-0.78,1.447-1.251,3.387-1.251c0.512,0,5,0.168,5,6C22,16.595,17.813,21.978,15,21.978"
|
||||||
|
fill="#010202" /></g></svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/icons/emoji-categories/nature.png
Normal file
After Width: | Height: | Size: 725 B |
36
resources/icons/emoji-categories/nature.svg
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata6036"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs6034" /><g
|
||||||
|
id="g6024"><g
|
||||||
|
id="g6578"><g
|
||||||
|
id="g6583"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path6028"
|
||||||
|
d="M15.5,8C14.672,8,14,8.672,14,9.5s0.672,1.5,1.5,1.5S17,10.329,17,9.5S16.328,8,15.5,8"
|
||||||
|
fill="#010202" /><g
|
||||||
|
id="g6588"><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M8.5,8C7.672,8,7,8.672,7,9.5S7.672,11,8.5,11S10,10.329,10,9.5S9.329,8,8.5,8"
|
||||||
|
id="path6026"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M18.933,0h-0.027c-0.97,0-2.138,0.787-3.018,1.497c-1.274-0.374-2.612-0.51-3.887-0.51 c-1.285,0-2.616,0.133-3.874,0.517C7.245,0.79,6.069,0,5.093,0H5.066C3.352,0,0.07,2.67,0.002,7.026 c-0.039,2.479,0.276,4.238,1.04,5.013c0.254,0.258,0.882,0.677,1.295,0.882c0.191,3.177,0.922,5.238,2.536,6.38 c0.897,0.637,2.187,0.949,3.2,1.102C8.04,20.6,8,20.795,8,21c0,1.773,2.35,3,4,3c1.648,0,4-1.227,4-3 c0-0.201-0.038-0.393-0.072-0.586c2.573-0.385,5.435-1.877,5.925-7.587c0.396-0.22,0.887-0.568,1.104-0.788 c0.763-0.774,1.079-2.534,1.04-5.013C23.929,2.67,20.646,0,18.933,0 M3.223,9.135c-0.237,0.281-0.837,1.155-0.884,1.238 c-0.15-0.41-0.368-1.349-0.337-3.291C2.053,3.801,4.48,2.11,5.093,2.051c0.256,0.015,0.731,0.27,1.265,0.646 c-1.11,1.171-2.275,2.915-2.352,5.125C3.873,8.368,3.608,8.68,3.223,9.135 M12,22c-0.901,0-1.954-0.693-2-1 c0-0.654,0.475-1.236,1-1.602V20c0,0.553,0.447,1,1,1s1-0.447,1-1v-0.602c0.524,0.365,1,0.947,1,1.602 C13.954,21.307,12.901,22,12,22 M15,18.52v0.02c-0.366-0.418-0.798-0.762-1.262-1.02c1.092-0.516,2.239-1.334,2.239-2.217 c0-1.842-1.781-2.195-3.977-2.195c-2.196,0-3.978,0.354-3.978,2.195c0,0.883,1.148,1.701,2.238,2.217 C9.799,17.777,9.368,18.121,9,18.539v-0.025c-1-0.076-2.182-0.281-2.973-0.842c-1.301-0.92-1.838-3.045-1.853-6.478 c0.008-0.014,0.016-0.028,0.023-0.041c0.496-0.826,1.49-1.45,1.804-3.102c0-2.047,1.357-3.631,2.362-4.522 C9.37,3.178,10.555,3,11.948,3c1.447,0,2.685,0.192,3.733,0.57c1,0.9,2.316,2.465,2.316,4.48c0.313,1.651,1.307,2.275,1.803,3.102 c0.035,0.058,0.068,0.117,0.102,0.178C19.843,17.297,17.953,18.34,15,18.52 M21.628,10.318c-0.037-0.065-0.074-0.13-0.113-0.195 c-0.233-0.387-0.502-0.706-0.739-0.987c-0.385-0.455-0.648-0.768-0.782-1.313c-0.076-2.209-1.241-3.954-2.353-5.124 c0.531-0.376,1.004-0.63,1.261-0.647c0.636,0.071,3.044,1.764,3.096,5.031C22.025,8.893,21.651,10.301,21.628,10.318"
|
||||||
|
id="path6030"
|
||||||
|
style="fill:#000000;fill-opacity:1" /></g></g></g></g></svg>
|
After Width: | Height: | Size: 3.2 KiB |
BIN
resources/icons/emoji-categories/objects.png
Normal file
After Width: | Height: | Size: 640 B |
30
resources/icons/emoji-categories/objects.svg
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata4838"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4836" /><g
|
||||||
|
id="g4820"><g
|
||||||
|
id="g4822" /><g
|
||||||
|
id="g4830"><g
|
||||||
|
id="g5383"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
d="M 12 0 C 7.029 0 3 4.029 3 9 C 3 12.120081 4.5888411 14.867862 7 16.482422 L 7 21 C 7 21 9.035 24 12 24 C 14.965 24 17 21 17 21 L 17 16.482422 C 19.411159 14.867862 21 12.120081 21 9 C 21 4.029 16.971 0 12 0 z M 12 2 C 15.86 2 19 5.141 19 9 C 19 12.859 15.86 16 12 16 C 8.14 16 5 12.859 5 9 C 5 5.141 8.14 2 12 2 z M 9 17.476562 C 9.9397054 17.809261 10.946226 18 12 18 C 13.053774 18 14.060295 17.809261 15 17.476562 L 15 18.310547 C 14.089581 18.746635 13.074971 19 12 19 C 10.925029 19 9.9104192 18.746635 9 18.310547 L 9 17.476562 z M 9.2363281 20.546875 C 10.108023 20.832252 11.032636 21 12 21 C 12.965197 21 13.887813 20.832689 14.757812 20.548828 C 14.155076 21.173162 13.152816 22 12 22 C 10.89775 22 9.8827458 21.211335 9.2363281 20.546875 z "
|
||||||
|
id="path4824" /><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M14.745,12.449h-0.004c-0.852-0.024-1.188-0.858-1.577-1.824c-0.421-1.061-0.703-1.561-1.182-1.566h-0.009 c-0.481,0-0.783,0.497-1.235,1.537c-0.436,0.982-0.801,1.811-1.636,1.791l-0.276-0.043c-0.565-0.171-0.853-0.691-1.284-1.794 c-0.125-0.313-0.202-0.632-0.27-0.913C7.221,9.424,7.145,9.107,7.077,9.003C7.067,9.004,7.039,9,6.99,9 C6.438,8.994,5.994,8.543,6,7.99C6.006,7.441,6.452,7,7,7h0.01c1.662,0.017,2.015,1.373,2.198,2.134 c0.486-0.981,1.304-2.058,2.797-2.075c1.531,0.018,2.28,1.153,2.731,2.141c0-0.002,0.001-0.006,0.002-0.008 C14.944,8.424,15.327,7,16.979,7h0.032C17.563,7.007,18.006,7.459,18,8.012C17.994,8.56,17.547,9,17,9h-0.011 c-0.149,0.076-0.256,0.474-0.319,0.709c-0.079,0.295-0.169,0.629-0.311,0.951C15.93,11.633,15.569,12.449,14.745,12.449"
|
||||||
|
id="path4832" /></g></g></g></svg>
|
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/icons/emoji-categories/people.png
Normal file
After Width: | Height: | Size: 637 B |
37
resources/icons/emoji-categories/people.svg
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata7236"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs7234" /><g
|
||||||
|
id="g7222"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7224"
|
||||||
|
d="M12,0C5.373,0,0,5.373,0,12s5.373,12,12,12s12-5.373,12-12S18.627,0,12,0 M12,22C6.486,22,2,17.514,2,12 S6.486,2,12,2s10,4.486,10,10S17.514,22,12,22"
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7226"
|
||||||
|
d="M8,7C6.895,7,6,7.895,6,9s0.895,2,2,2s2-0.895,2-2S9.105,7,8,7"
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7228"
|
||||||
|
d="M16,7c-1.105,0-2,0.895-2,2s0.895,2,2,2s2-0.895,2-2S17.105,7,16,7"
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7230"
|
||||||
|
d="M15.232,15c-0.693,1.195-1.87,2-3.349,2c-1.477,0-2.655-0.805-3.347-2H15 M18,13H6c0,3.314,2.686,6,6,6 S18,16.314,18,13"
|
||||||
|
fill="#010202" /></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
29
resources/icons/emoji-categories/recent.svg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata8433"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs8431" /><g
|
||||||
|
id="g8421"><path
|
||||||
|
id="polygon8423"
|
||||||
|
d="M 13,4 11,4 10.999,11 9,11 l 0,2 2,0 0,2 2,0 0,-2 4,0 0,-2 -4,0 z"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><g
|
||||||
|
id="g8425"><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path8427"
|
||||||
|
d="M12,0C5.373,0,0,5.373,0,12s5.373,12,12,12s12-5.373,12-12S18.627,0,12,0 M12,22C6.486,22,2,17.514,2,12 S6.486,2,12,2s10,4.486,10,10S17.514,22,12,22"
|
||||||
|
fill="#010202" /></g></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/icons/emoji-categories/symbols.png
Normal file
After Width: | Height: | Size: 560 B |
46
resources/icons/emoji-categories/symbols.svg
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata7837"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs7835" /><g
|
||||||
|
id="g7817"><path
|
||||||
|
id="rect7819"
|
||||||
|
d="M 0,0 11,0 11,2 0,2 Z"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
id="polygon7821"
|
||||||
|
d="M 4,11 7,11 7,6 11,6 11,4 0,4 0,6 4,6 Z"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7823"
|
||||||
|
d="M15.5,17c1.381,0,2.5-1.116,2.5-2.493s-1.119-2.493-2.5-2.493S13,13.13,13,14.507S14.119,17,15.5,17 M15.5,14.014c0.276,0,0.5,0.222,0.5,0.493C16,14.779,15.776,15,15.5,15S15,14.779,15,14.507C15,14.235,15.224,14.014,15.5,14.014"
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7825"
|
||||||
|
d="M21.5,19.014c-1.381,0-2.5,1.116-2.5,2.493S20.119,24,21.5,24s2.5-1.116,2.5-2.493 S22.881,19.014,21.5,19.014 M21.5,22c-0.276,0-0.5-0.221-0.5-0.493c0-0.271,0.224-0.493,0.5-0.493s0.5,0.222,0.5,0.493 C22,21.779,21.776,22,21.5,22"
|
||||||
|
fill="#010202" /><path
|
||||||
|
id="polygon7827"
|
||||||
|
d="m 22,13 -9,9 1.513,1.5 8.99,-9.009 z"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7829"
|
||||||
|
d="M17,11c2.209,0,4-1.119,4-2.5V2c0,0,0.985-0.161,1.498,0.949C23.01,4.055,23,6,23,6s1-1.119,1-3.135 C24-0.02,21,0,21,0h-2v6.347C18.41,6.132,17.732,6,17,6c-2.209,0-4,1.119-4,2.5S14.791,11,17,11"
|
||||||
|
fill="#010202" /><path
|
||||||
|
style="fill:#000000;fill-opacity:1"
|
||||||
|
id="path7831"
|
||||||
|
d="M10.297,20.482l-1.475-1.585c-0.773,0.619-1.254,0.995-1.442,1.129c-0.307-0.288-0.989-1.016-2.045-2.183 c0.902-0.836,1.479-1.466,1.729-1.892s0.376-0.871,0.376-1.336c0-0.592-0.273-1.178-0.818-1.759 c-0.546-0.581-1.329-0.871-2.349-0.871c-1.008,0-1.79,0.293-2.344,0.879c-0.556,0.587-0.832,1.181-0.832,1.784 c0,0.813,0.419,1.748,1.256,2.805c-0.847,0.614-1.444,1.208-1.794,1.784c-0.35,0.575-0.523,1.186-0.523,1.833 c0,0.857,0.308,1.56,0.924,2.107C1.576,23.726,2.383,24,3.38,24c1.173,0,2.444-0.379,3.813-1.137L8.235,24h2.819l-2.09-2.383 L10.297,20.482z M3.561,14.093c0.199-0.19,0.443-0.286,0.73-0.286c0.31,0,0.559,0.085,0.747,0.254 c0.189,0.171,0.283,0.391,0.283,0.659c0,0.518-0.419,1.112-1.257,1.784c-0.536-0.651-0.805-1.231-0.805-1.742 C3.26,14.508,3.36,14.284,3.561,14.093 M3.74,22c-0.427,0-0.778-0.116-1.057-0.349c-0.279-0.232-0.418-0.487-0.418-0.766 c0-0.594,0.509-1.288,1.527-2.083c0.968,1.134,1.717,1.946,2.248,2.438C5.119,21.747,4.354,22,3.74,22"
|
||||||
|
fill="#010202" /></g></svg>
|
After Width: | Height: | Size: 3.1 KiB |
BIN
resources/icons/emoji-categories/travel.png
Normal file
After Width: | Height: | Size: 535 B |
34
resources/icons/emoji-categories/travel.svg
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
width="24px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Слой_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata5438"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs5436" /><g
|
||||||
|
id="g5426"><g
|
||||||
|
id="g5980"><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M6.5,12C5.122,12,4,13.121,4,14.5S5.122,17,6.5,17S9,15.879,9,14.5S7.878,12,6.5,12 M6.5,15 C6.225,15,6,14.775,6,14.5S6.225,14,6.5,14S7,14.225,7,14.5S6.775,15,6.5,15"
|
||||||
|
id="path5428"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M17.5,12c-1.378,0-2.5,1.121-2.5,2.5s1.122,2.5,2.5,2.5s2.5-1.121,2.5-2.5S18.878,12,17.5,12 M17.5,15 c-0.275,0-0.5-0.225-0.5-0.5s0.225-0.5,0.5-0.5s0.5,0.225,0.5,0.5S17.775,15,17.5,15"
|
||||||
|
id="path5430"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
fill="#010202"
|
||||||
|
d="M22.482,9.494l-1.039-0.346L21.4,9H22c0.552,0,1-0.439,1-0.992C23,8.002,22.997,8,22.997,8H23 c0-1-0.889-2-1.984-2h-0.642l-0.731-1.717C19.262,3.012,18.091,2,16.764,2H7.236C5.909,2,4.738,3.012,4.357,4.283L3.626,6H2.984 C1.889,6,1,7,1,8h0.003C1.003,8,1,8.002,1,8.008C1,8.561,1.448,9,2,9h0.6L2.557,9.148L1.518,9.494 C0.63,9.79,0.066,10.661,0.159,11.591l0.751,7.508C0.961,19.611,1.391,20,1.904,20H3v1c0,1.103,0.896,2,2,2h2c1.104,0,2-0.897,2-2 v-1h6v1c0,1.103,0.896,2,2,2h2c1.104,0,2-0.897,2-2v-1h1.096c0.514,0,0.943-0.389,0.994-0.901l0.751-7.508 C23.934,10.661,23.37,9.79,22.482,9.494 M6.273,4.857C6.402,4.43,6.788,4,7.236,4h9.527c0.448,0,0.834,0.43,0.963,0.857L19.313,9 H4.688L6.273,4.857z M7,21H5v-1h2V21z M19,21h-2v-1h2V21z M21.189,18H21h-6H9H3H2.811l-0.662-6.607L3,11h18l0.852,0.393L21.189,18z "
|
||||||
|
id="path5432"
|
||||||
|
style="fill:#000000;fill-opacity:1" /></g></g></svg>
|
After Width: | Height: | Size: 2.2 KiB |
30
resources/icons/emoji-categories/unicode9.svg
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
id="svg2"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
height="32"
|
||||||
|
width="32"
|
||||||
|
version="1.1">
|
||||||
|
<metadata
|
||||||
|
id="metadata10">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<path
|
||||||
|
id="path4"
|
||||||
|
d="M20 12.667v-2.688h-2.688v2.688h2.688zM20 7.354c1.438 0 2.688 1.125 2.688 2.625v8c0 1.5-1.25 2.688-2.688 2.688h-5.313v-2.688h5.313v-2.625h-2.688c-1.438 0-2.625-1.188-2.625-2.688v-2.688c0-1.5 1.188-2.625 2.625-2.625h2.688zM28 23.354v-18.688h-18.688v18.688h18.688zM28 1.979c1.438 0 2.688 1.25 2.688 2.688v18.688c0 1.438-1.25 2.625-2.688 2.625h-18.688c-1.438 0-2.625-1.188-2.625-2.625v-18.688c0-1.438 1.188-2.688 2.625-2.688h18.688zM4 7.354v21.313h21.313v2.688h-21.313c-1.438 0-2.688-1.25-2.688-2.688v-21.313h2.688z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/icons/smile.png
Normal file
After Width: | Height: | Size: 631 B |
|
@ -11,6 +11,17 @@
|
||||||
<file>icons/share-dark.png</file>
|
<file>icons/share-dark.png</file>
|
||||||
<file>icons/user-shape.png</file>
|
<file>icons/user-shape.png</file>
|
||||||
<file>icons/power-button-off.png</file>
|
<file>icons/power-button-off.png</file>
|
||||||
|
<file>icons/smile.png</file>
|
||||||
|
|
||||||
|
<file>icons/emoji-categories/people.png</file>
|
||||||
|
<file>icons/emoji-categories/nature.png</file>
|
||||||
|
<file>icons/emoji-categories/foods.png</file>
|
||||||
|
<file>icons/emoji-categories/activity.png</file>
|
||||||
|
<file>icons/emoji-categories/travel.png</file>
|
||||||
|
<file>icons/emoji-categories/objects.png</file>
|
||||||
|
<file>icons/emoji-categories/symbols.png</file>
|
||||||
|
<file>icons/emoji-categories/flags.png</file>
|
||||||
|
|
||||||
</qresource>
|
</qresource>
|
||||||
|
|
||||||
<qresource prefix="/logos">
|
<qresource prefix="/logos">
|
||||||
|
|
89
scripts/emoji_codegen.py
Executable file
|
@ -0,0 +1,89 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
from jinja2 import Template
|
||||||
|
|
||||||
|
|
||||||
|
class Emoji(object):
|
||||||
|
def __init__(self, code, shortname, category, order):
|
||||||
|
self.code = ''.join(list(map(code_to_bytes, code.split('-'))))
|
||||||
|
self.shortname = shortname
|
||||||
|
self.category = category
|
||||||
|
self.order = int(order)
|
||||||
|
|
||||||
|
|
||||||
|
def code_to_bytes(codepoint):
|
||||||
|
'''
|
||||||
|
Convert hex unicode codepoint to hex byte array.
|
||||||
|
'''
|
||||||
|
bytes = chr(int(codepoint, 16)).encode('utf-8')
|
||||||
|
|
||||||
|
return str(bytes)[1:].strip("'")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_code(emojis, category):
|
||||||
|
tmpl = Template('''
|
||||||
|
const QList<Emoji> EmojiProvider::{{ category }} = {
|
||||||
|
{%- for e in emoji %}
|
||||||
|
Emoji{QString::fromUtf8("{{ e.code }}"), "{{ e.shortname }}"},
|
||||||
|
{%- endfor %}
|
||||||
|
};
|
||||||
|
''')
|
||||||
|
|
||||||
|
d = dict(category=category, emoji=emojis)
|
||||||
|
print(tmpl.render(d))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print('usage: emoji_codegen.py /path/to/emoji.json')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
filename = sys.argv[1]
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
with open(filename, 'r') as filename:
|
||||||
|
data = json.loads(filename.read())
|
||||||
|
|
||||||
|
emojis = []
|
||||||
|
|
||||||
|
for emoji_name in data:
|
||||||
|
tmp = data[emoji_name]
|
||||||
|
|
||||||
|
l = len(tmp['unicode'].split('-'))
|
||||||
|
|
||||||
|
if l > 1 and tmp['category'] == 'people':
|
||||||
|
continue
|
||||||
|
|
||||||
|
emojis.append(
|
||||||
|
Emoji(
|
||||||
|
tmp['unicode'],
|
||||||
|
tmp['shortname'],
|
||||||
|
tmp['category'],
|
||||||
|
tmp['emoji_order']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
emojis.sort(key=lambda x: x.order)
|
||||||
|
|
||||||
|
people = list(filter(lambda x: x.category == "people", emojis))
|
||||||
|
nature = list(filter(lambda x: x.category == "nature", emojis))
|
||||||
|
food = list(filter(lambda x: x.category == "food", emojis))
|
||||||
|
activity = list(filter(lambda x: x.category == "activity", emojis))
|
||||||
|
travel = list(filter(lambda x: x.category == "travel", emojis))
|
||||||
|
objects = list(filter(lambda x: x.category == "objects", emojis))
|
||||||
|
symbols = list(filter(lambda x: x.category == "symbols", emojis))
|
||||||
|
flags = list(filter(lambda x: x.category == "flags", emojis))
|
||||||
|
|
||||||
|
# Use xclip to pipe the output to clipboard.
|
||||||
|
# e.g ./codegen.py emoji.json | xclip -sel clip
|
||||||
|
generate_code(people, 'people')
|
||||||
|
generate_code(nature, 'nature')
|
||||||
|
generate_code(food, 'food')
|
||||||
|
generate_code(activity, 'activity')
|
||||||
|
generate_code(travel, 'travel')
|
||||||
|
generate_code(objects, 'objects')
|
||||||
|
generate_code(symbols, 'symbols')
|
||||||
|
generate_code(flags, 'flags')
|
84
src/EmojiCategory.cc
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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 <QScrollBar>
|
||||||
|
|
||||||
|
#include "EmojiCategory.h"
|
||||||
|
|
||||||
|
EmojiCategory::EmojiCategory(QString category, QList<Emoji> emoji, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
mainLayout_ = new QVBoxLayout(this);
|
||||||
|
mainLayout_->setMargin(0);
|
||||||
|
|
||||||
|
emojiListView_ = new QListView();
|
||||||
|
itemModel_ = new QStandardItemModel(this);
|
||||||
|
|
||||||
|
delegate_ = new EmojiItemDelegate(this);
|
||||||
|
data_ = new Emoji;
|
||||||
|
|
||||||
|
emojiListView_->setItemDelegate(delegate_);
|
||||||
|
emojiListView_->setSpacing(5);
|
||||||
|
emojiListView_->setModel(itemModel_);
|
||||||
|
emojiListView_->setViewMode(QListView::IconMode);
|
||||||
|
emojiListView_->setFlow(QListView::LeftToRight);
|
||||||
|
emojiListView_->setResizeMode(QListView::Adjust);
|
||||||
|
emojiListView_->verticalScrollBar()->setEnabled(false);
|
||||||
|
emojiListView_->horizontalScrollBar()->setEnabled(false);
|
||||||
|
|
||||||
|
const int cols = 7;
|
||||||
|
const int rows = emoji.size() / 7;
|
||||||
|
|
||||||
|
// TODO: Be precise here. Take the parent into consideration.
|
||||||
|
emojiListView_->setFixedSize(cols * 50 + 20, rows * 50 + 20);
|
||||||
|
emojiListView_->setGridSize(QSize(50, 50));
|
||||||
|
emojiListView_->setDragEnabled(false);
|
||||||
|
emojiListView_->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
|
||||||
|
for (const auto &e : emoji) {
|
||||||
|
data_->unicode = e.unicode;
|
||||||
|
|
||||||
|
auto item = new QStandardItem;
|
||||||
|
item->setSizeHint(QSize(24, 24));
|
||||||
|
|
||||||
|
QVariant unicode(data_->unicode);
|
||||||
|
item->setData(unicode.toString(), Qt::UserRole);
|
||||||
|
|
||||||
|
itemModel_->appendRow(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
category_ = new QLabel(category, this);
|
||||||
|
category_->setStyleSheet(
|
||||||
|
"color: #ccc;"
|
||||||
|
"margin: 20px 0px 15px 8px;"
|
||||||
|
"font-weight: 500;"
|
||||||
|
"font-size: 12px;");
|
||||||
|
|
||||||
|
auto labelLayout_ = new QHBoxLayout();
|
||||||
|
labelLayout_->addWidget(category_);
|
||||||
|
labelLayout_->addStretch(1);
|
||||||
|
|
||||||
|
mainLayout_->addLayout(labelLayout_);
|
||||||
|
mainLayout_->addWidget(emojiListView_);
|
||||||
|
|
||||||
|
connect(emojiListView_, &QListView::clicked, this, &EmojiCategory::clickIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmojiCategory::~EmojiCategory()
|
||||||
|
{
|
||||||
|
}
|
47
src/EmojiItemDelegate.cc
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 <QPainter>
|
||||||
|
|
||||||
|
#include "EmojiItemDelegate.h"
|
||||||
|
|
||||||
|
EmojiItemDelegate::EmojiItemDelegate(QObject *parent)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
{
|
||||||
|
data_ = new Emoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmojiItemDelegate::~EmojiItemDelegate()
|
||||||
|
{
|
||||||
|
delete data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(index);
|
||||||
|
|
||||||
|
QStyleOptionViewItem viewOption(option);
|
||||||
|
|
||||||
|
auto emoji = index.data(Qt::UserRole).toString();
|
||||||
|
|
||||||
|
QFont font("Emoji One");
|
||||||
|
font.setPixelSize(19);
|
||||||
|
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->drawText(viewOption.rect, emoji);
|
||||||
|
}
|
247
src/EmojiPanel.cc
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
* 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 <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Avatar.h"
|
||||||
|
#include "EmojiCategory.h"
|
||||||
|
#include "EmojiPanel.h"
|
||||||
|
#include "FlatButton.h"
|
||||||
|
|
||||||
|
EmojiPanel::EmojiPanel(QWidget *parent)
|
||||||
|
: QFrame(parent)
|
||||||
|
{
|
||||||
|
setStyleSheet(
|
||||||
|
"QWidget {background: #f8fbfe; color: #e8e8e8; border: none;}"
|
||||||
|
"QScrollBar:vertical { background-color: #f8fbfe; width: 8px; border-radius: 20px; margin: 0px 2px 0 2px; }"
|
||||||
|
"QScrollBar::handle:vertical { border-radius : 50px; background-color : #d6dde3; }"
|
||||||
|
"QScrollBar::add-line:vertical { border: none; background: none; }"
|
||||||
|
"QScrollBar::sub-line:vertical { border: none; background: none; }");
|
||||||
|
|
||||||
|
setParent(0); // Create TopLevel-Widget
|
||||||
|
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||||
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||||
|
setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
|
||||||
|
|
||||||
|
// TODO: Make it MainWindow aware
|
||||||
|
auto main_frame_ = new QFrame(this);
|
||||||
|
main_frame_->setMinimumSize(370, 350);
|
||||||
|
main_frame_->setMaximumSize(370, 350);
|
||||||
|
|
||||||
|
auto top_layout = new QVBoxLayout(this);
|
||||||
|
top_layout->addWidget(main_frame_);
|
||||||
|
top_layout->setMargin(0);
|
||||||
|
|
||||||
|
auto content_layout = new QVBoxLayout(main_frame_);
|
||||||
|
content_layout->setMargin(0);
|
||||||
|
|
||||||
|
auto emoji_categories = new QFrame(main_frame_);
|
||||||
|
emoji_categories->setStyleSheet("background-color: #f2f2f2");
|
||||||
|
|
||||||
|
auto categories_layout = new QHBoxLayout(emoji_categories);
|
||||||
|
categories_layout->setSpacing(6);
|
||||||
|
categories_layout->setMargin(5);
|
||||||
|
|
||||||
|
auto people_category = new FlatButton(emoji_categories);
|
||||||
|
people_category->setIcon(QIcon(":/icons/icons/emoji-categories/people.png"));
|
||||||
|
people_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
people_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto nature_category = new FlatButton(emoji_categories);
|
||||||
|
nature_category->setIcon(QIcon(":/icons/icons/emoji-categories/nature.png"));
|
||||||
|
nature_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
nature_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto food_category = new FlatButton(emoji_categories);
|
||||||
|
food_category->setIcon(QIcon(":/icons/icons/emoji-categories/foods.png"));
|
||||||
|
food_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
food_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto activity_category = new FlatButton(emoji_categories);
|
||||||
|
activity_category->setIcon(QIcon(":/icons/icons/emoji-categories/activity.png"));
|
||||||
|
activity_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
activity_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto travel_category = new FlatButton(emoji_categories);
|
||||||
|
travel_category->setIcon(QIcon(":/icons/icons/emoji-categories/travel.png"));
|
||||||
|
travel_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
travel_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto objects_category = new FlatButton(emoji_categories);
|
||||||
|
objects_category->setIcon(QIcon(":/icons/icons/emoji-categories/objects.png"));
|
||||||
|
objects_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
objects_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto symbols_category = new FlatButton(emoji_categories);
|
||||||
|
symbols_category->setIcon(QIcon(":/icons/icons/emoji-categories/symbols.png"));
|
||||||
|
symbols_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
symbols_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
auto flags_category = new FlatButton(emoji_categories);
|
||||||
|
flags_category->setIcon(QIcon(":/icons/icons/emoji-categories/flags.png"));
|
||||||
|
flags_category->setIconSize(QSize(category_icon_size_, category_icon_size_));
|
||||||
|
flags_category->setForegroundColor("gray");
|
||||||
|
|
||||||
|
categories_layout->addWidget(people_category);
|
||||||
|
categories_layout->addWidget(nature_category);
|
||||||
|
categories_layout->addWidget(food_category);
|
||||||
|
categories_layout->addWidget(activity_category);
|
||||||
|
categories_layout->addWidget(travel_category);
|
||||||
|
categories_layout->addWidget(objects_category);
|
||||||
|
categories_layout->addWidget(symbols_category);
|
||||||
|
categories_layout->addWidget(flags_category);
|
||||||
|
|
||||||
|
scroll_area_ = new QScrollArea(this);
|
||||||
|
scroll_area_->setWidgetResizable(true);
|
||||||
|
scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
auto scroll_widget_ = new QWidget(this);
|
||||||
|
auto scroll_layout_ = new QVBoxLayout(scroll_widget_);
|
||||||
|
|
||||||
|
scroll_layout_->setMargin(0);
|
||||||
|
scroll_area_->setWidget(scroll_widget_);
|
||||||
|
|
||||||
|
auto people_emoji = new EmojiCategory("Smileys & People", emoji_provider_.people, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(people_emoji);
|
||||||
|
|
||||||
|
auto nature_emoji = new EmojiCategory("Animals & Nature", emoji_provider_.nature, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(nature_emoji);
|
||||||
|
|
||||||
|
auto food_emoji = new EmojiCategory("Food & Drink", emoji_provider_.food, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(food_emoji);
|
||||||
|
|
||||||
|
auto activity_emoji = new EmojiCategory("Activity", emoji_provider_.activity, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(activity_emoji);
|
||||||
|
|
||||||
|
auto travel_emoji = new EmojiCategory("Travel & Places", emoji_provider_.travel, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(travel_emoji);
|
||||||
|
|
||||||
|
auto objects_emoji = new EmojiCategory("Objects", emoji_provider_.objects, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(objects_emoji);
|
||||||
|
|
||||||
|
auto symbols_emoji = new EmojiCategory("Symbols", emoji_provider_.symbols, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(symbols_emoji);
|
||||||
|
|
||||||
|
auto flags_emoji = new EmojiCategory("Flags", emoji_provider_.flags, scroll_widget_);
|
||||||
|
scroll_layout_->addWidget(flags_emoji);
|
||||||
|
|
||||||
|
content_layout->addStretch(1);
|
||||||
|
content_layout->addWidget(scroll_area_);
|
||||||
|
content_layout->addWidget(emoji_categories);
|
||||||
|
|
||||||
|
setLayout(top_layout);
|
||||||
|
|
||||||
|
// TODO: Add parallel animation with geometry
|
||||||
|
opacity_ = new QGraphicsOpacityEffect(this);
|
||||||
|
opacity_->setOpacity(1.0);
|
||||||
|
|
||||||
|
setGraphicsEffect(opacity_);
|
||||||
|
|
||||||
|
animation_ = new QPropertyAnimation(opacity_, "opacity", this);
|
||||||
|
animation_->setDuration(180);
|
||||||
|
animation_->setStartValue(1.0);
|
||||||
|
animation_->setEndValue(0.0);
|
||||||
|
|
||||||
|
connect(people_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(people_category, &QPushButton::clicked, [this, people_emoji]() {
|
||||||
|
this->showEmojiCategory(people_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(nature_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(nature_category, &QPushButton::clicked, [this, nature_emoji]() {
|
||||||
|
this->showEmojiCategory(nature_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(food_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(food_category, &QPushButton::clicked, [this, food_emoji]() {
|
||||||
|
this->showEmojiCategory(food_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(activity_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(activity_category, &QPushButton::clicked, [this, activity_emoji]() {
|
||||||
|
this->showEmojiCategory(activity_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(travel_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(travel_category, &QPushButton::clicked, [this, travel_emoji]() {
|
||||||
|
this->showEmojiCategory(travel_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(objects_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(objects_category, &QPushButton::clicked, [this, objects_emoji]() {
|
||||||
|
this->showEmojiCategory(objects_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(symbols_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(symbols_category, &QPushButton::clicked, [this, symbols_emoji]() {
|
||||||
|
this->showEmojiCategory(symbols_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(flags_emoji, &EmojiCategory::emojiSelected, this, &EmojiPanel::emojiSelected);
|
||||||
|
connect(flags_category, &QPushButton::clicked, [this, flags_emoji]() {
|
||||||
|
this->showEmojiCategory(flags_emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(animation_, &QPropertyAnimation::finished, [this]() {
|
||||||
|
if (animation_->direction() == QAbstractAnimation::Forward)
|
||||||
|
this->hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPanel::showEmojiCategory(const EmojiCategory *category)
|
||||||
|
{
|
||||||
|
auto posToGo = category->mapToParent(QPoint()).y();
|
||||||
|
auto current = scroll_area_->verticalScrollBar()->value();
|
||||||
|
|
||||||
|
if (current == posToGo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// HACK
|
||||||
|
// If we want to go to a previous category and position the label at the top
|
||||||
|
// the 6*50 offset won't work because not all the categories have the same height.
|
||||||
|
// To ensure the category is at the top, we move to the top
|
||||||
|
// and go as normal to the next category.
|
||||||
|
if (current > posToGo)
|
||||||
|
this->scroll_area_->ensureVisible(0, 0, 0, 0);
|
||||||
|
|
||||||
|
posToGo += 6 * 50;
|
||||||
|
this->scroll_area_->ensureVisible(0, posToGo, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPanel::leaveEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
|
||||||
|
fadeOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPanel::fadeOut()
|
||||||
|
{
|
||||||
|
animation_->setDirection(QAbstractAnimation::Forward);
|
||||||
|
animation_->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPanel::fadeIn()
|
||||||
|
{
|
||||||
|
animation_->setDirection(QAbstractAnimation::Backward);
|
||||||
|
animation_->start();
|
||||||
|
}
|
65
src/EmojiPickButton.cc
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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 "EmojiPickButton.h"
|
||||||
|
|
||||||
|
EmojiPickButton::EmojiPickButton(QWidget *parent)
|
||||||
|
: FlatButton(parent)
|
||||||
|
, panel_{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPickButton::enterEvent(QEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(e);
|
||||||
|
|
||||||
|
if (panel_ == nullptr) {
|
||||||
|
panel_ = new EmojiPanel(this);
|
||||||
|
connect(panel_, &EmojiPanel::emojiSelected, this, &EmojiPickButton::emojiSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_->fadeIn();
|
||||||
|
panel_->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiPickButton::leaveEvent(QEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(e);
|
||||||
|
|
||||||
|
if (panel_->underMouse())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto pos = QCursor::pos();
|
||||||
|
auto panel_geometry = panel_->geometry();
|
||||||
|
panel_geometry.adjust(0, 0, 0, vertical_distance_);
|
||||||
|
|
||||||
|
if (panel_geometry.contains(pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
panel_->fadeOut();
|
||||||
|
}
|
1470
src/EmojiProvider.cc
Normal file
|
@ -142,10 +142,10 @@ QString HistoryViewItem::replaceEmoji(const QString &body)
|
||||||
QString fmtBody = "";
|
QString fmtBody = "";
|
||||||
|
|
||||||
for (auto &c : body) {
|
for (auto &c : body) {
|
||||||
auto code = c.unicode();
|
int code = c.unicode();
|
||||||
|
|
||||||
// TODO: A map should be used with the unicode codes supported by emoji one
|
// TODO: Be more precise here.
|
||||||
if (code > 127)
|
if (code > 9000)
|
||||||
fmtBody += "<span style=\"font-family: Emoji One; font-size: 16px\">" + QString(c) + "</span>";
|
fmtBody += "<span style=\"font-family: Emoji One; font-size: 16px\">" + QString(c) + "</span>";
|
||||||
else
|
else
|
||||||
fmtBody += c;
|
fmtBody += c;
|
||||||
|
|
|
@ -16,11 +16,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
|
|
||||||
#include "TextInputWidget.h"
|
#include "TextInputWidget.h"
|
||||||
|
|
||||||
|
FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
|
: QTextEdit(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
|
||||||
|
emit enterPressed();
|
||||||
|
else
|
||||||
|
QTextEdit::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
TextInputWidget::TextInputWidget(QWidget *parent)
|
TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
|
@ -31,8 +45,8 @@ TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
setStyleSheet("background-color: #f8fbfe; height: 45px;");
|
setStyleSheet("background-color: #f8fbfe; height: 45px;");
|
||||||
|
|
||||||
top_layout_ = new QHBoxLayout();
|
top_layout_ = new QHBoxLayout();
|
||||||
top_layout_->setSpacing(6);
|
top_layout_->setSpacing(0);
|
||||||
top_layout_->setContentsMargins(6, 0, 0, 0);
|
top_layout_->setMargin(0);
|
||||||
|
|
||||||
send_file_button_ = new FlatButton(this);
|
send_file_button_ = new FlatButton(this);
|
||||||
send_file_button_->setCursor(Qt::PointingHandCursor);
|
send_file_button_->setCursor(Qt::PointingHandCursor);
|
||||||
|
@ -43,9 +57,10 @@ TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
send_file_button_->setIcon(send_file_icon);
|
send_file_button_->setIcon(send_file_icon);
|
||||||
send_file_button_->setIconSize(QSize(24, 24));
|
send_file_button_->setIconSize(QSize(24, 24));
|
||||||
|
|
||||||
input_ = new QLineEdit(this);
|
input_ = new FilteredTextEdit(this);
|
||||||
|
input_->setFixedHeight(45);
|
||||||
input_->setPlaceholderText("Write a message...");
|
input_->setPlaceholderText("Write a message...");
|
||||||
input_->setStyleSheet("color: black; font-size: 10pt; border-radius: 0; padding: 2px; margin-bottom: 4px;");
|
input_->setStyleSheet("color: #333333; font-size: 13px; border-radius: 0; padding-top: 10px;");
|
||||||
|
|
||||||
send_message_button_ = new FlatButton(this);
|
send_message_button_ = new FlatButton(this);
|
||||||
send_message_button_->setCursor(Qt::PointingHandCursor);
|
send_message_button_->setCursor(Qt::PointingHandCursor);
|
||||||
|
@ -56,24 +71,59 @@ TextInputWidget::TextInputWidget(QWidget *parent)
|
||||||
send_message_button_->setIcon(send_message_icon);
|
send_message_button_->setIcon(send_message_icon);
|
||||||
send_message_button_->setIconSize(QSize(24, 24));
|
send_message_button_->setIconSize(QSize(24, 24));
|
||||||
|
|
||||||
|
emoji_button_ = new EmojiPickButton(this);
|
||||||
|
emoji_button_->setCursor(Qt::PointingHandCursor);
|
||||||
|
emoji_button_->setForegroundColor(QColor("#acc7dc"));
|
||||||
|
|
||||||
|
QIcon emoji_icon;
|
||||||
|
emoji_icon.addFile(":/icons/icons/smile.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||||
|
emoji_button_->setIcon(emoji_icon);
|
||||||
|
emoji_button_->setIconSize(QSize(24, 24));
|
||||||
|
|
||||||
top_layout_->addWidget(send_file_button_);
|
top_layout_->addWidget(send_file_button_);
|
||||||
top_layout_->addWidget(input_);
|
top_layout_->addWidget(input_);
|
||||||
|
top_layout_->addWidget(emoji_button_);
|
||||||
top_layout_->addWidget(send_message_button_);
|
top_layout_->addWidget(send_message_button_);
|
||||||
|
|
||||||
setLayout(top_layout_);
|
setLayout(top_layout_);
|
||||||
|
|
||||||
connect(send_message_button_, SIGNAL(clicked()), this, SLOT(onSendButtonClicked()));
|
connect(send_message_button_, SIGNAL(clicked()), this, SLOT(onSendButtonClicked()));
|
||||||
connect(input_, SIGNAL(returnPressed()), send_message_button_, SIGNAL(clicked()));
|
connect(input_, SIGNAL(enterPressed()), send_message_button_, SIGNAL(clicked()));
|
||||||
|
connect(emoji_button_, SIGNAL(emojiSelected(const QString &)), this, SLOT(addSelectedEmoji(const QString &)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextInputWidget::addSelectedEmoji(const QString &emoji)
|
||||||
|
{
|
||||||
|
QTextCursor cursor = input_->textCursor();
|
||||||
|
|
||||||
|
QFont emoji_font("Emoji One");
|
||||||
|
emoji_font.setPixelSize(18);
|
||||||
|
|
||||||
|
QFont text_font("Open Sans");
|
||||||
|
text_font.setPixelSize(13);
|
||||||
|
|
||||||
|
QTextCharFormat charfmt;
|
||||||
|
charfmt.setFont(emoji_font);
|
||||||
|
input_->setCurrentCharFormat(charfmt);
|
||||||
|
|
||||||
|
input_->insertPlainText(emoji);
|
||||||
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
|
||||||
|
charfmt.setFont(text_font);
|
||||||
|
input_->setCurrentCharFormat(charfmt);
|
||||||
|
|
||||||
|
input_->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextInputWidget::onSendButtonClicked()
|
void TextInputWidget::onSendButtonClicked()
|
||||||
{
|
{
|
||||||
auto msg_text = input_->text().trimmed();
|
auto msg_text = input_->document()->toPlainText().trimmed();
|
||||||
|
|
||||||
if (msg_text.isEmpty())
|
if (msg_text.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
emit sendTextMessage(msg_text);
|
emit sendTextMessage(msg_text);
|
||||||
|
|
||||||
input_->clear();
|
input_->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -472,11 +472,11 @@ void FlatButton::paintForeground(QPainter *painter)
|
||||||
QRect textGeometry(pos + QPoint(0, base.height() / 2), textSize);
|
QRect textGeometry(pos + QPoint(0, base.height() / 2), textSize);
|
||||||
QRect iconGeometry(pos + QPoint(0, (height() - iconSize().height()) / 2), iconSize());
|
QRect iconGeometry(pos + QPoint(0, (height() - iconSize().height()) / 2), iconSize());
|
||||||
|
|
||||||
if (ui::LeftIcon == icon_placement_) {
|
/* if (ui::LeftIcon == icon_placement_) { */
|
||||||
textGeometry.translate(iw, 0);
|
/* textGeometry.translate(iw, 0); */
|
||||||
} else {
|
/* } else { */
|
||||||
iconGeometry.translate(textSize.width() + IconPadding, 0);
|
/* iconGeometry.translate(textSize.width() + IconPadding, 0); */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
painter->drawText(textGeometry, Qt::AlignCenter, text());
|
painter->drawText(textGeometry, Qt::AlignCenter, text());
|
||||||
|
|
||||||
|
|