added namespaces
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#include "widgets/chatwidget.h"
|
||||
#include "channels.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/textinputdialog.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QFontDatabase>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidget::ChatWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, channel(NULL)
|
||||
, channelName(QString())
|
||||
, vbox(this)
|
||||
, header(this)
|
||||
, view(this)
|
||||
, input()
|
||||
{
|
||||
this->vbox.setSpacing(0);
|
||||
this->vbox.setMargin(1);
|
||||
|
||||
this->vbox.addWidget(&header);
|
||||
this->vbox.addWidget(&view);
|
||||
this->vbox.addWidget(&input);
|
||||
}
|
||||
|
||||
ChatWidget::~ChatWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidget::setChannelName(const QString &name)
|
||||
{
|
||||
QString channel = name.trimmed();
|
||||
|
||||
if (QString::compare(channel, this->channelName, Qt::CaseInsensitive) ==
|
||||
0) {
|
||||
this->channelName = channel;
|
||||
this->header.updateChannelText();
|
||||
return;
|
||||
}
|
||||
|
||||
this->channelName = channel;
|
||||
this->header.updateChannelText();
|
||||
|
||||
this->view.layoutMessages();
|
||||
|
||||
if (!this->channelName.isEmpty()) {
|
||||
Channels::removeChannel(this->channelName);
|
||||
}
|
||||
|
||||
if (channel.isEmpty()) {
|
||||
this->channel = NULL;
|
||||
} else {
|
||||
this->channel = Channels::addChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidget::showChangeChannelPopup()
|
||||
{
|
||||
TextInputDialog dialog(this);
|
||||
|
||||
dialog.setText(this->channelName);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
setChannelName(dialog.getText());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidget::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(this->rect(), ColorScheme::instance().ChatBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef CHATWIDGET_H
|
||||
#define CHATWIDGET_H
|
||||
|
||||
#include "channel.h"
|
||||
#include "widgets/chatwidgetheader.h"
|
||||
#include "widgets/chatwidgetinput.h"
|
||||
#include "widgets/chatwidgetview.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidget(QWidget *parent = 0);
|
||||
~ChatWidget();
|
||||
|
||||
ChatWidgetView &
|
||||
getView()
|
||||
{
|
||||
return view;
|
||||
}
|
||||
|
||||
Channel *
|
||||
getChannel() const
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
|
||||
const QString &
|
||||
getChannelName() const
|
||||
{
|
||||
return channelName;
|
||||
}
|
||||
|
||||
void setChannelName(const QString &name);
|
||||
|
||||
void showChangeChannelPopup();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
Channel *channel;
|
||||
QString channelName;
|
||||
|
||||
QFont font;
|
||||
QVBoxLayout vbox;
|
||||
ChatWidgetHeader header;
|
||||
ChatWidgetView view;
|
||||
ChatWidgetInput input;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATWIDGET_H
|
||||
@@ -0,0 +1,216 @@
|
||||
#include "widgets/chatwidgetheader.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/chatwidget.h"
|
||||
#include "widgets/notebookpage.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDrag>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetHeader::ChatWidgetHeader(ChatWidget *parent)
|
||||
: QWidget()
|
||||
, chatWidget(parent)
|
||||
, dragStart()
|
||||
, dragging(false)
|
||||
, leftLabel()
|
||||
, middleLabel()
|
||||
, rightLabel()
|
||||
, leftMenu(this)
|
||||
, rightMenu(this)
|
||||
{
|
||||
setFixedHeight(32);
|
||||
|
||||
updateColors();
|
||||
updateChannelText();
|
||||
|
||||
setLayout(&this->hbox);
|
||||
this->hbox.setMargin(0);
|
||||
this->hbox.addWidget(&this->leftLabel);
|
||||
this->hbox.addWidget(&this->middleLabel, 1);
|
||||
this->hbox.addWidget(&this->rightLabel);
|
||||
|
||||
// left
|
||||
this->leftLabel.getLabel().setTextFormat(Qt::RichText);
|
||||
this->leftLabel.getLabel().setText(
|
||||
"<img src=':/images/tool_moreCollapser_off16.png' />");
|
||||
|
||||
QObject::connect(&this->leftLabel, &ChatWidgetHeaderButton::clicked, this,
|
||||
&ChatWidgetHeader::leftButtonClicked);
|
||||
|
||||
this->leftMenu.addAction("Add new split", this, SLOT(menuAddSplit()),
|
||||
QKeySequence(tr("Ctrl+T")));
|
||||
this->leftMenu.addAction("Close split", this, SLOT(menuCloseSplit()),
|
||||
QKeySequence(tr("Ctrl+W")));
|
||||
this->leftMenu.addAction("Move split", this, SLOT(menuMoveSplit()));
|
||||
this->leftMenu.addSeparator();
|
||||
this->leftMenu.addAction("Change channel", this, SLOT(menuChangeChannel()),
|
||||
QKeySequence(tr("Ctrl+R")));
|
||||
this->leftMenu.addAction("Clear chat", this, SLOT(menuClearChat()));
|
||||
this->leftMenu.addAction("Open channel", this, SLOT(menuOpenChannel()));
|
||||
this->leftMenu.addAction("Open pop-out player", this,
|
||||
SLOT(menuPopupPlayer()));
|
||||
this->leftMenu.addSeparator();
|
||||
this->leftMenu.addAction("Reload channel emotes", this,
|
||||
SLOT(menuReloadChannelEmotes()));
|
||||
this->leftMenu.addAction("Manual reconnect", this,
|
||||
SLOT(menuManualReconnect()));
|
||||
this->leftMenu.addSeparator();
|
||||
this->leftMenu.addAction("Show changelog", this, SLOT(menuShowChangelog()));
|
||||
|
||||
// middle
|
||||
this->middleLabel.setAlignment(Qt::AlignCenter);
|
||||
/*QObject::connect(&this->middleLabel,
|
||||
* SIGNAL(mouseDoubleClickEvent(QMouseEvent)), this,
|
||||
* SLOT(mouseDoubleClickEvent));
|
||||
* mouseDoubleClickEvent is not a signal, its an event handler
|
||||
*/
|
||||
connect(&this->middleLabel, &SignalLabel::mouseDoubleClick, this,
|
||||
&ChatWidgetHeader::mouseDoubleClickEvent);
|
||||
|
||||
// right
|
||||
this->rightLabel.setMinimumWidth(height());
|
||||
this->rightLabel.getLabel().setTextFormat(Qt::RichText);
|
||||
this->rightLabel.getLabel().setText("ayy");
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::updateColors()
|
||||
{
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Foreground, ColorScheme::instance().Text);
|
||||
|
||||
this->leftLabel.setPalette(palette);
|
||||
this->middleLabel.setPalette(palette);
|
||||
this->rightLabel.setPalette(palette);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::updateChannelText()
|
||||
{
|
||||
const QString &c = this->chatWidget->getChannelName();
|
||||
|
||||
this->middleLabel.setText(c.isEmpty() ? "<no channel>" : c);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(rect(), ColorScheme::instance().ChatHeaderBackground);
|
||||
painter.setPen(ColorScheme::instance().ChatHeaderBorder);
|
||||
painter.drawRect(0, 0, width() - 1, height() - 1);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
this->dragging = true;
|
||||
|
||||
this->dragStart = event->pos();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (this->dragging) {
|
||||
if (std::abs(this->dragStart.x() - event->pos().x()) > 12 ||
|
||||
std::abs(this->dragStart.y() - event->pos().y()) > 12) {
|
||||
auto chatWidget = this->chatWidget;
|
||||
auto page = static_cast<NotebookPage *>(chatWidget->parentWidget());
|
||||
|
||||
if (page != NULL) {
|
||||
NotebookPage::isDraggingSplit = true;
|
||||
NotebookPage::draggingSplit = chatWidget;
|
||||
|
||||
auto originalLocation = page->removeFromLayout(chatWidget);
|
||||
|
||||
// page->repaint();
|
||||
|
||||
QDrag *drag = new QDrag(chatWidget);
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
mimeData->setData("chatterino/split", "xD");
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
|
||||
|
||||
if (dropAction == Qt::IgnoreAction) {
|
||||
page->addToLayout(chatWidget, originalLocation);
|
||||
}
|
||||
|
||||
NotebookPage::isDraggingSplit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
this->chatWidget->showChangeChannelPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::leftButtonClicked()
|
||||
{
|
||||
this->leftMenu.move(
|
||||
this->leftLabel.mapToGlobal(QPoint(0, this->leftLabel.height())));
|
||||
this->leftMenu.show();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::rightButtonClicked()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeader::menuAddSplit()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuCloseSplit()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuMoveSplit()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuChangeChannel()
|
||||
{
|
||||
this->chatWidget->showChangeChannelPopup();
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuClearChat()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuOpenChannel()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuPopupPlayer()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuReloadChannelEmotes()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuManualReconnect()
|
||||
{
|
||||
}
|
||||
void
|
||||
ChatWidgetHeader::menuShowChangelog()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef CHATWIDGETHEADER_H
|
||||
#define CHATWIDGETHEADER_H
|
||||
|
||||
#include "signallabel.h"
|
||||
#include "widgets/chatwidgetheaderbutton.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QPoint>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetHeader : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChatWidgetHeader(ChatWidget *parent);
|
||||
|
||||
ChatWidget *
|
||||
getChatWidget()
|
||||
{
|
||||
return chatWidget;
|
||||
}
|
||||
|
||||
void updateColors();
|
||||
void updateChannelText();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
ChatWidget *chatWidget;
|
||||
|
||||
QPoint dragStart;
|
||||
bool dragging;
|
||||
|
||||
QHBoxLayout hbox;
|
||||
|
||||
ChatWidgetHeaderButton leftLabel;
|
||||
SignalLabel middleLabel;
|
||||
ChatWidgetHeaderButton rightLabel;
|
||||
|
||||
QMenu leftMenu;
|
||||
QMenu rightMenu;
|
||||
|
||||
void leftButtonClicked();
|
||||
void rightButtonClicked();
|
||||
|
||||
private slots:
|
||||
void menuAddSplit();
|
||||
void menuCloseSplit();
|
||||
void menuMoveSplit();
|
||||
void menuChangeChannel();
|
||||
void menuClearChat();
|
||||
void menuOpenChannel();
|
||||
void menuPopupPlayer();
|
||||
void menuReloadChannelEmotes();
|
||||
void menuManualReconnect();
|
||||
void menuShowChangelog();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATWIDGETHEADER_H
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "widgets/chatwidgetheaderbutton.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetHeaderButton::ChatWidgetHeaderButton()
|
||||
: QWidget()
|
||||
, hbox()
|
||||
, label()
|
||||
, mouseOver(false)
|
||||
, mouseDown(false)
|
||||
{
|
||||
setLayout(&hbox);
|
||||
|
||||
hbox.setMargin(0);
|
||||
hbox.addSpacing(6);
|
||||
hbox.addWidget(&this->label);
|
||||
hbox.addSpacing(6);
|
||||
|
||||
QObject::connect(&this->label, &ChatWidgetHeaderButtonLabel::mouseUp, this,
|
||||
&ChatWidgetHeaderButton::labelMouseUp);
|
||||
QObject::connect(&this->label, &ChatWidgetHeaderButtonLabel::mouseDown,
|
||||
this, &ChatWidgetHeaderButton::labelMouseDown);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QBrush brush(ColorScheme::instance().IsLightTheme
|
||||
? QColor(0, 0, 0, 32)
|
||||
: QColor(255, 255, 255, 32));
|
||||
|
||||
if (this->mouseDown) {
|
||||
painter.fillRect(rect(), brush);
|
||||
}
|
||||
|
||||
if (this->mouseOver) {
|
||||
painter.fillRect(rect(), brush);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
this->mouseDown = true;
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
this->mouseDown = false;
|
||||
|
||||
repaint();
|
||||
|
||||
emit clicked();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::enterEvent(QEvent *)
|
||||
{
|
||||
this->mouseOver = true;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::leaveEvent(QEvent *)
|
||||
{
|
||||
this->mouseOver = false;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::labelMouseUp()
|
||||
{
|
||||
this->mouseDown = false;
|
||||
|
||||
repaint();
|
||||
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButton::labelMouseDown()
|
||||
{
|
||||
this->mouseDown = true;
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef CHATWIDGETHEADERBUTTON_H
|
||||
#define CHATWIDGETHEADERBUTTON_H
|
||||
|
||||
#include "widgets/chatwidgetheaderbuttonlabel.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidgetHeaderButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidgetHeaderButton();
|
||||
|
||||
ChatWidgetHeaderButtonLabel &
|
||||
getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
void enterEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QHBoxLayout hbox;
|
||||
ChatWidgetHeaderButtonLabel label;
|
||||
|
||||
bool mouseOver;
|
||||
bool mouseDown;
|
||||
|
||||
void labelMouseUp();
|
||||
void labelMouseDown();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATWIDGETHEADERBUTTON_H
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "widgets/chatwidgetheaderbuttonlabel.h"
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetHeaderButtonLabel::ChatWidgetHeaderButtonLabel()
|
||||
{
|
||||
setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButtonLabel::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit mouseDown();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetHeaderButtonLabel::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit mouseUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef CHATWIDGETHEADERBUTTONLABEL_H
|
||||
#define CHATWIDGETHEADERBUTTONLABEL_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidgetHeaderButtonLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidgetHeaderButtonLabel();
|
||||
|
||||
signals:
|
||||
void mouseDown();
|
||||
void mouseUp();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATWIDGETHEADERBUTTONLABEL_H
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "widgets/chatwidgetinput.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetInput::ChatWidgetInput()
|
||||
{
|
||||
setFixedHeight(38);
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetInput::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(rect(), ColorScheme::instance().ChatInputBackground);
|
||||
painter.setPen(ColorScheme::instance().ChatInputBorder);
|
||||
painter.drawRect(0, 0, width() - 1, height() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef CHATWIDGETINPUT_H
|
||||
#define CHATWIDGETINPUT_H
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidgetInput : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidgetInput();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATWIDGETINPUT_H
|
||||
@@ -0,0 +1,153 @@
|
||||
#include "widgets/chatwidgetview.h"
|
||||
#include "channels.h"
|
||||
#include "colorscheme.h"
|
||||
#include "messages/message.h"
|
||||
#include "messages/word.h"
|
||||
#include "messages/wordpart.h"
|
||||
#include "widgets/chatwidget.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <QPainter>
|
||||
#include <QScroller>
|
||||
#include <functional>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetView::ChatWidgetView(ChatWidget *parent)
|
||||
: QWidget()
|
||||
, chatWidget(parent)
|
||||
, scrollbar(this)
|
||||
{
|
||||
auto scroll = QScroller::scroller(this);
|
||||
|
||||
scroll->scrollTo(QPointF(0, 100));
|
||||
}
|
||||
|
||||
bool
|
||||
ChatWidgetView::layoutMessages()
|
||||
{
|
||||
auto c = this->chatWidget->getChannel();
|
||||
|
||||
if (c == NULL)
|
||||
return false;
|
||||
|
||||
auto messages = c->getMessagesClone();
|
||||
|
||||
bool redraw = false;
|
||||
|
||||
for (std::shared_ptr<Message> &message : messages) {
|
||||
redraw |= message.get()->layout(this->width(), true);
|
||||
}
|
||||
|
||||
return redraw;
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetView::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
this->scrollbar.resize(this->scrollbar.width(), height());
|
||||
this->scrollbar.move(width() - this->scrollbar.width(), 0);
|
||||
|
||||
layoutMessages();
|
||||
}
|
||||
|
||||
void
|
||||
ChatWidgetView::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
auto c = this->chatWidget->getChannel();
|
||||
|
||||
QColor color;
|
||||
|
||||
ColorScheme &scheme = ColorScheme::instance();
|
||||
|
||||
// code for tesing colors
|
||||
/*
|
||||
static ConcurrentMap<qreal, QImage *> imgCache;
|
||||
|
||||
std::function<QImage *(qreal)> getImg = [&scheme](qreal light) {
|
||||
return imgCache.getOrAdd(light, [&scheme, &light] {
|
||||
QImage *img = new QImage(150, 50, QImage::Format_RGB32);
|
||||
|
||||
QColor color;
|
||||
|
||||
for (int j = 0; j < 50; j++) {
|
||||
for (qreal i = 0; i < 150; i++) {
|
||||
color = QColor::fromHslF(i / 150.0, light, j / 50.0);
|
||||
|
||||
scheme.normalizeColor(color);
|
||||
|
||||
img->setPixelColor(i, j, color);
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
});
|
||||
};
|
||||
|
||||
for (qreal k = 0; k < 4.8; k++) {
|
||||
auto img = getImg(k / 5);
|
||||
|
||||
painter.drawImage(QRect(k * 150, 0, 150, 150), *img);
|
||||
}
|
||||
|
||||
painter.fillRect(QRect(0, 9, 500, 2), QColor(0, 0, 0));*/
|
||||
|
||||
if (c == NULL)
|
||||
return;
|
||||
|
||||
auto messages = c->getMessagesClone();
|
||||
|
||||
int start = this->scrollbar.getValue();
|
||||
|
||||
if (start >= messages.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int y = -(messages[start].get()->getHeight() *
|
||||
(fmod(this->scrollbar.getValue(), 1)));
|
||||
|
||||
for (int i = start; i < messages.size(); ++i) {
|
||||
Message *message = messages[i].get();
|
||||
|
||||
for (WordPart const &wordPart : message->getWordParts()) {
|
||||
painter.setPen(QColor(255, 0, 0));
|
||||
painter.drawRect(wordPart.getX(), wordPart.getY() + y,
|
||||
wordPart.getWidth(), wordPart.getHeight());
|
||||
|
||||
// image
|
||||
if (wordPart.getWord().isImage()) {
|
||||
LazyLoadedImage &lli = wordPart.getWord().getImage();
|
||||
|
||||
const QPixmap *image = lli.getPixmap();
|
||||
|
||||
if (image != NULL) {
|
||||
painter.drawPixmap(
|
||||
QRect(wordPart.getX(), wordPart.getY() + y,
|
||||
wordPart.getWidth(), wordPart.getHeight()),
|
||||
*image);
|
||||
}
|
||||
}
|
||||
// text
|
||||
else {
|
||||
QColor color = wordPart.getWord().getColor();
|
||||
|
||||
painter.setPen(color);
|
||||
painter.setFont(wordPart.getWord().getFont());
|
||||
|
||||
painter.drawText(
|
||||
QRectF(wordPart.getX(), wordPart.getY() + y, 10000, 10000),
|
||||
wordPart.getText(),
|
||||
QTextOption(Qt::AlignLeft | Qt::AlignTop));
|
||||
}
|
||||
}
|
||||
|
||||
y += message->getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef CHATVIEW_H
|
||||
#define CHATVIEW_H
|
||||
|
||||
#include "channel.h"
|
||||
#include "widgets/scrollbar.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChatWidgetView(ChatWidget *parent);
|
||||
|
||||
bool layoutMessages();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
private:
|
||||
ChatWidget *chatWidget;
|
||||
|
||||
ScrollBar scrollbar;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CHATVIEW_H
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "widgets/mainwindow.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/chatwidget.h"
|
||||
#include "widgets/notebook.h"
|
||||
|
||||
#include <QPalette>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, notebook(this)
|
||||
{
|
||||
setCentralWidget(&this->notebook);
|
||||
|
||||
this->notebook.addPage();
|
||||
this->notebook.addPage();
|
||||
this->notebook.addPage();
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Background,
|
||||
ColorScheme::instance().TabPanelBackground);
|
||||
setPalette(palette);
|
||||
|
||||
resize(1280, 800);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::layoutVisibleChatWidgets(Channel *channel)
|
||||
{
|
||||
auto *page = notebook.getSelectedPage();
|
||||
|
||||
if (page == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<ChatWidget *> &widgets = page->getChatWidgets();
|
||||
|
||||
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
|
||||
ChatWidget *widget = *it;
|
||||
|
||||
if (channel == NULL || channel == widget->getChannel()) {
|
||||
if (widget->getView().layoutMessages()) {
|
||||
widget->repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::repaintVisibleChatWidgets(Channel *channel)
|
||||
{
|
||||
auto *page = notebook.getSelectedPage();
|
||||
|
||||
if (page == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<ChatWidget *> &widgets = page->getChatWidgets();
|
||||
|
||||
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
|
||||
ChatWidget *widget = *it;
|
||||
|
||||
if (channel == NULL || channel == widget->getChannel()) {
|
||||
widget->getView().layoutMessages();
|
||||
widget->repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "widgets/notebook.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
Notebook notebook;
|
||||
|
||||
void layoutVisibleChatWidgets(Channel *channel = NULL);
|
||||
void repaintVisibleChatWidgets(Channel *channel = NULL);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
@@ -0,0 +1,115 @@
|
||||
#include "widgets/notebook.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/notebookbutton.h"
|
||||
#include "widgets/notebookpage.h"
|
||||
#include "widgets/notebooktab.h"
|
||||
#include "widgets/settingsdialog.h"
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QLayout>
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
Notebook::Notebook(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, addButton(this)
|
||||
, settingsButton(this)
|
||||
, userButton(this)
|
||||
{
|
||||
connect(&this->settingsButton, SIGNAL(clicked()), this,
|
||||
SLOT(settingsButtonClicked()));
|
||||
|
||||
this->settingsButton.resize(24, 24);
|
||||
this->settingsButton.icon = NotebookButton::IconSettings;
|
||||
this->userButton.resize(24, 24);
|
||||
this->userButton.move(24, 0);
|
||||
this->userButton.icon = NotebookButton::IconUser;
|
||||
this->addButton.resize(24, 24);
|
||||
}
|
||||
|
||||
void
|
||||
Notebook::settingsButtonClicked()
|
||||
{
|
||||
SettingsDialog *a = new SettingsDialog();
|
||||
|
||||
a->show();
|
||||
}
|
||||
|
||||
NotebookPage *
|
||||
Notebook::addPage()
|
||||
{
|
||||
auto tab = new NotebookTab(this);
|
||||
auto page = new NotebookPage(this, tab);
|
||||
|
||||
if (this->pages.count() == 0) {
|
||||
select(page);
|
||||
}
|
||||
|
||||
this->pages.append(page);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void
|
||||
Notebook::select(NotebookPage *page)
|
||||
{
|
||||
if (page == this->selectedPage)
|
||||
return;
|
||||
|
||||
if (page != nullptr) {
|
||||
page->setHidden(false);
|
||||
page->tab->setSelected(true);
|
||||
}
|
||||
|
||||
if (this->selectedPage != nullptr) {
|
||||
this->selectedPage->setHidden(true);
|
||||
this->selectedPage->tab->setSelected(false);
|
||||
}
|
||||
|
||||
this->selectedPage = page;
|
||||
|
||||
performLayout();
|
||||
}
|
||||
|
||||
void
|
||||
Notebook::performLayout()
|
||||
{
|
||||
int x = 48, y = 0;
|
||||
int tabHeight = 16;
|
||||
bool first = true;
|
||||
|
||||
for (auto &i : this->pages) {
|
||||
tabHeight = i->tab->height();
|
||||
|
||||
if (!first &&
|
||||
(i == this->pages.last() ? tabHeight : 0) + x + i->tab->width() >
|
||||
width()) {
|
||||
y += i->tab->height();
|
||||
i->tab->move(0, y);
|
||||
x = i->tab->width();
|
||||
} else {
|
||||
i->tab->move(x, y);
|
||||
x += i->tab->width();
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
this->addButton.move(x, y);
|
||||
|
||||
if (this->selectedPage != nullptr) {
|
||||
this->selectedPage->move(0, y + tabHeight);
|
||||
this->selectedPage->resize(width(), height() - y - tabHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Notebook::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
performLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef NOTEBOOK_H
|
||||
#define NOTEBOOK_H
|
||||
|
||||
#include "widgets/notebookbutton.h"
|
||||
#include "widgets/notebookpage.h"
|
||||
#include "widgets/notebooktab.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class Notebook : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Notebook(QWidget *parent);
|
||||
|
||||
NotebookPage *addPage();
|
||||
|
||||
enum HighlightType { none, highlighted, newMessage };
|
||||
|
||||
void select(NotebookPage *page);
|
||||
|
||||
NotebookPage *
|
||||
getSelectedPage()
|
||||
{
|
||||
return selectedPage;
|
||||
}
|
||||
|
||||
void performLayout();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
void settingsButtonMouseReleased(QMouseEvent *event);
|
||||
|
||||
public slots:
|
||||
void settingsButtonClicked();
|
||||
|
||||
private:
|
||||
QList<NotebookPage *> pages;
|
||||
|
||||
NotebookButton addButton;
|
||||
NotebookButton settingsButton;
|
||||
NotebookButton userButton;
|
||||
|
||||
NotebookPage *selectedPage = nullptr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NOTEBOOK_H
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "widgets/notebookbutton.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
NotebookButton::NotebookButton(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NotebookButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QColor background;
|
||||
QColor foreground;
|
||||
|
||||
auto colorScheme = ColorScheme::instance();
|
||||
|
||||
if (mouseDown) {
|
||||
background = colorScheme.TabSelectedBackground;
|
||||
foreground = colorScheme.TabSelectedText;
|
||||
} else if (mouseOver) {
|
||||
background = colorScheme.TabHoverBackground;
|
||||
foreground = colorScheme.TabSelectedBackground;
|
||||
} else {
|
||||
background = colorScheme.TabPanelBackground;
|
||||
foreground = colorScheme.TabSelectedBackground;
|
||||
}
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.fillRect(this->rect(), background);
|
||||
|
||||
float h = this->height(), w = this->width();
|
||||
|
||||
if (icon == IconPlus) {
|
||||
painter.fillRect(QRectF((h / 12) * 2 + 1, (h / 12) * 5 + 1,
|
||||
w - ((h / 12) * 5), (h / 12) * 1),
|
||||
foreground);
|
||||
painter.fillRect(QRectF((h / 12) * 5 + 1, (h / 12) * 2 + 1,
|
||||
(h / 12) * 1, w - ((h / 12) * 5)),
|
||||
foreground);
|
||||
} else if (icon == IconUser) {
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
||||
auto a = w / 8;
|
||||
QPainterPath path;
|
||||
|
||||
path.arcMoveTo(a, 4 * a, 6 * a, 6 * a, 0);
|
||||
path.arcTo(a, 4 * a, 6 * a, 6 * a, 0, 180);
|
||||
|
||||
painter.fillPath(path, foreground);
|
||||
|
||||
painter.setBrush(background);
|
||||
painter.drawEllipse(2 * a, 1 * a, 4 * a, 4 * a);
|
||||
|
||||
painter.setBrush(foreground);
|
||||
painter.drawEllipse(2.5 * a, 1.5 * a, 3 * a + 1, 3 * a);
|
||||
} else // IconSettings
|
||||
{
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
||||
auto a = w / 8;
|
||||
QPainterPath path;
|
||||
|
||||
path.arcMoveTo(a, a, 6 * a, 6 * a, 0 - (360 / 32.0));
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
path.arcTo(a, a, 6 * a, 6 * a, i * (360 / 8.0) - (360 / 32.0),
|
||||
(360 / 32.0));
|
||||
path.arcTo(2 * a, 2 * a, 4 * a, 4 * a,
|
||||
i * (360 / 8.0) + (360 / 32.0), (360 / 32.0));
|
||||
}
|
||||
|
||||
painter.fillPath(path, foreground);
|
||||
|
||||
painter.setBrush(background);
|
||||
painter.drawEllipse(3 * a, 3 * a, 2 * a, 2 * a);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookButton::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
mouseDown = true;
|
||||
|
||||
this->repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
mouseDown = false;
|
||||
|
||||
this->repaint();
|
||||
|
||||
emit clicked();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookButton::enterEvent(QEvent *)
|
||||
{
|
||||
mouseOver = true;
|
||||
|
||||
this->repaint();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookButton::leaveEvent(QEvent *)
|
||||
{
|
||||
mouseOver = false;
|
||||
|
||||
this->repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef NOTEBOOKBUTTON_H
|
||||
#define NOTEBOOKBUTTON_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class NotebookButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const int IconPlus = 0;
|
||||
static const int IconUser = 1;
|
||||
static const int IconSettings = 2;
|
||||
|
||||
int icon = 0;
|
||||
|
||||
NotebookButton(QWidget *parent);
|
||||
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void enterEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
bool mouseOver = false;
|
||||
bool mouseDown = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NOTEBOOKBUTTON_H
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "widgets/notebookpage.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/chatwidget.h"
|
||||
#include "widgets/notebooktab.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
bool NotebookPage::isDraggingSplit = false;
|
||||
ChatWidget *NotebookPage::draggingSplit = NULL;
|
||||
std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
|
||||
|
||||
NotebookPage::NotebookPage(QWidget *parent, NotebookTab *tab)
|
||||
: QWidget(parent)
|
||||
, parentbox(this)
|
||||
, chatWidgets()
|
||||
, preview(this)
|
||||
{
|
||||
this->tab = tab;
|
||||
tab->page = this;
|
||||
|
||||
setHidden(true);
|
||||
setAcceptDrops(true);
|
||||
|
||||
this->parentbox.addSpacing(2);
|
||||
this->parentbox.addLayout(&this->hbox);
|
||||
this->parentbox.setMargin(0);
|
||||
|
||||
this->hbox.setSpacing(1);
|
||||
this->hbox.setMargin(0);
|
||||
}
|
||||
|
||||
std::pair<int, int>
|
||||
NotebookPage::removeFromLayout(ChatWidget *widget)
|
||||
{
|
||||
for (auto it = this->chatWidgets.begin(); it != this->chatWidgets.end();
|
||||
++it) {
|
||||
if (*it == widget) {
|
||||
this->chatWidgets.erase(it);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->hbox.count(); ++i) {
|
||||
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(i));
|
||||
|
||||
for (int j = 0; j < vbox->count(); ++j) {
|
||||
if (vbox->itemAt(j)->widget() != widget)
|
||||
continue;
|
||||
|
||||
widget->setParent(NULL);
|
||||
|
||||
bool isLastItem = vbox->count() == 0;
|
||||
|
||||
if (isLastItem) {
|
||||
this->hbox.removeItem(vbox);
|
||||
|
||||
delete vbox;
|
||||
}
|
||||
|
||||
return std::pair<int, int>(i, isLastItem ? -1 : j);
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<int, int>(-1, -1);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::addToLayout(
|
||||
ChatWidget *widget,
|
||||
std::pair<int, int> position = std::pair<int, int>(-1, -1))
|
||||
{
|
||||
this->chatWidgets.push_back(widget);
|
||||
|
||||
// add vbox at the end
|
||||
if (position.first < 0 || position.first >= this->hbox.count()) {
|
||||
auto vbox = new QVBoxLayout();
|
||||
vbox->addWidget(widget);
|
||||
|
||||
this->hbox.addLayout(vbox);
|
||||
return;
|
||||
}
|
||||
|
||||
// insert vbox
|
||||
if (position.second == -1) {
|
||||
auto vbox = new QVBoxLayout();
|
||||
vbox->addWidget(widget);
|
||||
|
||||
this->hbox.insertLayout(position.first, vbox);
|
||||
return;
|
||||
}
|
||||
|
||||
// add to existing vbox
|
||||
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(position.first));
|
||||
|
||||
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)),
|
||||
widget);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::enterEvent(QEvent *)
|
||||
{
|
||||
if (this->hbox.count() == 0) {
|
||||
setCursor(QCursor(Qt::PointingHandCursor));
|
||||
} else {
|
||||
setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::leaveEvent(QEvent *)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (this->hbox.count() == 0 && event->button() == Qt::LeftButton) {
|
||||
addToLayout(new ChatWidget(), std::pair<int, int>(-1, -1));
|
||||
|
||||
setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (!event->mimeData()->hasFormat("chatterino/split"))
|
||||
return;
|
||||
|
||||
if (isDraggingSplit) {
|
||||
this->dropRegions.clear();
|
||||
|
||||
if (this->hbox.count() == 0) {
|
||||
this->dropRegions.push_back(
|
||||
DropRegion(rect(), std::pair<int, int>(-1, -1)));
|
||||
} else {
|
||||
for (int i = 0; i < this->hbox.count() + 1; ++i) {
|
||||
this->dropRegions.push_back(DropRegion(
|
||||
QRect(((i * 4 - 1) * width() / this->hbox.count()) / 4, 0,
|
||||
width() / this->hbox.count() / 2, height()),
|
||||
std::pair<int, int>(i, -1)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->hbox.count(); ++i) {
|
||||
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(i));
|
||||
|
||||
for (int j = 0; j < vbox->count() + 1; ++j) {
|
||||
this->dropRegions.push_back(DropRegion(
|
||||
QRect(i * width() / this->hbox.count(),
|
||||
((j * 2 - 1) * height() / vbox->count()) / 2,
|
||||
width() / this->hbox.count(),
|
||||
height() / vbox->count()),
|
||||
std::pair<int, int>(i, j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setPreviewRect(event->pos());
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
setPreviewRect(event->pos());
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::setPreviewRect(QPoint mousePos)
|
||||
{
|
||||
for (DropRegion region : this->dropRegions) {
|
||||
if (region.rect.contains(mousePos)) {
|
||||
this->preview.setBounds(region.rect);
|
||||
// this->preview.move(region.rect.x(), region.rect.y());
|
||||
// this->preview.resize(region.rect.width(),
|
||||
// region.rect.height());
|
||||
this->preview.show();
|
||||
this->preview.raise();
|
||||
|
||||
dropPosition = region.position;
|
||||
|
||||
return;
|
||||
} else {
|
||||
this->preview.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
this->preview.hide();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (isDraggingSplit) {
|
||||
event->acceptProposedAction();
|
||||
|
||||
NotebookPage::draggingSplit->setParent(this);
|
||||
|
||||
addToLayout(NotebookPage::draggingSplit, dropPosition);
|
||||
}
|
||||
|
||||
this->preview.hide();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPage::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
if (this->hbox.count() == 0) {
|
||||
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
|
||||
|
||||
painter.fillRect(0, 0, width(), 2,
|
||||
ColorScheme::instance().TabSelectedBackground);
|
||||
|
||||
painter.setPen(ColorScheme::instance().Text);
|
||||
painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter));
|
||||
} else {
|
||||
painter.fillRect(rect(), ColorScheme::instance().TabSelectedBackground);
|
||||
|
||||
painter.fillRect(0, 0, width(), 2,
|
||||
ColorScheme::instance().TabSelectedBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef NOTEBOOKPAGE_H
|
||||
#define NOTEBOOKPAGE_H
|
||||
|
||||
#include "widgets/chatwidget.h"
|
||||
#include "widgets/notebookpage.h"
|
||||
#include "widgets/notebookpagedroppreview.h"
|
||||
#include "widgets/notebooktab.h"
|
||||
|
||||
#include <QDragEnterEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QRect>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVector>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class NotebookPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotebookPage(QWidget *parent, NotebookTab *tab);
|
||||
NotebookTab *tab;
|
||||
|
||||
std::pair<int, int> removeFromLayout(ChatWidget *widget);
|
||||
void addToLayout(ChatWidget *widget, std::pair<int, int> position);
|
||||
|
||||
const std::vector<ChatWidget *> &
|
||||
getChatWidgets() const
|
||||
{
|
||||
return chatWidgets;
|
||||
}
|
||||
|
||||
static bool isDraggingSplit;
|
||||
static ChatWidget *draggingSplit;
|
||||
static std::pair<int, int> dropPosition;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
void enterEvent(QEvent *) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
|
||||
void dragMoveEvent(QDragMoveEvent *event) Q_DECL_OVERRIDE;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
|
||||
void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
struct DropRegion {
|
||||
QRect rect;
|
||||
std::pair<int, int> position;
|
||||
|
||||
DropRegion(QRect rect, std::pair<int, int> position)
|
||||
{
|
||||
this->rect = rect;
|
||||
this->position = position;
|
||||
}
|
||||
};
|
||||
|
||||
QVBoxLayout parentbox;
|
||||
QHBoxLayout hbox;
|
||||
|
||||
std::vector<ChatWidget *> chatWidgets;
|
||||
std::vector<DropRegion> dropRegions;
|
||||
|
||||
NotebookPageDropPreview preview;
|
||||
|
||||
private:
|
||||
void setPreviewRect(QPoint mousePos);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NOTEBOOKPAGE_H
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "widgets/notebookpagedroppreview.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
NotebookPageDropPreview::NotebookPageDropPreview(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, positionAnimation(this, "geometry")
|
||||
, desiredGeometry()
|
||||
{
|
||||
setHidden(true);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPageDropPreview::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(8, 8, width() - 17, height() - 17,
|
||||
ColorScheme::instance().DropPreviewBackground);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookPageDropPreview::setBounds(const QRect &rect)
|
||||
{
|
||||
if (rect == this->desiredGeometry) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->positionAnimation.stop();
|
||||
this->positionAnimation.setDuration(50);
|
||||
this->positionAnimation.setStartValue(geometry());
|
||||
this->positionAnimation.setEndValue(rect);
|
||||
this->positionAnimation.start();
|
||||
|
||||
this->desiredGeometry = rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef NOTEBOOKPAGEDROPPREVIEW_H
|
||||
#define NOTEBOOKPAGEDROPPREVIEW_H
|
||||
|
||||
#include <QPropertyAnimation>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class NotebookPageDropPreview : public QWidget
|
||||
{
|
||||
public:
|
||||
NotebookPageDropPreview(QWidget *parent);
|
||||
|
||||
void setBounds(const QRect &rect);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
QPropertyAnimation positionAnimation;
|
||||
QRect desiredGeometry;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NOTEBOOKPAGEDROPPREVIEW_H
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "widgets/notebooktab.h"
|
||||
#include "colorscheme.h"
|
||||
#include "widgets/notebook.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
NotebookTab::NotebookTab(Notebook *notebook)
|
||||
: QWidget(notebook)
|
||||
, notebook(notebook)
|
||||
, text("<no title>")
|
||||
, selected(false)
|
||||
, mouseOver(false)
|
||||
, mouseDown(false)
|
||||
, highlightStyle(HighlightNone)
|
||||
{
|
||||
calcSize();
|
||||
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::calcSize()
|
||||
{
|
||||
resize(fontMetrics().width(this->text) + 8, 24);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QColor fg = QColor(0, 0, 0);
|
||||
|
||||
auto colorScheme = ColorScheme::instance();
|
||||
|
||||
if (this->selected) {
|
||||
painter.fillRect(rect(), colorScheme.TabSelectedBackground);
|
||||
fg = colorScheme.TabSelectedText;
|
||||
} else if (this->mouseOver) {
|
||||
painter.fillRect(rect(), colorScheme.TabHoverBackground);
|
||||
fg = colorScheme.TabHoverText;
|
||||
} else if (this->highlightStyle == HighlightHighlighted) {
|
||||
painter.fillRect(rect(), colorScheme.TabHighlightedBackground);
|
||||
fg = colorScheme.TabHighlightedText;
|
||||
} else if (this->highlightStyle == HighlightNewMessage) {
|
||||
painter.fillRect(rect(), colorScheme.TabNewMessageBackground);
|
||||
fg = colorScheme.TabHighlightedText;
|
||||
} else {
|
||||
painter.fillRect(rect(), colorScheme.TabBackground);
|
||||
fg = colorScheme.TabText;
|
||||
}
|
||||
|
||||
painter.setPen(fg);
|
||||
painter.drawText(4, (height() + fontMetrics().height()) / 2, this->text);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
this->mouseDown = true;
|
||||
|
||||
repaint();
|
||||
|
||||
this->notebook->select(page);
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
this->mouseDown = false;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::enterEvent(QEvent *)
|
||||
{
|
||||
this->mouseOver = true;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::leaveEvent(QEvent *)
|
||||
{
|
||||
this->mouseOver = false;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void
|
||||
NotebookTab::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
this->notebook->select(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef NOTEBOOKTAB_H
|
||||
#define NOTEBOOKTAB_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class Notebook;
|
||||
class NotebookPage;
|
||||
|
||||
class NotebookTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum HighlightStyle {
|
||||
HighlightNone,
|
||||
HighlightHighlighted,
|
||||
HighlightNewMessage
|
||||
};
|
||||
|
||||
NotebookTab(Notebook *notebook);
|
||||
|
||||
void calcSize();
|
||||
|
||||
NotebookPage *page;
|
||||
|
||||
const QString &
|
||||
getText() const
|
||||
{
|
||||
return this->text;
|
||||
}
|
||||
|
||||
void
|
||||
setText(const QString &text)
|
||||
{
|
||||
this->text = text;
|
||||
}
|
||||
|
||||
bool
|
||||
getSelected()
|
||||
{
|
||||
return this->selected;
|
||||
}
|
||||
|
||||
void
|
||||
setSelected(bool value)
|
||||
{
|
||||
this->selected = value;
|
||||
repaint();
|
||||
}
|
||||
|
||||
HighlightStyle
|
||||
getHighlightStyle() const
|
||||
{
|
||||
return this->highlightStyle;
|
||||
}
|
||||
|
||||
void
|
||||
setHighlightStyle(HighlightStyle style)
|
||||
{
|
||||
this->highlightStyle = style;
|
||||
repaint();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
|
||||
void enterEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
Notebook *notebook;
|
||||
|
||||
QString text;
|
||||
|
||||
bool selected;
|
||||
bool mouseOver;
|
||||
bool mouseDown;
|
||||
HighlightStyle highlightStyle;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NOTEBOOKTAB_H
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "widgets/scrollbar.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#define MIN_THUMB_HEIGHT 10
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ScrollBar::ScrollBar(QWidget *widget)
|
||||
: QWidget(widget)
|
||||
, mutex()
|
||||
, highlights(NULL)
|
||||
, thumbRect()
|
||||
, maximum()
|
||||
, minimum()
|
||||
, largeChange()
|
||||
, smallChange()
|
||||
, value()
|
||||
{
|
||||
resize(16, 100);
|
||||
}
|
||||
|
||||
ScrollBar::~ScrollBar()
|
||||
{
|
||||
auto highlight = this->highlights;
|
||||
|
||||
while (highlight != NULL) {
|
||||
auto tmp = highlight->next;
|
||||
delete highlight;
|
||||
highlight = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func)
|
||||
{
|
||||
this->mutex.lock();
|
||||
|
||||
ScrollBarHighlight *last = NULL;
|
||||
ScrollBarHighlight *current = this->highlights;
|
||||
|
||||
while (current != NULL) {
|
||||
if (func(*current)) {
|
||||
if (last == NULL) {
|
||||
this->highlights = current->next;
|
||||
} else {
|
||||
last->next = current->next;
|
||||
}
|
||||
|
||||
auto oldCurrent = current;
|
||||
|
||||
current = current->next;
|
||||
last = current;
|
||||
|
||||
delete oldCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
this->mutex.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::addHighlight(ScrollBarHighlight *highlight)
|
||||
{
|
||||
this->mutex.lock();
|
||||
|
||||
if (this->highlights == NULL) {
|
||||
this->highlights = highlight;
|
||||
} else {
|
||||
highlight->next = this->highlights->next;
|
||||
this->highlights->next = highlight;
|
||||
}
|
||||
|
||||
this->mutex.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), ColorScheme::instance().ScrollbarBG);
|
||||
|
||||
painter.fillRect(QRect(0, 0, width(), this->buttonHeight),
|
||||
QColor(255, 0, 0));
|
||||
painter.fillRect(
|
||||
QRect(0, height() - this->buttonHeight, width(), this->buttonHeight),
|
||||
QColor(255, 0, 0));
|
||||
|
||||
ScrollBarHighlight *highlight = this->highlights;
|
||||
|
||||
this->mutex.lock();
|
||||
|
||||
// do {
|
||||
// painter.fillRect();
|
||||
// } while ((highlight = highlight->next()) != NULL);
|
||||
|
||||
this->mutex.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollBar::updateScroll()
|
||||
{
|
||||
this->trackHeight = height() - this->buttonHeight - this->buttonHeight -
|
||||
MIN_THUMB_HEIGHT - 1;
|
||||
|
||||
this->thumbRect =
|
||||
QRect(0,
|
||||
(int)(this->value / this->maximum * this->trackHeight) + 1 +
|
||||
this->buttonHeight,
|
||||
width(),
|
||||
(int)(this->largeChange / this->maximum * this->trackHeight) +
|
||||
MIN_THUMB_HEIGHT);
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef SCROLLBAR_H
|
||||
#define SCROLLBAR_H
|
||||
|
||||
#include "widgets/scrollbarhighlight.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QWidget>
|
||||
#include <functional>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ScrollBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScrollBar(QWidget *parent = 0);
|
||||
~ScrollBar();
|
||||
|
||||
void removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func);
|
||||
void addHighlight(ScrollBarHighlight *highlight);
|
||||
|
||||
void
|
||||
setMaximum(qreal value)
|
||||
{
|
||||
this->maximum = value;
|
||||
|
||||
this->updateScroll();
|
||||
}
|
||||
|
||||
void
|
||||
setMinimum(qreal value)
|
||||
{
|
||||
this->minimum = value;
|
||||
|
||||
this->updateScroll();
|
||||
}
|
||||
|
||||
void
|
||||
setLargeChange(qreal value)
|
||||
{
|
||||
this->largeChange = value;
|
||||
|
||||
this->updateScroll();
|
||||
}
|
||||
|
||||
void
|
||||
setSmallChange(qreal value)
|
||||
{
|
||||
this->smallChange = value;
|
||||
|
||||
this->updateScroll();
|
||||
}
|
||||
|
||||
void
|
||||
setValue(qreal value)
|
||||
{
|
||||
this->value = value;
|
||||
|
||||
this->updateScroll();
|
||||
}
|
||||
|
||||
qreal
|
||||
getMaximum() const
|
||||
{
|
||||
return this->maximum;
|
||||
}
|
||||
|
||||
qreal
|
||||
getMinimum() const
|
||||
{
|
||||
return this->minimum;
|
||||
}
|
||||
|
||||
qreal
|
||||
getLargeChange() const
|
||||
{
|
||||
return this->largeChange;
|
||||
}
|
||||
|
||||
qreal
|
||||
getSmallChange() const
|
||||
{
|
||||
return this->smallChange;
|
||||
}
|
||||
|
||||
qreal
|
||||
getValue() const
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
private:
|
||||
QMutex mutex;
|
||||
ScrollBarHighlight *highlights;
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
int buttonHeight;
|
||||
int trackHeight;
|
||||
|
||||
QRect thumbRect;
|
||||
|
||||
qreal maximum;
|
||||
qreal minimum;
|
||||
qreal largeChange;
|
||||
qreal smallChange;
|
||||
qreal value;
|
||||
|
||||
void updateScroll();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCROLLBAR_H
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "widgets/scrollbarhighlight.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ScrollBarHighlight::ScrollBarHighlight(float position, int colorIndex,
|
||||
Style style, QString tag)
|
||||
: position(position)
|
||||
, colorIndex(std::max(
|
||||
0, std::min(ColorScheme::instance().HighlightColorCount, colorIndex)))
|
||||
, style(style)
|
||||
, tag(tag)
|
||||
, next(NULL)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef SCROLLBARHIGHLIGHT_H
|
||||
#define SCROLLBARHIGHLIGHT_H
|
||||
|
||||
#include "QString"
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class ScrollBarHighlight
|
||||
{
|
||||
public:
|
||||
enum Style { Default, Left, Right, SingleLine };
|
||||
|
||||
ScrollBarHighlight(float getPosition, int getColorIndex,
|
||||
Style getStyle = Default, QString tag = "");
|
||||
|
||||
Style
|
||||
getStyle()
|
||||
{
|
||||
return style;
|
||||
}
|
||||
|
||||
float
|
||||
getPosition()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
int
|
||||
getColorIndex()
|
||||
{
|
||||
return colorIndex;
|
||||
}
|
||||
|
||||
QString
|
||||
getTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
ScrollBarHighlight *next;
|
||||
|
||||
private:
|
||||
Style style;
|
||||
float position;
|
||||
int colorIndex;
|
||||
QString tag;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SCROLLBARHIGHLIGHT_H
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "widgets/settingsdialog.h"
|
||||
#include "widgets/settingsdialogtab.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QFile>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QPalette>
|
||||
#include <QResource>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
SettingsDialog::SettingsDialog()
|
||||
{
|
||||
QFile file(":/qss/settings.qss");
|
||||
file.open(QFile::ReadOnly);
|
||||
QString styleSheet = QLatin1String(file.readAll());
|
||||
setStyleSheet(styleSheet);
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Background, QColor("#444"));
|
||||
setPalette(palette);
|
||||
|
||||
pageStack.setObjectName("pages");
|
||||
|
||||
setLayout(&vbox);
|
||||
|
||||
vbox.addLayout(&hbox);
|
||||
|
||||
vbox.addWidget(&buttonBox);
|
||||
|
||||
auto tabWidget = new QWidget();
|
||||
tabWidget->setObjectName("tabWidget");
|
||||
|
||||
tabWidget->setLayout(&tabs);
|
||||
tabWidget->setFixedWidth(200);
|
||||
|
||||
hbox.addWidget(tabWidget);
|
||||
hbox.addLayout(&pageStack);
|
||||
|
||||
buttonBox.addButton(&okButton, QDialogButtonBox::ButtonRole::AcceptRole);
|
||||
buttonBox.addButton(&cancelButton,
|
||||
QDialogButtonBox::ButtonRole::RejectRole);
|
||||
okButton.setText("OK");
|
||||
cancelButton.setText("Cancel");
|
||||
|
||||
resize(600, 500);
|
||||
|
||||
addTabs();
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::addTabs()
|
||||
{
|
||||
QVBoxLayout *vbox;
|
||||
|
||||
// Appearance
|
||||
vbox = new QVBoxLayout();
|
||||
|
||||
{
|
||||
auto group = new QGroupBox("Application");
|
||||
|
||||
auto form = new QFormLayout();
|
||||
auto combo = new QComboBox();
|
||||
auto slider = new QSlider(Qt::Horizontal);
|
||||
auto font = new QPushButton("select");
|
||||
|
||||
form->addRow("Theme:", combo);
|
||||
form->addRow("Theme color:", slider);
|
||||
form->addRow("Font:", font);
|
||||
|
||||
group->setLayout(form);
|
||||
|
||||
vbox->addWidget(group);
|
||||
}
|
||||
|
||||
{
|
||||
auto group = new QGroupBox("Messages");
|
||||
|
||||
auto v = new QVBoxLayout();
|
||||
v->addWidget(createCheckbox("Show timestamp", ""));
|
||||
v->addWidget(createCheckbox("Show seconds in timestamp", ""));
|
||||
v->addWidget(createCheckbox(
|
||||
"Allow sending duplicate messages (add a space at the end)", ""));
|
||||
v->addWidget(createCheckbox("Seperate messages", ""));
|
||||
v->addWidget(createCheckbox("Show message length", ""));
|
||||
|
||||
group->setLayout(v);
|
||||
|
||||
vbox->addWidget(group);
|
||||
}
|
||||
|
||||
vbox->addStretch(1);
|
||||
|
||||
addTab(vbox, "Appearance", ":/images/AppearanceEditorPart_16x.png");
|
||||
|
||||
// Behaviour
|
||||
vbox = new QVBoxLayout();
|
||||
|
||||
vbox->addWidget(createCheckbox("Hide input box if empty", ""));
|
||||
vbox->addWidget(
|
||||
createCheckbox("Mention users with a @ (except in commands)", ""));
|
||||
vbox->addWidget(createCheckbox("Window always on top", ""));
|
||||
vbox->addWidget(createCheckbox("Show last read message indicator", ""));
|
||||
|
||||
{
|
||||
auto v = new QVBoxLayout();
|
||||
v->addWidget(new QLabel("Mouse scroll speed"));
|
||||
|
||||
auto scroll = new QSlider(Qt::Horizontal);
|
||||
|
||||
v->addWidget(scroll);
|
||||
v->addStretch(1);
|
||||
}
|
||||
|
||||
vbox->addStretch(1);
|
||||
|
||||
addTab(vbox, "Behaviour", ":/images/AppearanceEditorPart_16x.png");
|
||||
|
||||
// Commands
|
||||
vbox = new QVBoxLayout();
|
||||
|
||||
vbox->addWidget(new QLabel());
|
||||
|
||||
vbox->addStretch(1);
|
||||
|
||||
addTab(vbox, "Commands", ":/images/CustomActionEditor_16x.png");
|
||||
|
||||
// Add stretch
|
||||
tabs.addStretch(1);
|
||||
}
|
||||
|
||||
QCheckBox *
|
||||
SettingsDialog::createCheckbox(QString title, QString settingsId)
|
||||
{
|
||||
return new QCheckBox(title);
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::addTab(QLayout *layout, QString title, QString imageRes)
|
||||
{
|
||||
auto widget = new QWidget();
|
||||
|
||||
widget->setLayout(layout);
|
||||
|
||||
auto tab = new SettingsDialogTab(this, title, imageRes);
|
||||
|
||||
tab->setWidget(widget);
|
||||
|
||||
tabs.addWidget(tab, 0, Qt::AlignTop);
|
||||
|
||||
pageStack.addWidget(widget);
|
||||
|
||||
if (tabs.count() == 1) {
|
||||
select(tab);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::select(SettingsDialogTab *tab)
|
||||
{
|
||||
pageStack.setCurrentWidget(tab->getWidget());
|
||||
|
||||
if (selectedTab != NULL) {
|
||||
selectedTab->setSelected(false);
|
||||
selectedTab->setStyleSheet("");
|
||||
}
|
||||
|
||||
tab->setSelected(true);
|
||||
tab->setStyleSheet("background: #F00;"
|
||||
"background: qlineargradient( x1:0 y1:0, x2:1 y2:0, "
|
||||
"stop:0 #333, stop:1 #555);"
|
||||
"border-right: none;");
|
||||
selectedTab = tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include "widgets/settingsdialogtab.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QListView>
|
||||
#include <QMainWindow>
|
||||
#include <QPushButton>
|
||||
#include <QStackedLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class SettingsDialog : public QWidget
|
||||
{
|
||||
public:
|
||||
SettingsDialog();
|
||||
|
||||
void select(SettingsDialogTab *tab);
|
||||
|
||||
private:
|
||||
QVBoxLayout tabs;
|
||||
QVBoxLayout vbox;
|
||||
QHBoxLayout hbox;
|
||||
QStackedLayout pageStack;
|
||||
QDialogButtonBox buttonBox;
|
||||
QPushButton okButton;
|
||||
QPushButton cancelButton;
|
||||
|
||||
void addTab(QLayout *layout, QString title, QString imageRes);
|
||||
|
||||
void addTabs();
|
||||
|
||||
SettingsDialogTab *selectedTab = NULL;
|
||||
|
||||
QCheckBox *createCheckbox(QString title, QString settingsId);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "widgets/settingsdialogtab.h"
|
||||
#include "widgets/settingsdialog.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
SettingsDialogTab::SettingsDialogTab(SettingsDialog *dialog, QString label,
|
||||
QString imageRes)
|
||||
: image(QImage(imageRes))
|
||||
{
|
||||
this->dialog = dialog;
|
||||
|
||||
this->label = label;
|
||||
setFixedHeight(32);
|
||||
|
||||
setCursor(QCursor(Qt::PointingHandCursor));
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialogTab::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
|
||||
|
||||
int a = (height() - image.width()) / 2;
|
||||
|
||||
painter.drawImage(a, a, image);
|
||||
|
||||
a = a + a + image.width();
|
||||
|
||||
painter.drawText(QRect(a, 0, width() - a, height()), label,
|
||||
QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialogTab::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
dialog->select(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef SETTINGSNOTEBOOKTAB_H
|
||||
#define SETTINGSNOTEBOOKTAB_H
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class SettingsDialogTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool getSelected READ getSelected WRITE setSelected NOTIFY
|
||||
selectedChanged)
|
||||
|
||||
public:
|
||||
SettingsDialogTab(SettingsDialog *dialog, QString label, QString imageRes);
|
||||
|
||||
void
|
||||
setSelected(bool selected)
|
||||
{
|
||||
if (this->selected == selected)
|
||||
return;
|
||||
|
||||
this->selected = selected;
|
||||
emit selectedChanged(selected);
|
||||
}
|
||||
|
||||
bool
|
||||
getSelected() const
|
||||
{
|
||||
return this->selected;
|
||||
}
|
||||
|
||||
QWidget *
|
||||
getWidget()
|
||||
{
|
||||
return this->widget;
|
||||
}
|
||||
|
||||
void
|
||||
setWidget(QWidget *widget)
|
||||
{
|
||||
this->widget = widget;
|
||||
}
|
||||
|
||||
signals:
|
||||
void selectedChanged(bool);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
QWidget *widget;
|
||||
QString label;
|
||||
QImage image;
|
||||
|
||||
SettingsDialog *dialog = NULL;
|
||||
|
||||
bool selected = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SETTINGSNOTEBOOKTAB_H
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SIGNALLABEL_H
|
||||
#define SIGNALLABEL_H
|
||||
|
||||
#include <QFlags>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
|
||||
class SignalLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SignalLabel(QWidget *parent = 0, Qt::WindowFlags f = 0)
|
||||
: QLabel(parent, f) {}
|
||||
virtual ~SignalLabel() = default;
|
||||
signals:
|
||||
void mouseDoubleClick(QMouseEvent *ev);
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *ev) override {
|
||||
emit this->mouseDoubleClick(ev);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SIGNALLABEL_H
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "widgets/textinputdialog.h"
|
||||
#include <QSizePolicy>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
TextInputDialog::TextInputDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, vbox(this)
|
||||
, lineEdit()
|
||||
, buttonBox()
|
||||
, okButton("OK")
|
||||
, cancelButton("Cancel")
|
||||
{
|
||||
this->vbox.addWidget(&this->lineEdit);
|
||||
this->vbox.addLayout(&this->buttonBox);
|
||||
this->buttonBox.addStretch(1);
|
||||
this->buttonBox.addWidget(&this->okButton);
|
||||
this->buttonBox.addWidget(&this->cancelButton);
|
||||
|
||||
QObject::connect(&this->okButton, SIGNAL(clicked()), this,
|
||||
SLOT(okButtonClicked()));
|
||||
QObject::connect(&this->cancelButton, SIGNAL(clicked()), this,
|
||||
SLOT(cancelButtonClicked()));
|
||||
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
setWindowFlags((windowFlags() & ~(Qt::WindowContextHelpButtonHint)) |
|
||||
Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
|
||||
}
|
||||
|
||||
void
|
||||
TextInputDialog::okButtonClicked()
|
||||
{
|
||||
accept();
|
||||
close();
|
||||
}
|
||||
|
||||
void
|
||||
TextInputDialog::cancelButtonClicked()
|
||||
{
|
||||
reject();
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef TEXTINPUTDIALOG_H
|
||||
#define TEXTINPUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class TextInputDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TextInputDialog(QWidget *parent = NULL);
|
||||
|
||||
QString
|
||||
getText() const
|
||||
{
|
||||
return lineEdit.text();
|
||||
}
|
||||
|
||||
void
|
||||
setText(const QString &text)
|
||||
{
|
||||
lineEdit.setText(text);
|
||||
}
|
||||
|
||||
private:
|
||||
QVBoxLayout vbox;
|
||||
QLineEdit lineEdit;
|
||||
QHBoxLayout buttonBox;
|
||||
QPushButton okButton;
|
||||
QPushButton cancelButton;
|
||||
|
||||
private slots:
|
||||
void okButtonClicked();
|
||||
void cancelButtonClicked();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TEXTINPUTDIALOG_H
|
||||
Reference in New Issue
Block a user