Show forwarded info in Dice media.

This commit is contained in:
John Preston 2020-03-06 11:53:59 +04:00
parent c83e297554
commit e7ca405e8c
4 changed files with 126 additions and 32 deletions

View File

@ -3245,7 +3245,7 @@ QString HistoryInner::tooltipText() const {
} }
} else if (_mouseCursorState == CursorState::Forwarded } else if (_mouseCursorState == CursorState::Forwarded
&& _mouseAction == MouseAction::None) { && _mouseAction == MouseAction::None) {
if (const auto view = App::hoveredItem()) { if (const auto view = App::mousedItem()) {
if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) { if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) {
return forwarded->text.toString(); return forwarded->text.toString();
} }

View File

@ -29,6 +29,9 @@ public:
_end->unloadHeavyPart(); _end->unloadHeavyPart();
} }
} }
bool hidesForwardedInfo() override {
return false;
}
private: private:
const not_null<Element*> _parent; const not_null<Element*> _parent;

View File

@ -18,6 +18,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_history.h" #include "styles/style_history.h"
namespace HistoryView { namespace HistoryView {
namespace {
constexpr auto kMaxForwardedBarLines = 4;
} // namespace
UnwrappedMedia::Content::~Content() = default; UnwrappedMedia::Content::~Content() = default;
@ -40,11 +45,16 @@ QSize UnwrappedMedia::countOptimalSize() {
const auto item = _parent->data(); const auto item = _parent->data();
const auto via = item->Get<HistoryMessageVia>(); const auto via = item->Get<HistoryMessageVia>();
const auto reply = item->Get<HistoryMessageReply>(); const auto reply = item->Get<HistoryMessageReply>();
maxWidth += additionalWidth(via, reply); const auto forwarded = getDisplayedForwardedInfo();
if (const auto surrounding = surroundingHeight(via, reply)) { 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 const auto infoHeight = st::msgDateImgPadding.y() * 2
+ st::msgDateFont->height; + st::msgDateFont->height;
const auto minimal = surrounding const auto minimal = surrounding.height
+ st::msgDateImgDelta + st::msgDateImgDelta
+ infoHeight; + infoHeight;
minHeight = std::max(minHeight, minimal); 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 infoWidth = _parent->infoWidth() + 2 * st::msgDateImgPadding.x();
const auto via = item->Get<HistoryMessageVia>(); const auto via = item->Get<HistoryMessageVia>();
const auto reply = item->Get<HistoryMessageReply>(); const auto reply = item->Get<HistoryMessageReply>();
if (via || reply) { const auto forwarded = getDisplayedForwardedInfo();
int usew = maxWidth() - additionalWidth(via, reply); if (via || reply || forwarded) {
int usew = maxWidth() - additionalWidth(via, reply, forwarded);
int availw = newWidth - usew - st::msgReplyPadding.left() - st::msgReplyPadding.left() - st::msgReplyPadding.left(); int availw = newWidth - usew - st::msgReplyPadding.left() - st::msgReplyPadding.left() - st::msgReplyPadding.left();
if (via) { if (via) {
via->resize(availw); via->resize(availw);
@ -99,10 +110,11 @@ void UnwrappedMedia::draw(
const auto item = _parent->data(); const auto item = _parent->data();
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>(); const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>(); const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>();
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
auto usex = 0; auto usex = 0;
auto usew = maxWidth(); auto usew = maxWidth();
if (!inWebPage) { if (!inWebPage) {
usew -= additionalWidth(via, reply); usew -= additionalWidth(via, reply, forwarded);
if (rightAligned) { if (rightAligned) {
usex = width() - usew; usex = width() - usew;
} }
@ -121,25 +133,37 @@ void UnwrappedMedia::draw(
_content->draw(p, inner, selected); _content->draw(p, inner, selected);
if (!inWebPage) { 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 HistoryMessageVia *via,
const HistoryMessageReply *reply) const { const HistoryMessageReply *reply,
if (!via && !reply) { const HistoryMessageForwarded *forwarded,
return 0; int outerw) const {
if (!via && !reply && !forwarded) {
return {};
} }
auto result = st::msgReplyPadding.top() + st::msgReplyPadding.bottom(); auto height = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
if (via) { const auto innerw = outerw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
result += st::msgServiceNameFont->height 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); + (reply ? st::msgReplyPadding.top() : 0);
} }
if (reply) { if (reply) {
result += st::msgReplyBarSize.height(); height += st::msgReplyBarSize.height();
} }
return result; return { height, forwardedHeight, breakEverywhere };
} }
void UnwrappedMedia::drawSurrounding( void UnwrappedMedia::drawSurrounding(
@ -147,7 +171,8 @@ void UnwrappedMedia::drawSurrounding(
const QRect &inner, const QRect &inner,
bool selected, bool selected,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply) const { const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const {
const auto rightAligned = _parent->hasOutLayout() && !Adaptive::ChatWide(); const auto rightAligned = _parent->hasOutLayout() && !Adaptive::ChatWide();
const auto rightAction = _parent->displayRightAction(); const auto rightAction = _parent->displayRightAction();
const auto fullRight = calculateFullRight(inner); const auto fullRight = calculateFullRight(inner);
@ -162,8 +187,9 @@ void UnwrappedMedia::drawSurrounding(
InfoDisplayType::Background); InfoDisplayType::Background);
} }
auto replyRight = 0; auto replyRight = 0;
if (const auto recth = surroundingHeight(via, reply)) { auto rectw = width() - inner.width() - st::msgReplyPadding.left();
int 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 rectx = rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left());
int recty = 0; int recty = 0;
if (rtl()) rectx = width() - rectx - rectw; if (rtl()) rectx = width() - rectx - rectw;
@ -172,6 +198,16 @@ void UnwrappedMedia::drawSurrounding(
p.setPen(st::msgServiceFg); p.setPen(st::msgServiceFg);
rectx += st::msgReplyPadding.left(); rectx += st::msgReplyPadding.left();
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right(); 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) { if (via) {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);
p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text); 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 item = _parent->data();
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>(); const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>(); const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>();
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
auto usex = 0; auto usex = 0;
auto usew = maxWidth(); auto usew = maxWidth();
if (!inWebPage) { if (!inWebPage) {
usew -= additionalWidth(via, reply); usew -= additionalWidth(via, reply, forwarded);
if (rightAligned) { if (rightAligned) {
usex = width() - usew; usex = width() - usew;
} }
@ -246,10 +283,11 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
const auto item = _parent->data(); const auto item = _parent->data();
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>(); const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>(); const auto reply = inWebPage ? nullptr : item->Get<HistoryMessageReply>();
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
auto usex = 0; auto usex = 0;
auto usew = maxWidth(); auto usew = maxWidth();
if (!inWebPage) { if (!inWebPage) {
usew -= additionalWidth(via, reply); usew -= additionalWidth(via, reply, forwarded);
if (rightAligned) { if (rightAligned) {
usex = width() - usew; usex = width() - usew;
} }
@ -268,13 +306,36 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
if (_parent->media() == this) { if (_parent->media() == this) {
auto replyRight = 0; auto replyRight = 0;
if (auto recth = surroundingHeight(via, reply)) { auto rectw = width() - inner.width() - st::msgReplyPadding.left();
int 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 rectx = rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left());
int recty = 0; int recty = 0;
if (rtl()) rectx = width() - rectx - rectw; 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()); int viah = st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? 0 : st::msgReplyPadding.bottom());
if (QRect(rectx, recty, rectw, viah).contains(point)) { if (QRect(rectx, recty, rectw, viah).contains(point)) {
result.link = via->link; result.link = via->link;
@ -373,9 +434,14 @@ bool UnwrappedMedia::needInfoDisplay() const {
&& _content->alwaysShowOutTimestamp()); && _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(); 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()); accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.left());
} }
if (reply) { if (reply) {
@ -384,4 +450,11 @@ int UnwrappedMedia::additionalWidth(const HistoryMessageVia *via, const HistoryM
return result; return result;
} }
auto UnwrappedMedia::getDisplayedForwardedInfo() const
-> const HistoryMessageForwarded * {
return _content->hidesForwardedInfo()
? nullptr
: _parent->data()->Get<HistoryMessageForwarded>();
}
} // namespace HistoryView } // namespace HistoryView

View File

@ -38,6 +38,9 @@ public:
} }
virtual void refreshLink() { virtual void refreshLink() {
} }
[[nodiscard]] virtual bool hidesForwardedInfo() {
return true;
}
[[nodiscard]] virtual bool alwaysShowOutTimestamp() { [[nodiscard]] virtual bool alwaysShowOutTimestamp() {
return false; return false;
} }
@ -73,7 +76,7 @@ public:
return true; return true;
} }
bool hidesForwardedInfo() const override { bool hidesForwardedInfo() const override {
return true; return _content->hidesForwardedInfo();
} }
void clearStickerLoopPlayed() override { void clearStickerLoopPlayed() override {
_content->clearStickerLoopPlayed(); _content->clearStickerLoopPlayed();
@ -84,15 +87,27 @@ public:
} }
private: 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 HistoryMessageVia *via,
const HistoryMessageReply *reply) const; const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded,
int outerw) const;
void drawSurrounding( void drawSurrounding(
Painter &p, Painter &p,
const QRect &inner, const QRect &inner,
bool selected, bool selected,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply) const; const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const;
QSize countOptimalSize() override; QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override; QSize countCurrentSize(int newWidth) override;
@ -100,7 +115,8 @@ private:
bool needInfoDisplay() const; bool needInfoDisplay() const;
int additionalWidth( int additionalWidth(
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply) const; const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const;
inline int calculateFullRight(const QRect &inner) const; inline int calculateFullRight(const QRect &inner) const;
inline QPoint calculateFastActionPosition( inline QPoint calculateFastActionPosition(
@ -108,6 +124,8 @@ private:
int replyRight, int replyRight,
int fullRight) const; int fullRight) const;
const HistoryMessageForwarded *getDisplayedForwardedInfo() const;
std::unique_ptr<Content> _content; std::unique_ptr<Content> _content;
QSize _contentSize; QSize _contentSize;