qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
emoticonswidget.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2014-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "emoticonswidget.h"
23 #include "src/widget/style.h"
24 
25 #include <QFile>
26 #include <QGridLayout>
27 #include <QLayout>
28 #include <QMouseEvent>
29 #include <QPushButton>
30 #include <QRadioButton>
31 
32 #include <math.h>
33 
35  : QMenu(parent)
36 {
37  setStyleSheet(Style::getStylesheet("emoticonWidget/emoticonWidget.css"));
38  setLayout(&layout);
39  layout.addWidget(&stack);
40 
41  QWidget* pageButtonsContainer = new QWidget;
42  QHBoxLayout* buttonLayout = new QHBoxLayout;
43  pageButtonsContainer->setLayout(buttonLayout);
44 
45  layout.addWidget(pageButtonsContainer);
46 
47  const int maxCols = 8;
48  const int maxRows = 8;
49  const int itemsPerPage = maxRows * maxCols;
50 
52  int itemCount = emoticons.size();
53  int pageCount = ceil(float(itemCount) / float(itemsPerPage));
54  int currPage = 0;
55  int currItem = 0;
56  int row = 0;
57  int col = 0;
58 
59  // respect configured emoticon size
61  const QSize size(px, px);
62 
63  // create pages
64  buttonLayout->addStretch();
65  for (int i = 0; i < pageCount; ++i) {
66  QGridLayout* pageLayout = new QGridLayout;
67  pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding),
68  maxRows, 0);
69  pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 0,
70  maxCols);
71 
72  QWidget* page = new QWidget;
73  page->setLayout(pageLayout);
74  stack.addWidget(page);
75 
76  // page buttons are only needed if there is more than 1 page
77  if (pageCount > 1) {
78  QRadioButton* pageButton = new QRadioButton;
79  pageButton->setProperty("pageIndex", i);
80  pageButton->setCursor(Qt::PointingHandCursor);
81  pageButton->setChecked(i == 0);
82  buttonLayout->addWidget(pageButton);
83 
84  connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked);
85  }
86  }
87  buttonLayout->addStretch();
88 
89  SmileyPack& smileyPack = SmileyPack::getInstance();
90  for (const QStringList& set : emoticons) {
91  QPushButton* button = new QPushButton;
92  std::shared_ptr<QIcon> icon = smileyPack.getAsIcon(set[0]);
93  emoticonsIcons.append(icon);
94  button->setIcon(icon->pixmap(size));
95  button->setToolTip(set.join(" "));
96  button->setProperty("sequence", set[0]);
97  button->setCursor(Qt::PointingHandCursor);
98  button->setFlat(true);
99  button->setIconSize(size);
100  button->setFixedSize(size);
101 
102  connect(button, &QPushButton::clicked, this, &EmoticonsWidget::onSmileyClicked);
103 
104  qobject_cast<QGridLayout*>(stack.widget(currPage)->layout())->addWidget(button, row, col);
105 
106  ++col;
107  ++currItem;
108 
109  // next row
110  if (col >= maxCols) {
111  col = 0;
112  ++row;
113  }
114 
115  // next page
116  if (currItem >= itemsPerPage) {
117  row = 0;
118  currItem = 0;
119  ++currPage;
120  }
121  }
122 
123  // calculates sizeHint
124  layout.activate();
125 }
126 
128 {
129  // emit insert emoticon
130  QWidget* sender = qobject_cast<QWidget*>(QObject::sender());
131  if (sender) {
132  QString sequence =
133  sender->property("sequence").toString().replace("&lt;", "<").replace("&gt;", ">");
134  emit insertEmoticon(sequence);
135  }
136 }
137 
139 {
140  QWidget* sender = qobject_cast<QRadioButton*>(QObject::sender());
141  if (sender) {
142  int page = sender->property("pageIndex").toInt();
143  stack.setCurrentIndex(page);
144  }
145 }
146 
148 {
149  return layout.sizeHint();
150 }
151 
153 {
154  if (!rect().contains(ev->pos()))
155  hide();
156 }
157 
159 {
160 }
161 
162 void EmoticonsWidget::wheelEvent(QWheelEvent* e)
163 {
164 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
165  const bool vertical = qAbs(e->angleDelta().y()) >= qAbs(e->angleDelta().x());
166  const int delta = vertical ? e->angleDelta().y() : e->angleDelta().x();
167 
168  if (vertical) {
169  if (delta < 0) {
170 #else
171  if (e->orientation() == Qt::Vertical) {
172  if (e->delta() < 0) {
173 #endif
174  stack.setCurrentIndex(stack.currentIndex() + 1);
175  } else {
176  stack.setCurrentIndex(stack.currentIndex() - 1);
177  }
178  emit PageButtonsUpdate();
179  }
180 }
181 
183 {
184  QList<QRadioButton*> pageButtons = this->findChildren<QRadioButton*>(QString());
185  foreach (QRadioButton* t_pageButton, pageButtons) {
186  if (t_pageButton->property("pageIndex").toInt() == stack.currentIndex())
187  t_pageButton->setChecked(true);
188  else
189  t_pageButton->setChecked(false);
190  }
191 }
192 
194 {
195  Q_UNUSED(e)
196  hide();
197 }
SmileyPack::getAsIcon
std::shared_ptr< QIcon > getAsIcon(const QString &key) const
Gets icon accoring to passed emoticon.
Definition: smileypack.cpp:336
EmoticonsWidget::PageButtonsUpdate
void PageButtonsUpdate()
Definition: emoticonswidget.cpp:182
style.h
EmoticonsWidget::onPageButtonClicked
void onPageButtonClicked()
Definition: emoticonswidget.cpp:138
settings.h
EmoticonsWidget::keyPressEvent
void keyPressEvent(QKeyEvent *e) final
Definition: emoticonswidget.cpp:193
EmoticonsWidget::EmoticonsWidget
EmoticonsWidget(QWidget *parent=nullptr)
Definition: emoticonswidget.cpp:34
Settings::getEmojiFontPointSize
int getEmojiFontPointSize() const
Definition: settings.cpp:1468
EmoticonsWidget::layout
QVBoxLayout layout
Definition: emoticonswidget.h:53
EmoticonsWidget::wheelEvent
void wheelEvent(QWheelEvent *event) final
Definition: emoticonswidget.cpp:162
EmoticonsWidget::sizeHint
QSize sizeHint() const override
Definition: emoticonswidget.cpp:147
QList< QStringList >
SmileyPack::getEmoticons
QList< QStringList > getEmoticons() const
Returns all emoticons that was extracted from files, grouped by according icon file.
Definition: smileypack.cpp:325
EmoticonsWidget::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *ev) final
Definition: emoticonswidget.cpp:152
EmoticonsWidget::stack
QStackedWidget stack
Definition: emoticonswidget.h:52
smileypack.h
EmoticonsWidget::onSmileyClicked
void onSmileyClicked()
Definition: emoticonswidget.cpp:127
SmileyPack::getInstance
static SmileyPack & getInstance()
Returns the singleton instance.
Definition: smileypack.cpp:147
EmoticonsWidget::emoticonsIcons
QList< std::shared_ptr< QIcon > > emoticonsIcons
Definition: emoticonswidget.h:54
Settings::getInstance
static Settings & getInstance()
Returns the singleton instance.
Definition: settings.cpp:88
emoticonswidget.h
Style::getStylesheet
static const QString getStylesheet(const QString &filename, const QFont &baseFont=QFont())
Definition: style.cpp:165
EmoticonsWidget::mousePressEvent
void mousePressEvent(QMouseEvent *ev) final
Definition: emoticonswidget.cpp:158
EmoticonsWidget::insertEmoticon
void insertEmoticon(QString str)
SmileyPack
Maps emoticons to smileys.
Definition: smileypack.h:31