diff --git a/.gitignore b/.gitignore
index 3c6ec6855..3d5ecc2b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+__pycache__/
+
# C++ objects and libs
*.slo
diff --git a/resources/__pycache__/_generate_resources.cpython-36.pyc b/resources/__pycache__/_generate_resources.cpython-36.pyc
deleted file mode 100644
index dfaf6af51..000000000
Binary files a/resources/__pycache__/_generate_resources.cpython-36.pyc and /dev/null differ
diff --git a/resources/buttons/addSplitDark.png b/resources/buttons/addSplitDark.png
new file mode 100644
index 000000000..c6cd6707a
Binary files /dev/null and b/resources/buttons/addSplitDark.png differ
diff --git a/resources/resources_autogenerated.qrc b/resources/resources_autogenerated.qrc
index 6fc9e6f68..65204d1b9 100644
--- a/resources/resources_autogenerated.qrc
+++ b/resources/resources_autogenerated.qrc
@@ -1,64 +1,67 @@
- pajaDank.png
- icon.png
- emojidata.txt
+ chatterino2.icns
contributors.txt
- error.png
emoji.json
+ emojidata.txt
+ error.png
icon.ico
+ icon.png
+ pajaDank.png
tlds.txt
- chatterino2.icns
- qss/settings.qss
- __pycache__/_generate_resources.cpython-36.pyc
- licenses/fmt_bsd2.txt
- licenses/openssl.txt
- licenses/pajlada_settings.txt
- licenses/qt_lgpl-3.0.txt
- licenses/pajlada_signals.txt
- licenses/rapidjson.txt
- licenses/websocketpp.txt
- licenses/boost_boost.txt
- licenses/libcommuni_BSD3.txt
- settings/aboutlogo.png
- settings/behave.svg
- settings/accounts.svg
- settings/about.svg
- settings/notifications.svg
- settings/commands.svg
- settings/theme.svg
- split/up.png
- split/left.png
- split/move.png
- split/right.png
- split/down.png
- buttons/unban.png
- buttons/menuDark.png
- buttons/mod.png
- buttons/emote.svg
- buttons/modModeEnabled2.png
+ avatars/fourtf.png
+ avatars/pajlada.png
+ buttons/addSplitDark.png
buttons/ban.png
- buttons/unmod.png
+ buttons/banRed.png
+ buttons/emote.svg
buttons/emoteDark.svg
- buttons/updateError.png
+ buttons/menuDark.png
+ buttons/menuLight.png
+ buttons/mod.png
buttons/modModeDisabled.png
buttons/modModeDisabled2.png
buttons/modModeEnabled.png
- buttons/menuLight.png
- buttons/update.png
+ buttons/modModeEnabled2.png
buttons/timeout.png
- buttons/banRed.png
+ buttons/unban.png
+ buttons/unmod.png
+ buttons/update.png
+ buttons/updateError.png
+ licenses/boost_boost.txt
+ licenses/emoji-data-source.txt
+ licenses/fmt_bsd2.txt
+ licenses/libcommuni_BSD3.txt
+ licenses/openssl.txt
+ licenses/pajlada_settings.txt
+ licenses/pajlada_signals.txt
+ licenses/qt_lgpl-3.0.txt
+ licenses/rapidjson.txt
+ licenses/websocketpp.txt
+ qss/settings.qss
+ settings/about.svg
+ settings/aboutlogo.png
+ settings/accounts.svg
+ settings/behave.svg
+ settings/commands.svg
+ settings/emote.svg
+ settings/notifications.svg
+ settings/theme.svg
sounds/ping2.wav
- twitch/prime.png
- twitch/verified.png
+ split/down.png
+ split/left.png
+ split/move.png
+ split/right.png
+ split/up.png
twitch/admin.png
+ twitch/broadcaster.png
+ twitch/cheer1.png
+ twitch/globalmod.png
+ twitch/moderator.png
+ twitch/prime.png
+ twitch/staff.png
twitch/subscriber.png
twitch/turbo.png
- twitch/moderator.png
- twitch/globalmod.png
- twitch/cheer1.png
- twitch/broadcaster.png
- twitch/staff.png
- avatars/fourtf.png
- avatars/pajlada.png
+ twitch/verified.png
+ __pycache__/_generate_resources.cpython-36.pyc
\ No newline at end of file
diff --git a/src/autogenerated/ResourcesAutogen.cpp b/src/autogenerated/ResourcesAutogen.cpp
index c5035f2e6..9d67608e8 100644
--- a/src/autogenerated/ResourcesAutogen.cpp
+++ b/src/autogenerated/ResourcesAutogen.cpp
@@ -6,6 +6,7 @@ Resources2::Resources2()
{
this->avatars.fourtf = QPixmap(":/avatars/fourtf.png");
this->avatars.pajlada = QPixmap(":/avatars/pajlada.png");
+ this->buttons.addSplitDark = QPixmap(":/buttons/addSplitDark.png");
this->buttons.ban = QPixmap(":/buttons/ban.png");
this->buttons.banRed = QPixmap(":/buttons/banRed.png");
this->buttons.menuDark = QPixmap(":/buttons/menuDark.png");
diff --git a/src/autogenerated/ResourcesAutogen.hpp b/src/autogenerated/ResourcesAutogen.hpp
index c6adb3576..4a6f9fc4b 100644
--- a/src/autogenerated/ResourcesAutogen.hpp
+++ b/src/autogenerated/ResourcesAutogen.hpp
@@ -3,8 +3,7 @@
namespace chatterino {
-class Resources2 : public Singleton
-{
+class Resources2 : public Singleton {
public:
Resources2();
@@ -13,6 +12,7 @@ public:
QPixmap pajlada;
} avatars;
struct {
+ QPixmap addSplitDark;
QPixmap ban;
QPixmap banRed;
QPixmap menuDark;
diff --git a/src/widgets/Notebook.hpp b/src/widgets/Notebook.hpp
index 022c075a2..b0cb22c9d 100644
--- a/src/widgets/Notebook.hpp
+++ b/src/widgets/Notebook.hpp
@@ -61,9 +61,9 @@ protected:
private:
struct Item {
- NotebookTab *tab;
- QWidget *page;
- QWidget *selectedWidget = nullptr;
+ NotebookTab *tab{};
+ QWidget *page{};
+ QWidget *selectedWidget{};
};
bool containsPage(QWidget *page);
diff --git a/src/widgets/dialogs/EmotePopup.cpp b/src/widgets/dialogs/EmotePopup.cpp
index e04595702..0f3375121 100644
--- a/src/widgets/dialogs/EmotePopup.cpp
+++ b/src/widgets/dialogs/EmotePopup.cpp
@@ -112,7 +112,7 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
{
BenchmarkGuard guard("loadChannel");
- this->setWindowTitle("Emotes from " + _channel->getName());
+ this->setWindowTitle("Emotes in #" + _channel->getName());
auto twitchChannel = dynamic_cast(_channel.get());
if (twitchChannel == nullptr) return;
diff --git a/src/widgets/helper/Button.cpp b/src/widgets/helper/Button.cpp
index 2e035c02c..948fbc6d2 100644
--- a/src/widgets/helper/Button.cpp
+++ b/src/widgets/helper/Button.cpp
@@ -62,6 +62,18 @@ bool Button::getEnable() const
return this->enabled_;
}
+void Button::setEnableMargin(bool value)
+{
+ this->enableMargin_ = value;
+
+ this->update();
+}
+
+bool Button::getEnableMargin() const
+{
+ return this->enableMargin_;
+}
+
qreal Button::getCurrentDimAmount() const
{
return this->dimPixmap_ && !this->mouseOver_ ? 0.7 : 1;
@@ -105,7 +117,7 @@ void Button::paintEvent(QPaintEvent *)
}
QRect rect = this->rect();
- int s = int(6 * this->getScale());
+ int s = this->enableMargin_ ? int(6 * this->getScale()) : 0;
rect.moveLeft(s);
rect.setRight(rect.right() - s - s);
diff --git a/src/widgets/helper/Button.hpp b/src/widgets/helper/Button.hpp
index e75385bcd..b7d3bffa2 100644
--- a/src/widgets/helper/Button.hpp
+++ b/src/widgets/helper/Button.hpp
@@ -41,6 +41,9 @@ public:
void setEnable(bool value);
bool getEnable() const;
+ void setEnableMargin(bool value);
+ bool getEnableMargin() const;
+
void setBorderColor(const QColor &color);
const QColor &getBorderColor() const;
@@ -73,6 +76,7 @@ private:
QColor borderColor_{};
QPixmap pixmap_{};
bool dimPixmap_{true};
+ bool enableMargin_{true};
QPoint mousePos_{};
double hoverMultiplier_{0.0};
QTimer effectTimer_{};
diff --git a/src/widgets/settingspages/LookPage.cpp b/src/widgets/settingspages/LookPage.cpp
index eb2a9ff1c..f153fc876 100644
--- a/src/widgets/settingspages/LookPage.cpp
+++ b/src/widgets/settingspages/LookPage.cpp
@@ -270,12 +270,12 @@ void LookPage::addEmoteTab(LayoutCreator layout)
void LookPage::addSplitHeaderTab(LayoutCreator layout)
{
- layout.append(this->createCheckBox("Show viewer count",
- getSettings()->showViewerCount));
- layout.append(this->createCheckBox("Show title", getSettings()->showTitle));
- layout.append(this->createCheckBox("Show game", getSettings()->showGame));
layout.append(
this->createCheckBox("Show uptime", getSettings()->showUptime));
+ layout.append(this->createCheckBox("Show viewer count",
+ getSettings()->showViewerCount));
+ layout.append(this->createCheckBox("Show game", getSettings()->showGame));
+ layout.append(this->createCheckBox("Show title", getSettings()->showTitle));
layout->addStretch(1);
}
diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp
index 01a2faaad..856e8ffd7 100644
--- a/src/widgets/splits/Split.cpp
+++ b/src/widgets/splits/Split.cpp
@@ -363,6 +363,12 @@ void Split::handleModifiers(Qt::KeyboardModifiers modifiers)
}
}
+void Split::setIsTopRightSplit(bool value)
+{
+ this->isTopRightSplit_ = value;
+ this->header_->setAddButtonVisible(value);
+}
+
/// Slots
void Split::addSibling()
{
diff --git a/src/widgets/splits/Split.hpp b/src/widgets/splits/Split.hpp
index 8c4ebf84a..6b7e6d057 100644
--- a/src/widgets/splits/Split.hpp
+++ b/src/widgets/splits/Split.hpp
@@ -65,6 +65,7 @@ public:
void layoutMessages();
void updateGifEmotes();
void updateLastReadMessage();
+ void setIsTopRightSplit(bool value);
void drag();
@@ -106,10 +107,11 @@ private:
NullablePtr selectChannelDialog_;
- bool moderationMode_ = false;
+ bool moderationMode_{};
+ bool isTopRightSplit_{};
- bool isMouseOver_ = false;
- bool isDragging_ = false;
+ bool isMouseOver_{};
+ bool isDragging_{};
pajlada::Signals::Connection channelIDChangedConnection_;
pajlada::Signals::Connection usermodeChangedConnection_;
diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp
index cac6f2dfb..25e932207 100644
--- a/src/widgets/splits/SplitContainer.cpp
+++ b/src/widgets/splits/SplitContainer.cpp
@@ -310,8 +310,33 @@ void SplitContainer::focusSplitRecursive(Node *node, Direction direction)
}
}
+Split *SplitContainer::getTopRightSplit(Node &node)
+{
+ switch (node.getType()) {
+ case Node::_Split:
+ return node.getSplit();
+ case Node::VerticalContainer:
+ if (!node.getChildren().empty())
+ return getTopRightSplit(*node.getChildren().front());
+ break;
+ case Node::HorizontalContainer:
+ if (!node.getChildren().empty())
+ return getTopRightSplit(*node.getChildren().back());
+ break;
+ default:;
+ }
+ return nullptr;
+}
+
void SplitContainer::layout()
{
+ // update top right split
+ auto topRight = this->getTopRightSplit(this->baseNode_);
+ if (this->topRight_) this->topRight_->setIsTopRightSplit(false);
+ this->topRight_ = topRight;
+ if (topRight) this->topRight_->setIsTopRightSplit(true);
+
+ // layout
this->baseNode_.geometry_ = this->rect().adjusted(-1, -1, 0, 0);
std::vector _dropRects;
diff --git a/src/widgets/splits/SplitContainer.hpp b/src/widgets/splits/SplitContainer.hpp
index 1f0a2e701..1f90e99aa 100644
--- a/src/widgets/splits/SplitContainer.hpp
+++ b/src/widgets/splits/SplitContainer.hpp
@@ -219,6 +219,7 @@ private:
void addSplit(Split *split);
void decodeNodeRecusively(QJsonObject &obj, Node *node);
+ Split *getTopRightSplit(Node &node);
struct DropRegion {
QRect rect;
@@ -239,6 +240,7 @@ private:
Node baseNode_;
Split *selected_;
+ Split *topRight_{};
NotebookTab *tab_;
std::vector splits_;
diff --git a/src/widgets/splits/SplitHeader.cpp b/src/widgets/splits/SplitHeader.cpp
index 53f64e50e..ab90a39d4 100644
--- a/src/widgets/splits/SplitHeader.cpp
+++ b/src/widgets/splits/SplitHeader.cpp
@@ -92,11 +92,11 @@ namespace {
title += " (live)";
// description
+ if (settings.showUptime) title += " - " + s.uptime;
if (settings.showViewerCount)
title += " - " + QString::number(s.viewerCount);
- if (settings.showTitle) title += " - " + s.title;
if (settings.showGame) title += " - " + s.game;
- if (settings.showUptime) title += " - " + s.uptime;
+ if (settings.showTitle) title += " - " + s.title;
return title;
}
@@ -137,33 +137,42 @@ SplitHeader::SplitHeader(Split *_split)
void SplitHeader::initializeLayout()
{
- auto layout = makeLayout(
- {// title
- this->titleLabel = makeWidget