From 4de2a6b65fc3fc0915065f95148da0907ede7850 Mon Sep 17 00:00:00 2001 From: fourtf Date: Thu, 24 May 2018 11:35:50 +0200 Subject: [PATCH] added a setting to collapse long messages by default --- src/messages/layouts/messagelayout.cpp | 20 ++++++-- src/messages/layouts/messagelayout.hpp | 4 +- .../layouts/messagelayoutcontainer.cpp | 48 +++++++++++++++++-- .../layouts/messagelayoutcontainer.hpp | 9 +++- src/providers/twitch/twitchmessagebuilder.cpp | 14 +++--- src/singletons/settingsmanager.hpp | 1 + src/widgets/helper/channelview.cpp | 10 ++-- src/widgets/settingspages/appearancepage.cpp | 6 +++ 8 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/messages/layouts/messagelayout.cpp b/src/messages/layouts/messagelayout.cpp index 961511148..f92d4b03b 100644 --- a/src/messages/layouts/messagelayout.cpp +++ b/src/messages/layouts/messagelayout.cpp @@ -107,12 +107,20 @@ bool MessageLayout::layout(int width, float scale, MessageElement::Flags flags) return true; } -void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags) +void MessageLayout::actuallyLayout(int width, MessageElement::Flags _flags) { - this->container.begin(width, this->scale, this->message->flags.value); + auto messageFlags = this->message->flags.value; + + if (this->flags & MessageLayout::Expanded || + (_flags & MessageElement::ModeratorTools && + !(this->message->flags & Message::MessageFlags::Disabled))) { + messageFlags = (Message::MessageFlags)(messageFlags & ~Message::MessageFlags::Collapsed); + } + + this->container.begin(width, this->scale, messageFlags); for (const std::unique_ptr &element : this->message->getElements()) { - element->addToContainer(this->container, flags); + element->addToContainer(this->container, _flags); } if (this->height != this->container.getHeight()) { @@ -121,6 +129,12 @@ void MessageLayout::actuallyLayout(int width, MessageElement::Flags flags) this->container.end(); this->height = this->container.getHeight(); + + // collapsed state + this->flags &= ~Flags::Collapsed; + if (this->container.isCollapsed()) { + this->flags |= Flags::Collapsed; + } } // Painting diff --git a/src/messages/layouts/messagelayout.hpp b/src/messages/layouts/messagelayout.hpp index b6f045a80..9e329fd1a 100644 --- a/src/messages/layouts/messagelayout.hpp +++ b/src/messages/layouts/messagelayout.hpp @@ -22,7 +22,9 @@ public: enum Flags : uint8_t { RequiresBufferUpdate = 1 << 1, RequiresLayout = 1 << 2, - AlternateBackground = 1 << 3 + AlternateBackground = 1 << 3, + Collapsed = 1 << 4, + Expanded = 1 << 5, }; MessageLayout(MessagePtr message); diff --git a/src/messages/layouts/messagelayoutcontainer.cpp b/src/messages/layouts/messagelayoutcontainer.cpp index e5e3b474b..16b109a30 100644 --- a/src/messages/layouts/messagelayoutcontainer.cpp +++ b/src/messages/layouts/messagelayoutcontainer.cpp @@ -9,6 +9,7 @@ #include #define COMPACT_EMOTES_OFFSET 6 +#define MAX_UNCOLLAPSED_LINES 3 namespace chatterino { namespace messages { @@ -39,6 +40,9 @@ void MessageLayoutContainer::begin(int _width, float _scale, Message::MessageFla auto mediumFontMetrics = getApp()->fonts->getFontMetrics(FontStyle::ChatMedium, _scale); this->textLineHeight = mediumFontMetrics.height(); this->spaceWidth = mediumFontMetrics.width(' '); + this->dotdotdotWidth = mediumFontMetrics.width("..."); + this->_canAddMessages = true; + this->_isCollapsed = false; } void MessageLayoutContainer::clear() @@ -71,12 +75,12 @@ void MessageLayoutContainer::addElementNoLineBreak(MessageLayoutElement *element bool MessageLayoutContainer::canAddElements() { - return !(this->flags & Message::MessageFlags::Collapsed && line >= 3); + return this->_canAddMessages; } -void MessageLayoutContainer::_addElement(MessageLayoutElement *element) +void MessageLayoutContainer::_addElement(MessageLayoutElement *element, bool forceAdd) { - if (!this->canAddElements()) { + if (!this->canAddElements() && !forceAdd) { delete element; return; } @@ -154,12 +158,18 @@ void MessageLayoutContainer::breakLine() this->lineStart = this->elements.size(); // this->currentX = (int)(this->scale * 8); + + if (this->canCollapse() && line + 1 >= MAX_UNCOLLAPSED_LINES) { + this->_canAddMessages = false; + return; + } + this->currentX = 0; this->currentY += this->lineHeight; this->height = this->currentY + (this->margin.bottom * this->scale); this->lineHeight = 0; this->line++; -} // namespace layouts +} bool MessageLayoutContainer::atStartOfLine() { @@ -168,15 +178,32 @@ bool MessageLayoutContainer::atStartOfLine() bool MessageLayoutContainer::fitsInLine(int _width) { - return this->currentX + _width <= this->width - this->margin.left - this->margin.right; + return this->currentX + _width <= + (this->width - this->margin.left - this->margin.right - + (this->line + 1 == MAX_UNCOLLAPSED_LINES ? this->dotdotdotWidth : 0)); } void MessageLayoutContainer::end() { + if (!this->canAddElements()) { + static TextElement dotdotdot("...", MessageElement::Collapsed, MessageColor::Link); + static QString dotdotdotText("..."); + + auto *element = new TextLayoutElement( + dotdotdot, dotdotdotText, QSize(this->dotdotdotWidth, this->textLineHeight), + QColor("#00D80A"), FontStyle::ChatMediumBold, this->scale); + + // getApp()->themes->messages.textColors.system + this->_addElement(element, true); + this->_isCollapsed = true; + } + if (!this->atStartOfLine()) { this->breakLine(); } + this->height += this->lineHeight; + if (this->lines.size() != 0) { this->lines[0].rect.setTop(-100000); this->lines.back().rect.setBottom(100000); @@ -185,6 +212,17 @@ void MessageLayoutContainer::end() } } +bool MessageLayoutContainer::canCollapse() +{ + return getApp()->settings->collapseLongMessages.getValue() && + this->flags & Message::MessageFlags::Collapsed; +} + +bool MessageLayoutContainer::isCollapsed() +{ + return this->_isCollapsed; +} + MessageLayoutElement *MessageLayoutContainer::getElementAt(QPoint point) { for (std::unique_ptr &element : this->elements) { diff --git a/src/messages/layouts/messagelayoutcontainer.hpp b/src/messages/layouts/messagelayoutcontainer.hpp index b55c1427c..91e4df1d1 100644 --- a/src/messages/layouts/messagelayoutcontainer.hpp +++ b/src/messages/layouts/messagelayoutcontainer.hpp @@ -76,6 +76,8 @@ struct MessageLayoutContainer { int getLastCharacterIndex() const; void addSelectionText(QString &str, int from, int to); + bool isCollapsed(); + private: struct Line { int startIndex; @@ -86,7 +88,7 @@ private: }; // helpers - void _addElement(MessageLayoutElement *element); + void _addElement(MessageLayoutElement *element, bool forceAdd = false); // variables float scale = 1.f; @@ -101,6 +103,11 @@ private: int lineHeight = 0; int spaceWidth = 4; int textLineHeight = 0; + int dotdotdotWidth = 0; + bool _canAddMessages = true; + bool _isCollapsed = false; + + bool canCollapse(); std::vector> elements; std::vector lines; diff --git a/src/providers/twitch/twitchmessagebuilder.cpp b/src/providers/twitch/twitchmessagebuilder.cpp index 2c6282736..07e2dee00 100644 --- a/src/providers/twitch/twitchmessagebuilder.cpp +++ b/src/providers/twitch/twitchmessagebuilder.cpp @@ -97,12 +97,14 @@ MessagePtr TwitchMessageBuilder::build() // PARSING this->parseUsername(); -#ifdef XD - if (this->originalMessage.length() > 100) { - this->message->flags |= Message::Collapsed; - this->emplace(getApp()->resources->badgeCollapsed, MessageElement::Collapsed); - } -#endif + //#ifdef XD + // if (this->originalMessage.length() > 100) { + // this->message->flags |= Message::Collapsed; + // this->emplace(getApp()->resources->badgeCollapsed, + // MessageElement::Collapsed); + // } + //#endif + this->message->flags |= Message::Collapsed; // PARSING this->parseMessageID(); diff --git a/src/singletons/settingsmanager.hpp b/src/singletons/settingsmanager.hpp index f9b2fcbdd..dcaad8529 100644 --- a/src/singletons/settingsmanager.hpp +++ b/src/singletons/settingsmanager.hpp @@ -40,6 +40,7 @@ public: BoolSetting hideEmptyInput = {"/appearance/hideEmptyInputBox", false}; BoolSetting showMessageLength = {"/appearance/messages/showMessageLength", false}; BoolSetting seperateMessages = {"/appearance/messages/separateMessages", false}; + BoolSetting collapseLongMessages = {"/appearance/messages/collapseLongMessages", false}; BoolSetting alternateMessageBackground = {"/appearance/messages/alternateMessageBackground", false}; BoolSetting windowTopMost = {"/appearance/windowAlwaysOnTop", false}; diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index ecabe9fc9..33d2eb91c 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -778,7 +778,7 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event) } // message under cursor is collapsed - if (layout->getMessage()->flags & Message::Collapsed) { + if (layout->flags & MessageLayout::Collapsed) { this->setCursor(Qt::PointingHandCursor); tooltipWidget->hide(); return; @@ -856,7 +856,7 @@ void ChannelView::mousePressEvent(QMouseEvent *event) } // check if message is collapsed - if (layout->getMessage()->flags & Message::Collapsed) { + if (layout->flags & MessageLayout::Collapsed) { return; } @@ -923,8 +923,8 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event) } // message under cursor is collapsed - if (layout->getMessage()->flags & Message::MessageFlags::Collapsed) { - layout->getMessage()->flags &= ~Message::MessageFlags::Collapsed; + if (layout->flags & MessageLayout::Collapsed) { + layout->flags |= MessageLayout::Expanded; this->layoutMessages(); return; @@ -1038,7 +1038,7 @@ void ChannelView::mouseDoubleClickEvent(QMouseEvent *event) } // message under cursor is collapsed - if (layout->getMessage()->flags & Message::Collapsed) { + if (layout->flags & MessageLayout::Collapsed) { return; } diff --git a/src/widgets/settingspages/appearancepage.cpp b/src/widgets/settingspages/appearancepage.cpp index 0209f031c..1b4472da2 100644 --- a/src/widgets/settingspages/appearancepage.cpp +++ b/src/widgets/settingspages/appearancepage.cpp @@ -77,6 +77,12 @@ AppearancePage::AppearancePage() } messages.append(this->createCheckBox("Show badges", app->settings->showBadges)); + + auto *collapseMessages = this->createCheckBox("Collapse large messages (3+ lines)", + app->settings->collapseLongMessages); + QObject::connect(collapseMessages, &QCheckBox::toggled, + [] { getApp()->windows->layoutVisibleChatWidgets(); }); + messages.append(collapseMessages); { auto checkbox = this->createCheckBox("Seperate messages", app->settings->seperateMessages);