mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Show nice replies with quotes.
This commit is contained in:
parent
4b6107fa56
commit
b9af4f3cb0
15 changed files with 285 additions and 241 deletions
|
@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/main_window.h" // Window::LogoNoMargin.
|
#include "window/main_window.h" // Window::LogoNoMargin.
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/chat/chat_style.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
|
|
@ -40,14 +40,14 @@ void ReplyPreview::prepare(
|
||||||
if (h <= 0) h = 1;
|
if (h <= 0) h = 1;
|
||||||
auto thumbSize = (w > h)
|
auto thumbSize = (w > h)
|
||||||
? QSize(
|
? QSize(
|
||||||
w * st::msgReplyBarSize.height() / h,
|
w * st::historyReplyPreview / h,
|
||||||
st::msgReplyBarSize.height())
|
st::historyReplyPreview)
|
||||||
: QSize(
|
: QSize(
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
h * st::msgReplyBarSize.height() / w);
|
h * st::historyReplyPreview / w);
|
||||||
thumbSize *= style::DevicePixelRatio();
|
thumbSize *= style::DevicePixelRatio();
|
||||||
options |= Option::TransparentBackground;
|
options |= Option::TransparentBackground;
|
||||||
auto outerSize = st::msgReplyBarSize.height();
|
auto outerSize = st::historyReplyPreview;
|
||||||
auto original = spoiler
|
auto original = spoiler
|
||||||
? image->original().scaled(
|
? image->original().scaled(
|
||||||
{ 40, 40 },
|
{ 40, 40 },
|
||||||
|
|
|
@ -3305,6 +3305,7 @@ void HistoryItem::createComponentsHelper(
|
||||||
config.reply.topicPost = LookupReplyIsTopicPost(to)
|
config.reply.topicPost = LookupReplyIsTopicPost(to)
|
||||||
|| (to && to->Has<HistoryServiceTopicInfo>())
|
|| (to && to->Has<HistoryServiceTopicInfo>())
|
||||||
|| (forum && forum->creating(config.reply.topMessageId));
|
|| (forum && forum->creating(config.reply.topMessageId));
|
||||||
|
config.reply.quote = std::move(replyTo.quote);
|
||||||
}
|
}
|
||||||
config.markup = std::move(markup);
|
config.markup = std::move(markup);
|
||||||
if (flags & MessageFlag::HasPostAuthor) config.postAuthor = postAuthor;
|
if (flags & MessageFlag::HasPostAuthor) config.postAuthor = postAuthor;
|
||||||
|
|
|
@ -570,31 +570,32 @@ void HistoryMessageReply::updateName(
|
||||||
std::optional<PeerData*> resolvedSender) const {
|
std::optional<PeerData*> resolvedSender) const {
|
||||||
const auto peer = resolvedSender.value_or(sender(holder));
|
const auto peer = resolvedSender.value_or(sender(holder));
|
||||||
const auto name = peer ? senderName(peer) : senderName(holder);
|
const auto name = peer ? senderName(peer) : senderName(holder);
|
||||||
|
const auto hasPreview = (resolvedStory
|
||||||
|
&& resolvedStory->hasReplyPreview())
|
||||||
|
|| (resolvedMessage
|
||||||
|
&& resolvedMessage->media()
|
||||||
|
&& resolvedMessage->media()->hasReplyPreview());
|
||||||
|
const auto textLeft = hasPreview
|
||||||
|
? (st::messageQuoteStyle.outline
|
||||||
|
+ st::historyReplyPreviewMargin.left()
|
||||||
|
+ st::historyReplyPreview
|
||||||
|
+ st::historyReplyPreviewMargin.right())
|
||||||
|
: st::historyReplyPadding.left();
|
||||||
if (!name.isEmpty()) {
|
if (!name.isEmpty()) {
|
||||||
_name.setText(st::fwdTextStyle, name, Ui::NameTextOptions());
|
_name.setText(st::fwdTextStyle, name, Ui::NameTextOptions());
|
||||||
if (peer) {
|
if (peer) {
|
||||||
_nameVersion = peer->nameVersion();
|
_nameVersion = peer->nameVersion();
|
||||||
}
|
}
|
||||||
bool hasPreview = (resolvedStory
|
const auto w = _name.maxWidth()
|
||||||
&& resolvedStory->hasReplyPreview())
|
+ (originalVia
|
||||||
|| (resolvedMessage
|
? (st::msgServiceFont->spacew + originalVia->maxWidth)
|
||||||
&& resolvedMessage->media()
|
: 0)
|
||||||
&& resolvedMessage->media()->hasReplyPreview());
|
+ (_fields.quote.empty()
|
||||||
int32 previewSkip = hasPreview
|
? 0
|
||||||
? (st::msgReplyBarSize.height()
|
: st::messageTextStyle.blockquote.icon.width());
|
||||||
+ st::msgReplyBarSkip
|
_maxWidth = std::max(
|
||||||
- st::msgReplyBarSize.width()
|
w,
|
||||||
- st::msgReplyBarPos.x())
|
std::min(_text.maxWidth(), st::maxSignatureSize))
|
||||||
: 0;
|
|
||||||
int32 w = _name.maxWidth();
|
|
||||||
if (originalVia) {
|
|
||||||
w += st::msgServiceFont->spacew + originalVia->maxWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
_maxWidth = previewSkip
|
|
||||||
+ std::max(
|
|
||||||
w,
|
|
||||||
std::min(_text.maxWidth(), st::maxSignatureSize))
|
|
||||||
+ (_fields.storyId
|
+ (_fields.storyId
|
||||||
? (st::dialogsMiniReplyStory.skipText
|
? (st::dialogsMiniReplyStory.skipText
|
||||||
+ st::dialogsMiniReplyStory.icon.icon.width())
|
+ st::dialogsMiniReplyStory.icon.icon.width())
|
||||||
|
@ -602,31 +603,48 @@ void HistoryMessageReply::updateName(
|
||||||
} else {
|
} else {
|
||||||
_maxWidth = st::msgDateFont->width(statePhrase());
|
_maxWidth = st::msgDateFont->width(statePhrase());
|
||||||
}
|
}
|
||||||
_maxWidth = st::msgReplyPadding.left()
|
_maxWidth = textLeft
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
+ _maxWidth
|
+ _maxWidth
|
||||||
+ st::msgReplyPadding.right();
|
+ st::historyReplyPadding.right();
|
||||||
|
_minHeight = st::historyReplyPadding.top()
|
||||||
|
+ st::msgServiceNameFont->height
|
||||||
|
+ st::normalFont->height
|
||||||
|
+ st::historyReplyPadding.bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessageReply::resize(int width) const {
|
int HistoryMessageReply::resizeToWidth(int width) const {
|
||||||
|
const auto hasPreview = (resolvedStory
|
||||||
|
&& resolvedStory->hasReplyPreview())
|
||||||
|
|| (resolvedMessage
|
||||||
|
&& resolvedMessage->media()
|
||||||
|
&& resolvedMessage->media()->hasReplyPreview());
|
||||||
|
const auto textLeft = hasPreview
|
||||||
|
? (st::messageQuoteStyle.outline
|
||||||
|
+ st::historyReplyPreviewMargin.left()
|
||||||
|
+ st::historyReplyPreview
|
||||||
|
+ st::historyReplyPreviewMargin.right())
|
||||||
|
: st::historyReplyPadding.left();
|
||||||
if (originalVia) {
|
if (originalVia) {
|
||||||
bool hasPreview = (resolvedStory
|
|
||||||
&& resolvedStory->hasReplyPreview())
|
|
||||||
|| (resolvedMessage
|
|
||||||
&& resolvedMessage->media()
|
|
||||||
&& resolvedMessage->media()->hasReplyPreview());
|
|
||||||
int previewSkip = hasPreview
|
|
||||||
? (st::msgReplyBarSize.height()
|
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x())
|
|
||||||
: 0;
|
|
||||||
originalVia->resize(width
|
originalVia->resize(width
|
||||||
- st::msgReplyBarSkip
|
- textLeft
|
||||||
- previewSkip
|
- st::historyReplyPadding.right()
|
||||||
- _name.maxWidth()
|
- _name.maxWidth()
|
||||||
- st::msgServiceFont->spacew);
|
- st::msgServiceFont->spacew);
|
||||||
}
|
}
|
||||||
|
if (width >= _maxWidth) {
|
||||||
|
_height = _minHeight;
|
||||||
|
return height();
|
||||||
|
}
|
||||||
|
_height = _minHeight;
|
||||||
|
return height();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryMessageReply::height() const {
|
||||||
|
return _height + st::historyReplyTop + st::historyReplyBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins HistoryMessageReply::margins() const {
|
||||||
|
return QMargins(0, st::historyReplyTop, 0, st::historyReplyBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessageReply::itemRemoved(
|
void HistoryMessageReply::itemRemoved(
|
||||||
|
@ -658,58 +676,66 @@ void HistoryMessageReply::paint(
|
||||||
const auto st = context.st;
|
const auto st = context.st;
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
|
|
||||||
{
|
y += st::historyReplyTop;
|
||||||
const auto opacity = p.opacity();
|
const auto rect = QRect(x, y, w, _height);
|
||||||
const auto outerWidth = w + 2 * x;
|
const auto hasQuote = !_fields.quote.empty();
|
||||||
const auto &bar = !inBubble
|
const auto selected = context.selected();
|
||||||
? st->msgImgReplyBarColor()
|
const auto cache = !inBubble
|
||||||
: _colorIndexPlusOne
|
? (hasQuote
|
||||||
? HistoryView::FromNameFg(context, _colorIndexPlusOne - 1)
|
? st->serviceQuoteCache()
|
||||||
: stm->msgReplyBarColor;
|
: st->serviceReplyCache()).get()
|
||||||
const auto rbar = style::rtlrect(
|
: _colorIndexPlusOne
|
||||||
x + st::msgReplyBarPos.x(),
|
? (hasQuote
|
||||||
y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(),
|
? st->coloredQuoteCache(selected, _colorIndexPlusOne - 1)
|
||||||
st::msgReplyBarSize.width(),
|
: st->coloredReplyCache(selected, _colorIndexPlusOne - 1)).get()
|
||||||
st::msgReplyBarSize.height(),
|
: (hasQuote ? stm->quoteCache : stm->replyCache).get();
|
||||||
outerWidth);
|
const auto "eSt = hasQuote
|
||||||
|
? st::messageTextStyle.blockquote
|
||||||
if (ripple.animation) {
|
: st::messageQuoteStyle;
|
||||||
const auto colorOverride = &stm->msgWaveformInactive->c;
|
const auto rippleColor = cache->bg;
|
||||||
p.setOpacity(st::historyPollRippleOpacity);
|
if (!inBubble) {
|
||||||
ripple.animation->paint(
|
cache->bg = QColor(0, 0, 0, 0);
|
||||||
p,
|
}
|
||||||
x - st::msgReplyPadding.left(),
|
Ui::Text::ValidateQuotePaintCache(*cache, quoteSt);
|
||||||
y,
|
Ui::Text::FillQuotePaint(p, rect, *cache, quoteSt);
|
||||||
outerWidth,
|
if (!inBubble) {
|
||||||
colorOverride);
|
cache->bg = rippleColor;
|
||||||
if (ripple.animation->empty()) {
|
|
||||||
ripple.animation.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.setOpacity(opacity * kBarAlpha);
|
|
||||||
p.fillRect(rbar, bar);
|
|
||||||
p.setOpacity(opacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ripple.animation) {
|
||||||
|
ripple.animation->paint(p, x, y, w, &rippleColor);
|
||||||
|
if (ripple.animation->empty()) {
|
||||||
|
ripple.animation.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto withPreviewLeft = st::messageQuoteStyle.outline
|
||||||
|
+ st::historyReplyPreviewMargin.left()
|
||||||
|
+ st::historyReplyPreview
|
||||||
|
+ st::historyReplyPreviewMargin.right();
|
||||||
|
auto textLeft = st::historyReplyPadding.left();
|
||||||
const auto pausedSpoiler = context.paused
|
const auto pausedSpoiler = context.paused
|
||||||
|| On(PowerSaving::kChatSpoiler);
|
|| On(PowerSaving::kChatSpoiler);
|
||||||
if (w > st::msgReplyBarSkip) {
|
if (w > textLeft) {
|
||||||
if (resolvedMessage || resolvedStory || !_text.isEmpty()) {
|
if (resolvedMessage || resolvedStory || !_text.isEmpty()) {
|
||||||
const auto media = resolvedMessage ? resolvedMessage->media() : nullptr;
|
const auto media = resolvedMessage ? resolvedMessage->media() : nullptr;
|
||||||
auto hasPreview = (media && media->hasReplyPreview())
|
auto hasPreview = (media && media->hasReplyPreview())
|
||||||
|| (resolvedStory && resolvedStory->hasReplyPreview());
|
|| (resolvedStory && resolvedStory->hasReplyPreview());
|
||||||
if (hasPreview && w < st::msgReplyBarSkip + st::msgReplyBarSize.height()) {
|
if (hasPreview && w <= withPreviewLeft) {
|
||||||
hasPreview = false;
|
hasPreview = false;
|
||||||
}
|
}
|
||||||
auto previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
|
|
||||||
|
|
||||||
if (hasPreview) {
|
if (hasPreview) {
|
||||||
|
textLeft = withPreviewLeft;
|
||||||
const auto image = media
|
const auto image = media
|
||||||
? media->replyPreview()
|
? media->replyPreview()
|
||||||
: resolvedStory->replyPreview();
|
: resolvedStory->replyPreview();
|
||||||
if (image) {
|
if (image) {
|
||||||
auto to = style::rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x);
|
auto to = style::rtlrect(
|
||||||
|
x + st::historyReplyPreviewMargin.left(),
|
||||||
|
y + st::historyReplyPreviewMargin.top(),
|
||||||
|
st::historyReplyPreview,
|
||||||
|
st::historyReplyPreview,
|
||||||
|
w + 2 * x);
|
||||||
const auto preview = image->pixSingle(
|
const auto preview = image->pixSingle(
|
||||||
image->size() / style::DevicePixelRatio(),
|
image->size() / style::DevicePixelRatio(),
|
||||||
{
|
{
|
||||||
|
@ -732,7 +758,8 @@ void HistoryMessageReply::paint(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w > st::msgReplyBarSkip + previewSkip) {
|
if (w > textLeft + st::historyReplyPadding.right()) {
|
||||||
|
w -= textLeft + st::historyReplyPadding.right();
|
||||||
p.setPen(!inBubble
|
p.setPen(!inBubble
|
||||||
? st->msgImgReplyBarColor()
|
? st->msgImgReplyBarColor()
|
||||||
: _colorIndexPlusOne
|
: _colorIndexPlusOne
|
||||||
|
@ -740,10 +767,10 @@ void HistoryMessageReply::paint(
|
||||||
context,
|
context,
|
||||||
_colorIndexPlusOne - 1)
|
_colorIndexPlusOne - 1)
|
||||||
: stm->msgServiceFg);
|
: stm->msgServiceFg);
|
||||||
_name.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
|
_name.drawLeftElided(p, x + textLeft, y + st::historyReplyPadding.top(), w, w + 2 * x + 2 * textLeft);
|
||||||
if (originalVia && w > st::msgReplyBarSkip + previewSkip + _name.maxWidth() + st::msgServiceFont->spacew) {
|
if (originalVia && w > _name.maxWidth() + st::msgServiceFont->spacew) {
|
||||||
p.setFont(st::msgServiceFont);
|
p.setFont(st::msgServiceFont);
|
||||||
p.drawText(x + st::msgReplyBarSkip + previewSkip + _name.maxWidth() + st::msgServiceFont->spacew, y + st::msgReplyPadding.top() + st::msgServiceFont->ascent, originalVia->text);
|
p.drawText(x + textLeft + _name.maxWidth() + st::msgServiceFont->spacew, y + st::historyReplyPadding.top() + st::msgServiceFont->ascent, originalVia->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(inBubble
|
p.setPen(inBubble
|
||||||
|
@ -751,8 +778,8 @@ void HistoryMessageReply::paint(
|
||||||
: st->msgImgReplyBarColor());
|
: st->msgImgReplyBarColor());
|
||||||
holder->prepareCustomEmojiPaint(p, context, _text);
|
holder->prepareCustomEmojiPaint(p, context, _text);
|
||||||
auto replyToTextPosition = QPoint(
|
auto replyToTextPosition = QPoint(
|
||||||
x + st::msgReplyBarSkip + previewSkip,
|
x + textLeft,
|
||||||
y + st::msgReplyPadding.top() + st::msgServiceNameFont->height);
|
y + st::historyReplyPadding.top() + st::msgServiceNameFont->height);
|
||||||
const auto replyToTextPalette = &(inBubble
|
const auto replyToTextPalette = &(inBubble
|
||||||
? stm->replyTextPalette
|
? stm->replyTextPalette
|
||||||
: st->imgReplyTextPalette());
|
: st->imgReplyTextPalette());
|
||||||
|
@ -760,7 +787,7 @@ void HistoryMessageReply::paint(
|
||||||
st::dialogsMiniReplyStory.icon.icon.paint(
|
st::dialogsMiniReplyStory.icon.icon.paint(
|
||||||
p,
|
p,
|
||||||
replyToTextPosition,
|
replyToTextPosition,
|
||||||
w - st::msgReplyBarSkip - previewSkip,
|
w + 2 * x + 2 * textLeft,
|
||||||
replyToTextPalette->linkFg->c);
|
replyToTextPalette->linkFg->c);
|
||||||
replyToTextPosition += QPoint(
|
replyToTextPosition += QPoint(
|
||||||
st::dialogsMiniReplyStory.skipText
|
st::dialogsMiniReplyStory.skipText
|
||||||
|
@ -769,7 +796,7 @@ void HistoryMessageReply::paint(
|
||||||
}
|
}
|
||||||
_text.draw(p, {
|
_text.draw(p, {
|
||||||
.position = replyToTextPosition,
|
.position = replyToTextPosition,
|
||||||
.availableWidth = w - st::msgReplyBarSkip - previewSkip,
|
.availableWidth = w,
|
||||||
.palette = replyToTextPalette,
|
.palette = replyToTextPalette,
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
@ -782,10 +809,14 @@ void HistoryMessageReply::paint(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
p.setPen(inBubble
|
p.setPen(cache->outline);
|
||||||
? stm->msgDateFg
|
p.drawTextLeft(
|
||||||
: st->msgDateImgFg());
|
x + textLeft,
|
||||||
p.drawTextLeft(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2, w + 2 * x, st::msgDateFont->elided(statePhrase(), w - st::msgReplyBarSkip));
|
(y + (_height - st::msgDateFont->height) / 2),
|
||||||
|
w + 2 * x + 2 * textLeft,
|
||||||
|
st::msgDateFont->elided(
|
||||||
|
statePhrase(),
|
||||||
|
w - textLeft - st::historyReplyPadding.right()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,9 @@ struct HistoryMessageReply
|
||||||
void updateName(
|
void updateName(
|
||||||
not_null<HistoryItem*> holder,
|
not_null<HistoryItem*> holder,
|
||||||
std::optional<PeerData*> resolvedSender = std::nullopt) const;
|
std::optional<PeerData*> resolvedSender = std::nullopt) const;
|
||||||
void resize(int width) const;
|
[[nodiscard]] int resizeToWidth(int width) const;
|
||||||
|
[[nodiscard]] int height() const;
|
||||||
|
[[nodiscard]] QMargins margins() const;
|
||||||
void itemRemoved(
|
void itemRemoved(
|
||||||
not_null<HistoryItem*> holder,
|
not_null<HistoryItem*> holder,
|
||||||
not_null<HistoryItem*> removed);
|
not_null<HistoryItem*> removed);
|
||||||
|
@ -325,7 +327,6 @@ struct HistoryMessageReply
|
||||||
ReplyToStoryPointer resolvedStory;
|
ReplyToStoryPointer resolvedStory;
|
||||||
std::unique_ptr<HistoryMessageVia> originalVia;
|
std::unique_ptr<HistoryMessageVia> originalVia;
|
||||||
std::unique_ptr<Ui::SpoilerAnimation> spoiler;
|
std::unique_ptr<Ui::SpoilerAnimation> spoiler;
|
||||||
int toWidth = 0;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
mutable std::unique_ptr<Ui::RippleAnimation> animation;
|
mutable std::unique_ptr<Ui::RippleAnimation> animation;
|
||||||
|
@ -339,8 +340,10 @@ private:
|
||||||
mutable Ui::Text::String _text;
|
mutable Ui::Text::String _text;
|
||||||
mutable PeerData *_externalSender = nullptr;
|
mutable PeerData *_externalSender = nullptr;
|
||||||
mutable int _maxWidth = 0;
|
mutable int _maxWidth = 0;
|
||||||
|
mutable int _minHeight = 0;
|
||||||
|
mutable int _height = 0;
|
||||||
mutable int _nameVersion = 0;
|
mutable int _nameVersion = 0;
|
||||||
uint8 _colorIndexPlusOne : 7 = 0;
|
uint8 _colorIndexPlusOne : 6 = 0;
|
||||||
uint8 _unavailable : 1 = 0;
|
uint8 _unavailable : 1 = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4352,9 +4352,11 @@ void HistoryWidget::updateOverStates(QPoint pos) {
|
||||||
&& _photoEditMedia
|
&& _photoEditMedia
|
||||||
&& QRect(
|
&& QRect(
|
||||||
replyEditForwardInfoRect.x(),
|
replyEditForwardInfoRect.x(),
|
||||||
replyEditForwardInfoRect.y() + st::msgReplyPadding.top(),
|
(replyEditForwardInfoRect.y()
|
||||||
st::msgReplyBarSize.height(),
|
+ (replyEditForwardInfoRect.height()
|
||||||
st::msgReplyBarSize.height()).contains(pos);
|
- st::historyReplyPreview) / 2),
|
||||||
|
st::historyReplyPreview,
|
||||||
|
st::historyReplyPreview).contains(pos);
|
||||||
auto inClickable = inReplyEditForward;
|
auto inClickable = inReplyEditForward;
|
||||||
if (_inPhotoEdit != inPhotoEdit) {
|
if (_inPhotoEdit != inPhotoEdit) {
|
||||||
_inPhotoEdit = inPhotoEdit;
|
_inPhotoEdit = inPhotoEdit;
|
||||||
|
@ -7809,7 +7811,9 @@ void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
|
||||||
};
|
};
|
||||||
_replyEditMsgText.setMarkedText(
|
_replyEditMsgText.setMarkedText(
|
||||||
st::defaultTextStyle,
|
st::defaultTextStyle,
|
||||||
item->inReplyText(),
|
((_editMsgId || _replyTo.quote.empty())
|
||||||
|
? item->inReplyText()
|
||||||
|
: _replyTo.quote),
|
||||||
Ui::DialogTextOptions(),
|
Ui::DialogTextOptions(),
|
||||||
context);
|
context);
|
||||||
if (fieldOrDisabledShown() || isRecording()) {
|
if (fieldOrDisabledShown() || isRecording()) {
|
||||||
|
@ -7956,7 +7960,11 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
const auto overEdit = _photoEditMedia
|
const auto overEdit = _photoEditMedia
|
||||||
? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.)
|
? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.)
|
||||||
: 0.;
|
: 0.;
|
||||||
auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
auto to = QRect(
|
||||||
|
replyLeft,
|
||||||
|
backy + (st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
|
st::historyReplyPreview,
|
||||||
|
st::historyReplyPreview);
|
||||||
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
||||||
preview->size() / style::DevicePixelRatio(),
|
preview->size() / style::DevicePixelRatio(),
|
||||||
{
|
{
|
||||||
|
@ -7980,7 +7988,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
replyLeft += st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
}
|
}
|
||||||
p.setPen(st::historyReplyNameFg);
|
p.setPen(st::historyReplyNameFg);
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
|
@ -8004,7 +8012,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
} else {
|
} else {
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
p.setPen(st::historyComposeAreaFgService);
|
p.setPen(st::historyComposeAreaFgService);
|
||||||
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
|
p.drawText(replyLeft, backy + (st::historyReplyHeight - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (hasForward) {
|
} else if (hasForward) {
|
||||||
|
@ -8020,24 +8028,15 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
}
|
}
|
||||||
if (drawWebPagePreview) {
|
if (drawWebPagePreview) {
|
||||||
const auto textTop = backy + st::msgReplyPadding.top();
|
const auto textTop = backy + st::msgReplyPadding.top();
|
||||||
auto previewLeft = st::historyReplySkip + st::webPageLeft;
|
auto previewLeft = st::historyReplySkip;
|
||||||
p.fillRect(
|
|
||||||
st::historyReplySkip,
|
|
||||||
textTop,
|
|
||||||
st::webPageBar,
|
|
||||||
st::msgReplyBarSize.height(),
|
|
||||||
st::msgInReplyBarColor);
|
|
||||||
|
|
||||||
const auto to = QRect(
|
const auto to = QRect(
|
||||||
previewLeft,
|
previewLeft,
|
||||||
textTop,
|
backy + (st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
st::msgReplyBarSize.height());
|
st::historyReplyPreview);
|
||||||
if (HistoryView::DrawWebPageDataPreview(p, _previewData, _peer, to)) {
|
if (HistoryView::DrawWebPageDataPreview(p, _previewData, _peer, to)) {
|
||||||
previewLeft += st::msgReplyBarSize.height()
|
previewLeft += st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x();
|
|
||||||
}
|
}
|
||||||
p.setPen(st::historyReplyNameFg);
|
p.setPen(st::historyReplyNameFg);
|
||||||
const auto elidedWidth = width()
|
const auto elidedWidth = width()
|
||||||
|
|
|
@ -776,23 +776,14 @@ void FieldHeader::paintWebPage(Painter &p, not_null<PeerData*> context) {
|
||||||
|
|
||||||
const auto textTop = st::msgReplyPadding.top();
|
const auto textTop = st::msgReplyPadding.top();
|
||||||
auto previewLeft = st::historyReplySkip + st::webPageLeft;
|
auto previewLeft = st::historyReplySkip + st::webPageLeft;
|
||||||
p.fillRect(
|
|
||||||
st::historyReplySkip,
|
|
||||||
textTop,
|
|
||||||
st::webPageBar,
|
|
||||||
st::msgReplyBarSize.height(),
|
|
||||||
st::msgInReplyBarColor);
|
|
||||||
|
|
||||||
const QRect to(
|
const QRect to(
|
||||||
previewLeft,
|
previewLeft,
|
||||||
textTop,
|
(st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
st::msgReplyBarSize.height());
|
st::historyReplyPreview);
|
||||||
if (HistoryView::DrawWebPageDataPreview(p, _preview.data, context, to)) {
|
if (HistoryView::DrawWebPageDataPreview(p, _preview.data, context, to)) {
|
||||||
previewLeft += st::msgReplyBarSize.height()
|
previewLeft += st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x();
|
|
||||||
}
|
}
|
||||||
const auto elidedWidth = width()
|
const auto elidedWidth = width()
|
||||||
- previewLeft
|
- previewLeft
|
||||||
|
@ -826,8 +817,7 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) {
|
||||||
if (!_shownMessage) {
|
if (!_shownMessage) {
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
p.setPen(st::historyComposeAreaFgService);
|
p.setPen(st::historyComposeAreaFgService);
|
||||||
const auto top = (st::msgReplyPadding.top()
|
const auto top = (st::historyReplyHeight - st::msgDateFont->height) / 2;
|
||||||
+ (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2);
|
|
||||||
p.drawText(
|
p.drawText(
|
||||||
replySkip,
|
replySkip,
|
||||||
top + st::msgDateFont->ascent,
|
top + st::msgDateFont->ascent,
|
||||||
|
@ -863,10 +853,8 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) {
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const auto previewSkipValue = st::msgReplyBarSize.height()
|
const auto previewSkipValue = st::historyReplyPreview
|
||||||
+ st::msgReplyBarSkip
|
+ st::msgReplyBarSkip;
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x();
|
|
||||||
const auto previewSkip = _shownMessageHasPreview ? previewSkipValue : 0;
|
const auto previewSkip = _shownMessageHasPreview ? previewSkipValue : 0;
|
||||||
const auto textLeft = replySkip + previewSkip;
|
const auto textLeft = replySkip + previewSkip;
|
||||||
const auto textAvailableWidth = availableWidth - previewSkip;
|
const auto textAvailableWidth = availableWidth - previewSkip;
|
||||||
|
@ -876,9 +864,9 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) {
|
||||||
: 0.;
|
: 0.;
|
||||||
const auto to = QRect(
|
const auto to = QRect(
|
||||||
replySkip,
|
replySkip,
|
||||||
st::msgReplyPadding.top(),
|
(st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
st::msgReplyBarSize.height());
|
st::historyReplyPreview);
|
||||||
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
||||||
preview->size() / style::DevicePixelRatio(),
|
preview->size() / style::DevicePixelRatio(),
|
||||||
{
|
{
|
||||||
|
@ -999,9 +987,9 @@ void FieldHeader::updateControlsGeometry(QSize size) {
|
||||||
height());
|
height());
|
||||||
_shownMessagePreviewRect = QRect(
|
_shownMessagePreviewRect = QRect(
|
||||||
st::historyReplySkip,
|
st::historyReplySkip,
|
||||||
st::msgReplyPadding.top(),
|
(st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
st::msgReplyBarSize.height());
|
st::historyReplyPreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldHeader::editMessage(FullMsgId id, bool photoEditAllowed) {
|
void FieldHeader::editMessage(FullMsgId id, bool photoEditAllowed) {
|
||||||
|
|
|
@ -362,9 +362,9 @@ void ForwardPanel::paint(
|
||||||
if (preview) {
|
if (preview) {
|
||||||
auto to = QRect(
|
auto to = QRect(
|
||||||
x,
|
x,
|
||||||
y + st::msgReplyPadding.top(),
|
y + (st::historyReplyHeight - st::historyReplyPreview) / 2,
|
||||||
st::msgReplyBarSize.height(),
|
st::historyReplyPreview,
|
||||||
st::msgReplyBarSize.height());
|
st::historyReplyPreview);
|
||||||
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
|
||||||
preview->size() / style::DevicePixelRatio(),
|
preview->size() / style::DevicePixelRatio(),
|
||||||
{
|
{
|
||||||
|
@ -375,10 +375,7 @@ void ForwardPanel::paint(
|
||||||
Ui::FillSpoilerRect(p, to, Ui::DefaultImageSpoiler().frame(
|
Ui::FillSpoilerRect(p, to, Ui::DefaultImageSpoiler().frame(
|
||||||
_spoiler->index(now, pausedSpoiler)));
|
_spoiler->index(now, pausedSpoiler)));
|
||||||
}
|
}
|
||||||
const auto skip = st::msgReplyBarSize.height()
|
const auto skip = st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x();
|
|
||||||
x += skip;
|
x += skip;
|
||||||
available -= skip;
|
available -= skip;
|
||||||
}
|
}
|
||||||
|
|
|
@ -776,9 +776,12 @@ QSize Message::performCountOptimalSize() {
|
||||||
accumulate_max(maxWidth, namew);
|
accumulate_max(maxWidth, namew);
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
auto replyw = st::msgPadding.left() + reply->maxWidth() - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
|
auto replyw = st::msgPadding.left()
|
||||||
|
+ reply->maxWidth()
|
||||||
|
+ st::msgPadding.right();
|
||||||
if (reply->originalVia) {
|
if (reply->originalVia) {
|
||||||
replyw += st::msgServiceFont->spacew + reply->originalVia->maxWidth;
|
replyw += st::msgServiceFont->spacew
|
||||||
|
+ reply->originalVia->maxWidth;
|
||||||
}
|
}
|
||||||
accumulate_max(maxWidth, replyw);
|
accumulate_max(maxWidth, replyw);
|
||||||
}
|
}
|
||||||
|
@ -1558,9 +1561,8 @@ void Message::paintReplyInfo(
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
const PaintContext &context) const {
|
const PaintContext &context) const {
|
||||||
if (const auto reply = displayedReply()) {
|
if (const auto reply = displayedReply()) {
|
||||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
|
||||||
reply->paint(p, this, context, trect.x(), trect.y(), trect.width(), true);
|
reply->paint(p, this, context, trect.x(), trect.y(), trect.width(), true);
|
||||||
trect.setY(trect.y() + h);
|
trect.setY(trect.y() + reply->height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,41 +1763,18 @@ void Message::toggleReplyRipple(bool pressed) {
|
||||||
|
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
if (!reply->ripple.animation && !unwrapped()) {
|
if (!reply->ripple.animation && !unwrapped()) {
|
||||||
const auto smallTop = displayFromName()
|
const auto &padding = st::msgPadding;
|
||||||
|| displayedTopicButton()
|
|
||||||
|| displayForwardedFrom();
|
|
||||||
const auto rounding = countBubbleRounding();
|
|
||||||
|
|
||||||
using Corner = Ui::BubbleCornerRounding;
|
|
||||||
using Radius = Ui::CachedCornerRadius;
|
|
||||||
const auto &small = Ui::CachedCornersMasks(Radius::ThumbSmall);
|
|
||||||
const auto &large = Ui::CachedCornersMasks(Radius::ThumbLarge);
|
|
||||||
const auto corners = std::array<QImage, 4>{{
|
|
||||||
((smallTop || (rounding.topLeft == Corner::Small))
|
|
||||||
? small
|
|
||||||
: large)[0],
|
|
||||||
((smallTop || (rounding.topRight == Corner::Small))
|
|
||||||
? small
|
|
||||||
: large)[1],
|
|
||||||
small[2],
|
|
||||||
small[3],
|
|
||||||
}};
|
|
||||||
|
|
||||||
const auto &padding = st::msgReplyPadding;
|
|
||||||
const auto geometry = countGeometry();
|
const auto geometry = countGeometry();
|
||||||
const auto item = data();
|
const auto item = data();
|
||||||
|
const auto margins = reply->margins();
|
||||||
const auto size = QSize(
|
const auto size = QSize(
|
||||||
geometry.width()
|
geometry.width() - padding.left() - padding.right(),
|
||||||
- padding.left() / 2
|
reply->height() - margins.top() - margins.bottom());
|
||||||
- padding.right(),
|
|
||||||
st::msgReplyBarSize.height()
|
|
||||||
+ padding.top()
|
|
||||||
+ padding.bottom());
|
|
||||||
reply->ripple.animation = std::make_unique<Ui::RippleAnimation>(
|
reply->ripple.animation = std::make_unique<Ui::RippleAnimation>(
|
||||||
st::defaultRippleAnimation,
|
st::defaultRippleAnimation,
|
||||||
Images::Round(
|
Ui::RippleAnimation::RoundRectMask(
|
||||||
Ui::RippleAnimation::MaskByDrawer(size, true, nullptr),
|
size,
|
||||||
corners),
|
st::messageQuoteStyle.radius),
|
||||||
[=] { item->history()->owner().requestItemRepaint(item); });
|
[=] { item->history()->owner().requestItemRepaint(item); });
|
||||||
}
|
}
|
||||||
if (reply->ripple.animation) {
|
if (reply->ripple.animation) {
|
||||||
|
@ -2436,14 +2415,15 @@ bool Message::getStateReplyInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<TextState*> outResult) const {
|
not_null<TextState*> outResult) const {
|
||||||
if (auto reply = displayedReply()) {
|
if (const auto reply = displayedReply()) {
|
||||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
const auto margins = reply->margins();
|
||||||
if (point.y() >= trect.top() && point.y() < trect.top() + h) {
|
const auto height = reply->height();
|
||||||
|
if (point.y() >= trect.top() && point.y() < trect.top() + height) {
|
||||||
const auto g = QRect(
|
const auto g = QRect(
|
||||||
trect.x(),
|
trect.x(),
|
||||||
trect.y() + st::msgReplyPadding.top(),
|
trect.y() + margins.top(),
|
||||||
trect.width(),
|
trect.width(),
|
||||||
st::msgReplyBarSize.height());
|
height - margins.top() - margins.bottom());
|
||||||
if (g.contains(point)) {
|
if (g.contains(point)) {
|
||||||
if (const auto link = reply->link()) {
|
if (const auto link = reply->link()) {
|
||||||
outResult->link = reply->link();
|
outResult->link = reply->link();
|
||||||
|
@ -2452,7 +2432,7 @@ bool Message::getStateReplyInfo(
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
trect.setTop(trect.top() + h);
|
trect.setTop(trect.top() + height);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2530,9 +2510,8 @@ void Message::updatePressed(QPoint point) {
|
||||||
auto fwdheight = ((forwarded->text.maxWidth() > trect.width()) ? 2 : 1) * st::semiboldFont->height;
|
auto fwdheight = ((forwarded->text.maxWidth() > trect.width()) ? 2 : 1) * st::semiboldFont->height;
|
||||||
trect.setTop(trect.top() + fwdheight);
|
trect.setTop(trect.top() + fwdheight);
|
||||||
}
|
}
|
||||||
if (item->Get<HistoryMessageReply>()) {
|
if (const auto reply = item->Get<HistoryMessageReply>()) {
|
||||||
auto h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
trect.setTop(trect.top() + reply->height());
|
||||||
trect.setTop(trect.top() + h);
|
|
||||||
}
|
}
|
||||||
if (const auto via = item->Get<HistoryMessageVia>()) {
|
if (const auto via = item->Get<HistoryMessageVia>()) {
|
||||||
if (!displayFromName() && !displayForwardedFrom()) {
|
if (!displayFromName() && !displayForwardedFrom()) {
|
||||||
|
@ -3642,13 +3621,9 @@ QRect Message::innerGeometry() const {
|
||||||
+ st::topicButtonSkip);
|
+ st::topicButtonSkip);
|
||||||
}
|
}
|
||||||
// Skip displayForwardedFrom() until there are no animations for it.
|
// Skip displayForwardedFrom() until there are no animations for it.
|
||||||
if (displayedReply()) {
|
if (const auto reply = displayedReply()) {
|
||||||
// See paintReplyInfo().
|
// See paintReplyInfo().
|
||||||
result.translate(
|
result.translate(0, reply->height());
|
||||||
0,
|
|
||||||
st::msgReplyPadding.top()
|
|
||||||
+ st::msgReplyBarSize.height()
|
|
||||||
+ st::msgReplyPadding.bottom());
|
|
||||||
}
|
}
|
||||||
if (!displayFromName() && !displayForwardedFrom()) {
|
if (!displayFromName() && !displayForwardedFrom()) {
|
||||||
// See paintViaBotIdInfo().
|
// See paintViaBotIdInfo().
|
||||||
|
@ -3900,9 +3875,10 @@ int Message::resizeContentGetHeight(int newWidth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply) {
|
if (reply) {
|
||||||
reply->resize(contentWidth - st::msgPadding.left() - st::msgPadding.right());
|
newHeight += reply->resizeToWidth(contentWidth
|
||||||
|
- st::msgPadding.left()
|
||||||
|
- st::msgPadding.right());
|
||||||
reply->ripple.animation = nullptr;
|
reply->ripple.animation = nullptr;
|
||||||
newHeight += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
|
||||||
}
|
}
|
||||||
if (needInfoDisplay()) {
|
if (needInfoDisplay()) {
|
||||||
newHeight += (bottomInfoHeight - st::msgDateFont->height);
|
newHeight += (bottomInfoHeight - st::msgDateFont->height);
|
||||||
|
|
|
@ -286,7 +286,7 @@ QSize Gif::countCurrentSize(int newWidth) {
|
||||||
via->resize(availw);
|
via->resize(availw);
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
reply->resize(availw);
|
[[maybe_unused]] int height = reply->resizeToWidth(availw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -652,16 +652,21 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
if (via || reply || forwarded) {
|
if (via || reply || forwarded) {
|
||||||
auto rectw = width() - usew - st::msgReplyPadding.left();
|
auto rectw = width() - usew - st::msgReplyPadding.left();
|
||||||
auto innerw = rectw - (st::msgReplyPadding.left() + st::msgReplyPadding.right());
|
auto innerw = rectw - (st::msgReplyPadding.left() + st::msgReplyPadding.right());
|
||||||
auto recth = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
auto recth = 0;
|
||||||
auto forwardedHeightReal = forwarded ? forwarded->text.countHeight(innerw) : 0;
|
auto forwardedHeightReal = forwarded ? forwarded->text.countHeight(innerw) : 0;
|
||||||
auto forwardedHeight = qMin(forwardedHeightReal, kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
auto forwardedHeight = qMin(forwardedHeightReal, kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
||||||
if (forwarded) {
|
if (forwarded) {
|
||||||
recth += forwardedHeight;
|
recth += st::msgReplyPadding.top() + forwardedHeight;
|
||||||
} else if (via) {
|
} else if (via) {
|
||||||
recth += st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
recth += st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
recth += st::msgReplyBarSize.height();
|
const auto replyMargins = reply->margins();
|
||||||
|
recth += reply->height()
|
||||||
|
- ((forwarded || via) ? 0 : replyMargins.top())
|
||||||
|
- replyMargins.bottom();
|
||||||
|
} else {
|
||||||
|
recth += st::msgReplyPadding.bottom();
|
||||||
}
|
}
|
||||||
int rectx = rightAligned ? 0 : (usew + st::msgReplyPadding.left());
|
int rectx = rightAligned ? 0 : (usew + st::msgReplyPadding.left());
|
||||||
int recty = painty;
|
int recty = painty;
|
||||||
|
@ -669,25 +674,31 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
|
|
||||||
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
|
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
|
||||||
p.setPen(st->msgServiceFg());
|
p.setPen(st->msgServiceFg());
|
||||||
rectx += st::msgReplyPadding.left();
|
const auto textx = rectx + st::msgReplyPadding.left();
|
||||||
rectw = innerw;
|
const auto textw = rectw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
|
||||||
if (forwarded) {
|
if (forwarded) {
|
||||||
p.setTextPalette(st->serviceTextPalette());
|
p.setTextPalette(st->serviceTextPalette());
|
||||||
auto breakEverywhere = (forwardedHeightReal > forwardedHeight);
|
auto breakEverywhere = (forwardedHeightReal > forwardedHeight);
|
||||||
forwarded->text.drawElided(p, rectx, recty + st::msgReplyPadding.top(), rectw, kMaxGifForwardedBarLines, style::al_left, 0, -1, 0, breakEverywhere);
|
forwarded->text.drawElided(p, textx, recty + st::msgReplyPadding.top(), textw, kMaxGifForwardedBarLines, style::al_left, 0, -1, 0, breakEverywhere);
|
||||||
p.restoreTextPalette();
|
p.restoreTextPalette();
|
||||||
|
|
||||||
const auto skip = std::min(
|
const auto skip = std::min(
|
||||||
forwarded->text.countHeight(rectw),
|
forwarded->text.countHeight(textw),
|
||||||
kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
||||||
recty += skip;
|
recty += skip;
|
||||||
} else if (via) {
|
} else if (via) {
|
||||||
p.setFont(st::msgServiceNameFont);
|
p.setFont(st::msgServiceNameFont);
|
||||||
p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text);
|
p.drawTextLeft(textx, recty + st::msgReplyPadding.top(), 2 * textx + textw, via->text);
|
||||||
int skip = st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
int skip = st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
||||||
recty += skip;
|
recty += skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
if (forwarded || via) {
|
||||||
|
recty += st::msgReplyPadding.top();
|
||||||
|
recth -= st::msgReplyPadding.top();
|
||||||
|
} else {
|
||||||
|
recty -= reply->margins().top();
|
||||||
|
}
|
||||||
reply->paint(p, _parent, context, rectx, recty, rectw, false);
|
reply->paint(p, _parent, context, rectx, recty, rectw, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1019,16 +1030,21 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
|
||||||
if (via || reply || forwarded) {
|
if (via || reply || forwarded) {
|
||||||
auto rectw = paintw - usew - st::msgReplyPadding.left();
|
auto rectw = paintw - usew - st::msgReplyPadding.left();
|
||||||
auto innerw = rectw - (st::msgReplyPadding.left() + st::msgReplyPadding.right());
|
auto innerw = rectw - (st::msgReplyPadding.left() + st::msgReplyPadding.right());
|
||||||
auto recth = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
auto recth = 0;
|
||||||
auto forwardedHeightReal = forwarded ? forwarded->text.countHeight(innerw) : 0;
|
auto forwardedHeightReal = forwarded ? forwarded->text.countHeight(innerw) : 0;
|
||||||
auto forwardedHeight = qMin(forwardedHeightReal, kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
auto forwardedHeight = qMin(forwardedHeightReal, kMaxGifForwardedBarLines * st::msgServiceNameFont->height);
|
||||||
if (forwarded) {
|
if (forwarded) {
|
||||||
recth += forwardedHeight;
|
recth += st::msgReplyPadding.top() + forwardedHeight;
|
||||||
} else if (via) {
|
} else if (via) {
|
||||||
recth += st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
recth += st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? st::msgReplyPadding.top() : 0);
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
recth += st::msgReplyBarSize.height();
|
const auto replyMargins = reply->margins();
|
||||||
|
recth += reply->height()
|
||||||
|
- ((forwarded || via) ? 0 : replyMargins.top())
|
||||||
|
- replyMargins.bottom();
|
||||||
|
} else {
|
||||||
|
recth += st::msgReplyPadding.bottom();
|
||||||
}
|
}
|
||||||
auto rectx = rightAligned ? 0 : (usew + st::msgReplyPadding.left());
|
auto rectx = rightAligned ? 0 : (usew + st::msgReplyPadding.left());
|
||||||
auto recty = painty;
|
auto recty = painty;
|
||||||
|
@ -1067,6 +1083,12 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
|
||||||
recth -= skip;
|
recth -= skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
if (forwarded || via) {
|
||||||
|
recty += st::msgReplyPadding.top();
|
||||||
|
recth -= st::msgReplyPadding.top() + reply->margins().top();
|
||||||
|
} else {
|
||||||
|
recty -= reply->margins().top();
|
||||||
|
}
|
||||||
const auto replyRect = QRect(rectx, recty, rectw, recth);
|
const auto replyRect = QRect(rectx, recty, rectw, recth);
|
||||||
if (replyRect.contains(point)) {
|
if (replyRect.contains(point)) {
|
||||||
result.link = reply->link();
|
result.link = reply->link();
|
||||||
|
@ -1076,7 +1098,7 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
|
||||||
st::defaultRippleAnimation,
|
st::defaultRippleAnimation,
|
||||||
Ui::RippleAnimation::RoundRectMask(
|
Ui::RippleAnimation::RoundRectMask(
|
||||||
replyRect.size(),
|
replyRect.size(),
|
||||||
st::roundRadiusSmall),
|
st::messageQuoteStyle.radius),
|
||||||
[=] { item->history()->owner().requestItemRepaint(item); });
|
[=] { item->history()->owner().requestItemRepaint(item); });
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -123,7 +123,7 @@ QSize UnwrappedMedia::countCurrentSize(int newWidth) {
|
||||||
via->resize(availw);
|
via->resize(availw);
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
reply->resize(availw);
|
[[maybe_unused]] int height = reply->resizeToWidth(availw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { newWidth, newHeight };
|
return { newWidth, newHeight };
|
||||||
|
@ -211,11 +211,16 @@ UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo(
|
||||||
panelHeight += st::msgServiceNameFont->height
|
panelHeight += st::msgServiceNameFont->height
|
||||||
+ (reply ? st::msgReplyPadding.top() : 0);
|
+ (reply ? st::msgReplyPadding.top() : 0);
|
||||||
}
|
}
|
||||||
if (reply) {
|
|
||||||
panelHeight += st::msgReplyBarSize.height();
|
|
||||||
}
|
|
||||||
if (panelHeight) {
|
if (panelHeight) {
|
||||||
panelHeight += st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
panelHeight += st::msgReplyPadding.top();
|
||||||
|
}
|
||||||
|
if (reply) {
|
||||||
|
const auto replyMargins = reply->margins();
|
||||||
|
panelHeight += reply->height()
|
||||||
|
- ((forwarded || via) ? 0 : replyMargins.top())
|
||||||
|
- replyMargins.bottom();
|
||||||
|
} else {
|
||||||
|
panelHeight += st::msgReplyPadding.bottom();
|
||||||
}
|
}
|
||||||
const auto total = (topicSize.isEmpty() ? 0 : topicSize.height())
|
const auto total = (topicSize.isEmpty() ? 0 : topicSize.height())
|
||||||
+ ((panelHeight || !topicSize.height()) ? st::topicButtonSkip : 0)
|
+ ((panelHeight || !topicSize.height()) ? st::topicButtonSkip : 0)
|
||||||
|
@ -303,26 +308,32 @@ void UnwrappedMedia::drawSurrounding(
|
||||||
|
|
||||||
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
|
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
|
||||||
p.setPen(st->msgServiceFg());
|
p.setPen(st->msgServiceFg());
|
||||||
rectx += st::msgReplyPadding.left();
|
const auto textx = rectx + st::msgReplyPadding.left();
|
||||||
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
|
const auto textw = rectw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
|
||||||
if (forwarded) {
|
if (forwarded) {
|
||||||
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);
|
forwarded->text.drawElided(p, textx, recty + st::msgReplyPadding.top(), textw, kMaxForwardedBarLines, style::al_left, 0, -1, 0, surrounding.forwardedBreakEverywhere);
|
||||||
p.restoreTextPalette();
|
p.restoreTextPalette();
|
||||||
|
|
||||||
const auto skip = std::min(
|
const auto skip = std::min(
|
||||||
forwarded->text.countHeight(rectw),
|
forwarded->text.countHeight(textw),
|
||||||
kMaxForwardedBarLines * st::msgServiceNameFont->height);
|
kMaxForwardedBarLines * st::msgServiceNameFont->height);
|
||||||
recty += skip;
|
recty += skip;
|
||||||
} else if (via) {
|
} else 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 * textx + textw, via->text);
|
||||||
|
|
||||||
const auto skip = st::msgServiceNameFont->height
|
const auto skip = st::msgServiceNameFont->height
|
||||||
+ (reply ? st::msgReplyPadding.top() : 0);
|
+ (reply ? st::msgReplyPadding.top() : 0);
|
||||||
recty += skip;
|
recty += skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
if (forwarded || via) {
|
||||||
|
recty += st::msgReplyPadding.top();
|
||||||
|
recth -= st::msgReplyPadding.top();
|
||||||
|
} else {
|
||||||
|
recty -= reply->margins().top();
|
||||||
|
}
|
||||||
reply->paint(p, _parent, context, rectx, recty, rectw, false);
|
reply->paint(p, _parent, context, rectx, recty, rectw, false);
|
||||||
}
|
}
|
||||||
replyRight = rectx + rectw;
|
replyRight = rectx + rectw;
|
||||||
|
@ -330,8 +341,9 @@ void UnwrappedMedia::drawSurrounding(
|
||||||
}
|
}
|
||||||
if (rightActionSize) {
|
if (rightActionSize) {
|
||||||
const auto position = calculateFastActionPosition(
|
const auto position = calculateFastActionPosition(
|
||||||
fullBottom,
|
|
||||||
replyRight,
|
replyRight,
|
||||||
|
reply ? reply->height() : 0,
|
||||||
|
fullBottom,
|
||||||
fullRight,
|
fullRight,
|
||||||
*rightActionSize);
|
*rightActionSize);
|
||||||
const auto outer = 2 * inner.x() + inner.width();
|
const auto outer = 2 * inner.x() + inner.width();
|
||||||
|
@ -462,6 +474,12 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
||||||
recth -= skip;
|
recth -= skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
if (forwarded || via) {
|
||||||
|
recty += st::msgReplyPadding.top();
|
||||||
|
recth -= st::msgReplyPadding.top() + reply->margins().top();
|
||||||
|
} else {
|
||||||
|
recty -= reply->margins().top();
|
||||||
|
}
|
||||||
const auto replyRect = QRect(rectx, recty, rectw, recth);
|
const auto replyRect = QRect(rectx, recty, rectw, recth);
|
||||||
if (replyRect.contains(point)) {
|
if (replyRect.contains(point)) {
|
||||||
result.link = reply->link();
|
result.link = reply->link();
|
||||||
|
@ -471,7 +489,7 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
||||||
st::defaultRippleAnimation,
|
st::defaultRippleAnimation,
|
||||||
Ui::RippleAnimation::RoundRectMask(
|
Ui::RippleAnimation::RoundRectMask(
|
||||||
replyRect.size(),
|
replyRect.size(),
|
||||||
st::roundRadiusSmall),
|
st::messageQuoteStyle.radius),
|
||||||
[=] { item->history()->owner().requestItemRepaint(item); });
|
[=] { item->history()->owner().requestItemRepaint(item); });
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -495,8 +513,9 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
||||||
}
|
}
|
||||||
if (rightActionSize) {
|
if (rightActionSize) {
|
||||||
const auto position = calculateFastActionPosition(
|
const auto position = calculateFastActionPosition(
|
||||||
fullBottom,
|
|
||||||
replyRight,
|
replyRight,
|
||||||
|
reply ? reply->height() : 0,
|
||||||
|
fullBottom,
|
||||||
fullRight,
|
fullRight,
|
||||||
*rightActionSize);
|
*rightActionSize);
|
||||||
if (QRect(position.x(), position.y(), rightActionSize->width(), rightActionSize->height()).contains(point)) {
|
if (QRect(position.x(), position.y(), rightActionSize->width(), rightActionSize->height()).contains(point)) {
|
||||||
|
@ -598,17 +617,16 @@ int UnwrappedMedia::calculateFullRight(const QRect &inner) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint UnwrappedMedia::calculateFastActionPosition(
|
QPoint UnwrappedMedia::calculateFastActionPosition(
|
||||||
int fullBottom,
|
|
||||||
int replyRight,
|
int replyRight,
|
||||||
|
int replyHeight,
|
||||||
|
int fullBottom,
|
||||||
int fullRight,
|
int fullRight,
|
||||||
QSize size) const {
|
QSize size) const {
|
||||||
const auto fastShareTop = (fullBottom
|
const auto fastShareTop = (fullBottom
|
||||||
- st::historyFastShareBottom
|
- st::historyFastShareBottom
|
||||||
- size.height());
|
- size.height());
|
||||||
const auto doesRightActionHitReply = replyRight && (fastShareTop <
|
const auto doesRightActionHitReply = replyRight
|
||||||
st::msgReplyBarSize.height()
|
&& (fastShareTop < replyHeight);
|
||||||
+ st::msgReplyPadding.top()
|
|
||||||
+ st::msgReplyPadding.bottom());
|
|
||||||
const auto fastShareLeft = ((doesRightActionHitReply
|
const auto fastShareLeft = ((doesRightActionHitReply
|
||||||
? replyRight
|
? replyRight
|
||||||
: fullRight) + st::historyFastShareLeft);
|
: fullRight) + st::historyFastShareLeft);
|
||||||
|
@ -641,7 +659,7 @@ int UnwrappedMedia::additionalWidth(
|
||||||
accumulate_max(result, 2 * st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.right());
|
accumulate_max(result, 2 * st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.right());
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
accumulate_max(result, st::msgReplyPadding.left() + reply->maxWidth());
|
accumulate_max(result, reply->maxWidth());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,8 +145,9 @@ private:
|
||||||
|
|
||||||
int calculateFullRight(const QRect &inner) const;
|
int calculateFullRight(const QRect &inner) const;
|
||||||
QPoint calculateFastActionPosition(
|
QPoint calculateFastActionPosition(
|
||||||
int fullBottom,
|
|
||||||
int replyRight,
|
int replyRight,
|
||||||
|
int replyHeight,
|
||||||
|
int fullBottom,
|
||||||
int fullRight,
|
int fullRight,
|
||||||
QSize size) const;
|
QSize size) const;
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,17 @@ msgDateFont: font(13px);
|
||||||
msgMinWidth: 160px;
|
msgMinWidth: 160px;
|
||||||
msgPhotoSize: 33px;
|
msgPhotoSize: 33px;
|
||||||
msgPhotoSkip: 40px;
|
msgPhotoSkip: 40px;
|
||||||
msgPadding: margins(13px, 7px, 13px, 8px);
|
msgPadding: margins(10px, 8px, 10px, 8px);
|
||||||
msgMargin: margins(16px, 6px, 56px, 2px);
|
msgMargin: margins(16px, 6px, 56px, 2px);
|
||||||
msgMarginTopAttached: 0px;
|
msgMarginTopAttached: 0px;
|
||||||
msgShadow: 2px;
|
msgShadow: 2px;
|
||||||
|
|
||||||
|
historyReplyTop: 2px;
|
||||||
|
historyReplyBottom: 2px;
|
||||||
|
historyReplyPreview: 32px;
|
||||||
|
historyReplyPreviewMargin: margins(7px, 4px, 4px, 4px);
|
||||||
|
historyReplyPadding: margins(11px, 2px, 6px, 2px);
|
||||||
|
|
||||||
msgReplyPadding: margins(6px, 6px, 11px, 6px);
|
msgReplyPadding: margins(6px, 6px, 11px, 6px);
|
||||||
msgReplyBarPos: point(1px, 0px);
|
msgReplyBarPos: point(1px, 0px);
|
||||||
msgReplyBarSize: size(2px, 36px);
|
msgReplyBarSize: size(2px, 36px);
|
||||||
|
|
|
@ -583,6 +583,10 @@ const MessageStyle &ChatStyle::messageStyle(bool outbg, bool selected) const {
|
||||||
EnsureBlockquoteCache(
|
EnsureBlockquoteCache(
|
||||||
result.replyCache,
|
result.replyCache,
|
||||||
result.msgReplyBarColor);
|
result.msgReplyBarColor);
|
||||||
|
if (!result.quoteCache) {
|
||||||
|
result.quoteCache = std::make_unique<Text::QuotePaintCache>(
|
||||||
|
*result.replyCache);
|
||||||
|
}
|
||||||
|
|
||||||
const auto preBgOverride = [&] {
|
const auto preBgOverride = [&] {
|
||||||
const auto withBg = [&](const QColor &color) {
|
const auto withBg = [&](const QColor &color) {
|
||||||
|
|
|
@ -222,8 +222,8 @@ void MessageBar::updateFromContent(MessageBarContent &&content) {
|
||||||
|
|
||||||
QRect MessageBar::imageRect() const {
|
QRect MessageBar::imageRect() const {
|
||||||
const auto left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
const auto left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
const auto top = st::msgReplyPadding.top();
|
const auto top = (st::historyReplyHeight - st::historyReplyPreview) / 2;
|
||||||
const auto size = st::msgReplyBarSize.height();
|
const auto size = st::historyReplyPreview;
|
||||||
return QRect(left, top, size, size);
|
return QRect(left, top, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,14 +243,11 @@ QRect MessageBar::titleRangeRect(int from, int till) const {
|
||||||
|
|
||||||
QRect MessageBar::bodyRect(bool withImage) const {
|
QRect MessageBar::bodyRect(bool withImage) const {
|
||||||
const auto innerLeft = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
const auto innerLeft = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
const auto imageSkip = st::msgReplyBarSize.height()
|
const auto imageSkip = st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
+ st::msgReplyBarSkip
|
|
||||||
- st::msgReplyBarSize.width()
|
|
||||||
- st::msgReplyBarPos.x();
|
|
||||||
const auto left = innerLeft + (withImage ? imageSkip : 0);
|
const auto left = innerLeft + (withImage ? imageSkip : 0);
|
||||||
const auto top = st::msgReplyPadding.top();
|
const auto top = st::msgReplyPadding.top();
|
||||||
const auto width = _widget.width() - left - st::msgReplyPadding.right();
|
const auto width = _widget.width() - left - st::msgReplyPadding.right();
|
||||||
const auto height = st::msgReplyBarSize.height();
|
const auto height = (st::historyReplyHeight - 2 * top);
|
||||||
return QRect(left, top, width, height) - _content.margins;
|
return QRect(left, top, width, height) - _content.margins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue