diff --git a/resources/images/moderatormode_disabled.png b/resources/images/moderatormode_disabled.png
new file mode 100644
index 000000000..b0a063072
Binary files /dev/null and b/resources/images/moderatormode_disabled.png differ
diff --git a/resources/images/moderatormode_enabled.png b/resources/images/moderatormode_enabled.png
new file mode 100644
index 000000000..a563c4ba4
Binary files /dev/null and b/resources/images/moderatormode_enabled.png differ
diff --git a/resources/resources.qrc b/resources/resources.qrc
index 73976001b..cb535c604 100644
--- a/resources/resources.qrc
+++ b/resources/resources.qrc
@@ -44,6 +44,8 @@
images/commands.svg
images/aboutlogo.png
images/about.svg
+ images/moderatormode_disabled.png
+ images/moderatormode_enabled.png
qt.conf
diff --git a/src/messages/layouts/messagelayout.cpp b/src/messages/layouts/messagelayout.cpp
index acddd5e56..af4909ca9 100644
--- a/src/messages/layouts/messagelayout.cpp
+++ b/src/messages/layouts/messagelayout.cpp
@@ -61,7 +61,7 @@ void MessageLayout::removeFlags(Flags _flags)
// Layout
// return true if redraw is required
-bool MessageLayout::layout(int width, float scale)
+bool MessageLayout::layout(int width, float scale, MessageElement::Flags flags)
{
auto &emoteManager = singletons::EmoteManager::getInstance();
@@ -114,20 +114,20 @@ bool MessageLayout::layout(int width, float scale)
return false;
}
- this->actuallyLayout(width);
+ this->actuallyLayout(width, flags);
this->invalidateBuffer();
return true;
}
-void MessageLayout::actuallyLayout(int width)
+void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags)
{
this->container.clear();
this->container.width = width;
this->container.scale = this->scale;
for (const std::unique_ptr &element : this->message->getElements()) {
- element->addToContainer(this->container, MessageElement::Default);
+ element->addToContainer(this->container, flags);
}
if (this->height != this->container.getHeight()) {
diff --git a/src/messages/layouts/messagelayout.hpp b/src/messages/layouts/messagelayout.hpp
index 08fac98e7..7792c1f6b 100644
--- a/src/messages/layouts/messagelayout.hpp
+++ b/src/messages/layouts/messagelayout.hpp
@@ -38,7 +38,7 @@ public:
void removeFlags(Flags flags);
// Layout
- bool layout(int width, float scale);
+ bool layout(int width, float scale, MessageElement::Flags flags);
// Painting
void paint(QPainter &painter, int y, int messageIndex, Selection &selection);
@@ -75,7 +75,7 @@ private:
int collapsedHeight = 32;
// methods
- void actuallyLayout(int width);
+ void actuallyLayout(int width, MessageElement::Flags flags);
void updateBuffer(QPixmap *pixmap, int messageIndex, Selection &selection);
};
diff --git a/src/messages/messageelement.cpp b/src/messages/messageelement.cpp
index 94ea99d10..193ae3c4b 100644
--- a/src/messages/messageelement.cpp
+++ b/src/messages/messageelement.cpp
@@ -68,10 +68,6 @@ void ImageElement::addToContainer(MessageLayoutContainer &container, MessageElem
(new ImageLayoutElement(*this, this->image, size))->setLink(this->getLink()));
}
-void ImageElement::update(UpdateFlags _flags)
-{
-}
-
// EMOTE
EmoteElement::EmoteElement(const util::EmoteData &_data, MessageElement::Flags flags)
: MessageElement(flags)
@@ -106,10 +102,6 @@ void EmoteElement::addToContainer(MessageLayoutContainer &container, MessageElem
container.addElement((new ImageLayoutElement(*this, _image, size))->setLink(this->getLink()));
}
-void EmoteElement::update(UpdateFlags _flags)
-{
-}
-
// TEXT
TextElement::TextElement(const QString &text, MessageElement::Flags flags,
const MessageColor &_color, FontStyle _style)
@@ -195,15 +187,6 @@ void TextElement::addToContainer(MessageLayoutContainer &container, MessageEleme
}
}
-void TextElement::update(UpdateFlags _flags)
-{
- if (_flags & UpdateFlags::Update_Text) {
- for (Word &word : this->words) {
- word.width = -1;
- }
- }
-}
-
// TIMESTAMP
TimestampElement::TimestampElement()
: TimestampElement(QTime::currentTime())
@@ -235,11 +218,6 @@ void TimestampElement::addToContainer(MessageLayoutContainer &container,
this->element->addToContainer(container, _flags);
}
-void TimestampElement::update(UpdateFlags _flags)
-{
- this->element->update(_flags);
-}
-
TextElement *TimestampElement::formatTime(const QTime &time)
{
QString format = time.toString(singletons::SettingManager::getInstance().timestampFormat);
@@ -256,23 +234,24 @@ TwitchModerationElement::TwitchModerationElement()
void TwitchModerationElement::addToContainer(MessageLayoutContainer &container,
MessageElement::Flags _flags)
{
- QSize size((int)(container.scale * 16), (int)(container.scale * 16));
+ qDebug() << _flags;
- for (const singletons::ModerationAction &m :
- singletons::SettingManager::getInstance().getModerationActions()) {
- if (m.isImage()) {
- container.addElement((new ImageLayoutElement(*this, m.getImage(), size))
- ->setLink(Link(Link::UserAction, m.getAction())));
- } else {
- container.addElement((new TextIconLayoutElement(*this, m.getLine1(), m.getLine2(),
- container.scale, size))
- ->setLink(Link(Link::UserAction, m.getAction())));
+ if (_flags & MessageElement::ModeratorTools) {
+ QSize size((int)(container.scale * 16), (int)(container.scale * 16));
+
+ for (const singletons::ModerationAction &m :
+ singletons::SettingManager::getInstance().getModerationActions()) {
+ if (m.isImage()) {
+ container.addElement((new ImageLayoutElement(*this, m.getImage(), size))
+ ->setLink(Link(Link::UserAction, m.getAction())));
+ } else {
+ container.addElement((new TextIconLayoutElement(*this, m.getLine1(), m.getLine2(),
+ container.scale, size))
+ ->setLink(Link(Link::UserAction, m.getAction())));
+ }
}
}
}
-void TwitchModerationElement::update(UpdateFlags _flags)
-{
-}
} // namespace messages
} // namespace chatterino
diff --git a/src/messages/messageelement.hpp b/src/messages/messageelement.hpp
index 33cd09edb..dd3e7c482 100644
--- a/src/messages/messageelement.hpp
+++ b/src/messages/messageelement.hpp
@@ -122,7 +122,6 @@ public:
Flags getFlags() const;
virtual void addToContainer(MessageLayoutContainer &container, MessageElement::Flags flags) = 0;
- virtual void update(UpdateFlags flags) = 0;
protected:
MessageElement(Flags flags);
@@ -144,7 +143,6 @@ public:
virtual void addToContainer(MessageLayoutContainer &container,
MessageElement::Flags flags) override;
- virtual void update(UpdateFlags flags) override;
};
// contains emote data and will pick the emote based on :
@@ -159,7 +157,6 @@ public:
virtual void addToContainer(MessageLayoutContainer &container,
MessageElement::Flags flags) override;
- virtual void update(UpdateFlags flags) override;
};
// contains a text, it will split it into words
@@ -181,7 +178,6 @@ public:
virtual void addToContainer(MessageLayoutContainer &container,
MessageElement::Flags flags) override;
- virtual void update(UpdateFlags flags);
};
// contains a text, formated depending on the preferences
@@ -198,7 +194,6 @@ public:
virtual void addToContainer(MessageLayoutContainer &container,
MessageElement::Flags flags) override;
- virtual void update(UpdateFlags flags);
TextElement *formatTime(const QTime &time);
};
@@ -212,7 +207,6 @@ public:
virtual void addToContainer(MessageLayoutContainer &container,
MessageElement::Flags flags) override;
- virtual void update(UpdateFlags flags);
};
// adds bits as text, static image or animated image
diff --git a/src/singletons/resourcemanager.cpp b/src/singletons/resourcemanager.cpp
index 305e66da4..4383d8f14 100644
--- a/src/singletons/resourcemanager.cpp
+++ b/src/singletons/resourcemanager.cpp
@@ -265,7 +265,6 @@ inline void ParseCheermoteSets(std::vector &s
}
} // namespace
-
ResourceManager::ResourceManager()
: badgeStaff(lli(":/images/staff_bg.png"))
, badgeAdmin(lli(":/images/admin_bg.png"))
@@ -285,6 +284,9 @@ ResourceManager::ResourceManager()
, cheerBadge1(lli(":/images/cheer1"))
, buttonBan(lli(":/images/button_ban.png", 0.25))
, buttonTimeout(lli(":/images/button_timeout.png", 0.25))
+ , moderationmode_enabled(lli(":/images/moderatormode_enabled"))
+ , moderationmode_disabled(lli(":/images/moderatormode_disabled"))
+ , splitHeaderContext(lli(":/images/tool_moreCollapser_off16.png"))
{
this->loadDynamicTwitchBadges();
diff --git a/src/singletons/resourcemanager.hpp b/src/singletons/resourcemanager.hpp
index 7564a8f5b..981aade8f 100644
--- a/src/singletons/resourcemanager.hpp
+++ b/src/singletons/resourcemanager.hpp
@@ -36,6 +36,11 @@ public:
messages::Image *cheerBadge100;
messages::Image *cheerBadge1;
+ messages::Image *moderationmode_enabled;
+ messages::Image *moderationmode_disabled;
+
+ messages::Image *splitHeaderContext;
+
std::map cheerBadges;
struct BadgeVersion {
diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp
index 2184d4612..a58c04bdb 100644
--- a/src/widgets/helper/channelview.cpp
+++ b/src/widgets/helper/channelview.cpp
@@ -153,6 +153,8 @@ void ChannelView::actuallyLayoutMessages()
// (this->scrollBar.isVisible() ? width() - this->scrollBar.width() : width()) - 4;
int layoutWidth = LAYOUT_WIDTH;
+ MessageElement::Flags flags = this->getFlags();
+
// layout the visible messages in the view
if (messagesSnapshot.getLength() > start) {
int y =
@@ -161,7 +163,7 @@ void ChannelView::actuallyLayoutMessages()
for (size_t i = start; i < messagesSnapshot.getLength(); ++i) {
auto message = messagesSnapshot[i];
- redrawRequired |= message->layout(layoutWidth, this->getDpiMultiplier());
+ redrawRequired |= message->layout(layoutWidth, this->getDpiMultiplier(), flags);
y += message->getHeight();
@@ -177,7 +179,7 @@ void ChannelView::actuallyLayoutMessages()
for (int i = (int)messagesSnapshot.getLength() - 1; i >= 0; i--) {
auto *message = messagesSnapshot[i].get();
- message->layout(layoutWidth, this->getDpiMultiplier());
+ message->layout(layoutWidth, this->getDpiMultiplier(), flags);
h -= message->getHeight();
@@ -432,6 +434,21 @@ void ChannelView::setSelection(const SelectionItem &start, const SelectionItem &
// << max.charIndex;
}
+messages::MessageElement::Flags ChannelView::getFlags() const
+{
+ MessageElement::Flags flags = MessageElement::Default;
+
+ Split *split = dynamic_cast(this->parentWidget());
+
+ if (split != nullptr) {
+ if (split->getModerationMode()) {
+ flags = (MessageElement::Flags)(flags | MessageElement::ModeratorTools);
+ }
+ }
+
+ return flags;
+}
+
void ChannelView::paintEvent(QPaintEvent * /*event*/)
{
// BENCH(timer);
@@ -536,7 +553,8 @@ void ChannelView::wheelEvent(QWheelEvent *event)
if (i == 0) {
desired = 0;
} else {
- snapshot[i - 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier());
+ snapshot[i - 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier(),
+ this->getFlags());
scrollFactor = 1;
currentScrollLeft = snapshot[i - 1]->getHeight();
}
@@ -558,7 +576,8 @@ void ChannelView::wheelEvent(QWheelEvent *event)
if (i == snapshotLength - 1) {
desired = snapshot.getLength();
} else {
- snapshot[i + 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier());
+ snapshot[i + 1]->layout(LAYOUT_WIDTH, this->getDpiMultiplier(),
+ this->getFlags());
scrollFactor = 1;
currentScrollLeft = snapshot[i + 1]->getHeight();
diff --git a/src/widgets/helper/channelview.hpp b/src/widgets/helper/channelview.hpp
index 1ed0aa8d1..90cb920c7 100644
--- a/src/widgets/helper/channelview.hpp
+++ b/src/widgets/helper/channelview.hpp
@@ -29,7 +29,7 @@ class ChannelView : public BaseWidget
public:
explicit ChannelView(BaseWidget *parent = 0);
- ~ChannelView();
+ virtual ~ChannelView();
void queueUpdate();
Scrollbar &getScrollBar();
@@ -80,6 +80,7 @@ private:
void drawMessages(QPainter &painter);
void setSelection(const messages::SelectionItem &start, const messages::SelectionItem &end);
+ messages::MessageElement::Flags getFlags() const;
SharedChannel channel;
diff --git a/src/widgets/helper/rippleeffectbutton.cpp b/src/widgets/helper/rippleeffectbutton.cpp
index 2c25dcb83..a2c46c8fe 100644
--- a/src/widgets/helper/rippleeffectbutton.cpp
+++ b/src/widgets/helper/rippleeffectbutton.cpp
@@ -10,7 +10,7 @@ namespace widgets {
RippleEffectButton::RippleEffectButton(BaseWidget *parent)
: BaseWidget(parent)
-
+ , pixmap(nullptr)
{
connect(&effectTimer, &QTimer::timeout, this, &RippleEffectButton::onMouseEffectTimeout);
@@ -23,11 +23,36 @@ void RippleEffectButton::setMouseEffectColor(boost::optional color)
this->mouseEffectColor = color;
}
+void RippleEffectButton::setPixmap(const QPixmap *_pixmap)
+{
+ this->pixmap = const_cast(_pixmap);
+ this->update();
+}
+
+const QPixmap *RippleEffectButton::getPixmap() const
+{
+ return this->pixmap;
+}
+
void RippleEffectButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+
this->fancyPaint(painter);
+
+ if (this->pixmap != nullptr) {
+ QRect rect = this->rect();
+ int xD = 6 * this->getDpiMultiplier();
+
+ rect.moveLeft(xD);
+ rect.setRight(rect.right() - xD - xD);
+ rect.moveTop(xD);
+ rect.setBottom(rect.bottom() - xD - xD);
+
+ painter.drawPixmap(rect, *this->pixmap);
+ }
}
void RippleEffectButton::fancyPaint(QPainter &painter)
diff --git a/src/widgets/helper/rippleeffectbutton.hpp b/src/widgets/helper/rippleeffectbutton.hpp
index cc4bf9239..5806ff4a4 100644
--- a/src/widgets/helper/rippleeffectbutton.hpp
+++ b/src/widgets/helper/rippleeffectbutton.hpp
@@ -31,6 +31,8 @@ public:
RippleEffectButton(BaseWidget *parent);
void setMouseEffectColor(boost::optional color);
+ void setPixmap(const QPixmap *pixmap);
+ const QPixmap *getPixmap() const;
signals:
void clicked();
@@ -50,6 +52,7 @@ protected:
void fancyPaint(QPainter &painter);
private:
+ QPixmap *pixmap;
QPoint mousePos;
double hoverMultiplier = 0.0;
QTimer effectTimer;
diff --git a/src/widgets/helper/splitheader.cpp b/src/widgets/helper/splitheader.cpp
index 8683f85c6..d60015855 100644
--- a/src/widgets/helper/splitheader.cpp
+++ b/src/widgets/helper/splitheader.cpp
@@ -1,4 +1,5 @@
#include "widgets/helper/splitheader.hpp"
+#include "singletons/resourcemanager.hpp"
#include "singletons/thememanager.hpp"
#include "twitch/twitchchannel.hpp"
#include "util/layoutcreator.hpp"
@@ -21,20 +22,20 @@ SplitHeader::SplitHeader(Split *_split)
{
this->setMouseTracking(true);
+ singletons::ResourceManager &resourceManager = singletons::ResourceManager::getInstance();
+
util::LayoutCreator layoutCreator(this);
auto layout = layoutCreator.emplace().withoutMargin();
{
// dropdown label
- auto dropdown = layout.emplace(this).assign(&this->dropdownLabel);
- dropdown->getLabel().setTextFormat(Qt::RichText);
- dropdown->getLabel().setText("
");
- dropdown->getLabel().setScaledContents(true);
+ auto dropdown = layout.emplace(this).assign(&this->dropdownButton);
dropdown->setMouseTracking(true);
+ dropdown->setPixmap(resourceManager.splitHeaderContext->getPixmap());
this->addDropdownItems(dropdown.getElement());
- QObject::connect(dropdown.getElement(), &RippleEffectLabel::clicked, this, [this] {
+ QObject::connect(dropdown.getElement(), &RippleEffectButton::clicked, this, [this] {
QTimer::singleShot(80, [&] {
this->dropdownMenu.move(
- this->dropdownLabel->mapToGlobal(QPoint(0, this->dropdownLabel->height())));
+ this->dropdownButton->mapToGlobal(QPoint(0, this->dropdownButton->height())));
this->dropdownMenu.show();
});
});
@@ -50,11 +51,13 @@ SplitHeader::SplitHeader(Split *_split)
layout->addStretch(1);
// moderation mode
- auto moderation = layout.emplace(this).assign(&this->moderationLabel);
- moderation->setMouseTracking(true);
- moderation->getLabel().setScaledContents(true);
- moderation->getLabel().setTextFormat(Qt::RichText);
- moderation->getLabel().setText("
");
+ auto moderator = layout.emplace(this).assign(&this->moderationButton);
+
+ QObject::connect(moderator.getElement(), &RippleEffectButton::clicked, this, [this] {
+ this->split->setModerationMode(!this->split->getModerationMode());
+ });
+
+ this->updateModerationModeIcon();
}
// ---- misc
@@ -63,8 +66,6 @@ SplitHeader::SplitHeader(Split *_split)
this->updateChannelText();
- // this->titleLabel.setAlignment(Qt::AlignCenter);
-
this->initializeChannelSignals();
this->split->channelChanged.connect([this]() {
@@ -77,11 +78,8 @@ SplitHeader::~SplitHeader()
this->onlineStatusChangedConnection.disconnect();
}
-void SplitHeader::addDropdownItems(RippleEffectLabel *label)
+void SplitHeader::addDropdownItems(RippleEffectButton *label)
{
- connect(this->dropdownLabel, &RippleEffectLabel::clicked, this,
- &SplitHeader::leftButtonClicked);
-
// clang-format off
this->dropdownMenu.addAction("Add new split", this->split, &Split::doAddSplit, QKeySequence(tr("Ctrl+T")));
this->dropdownMenu.addAction("Close split", this->split, &Split::doCloseSplit, QKeySequence(tr("Ctrl+W")));
@@ -122,8 +120,8 @@ void SplitHeader::resizeEvent(QResizeEvent *event)
int w = 28 * getDpiMultiplier();
this->setFixedHeight(w);
- this->dropdownLabel->setFixedWidth(w);
- this->moderationLabel->setFixedWidth(w);
+ this->dropdownButton->setFixedWidth(w);
+ this->moderationButton->setFixedWidth(w);
}
void SplitHeader::updateChannelText()
@@ -156,6 +154,14 @@ void SplitHeader::updateChannelText()
}
}
+void SplitHeader::updateModerationModeIcon()
+{
+ singletons::ResourceManager &resourceManager = singletons::ResourceManager::getInstance();
+ this->moderationButton->setPixmap(this->split->getModerationMode()
+ ? resourceManager.moderationmode_enabled->getPixmap()
+ : resourceManager.moderationmode_disabled->getPixmap());
+}
+
void SplitHeader::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@@ -203,10 +209,6 @@ void SplitHeader::mouseDoubleClickEvent(QMouseEvent *event)
}
}
-void SplitHeader::leftButtonClicked()
-{
-}
-
void SplitHeader::rightButtonClicked()
{
}
@@ -216,9 +218,9 @@ void SplitHeader::refreshTheme()
QPalette palette;
palette.setColor(QPalette::Foreground, this->themeManager.splits.header.text);
- this->dropdownLabel->setPalette(palette);
+ // this->dropdownButton->setPalette(palette);
this->titleLabel->setPalette(palette);
- this->moderationLabel->setPalette(palette);
+ // this->moderationLabel->setPalette(palette);
}
void SplitHeader::menuMoveSplit()
diff --git a/src/widgets/helper/splitheader.hpp b/src/widgets/helper/splitheader.hpp
index c0bd04a0f..f72429941 100644
--- a/src/widgets/helper/splitheader.hpp
+++ b/src/widgets/helper/splitheader.hpp
@@ -30,6 +30,7 @@ public:
// Update channel text from chat widget
void updateChannelText();
+ void updateModerationModeIcon();
protected:
virtual void paintEvent(QPaintEvent *) override;
@@ -47,13 +48,12 @@ private:
boost::signals2::connection onlineStatusChangedConnection;
- RippleEffectLabel *dropdownLabel;
+ RippleEffectButton *dropdownButton;
SignalLabel *titleLabel;
- RippleEffectLabel *moderationLabel;
+ RippleEffectButton *moderationButton;
QMenu dropdownMenu;
- void leftButtonClicked();
void rightButtonClicked();
virtual void refreshTheme() override;
@@ -64,7 +64,7 @@ private:
bool isLive;
public slots:
- void addDropdownItems(RippleEffectLabel *label);
+ void addDropdownItems(RippleEffectButton *label);
void menuMoveSplit();
void menuReloadChannelEmotes();
diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp
index 052f2fad4..7307f75cb 100644
--- a/src/widgets/split.cpp
+++ b/src/widgets/split.cpp
@@ -52,6 +52,7 @@ Split::Split(SplitContainer *parent, const std::string &_uuid)
, input(this)
, flexSizeX(1)
, flexSizeY(1)
+ , moderationMode(false)
{
this->setMouseTracking(true);
@@ -115,6 +116,8 @@ Split::Split(SplitContainer *parent, const std::string &_uuid)
this->input.show();
}
});
+
+ this->header.updateModerationModeIcon();
}
Split::~Split()
@@ -168,6 +171,19 @@ double Split::getFlexSizeY()
return this->flexSizeY;
}
+void Split::setModerationMode(bool value)
+{
+ if (value != this->moderationMode) {
+ this->moderationMode = value;
+ this->header.updateModerationModeIcon();
+ }
+}
+
+bool Split::getModerationMode() const
+{
+ return this->moderationMode;
+}
+
void Split::channelNameUpdated(const std::string &newChannelName)
{
auto &cman = singletons::ChannelManager::getInstance();
diff --git a/src/widgets/split.hpp b/src/widgets/split.hpp
index 83587d073..6cab1c932 100644
--- a/src/widgets/split.hpp
+++ b/src/widgets/split.hpp
@@ -62,6 +62,9 @@ public:
void setFlexSizeY(double y);
double getFlexSizeY();
+ void setModerationMode(bool value);
+ bool getModerationMode() const;
+
bool showChangeChannelPopup(const char *dialogTitle, bool empty = false);
void giveFocus(Qt::FocusReason reason);
bool hasFocus() const;
@@ -88,6 +91,8 @@ private:
double flexSizeX;
double flexSizeY;
+ bool moderationMode;
+
boost::signals2::connection channelIDChangedConnection;
void setChannel(SharedChannel newChannel);