diff --git a/CHANGELOG.md b/CHANGELOG.md index 4182ce03d..0e8e2bcab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unversioned -- Major: Added support for Twitch's Chat Replies. [Wiki Page](https://wiki.chatterino.com/Features/#message-replies) (#3722, #3989, #4041, #4047, #4055, #4067) +- Major: Added support for Twitch's Chat Replies. [Wiki Page](https://wiki.chatterino.com/Features/#message-replies) (#3722, #3989, #4041, #4047, #4055, #4067, #4077) - Major: Added multi-channel searching to search dialog via keyboard shortcut. (Ctrl+Shift+F by default) (#3694, #3875) - Major: Added support for emotes and badges from [7TV](https://7tv.app). [Wiki Page](https://wiki.chatterino.com/Third_party_services/#7tv) (#4002, #4062) - Minor: Added highlights for `Elevated Messages`. (#4016) diff --git a/src/messages/MessageElement.cpp b/src/messages/MessageElement.cpp index 057c51474..60b305738 100644 --- a/src/messages/MessageElement.cpp +++ b/src/messages/MessageElement.cpp @@ -678,21 +678,23 @@ void ScalingImageElement::addToContainer(MessageLayoutContainer &container, ReplyCurveElement::ReplyCurveElement() : MessageElement(MessageElementFlag::RepliedMessage) - // these values nicely align with a single badge - , neededMargin_(3) - , size_(18, 14) { } void ReplyCurveElement::addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) { + static const int width = 18; // Overall width + static const float thickness = 1.5; // Pen width + static const int radius = 6; // Radius of the top left corner + static const int margin = 2; // Top/Left/Bottom margin + if (flags.hasAny(this->getFlags())) { - QSize boxSize = this->size_ * container.getScale(); - container.addElement(new ReplyCurveLayoutElement( - *this, boxSize, 1.5 * container.getScale(), - this->neededMargin_ * container.getScale())); + float scale = container.getScale(); + container.addElement( + new ReplyCurveLayoutElement(*this, width * scale, thickness * scale, + radius * scale, margin * scale)); } } diff --git a/src/messages/MessageElement.hpp b/src/messages/MessageElement.hpp index a61816c4e..9cc9d8bb6 100644 --- a/src/messages/MessageElement.hpp +++ b/src/messages/MessageElement.hpp @@ -429,10 +429,6 @@ public: void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; - -private: - int neededMargin_; - QSize size_; }; } // namespace chatterino diff --git a/src/messages/layouts/MessageLayoutContainer.cpp b/src/messages/layouts/MessageLayoutContainer.cpp index eefc88ae0..f7e3d9c47 100644 --- a/src/messages/layouts/MessageLayoutContainer.cpp +++ b/src/messages/layouts/MessageLayoutContainer.cpp @@ -133,21 +133,20 @@ void MessageLayoutContainer::_addElement(MessageLayoutElement *element, this->currentY_ = int(this->margin.top * this->scale_); } - int newLineHeight = element->getRect().height(); + int elementLineHeight = element->getRect().height(); // compact emote offset bool isCompactEmote = - getSettings()->compactEmotes && !this->flags_.has(MessageFlag::DisableCompactEmotes) && element->getCreator().getFlags().has(MessageElementFlag::EmoteImages); if (isCompactEmote) { - newLineHeight -= COMPACT_EMOTES_OFFSET * this->scale_; + elementLineHeight -= COMPACT_EMOTES_OFFSET * this->scale_; } // update line height - this->lineHeight_ = std::max(this->lineHeight_, newLineHeight); + this->lineHeight_ = std::max(this->lineHeight_, elementLineHeight); auto xOffset = 0; bool isZeroWidthEmote = element->getCreator().getFlags().has( @@ -218,7 +217,6 @@ void MessageLayoutContainer::breakLine() MessageLayoutElement *element = this->elements_.at(i).get(); bool isCompactEmote = - getSettings()->compactEmotes && !this->flags_.has(MessageFlag::DisableCompactEmotes) && element->getCreator().getFlags().has( MessageElementFlag::EmoteImages); @@ -229,15 +227,6 @@ void MessageLayoutContainer::breakLine() yExtra = (COMPACT_EMOTES_OFFSET / 2) * this->scale_; } - // if (element->getCreator().getFlags() & - // MessageElementFlag::Badges) - // { - if (element->getRect().height() < this->textLineHeight_) - { - // yExtra -= (this->textLineHeight_ - element->getRect().height()) / - // 2; - } - element->setPosition( QPoint(element->getRect().x() + xOffset + int(this->margin.left * this->scale_), diff --git a/src/messages/layouts/MessageLayoutElement.cpp b/src/messages/layouts/MessageLayoutElement.cpp index 492a4c8bb..1aa9a25ca 100644 --- a/src/messages/layouts/MessageLayoutElement.cpp +++ b/src/messages/layouts/MessageLayoutElement.cpp @@ -442,11 +442,12 @@ int TextIconLayoutElement::getXFromIndex(int index) } ReplyCurveLayoutElement::ReplyCurveLayoutElement(MessageElement &creator, - const QSize &size, - float thickness, + int width, float thickness, + float radius, float neededMargin) - : MessageLayoutElement(creator, size) + : MessageLayoutElement(creator, QSize(width, 0)) , pen_(QColor("#888"), thickness, Qt::SolidLine, Qt::RoundCap) + , radius_(radius) , neededMargin_(neededMargin) { } @@ -454,23 +455,36 @@ ReplyCurveLayoutElement::ReplyCurveLayoutElement(MessageElement &creator, void ReplyCurveLayoutElement::paint(QPainter &painter) { QRectF paintRect(this->getRect()); - QPainterPath bezierPath; + QPainterPath path; - qreal top = paintRect.top() + paintRect.height() * 0.25; // 25% from top - qreal left = paintRect.left() + this->neededMargin_; - qreal bottom = paintRect.bottom() - this->neededMargin_; - QPointF startPoint(left, bottom); - QPointF controlPoint(left, top); - QPointF endPoint(paintRect.right(), top); + QRectF curveRect = paintRect.marginsRemoved(QMarginsF( + this->neededMargin_, this->neededMargin_, 0, this->neededMargin_)); - // Create curve path - bezierPath.moveTo(startPoint); - bezierPath.quadTo(controlPoint, endPoint); + // Make sure that our curveRect can always fit the radius curve + if (curveRect.height() < this->radius_) + { + curveRect.setTop(curveRect.top() - + (this->radius_ - curveRect.height())); + } + + QPointF bStartPoint(curveRect.left(), curveRect.top() + this->radius_); + QPointF bEndPoint(curveRect.left() + this->radius_, curveRect.top()); + QPointF bControlPoint(curveRect.topLeft()); + + // Draw line from bottom left to curve + path.moveTo(curveRect.bottomLeft()); + path.lineTo(bStartPoint); + + // Draw curve path + path.quadTo(bControlPoint, bEndPoint); + + // Draw line from curve to top right + path.lineTo(curveRect.topRight()); // Render curve painter.setPen(this->pen_); painter.setRenderHint(QPainter::Antialiasing); - painter.drawPath(bezierPath); + painter.drawPath(path); } void ReplyCurveLayoutElement::paintAnimated(QPainter &painter, int yOffset) diff --git a/src/messages/layouts/MessageLayoutElement.hpp b/src/messages/layouts/MessageLayoutElement.hpp index 4bf26ad29..6684731ad 100644 --- a/src/messages/layouts/MessageLayoutElement.hpp +++ b/src/messages/layouts/MessageLayoutElement.hpp @@ -163,8 +163,8 @@ private: class ReplyCurveLayoutElement : public MessageLayoutElement { public: - ReplyCurveLayoutElement(MessageElement &creator, const QSize &size, - float thickness, float lMargin); + ReplyCurveLayoutElement(MessageElement &creator, int width, float thickness, + float radius, float neededMargin); protected: void paint(QPainter &painter) override; @@ -177,6 +177,7 @@ protected: private: const QPen pen_; + const float radius_; const float neededMargin_; }; diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 2970cc8fa..a56b79b2b 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -100,7 +100,6 @@ public: false}; BoolSetting separateMessages = {"/appearance/messages/separateMessages", false}; - BoolSetting compactEmotes = {"/appearance/messages/compactEmotes", true}; BoolSetting hideModerated = {"/appearance/messages/hideModerated", false}; BoolSetting hideModerationActions = { "/appearance/messages/hideModerationActions", false};