added add split button

This commit is contained in:
fourtf 2018-09-04 21:39:54 +02:00
parent 3f4e9cdf91
commit 1d682c4a93
17 changed files with 169 additions and 96 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
__pycache__/
# C++ objects and libs # C++ objects and libs
*.slo *.slo

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

View file

@ -1,64 +1,67 @@
<RCC> <RCC>
<qresource prefix="/"> <file>pajaDank.png</file> <qresource prefix="/"> <file>chatterino2.icns</file>
<file>icon.png</file>
<file>emojidata.txt</file>
<file>contributors.txt</file> <file>contributors.txt</file>
<file>error.png</file>
<file>emoji.json</file> <file>emoji.json</file>
<file>emojidata.txt</file>
<file>error.png</file>
<file>icon.ico</file> <file>icon.ico</file>
<file>icon.png</file>
<file>pajaDank.png</file>
<file>tlds.txt</file> <file>tlds.txt</file>
<file>chatterino2.icns</file> <file>avatars/fourtf.png</file>
<file>qss/settings.qss</file> <file>avatars/pajlada.png</file>
<file>__pycache__/_generate_resources.cpython-36.pyc</file> <file>buttons/addSplitDark.png</file>
<file>licenses/fmt_bsd2.txt</file>
<file>licenses/openssl.txt</file>
<file>licenses/pajlada_settings.txt</file>
<file>licenses/qt_lgpl-3.0.txt</file>
<file>licenses/pajlada_signals.txt</file>
<file>licenses/rapidjson.txt</file>
<file>licenses/websocketpp.txt</file>
<file>licenses/boost_boost.txt</file>
<file>licenses/libcommuni_BSD3.txt</file>
<file>settings/aboutlogo.png</file>
<file>settings/behave.svg</file>
<file>settings/accounts.svg</file>
<file>settings/about.svg</file>
<file>settings/notifications.svg</file>
<file>settings/commands.svg</file>
<file>settings/theme.svg</file>
<file>split/up.png</file>
<file>split/left.png</file>
<file>split/move.png</file>
<file>split/right.png</file>
<file>split/down.png</file>
<file>buttons/unban.png</file>
<file>buttons/menuDark.png</file>
<file>buttons/mod.png</file>
<file>buttons/emote.svg</file>
<file>buttons/modModeEnabled2.png</file>
<file>buttons/ban.png</file> <file>buttons/ban.png</file>
<file>buttons/unmod.png</file> <file>buttons/banRed.png</file>
<file>buttons/emote.svg</file>
<file>buttons/emoteDark.svg</file> <file>buttons/emoteDark.svg</file>
<file>buttons/updateError.png</file> <file>buttons/menuDark.png</file>
<file>buttons/menuLight.png</file>
<file>buttons/mod.png</file>
<file>buttons/modModeDisabled.png</file> <file>buttons/modModeDisabled.png</file>
<file>buttons/modModeDisabled2.png</file> <file>buttons/modModeDisabled2.png</file>
<file>buttons/modModeEnabled.png</file> <file>buttons/modModeEnabled.png</file>
<file>buttons/menuLight.png</file> <file>buttons/modModeEnabled2.png</file>
<file>buttons/update.png</file>
<file>buttons/timeout.png</file> <file>buttons/timeout.png</file>
<file>buttons/banRed.png</file> <file>buttons/unban.png</file>
<file>buttons/unmod.png</file>
<file>buttons/update.png</file>
<file>buttons/updateError.png</file>
<file>licenses/boost_boost.txt</file>
<file>licenses/emoji-data-source.txt</file>
<file>licenses/fmt_bsd2.txt</file>
<file>licenses/libcommuni_BSD3.txt</file>
<file>licenses/openssl.txt</file>
<file>licenses/pajlada_settings.txt</file>
<file>licenses/pajlada_signals.txt</file>
<file>licenses/qt_lgpl-3.0.txt</file>
<file>licenses/rapidjson.txt</file>
<file>licenses/websocketpp.txt</file>
<file>qss/settings.qss</file>
<file>settings/about.svg</file>
<file>settings/aboutlogo.png</file>
<file>settings/accounts.svg</file>
<file>settings/behave.svg</file>
<file>settings/commands.svg</file>
<file>settings/emote.svg</file>
<file>settings/notifications.svg</file>
<file>settings/theme.svg</file>
<file>sounds/ping2.wav</file> <file>sounds/ping2.wav</file>
<file>twitch/prime.png</file> <file>split/down.png</file>
<file>twitch/verified.png</file> <file>split/left.png</file>
<file>split/move.png</file>
<file>split/right.png</file>
<file>split/up.png</file>
<file>twitch/admin.png</file> <file>twitch/admin.png</file>
<file>twitch/broadcaster.png</file>
<file>twitch/cheer1.png</file>
<file>twitch/globalmod.png</file>
<file>twitch/moderator.png</file>
<file>twitch/prime.png</file>
<file>twitch/staff.png</file>
<file>twitch/subscriber.png</file> <file>twitch/subscriber.png</file>
<file>twitch/turbo.png</file> <file>twitch/turbo.png</file>
<file>twitch/moderator.png</file> <file>twitch/verified.png</file>
<file>twitch/globalmod.png</file> <file>__pycache__/_generate_resources.cpython-36.pyc</file>
<file>twitch/cheer1.png</file>
<file>twitch/broadcaster.png</file>
<file>twitch/staff.png</file>
<file>avatars/fourtf.png</file>
<file>avatars/pajlada.png</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -6,6 +6,7 @@ Resources2::Resources2()
{ {
this->avatars.fourtf = QPixmap(":/avatars/fourtf.png"); this->avatars.fourtf = QPixmap(":/avatars/fourtf.png");
this->avatars.pajlada = QPixmap(":/avatars/pajlada.png"); this->avatars.pajlada = QPixmap(":/avatars/pajlada.png");
this->buttons.addSplitDark = QPixmap(":/buttons/addSplitDark.png");
this->buttons.ban = QPixmap(":/buttons/ban.png"); this->buttons.ban = QPixmap(":/buttons/ban.png");
this->buttons.banRed = QPixmap(":/buttons/banRed.png"); this->buttons.banRed = QPixmap(":/buttons/banRed.png");
this->buttons.menuDark = QPixmap(":/buttons/menuDark.png"); this->buttons.menuDark = QPixmap(":/buttons/menuDark.png");

View file

@ -3,8 +3,7 @@
namespace chatterino { namespace chatterino {
class Resources2 : public Singleton class Resources2 : public Singleton {
{
public: public:
Resources2(); Resources2();
@ -13,6 +12,7 @@ public:
QPixmap pajlada; QPixmap pajlada;
} avatars; } avatars;
struct { struct {
QPixmap addSplitDark;
QPixmap ban; QPixmap ban;
QPixmap banRed; QPixmap banRed;
QPixmap menuDark; QPixmap menuDark;

View file

@ -61,9 +61,9 @@ protected:
private: private:
struct Item { struct Item {
NotebookTab *tab; NotebookTab *tab{};
QWidget *page; QWidget *page{};
QWidget *selectedWidget = nullptr; QWidget *selectedWidget{};
}; };
bool containsPage(QWidget *page); bool containsPage(QWidget *page);

View file

@ -112,7 +112,7 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
{ {
BenchmarkGuard guard("loadChannel"); BenchmarkGuard guard("loadChannel");
this->setWindowTitle("Emotes from " + _channel->getName()); this->setWindowTitle("Emotes in #" + _channel->getName());
auto twitchChannel = dynamic_cast<TwitchChannel *>(_channel.get()); auto twitchChannel = dynamic_cast<TwitchChannel *>(_channel.get());
if (twitchChannel == nullptr) return; if (twitchChannel == nullptr) return;

View file

@ -62,6 +62,18 @@ bool Button::getEnable() const
return this->enabled_; return this->enabled_;
} }
void Button::setEnableMargin(bool value)
{
this->enableMargin_ = value;
this->update();
}
bool Button::getEnableMargin() const
{
return this->enableMargin_;
}
qreal Button::getCurrentDimAmount() const qreal Button::getCurrentDimAmount() const
{ {
return this->dimPixmap_ && !this->mouseOver_ ? 0.7 : 1; return this->dimPixmap_ && !this->mouseOver_ ? 0.7 : 1;
@ -105,7 +117,7 @@ void Button::paintEvent(QPaintEvent *)
} }
QRect rect = this->rect(); QRect rect = this->rect();
int s = int(6 * this->getScale()); int s = this->enableMargin_ ? int(6 * this->getScale()) : 0;
rect.moveLeft(s); rect.moveLeft(s);
rect.setRight(rect.right() - s - s); rect.setRight(rect.right() - s - s);

View file

@ -41,6 +41,9 @@ public:
void setEnable(bool value); void setEnable(bool value);
bool getEnable() const; bool getEnable() const;
void setEnableMargin(bool value);
bool getEnableMargin() const;
void setBorderColor(const QColor &color); void setBorderColor(const QColor &color);
const QColor &getBorderColor() const; const QColor &getBorderColor() const;
@ -73,6 +76,7 @@ private:
QColor borderColor_{}; QColor borderColor_{};
QPixmap pixmap_{}; QPixmap pixmap_{};
bool dimPixmap_{true}; bool dimPixmap_{true};
bool enableMargin_{true};
QPoint mousePos_{}; QPoint mousePos_{};
double hoverMultiplier_{0.0}; double hoverMultiplier_{0.0};
QTimer effectTimer_{}; QTimer effectTimer_{};

View file

@ -270,12 +270,12 @@ void LookPage::addEmoteTab(LayoutCreator<QVBoxLayout> layout)
void LookPage::addSplitHeaderTab(LayoutCreator<QVBoxLayout> layout) void LookPage::addSplitHeaderTab(LayoutCreator<QVBoxLayout> 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( layout.append(
this->createCheckBox("Show uptime", getSettings()->showUptime)); 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); layout->addStretch(1);
} }

View file

@ -363,6 +363,12 @@ void Split::handleModifiers(Qt::KeyboardModifiers modifiers)
} }
} }
void Split::setIsTopRightSplit(bool value)
{
this->isTopRightSplit_ = value;
this->header_->setAddButtonVisible(value);
}
/// Slots /// Slots
void Split::addSibling() void Split::addSibling()
{ {

View file

@ -65,6 +65,7 @@ public:
void layoutMessages(); void layoutMessages();
void updateGifEmotes(); void updateGifEmotes();
void updateLastReadMessage(); void updateLastReadMessage();
void setIsTopRightSplit(bool value);
void drag(); void drag();
@ -106,10 +107,11 @@ private:
NullablePtr<SelectChannelDialog> selectChannelDialog_; NullablePtr<SelectChannelDialog> selectChannelDialog_;
bool moderationMode_ = false; bool moderationMode_{};
bool isTopRightSplit_{};
bool isMouseOver_ = false; bool isMouseOver_{};
bool isDragging_ = false; bool isDragging_{};
pajlada::Signals::Connection channelIDChangedConnection_; pajlada::Signals::Connection channelIDChangedConnection_;
pajlada::Signals::Connection usermodeChangedConnection_; pajlada::Signals::Connection usermodeChangedConnection_;

View file

@ -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() 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); this->baseNode_.geometry_ = this->rect().adjusted(-1, -1, 0, 0);
std::vector<DropRect> _dropRects; std::vector<DropRect> _dropRects;

View file

@ -219,6 +219,7 @@ private:
void addSplit(Split *split); void addSplit(Split *split);
void decodeNodeRecusively(QJsonObject &obj, Node *node); void decodeNodeRecusively(QJsonObject &obj, Node *node);
Split *getTopRightSplit(Node &node);
struct DropRegion { struct DropRegion {
QRect rect; QRect rect;
@ -239,6 +240,7 @@ private:
Node baseNode_; Node baseNode_;
Split *selected_; Split *selected_;
Split *topRight_{};
NotebookTab *tab_; NotebookTab *tab_;
std::vector<Split *> splits_; std::vector<Split *> splits_;

View file

@ -92,11 +92,11 @@ namespace {
title += " (live)"; title += " (live)";
// description // description
if (settings.showUptime) title += " - " + s.uptime;
if (settings.showViewerCount) if (settings.showViewerCount)
title += " - " + QString::number(s.viewerCount); title += " - " + QString::number(s.viewerCount);
if (settings.showTitle) title += " - " + s.title;
if (settings.showGame) title += " - " + s.game; if (settings.showGame) title += " - " + s.game;
if (settings.showUptime) title += " - " + s.uptime; if (settings.showTitle) title += " - " + s.title;
return title; return title;
} }
@ -137,33 +137,42 @@ SplitHeader::SplitHeader(Split *_split)
void SplitHeader::initializeLayout() void SplitHeader::initializeLayout()
{ {
auto layout = makeLayout<QHBoxLayout>( auto layout = makeLayout<QHBoxLayout>({
{// title // title
this->titleLabel = makeWidget<Label>([](auto w) { this->titleLabel_ = makeWidget<Label>([](auto w) {
w->setSizePolicy(QSizePolicy::MinimumExpanding, w->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::Preferred); QSizePolicy::Preferred);
w->setCentered(true); w->setCentered(true);
w->setHasOffset(false); w->setHasOffset(false);
}), }),
// mode // mode
this->modeButton_ = makeWidget<EffectLabel>([&](auto w) { this->modeButton_ = makeWidget<EffectLabel>([&](auto w) {
w->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); w->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
w->hide(); w->hide();
this->initializeModeSignals(*w); this->initializeModeSignals(*w);
w->setMenu(this->createChatModeMenu()); w->setMenu(this->createChatModeMenu());
}), }),
// moderator // moderator
this->moderationButton_ = makeWidget<Button>([&](auto w) { this->moderationButton_ = makeWidget<Button>([&](auto w) {
QObject::connect(w, &Button::clicked, this, [this, w]() mutable { QObject::connect(w, &Button::clicked, this, [this, w]() mutable {
this->split_->setModerationMode( this->split_->setModerationMode(
!this->split_->getModerationMode()); !this->split_->getModerationMode());
w->setDim(!this->split_->getModerationMode()); w->setDim(!this->split_->getModerationMode());
}); });
}), }),
// dropdown // dropdown
this->dropdownButton_ = makeWidget<Button>( this->dropdownButton_ = makeWidget<Button>(
[&](auto w) { w->setMenu(this->createMainMenu()); })}); [&](auto w) { w->setMenu(this->createMainMenu()); }),
// add split
this->addButton_ = makeWidget<Button>([&](auto w) {
w->setPixmap(getApp()->resources->buttons.addSplitDark);
w->setEnableMargin(false);
QObject::connect(w, &Button::clicked, this,
[this]() { this->split_->addSibling(); });
}),
});
layout->setMargin(0); layout->setMargin(0);
layout->setSpacing(0); layout->setSpacing(0);
@ -173,18 +182,16 @@ void SplitHeader::initializeLayout()
std::unique_ptr<QMenu> SplitHeader::createMainMenu() std::unique_ptr<QMenu> SplitHeader::createMainMenu()
{ {
auto menu = std::make_unique<QMenu>(); auto menu = std::make_unique<QMenu>();
menu->addAction("Add new", this->split_, &Split::addSibling, menu->addAction("Close channel", this->split_, &Split::deleteFromContainer,
QKeySequence("Ctrl+T"));
menu->addAction("Close", this->split_, &Split::deleteFromContainer,
QKeySequence("Ctrl+W")); QKeySequence("Ctrl+W"));
menu->addAction("Change channel", this->split_, &Split::changeChannel, menu->addAction("Change channel", this->split_, &Split::changeChannel,
QKeySequence("Ctrl+R")); QKeySequence("Ctrl+R"));
menu->addSeparator(); menu->addSeparator();
menu->addAction("Popup", this->split_, &Split::popup);
menu->addAction("Viewer list", this->split_, &Split::showViewerList); menu->addAction("Viewer list", this->split_, &Split::showViewerList);
menu->addAction("Search", this->split_, &Split::showSearch, menu->addAction("Search", this->split_, &Split::showSearch,
QKeySequence("Ctrl+F")); QKeySequence("Ctrl+F"));
menu->addSeparator(); menu->addSeparator();
menu->addAction("Popup", this->split_, &Split::popup);
#ifdef USEWEBENGINE #ifdef USEWEBENGINE
this->dropdownMenu.addAction("Start watching", this, [this] { this->dropdownMenu.addAction("Start watching", this, [this] {
ChannelPtr _channel = this->split->getChannel(); ChannelPtr _channel = this->split->getChannel();
@ -334,6 +341,12 @@ void SplitHeader::scaleChangedEvent(float scale)
this->setFixedHeight(w); this->setFixedHeight(w);
this->dropdownButton_->setFixedWidth(w); this->dropdownButton_->setFixedWidth(w);
this->moderationButton_->setFixedWidth(w); this->moderationButton_->setFixedWidth(w);
this->addButton_->setFixedWidth(w * 5 / 8);
}
void SplitHeader::setAddButtonVisible(bool value)
{
this->addButton_->setVisible(value);
} }
void SplitHeader::updateChannelText() void SplitHeader::updateChannelText()
@ -358,7 +371,7 @@ void SplitHeader::updateChannelText()
} }
} }
this->titleLabel->setText(title.isEmpty() ? "<empty>" : title); this->titleLabel_->setText(title.isEmpty() ? "<empty>" : title);
} }
void SplitHeader::updateModerationModeIcon() void SplitHeader::updateModerationModeIcon()
@ -484,7 +497,7 @@ void SplitHeader::themeChangedEvent()
} else { } else {
palette.setColor(QPalette::Foreground, this->theme->splits.header.text); palette.setColor(QPalette::Foreground, this->theme->splits.header.text);
} }
this->titleLabel->setPalette(palette); this->titleLabel_->setPalette(palette);
// -- // --
if (this->theme->isLightTheme()) { if (this->theme->isLightTheme()) {

View file

@ -24,6 +24,8 @@ class SplitHeader final : public BaseWidget, pajlada::Signals::SignalHolder
public: public:
explicit SplitHeader(Split *_chatWidget); explicit SplitHeader(Split *_chatWidget);
void setAddButtonVisible(bool value);
void updateChannelText(); void updateChannelText();
void updateModerationModeIcon(); void updateModerationModeIcon();
void updateRoomModes(); void updateRoomModes();
@ -53,9 +55,10 @@ private:
// ui // ui
Button *dropdownButton_{}; Button *dropdownButton_{};
Label *titleLabel{}; Label *titleLabel_{};
EffectLabel *modeButton_{}; EffectLabel *modeButton_{};
Button *moderationButton_{}; Button *moderationButton_{};
Button *addButton_{};
// states // states
QPoint dragStart_{}; QPoint dragStart_{};