2017-11-12 17:21:50 +01:00
|
|
|
#include "widgets/splitcontainer.hpp"
|
2017-12-26 12:32:24 +01:00
|
|
|
#include "common.hpp"
|
2017-12-31 00:50:07 +01:00
|
|
|
#include "singletons/thememanager.hpp"
|
2017-12-22 14:44:31 +01:00
|
|
|
#include "util/helpers.hpp"
|
2017-11-12 17:21:50 +01:00
|
|
|
#include "widgets/helper/notebooktab.hpp"
|
2017-06-26 16:41:20 +02:00
|
|
|
#include "widgets/notebook.hpp"
|
2017-11-12 17:21:50 +01:00
|
|
|
#include "widgets/split.hpp"
|
2016-12-29 17:31:07 +01:00
|
|
|
|
2017-08-17 16:43:19 +02:00
|
|
|
#include <QApplication>
|
2017-01-28 22:35:23 +01:00
|
|
|
#include <QDebug>
|
2017-01-18 04:52:47 +01:00
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QMimeData>
|
2017-01-29 12:26:22 +01:00
|
|
|
#include <QObject>
|
2017-01-18 04:52:47 +01:00
|
|
|
#include <QPainter>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
#include <QWidget>
|
2017-01-28 22:35:23 +01:00
|
|
|
#include <boost/foreach.hpp>
|
2017-01-18 04:52:47 +01:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
|
|
|
namespace widgets {
|
2017-01-18 21:30:23 +01:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
bool SplitContainer::isDraggingSplit = false;
|
|
|
|
Split *SplitContainer::draggingSplit = nullptr;
|
|
|
|
std::pair<int, int> SplitContainer::dropPosition = std::pair<int, int>(-1, -1);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-12-31 00:50:07 +01:00
|
|
|
SplitContainer::SplitContainer(Notebook *parent, NotebookTab *_tab, const std::string &_uuid)
|
|
|
|
: BaseWidget(parent->themeManager, parent)
|
2017-12-28 18:15:27 +01:00
|
|
|
, uuid(_uuid)
|
|
|
|
, settingRoot(fS("/containers/{}", this->uuid))
|
2017-12-22 14:44:31 +01:00
|
|
|
, chats(fS("{}/chats", this->settingRoot))
|
2017-06-13 21:13:58 +02:00
|
|
|
, tab(_tab)
|
2017-07-02 13:10:06 +02:00
|
|
|
, dropPreview(this)
|
2018-01-16 18:55:30 +01:00
|
|
|
, splits()
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
this->tab->page = this;
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->setLayout(&this->ui.parentLayout);
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->setHidden(true);
|
|
|
|
this->setAcceptDrops(true);
|
2017-05-29 21:26:55 +02:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->ui.parentLayout.addSpacing(2);
|
|
|
|
this->ui.parentLayout.addLayout(&this->ui.hbox);
|
|
|
|
this->ui.parentLayout.setMargin(0);
|
2017-05-29 21:26:55 +02:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->ui.hbox.setSpacing(1);
|
|
|
|
this->ui.hbox.setMargin(0);
|
2017-08-17 22:25:41 +02:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
this->loadSplits();
|
|
|
|
|
2017-08-17 22:25:41 +02:00
|
|
|
this->refreshTitle();
|
2017-05-29 21:26:55 +02:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::updateFlexValues()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < this->ui.hbox.count(); i++) {
|
|
|
|
QVBoxLayout *vbox = (QVBoxLayout *)ui.hbox.itemAt(i)->layout();
|
|
|
|
|
|
|
|
if (vbox->count() != 0) {
|
|
|
|
ui.hbox.setStretch(i, (int)(1000 * ((Split *)vbox->itemAt(0))->getFlexSizeX()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 18:55:30 +01:00
|
|
|
int SplitContainer::splitCount() const
|
|
|
|
{
|
|
|
|
return this->splits.size();
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
std::pair<int, int> SplitContainer::removeFromLayout(Split *widget)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
// remove reference to chat widget from chatWidgets vector
|
2018-01-16 18:55:30 +01:00
|
|
|
auto it = std::find(std::begin(this->splits), std::end(this->splits), widget);
|
|
|
|
if (it != std::end(this->splits)) {
|
|
|
|
this->splits.erase(it);
|
2017-08-13 16:52:16 +02:00
|
|
|
|
|
|
|
this->refreshTitle();
|
2017-01-16 03:15:07 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
// remove from box and return location
|
2017-07-02 13:10:06 +02:00
|
|
|
for (int i = 0; i < this->ui.hbox.count(); ++i) {
|
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->ui.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) {
|
2017-04-12 17:46:44 +02:00
|
|
|
if (vbox->itemAt(j)->widget() != widget) {
|
2017-01-11 18:52:09 +01:00
|
|
|
continue;
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-06-10 22:48:28 +02:00
|
|
|
widget->setParent(nullptr);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
bool isLastItem = vbox->count() == 0;
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (isLastItem) {
|
2017-07-02 13:10:06 +02:00
|
|
|
this->ui.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-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::addToLayout(Split *widget, std::pair<int, int> position)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2018-01-16 18:55:30 +01:00
|
|
|
this->splits.push_back(widget);
|
2017-08-13 16:52:16 +02:00
|
|
|
|
|
|
|
this->refreshTitle();
|
|
|
|
|
2017-08-12 15:41:14 +02:00
|
|
|
widget->giveFocus(Qt::MouseFocusReason);
|
2017-01-16 03:15:07 +01:00
|
|
|
|
2017-01-01 02:30:42 +01:00
|
|
|
// add vbox at the end
|
2017-07-02 13:10:06 +02:00
|
|
|
if (position.first < 0 || position.first >= this->ui.hbox.count()) {
|
2017-01-01 02:30:42 +01:00
|
|
|
auto vbox = new QVBoxLayout();
|
|
|
|
vbox->addWidget(widget);
|
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->ui.hbox.addLayout(vbox, 1);
|
2017-12-22 14:44:31 +01:00
|
|
|
|
2017-08-12 15:41:14 +02:00
|
|
|
this->refreshCurrentFocusCoordinates();
|
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-07-02 13:10:06 +02:00
|
|
|
this->ui.hbox.insertLayout(position.first, vbox, 1);
|
2017-08-12 15:41:14 +02:00
|
|
|
this->refreshCurrentFocusCoordinates();
|
2017-01-01 02:30:42 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add to existing vbox
|
2017-07-02 13:10:06 +02:00
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->ui.hbox.itemAt(position.first));
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)), widget);
|
2017-08-12 15:41:14 +02:00
|
|
|
|
|
|
|
this->refreshCurrentFocusCoordinates();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
const std::vector<Split *> &SplitContainer::getChatWidgets() const
|
2017-07-02 13:10:06 +02:00
|
|
|
{
|
2018-01-16 18:55:30 +01:00
|
|
|
return this->splits;
|
2017-07-02 13:10:06 +02:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
NotebookTab *SplitContainer::getTab() const
|
2017-07-02 13:10:06 +02:00
|
|
|
{
|
|
|
|
return this->tab;
|
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
void SplitContainer::addChat(bool openChannelNameDialog, std::string chatUUID)
|
2017-07-02 13:10:06 +02:00
|
|
|
{
|
2017-12-22 14:44:31 +01:00
|
|
|
if (chatUUID.empty()) {
|
|
|
|
chatUUID = CreateUUID().toStdString();
|
|
|
|
}
|
|
|
|
Split *w = this->createChatWidget(chatUUID);
|
2017-07-02 13:10:06 +02:00
|
|
|
|
|
|
|
if (openChannelNameDialog) {
|
2017-07-31 01:36:42 +02:00
|
|
|
bool ret = w->showChangeChannelPopup("Open channel", true);
|
|
|
|
|
|
|
|
if (!ret) {
|
|
|
|
delete w;
|
|
|
|
return;
|
|
|
|
}
|
2017-07-02 13:10:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this->addToLayout(w, std::pair<int, int>(-1, -1));
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::refreshCurrentFocusCoordinates(bool alsoSetLastRequested)
|
2017-08-12 15:41:14 +02:00
|
|
|
{
|
|
|
|
int setX = -1;
|
|
|
|
int setY = -1;
|
|
|
|
bool doBreak = false;
|
|
|
|
for (int x = 0; x < this->ui.hbox.count(); ++x) {
|
|
|
|
QLayoutItem *item = this->ui.hbox.itemAt(x);
|
|
|
|
if (item->isEmpty()) {
|
|
|
|
setX = x;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
QVBoxLayout *vbox = static_cast<QVBoxLayout *>(item->layout());
|
|
|
|
|
|
|
|
for (int y = 0; y < vbox->count(); ++y) {
|
|
|
|
QLayoutItem *innerItem = vbox->itemAt(y);
|
|
|
|
|
|
|
|
if (innerItem->isEmpty()) {
|
|
|
|
setX = x;
|
|
|
|
setY = y;
|
|
|
|
doBreak = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
QWidget *w = innerItem->widget();
|
|
|
|
if (w) {
|
2017-11-12 17:21:50 +01:00
|
|
|
Split *chatWidget = static_cast<Split *>(w);
|
2017-08-12 15:41:14 +02:00
|
|
|
if (chatWidget->hasFocus()) {
|
|
|
|
setX = x;
|
|
|
|
setY = y;
|
|
|
|
doBreak = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doBreak) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setX != -1) {
|
|
|
|
this->currentX = setX;
|
|
|
|
|
|
|
|
if (setY != -1) {
|
|
|
|
this->currentY = setY;
|
|
|
|
|
|
|
|
if (alsoSetLastRequested) {
|
|
|
|
this->lastRequestedY[setX] = setY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::requestFocus(int requestedX, int requestedY)
|
2017-08-12 15:41:14 +02:00
|
|
|
{
|
|
|
|
// XXX: Perhaps if we request an Y coordinate out of bounds, we shuold set all previously set
|
|
|
|
// requestedYs to 0 (if -1 is requested) or that x-coordinates vbox count (if requestedY >=
|
|
|
|
// currentvbox.count() is requested)
|
|
|
|
if (requestedX < 0 || requestedX >= this->ui.hbox.count()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QLayoutItem *item = this->ui.hbox.itemAt(requestedX);
|
|
|
|
QWidget *xW = item->widget();
|
|
|
|
if (item->isEmpty()) {
|
|
|
|
qDebug() << "Requested hbox item " << requestedX << "is empty";
|
|
|
|
if (xW) {
|
|
|
|
qDebug() << "but xW is not null";
|
|
|
|
// TODO: figure out what to do here
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVBoxLayout *vbox = static_cast<QVBoxLayout *>(item->layout());
|
|
|
|
|
|
|
|
if (requestedY < 0) {
|
|
|
|
requestedY = 0;
|
|
|
|
} else if (requestedY >= vbox->count()) {
|
|
|
|
requestedY = vbox->count() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->lastRequestedY[requestedX] = requestedY;
|
|
|
|
|
|
|
|
QLayoutItem *innerItem = vbox->itemAt(requestedY);
|
|
|
|
|
|
|
|
if (innerItem->isEmpty()) {
|
|
|
|
qDebug() << "Requested vbox item " << requestedY << "is empty";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QWidget *w = innerItem->widget();
|
|
|
|
if (w) {
|
2017-11-12 17:21:50 +01:00
|
|
|
Split *chatWidget = static_cast<Split *>(w);
|
2017-08-12 15:41:14 +02:00
|
|
|
chatWidget->giveFocus(Qt::OtherFocusReason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::enterEvent(QEvent *)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
if (this->ui.hbox.count() == 0) {
|
2017-06-26 16:41:20 +02:00
|
|
|
this->setCursor(QCursor(Qt::PointingHandCursor));
|
2017-01-11 18:52:09 +01:00
|
|
|
} else {
|
2017-06-26 16:41:20 +02:00
|
|
|
this->setCursor(QCursor(Qt::ArrowCursor));
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::leaveEvent(QEvent *)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::mouseReleaseEvent(QMouseEvent *event)
|
2017-01-01 13:07:36 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
if (this->ui.hbox.count() == 0 && event->button() == Qt::LeftButton) {
|
2017-01-29 11:38:00 +01:00
|
|
|
// "Add Chat" was clicked
|
2017-07-02 13:10:06 +02:00
|
|
|
this->addChat(true);
|
2017-01-16 03:15:07 +01:00
|
|
|
|
2017-06-26 16:41:20 +02:00
|
|
|
this->setCursor(QCursor(Qt::ArrowCursor));
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::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-08-05 22:53:21 +02:00
|
|
|
if (!isDraggingSplit) {
|
2017-04-12 17:46:44 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropRegions.clear();
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
if (this->ui.hbox.count() == 0) {
|
|
|
|
this->dropRegions.push_back(DropRegion(rect(), std::pair<int, int>(-1, -1)));
|
2017-04-12 17:46:44 +02:00
|
|
|
} else {
|
2017-07-02 13:10:06 +02:00
|
|
|
for (int i = 0; i < this->ui.hbox.count() + 1; ++i) {
|
|
|
|
this->dropRegions.push_back(
|
|
|
|
DropRegion(QRect(((i * 4 - 1) * width() / this->ui.hbox.count()) / 4, 0,
|
|
|
|
width() / this->ui.hbox.count() / 2 + 1, height() + 1),
|
|
|
|
std::pair<int, int>(i, -1)));
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
for (int i = 0; i < this->ui.hbox.count(); ++i) {
|
|
|
|
auto vbox = static_cast<QVBoxLayout *>(this->ui.hbox.itemAt(i));
|
2017-01-01 13:07:36 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
for (int j = 0; j < vbox->count() + 1; ++j) {
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropRegions.push_back(DropRegion(
|
|
|
|
QRect(i * width() / this->ui.hbox.count(),
|
|
|
|
((j * 2 - 1) * height() / vbox->count()) / 2,
|
|
|
|
width() / this->ui.hbox.count() + 1, height() / vbox->count() + 1),
|
2017-01-24 19:51:57 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
std::pair<int, int>(i, j)));
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
setPreviewRect(event->pos());
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
event->acceptProposedAction();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::dragMoveEvent(QDragMoveEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
|
|
|
setPreviewRect(event->pos());
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::setPreviewRect(QPoint mousePos)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
for (DropRegion region : this->dropRegions) {
|
2017-01-11 18:52:09 +01:00
|
|
|
if (region.rect.contains(mousePos)) {
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropPreview.setBounds(region.rect);
|
2017-01-24 19:51:57 +01:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
if (!this->dropPreview.isVisible()) {
|
|
|
|
this->dropPreview.show();
|
|
|
|
this->dropPreview.raise();
|
2017-01-24 19:51:57 +01:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
|
|
|
dropPosition = region.position;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-01-24 19:51:57 +01:00
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropPreview.hide();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::dragLeaveEvent(QDragLeaveEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropPreview.hide();
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::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();
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
SplitContainer::draggingSplit->setParent(this);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
addToLayout(SplitContainer::draggingSplit, dropPosition);
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
this->dropPreview.hide();
|
2016-12-30 18:00:25 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
bool SplitContainer::eventFilter(QObject *object, QEvent *event)
|
2017-08-12 15:41:14 +02:00
|
|
|
{
|
|
|
|
if (event->type() == QEvent::FocusIn) {
|
|
|
|
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
|
|
|
|
|
|
|
|
this->refreshCurrentFocusCoordinates((focusEvent->reason() == Qt::MouseFocusReason));
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::paintEvent(QPaintEvent *)
|
2016-12-30 18:00:25 +01:00
|
|
|
{
|
|
|
|
QPainter painter(this);
|
|
|
|
|
2017-07-02 13:10:06 +02:00
|
|
|
if (this->ui.hbox.count() == 0) {
|
2018-01-02 02:15:11 +01:00
|
|
|
painter.fillRect(rect(), this->themeManager.splits.background);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2018-01-02 02:15:11 +01:00
|
|
|
painter.setPen(this->themeManager.splits.header.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 {
|
2018-01-02 02:15:11 +01:00
|
|
|
painter.fillRect(rect(), this->themeManager.splits.messageSeperator);
|
2017-01-01 13:07:36 +01:00
|
|
|
}
|
2017-08-17 16:43:19 +02:00
|
|
|
|
2018-01-02 02:15:11 +01:00
|
|
|
QBrush accentColor = (QApplication::activeWindow() == this->window()
|
|
|
|
? this->themeManager.tabs.selected.backgrounds.regular
|
|
|
|
: this->themeManager.tabs.selected.backgrounds.unfocused);
|
2017-08-17 16:43:19 +02:00
|
|
|
|
|
|
|
painter.fillRect(0, 0, width(), 2, accentColor);
|
2016-12-29 17:31:07 +01:00
|
|
|
}
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::showEvent(QShowEvent *event)
|
2017-08-12 15:41:14 +02:00
|
|
|
{
|
|
|
|
// Whenever this notebook page is shown, give focus to the last focused chat widget
|
|
|
|
// If this is the first time this notebook page is shown, it will give focus to the top-left
|
|
|
|
// chat widget
|
|
|
|
this->requestFocus(this->currentX, this->currentY);
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
static std::pair<int, int> getWidgetPositionInLayout(QLayout *layout, const Split *chatWidget)
|
2017-01-29 12:26:22 +01:00
|
|
|
{
|
|
|
|
for (int i = 0; i < layout->count(); ++i) {
|
|
|
|
printf("xD\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(-1, -1);
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
std::pair<int, int> SplitContainer::getChatPosition(const Split *chatWidget)
|
2017-01-29 12:26:22 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
auto layout = this->ui.hbox.layout();
|
2017-01-29 12:26:22 +01:00
|
|
|
|
|
|
|
if (layout == nullptr) {
|
|
|
|
return std::make_pair(-1, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return getWidgetPositionInLayout(layout, chatWidget);
|
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
Split *SplitContainer::createChatWidget(const std::string &uuid)
|
2017-06-26 16:41:20 +02:00
|
|
|
{
|
2017-12-31 00:50:07 +01:00
|
|
|
auto split = new Split(this, uuid);
|
2017-12-26 12:32:24 +01:00
|
|
|
|
|
|
|
split->getChannelView().highlightedMessageReceived.connect([this] {
|
|
|
|
this->tab->setHighlightState(HighlightState::Highlighted); //
|
|
|
|
});
|
|
|
|
|
|
|
|
return split;
|
2017-08-13 16:52:16 +02:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitContainer::refreshTitle()
|
2017-08-13 16:52:16 +02:00
|
|
|
{
|
|
|
|
if (!this->tab->useDefaultBehaviour) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString newTitle = "";
|
|
|
|
bool first = true;
|
|
|
|
|
2018-01-16 18:55:30 +01:00
|
|
|
for (const auto &chatWidget : this->splits) {
|
2017-08-17 22:25:41 +02:00
|
|
|
auto channelName = QString::fromStdString(chatWidget->channelName.getValue());
|
|
|
|
|
|
|
|
if (channelName.isEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-08-13 16:52:16 +02:00
|
|
|
if (!first) {
|
|
|
|
newTitle += ", ";
|
|
|
|
}
|
2017-08-17 22:25:41 +02:00
|
|
|
newTitle += channelName;
|
2017-08-13 16:52:16 +02:00
|
|
|
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
2017-08-17 22:25:41 +02:00
|
|
|
if (newTitle.isEmpty()) {
|
|
|
|
newTitle = "empty";
|
|
|
|
}
|
|
|
|
|
2017-08-13 16:52:16 +02:00
|
|
|
this->tab->setTitle(newTitle);
|
2017-06-26 16:41:20 +02:00
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
void SplitContainer::loadSplits()
|
2017-01-28 22:35:23 +01:00
|
|
|
{
|
2017-12-22 14:44:31 +01:00
|
|
|
const auto hboxes = this->chats.getValue();
|
|
|
|
int column = 0;
|
|
|
|
for (const std::vector<std::string> &hbox : hboxes) {
|
|
|
|
int row = 0;
|
|
|
|
for (const std::string &chatUUID : hbox) {
|
|
|
|
Split *split = this->createChatWidget(chatUUID);
|
|
|
|
|
|
|
|
this->addToLayout(split, std::pair<int, int>(column, row));
|
|
|
|
|
|
|
|
++row;
|
2017-01-29 11:38:00 +01:00
|
|
|
}
|
2017-12-22 14:44:31 +01:00
|
|
|
++column;
|
2017-01-29 11:38:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
template <typename Container>
|
|
|
|
static void saveFromLayout(QLayout *layout, Container &container)
|
2017-01-29 12:26:22 +01:00
|
|
|
{
|
|
|
|
for (int i = 0; i < layout->count(); ++i) {
|
|
|
|
auto item = layout->itemAt(i);
|
|
|
|
|
|
|
|
auto innerLayout = item->layout();
|
|
|
|
if (innerLayout != nullptr) {
|
2017-12-22 14:44:31 +01:00
|
|
|
std::vector<std::string> vbox;
|
|
|
|
|
|
|
|
for (int j = 0; j < innerLayout->count(); ++j) {
|
|
|
|
auto innerItem = innerLayout->itemAt(j);
|
|
|
|
auto innerWidget = innerItem->widget();
|
|
|
|
if (innerWidget == nullptr) {
|
|
|
|
assert(false);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Split *innerSplit = qobject_cast<Split *>(innerWidget);
|
|
|
|
vbox.push_back(innerSplit->getUUID());
|
2017-01-29 12:26:22 +01:00
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
container.push_back(vbox);
|
2017-01-29 12:26:22 +01:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
void SplitContainer::save()
|
2017-01-29 11:38:00 +01:00
|
|
|
{
|
2017-07-02 13:10:06 +02:00
|
|
|
auto layout = this->ui.hbox.layout();
|
2017-01-29 12:26:22 +01:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
std::vector<std::vector<std::string>> _chats;
|
2017-01-29 12:26:22 +01:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
for (int i = 0; i < layout->count(); ++i) {
|
|
|
|
auto item = layout->itemAt(i);
|
2017-01-29 12:26:22 +01:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
auto innerLayout = item->layout();
|
|
|
|
if (innerLayout != nullptr) {
|
|
|
|
std::vector<std::string> vbox;
|
|
|
|
|
|
|
|
for (int j = 0; j < innerLayout->count(); ++j) {
|
|
|
|
auto innerItem = innerLayout->itemAt(j);
|
|
|
|
auto innerWidget = innerItem->widget();
|
|
|
|
if (innerWidget == nullptr) {
|
|
|
|
assert(false);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Split *innerSplit = qobject_cast<Split *>(innerWidget);
|
|
|
|
vbox.push_back(innerSplit->getUUID());
|
|
|
|
}
|
2017-01-29 12:26:22 +01:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
_chats.push_back(vbox);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2017-01-29 11:38:00 +01:00
|
|
|
}
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2017-12-22 14:44:31 +01:00
|
|
|
this->chats = _chats;
|
2017-01-18 21:30:23 +01:00
|
|
|
}
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
} // namespace widgets
|
|
|
|
} // namespace chatterino
|