diff --git a/qtox.pro b/qtox.pro
index f1d64f544..707599b6c 100644
--- a/qtox.pro
+++ b/qtox.pro
@@ -84,7 +84,8 @@ HEADERS += widget/form/addfriendform.h \
widget/camera.h \
widget/netcamview.h \
widget/tool/clickablelabel.h \
- smileypack.h
+ smileypack.h \
+ widget/emoticonswidget.h
SOURCES += \
widget/form/addfriendform.cpp \
@@ -117,4 +118,5 @@ SOURCES += \
widget/camera.cpp \
widget/netcamview.cpp \
widget/tool/clickablelabel.cpp \
- smileypack.cpp
+ smileypack.cpp \
+ widget/emoticonswidget.cpp
diff --git a/res.qrc b/res.qrc
index cb2fa192b..67c2ecf50 100644
--- a/res.qrc
+++ b/res.qrc
@@ -111,5 +111,8 @@
ui/statusButton/menu_indicator.png
translations/de.qm
translations/it.qm
+ ui/emoticonWidget/dot_page.png
+ ui/emoticonWidget/dot_page_current.png
+ ui/emoticonWidget/emoticonWidget.css
diff --git a/ui/emoticonWidget/dot_page.png b/ui/emoticonWidget/dot_page.png
new file mode 100644
index 000000000..c7c2aa172
Binary files /dev/null and b/ui/emoticonWidget/dot_page.png differ
diff --git a/ui/emoticonWidget/dot_page_current.png b/ui/emoticonWidget/dot_page_current.png
new file mode 100644
index 000000000..aa101903a
Binary files /dev/null and b/ui/emoticonWidget/dot_page_current.png differ
diff --git a/ui/emoticonWidget/emoticonWidget.css b/ui/emoticonWidget/emoticonWidget.css
new file mode 100644
index 000000000..0cef06ec8
--- /dev/null
+++ b/ui/emoticonWidget/emoticonWidget.css
@@ -0,0 +1,49 @@
+QPushButton
+{
+ background-color: transparent;
+ background-repeat: none;
+ border: none;
+ width: 18px;
+ height: 18px;
+}
+
+QRadioButton::indicator
+{
+ width: 13px;
+ height: 13px;
+}
+
+QRadioButton::indicator::unchecked
+{
+ image: url(:/ui/emoticonWidget/dot_page.png);
+}
+
+QRadioButton::indicator:unchecked:hover
+{
+ image: url(:/ui/emoticonWidget/dot_page.png);
+}
+
+QRadioButton::indicator:unchecked:pressed
+{
+ image: url(:/ui/emoticonWidget/dot_page.png);
+}
+
+QRadioButton::indicator::checked
+{
+ image: url(:/ui/emoticonWidget/dot_page_current.png);
+}
+
+QRadioButton::indicator:checked:hover
+{
+ image: url(:/ui/emoticonWidget/dot_page_current.png);
+}
+
+QRadioButton::indicator:checked:pressed
+{
+ image: url(:/ui/emoticonWidget/dot_page.png);
+}
+
+QMenu
+{
+ background-color: rgb(240,240,240); /* sets background of the menu */
+}
\ No newline at end of file
diff --git a/widget/emoticonswidget.cpp b/widget/emoticonswidget.cpp
new file mode 100644
index 000000000..1b7866b85
--- /dev/null
+++ b/widget/emoticonswidget.cpp
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2014 by Project Tox
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ This program is libre 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 COPYING file for more details.
+*/
+
+#include "emoticonswidget.h"
+#include "smileypack.h"
+
+#include
+#include
+#include
+#include
+#include
+
+EmoticonsWidget::EmoticonsWidget(QWidget *parent) :
+ QMenu(parent)
+{
+ QFile f(":/ui/emoticonWidget/emoticonWidget.css");
+ f.open(QFile::ReadOnly | QFile::Text);
+ QString pageButtonCss = f.readAll();
+ setStyleSheet(pageButtonCss);
+
+ setLayout(&layout);
+ layout.addWidget(&stack);
+
+ QWidget* pageButtonsContainer = new QWidget;
+ QHBoxLayout* buttonLayout = new QHBoxLayout;
+ pageButtonsContainer->setLayout(buttonLayout);
+
+ layout.addWidget(pageButtonsContainer);
+
+ const int maxCols = 5;
+ const int maxRows = 3;
+ const int itemsPerPage = maxRows * maxCols;
+
+ const QList& emoticons = SmileyPack::getInstance().getEmoticons();
+ int itemCount = emoticons.size();
+ int pageCount = (itemCount / itemsPerPage) + 1;
+ int currPage = 0;
+ int currItem = 0;
+ int row = 0;
+ int col = 0;
+
+ // create pages
+ buttonLayout->addStretch();
+ for (int i = 0; i < pageCount; i++)
+ {
+ QGridLayout* pageLayout = new QGridLayout;
+ pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), maxRows, 0);
+ pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, maxCols);
+
+ QWidget* page = new QWidget;
+ page->setLayout(pageLayout);
+ stack.addWidget(page);
+
+ QRadioButton* pageButton = new QRadioButton;
+ pageButton->setProperty("pageIndex", i);
+ pageButton->setChecked(i == 0);
+ buttonLayout->addWidget(pageButton);
+
+ connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked);
+ }
+ buttonLayout->addStretch();
+
+ for (const QStringList& set : emoticons)
+ {
+ QPushButton* button = new QPushButton;
+ button->setIcon(SmileyPack::getInstance().getAsIcon(set[0]));
+ button->setToolTip(set.join(" "));
+ button->setProperty("sequence", set[0]);
+ button->setFlat(true);
+
+ connect(button, &QPushButton::clicked, this, &EmoticonsWidget::onSmileyClicked);
+
+ qobject_cast(stack.widget(currPage)->layout())->addWidget(button, row, col);
+
+ col++;
+ currItem++;
+
+ // next row
+ if (col >= maxCols)
+ {
+ col = 0;
+ row++;
+ }
+
+ // next page
+ if (currItem >= itemsPerPage)
+ {
+ row = 0;
+ currItem = 0;
+ currPage++;
+ }
+ }
+
+ // calculates sizeHint
+ layout.activate();
+}
+
+void EmoticonsWidget::onSmileyClicked()
+{
+ // hide the QMenu
+ QMenu::hide();
+
+ // emit insert emoticon
+ QWidget* sender = qobject_cast(QObject::sender());
+ if (sender)
+ emit insertEmoticon(' ' + sender->property("sequence").toString() + ' ');
+}
+
+void EmoticonsWidget::onPageButtonClicked()
+{
+ QWidget* sender = qobject_cast(QObject::sender());
+ if (sender)
+ {
+ int page = sender->property("pageIndex").toInt();
+ stack.setCurrentIndex(page);
+ }
+}
+
+QSize EmoticonsWidget::sizeHint() const
+{
+ return layout.sizeHint();
+}
diff --git a/widget/emoticonswidget.h b/widget/emoticonswidget.h
new file mode 100644
index 000000000..559fb7443
--- /dev/null
+++ b/widget/emoticonswidget.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2014 by Project Tox
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ This program is libre 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 COPYING file for more details.
+*/
+
+#ifndef EMOTICONSWIDGET_H
+#define EMOTICONSWIDGET_H
+
+#include
+#include
+#include
+
+class EmoticonsWidget : public QMenu
+{
+ Q_OBJECT
+public:
+ explicit EmoticonsWidget(QWidget *parent = 0);
+
+signals:
+ void insertEmoticon(QString str);
+
+private slots:
+ void onSmileyClicked();
+ void onPageButtonClicked();
+
+private:
+ QStackedWidget stack;
+ QVBoxLayout layout;
+
+public:
+ virtual QSize sizeHint() const;
+};
+
+#endif // EMOTICONSWIDGET_H
diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp
index 398579318..0e9e72f9f 100644
--- a/widget/form/chatform.cpp
+++ b/widget/form/chatform.cpp
@@ -20,6 +20,7 @@
#include "widget/friendwidget.h"
#include "widget/widget.h"
#include "widget/filetransfertwidget.h"
+#include "widget/emoticonswidget.h"
#include
#include
#include
@@ -176,10 +177,10 @@ ChatForm::ChatForm(Friend* chatFriend)
sendButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-// callButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-// videoButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-// msgEdit->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-// chatArea->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ // callButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ // videoButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ // msgEdit->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ // chatArea->setAttribute(Qt::WA_LayoutUsesWidgetRect);
connect(Widget::getInstance()->getCore(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
connect(Widget::getInstance()->getCore(), &Core::videoFrameReceived, netcam, &NetCamView::updateDisplay);
@@ -313,7 +314,7 @@ void ChatForm::onSliderRangeChanged()
{
QScrollBar* scroll = chatArea->verticalScrollBar();
if (lockSliderToBottom)
- scroll->setValue(scroll->maximum());
+ scroll->setValue(scroll->maximum());
}
void ChatForm::startFileSend(ToxFile file)
@@ -658,50 +659,23 @@ void ChatForm::onSaveLogClicked()
void ChatForm::onEmoteButtonClicked()
{
- QList emoticons = SmileyPack::getInstance().getEmoticons();
-
- QMenu menu;
- QGridLayout* gridLayout = new QGridLayout;
- menu.setLayout(gridLayout);
-
- int colCount = sqrt(emoticons.size()) + 1;
- int row = 0;
- int col = 0;
- for (const QStringList& set : emoticons)
- {
- QPushButton* button = new QPushButton;
- button->setIcon(SmileyPack::getInstance().getAsIcon(set[0]));
- button->setToolTip(set.join(" "));
- button->setProperty("sequence", set[0]);
- connect(button, &QPushButton::clicked, this, &ChatForm::onAddEmote);
-
- gridLayout->addWidget(button, row, ++col);
- if (col >= colCount)
- {
- col = 0;
- row++;
- }
- }
+ EmoticonsWidget widget;
+ connect(&widget, &EmoticonsWidget::insertEmoticon, this, &ChatForm::onEmoteInsertRequested);
QWidget* sender = qobject_cast(QObject::sender());
if (sender)
{
- QPoint pos(gridLayout->totalSizeHint().width() / 2, gridLayout->totalSizeHint().height());
- menu.exec(sender->mapToGlobal(-pos));
+ QPoint pos(widget.sizeHint().width() / 2, widget.sizeHint().height());
+ widget.exec(sender->mapToGlobal(-pos - QPoint(0, 10)));
}
}
-void ChatForm::onAddEmote()
+void ChatForm::onEmoteInsertRequested(QString str)
{
- // hide the QMenu
- QMenu* menu = qobject_cast(QObject::sender()->parent());
- if (menu)
- menu->hide();
-
// insert the emoticon
QWidget* sender = qobject_cast(QObject::sender());
if (sender)
- msgEdit->insertPlainText(' ' + sender->property("sequence").toString() + ' ');
+ msgEdit->insertPlainText(str);
- msgEdit->setFocus(); // refocus so that you can continue typing
+ msgEdit->setFocus(); // refocus so that we can continue typing
}
diff --git a/widget/form/chatform.h b/widget/form/chatform.h
index a58dc3237..064e05b29 100644
--- a/widget/form/chatform.h
+++ b/widget/form/chatform.h
@@ -84,7 +84,7 @@ private slots:
void onChatContextMenuRequested(QPoint pos);
void onSaveLogClicked();
void onEmoteButtonClicked();
- void onAddEmote();
+ void onEmoteInsertRequested(QString str);
private:
Friend* f;