Add jump-to-topic panel to stickers.

This commit is contained in:
John Preston 2022-12-02 20:32:06 +04:00
parent b5cb2bc9f0
commit 587715a966
12 changed files with 219 additions and 122 deletions

View file

@ -1179,8 +1179,8 @@ bool Element::displayFromName() const {
return false; return false;
} }
bool Element::displayTopicButton() const { TopicButton *Element::displayedTopicButton() const {
return false; return nullptr;
} }
bool Element::displayForwardedFrom() const { bool Element::displayForwardedFrom() const {

View file

@ -35,6 +35,7 @@ struct ChatPaintContext;
class ChatStyle; class ChatStyle;
struct ReactionFlyAnimationArgs; struct ReactionFlyAnimationArgs;
class ReactionFlyAnimation; class ReactionFlyAnimation;
class RippleAnimation;
} // namespace Ui } // namespace Ui
namespace HistoryView::Reactions { namespace HistoryView::Reactions {
@ -237,6 +238,14 @@ struct DateBadge : public RuntimeComponent<DateBadge, Element> {
}; };
struct TopicButton {
std::unique_ptr<Ui::RippleAnimation> ripple;
ClickHandlerPtr link;
Ui::Text::String name;
QPoint lastPoint;
int nameVersion = 0;
};
class Element class Element
: public Object : public Object
, public RuntimeComposer<Element> , public RuntimeComposer<Element>
@ -376,7 +385,7 @@ public:
[[nodiscard]] virtual bool displayFromPhoto() const; [[nodiscard]] virtual bool displayFromPhoto() const;
[[nodiscard]] virtual bool hasFromName() const; [[nodiscard]] virtual bool hasFromName() const;
[[nodiscard]] virtual bool displayFromName() const; [[nodiscard]] virtual bool displayFromName() const;
[[nodiscard]] virtual bool displayTopicButton() const; [[nodiscard]] virtual TopicButton *displayedTopicButton() const;
[[nodiscard]] virtual bool displayForwardedFrom() const; [[nodiscard]] virtual bool displayForwardedFrom() const;
[[nodiscard]] virtual bool hasOutLayout() const; [[nodiscard]] virtual bool hasOutLayout() const;
[[nodiscard]] virtual bool drawBubble() const; [[nodiscard]] virtual bool drawBubble() const;

View file

@ -285,14 +285,6 @@ struct Message::CommentsButton {
int rippleShift = 0; int rippleShift = 0;
}; };
struct Message::TopicButton {
std::unique_ptr<Ui::RippleAnimation> ripple;
ClickHandlerPtr link;
Ui::Text::String name;
QPoint lastPoint;
int nameVersion = 0;
};
struct Message::FromNameStatus { struct Message::FromNameStatus {
DocumentId id = 0; DocumentId id = 0;
std::unique_ptr<Ui::Text::CustomEmoji> custom; std::unique_ptr<Ui::Text::CustomEmoji> custom;
@ -642,7 +634,7 @@ QSize Message::performCountOptimalSize() {
} else if (via && !displayForwardedFrom()) { } else if (via && !displayForwardedFrom()) {
accumulate_max(maxWidth, st::msgPadding.left() + via->maxWidth + st::msgPadding.right()); accumulate_max(maxWidth, st::msgPadding.left() + via->maxWidth + st::msgPadding.right());
} }
if (displayTopicButton()) { if (displayedTopicButton()) {
const auto padding = st::msgPadding + st::topicButtonPadding; const auto padding = st::msgPadding + st::topicButtonPadding;
accumulate_max( accumulate_max(
maxWidth, maxWidth,
@ -1303,7 +1295,8 @@ void Message::paintTopicButton(
Painter &p, Painter &p,
QRect &trect, QRect &trect,
const PaintContext &context) const { const PaintContext &context) const {
if (!displayTopicButton()) { const auto button = displayedTopicButton();
if (!button) {
return; return;
} }
trect.setTop(trect.top() + st::topicButtonSkip); trect.setTop(trect.top() + st::topicButtonSkip);
@ -1316,7 +1309,7 @@ void Message::paintTopicButton(
std::min( std::min(
availableWidth, availableWidth,
(padding.left() (padding.left()
+ _topicButton->name.maxWidth() + button->name.maxWidth()
+ st::topicButtonArrowSkip + st::topicButtonArrowSkip
+ padding.right())), + padding.right())),
height); height);
@ -1333,21 +1326,21 @@ void Message::paintTopicButton(
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
p.drawRoundedRect(rect, height / 2, height / 2); p.drawRoundedRect(rect, height / 2, height / 2);
} }
if (_topicButton->ripple) { if (button->ripple) {
_topicButton->ripple->paint( button->ripple->paint(
p, p,
rect.x(), rect.x(),
rect.y(), rect.y(),
this->width(), this->width(),
&color); &color);
if (_topicButton->ripple->empty()) { if (button->ripple->empty()) {
_topicButton->ripple.reset(); button->ripple.reset();
} }
} }
clearCustomEmojiRepaint(); clearCustomEmojiRepaint();
p.setPen(stm->msgServiceFg); p.setPen(stm->msgServiceFg);
p.setTextPalette(stm->fwdTextPalette); p.setTextPalette(stm->fwdTextPalette);
_topicButton->name.drawElided( button->name.drawElided(
p, p,
trect.x() + padding.left(), trect.x() + padding.left(),
trect.y() + padding.top(), trect.y() + padding.top(),
@ -2082,7 +2075,7 @@ bool Message::getStateTopicButton(
QPoint point, QPoint point,
QRect &trect, QRect &trect,
not_null<TextState*> outResult) const { not_null<TextState*> outResult) const {
if (!displayTopicButton()) { if (!displayedTopicButton()) {
return false; return false;
} }
trect.setTop(trect.top() + st::topicButtonSkip); trect.setTop(trect.top() + st::topicButtonSkip);
@ -2285,7 +2278,7 @@ void Message::updatePressed(QPoint point) {
if (displayFromName()) { if (displayFromName()) {
trect.setTop(trect.top() + st::msgNameFont->height); trect.setTop(trect.top() + st::msgNameFont->height);
} }
if (displayTopicButton()) { if (displayedTopicButton()) {
trect.setTop(trect.top() trect.setTop(trect.top()
+ st::topicButtonSkip + st::topicButtonSkip
+ st::topicButtonPadding.top() + st::topicButtonPadding.top()
@ -2869,8 +2862,8 @@ bool Message::hasBubble() const {
return drawBubble(); return drawBubble();
} }
bool Message::displayTopicButton() const { TopicButton *Message::displayedTopicButton() const {
return _topicButton != nullptr; return _topicButton.get();
} }
bool Message::unwrapped() const { bool Message::unwrapped() const {
@ -3167,7 +3160,7 @@ void Message::updateMediaInBubbleState() {
auto mediaHasSomethingAbove = false; auto mediaHasSomethingAbove = false;
auto getMediaHasSomethingAbove = [&] { auto getMediaHasSomethingAbove = [&] {
return displayFromName() return displayFromName()
|| displayTopicButton() || displayedTopicButton()
|| displayForwardedFrom() || displayForwardedFrom()
|| displayedReply() || displayedReply()
|| item->Has<HistoryMessageVia>(); || item->Has<HistoryMessageVia>();
@ -3286,7 +3279,7 @@ QRect Message::innerGeometry() const {
// See paintFromName(). // See paintFromName().
result.translate(0, st::msgNameFont->height); result.translate(0, st::msgNameFont->height);
} }
if (displayTopicButton()) { if (displayedTopicButton()) {
result.translate(0, st::topicButtonSkip result.translate(0, st::topicButtonSkip
+ st::topicButtonPadding.top() + st::topicButtonPadding.top()
+ st::msgNameFont->height + st::msgNameFont->height
@ -3513,7 +3506,7 @@ int Message::resizeContentGetHeight(int newWidth) {
newHeight += st::msgNameFont->height; newHeight += st::msgNameFont->height;
} }
if (displayTopicButton()) { if (displayedTopicButton()) {
newHeight += st::topicButtonSkip newHeight += st::topicButtonSkip
+ st::topicButtonPadding.top() + st::topicButtonPadding.top()
+ st::msgNameFont->height + st::msgNameFont->height

View file

@ -123,7 +123,7 @@ public:
bool hasOutLayout() const override; bool hasOutLayout() const override;
bool drawBubble() const override; bool drawBubble() const override;
bool hasBubble() const override; bool hasBubble() const override;
bool displayTopicButton() const override; TopicButton *displayedTopicButton() const override;
bool unwrapped() const override; bool unwrapped() const override;
int minWidthForMedia() const override; int minWidthForMedia() const override;
bool hasFastReply() const override; bool hasFastReply() const override;
@ -168,7 +168,6 @@ protected:
private: private:
struct CommentsButton; struct CommentsButton;
struct FromNameStatus; struct FromNameStatus;
struct TopicButton;
void initLogEntryOriginal(); void initLogEntryOriginal();
void initPsa(); void initPsa();

View file

@ -254,7 +254,7 @@ RepliesWidget::RepliesWidget(
setupRootView(); setupRootView();
setupShortcuts(); setupShortcuts();
session().api().requestFullPeer(_history->peer); _history->peer->updateFull();
refreshTopBarActiveChat(); refreshTopBarActiveChat();

View file

@ -431,7 +431,7 @@ bool ExtendedPreview::needsBubble() const {
|| _parent->displayedReply() || _parent->displayedReply()
|| _parent->displayForwardedFrom() || _parent->displayForwardedFrom()
|| _parent->displayFromName() || _parent->displayFromName()
|| _parent->displayTopicButton()); || _parent->displayedTopicButton());
} }
QPoint ExtendedPreview::resolveCustomInfoRightBottom() const { QPoint ExtendedPreview::resolveCustomInfoRightBottom() const {

View file

@ -1309,7 +1309,7 @@ bool Gif::needsBubble() const {
|| _parent->displayedReply() || _parent->displayedReply()
|| _parent->displayForwardedFrom() || _parent->displayForwardedFrom()
|| _parent->displayFromName() || _parent->displayFromName()
|| _parent->displayTopicButton(); || _parent->displayedTopicButton();
return false; return false;
} }

View file

@ -378,7 +378,7 @@ bool Location::needsBubble() const {
|| _parent->displayedReply() || _parent->displayedReply()
|| _parent->displayForwardedFrom() || _parent->displayForwardedFrom()
|| _parent->displayFromName() || _parent->displayFromName()
|| _parent->displayTopicButton(); || _parent->displayedTopicButton();
} }
QPoint Location::resolveCustomInfoRightBottom() const { QPoint Location::resolveCustomInfoRightBottom() const {

View file

@ -775,7 +775,7 @@ bool GroupedMedia::computeNeedBubble() const {
|| _parent->displayedReply() || _parent->displayedReply()
|| _parent->displayForwardedFrom() || _parent->displayForwardedFrom()
|| _parent->displayFromName() || _parent->displayFromName()
|| _parent->displayTopicButton() || _parent->displayedTopicButton()
) { ) {
return true; return true;
} }

View file

@ -53,11 +53,12 @@ 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 = _parent->displayedReply(); const auto reply = _parent->displayedReply();
const auto topic = _parent->displayedTopicButton();
const auto forwarded = getDisplayedForwardedInfo(); const auto forwarded = getDisplayedForwardedInfo();
if (forwarded) { if (forwarded) {
forwarded->create(via); forwarded->create(via);
} }
maxWidth += additionalWidth(via, reply, forwarded); maxWidth += additionalWidth(topic, via, reply, forwarded);
accumulate_max(maxWidth, _parent->reactionsOptimalWidth()); accumulate_max(maxWidth, _parent->reactionsOptimalWidth());
if (const auto size = _parent->rightActionSize()) { if (const auto size = _parent->rightActionSize()) {
minHeight = std::max( minHeight = std::max(
@ -91,14 +92,14 @@ QSize UnwrappedMedia::countCurrentSize(int newWidth) {
_topAdded = 0; _topAdded = 0;
const auto via = item->Get<HistoryMessageVia>(); const auto via = item->Get<HistoryMessageVia>();
const auto reply = _parent->displayedReply(); const auto reply = _parent->displayedReply();
const auto topic = _parent->displayedTopicButton();
const auto forwarded = getDisplayedForwardedInfo(); const auto forwarded = getDisplayedForwardedInfo();
if (via || reply || forwarded) { if (topic || via || reply || forwarded) {
const auto paddings = 3 * st::msgReplyPadding.left(); const auto additional = additionalWidth(topic, via, reply, forwarded);
const auto additional = additionalWidth(via, reply, forwarded);
const auto optimalw = maxWidth() - additional; const auto optimalw = maxWidth() - additional;
const auto additionalMinWidth = std::min(additional, st::msgMinWidth / 2); const auto additionalMinWidth = std::min(additional, st::msgReplyPadding.left() + st::msgMinWidth / 2);
_additionalOnTop = (optimalw + paddings + additionalMinWidth) > newWidth; _additionalOnTop = (optimalw + additionalMinWidth) > newWidth;
const auto surrounding = surroundingInfo(via, reply, forwarded, additional - st::msgReplyPadding.left()); const auto surrounding = surroundingInfo(topic, via, reply, forwarded, additional);
if (_additionalOnTop) { if (_additionalOnTop) {
_topAdded = surrounding.height + st::msgMargin.bottom(); _topAdded = surrounding.height + st::msgMargin.bottom();
newHeight += _topAdded; newHeight += _topAdded;
@ -111,8 +112,8 @@ QSize UnwrappedMedia::countCurrentSize(int newWidth) {
newHeight = std::max(newHeight, minimal); newHeight = std::max(newHeight, minimal);
} }
const auto availw = newWidth const auto availw = newWidth
- (_additionalOnTop ? 0 : optimalw) - (_additionalOnTop ? 0 : optimalw + st::msgReplyPadding.left())
- paddings; - 2 * st::msgReplyPadding.left();
if (via) { if (via) {
via->resize(availw); via->resize(availw);
} }
@ -158,21 +159,40 @@ void UnwrappedMedia::draw(Painter &p, const PaintContext &context) const {
!= PaintContext::SkipDrawingParts::Surrounding)) { != PaintContext::SkipDrawingParts::Surrounding)) {
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>(); const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
const auto reply = inWebPage ? nullptr : _parent->displayedReply(); const auto reply = inWebPage ? nullptr : _parent->displayedReply();
const auto topic = inWebPage ? nullptr : _parent->displayedTopicButton();
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo(); const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
drawSurrounding(p, inner, context, via, reply, forwarded); drawSurrounding(p, inner, context, topic, via, reply, forwarded);
} }
} }
UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo( UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo(
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded, const HistoryMessageForwarded *forwarded,
int outerw) const { int outerw) const {
if (!via && !reply && !forwarded) { if (!topic && !via && !reply && !forwarded) {
return {}; return {};
} }
auto height = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
const auto innerw = outerw - st::msgReplyPadding.left() - st::msgReplyPadding.right(); const auto innerw = outerw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
auto topicSize = QSize();
if (topic) {
const auto padding = st::topicButtonPadding;
const auto height = padding.top()
+ st::msgNameFont->height
+ padding.bottom();
const auto width = std::max(
std::min(
outerw,
(st::msgReplyPadding.left()
+ topic->name.maxWidth()
+ st::topicButtonArrowSkip
+ st::topicButtonPadding.right())),
height);
topicSize = { width, height };
}
auto panelHeight = 0;
auto forwardedHeightReal = forwarded auto forwardedHeightReal = forwarded
? forwarded->text.countHeight(innerw) ? forwarded->text.countHeight(innerw)
: 0; : 0;
@ -181,21 +201,34 @@ UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo(
kMaxForwardedBarLines * st::msgServiceNameFont->height); kMaxForwardedBarLines * st::msgServiceNameFont->height);
const auto breakEverywhere = (forwardedHeightReal > forwardedHeight); const auto breakEverywhere = (forwardedHeightReal > forwardedHeight);
if (forwarded) { if (forwarded) {
height += forwardedHeight; panelHeight += forwardedHeight;
} else if (via) { } else if (via) {
height += st::msgServiceNameFont->height panelHeight += st::msgServiceNameFont->height
+ (reply ? st::msgReplyPadding.top() : 0); + (reply ? st::msgReplyPadding.top() : 0);
} }
if (reply) { if (reply) {
height += st::msgReplyBarSize.height(); panelHeight += st::msgReplyBarSize.height();
} }
return { height, forwardedHeight, breakEverywhere }; if (panelHeight) {
panelHeight += st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
}
const auto total = (topicSize.isEmpty() ? 0 : topicSize.height())
+ ((panelHeight || !topicSize.height()) ? st::topicButtonSkip : 0)
+ panelHeight;
return {
.topicSize = topicSize,
.height = total,
.panelHeight = panelHeight,
.forwardedHeight = forwardedHeight,
.forwardedBreakEverywhere = breakEverywhere,
};
} }
void UnwrappedMedia::drawSurrounding( void UnwrappedMedia::drawSurrounding(
Painter &p, Painter &p,
const QRect &inner, const QRect &inner,
const PaintContext &context, const PaintContext &context,
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const { const HistoryMessageForwarded *forwarded) const {
@ -217,41 +250,78 @@ void UnwrappedMedia::drawSurrounding(
} }
auto replyRight = 0; auto replyRight = 0;
auto rectw = _additionalOnTop auto rectw = _additionalOnTop
? std::min(width() - st::msgReplyPadding.left(), additionalWidth(via, reply, forwarded)) ? std::min(width() - st::msgReplyPadding.left(), additionalWidth(topic, via, reply, forwarded))
: (width() - inner.width() - st::msgReplyPadding.left()); : (width() - inner.width() - st::msgReplyPadding.left());
if (const auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) { if (const auto surrounding = surroundingInfo(topic, via, reply, forwarded, rectw)) {
auto recth = surrounding.height; auto recth = surrounding.panelHeight;
int rectx = _additionalOnTop if (!surrounding.topicSize.isEmpty()) {
? (rightAligned ? (inner.x() + inner.width() - rectw) : 0) auto rectw = surrounding.topicSize.width();
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left())); int rectx = _additionalOnTop
int recty = 0; ? (rightAligned ? (inner.x() + inner.width() - rectw) : 0)
if (rtl()) rectx = width() - rectx - rectw; : (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
int recty = 0;
if (rtl()) rectx = width() - rectx - rectw;
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall); {
p.setPen(st->msgServiceFg()); auto hq = PainterHighQualityEnabler(p);
rectx += st::msgReplyPadding.left(); p.setPen(Qt::NoPen);
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right(); p.setBrush(sti->msgServiceBg);
if (forwarded) { const auto recth = surrounding.topicSize.height();
p.drawRoundedRect(
QRect{ rectx, recty, rectw, recth },
recth / 2,
recth / 2);
}
p.setPen(st->msgServiceFg());
rectx += st::msgReplyPadding.left();
recty += st::topicButtonPadding.top();
rectw -= st::msgReplyPadding.left() + st::topicButtonPadding.right() + st::topicButtonArrowSkip;
p.setTextPalette(st->serviceTextPalette()); p.setTextPalette(st->serviceTextPalette());
forwarded->text.drawElided(p, rectx, recty + st::msgReplyPadding.top(), rectw, kMaxForwardedBarLines, style::al_left, 0, -1, 0, surrounding.forwardedBreakEverywhere); topic->name.drawElided(p, rectx, recty, rectw);
p.restoreTextPalette(); p.restoreTextPalette();
const auto skip = std::min( const auto &icon = st::topicButtonArrow;
forwarded->text.countHeight(rectw), icon.paint(
kMaxForwardedBarLines * st::msgServiceNameFont->height); p,
recty += skip; rectx + rectw + st::topicButtonArrowPosition.x(),
} else if (via) { recty + st::topicButtonArrowPosition.y(),
p.setFont(st::msgDateFont); width(),
p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text); st->msgServiceFg()->c);
}
if (recth) {
int rectx = _additionalOnTop
? (rightAligned ? (inner.x() + inner.width() - rectw) : 0)
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
int recty = surrounding.height - recth;
if (rtl()) rectx = width() - rectx - rectw;
const auto skip = st::msgServiceNameFont->height Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
+ (reply ? st::msgReplyPadding.top() : 0); p.setPen(st->msgServiceFg());
recty += skip; 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();
const auto skip = std::min(
forwarded->text.countHeight(rectw),
kMaxForwardedBarLines * st::msgServiceNameFont->height);
recty += skip;
} else if (via) {
p.setFont(st::msgDateFont);
p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text);
const auto skip = st::msgServiceNameFont->height
+ (reply ? st::msgReplyPadding.top() : 0);
recty += skip;
}
if (reply) {
reply->paint(p, _parent, context, rectx, recty, rectw, false);
}
replyRight = rectx + rectw;
} }
if (reply) {
reply->paint(p, _parent, context, rectx, recty, rectw, false);
}
replyRight = rectx + rectw;
} }
if (rightActionSize) { if (rightActionSize) {
const auto position = calculateFastActionPosition( const auto position = calculateFastActionPosition(
@ -327,58 +397,73 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
if (_parent->media() == this) { if (_parent->media() == this) {
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>(); const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
const auto reply = inWebPage ? nullptr : _parent->displayedReply(); const auto reply = inWebPage ? nullptr : _parent->displayedReply();
const auto topic = inWebPage ? nullptr : _parent->displayedTopicButton();
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo(); const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
auto replyRight = 0; auto replyRight = 0;
auto rectw = _additionalOnTop auto rectw = _additionalOnTop
? std::min(width() - st::msgReplyPadding.left(), additionalWidth(via, reply, forwarded)) ? std::min(width() - st::msgReplyPadding.left(), additionalWidth(topic, via, reply, forwarded))
: (width() - inner.width() - st::msgReplyPadding.left()); : (width() - inner.width() - st::msgReplyPadding.left());
if (const auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) { if (const auto surrounding = surroundingInfo(topic, via, reply, forwarded, rectw)) {
auto recth = surrounding.height; auto recth = surrounding.panelHeight;
int rectx = _additionalOnTop if (!surrounding.topicSize.isEmpty()) {
? (rightAligned ? (inner.width() + st::msgReplyPadding.left() - rectw) : 0) auto rectw = surrounding.topicSize.width();
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left())); int rectx = _additionalOnTop
int recty = 0; ? (rightAligned ? (inner.x() + inner.width() - rectw) : 0)
if (rtl()) rectx = width() - rectx - rectw; : (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
int recty = 0;
if (rtl()) rectx = width() - rectx - rectw;
if (QRect(QPoint(rectx, recty), surrounding.topicSize).contains(point)) {
result.link = topic->link;
return result;
}
}
if (recth) {
int rectx = _additionalOnTop
? (rightAligned ? (inner.width() + st::msgReplyPadding.left() - rectw) : 0)
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
int recty = surrounding.height - recth;
if (rtl()) rectx = width() - rectx - rectw;
if (forwarded) { if (forwarded) {
if (QRect(rectx, recty, rectw, st::msgReplyPadding.top() + surrounding.forwardedHeight).contains(point)) { if (QRect(rectx, recty, rectw, st::msgReplyPadding.top() + surrounding.forwardedHeight).contains(point)) {
auto textRequest = request.forText(); auto textRequest = request.forText();
if (surrounding.forwardedBreakEverywhere) { if (surrounding.forwardedBreakEverywhere) {
textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere; 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;
} }
const auto innerw = rectw - st::msgReplyPadding.left() - st::msgReplyPadding.right(); recty += surrounding.forwardedHeight;
result = TextState(_parent, forwarded->text.getState( recth -= surrounding.forwardedHeight;
point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()), } else if (via) {
innerw, int viah = st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? 0 : st::msgReplyPadding.bottom());
textRequest)); if (QRect(rectx, recty, rectw, viah).contains(point)) {
result.symbol = 0; result.link = via->link;
result.afterSymbol = false; return result;
if (surrounding.forwardedBreakEverywhere) {
result.cursor = CursorState::Forwarded;
} else {
result.cursor = CursorState::None;
} }
return result; int skip = st::msgServiceNameFont->height + (reply ? 2 * st::msgReplyPadding.top() : 0);
recty += skip;
recth -= skip;
} }
recty += surrounding.forwardedHeight; if (reply) {
recth -= surrounding.forwardedHeight; if (QRect(rectx, recty, rectw, recth).contains(point)) {
} else if (via) { result.link = reply->replyToLink();
int viah = st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? 0 : st::msgReplyPadding.bottom()); return result;
if (QRect(rectx, recty, rectw, viah).contains(point)) { }
result.link = via->link;
return result;
} }
int skip = st::msgServiceNameFont->height + (reply ? 2 * st::msgReplyPadding.top() : 0); replyRight = rectx + rectw - st::msgReplyPadding.right();
recty += skip;
recth -= skip;
} }
if (reply) {
if (QRect(rectx, recty, rectw, recth).contains(point)) {
result.link = reply->replyToLink();
return result;
}
}
replyRight = rectx + rectw - st::msgReplyPadding.right();
} }
const auto fullRight = calculateFullRight(inner); const auto fullRight = calculateFullRight(inner);
const auto rightActionSize = _parent->rightActionSize(); const auto rightActionSize = _parent->rightActionSize();
@ -522,14 +607,18 @@ bool UnwrappedMedia::needInfoDisplay() const {
} }
int UnwrappedMedia::additionalWidth( int UnwrappedMedia::additionalWidth(
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const { 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 (topic) {
accumulate_max(result, 2 * st::msgReplyPadding.left() + topic->name.maxWidth() + st::topicButtonArrowSkip + st::topicButtonPadding.right());
}
if (forwarded) { if (forwarded) {
accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + forwarded->text.maxWidth() + st::msgReplyPadding.right()); accumulate_max(result, 2 * st::msgReplyPadding.left() + forwarded->text.maxWidth() + st::msgReplyPadding.right());
} else if (via) { } else if (via) {
accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.left()); accumulate_max(result, 2 * st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.right());
} }
if (reply) { if (reply) {
accumulate_max(result, st::msgReplyPadding.left() + reply->replyToWidth()); accumulate_max(result, st::msgReplyPadding.left() + reply->replyToWidth());

View file

@ -17,6 +17,8 @@ struct HistoryMessageForwarded;
namespace HistoryView { namespace HistoryView {
struct TopicButton;
class UnwrappedMedia final : public Media { class UnwrappedMedia final : public Media {
public: public:
class Content { class Content {
@ -111,7 +113,9 @@ public:
private: private:
struct SurroundingInfo { struct SurroundingInfo {
QSize topicSize;
int height = 0; int height = 0;
int panelHeight = 0;
int forwardedHeight = 0; int forwardedHeight = 0;
bool forwardedBreakEverywhere = false; bool forwardedBreakEverywhere = false;
@ -120,6 +124,7 @@ private:
} }
}; };
[[nodiscard]] SurroundingInfo surroundingInfo( [[nodiscard]] SurroundingInfo surroundingInfo(
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded, const HistoryMessageForwarded *forwarded,
@ -128,6 +133,7 @@ private:
Painter &p, Painter &p,
const QRect &inner, const QRect &inner,
const PaintContext &context, const PaintContext &context,
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const; const HistoryMessageForwarded *forwarded) const;
@ -137,6 +143,7 @@ private:
bool needInfoDisplay() const; bool needInfoDisplay() const;
int additionalWidth( int additionalWidth(
const TopicButton *topic,
const HistoryMessageVia *via, const HistoryMessageVia *via,
const HistoryMessageReply *reply, const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const; const HistoryMessageForwarded *forwarded) const;

View file

@ -886,7 +886,7 @@ bool Photo::needsBubble() const {
|| _parent->displayedReply() || _parent->displayedReply()
|| _parent->displayForwardedFrom() || _parent->displayForwardedFrom()
|| _parent->displayFromName() || _parent->displayFromName()
|| _parent->displayTopicButton()); || _parent->displayedTopicButton());
} }
QPoint Photo::resolveCustomInfoRightBottom() const { QPoint Photo::resolveCustomInfoRightBottom() const {