mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add jump-to-topic panel to stickers.
This commit is contained in:
parent
b5cb2bc9f0
commit
587715a966
12 changed files with 219 additions and 122 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -254,7 +254,7 @@ RepliesWidget::RepliesWidget(
|
||||||
setupRootView();
|
setupRootView();
|
||||||
setupShortcuts();
|
setupShortcuts();
|
||||||
|
|
||||||
session().api().requestFullPeer(_history->peer);
|
_history->peer->updateFull();
|
||||||
|
|
||||||
refreshTopBarActiveChat();
|
refreshTopBarActiveChat();
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue