2017-01-18 21:30:23 +01:00
|
|
|
#include "widgets/notebookpage.h"
|
2017-01-11 18:52:09 +01:00
|
|
|
#include "colorscheme.h"
|
2017-01-18 21:30:23 +01:00
|
|
|
#include "widgets/chatwidget.h"
|
|
|
|
#include "widgets/notebooktab.h"
|
2016-12-29 17:31:07 +01:00
|
|
|
|
2017-01-18 04:52:47 +01:00
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QMimeData>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
#include <QWidget>
|
|
|
|
|
2017-01-18 21:30:23 +01:00
|
|
|
namespace chatterino {
|
|
|
|
namespace widgets {
|
|
|
|
|
2017-01-01 02:30:42 +01:00
|
|
|
bool NotebookPage::isDraggingSplit = false;
|
2017-01-11 18:52:09 +01:00
|
|
|
ChatWidget *NotebookPage::draggingSplit = NULL;
|
2017-01-01 02:30:42 +01:00
|
|
|
std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
|
|
|
|
|
|
|
|
NotebookPage::NotebookPage(QWidget *parent, NotebookTab *tab)
|
2017-01-11 18:52:09 +01:00
|
|
|
: QWidget(parent)
|
2017-01-18 04:33:30 +01:00
|
|
|
, parentbox(this)
|
|
|
|
, chatWidgets()
|
2017-01-18 14:48:42 +01:00
|
|
|
, preview(this)
|
2016-12-29 17:31:07 +01:00
|
|
|
{
|
2016-12-30 12:20:26 +01:00
|
|
|
this->tab = tab;
|
2016-12-30 18:00:25 +01:00
|
|
|
tab->page = this;
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
setHidden(true);
|
|
|
|
setAcceptDrops(true);
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
this->parentbox.addSpacing(2);
|
|
|
|
this->parentbox.addLayout(&this->hbox);
|
|
|
|
this->parentbox.setMargin(0);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
this->hbox.setSpacing(1);
|
|
|
|
this->hbox.setMargin(0);
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
std::pair<int, int>
|
|
|
|
NotebookPage::removeFromLayout(ChatWidget *widget)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
for (auto it = this->chatWidgets.begin(); it != this->chatWidgets.end();
|
|
|
|
++it) {
|
2017-01-16 03:15:07 +01:00
|
|
|
if (*it == widget) {
|
2017-01-18 04:33:30 +01:00
|
|
|
this->chatWidgets.erase(it);
|
2017-01-16 03:15:07 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
for (int i = 0; i < this->hbox.count(); ++i) {
|
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(i));
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
for (int j = 0; j < vbox->count(); ++j) {
|
|
|
|
if (vbox->itemAt(j)->widget() != widget)
|
|
|
|
continue;
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
widget->setParent(NULL);
|
|
|
|
|
|
|
|
bool isLastItem = vbox->count() == 0;
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (isLastItem) {
|
2017-01-18 04:33:30 +01:00
|
|
|
this->hbox.removeItem(vbox);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
delete vbox;
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
return std::pair<int, int>(i, isLastItem ? -1 : j);
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::pair<int, int>(-1, -1);
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::addToLayout(
|
|
|
|
ChatWidget *widget,
|
|
|
|
std::pair<int, int> position = std::pair<int, int>(-1, -1))
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
this->chatWidgets.push_back(widget);
|
2017-01-16 03:15:07 +01:00
|
|
|
|
2017-01-01 02:30:42 +01:00
|
|
|
// add vbox at the end
|
2017-01-18 04:33:30 +01:00
|
|
|
if (position.first < 0 || position.first >= this->hbox.count()) {
|
2017-01-01 02:30:42 +01:00
|
|
|
auto vbox = new QVBoxLayout();
|
|
|
|
vbox->addWidget(widget);
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
this->hbox.addLayout(vbox);
|
2017-01-01 02:30:42 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert vbox
|
2017-01-11 18:52:09 +01:00
|
|
|
if (position.second == -1) {
|
2017-01-01 02:30:42 +01:00
|
|
|
auto vbox = new QVBoxLayout();
|
|
|
|
vbox->addWidget(widget);
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
this->hbox.insertLayout(position.first, vbox);
|
2017-01-01 02:30:42 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add to existing vbox
|
2017-01-18 04:33:30 +01:00
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(position.first));
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)),
|
|
|
|
widget);
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::enterEvent(QEvent *)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
if (this->hbox.count() == 0) {
|
2017-01-01 13:07:36 +01:00
|
|
|
setCursor(QCursor(Qt::PointingHandCursor));
|
2017-01-11 18:52:09 +01:00
|
|
|
} else {
|
2017-01-01 13:07:36 +01:00
|
|
|
setCursor(QCursor(Qt::ArrowCursor));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::leaveEvent(QEvent *)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::mouseReleaseEvent(QMouseEvent *event)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
if (this->hbox.count() == 0 && event->button() == Qt::LeftButton) {
|
2017-01-01 13:07:36 +01:00
|
|
|
addToLayout(new ChatWidget(), std::pair<int, int>(-1, -1));
|
2017-01-16 03:15:07 +01:00
|
|
|
|
2017-01-01 13:07:36 +01:00
|
|
|
setCursor(QCursor(Qt::ArrowCursor));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::dragEnterEvent(QDragEnterEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-11 18:52:09 +01:00
|
|
|
if (!event->mimeData()->hasFormat("chatterino/split"))
|
|
|
|
return;
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (isDraggingSplit) {
|
2017-01-18 04:33:30 +01:00
|
|
|
this->dropRegions.clear();
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
if (this->hbox.count() == 0) {
|
|
|
|
this->dropRegions.push_back(
|
2017-01-11 18:52:09 +01:00
|
|
|
DropRegion(rect(), std::pair<int, int>(-1, -1)));
|
|
|
|
} else {
|
2017-01-18 04:33:30 +01:00
|
|
|
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,
|
2017-01-24 19:51:57 +01:00
|
|
|
width() / this->hbox.count() / 2 + 1, height() + 1),
|
|
|
|
|
2017-01-16 03:15:07 +01:00
|
|
|
std::pair<int, int>(i, -1)));
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
for (int i = 0; i < this->hbox.count(); ++i) {
|
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->hbox.itemAt(i));
|
2017-01-01 13:07:36 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
for (int j = 0; j < vbox->count() + 1; ++j) {
|
2017-01-18 04:33:30 +01:00
|
|
|
this->dropRegions.push_back(DropRegion(
|
|
|
|
QRect(i * width() / this->hbox.count(),
|
2017-01-11 18:52:09 +01:00
|
|
|
((j * 2 - 1) * height() / vbox->count()) / 2,
|
2017-01-24 19:51:57 +01:00
|
|
|
width() / this->hbox.count() + 1,
|
|
|
|
height() / vbox->count() + 1),
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
std::pair<int, int>(i, j)));
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setPreviewRect(event->pos());
|
|
|
|
|
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::dragMoveEvent(QDragMoveEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
|
|
|
setPreviewRect(event->pos());
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::setPreviewRect(QPoint mousePos)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
for (DropRegion region : this->dropRegions) {
|
2017-01-11 18:52:09 +01:00
|
|
|
if (region.rect.contains(mousePos)) {
|
2017-01-18 04:33:30 +01:00
|
|
|
this->preview.setBounds(region.rect);
|
2017-01-24 19:51:57 +01:00
|
|
|
|
|
|
|
if (!this->preview.isVisible()) {
|
|
|
|
this->preview.show();
|
|
|
|
this->preview.raise();
|
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
dropPosition = region.position;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-01-24 19:51:57 +01:00
|
|
|
|
|
|
|
this->preview.hide();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::dragLeaveEvent(QDragLeaveEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-18 04:33:30 +01:00
|
|
|
this->preview.hide();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::dropEvent(QDropEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-01-11 18:52:09 +01:00
|
|
|
if (isDraggingSplit) {
|
2017-01-01 02:30:42 +01:00
|
|
|
event->acceptProposedAction();
|
|
|
|
|
|
|
|
NotebookPage::draggingSplit->setParent(this);
|
|
|
|
|
|
|
|
addToLayout(NotebookPage::draggingSplit, dropPosition);
|
|
|
|
}
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
this->preview.hide();
|
2016-12-30 18:00:25 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
void
|
|
|
|
NotebookPage::paintEvent(QPaintEvent *)
|
2016-12-30 18:00:25 +01:00
|
|
|
{
|
|
|
|
QPainter painter(this);
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
if (this->hbox.count() == 0) {
|
2017-01-06 23:28:48 +01:00
|
|
|
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
painter.fillRect(0, 0, width(), 2,
|
|
|
|
ColorScheme::instance().TabSelectedBackground);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-06 23:28:48 +01:00
|
|
|
painter.setPen(ColorScheme::instance().Text);
|
2017-01-01 13:07:36 +01:00
|
|
|
painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter));
|
2017-01-11 18:52:09 +01:00
|
|
|
} else {
|
2017-01-06 23:28:48 +01:00
|
|
|
painter.fillRect(rect(), ColorScheme::instance().TabSelectedBackground);
|
2016-12-30 18:00:25 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
painter.fillRect(0, 0, width(), 2,
|
|
|
|
ColorScheme::instance().TabSelectedBackground);
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
2016-12-29 17:31:07 +01:00
|
|
|
}
|
2017-01-18 21:30:23 +01:00
|
|
|
}
|
|
|
|
}
|