diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 3b195f368c..67ae34198b 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -3245,7 +3245,7 @@ QString HistoryInner::tooltipText() const { } } else if (_mouseCursorState == CursorState::Forwarded && _mouseAction == MouseAction::None) { - if (const auto view = App::hoveredItem()) { + if (const auto view = App::mousedItem()) { if (const auto forwarded = view->data()->Get()) { return forwarded->text.toString(); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.h b/Telegram/SourceFiles/history/view/media/history_view_dice.h index 5d0d7c4a93..1afb1c08eb 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_dice.h +++ b/Telegram/SourceFiles/history/view/media/history_view_dice.h @@ -29,6 +29,9 @@ public: _end->unloadHeavyPart(); } } + bool hidesForwardedInfo() override { + return false; + } private: const not_null _parent; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp index 7b49cd2b11..f1b5554e47 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp @@ -18,6 +18,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_history.h" namespace HistoryView { +namespace { + +constexpr auto kMaxForwardedBarLines = 4; + +} // namespace UnwrappedMedia::Content::~Content() = default; @@ -40,11 +45,16 @@ QSize UnwrappedMedia::countOptimalSize() { const auto item = _parent->data(); const auto via = item->Get(); const auto reply = item->Get(); - maxWidth += additionalWidth(via, reply); - if (const auto surrounding = surroundingHeight(via, reply)) { + const auto forwarded = getDisplayedForwardedInfo(); + if (forwarded) { + forwarded->create(via); + } + const auto additional = additionalWidth(via, reply, forwarded); + maxWidth += additional; + if (const auto surrounding = surroundingInfo(via, reply, forwarded, additional - st::msgReplyPadding.left())) { const auto infoHeight = st::msgDateImgPadding.y() * 2 + st::msgDateFont->height; - const auto minimal = surrounding + const auto minimal = surrounding.height + st::msgDateImgDelta + infoHeight; minHeight = std::max(minHeight, minimal); @@ -60,8 +70,9 @@ QSize UnwrappedMedia::countCurrentSize(int newWidth) { const auto infoWidth = _parent->infoWidth() + 2 * st::msgDateImgPadding.x(); const auto via = item->Get(); const auto reply = item->Get(); - if (via || reply) { - int usew = maxWidth() - additionalWidth(via, reply); + const auto forwarded = getDisplayedForwardedInfo(); + if (via || reply || forwarded) { + int usew = maxWidth() - additionalWidth(via, reply, forwarded); int availw = newWidth - usew - st::msgReplyPadding.left() - st::msgReplyPadding.left() - st::msgReplyPadding.left(); if (via) { via->resize(availw); @@ -99,10 +110,11 @@ void UnwrappedMedia::draw( const auto item = _parent->data(); const auto via = inWebPage ? nullptr : item->Get(); const auto reply = inWebPage ? nullptr : item->Get(); + const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo(); auto usex = 0; auto usew = maxWidth(); if (!inWebPage) { - usew -= additionalWidth(via, reply); + usew -= additionalWidth(via, reply, forwarded); if (rightAligned) { usex = width() - usew; } @@ -121,25 +133,37 @@ void UnwrappedMedia::draw( _content->draw(p, inner, selected); if (!inWebPage) { - drawSurrounding(p, inner, selected, via, reply); + drawSurrounding(p, inner, selected, via, reply, forwarded); } } -int UnwrappedMedia::surroundingHeight( +UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo( const HistoryMessageVia *via, - const HistoryMessageReply *reply) const { - if (!via && !reply) { - return 0; + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded, + int outerw) const { + if (!via && !reply && !forwarded) { + return {}; } - auto result = st::msgReplyPadding.top() + st::msgReplyPadding.bottom(); - if (via) { - result += st::msgServiceNameFont->height + auto height = st::msgReplyPadding.top() + st::msgReplyPadding.bottom(); + const auto innerw = outerw - st::msgReplyPadding.left() - st::msgReplyPadding.right(); + auto forwardedHeightReal = forwarded + ? forwarded->text.countHeight(innerw) + : 0; + auto forwardedHeight = std::min( + forwardedHeightReal, + kMaxForwardedBarLines * st::msgServiceNameFont->height); + const auto breakEverywhere = (forwardedHeightReal > forwardedHeight); + if (forwarded) { + height += forwardedHeight; + } else if (via) { + height += st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0); } if (reply) { - result += st::msgReplyBarSize.height(); + height += st::msgReplyBarSize.height(); } - return result; + return { height, forwardedHeight, breakEverywhere }; } void UnwrappedMedia::drawSurrounding( @@ -147,7 +171,8 @@ void UnwrappedMedia::drawSurrounding( const QRect &inner, bool selected, const HistoryMessageVia *via, - const HistoryMessageReply *reply) const { + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded) const { const auto rightAligned = _parent->hasOutLayout() && !Adaptive::ChatWide(); const auto rightAction = _parent->displayRightAction(); const auto fullRight = calculateFullRight(inner); @@ -162,8 +187,9 @@ void UnwrappedMedia::drawSurrounding( InfoDisplayType::Background); } auto replyRight = 0; - if (const auto recth = surroundingHeight(via, reply)) { - int rectw = width() - inner.width() - st::msgReplyPadding.left(); + auto rectw = width() - inner.width() - st::msgReplyPadding.left(); + if (const auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) { + auto recth = surrounding.height; int rectx = rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()); int recty = 0; if (rtl()) rectx = width() - rectx - rectw; @@ -172,6 +198,16 @@ void UnwrappedMedia::drawSurrounding( p.setPen(st::msgServiceFg); rectx += st::msgReplyPadding.left(); rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right(); + if (forwarded) { + p.setTextPalette(st::serviceTextPalette); + forwarded->text.drawElided(p, rectx, recty + st::msgReplyPadding.top(), rectw, kMaxForwardedBarLines, style::al_left, 0, -1, 0, surrounding.forwardedBreakEverywhere); + p.restoreTextPalette(); + } else if (via) { + p.setFont(st::msgDateFont); + p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text); + int skip = st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0); + recty += skip; + } if (via) { p.setFont(st::msgDateFont); p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text); @@ -207,10 +243,11 @@ PointState UnwrappedMedia::pointState(QPoint point) const { const auto item = _parent->data(); const auto via = inWebPage ? nullptr : item->Get(); const auto reply = inWebPage ? nullptr : item->Get(); + const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo(); auto usex = 0; auto usew = maxWidth(); if (!inWebPage) { - usew -= additionalWidth(via, reply); + usew -= additionalWidth(via, reply, forwarded); if (rightAligned) { usex = width() - usew; } @@ -246,10 +283,11 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const { const auto item = _parent->data(); const auto via = inWebPage ? nullptr : item->Get(); const auto reply = inWebPage ? nullptr : item->Get(); + const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo(); auto usex = 0; auto usew = maxWidth(); if (!inWebPage) { - usew -= additionalWidth(via, reply); + usew -= additionalWidth(via, reply, forwarded); if (rightAligned) { usex = width() - usew; } @@ -268,13 +306,36 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const { if (_parent->media() == this) { auto replyRight = 0; - if (auto recth = surroundingHeight(via, reply)) { - int rectw = width() - inner.width() - st::msgReplyPadding.left(); + auto rectw = width() - inner.width() - st::msgReplyPadding.left(); + if (auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) { + auto recth = surrounding.height; int rectx = rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()); int recty = 0; if (rtl()) rectx = width() - rectx - rectw; - if (via) { + if (forwarded) { + if (QRect(rectx, recty, rectw, st::msgReplyPadding.top() + surrounding.forwardedHeight).contains(point)) { + auto textRequest = request.forText(); + if (surrounding.forwardedBreakEverywhere) { + textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere; + } + const auto innerw = rectw - st::msgReplyPadding.left() - st::msgReplyPadding.right(); + result = TextState(_parent, forwarded->text.getState( + point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()), + innerw, + textRequest)); + result.symbol = 0; + result.afterSymbol = false; + if (surrounding.forwardedBreakEverywhere) { + result.cursor = CursorState::Forwarded; + } else { + result.cursor = CursorState::None; + } + return result; + } + recty += surrounding.forwardedHeight; + recth -= surrounding.forwardedHeight; + } else if (via) { int viah = st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? 0 : st::msgReplyPadding.bottom()); if (QRect(rectx, recty, rectw, viah).contains(point)) { result.link = via->link; @@ -373,9 +434,14 @@ bool UnwrappedMedia::needInfoDisplay() const { && _content->alwaysShowOutTimestamp()); } -int UnwrappedMedia::additionalWidth(const HistoryMessageVia *via, const HistoryMessageReply *reply) const { +int UnwrappedMedia::additionalWidth( + const HistoryMessageVia *via, + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded) const { auto result = st::msgReplyPadding.left() + _parent->infoWidth() + 2 * st::msgDateImgPadding.x(); - if (via) { + if (forwarded) { + accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + forwarded->text.maxWidth() + st::msgReplyPadding.right()); + } else if (via) { accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.left()); } if (reply) { @@ -384,4 +450,11 @@ int UnwrappedMedia::additionalWidth(const HistoryMessageVia *via, const HistoryM return result; } +auto UnwrappedMedia::getDisplayedForwardedInfo() const +-> const HistoryMessageForwarded * { + return _content->hidesForwardedInfo() + ? nullptr + : _parent->data()->Get(); +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h index de27f2d0f5..71d3cb2b0f 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h @@ -38,6 +38,9 @@ public: } virtual void refreshLink() { } + [[nodiscard]] virtual bool hidesForwardedInfo() { + return true; + } [[nodiscard]] virtual bool alwaysShowOutTimestamp() { return false; } @@ -73,7 +76,7 @@ public: return true; } bool hidesForwardedInfo() const override { - return true; + return _content->hidesForwardedInfo(); } void clearStickerLoopPlayed() override { _content->clearStickerLoopPlayed(); @@ -84,15 +87,27 @@ public: } private: - int surroundingHeight( + struct SurroundingInfo { + int height = 0; + int forwardedHeight = 0; + bool forwardedBreakEverywhere = false; + + explicit operator bool() const { + return (height > 0); + } + }; + [[nodiscard]] SurroundingInfo surroundingInfo( const HistoryMessageVia *via, - const HistoryMessageReply *reply) const; + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded, + int outerw) const; void drawSurrounding( Painter &p, const QRect &inner, bool selected, const HistoryMessageVia *via, - const HistoryMessageReply *reply) const; + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded) const; QSize countOptimalSize() override; QSize countCurrentSize(int newWidth) override; @@ -100,7 +115,8 @@ private: bool needInfoDisplay() const; int additionalWidth( const HistoryMessageVia *via, - const HistoryMessageReply *reply) const; + const HistoryMessageReply *reply, + const HistoryMessageForwarded *forwarded) const; inline int calculateFullRight(const QRect &inner) const; inline QPoint calculateFastActionPosition( @@ -108,6 +124,8 @@ private: int replyRight, int fullRight) const; + const HistoryMessageForwarded *getDisplayedForwardedInfo() const; + std::unique_ptr _content; QSize _contentSize;