Custom colors in history_view_message module.

This commit is contained in:
John Preston 2021-09-03 01:08:57 +03:00
parent 444f21fd7e
commit 1a4a9319f3
37 changed files with 885 additions and 499 deletions

View file

@ -29,21 +29,26 @@ public:
int buttonRadius() const override;
void startPaint(Painter &p) const override;
void startPaint(Painter &p, const Ui::ChatStyle *st) const override;
const style::TextStyle &textStyle() const override;
void repaint(not_null<const HistoryItem*> item) const override;
protected:
void paintButtonBg(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
float64 howMuchOver) const override;
void paintButtonIcon(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
int outerWidth,
HistoryMessageMarkupButton::Type type) const override;
void paintButtonLoading(Painter &p, const QRect &rect) const override;
void paintButtonLoading(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect) const override;
int minButtonWidth(HistoryMessageMarkupButton::Type type) const override;
private:
@ -57,7 +62,7 @@ Style::Style(
: ReplyKeyboard::Style(st), _parent(parent) {
}
void Style::startPaint(Painter &p) const {
void Style::startPaint(Painter &p, const Ui::ChatStyle *st) const {
p.setPen(st::botKbColor);
p.setFont(st::botKbStyle.font);
}
@ -76,6 +81,7 @@ int Style::buttonRadius() const {
void Style::paintButtonBg(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
float64 howMuchOver) const {
Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners);
@ -83,13 +89,17 @@ void Style::paintButtonBg(
void Style::paintButtonIcon(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
int outerWidth,
HistoryMessageMarkupButton::Type type) const {
// Buttons with icons should not appear here.
}
void Style::paintButtonLoading(Painter &p, const QRect &rect) const {
void Style::paintButtonLoading(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect) const {
// Buttons with loading progress should not appear here.
}
@ -120,7 +130,7 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
if (_impl) {
int x = rtl() ? st::botKbScroll.width : _st->margin;
p.translate(x, st::botKbScroll.deltat);
_impl->paint(p, width(), clip.translated(-x, -st::botKbScroll.deltat));
_impl->paint(p, nullptr, width(), clip.translated(-x, -st::botKbScroll.deltat));
}
}

View file

@ -410,6 +410,8 @@ void CloudThemes::parseChatThemes(const QVector<MTPChatTheme> &list) {
.light = CloudTheme::Parse(_session, data.vtheme(), true),
.dark = CloudTheme::Parse(_session, data.vdark_theme(), true),
});
AssertIsDebug();
std::swap(_chatThemes.back().light, _chatThemes.back().dark);
});
}
}

View file

@ -1005,7 +1005,7 @@ PeerId PeerData::groupCallDefaultJoinAs() const {
}
void PeerData::setThemeEmoji(const QString &emoji) {
if (true || _themeEmoji == emoji) {
if (_themeEmoji == emoji) {
return;
}
_themeEmoji = emoji;

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/widgets/popup_menu.h"
#include "ui/image/image.h"
#include "ui/text/text_utilities.h"
@ -931,6 +932,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
p.translate(0, top);
for (auto i = from; i != to; ++i) {
const auto view = i->get();
context.outbg = view->hasOutLayout();
context.selection = (view == _selectedItem)
? _selectedText
: TextSelection();

View file

@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_context_menu.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/widgets/popup_menu.h"
#include "ui/image/image.h"
#include "ui/toast/toast.h"
@ -632,6 +633,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
}).translated(0, -top);
p.translate(0, top);
if (context.clip.y() < view->height()) while (top < drawToY) {
context.outbg = view->hasOutLayout();
context.selection = itemRenderSelection(
view,
selfromy - mtop,
@ -686,6 +688,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
while (top < drawToY) {
const auto height = view->height();
if (context.clip.y() < height && hdrawtop < top + height) {
context.outbg = view->hasOutLayout();
context.selection = itemRenderSelection(
view,
selfromy - htop,

View file

@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/text/text_options.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/chat_theme.h"
#include "history/history.h"
#include "history/history_message.h"
#include "history/view/history_view_service_message.h"
@ -337,16 +339,17 @@ void HistoryMessageReply::itemRemoved(
void HistoryMessageReply::paint(
Painter &p,
not_null<const HistoryView::Element*> holder,
const Ui::ChatPaintContext &context,
int x,
int y,
int w,
PaintFlags flags) const {
bool selected = (flags & PaintFlag::Selected), outbg = holder->hasOutLayout();
bool inBubble) const {
const auto st = context.st;
const auto stm = context.messageStyle();
style::color bar = st::msgImgReplyBarColor;
if (flags & PaintFlag::InBubble) {
bar = (flags & PaintFlag::Selected) ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor);
}
const auto &bar = inBubble
? stm->msgReplyBarColor
: st->msgImgReplyBarColor();
QRect rbar(style::rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x));
p.fillRect(rbar, bar);
@ -363,35 +366,34 @@ void HistoryMessageReply::paint(
auto to = style::rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x);
auto previewWidth = image->width() / cIntRetinaFactor();
auto previewHeight = image->height() / cIntRetinaFactor();
auto preview = image->pixSingle(previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr);
auto preview = image->pixSingle(previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, context.selected() ? &st->msgStickerOverlay() : nullptr);
p.drawPixmap(to.x(), to.y(), preview);
}
}
if (w > st::msgReplyBarSkip + previewSkip) {
if (flags & PaintFlag::InBubble) {
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
} else {
p.setPen(st::msgImgReplyBarColor);
}
p.setPen(inBubble
? stm->msgServiceFg
: st->msgImgReplyBarColor());
replyToName.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
if (replyToVia && w > st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew) {
p.setFont(st::msgServiceFont);
p.drawText(x + st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew, y + st::msgReplyPadding.top() + st::msgServiceFont->ascent, replyToVia->text);
}
if (flags & PaintFlag::InBubble) {
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));
p.setTextPalette(outbg ? (selected ? st::outReplyTextPaletteSelected : st::outReplyTextPalette) : (selected ? st::inReplyTextPaletteSelected : st::inReplyTextPalette));
} else {
p.setTextPalette(st::imgReplyTextPalette);
}
p.setPen(inBubble
? stm->historyTextFg
: st->msgImgReplyBarColor());
p.setTextPalette(inBubble
? stm->replyTextPalette
: st->imgReplyTextPalette());
replyToText.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
p.setTextPalette(selected ? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected) : (outbg ? st::outTextPalette : st::inTextPalette));
p.setTextPalette(stm->textPalette);
}
} else {
p.setFont(st::msgDateFont);
auto &date = outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg);
p.setPen((flags & PaintFlag::InBubble) ? date : st::msgDateImgFg);
p.setPen(inBubble
? stm->msgDateFg
: st->msgDateImgFg());
p.drawTextLeft(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2, w + 2 * x, st::msgDateFont->elided(replyToMsgId ? tr::lng_profile_loading(tr::now) : tr::lng_deleted_message(tr::now), w - st::msgReplyBarSkip));
}
}
@ -634,11 +636,15 @@ int ReplyKeyboard::naturalHeight() const {
return (_rows.size() - 1) * _st->buttonSkip() + _rows.size() * _st->buttonHeight();
}
void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip) const {
void ReplyKeyboard::paint(
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const QRect &clip) const {
Assert(_st != nullptr);
Assert(_width > 0);
_st->startPaint(p);
_st->startPaint(p, st);
for (const auto &row : _rows) {
for (const auto &button : row) {
const auto rect = button.rect;
@ -648,7 +654,7 @@ void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip) const {
// just ignore the buttons that didn't layout well
if (rect.x() + rect.width() > _width) break;
_st->paintButton(p, outerWidth, button);
_st->paintButton(p, st, outerWidth, button);
}
}
}
@ -784,23 +790,24 @@ int ReplyKeyboard::Style::buttonHeight() const {
void ReplyKeyboard::Style::paintButton(
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const ReplyKeyboard::Button &button) const {
const QRect &rect = button.rect;
paintButtonBg(p, rect, button.howMuchOver);
paintButtonBg(p, st, rect, button.howMuchOver);
if (button.ripple) {
button.ripple->paint(p, rect.x(), rect.y(), outerWidth);
if (button.ripple->empty()) {
button.ripple.reset();
}
}
paintButtonIcon(p, rect, outerWidth, button.type);
paintButtonIcon(p, st, rect, outerWidth, button.type);
if (button.type == HistoryMessageMarkupButton::Type::CallbackWithPassword
|| button.type == HistoryMessageMarkupButton::Type::Callback
|| button.type == HistoryMessageMarkupButton::Type::Game) {
if (auto data = button.link->getButton()) {
if (const auto data = button.link->getButton()) {
if (data->requestId) {
paintButtonLoading(p, rect);
paintButtonLoading(p, st, rect);
}
}
}

View file

@ -14,6 +14,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
struct WebPageData;
class VoiceSeekClickHandler;
namespace Ui {
struct ChatPaintContext;
class ChatStyle;
} // namespace Ui
namespace Data {
class Session;
} // namespace Data
@ -141,19 +146,14 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, Histor
void resize(int width) const;
void itemRemoved(HistoryMessage *holder, HistoryItem *removed);
enum class PaintFlag {
InBubble = (1 << 0),
Selected = (1 << 1),
};
using PaintFlags = base::flags<PaintFlag>;
friend inline constexpr auto is_flag_type(PaintFlag) { return true; };
void paint(
Painter &p,
not_null<const HistoryView::Element*> holder,
const Ui::ChatPaintContext &context,
int x,
int y,
int w,
PaintFlags flags) const;
bool inBubble) const;
[[nodiscard]] PeerId replyToPeer() const {
return replyToPeerId;
@ -304,7 +304,9 @@ public:
Style(const style::BotKeyboardButton &st) : _st(&st) {
}
virtual void startPaint(Painter &p) const = 0;
virtual void startPaint(
Painter &p,
const Ui::ChatStyle *st) const = 0;
virtual const style::TextStyle &textStyle() const = 0;
int buttonSkip() const;
@ -319,15 +321,18 @@ public:
protected:
virtual void paintButtonBg(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
float64 howMuchOver) const = 0;
virtual void paintButtonIcon(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
int outerWidth,
HistoryMessageMarkupButton::Type type) const = 0;
virtual void paintButtonLoading(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect) const = 0;
virtual int minButtonWidth(
HistoryMessageMarkupButton::Type type) const = 0;
@ -335,7 +340,11 @@ public:
private:
const style::BotKeyboardButton *_st;
void paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button) const;
void paintButton(
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const ReplyKeyboard::Button &button) const;
friend class ReplyKeyboard;
};
@ -354,7 +363,11 @@ public:
int naturalWidth() const;
int naturalHeight() const;
void paint(Painter &p, int outerWidth, const QRect &clip) const;
void paint(
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const QRect &clip) const;
ClickHandlerPtr getLink(QPoint point) const;
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);

View file

@ -753,6 +753,7 @@ std::optional<QSize> Element::rightActionSize() const {
void Element::drawRightAction(
Painter &p,
const PaintContext &context,
int left,
int top,
int outerWidth) const {
@ -897,10 +898,10 @@ Element *Element::nextDisplayedInBlocks() const {
void Element::drawInfo(
Painter &p,
const PaintContext &context,
int right,
int bottom,
int width,
bool selected,
InfoDisplayType type) const {
}

View file

@ -278,10 +278,10 @@ public:
virtual void updatePressed(QPoint point) = 0;
virtual void drawInfo(
Painter &p,
const PaintContext &context,
int right,
int bottom,
int width,
bool selected,
InfoDisplayType type) const;
virtual bool pointInTime(
int right,
@ -320,6 +320,7 @@ public:
virtual std::optional<QSize> rightActionSize() const;
virtual void drawRightAction(
Painter &p,
const PaintContext &context,
int left,
int top,
int outerWidth) const;

View file

@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/inactive_press.h"
#include "ui/effects/path_shift_gradient.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "lang/lang_keys.h"
#include "boxes/peers/edit_participant_box.h"
#include "data/data_session.h"
@ -1626,6 +1627,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
p.translate(0, top);
for (auto i = from; i != to; ++i) {
const auto view = *i;
context.outbg = view->hasOutLayout();
context.selection = itemRenderSelection(view);
view->draw(p, context);
const auto height = view->height();

View file

@ -15,10 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_web_page.h"
#include "history/view/history_view_group_call_tracker.h" // UserpicInRow.
#include "history/history.h"
#include "ui/chat/chat_theme.h"
#include "ui/effects/ripple_animation.h"
#include "base/unixtime.h"
#include "ui/chat/message_bubble.h"
#include "ui/chat/chat_style.h"
#include "ui/toast/toast.h"
#include "ui/text/text_utilities.h"
#include "ui/text/text_entity.h"
@ -31,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "window/window_session_controller.h"
#include "apiwrap.h"
#include "layout/layout_selection.h"
#include "styles/style_widgets.h"
#include "styles/style_chat.h"
@ -57,23 +56,38 @@ public:
int buttonRadius() const override;
void startPaint(Painter &p) const override;
void startPaint(
Painter &p,
const Ui::ChatStyle *st) const override;
const style::TextStyle &textStyle() const override;
void repaint(not_null<const HistoryItem*> item) const override;
protected:
void paintButtonBg(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
float64 howMuchOver) const override;
void paintButtonIcon(Painter &p, const QRect &rect, int outerWidth, HistoryMessageMarkupButton::Type type) const override;
void paintButtonLoading(Painter &p, const QRect &rect) const override;
void paintButtonIcon(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
int outerWidth,
HistoryMessageMarkupButton::Type type) const override;
void paintButtonLoading(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect) const override;
int minButtonWidth(HistoryMessageMarkupButton::Type type) const override;
};
void KeyboardStyle::startPaint(Painter &p) const {
p.setPen(st::msgServiceFg);
void KeyboardStyle::startPaint(
Painter &p,
const Ui::ChatStyle *st) const {
Expects(st != nullptr);
p.setPen(st->msgServiceFg());
}
const style::TextStyle &KeyboardStyle::textStyle() const {
@ -90,41 +104,52 @@ int KeyboardStyle::buttonRadius() const {
void KeyboardStyle::paintButtonBg(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
float64 howMuchOver) const {
Ui::FillRoundRect(p, rect, st::msgServiceBg, Ui::StickerCorners);
Expects(st != nullptr);
Ui::FillRoundRect(p, rect, st->msgServiceBg(), st->msgServiceBgCorners());
if (howMuchOver > 0) {
auto o = p.opacity();
p.setOpacity(o * howMuchOver);
Ui::FillRoundRect(p, rect, st::msgBotKbOverBgAdd, Ui::BotKbOverCorners);
Ui::FillRoundRect(p, rect, st->msgBotKbOverBgAdd(), st->msgBotKbOverBgAddCorners());
p.setOpacity(o);
}
}
void KeyboardStyle::paintButtonIcon(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect,
int outerWidth,
HistoryMessageMarkupButton::Type type) const {
Expects(st != nullptr);
using Type = HistoryMessageMarkupButton::Type;
const auto getIcon = [](Type type) -> const style::icon* {
const auto icon = [&]() -> const style::icon* {
switch (type) {
case Type::Url:
case Type::Auth: return &st::msgBotKbUrlIcon;
case Type::Buy: return &st::msgBotKbPaymentIcon;
case Type::Auth: return &st->msgBotKbUrlIcon();
case Type::Buy: return &st->msgBotKbPaymentIcon();
case Type::SwitchInlineSame:
case Type::SwitchInline: return &st::msgBotKbSwitchPmIcon;
case Type::SwitchInline: return &st->msgBotKbSwitchPmIcon();
}
return nullptr;
};
if (const auto icon = getIcon(type)) {
}();
if (icon) {
icon->paint(p, rect.x() + rect.width() - icon->width() - st::msgBotKbIconPadding, rect.y() + st::msgBotKbIconPadding, outerWidth);
}
}
void KeyboardStyle::paintButtonLoading(Painter &p, const QRect &rect) const {
auto icon = &st::historySendingInvertedIcon;
icon->paint(p, rect.x() + rect.width() - icon->width() - st::msgBotKbIconPadding, rect.y() + rect.height() - icon->height() - st::msgBotKbIconPadding, rect.x() * 2 + rect.width());
void KeyboardStyle::paintButtonLoading(
Painter &p,
const Ui::ChatStyle *st,
const QRect &rect) const {
Expects(st != nullptr);
const auto &icon = st->historySendingInvertedIcon();
icon.paint(p, rect.x() + rect.width() - icon.width() - st::msgBotKbIconPadding, rect.y() + rect.height() - icon.height() - st::msgBotKbIconPadding, rect.x() * 2 + rect.width());
}
int KeyboardStyle::minButtonWidth(
@ -151,29 +176,32 @@ QString FastReplyText() {
return tr::lng_fast_reply(tr::now);
}
style::color FromNameFg(PeerId peerId, bool selected) {
if (selected) {
style::color FromNameFg(
const Ui::ChatPaintContext &context,
PeerId peerId) {
const auto st = context.st;
if (context.selected()) {
const style::color colors[] = {
st::historyPeer1NameFgSelected,
st::historyPeer2NameFgSelected,
st::historyPeer3NameFgSelected,
st::historyPeer4NameFgSelected,
st::historyPeer5NameFgSelected,
st::historyPeer6NameFgSelected,
st::historyPeer7NameFgSelected,
st::historyPeer8NameFgSelected,
st->historyPeer1NameFgSelected(),
st->historyPeer2NameFgSelected(),
st->historyPeer3NameFgSelected(),
st->historyPeer4NameFgSelected(),
st->historyPeer5NameFgSelected(),
st->historyPeer6NameFgSelected(),
st->historyPeer7NameFgSelected(),
st->historyPeer8NameFgSelected(),
};
return colors[Data::PeerColorIndex(peerId)];
} else {
const style::color colors[] = {
st::historyPeer1NameFg,
st::historyPeer2NameFg,
st::historyPeer3NameFg,
st::historyPeer4NameFg,
st::historyPeer5NameFg,
st::historyPeer6NameFg,
st::historyPeer7NameFg,
st::historyPeer8NameFg,
st->historyPeer1NameFg(),
st->historyPeer2NameFg(),
st->historyPeer3NameFg(),
st->historyPeer4NameFg(),
st->historyPeer5NameFg(),
st->historyPeer6NameFg(),
st->historyPeer7NameFg(),
st->historyPeer8NameFg(),
};
return colors[Data::PeerColorIndex(peerId)];
}
@ -459,9 +487,8 @@ void Message::draw(Painter &p, const PaintContext &context) const {
const auto item = message();
const auto media = this->media();
const auto outbg = hasOutLayout();
const auto stm = context.messageStyle();
const auto bubble = drawBubble();
const auto selected = (context.selection == FullSelection);
auto dateh = 0;
if (const auto date = Get<DateBadge>()) {
@ -487,7 +514,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
auto mediaSelectionIntervals = (!selected && mediaDisplayed)
auto mediaSelectionIntervals = (!context.selected() && mediaDisplayed)
? media->getBubbleSelectionIntervals(context.selection)
: std::vector<Ui::BubbleSelectionInterval>();
auto localMediaTop = 0;
@ -524,9 +551,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
p.translate(-g.center());
}
p.setTextPalette(selected
? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected)
: (outbg ? st::outTextPalette : st::inTextPalette));
p.setTextPalette(stm->textPalette);
auto keyboard = item->inlineReplyKeyboard();
if (keyboard) {
@ -534,7 +559,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
g.setHeight(g.height() - keyboardHeight);
auto keyboardPosition = QPoint(g.left(), g.top() + g.height() + st::msgBotKbButton.margin);
p.translate(keyboardPosition);
keyboard->paint(p, g.width(), context.clip.translated(-keyboardPosition));
keyboard->paint(p, context.st, g.width(), context.clip.translated(-keyboardPosition));
p.translate(-keyboardPosition);
}
@ -552,7 +577,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
&& data()->isDiscussionPost());
const auto displayTail = skipTail
? RectPart::None
: (outbg && !delegate()->elementIsChatWide())
: (context.outbg && !delegate()->elementIsChatWide())
? RectPart::Right
: RectPart::Left;
Ui::PaintBubble(
@ -564,15 +589,15 @@ void Message::draw(Painter &p, const PaintContext &context) const {
.pattern = context.bubblesPattern,
.patternViewport = context.viewport,
.outerWidth = width(),
.selected = selected,
.outbg = outbg,
.selected = context.selected(),
.outbg = context.outbg,
.tailSide = displayTail,
},
.selection = mediaSelectionIntervals,
});
auto inner = g;
paintCommentsButton(p, inner, selected);
paintCommentsButton(p, inner, context);
auto trect = inner.marginsRemoved(st::msgPadding);
if (mediaOnBottom) {
@ -581,24 +606,25 @@ void Message::draw(Painter &p, const PaintContext &context) const {
if (mediaOnTop) {
trect.setY(trect.y() - st::msgPadding.top());
} else {
paintFromName(p, trect, selected);
paintForwardedInfo(p, trect, selected);
paintReplyInfo(p, trect, selected);
paintViaBotIdInfo(p, trect, selected);
paintFromName(p, trect, context);
paintForwardedInfo(p, trect, context);
paintReplyInfo(p, trect, context);
paintViaBotIdInfo(p, trect, context);
}
if (entry) {
trect.setHeight(trect.height() - entry->height());
}
paintText(p, trect, context.selection);
paintText(p, trect, context);
if (mediaDisplayed) {
auto mediaHeight = media->height();
auto mediaLeft = inner.left();
auto mediaTop = (trect.y() + trect.height() - mediaHeight);
p.translate(mediaLeft, mediaTop);
auto mediaContext = context.translated(-mediaLeft, -mediaTop);
mediaContext.selection = skipTextSelection(context.selection);
media->draw(p, mediaContext);
media->draw(p, context.translated(
-mediaLeft,
-mediaTop
).withSelection(context.selection));
p.translate(-mediaLeft, -mediaTop);
}
if (entry) {
@ -620,19 +646,23 @@ void Message::draw(Painter &p, const PaintContext &context) const {
? !media->customInfoLayout()
: true);
if (needDrawInfo) {
const auto bottomSelected = selected
const auto bottomSelected = context.selected()
|| (!mediaSelectionIntervals.empty()
&& (mediaSelectionIntervals.back().top
+ mediaSelectionIntervals.back().height
>= inner.y() + inner.height()));
drawInfo(p, inner.left() + inner.width(), inner.top() + inner.height(), 2 * inner.left() + inner.width(), bottomSelected, InfoDisplayType::Default);
drawInfo(
p,
context.withSelection(
bottomSelected ? FullSelection : TextSelection()),
inner.left() + inner.width(),
inner.top() + inner.height(),
2 * inner.left() + inner.width(),
InfoDisplayType::Default);
if (g != inner) {
const auto o = p.opacity();
p.setOpacity(0.3);
const auto color = bottomSelected
? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected)
: (outbg ? st::msgOutDateFg : st::msgInDateFg);
p.fillRect(inner.left(), inner.top() + inner.height() - st::lineWidth, inner.width(), st::lineWidth, color);
p.fillRect(inner.left(), inner.top() + inner.height() - st::lineWidth, inner.width(), st::lineWidth, stm->msgDateFg);
p.setOpacity(o);
}
}
@ -643,7 +673,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
st::historyFastShareBottom);
const auto fastShareLeft = g.left() + g.width() + st::historyFastShareLeft;
const auto fastShareTop = g.top() + g.height() - fastShareSkip - size->height();
drawRightAction(p, fastShareLeft, fastShareTop, width());
drawRightAction(p, context, fastShareLeft, fastShareTop, width());
}
if (media) {
@ -651,9 +681,9 @@ void Message::draw(Painter &p, const PaintContext &context) const {
}
} else if (media && media->isDisplayed()) {
p.translate(g.topLeft());
auto mediaContext = context.translated(-g.topLeft());
mediaContext.selection = skipTextSelection(context.selection);
media->draw(p, mediaContext);
media->draw(p, context.translated(
-g.topLeft()
).withSelection(skipTextSelection(context.selection)));
p.translate(-g.topLeft());
}
@ -673,7 +703,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
void Message::paintCommentsButton(
Painter &p,
QRect &g,
bool selected) const {
const PaintContext &context) const {
if (!data()->repliesAreComments() && !data()->externalReply()) {
return;
}
@ -681,7 +711,7 @@ void Message::paintCommentsButton(
_comments = std::make_unique<CommentsButton>();
history()->owner().registerHeavyViewPart(const_cast<Message*>(this));
}
const auto outbg = hasOutLayout();
const auto stm = context.messageStyle();
const auto views = data()->Get<HistoryMessageViews>();
g.setHeight(g.height() - st::historyCommentsButtonHeight);
@ -702,18 +732,14 @@ void Message::paintCommentsButton(
width -= st::historyCommentsSkipLeft
+ st::historyCommentsSkipRight;
const auto &open = outbg
? (selected ? st::historyCommentsOpenOutSelected : st::historyCommentsOpenOut)
: (selected ? st::historyCommentsOpenInSelected : st::historyCommentsOpenIn);
const auto &open = stm->historyCommentsOpen;
open.paint(p,
left + width - open.width(),
top + (st::historyCommentsButtonHeight - open.height()) / 2,
width);
if (!views || views->recentRepliers.empty()) {
const auto &icon = outbg
? (selected ? st::historyCommentsOutSelected : st::historyCommentsOut)
: (selected ? st::historyCommentsInSelected : st::historyCommentsIn);
const auto &icon = stm->historyComments;
icon.paint(
p,
left,
@ -771,7 +797,7 @@ void Message::paintCommentsButton(
}
left += st::historyCommentsSkipText;
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
p.setPen(stm->msgFileThumbLinkFg);
p.setFont(st::semiboldFont);
const auto textTop = top + (st::historyCommentsButtonHeight - st::semiboldFont->height) / 2;
@ -784,7 +810,7 @@ void Message::paintCommentsButton(
if (views && data()->areRepliesUnread()) {
p.setPen(Qt::NoPen);
p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg));
p.setBrush(stm->msgFileBg);
{
PainterHighQualityEnabler hq(p);
@ -796,7 +822,7 @@ void Message::paintCommentsButton(
void Message::paintFromName(
Painter &p,
QRect &trect,
bool selected) const {
const PaintContext &context) const {
const auto item = message();
if (!displayFromName()) {
return;
@ -816,20 +842,18 @@ void Message::paintFromName(
}
p.setFont(st::msgNameFont);
const auto outbg = hasOutLayout();
const auto stm = context.messageStyle();
const auto nameText = [&]() -> const Ui::Text::String * {
const auto from = item->displayFrom();
if (outbg) {
p.setPen(selected ? st::msgOutServiceFgSelected : st::msgOutServiceFg);
return &from->nameText();
} else if (item->isPost()) {
p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg);
if (context.outbg || item->isPost()) {
p.setPen(stm->msgServiceFg);
return &from->nameText();
} else if (from) {
p.setPen(FromNameFg(from->id, selected));
p.setPen(FromNameFg(context, from->id));
return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) {
p.setPen(FromNameFg(info->colorPeerId, selected));
p.setPen(FromNameFg(context, info->colorPeerId));
return &info->nameText;
} else {
Unexpected("Corrupt forwarded information in message.");
@ -842,16 +866,14 @@ void Message::paintFromName(
auto via = item->Get<HistoryMessageVia>();
if (via && !displayForwardedFrom() && availableWidth > 0) {
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
p.setPen(stm->msgServiceFg);
p.drawText(availableLeft, trect.top() + st::msgServiceFont->ascent, via->text);
auto skipWidth = via->width + st::msgServiceFont->spacew;
availableLeft += skipWidth;
availableWidth -= skipWidth;
}
if (rightWidth) {
p.setPen(outbg
? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg)
: (selected ? st::msgInDateFgSelected : st::msgInDateFg));
p.setPen(stm->msgDateFg);
p.setFont(ClickHandler::showAsActive(_fastReplyLink)
? st::msgFont->underline()
: st::msgFont);
@ -871,10 +893,16 @@ void Message::paintFromName(
trect.setY(trect.y() + st::msgNameFont->height);
}
void Message::paintForwardedInfo(Painter &p, QRect &trect, bool selected) const {
void Message::paintForwardedInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const {
if (displayForwardedFrom()) {
const auto item = message();
const auto outbg = hasOutLayout();
const auto selected = context.selected();
const auto st = context.st;
const auto stm = context.messageStyle();
const auto forwarded = item->Get<HistoryMessageForwarded>();
const auto &serviceFont = st::msgServiceFont;
@ -890,26 +918,14 @@ void Message::paintForwardedInfo(Painter &p, QRect &trect, bool selected) const
const auto countedHeight = forwarded->text.countHeight(useWidth);
const auto breakEverywhere = (countedHeight > 2 * serviceFont->height);
p.setPen(!forwarded->psaType.isEmpty()
? st::boxTextFgGood
: selected
? (outbg
? st::msgOutServiceFgSelected
: st::msgInServiceFgSelected)
: (outbg
? st::msgOutServiceFg
: st::msgInServiceFg));
? st->boxTextFgGood()
: stm->msgServiceFg);
p.setFont(serviceFont);
p.setTextPalette(!forwarded->psaType.isEmpty()
? st::historyPsaForwardPalette
: selected
? (outbg
? st::outFwdTextPaletteSelected
: st::inFwdTextPaletteSelected)
: (outbg
? st::outFwdTextPalette
: st::inFwdTextPalette));
? st->historyPsaForwardPalette()
: stm->fwdTextPalette);
forwarded->text.drawElided(p, trect.x(), trect.y(), useWidth, 2, style::al_left, 0, -1, 0, breakEverywhere);
p.setTextPalette(selected ? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected) : (outbg ? st::outTextPalette : st::inTextPalette));
p.setTextPalette(stm->textPalette);
if (!forwarded->psaType.isEmpty()) {
const auto entry = Get<PsaTooltipState>();
@ -917,11 +933,7 @@ void Message::paintForwardedInfo(Painter &p, QRect &trect, bool selected) const
const auto shown = entry->buttonVisibleAnimation.value(
entry->buttonVisible ? 1. : 0.);
if (shown > 0) {
const auto &icon = selected
? (outbg
? st::historyPsaIconOutSelected
: st::historyPsaIconInSelected)
: (outbg ? st::historyPsaIconOut : st::historyPsaIconIn);
const auto &icon = stm->historyPsaIcon;
const auto position = fits
? st::historyPsaIconPosition1
: st::historyPsaIconPosition2;
@ -944,44 +956,45 @@ void Message::paintForwardedInfo(Painter &p, QRect &trect, bool selected) const
}
}
void Message::paintReplyInfo(Painter &p, QRect &trect, bool selected) const {
if (auto reply = displayedReply()) {
void Message::paintReplyInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const {
if (const auto reply = displayedReply()) {
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
auto flags = HistoryMessageReply::PaintFlag::InBubble | 0;
if (selected) {
flags |= HistoryMessageReply::PaintFlag::Selected;
}
reply->paint(p, this, trect.x(), trect.y(), trect.width(), flags);
reply->paint(p, this, context, trect.x(), trect.y(), trect.width(), true);
trect.setY(trect.y() + h);
}
}
void Message::paintViaBotIdInfo(Painter &p, QRect &trect, bool selected) const {
void Message::paintViaBotIdInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const {
const auto item = message();
if (!displayFromName() && !displayForwardedFrom()) {
if (auto via = item->Get<HistoryMessageVia>()) {
const auto outbg = hasOutLayout();
const auto stm = context.messageStyle();
p.setFont(st::msgServiceNameFont);
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
p.setPen(stm->msgServiceFg);
p.drawTextLeft(trect.left(), trect.top(), width(), via->text);
trect.setY(trect.y() + st::msgServiceNameFont->height);
}
}
}
void Message::paintText(Painter &p, QRect &trect, TextSelection selection) const {
void Message::paintText(
Painter &p,
QRect &trect,
const PaintContext &context) const {
if (!hasVisibleText()) {
return;
}
const auto item = message();
const auto outbg = hasOutLayout();
auto selected = (selection == FullSelection);
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));
const auto stm = context.messageStyle();
p.setPen(stm->historyTextFg);
p.setFont(st::msgFont);
item->_text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, selection);
item->_text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, context.selection);
}
PointState Message::pointState(QPoint point) const {
@ -1666,14 +1679,15 @@ TextSelection Message::adjustSelection(
void Message::drawInfo(
Painter &p,
const PaintContext &context,
int right,
int bottom,
int width,
bool selected,
InfoDisplayType type) const {
p.setFont(st::msgDateFont);
bool outbg = hasOutLayout();
const auto stm = context.messageStyle();
const auto st = context.st;
bool invertedsprites = (type == InfoDisplayType::Image)
|| (type == InfoDisplayType::Background);
int32 infoRight = right, infoBottom = bottom;
@ -1681,23 +1695,22 @@ void Message::drawInfo(
case InfoDisplayType::Default:
infoRight -= st::msgPadding.right() - st::msgDateDelta.x();
infoBottom -= st::msgPadding.bottom() - st::msgDateDelta.y();
p.setPen(selected
? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected)
: (outbg ? st::msgOutDateFg : st::msgInDateFg));
p.setPen(stm->msgDateFg);
break;
case InfoDisplayType::Image:
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
p.setPen(st::msgDateImgFg);
p.setPen(st->msgDateImgFg());
break;
case InfoDisplayType::Background:
infoRight -= st::msgDateImgPadding.x();
infoBottom -= st::msgDateImgPadding.y();
p.setPen(st::msgServiceFg);
p.setPen(st->msgServiceFg());
break;
}
const auto item = message();
const auto selected = context.selected();
auto infoW = infoWidth();
if (rtl()) infoRight = width - infoRight + infoW;
@ -1705,10 +1718,10 @@ void Message::drawInfo(
auto dateY = infoBottom - st::msgDateFont->height;
if (type == InfoDisplayType::Image) {
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
} else if (type == InfoDisplayType::Background) {
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st->msgServiceBgSelected() : st->msgServiceBg(), selected ? st->msgServiceBgSelectedCorners() : st->msgServiceBgCorners());
}
dateX += timeLeft();
@ -1728,101 +1741,70 @@ void Message::drawInfo(
const auto textTop = infoBottom - st::msgDateFont->descent;
if (views->replies.count > 0
&& !views->commentsMegagroupId
&& context() != Context::Replies) {
auto icon = [&] {
if (item->id > 0) {
if (outbg) {
return &(invertedsprites
? st::historyRepliesInvertedIcon
: selected
? st::historyRepliesOutSelectedIcon
: st::historyRepliesOutIcon);
}
return &(invertedsprites
? st::historyRepliesInvertedIcon
: selected
? st::historyRepliesInSelectedIcon
: st::historyRepliesInIcon);
}
return &(invertedsprites
? st::historyViewsSendingInvertedIcon
: st::historyViewsSendingIcon);
}();
&& this->context() != Context::Replies) {
const auto &icon = (item->id > 0)
? (invertedsprites
? st->historyRepliesInvertedIcon()
: stm->historyRepliesIcon)
: (invertedsprites
? st->historyViewsSendingInvertedIcon()
: st->historyViewsSendingIcon());
if (item->id > 0) {
icon->paint(p, left, viewIconTop, width);
icon.paint(p, left, viewIconTop, width);
p.drawText(left + st::historyViewsWidth, textTop, views->replies.text);
} else if (!outbg && views->views.count < 0) { // sending outbg icon will be painted below
} else if (!context.outbg && views->views.count < 0) { // sending outbg icon will be painted below
auto iconSkip = st::historyViewsSpace + views->replies.textWidth;
icon->paint(p, left + iconSkip, viewIconTop, width);
icon.paint(p, left + iconSkip, viewIconTop, width);
}
left += st::historyViewsSpace
+ views->replies.textWidth
+ st::historyViewsWidth;
}
if (views->views.count >= 0) {
auto icon = [&] {
if (item->id > 0) {
if (outbg) {
return &(invertedsprites
? st::historyViewsInvertedIcon
: selected
? st::historyViewsOutSelectedIcon
: st::historyViewsOutIcon);
}
return &(invertedsprites
? st::historyViewsInvertedIcon
: selected
? st::historyViewsInSelectedIcon
: st::historyViewsInIcon);
}
return &(invertedsprites
? st::historyViewsSendingInvertedIcon
: st::historyViewsSendingIcon);
}();
const auto &icon = (item->id > 0)
? (invertedsprites
? st->historyViewsInvertedIcon()
: stm->historyViewsIcon)
: (invertedsprites
? st->historyViewsSendingInvertedIcon()
: st->historyViewsSendingIcon());
if (item->id > 0) {
icon->paint(p, left, viewIconTop, width);
icon.paint(p, left, viewIconTop, width);
p.drawText(left + st::historyViewsWidth, textTop, views->views.text);
} else if (!outbg) { // sending outbg icon will be painted below
} else if (!context.outbg) { // sending outbg icon will be painted below
auto iconSkip = st::historyViewsSpace + views->views.textWidth;
icon->paint(p, left + iconSkip, viewIconTop, width);
icon.paint(p, left + iconSkip, viewIconTop, width);
}
left += st::historyViewsSpace
+ views->views.textWidth
+ st::historyViewsWidth;
}
} else if (item->id < 0 && item->history()->peer->isSelf() && !outbg) {
auto icon = &(invertedsprites ? st::historyViewsSendingInvertedIcon : st::historyViewsSendingIcon);
icon->paint(p, left, viewIconTop, width);
} else if (item->id < 0 && item->history()->peer->isSelf() && !context.outbg) {
const auto &icon = invertedsprites
? st->historyViewsSendingInvertedIcon()
: st->historyViewsSendingIcon();
icon.paint(p, left, viewIconTop, width);
}
if (displayPinIcon()) {
const auto icon = [&] {
if (outbg) {
return &(invertedsprites
? st::historyPinInvertedIcon
: selected
? st::historyPinOutSelectedIcon
: st::historyPinOutIcon);
}
return &(invertedsprites
? st::historyPinInvertedIcon
: selected
? st::historyPinInSelectedIcon
: st::historyPinInIcon);
}();
icon->paint(p, left, pinIconTop, width);
const auto &icon = invertedsprites
? st->historyPinInvertedIcon()
: stm->historyPinIcon;
icon.paint(p, left, pinIconTop, width);
left += st::historyPinWidth;
}
if (outbg) {
auto icon = [&] {
if (item->id > 0) {
if (delegate()->elementShownUnread(this)) {
return &(invertedsprites ? st::historySentInvertedIcon : (selected ? st::historySentSelectedIcon : st::historySentIcon));
}
return &(invertedsprites ? st::historyReceivedInvertedIcon : (selected ? st::historyReceivedSelectedIcon : st::historyReceivedIcon));
}
return &(invertedsprites ? st::historySendingInvertedIcon : st::historySendingIcon);
}();
icon->paint(p, QPoint(infoRight, infoBottom) + st::historySendStatePosition, width);
if (context.outbg) {
const auto &icon = (item->id <= 0)
? (invertedsprites
? st->historySendingInvertedIcon()
: st->historySendingIcon())
: delegate()->elementShownUnread(this)
? (invertedsprites
? st->historySentInvertedIcon()
: stm->historySentIcon)
: (invertedsprites
? st->historyReceivedInvertedIcon()
: stm->historyReceivedIcon);
icon.paint(p, QPoint(infoRight, infoBottom) + st::historySendStatePosition, width);
}
}
@ -2195,12 +2177,14 @@ bool Message::displayGoToOriginal() const {
void Message::drawRightAction(
Painter &p,
const PaintContext &context,
int left,
int top,
int outerWidth) const {
const auto size = rightActionSize();
const auto st = context.st;
p.setPen(Qt::NoPen);
p.setBrush(st::msgServiceBg);
p.setBrush(st->msgServiceBg());
{
PainterHighQualityEnabler hq(p);
const auto rect = style::rtlrect(
@ -2217,7 +2201,7 @@ void Message::drawRightAction(
}
}
if (displayRightActionComments()) {
const auto &icon = st::historyFastCommentsIcon;
const auto &icon = st->historyFastCommentsIcon();
icon.paint(
p,
left + (size->width() - icon.width()) / 2,
@ -2226,7 +2210,7 @@ void Message::drawRightAction(
const auto views = data()->Get<HistoryMessageViews>();
Assert(views != nullptr);
if (views->repliesSmall.textWidth > 0) {
p.setPen(st::msgServiceFg);
p.setPen(st->msgServiceFg());
p.setFont(st::semiboldFont);
p.drawTextLeft(
left + (size->width() - views->repliesSmall.textWidth) / 2,
@ -2237,8 +2221,8 @@ void Message::drawRightAction(
}
} else {
const auto &icon = (displayFastShare() && !isPinnedContext())
? st::historyFastShareIcon
: st::historyGoToOriginalIcon;
? st->historyFastShareIcon()
: st->historyGoToOriginalIcon();
icon.paintInCenter(p, { left, top, size->width(), size->height() });
}
}

View file

@ -59,10 +59,10 @@ public:
void updatePressed(QPoint point) override;
void drawInfo(
Painter &p,
const PaintContext &context,
int right,
int bottom,
int width,
bool selected,
InfoDisplayType type) const override;
bool pointInTime(
int right,
@ -94,6 +94,7 @@ public:
std::optional<QSize> rightActionSize() const override;
void drawRightAction(
Painter &p,
const PaintContext &context,
int left,
int top,
int outerWidth) const override;
@ -132,13 +133,32 @@ private:
void toggleCommentsButtonRipple(bool pressed);
void paintCommentsButton(Painter &p, QRect &g, bool selected) const;
void paintFromName(Painter &p, QRect &trect, bool selected) const;
void paintForwardedInfo(Painter &p, QRect &trect, bool selected) const;
void paintReplyInfo(Painter &p, QRect &trect, bool selected) const;
// this method draws "via @bot" if it is not painted in forwarded info or in from name
void paintViaBotIdInfo(Painter &p, QRect &trect, bool selected) const;
void paintText(Painter &p, QRect &trect, TextSelection selection) const;
void paintCommentsButton(
Painter &p,
QRect &g,
const PaintContext &context) const;
void paintFromName(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintForwardedInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintReplyInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
// This method draws "via @bot" if it is not painted
// in forwarded info or in from name.
void paintViaBotIdInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintText(
Painter &p,
QRect &trect,
const PaintContext &context) const;
bool getStateCommentsButton(
QPoint point,

View file

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_abstract_structure.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/text/text_options.h"
#include "ui/ui_utility.h"
#include "mainwidget.h"
@ -562,9 +562,7 @@ void Service::draw(Painter &p, const PaintContext &context) const {
height -= st::msgServiceMargin.top() + media->height();
auto left = st::msgServiceMargin.left() + (g.width() - media->maxWidth()) / 2, top = st::msgServiceMargin.top() + height + st::msgServiceMargin.top();
p.translate(left, top);
auto mediaContext = context.translated(-left, -top);
mediaContext.selection = TextSelection();
media->draw(p, mediaContext);
media->draw(p, context.translated(-left, -top).withSelection({}));
p.translate(-left, -top);
}

View file

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_call.h"
#include "lang/lang_keys.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/text/format_values.h"
#include "layout/layout_selection.h" // FullSelection
#include "history/history.h"

View file

@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "window/window_session_controller.h"
#include "ui/empty_userpic.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_options.h"
#include "data/data_session.h"

View file

@ -20,10 +20,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/format_values.h"
#include "ui/text/format_song_document_name.h"
#include "ui/chat/message_bubble.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/cached_round_corners.h"
#include "ui/ui_utility.h"
#include "layout/layout_selection.h" // FullSelection
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_document_media.h"

View file

@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_game.h"
#include "lang/lang_keys.h"
#include "layout/layout_selection.h"
#include "history/history_item_components.h"
#include "history/history.h"
#include "history/view/history_view_element.h"
@ -16,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media_common.h"
#include "ui/item_text_options.h"
#include "ui/cached_round_corners.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "core/ui_integration.h"
#include "data/data_session.h"
#include "data/data_game.h"
@ -203,11 +202,16 @@ void Game::draw(Painter &p, const PaintContext &context) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
auto paintw = width();
auto outbg = _parent->hasOutLayout();
bool selected = (context.selection == FullSelection);
const auto outbg = _parent->hasOutLayout();
const auto selected = context.selected();
const auto st = context.st;
auto &barfg = selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor);
auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
const auto &barfg = selected
? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor)
: (outbg ? st->msgOutReplyBarColor() : st->msgInReplyBarColor());
const auto &semibold = selected
? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected)
: (outbg ? st->msgOutServiceFg() : st->msgInServiceFg());
QMargins bubble(_attach ? _attach->bubbleMargins() : QMargins());
auto padding = inBubblePadding();
@ -248,11 +252,11 @@ void Game::draw(Painter &p, const PaintContext &context) const {
auto attachTop = tshift - bubble.top();
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
auto attachContext = context.translated(-attachLeft, -attachTop);
attachContext.selection = selected ? FullSelection : TextSelection { 0, 0 };
p.translate(attachLeft, attachTop);
_attach->draw(p, attachContext);
_attach->draw(p, context.translated(
-attachLeft,
-attachTop
).withSelection(selected ? FullSelection : TextSelection()));
auto pixwidth = _attach->width();
auto pixheight = _attach->height();
@ -261,7 +265,7 @@ void Game::draw(Painter &p, const PaintContext &context) const {
auto gameX = pixwidth - st::msgDateImgDelta - gameW;
auto gameY = pixheight - st::msgDateImgDelta - gameH;
Ui::FillRoundRect(p, style::rtlrect(gameX, gameY, gameW, gameH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, style::rtlrect(gameX, gameY, gameW, gameH, pixwidth), selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
p.setFont(st::msgDateFont);
p.setPen(st::msgDateImgFg);

View file

@ -26,7 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media_common.h"
#include "window/window_session_controller.h"
#include "core/application.h" // Application::showDocument.
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/image/image.h"
#include "ui/text/format_values.h"
#include "ui/grouped_layout.h"
@ -37,7 +37,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_click_handler.h"
#include "data/data_file_origin.h"
#include "data/data_document_media.h"
#include "layout/layout_selection.h" // FullSelection
#include "styles/style_chat.h"
namespace HistoryView {
@ -284,6 +283,8 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
const auto item = _parent->data();
const auto loaded = dataLoaded();
const auto displayLoading = item->isSending() || _data->displayLoading();
const auto st = context.st;
const auto stm = context.messageStyle();
const auto selected = (context.selection == FullSelection);
const auto autoPaused = _parent->delegate()->elementIsGifPaused();
const auto cornerDownload = downloadInCorner();
@ -545,7 +546,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
}
if (!isRound) {
drawCornerStatus(p, selected, QPoint());
drawCornerStatus(p, context, QPoint());
}
if (!inWebPage && isRound) {
@ -557,7 +558,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
if (mediaUnread) {
statusW += st::mediaUnreadSkip + st::mediaUnreadSize;
}
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st->msgServiceBgSelected() : st->msgServiceBg(), selected ? st->msgServiceBgSelectedCorners() : st->msgServiceBgCorners());
p.setFont(st::normalFont);
p.setPen(st::msgServiceFg);
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
@ -588,7 +589,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
int recty = painty;
if (rtl()) rectx = width() - rectx - rectw;
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st->msgServiceBgSelected() : st->msgServiceBg(), selected ? st->msgServiceBgSelectedCorners() : st->msgServiceBgCorners());
p.setPen(st::msgServiceFg);
rectx += st::msgReplyPadding.left();
rectw = innerw;
@ -604,11 +605,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
recty += skip;
}
if (reply) {
HistoryMessageReply::PaintFlags flags = 0;
if (selected) {
flags |= HistoryMessageReply::PaintFlag::Selected;
}
reply->paint(p, _parent, rectx, recty, rectw, flags);
reply->paint(p, _parent, context, rectx, recty, rectw, false);
}
}
}
@ -635,7 +632,15 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
}
}
if (isRound || needInfoDisplay()) {
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, isRound ? InfoDisplayType::Background : InfoDisplayType::Image);
_parent->drawInfo(
p,
context,
fullRight,
fullBottom,
2 * paintx + paintw,
(isRound
? InfoDisplayType::Background
: InfoDisplayType::Image));
}
if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) {
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
@ -644,7 +649,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
fastShareLeft = (fullRight - size->width() - st::msgDateImgDelta);
fastShareTop -= (st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y());
}
_parent->drawRightAction(p, fastShareLeft, fastShareTop, 2 * paintx + paintw);
_parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw);
}
}
}
@ -660,11 +665,16 @@ void Gif::validateVideoThumbnail() const {
: info.thumbnail);
}
void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
void Gif::drawCornerStatus(
Painter &p,
const PaintContext &context,
QPoint position) const {
if (!needCornerStatusDisplay()) {
return;
}
const auto own = activeOwnStreamed();
const auto st = context.st;
const auto selected = context.selected();
const auto text = (own && !own->frozenStatusText.isEmpty())
? own->frozenStatusText
: _statusText;
@ -681,7 +691,7 @@ void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
const auto statusY = position.y() + st::msgDateImgDelta + padding.y();
const auto around = style::rtlrect(statusX - padding.x(), statusY - padding.y(), statusW, statusH, width());
const auto statusTextTop = statusY + (cornerDownload ? (((statusH - 2 * st::normalFont->height) / 3) - padding.y()) : 0);
Ui::FillRoundRect(p, around, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, around, selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
p.setFont(st::normalFont);
p.setPen(st::msgDateImgFg);
p.drawTextLeft(statusX + addLeft, statusTextTop, width(), text, statusW - 2 * padding.x());
@ -1088,7 +1098,7 @@ void Gif::drawGrouped(
}
}
if (fullFeatured) {
drawCornerStatus(p, selected, geometry.topLeft());
drawCornerStatus(p, context, geometry.topLeft());
}
}

View file

@ -165,7 +165,10 @@ private:
[[nodiscard]] QSize sizeForAspectRatio() const;
[[nodiscard]] bool downloadInCorner() const;
void drawCornerStatus(Painter &p, bool selected, QPoint position) const;
void drawCornerStatus(
Painter &p,
const PaintContext &context,
QPoint position) const;
[[nodiscard]] TextState cornerStatusTextState(
QPoint point,
StateRequest request,

View file

@ -8,13 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_invoice.h"
#include "lang/lang_keys.h"
#include "layout/layout_selection.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h"
#include "history/view/media/history_view_photo.h"
#include "history/view/media/history_view_media_common.h"
#include "ui/item_text_options.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/text/format_values.h"
#include "ui/cached_round_corners.h"
#include "data/data_media_types.h"
@ -204,10 +203,13 @@ void Invoice::draw(Painter &p, const PaintContext &context) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
auto paintw = width();
auto outbg = _parent->hasOutLayout();
bool selected = (context.selection == FullSelection);
const auto outbg = _parent->hasOutLayout();
const auto selected = context.selected();
const auto st = context.st;
auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
auto &semibold = selected
? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected)
: (outbg ? st->msgOutServiceFg() : st->msgInServiceFg());
QMargins bubble(_attach ? _attach->bubbleMargins() : QMargins());
auto padding = inBubblePadding();
@ -245,11 +247,11 @@ void Invoice::draw(Painter &p, const PaintContext &context) const {
auto attachTop = tshift - bubble.top();
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
auto attachContext = context.translated(-attachLeft, -attachTop);
attachContext.selection = selected ? FullSelection : TextSelection { 0, 0 };
p.translate(attachLeft, attachTop);
_attach->draw(p, attachContext);
_attach->draw(p, context.translated(
-attachLeft,
-attachTop
).withSelection(selected ? FullSelection : TextSelection()));
auto pixwidth = _attach->width();
auto available = _status.maxWidth();
@ -258,7 +260,7 @@ void Invoice::draw(Painter &p, const PaintContext &context) const {
auto statusX = st::msgDateImgDelta;
auto statusY = st::msgDateImgDelta;
Ui::FillRoundRect(p, style::rtlrect(statusX, statusY, statusW, statusH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, style::rtlrect(statusX, statusY, statusW, statusH, pixwidth), selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
p.setFont(st::msgDateFont);
p.setPen(st::msgDateImgFg);

View file

@ -7,14 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_location.h"
#include "layout/layout_selection.h"
#include "history/history.h"
#include "history/history_item_components.h"
#include "history/history_item.h"
#include "history/history_location_manager.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/image/image.h"
#include "ui/text/text_options.h"
#include "ui/cached_round_corners.h"
@ -210,11 +209,17 @@ void Location::draw(Painter &p, const PaintContext &context) const {
if (_parent->media() == this) {
auto fullRight = paintx + paintw;
auto fullBottom = height();
_parent->drawInfo(p, fullRight, fullBottom, paintx * 2 + paintw, selected, InfoDisplayType::Image);
_parent->drawInfo(
p,
context,
fullRight,
fullBottom,
paintx * 2 + paintw,
InfoDisplayType::Image);
if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) {
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height());
_parent->drawRightAction(p, fastShareLeft, fastShareTop, 2 * paintx + paintw);
_parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw);
}
}
}

View file

@ -13,10 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "lottie/lottie_single_player.h"
#include "storage/storage_shared_media.h"
#include "layout/layout_selection.h"
#include "data/data_document.h"
#include "ui/item_text_options.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/message_bubble.h"
#include "core/ui_integration.h"
#include "styles/style_chat.h"

View file

@ -17,7 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_shared_media.h"
#include "lang/lang_keys.h"
#include "ui/grouped_layout.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/message_bubble.h"
#include "ui/text/text_options.h"
#include "layout/layout_selection.h"
@ -293,14 +293,13 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
&& !IsSubGroupSelection(selection);
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
const auto &part = _parts[i];
auto partContext = context;
partContext.selection = fullSelection
const auto partContext = context.withSelection(fullSelection
? FullSelection
: textSelection
? selection
: IsGroupItemSelection(selection, i)
? FullSelection
: TextSelection();
: TextSelection());
if (textSelection) {
selection = part.content->skipSelection(selection);
}
@ -342,12 +341,18 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
auto fullRight = width();
auto fullBottom = height();
if (needInfoDisplay()) {
_parent->drawInfo(p, fullRight, fullBottom, width(), selected, InfoDisplayType::Image);
_parent->drawInfo(
p,
context,
fullRight,
fullBottom,
width(),
InfoDisplayType::Image);
}
if (const auto size = _parent->hasBubble() ? std::nullopt : _parent->rightActionSize()) {
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height());
_parent->drawRightAction(p, fastShareLeft, fastShareTop, width());
_parent->drawRightAction(p, context, fastShareLeft, fastShareTop, width());
}
}
}

View file

@ -14,8 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h"
#include "lottie/lottie_single_player.h"
#include "ui/cached_round_corners.h"
#include "ui/chat/chat_theme.h"
#include "layout/layout_selection.h"
#include "ui/chat/chat_style.h"
#include "styles/style_chat.h"
namespace HistoryView {
@ -141,7 +140,7 @@ void UnwrappedMedia::draw(Painter &p, const PaintContext &context) const {
_content->draw(p, inner, selected);
if (!inWebPage) {
drawSurrounding(p, inner, selected, via, reply, forwarded);
drawSurrounding(p, inner, context, via, reply, forwarded);
}
}
@ -177,10 +176,12 @@ UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo(
void UnwrappedMedia::drawSurrounding(
Painter &p,
const QRect &inner,
bool selected,
const PaintContext &context,
const HistoryMessageVia *via,
const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const {
const auto selected = context.selected();
const auto st = context.st;
const auto rightAligned = _parent->hasOutLayout()
&& !_parent->delegate()->elementIsChatWide();
const auto rightActionSize = _parent->rightActionSize();
@ -189,10 +190,10 @@ void UnwrappedMedia::drawSurrounding(
if (needInfoDisplay()) {
_parent->drawInfo(
p,
context,
fullRight,
fullBottom,
inner.x() * 2 + inner.width(),
selected,
InfoDisplayType::Background);
}
auto replyRight = 0;
@ -203,7 +204,7 @@ void UnwrappedMedia::drawSurrounding(
int recty = 0;
if (rtl()) rectx = width() - rectx - rectw;
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st->msgServiceBgSelected() : st->msgServiceBg(), selected ? st->msgServiceBgSelectedCorners() : st->msgServiceBgCorners());
p.setPen(st::msgServiceFg);
rectx += st::msgReplyPadding.left();
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
@ -218,11 +219,7 @@ void UnwrappedMedia::drawSurrounding(
recty += skip;
}
if (reply) {
HistoryMessageReply::PaintFlags flags = 0;
if (selected) {
flags |= HistoryMessageReply::PaintFlag::Selected;
}
reply->paint(p, _parent, rectx, recty, rectw, flags);
reply->paint(p, _parent, context, rectx, recty, rectw, false);
}
replyRight = rectx + rectw;
}
@ -233,7 +230,7 @@ void UnwrappedMedia::drawSurrounding(
fullRight,
*rightActionSize);
const auto outer = 2 * inner.x() + inner.width();
_parent->drawRightAction(p, position.x(), position.y(), outer);
_parent->drawRightAction(p, context, position.x(), position.y(), outer);
}
}

View file

@ -116,7 +116,7 @@ private:
void drawSurrounding(
Painter &p,
const QRect &inner,
bool selected,
const PaintContext &context,
const HistoryMessageVia *via,
const HistoryMessageReply *reply,
const HistoryMessageForwarded *forwarded) const;

View file

@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_photo.h"
#include "layout/layout_selection.h"
#include "history/history_item_components.h"
#include "history/history_item.h"
#include "history/history.h"
@ -20,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "ui/image/image.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/grouped_layout.h"
#include "ui/cached_round_corners.h"
#include "data/data_session.h"
@ -336,12 +335,18 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
auto fullRight = paintx + paintw;
auto fullBottom = painty + painth;
if (needInfoDisplay()) {
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayType::Image);
_parent->drawInfo(
p,
context,
fullRight,
fullBottom,
2 * paintx + paintw,
InfoDisplayType::Image);
}
if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) {
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height());
_parent->drawRightAction(p, fastShareLeft, fastShareTop, 2 * paintx + paintw);
_parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw);
}
}
}

View file

@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "calls/calls_instance.h"
#include "ui/chat/message_bubble.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/text/text_options.h"
#include "ui/text/text_utilities.h"
#include "ui/text/format_values.h"
@ -30,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "base/timer.h"
#include "main/main_session.h"
#include "layout/layout_selection.h" // FullSelection
#include "apiwrap.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
@ -742,8 +741,8 @@ void Poll::draw(Painter &p, const PaintContext &context) const {
p.setPen(regular);
_subtitle.drawLeftElided(p, padding.left(), tshift, paintw, width());
paintRecentVoters(p, padding.left() + _subtitle.maxWidth(), tshift, context);
paintCloseByTimer(p, padding.left() + paintw, tshift, context.selection);
paintShowSolution(p, padding.left() + paintw, tshift, context.selection);
paintCloseByTimer(p, padding.left() + paintw, tshift, context);
paintShowSolution(p, padding.left() + paintw, tshift, context);
tshift += st::msgDateFont->height + st::historyPollAnswersSkip;
const auto progress = _answersAnimation
@ -775,14 +774,14 @@ void Poll::draw(Painter &p, const PaintContext &context) const {
tshift,
paintw,
width(),
context.selection);
context);
tshift += height;
}
if (!inlineFooter()) {
paintBottom(p, padding.left(), tshift, paintw, context.selection);
paintBottom(p, padding.left(), tshift, paintw, context);
} else if (!_totalVotesLabel.isEmpty()) {
tshift += st::msgPadding.bottom();
paintInlineFooter(p, padding.left(), tshift, paintw, context.selection);
paintInlineFooter(p, padding.left(), tshift, paintw, context);
}
}
@ -791,8 +790,8 @@ void Poll::paintInlineFooter(
int left,
int top,
int paintw,
TextSelection selection) const {
const auto selected = (selection == FullSelection);
const PaintContext &context) const {
const auto selected = context.selected();
const auto outbg = _parent->hasOutLayout();
const auto &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);
p.setPen(regular);
@ -811,9 +810,9 @@ void Poll::paintBottom(
int left,
int top,
int paintw,
TextSelection selection) const {
const PaintContext &context) const {
const auto stringtop = top + st::msgPadding.bottom() + st::historyPollBottomButtonTop;
const auto selected = (selection == FullSelection);
const auto selected = context.selected();
const auto outbg = _parent->hasOutLayout();
const auto &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);
if (showVotersCount()) {
@ -921,7 +920,7 @@ void Poll::paintCloseByTimer(
Painter &p,
int right,
int top,
TextSelection selection) const {
const PaintContext &context) const {
if (!canVote() || _poll->closeDate <= 0 || _poll->closePeriod <= 0) {
_close = nullptr;
return;
@ -949,7 +948,7 @@ void Poll::paintCloseByTimer(
}
const auto time = Ui::FormatDurationText(int(std::ceil(left / 1000.)));
const auto outbg = _parent->hasOutLayout();
const auto selected = (selection == FullSelection);
const auto selected = context.selected();
const auto &icon = selected
? (outbg
? st::historyQuizTimerOutSelected
@ -995,7 +994,7 @@ void Poll::paintShowSolution(
Painter &p,
int right,
int top,
TextSelection selection) const {
const PaintContext &context) const {
const auto shown = _solutionButtonAnimation.value(
_solutionButtonVisible ? 1. : 0.);
if (!shown) {
@ -1006,7 +1005,7 @@ void Poll::paintShowSolution(
crl::guard(this, [=] { showSolution(); }));
}
const auto outbg = _parent->hasOutLayout();
const auto &icon = (selection == FullSelection)
const auto &icon = context.selected()
? (outbg
? st::historyQuizExplainOutSelected
: st::historyQuizExplainInSelected)
@ -1033,7 +1032,7 @@ int Poll::paintAnswer(
int top,
int width,
int outerWidth,
TextSelection selection) const {
const PaintContext &context) const {
const auto height = countAnswerHeight(answer, width);
const auto outbg = _parent->hasOutLayout();
const auto aleft = left + st::historyPollAnswerPadding.left();
@ -1054,7 +1053,7 @@ int Poll::paintAnswer(
const auto opacity = animation->opacity.current();
if (opacity < 1.) {
p.setOpacity(1. - opacity);
paintRadio(p, answer, left, top, selection);
paintRadio(p, answer, left, top, context);
}
if (opacity > 0.) {
const auto percent = QString::number(
@ -1069,7 +1068,7 @@ int Poll::paintAnswer(
left,
top,
outerWidth,
selection);
context);
p.setOpacity(sqrt(opacity));
paintFilling(
p,
@ -1080,11 +1079,11 @@ int Poll::paintAnswer(
top,
width,
height,
selection);
context);
p.setOpacity(1.);
}
} else if (!showVotes()) {
paintRadio(p, answer, left, top, selection);
paintRadio(p, answer, left, top, context);
} else {
paintPercent(
p,
@ -1093,7 +1092,7 @@ int Poll::paintAnswer(
left,
top,
outerWidth,
selection);
context);
paintFilling(
p,
answer.chosen,
@ -1103,7 +1102,7 @@ int Poll::paintAnswer(
top,
width,
height,
selection);
context);
}
top += st::historyPollAnswerPadding.top();
@ -1118,14 +1117,15 @@ void Poll::paintRadio(
const Answer &answer,
int left,
int top,
TextSelection selection) const {
const PaintContext &context) const {
top += st::historyPollAnswerPadding.top();
const auto outbg = _parent->hasOutLayout();
const auto selected = (selection == FullSelection);
const auto selected = context.selected();
const auto st = context.st;
PainterHighQualityEnabler hq(p);
const auto &st = st::historyPollRadio;
const auto &radio = st::historyPollRadio;
const auto over = ClickHandler::showAsActive(answer.handler);
const auto &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);
@ -1137,15 +1137,19 @@ void Poll::paintRadio(
p.setOpacity(o * (over ? st::historyPollRadioOpacityOver : st::historyPollRadioOpacity));
}
const auto rect = QRectF(left, top, st.diameter, st.diameter).marginsRemoved(QMarginsF(st.thickness / 2., st.thickness / 2., st.thickness / 2., st.thickness / 2.));
const auto rect = QRectF(left, top, radio.diameter, radio.diameter).marginsRemoved(QMarginsF(radio.thickness / 2., radio.thickness / 2., radio.thickness / 2., radio.thickness / 2.));
if (_sendingAnimation && _sendingAnimation->option == answer.option) {
const auto &active = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
const auto &active = selected
? (outbg
? st::msgOutServiceFgSelected
: st::msgInServiceFgSelected)
: (outbg ? st->msgOutServiceFg() : st->msgInServiceFg());
if (anim::Disabled()) {
anim::DrawStaticLoading(p, rect, st.thickness, active);
anim::DrawStaticLoading(p, rect, radio.thickness, active);
} else {
const auto state = _sendingAnimation->animation.computeState();
auto pen = anim::pen(regular, active, state.shown);
pen.setWidth(st.thickness);
pen.setWidth(radio.thickness);
pen.setCapStyle(Qt::RoundCap);
p.setPen(pen);
p.drawArc(
@ -1156,21 +1160,21 @@ void Poll::paintRadio(
} else {
if (checkmark < 1.) {
auto pen = regular->p;
pen.setWidth(st.thickness);
pen.setWidth(radio.thickness);
p.setPen(pen);
p.drawEllipse(rect);
}
if (checkmark > 0.) {
const auto removeFull = (st.diameter / 2 - st.thickness);
const auto removeFull = (radio.diameter / 2 - radio.thickness);
const auto removeNow = removeFull * (1. - checkmark);
const auto color = outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg);
auto pen = color->p;
pen.setWidth(st.thickness);
pen.setWidth(radio.thickness);
p.setPen(pen);
p.setBrush(color);
p.drawEllipse(rect.marginsRemoved({ removeNow, removeNow, removeNow, removeNow }));
const auto &icon = outbg ? (selected ? st::historyPollOutChosenSelected : st::historyPollOutChosen) : (selected ? st::historyPollInChosenSelected : st::historyPollInChosen);
icon.paint(p, left + (st.diameter - icon.width()) / 2, top + (st.diameter - icon.height()) / 2, width());
icon.paint(p, left + (radio.diameter - icon.width()) / 2, top + (radio.diameter - icon.height()) / 2, width());
}
}
@ -1184,7 +1188,7 @@ void Poll::paintPercent(
int left,
int top,
int outerWidth,
TextSelection selection) const {
const PaintContext &context) const {
const auto outbg = _parent->hasOutLayout();
const auto aleft = left + st::historyPollAnswerPadding.left();
@ -1205,10 +1209,10 @@ void Poll::paintFilling(
int top,
int width,
int height,
TextSelection selection) const {
const PaintContext &context) const {
const auto bottom = top + height;
const auto outbg = _parent->hasOutLayout();
const auto selected = (selection == FullSelection);
const auto selected = context.selected();
const auto aleft = left + st::historyPollAnswerPadding.left();
const auto awidth = width
- st::historyPollAnswerPadding.left()

View file

@ -112,12 +112,12 @@ private:
Painter &p,
int right,
int top,
TextSelection selection) const;
const PaintContext &context) const;
void paintShowSolution(
Painter &p,
int right,
int top,
TextSelection selection) const;
const PaintContext &context) const;
int paintAnswer(
Painter &p,
const Answer &answer,
@ -126,13 +126,13 @@ private:
int top,
int width,
int outerWidth,
TextSelection selection) const;
const PaintContext &context) const;
void paintRadio(
Painter &p,
const Answer &answer,
int left,
int top,
TextSelection selection) const;
const PaintContext &context) const;
void paintPercent(
Painter &p,
const QString &percent,
@ -140,7 +140,7 @@ private:
int left,
int top,
int outerWidth,
TextSelection selection) const;
const PaintContext &context) const;
void paintFilling(
Painter &p,
bool chosen,
@ -150,19 +150,19 @@ private:
int top,
int width,
int height,
TextSelection selection) const;
const PaintContext &context) const;
void paintInlineFooter(
Painter &p,
int left,
int top,
int paintw,
TextSelection selection) const;
const PaintContext &context) const;
void paintBottom(
Painter &p,
int left,
int top,
int paintw,
TextSelection selection) const;
const PaintContext &context) const;
bool checkAnimationStart() const;
bool answerVotesChanged() const;

View file

@ -20,10 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/qthelp_url.h"
#include "core/local_url_handlers.h"
#include "ui/text/format_values.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/chat_theme.h"
#include "ui/cached_round_corners.h"
#include "ui/ui_utility.h"
#include "layout/layout_selection.h" // FullSelection
#include "styles/style_chat.h"
namespace HistoryView {
@ -159,6 +159,7 @@ void ThemeDocument::draw(Painter &p, const PaintContext &context) const {
if (_data) {
_dataMedia->automaticLoad(_realParent->fullId(), _parent->data());
}
const auto st = context.st;
auto selected = (context.selection == FullSelection);
auto loaded = dataLoaded();
auto displayLoading = _data && _data->displayLoading();
@ -187,7 +188,7 @@ void ThemeDocument::draw(Painter &p, const PaintContext &context) const {
auto statusY = painty + st::msgDateImgDelta + st::msgDateImgPadding.y();
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
auto statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
p.setFont(st::normalFont);
p.setPen(st::msgDateImgFg);
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());

View file

@ -20,9 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image.h"
#include "ui/text/text_options.h"
#include "ui/text/format_values.h"
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/cached_round_corners.h"
#include "layout/layout_selection.h" // FullSelection
#include "data/data_session.h"
#include "data/data_wall_paper.h"
#include "data/data_media_types.h"
@ -453,11 +452,12 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
auto paintw = width();
auto outbg = _parent->hasOutLayout();
bool selected = (context.selection == FullSelection);
const auto st = context.st;
const auto stm = context.messageStyle();
const auto selected = context.selected();
auto &barfg = selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor);
auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
const auto &barfg = stm->msgReplyBarColor;
const auto &semibold = stm->msgServiceFg;
QMargins bubble(_attach ? _attach->bubbleMargins() : QMargins());
auto padding = inBubblePadding();
@ -517,7 +517,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
tshift += lineHeight;
}
if (_titleLines) {
p.setPen(outbg ? st::webPageTitleOutFg : st::webPageTitleInFg);
p.setPen(stm->webPageTitleFg);
auto endskip = 0;
if (_title.hasSkipBlock()) {
endskip = _parent->skipBlockWidth();
@ -526,7 +526,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
tshift += _titleLines * lineHeight;
}
if (_descriptionLines) {
p.setPen(outbg ? st::webPageDescriptionOutFg : st::webPageDescriptionInFg);
p.setPen(stm->webPageDescriptionFg);
auto endskip = 0;
if (_description.hasSkipBlock()) {
endskip = _parent->skipBlockWidth();
@ -549,9 +549,10 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
p.translate(attachLeft, attachTop);
auto attachContext = context.translated(-attachLeft, -attachTop);
attachContext.selection = selected ? FullSelection : TextSelection { 0, 0 };
_attach->draw(p, attachContext);
_attach->draw(p, context.translated(
-attachLeft,
-attachTop
).withSelection(selected ? FullSelection : TextSelection()));
auto pixwidth = _attach->width();
auto pixheight = _attach->height();
@ -572,7 +573,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
auto dateW = pixwidth - dateX - st::msgDateImgDelta;
auto dateH = pixheight - dateY - st::msgDateImgDelta;
Ui::FillRoundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
Ui::FillRoundRect(p, dateX, dateY, dateW, dateH, selected ? st->msgDateImgBgSelected() : st->msgDateImgBg(), selected ? st->msgDateImgBgSelectedCorners() : st->msgDateImgBgCorners());
p.setFont(st::msgDateFont);
p.setPen(st::msgDateImgFg);
@ -584,7 +585,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
if (!attachAdditionalInfoText.isEmpty()) {
p.setFont(st::msgDateFont);
p.setPen(selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg));
p.setPen(stm->msgDateFg);
p.drawTextLeft(st::msgPadding.left(), bar.y() + bar.height() + st::mediaInBubbleSkip, width(), attachAdditionalInfoText);
}
}

View file

@ -75,13 +75,9 @@ void CreateMaskCorners() {
void CreatePaletteCorners() {
PrepareCorners(MenuCorners, st::roundRadiusSmall, st::menuBg);
PrepareCorners(BoxCorners, st::boxRadius, st::boxBg);
PrepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd);
PrepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
PrepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
PrepareCorners(SelectedOverlaySmallCorners, st::roundRadiusSmall, st::msgSelectOverlay);
PrepareCorners(SelectedOverlayLargeCorners, st::historyMessageRadius, st::msgSelectOverlay);
PrepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
PrepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
PrepareCorners(OverviewVideoCorners, st::overviewVideoStatusRadius, st::msgDateImgBg);
PrepareCorners(OverviewVideoSelectedCorners, st::overviewVideoStatusRadius, st::msgDateImgBgSelected);
PrepareCorners(InShadowCorners, st::historyMessageRadius, st::msgInShadow);

View file

@ -22,13 +22,9 @@ struct CornersPixmaps {
enum CachedRoundCorners : int {
BoxCorners,
MenuCorners,
BotKbOverCorners,
StickerCorners,
StickerSelectedCorners,
SelectedOverlaySmallCorners,
SelectedOverlayLargeCorners,
DateCorners,
DateSelectedCorners,
OverviewVideoCorners,
OverviewVideoSelectedCorners,
ForwardCorners,
@ -59,15 +55,15 @@ void FillComplexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, Re
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
}
void FillRoundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, CachedRoundCorners index, RectParts parts = RectPart::Full);
inline void FillRoundShadow(Painter &p, const QRect &rect, style::color shadow, CachedRoundCorners index, RectParts parts = RectPart::Full) {
return FillRoundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
FillRoundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
}
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
}
[[nodiscard]] CornersPixmaps PrepareCornerPixmaps(
@ -79,6 +75,9 @@ inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, ImageR
style::color bg,
const style::color *sh);
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, const CornersPixmaps &corner, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, corner, shadow, parts);
}
void StartCachedCorners();
void FinishCachedCorners();

View file

@ -9,35 +9,186 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/chat_theme.h"
#include "styles/style_chat.h"
#include "styles/style_dialogs.h"
namespace Ui {
namespace {
void EnsureCorners(
CornersPixmaps &corners,
int radius,
const style::color &color,
const style::color *shadow = nullptr) {
if (corners.p[0].isNull()) {
corners = Ui::PrepareCornerPixmaps(radius, color, shadow);
}
}
} // namespace
not_null<const MessageStyle*> ChatPaintContext::messageStyle() const {
return &st->messageStyle(outbg, selected());
}
ChatStyle::ChatStyle() {
finalize();
messageIcon(
make(_historyPsaForwardPalette, st::historyPsaForwardPalette);
make(_imgReplyTextPalette, st::imgReplyTextPalette);
make(_historyRepliesInvertedIcon, st::historyRepliesInvertedIcon);
make(_historyViewsInvertedIcon, st::historyViewsInvertedIcon);
make(_historyViewsSendingIcon, st::historyViewsSendingIcon);
make(
_historyViewsSendingInvertedIcon,
st::historyViewsSendingInvertedIcon);
make(_historyPinInvertedIcon, st::historyPinInvertedIcon);
make(_historySendingIcon, st::historySendingIcon);
make(_historySendingInvertedIcon, st::historySendingInvertedIcon);
make(_historySentInvertedIcon, st::historySentInvertedIcon);
make(_historyReceivedInvertedIcon, st::historyReceivedInvertedIcon);
make(_msgBotKbUrlIcon, st::msgBotKbUrlIcon);
make(_msgBotKbPaymentIcon, st::msgBotKbPaymentIcon);
make(_msgBotKbSwitchPmIcon, st::msgBotKbSwitchPmIcon);
make(_historyFastCommentsIcon, st::historyFastCommentsIcon);
make(_historyFastShareIcon, st::historyFastShareIcon);
make(_historyGoToOriginalIcon, st::historyGoToOriginalIcon);
make(
&MessageStyle::msgBg,
st::msgInBg,
st::msgInBgSelected,
st::msgOutBg,
st::msgOutBgSelected);
make(
&MessageStyle::msgShadow,
st::msgInShadow,
st::msgInShadowSelected,
st::msgOutShadow,
st::msgOutShadowSelected);
make(
&MessageStyle::msgServiceFg,
st::msgInServiceFg,
st::msgInServiceFgSelected,
st::msgOutServiceFg,
st::msgOutServiceFgSelected);
make(
&MessageStyle::msgDateFg,
st::msgInDateFg,
st::msgInDateFgSelected,
st::msgOutDateFg,
st::msgOutDateFgSelected);
make(
&MessageStyle::msgFileThumbLinkFg,
st::msgFileThumbLinkInFg,
st::msgFileThumbLinkInFgSelected,
st::msgFileThumbLinkOutFg,
st::msgFileThumbLinkOutFgSelected);
make(
&MessageStyle::msgFileBg,
st::msgFileInBg,
st::msgFileInBgSelected,
st::msgFileOutBg,
st::msgFileOutBgSelected);
make(
&MessageStyle::historyTextFg,
st::historyTextInFg,
st::historyTextInFgSelected,
st::historyTextOutFg,
st::historyTextOutFgSelected);
make(
&MessageStyle::msgReplyBarColor,
st::msgInReplyBarColor,
st::msgInReplyBarSelColor,
st::msgOutReplyBarColor,
st::msgOutReplyBarSelColor);
make(
&MessageStyle::webPageTitleFg,
st::webPageTitleInFg,
st::webPageTitleInFg,
st::webPageTitleOutFg,
st::webPageTitleOutFg);
make(
&MessageStyle::webPageDescriptionFg,
st::webPageDescriptionInFg,
st::webPageDescriptionInFg,
st::webPageDescriptionOutFg,
st::webPageDescriptionOutFg);
make(
&MessageStyle::textPalette,
st::inTextPalette,
st::inTextPaletteSelected,
st::outTextPalette,
st::outTextPaletteSelected);
make(
&MessageStyle::fwdTextPalette,
st::inFwdTextPalette,
st::inFwdTextPaletteSelected,
st::outFwdTextPalette,
st::outFwdTextPaletteSelected);
make(
&MessageStyle::replyTextPalette,
st::inReplyTextPalette,
st::inReplyTextPaletteSelected,
st::outReplyTextPalette,
st::outReplyTextPaletteSelected);
make(
&MessageStyle::tailLeft,
st::historyBubbleTailInLeft,
st::historyBubbleTailInLeftSelected,
st::historyBubbleTailOutLeft,
st::historyBubbleTailOutLeftSelected);
messageIcon(
make(
&MessageStyle::tailRight,
st::historyBubbleTailInRight,
st::historyBubbleTailInRightSelected,
st::historyBubbleTailOutRight,
st::historyBubbleTailOutRightSelected);
messageColor(
&MessageStyle::msgBg,
msgInBg(),
msgInBgSelected(),
msgOutBg(),
msgOutBgSelected());
messageColor(
&MessageStyle::msgShadow,
msgInShadow(),
msgInShadowSelected(),
msgOutShadow(),
msgOutShadowSelected());
make(
&MessageStyle::historyRepliesIcon,
st::historyRepliesInIcon,
st::historyRepliesInSelectedIcon,
st::historyRepliesOutIcon,
st::historyRepliesOutSelectedIcon);
make(
&MessageStyle::historyViewsIcon,
st::historyViewsInIcon,
st::historyViewsInSelectedIcon,
st::historyViewsOutIcon,
st::historyViewsOutSelectedIcon);
make(
&MessageStyle::historyPinIcon,
st::historyPinInIcon,
st::historyPinInSelectedIcon,
st::historyPinOutIcon,
st::historyPinOutSelectedIcon);
make(
&MessageStyle::historySentIcon,
st::historySentIcon,
st::historySentSelectedIcon,
st::historySentIcon,
st::historySentSelectedIcon);
make(
&MessageStyle::historyReceivedIcon,
st::historyReceivedIcon,
st::historyReceivedSelectedIcon,
st::historyReceivedIcon,
st::historyReceivedSelectedIcon);
make(
&MessageStyle::historyPsaIcon,
st::historyPsaIconIn,
st::historyPsaIconInSelected,
st::historyPsaIconOut,
st::historyPsaIconOutSelected);
make(
&MessageStyle::historyCommentsOpen,
st::historyCommentsOpenIn,
st::historyCommentsOpenInSelected,
st::historyCommentsOpenOut,
st::historyCommentsOpenOutSelected);
make(
&MessageStyle::historyComments,
st::historyCommentsIn,
st::historyCommentsInSelected,
st::historyCommentsOut,
st::historyCommentsOutSelected);
}
void ChatStyle::apply(not_null<ChatTheme*> theme) {
@ -61,27 +212,82 @@ void ChatStyle::assignPalette(not_null<const style::palette*> palette) {
for (auto &style : _messageStyles) {
style.corners = {};
}
_msgServiceBgCorners = {};
_msgServiceBgSelectedCorners = {};
_msgBotKbOverBgAddCorners = {};
}
const MessageStyle &ChatStyle::messageStyle(bool outbg, bool selected) const {
auto &result = messageStyleRaw(outbg, selected);
if (result.corners.p[0].isNull()) {
result.corners = Ui::PrepareCornerPixmaps(
st::historyMessageRadius,
result.msgBg,
&result.msgShadow);
}
EnsureCorners(
result.corners,
st::historyMessageRadius,
result.msgBg,
&result.msgShadow);
return result;
}
const CornersPixmaps &ChatStyle::msgServiceBgCorners() const {
EnsureCorners(_msgServiceBgCorners, st::dateRadius, msgServiceBg());
return _msgServiceBgCorners;
}
const CornersPixmaps &ChatStyle::msgServiceBgSelectedCorners() const {
EnsureCorners(
_msgServiceBgSelectedCorners,
st::dateRadius,
msgServiceBgSelected());
return _msgServiceBgSelectedCorners;
}
const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCorners() const {
EnsureCorners(
_msgBotKbOverBgAddCorners,
st::dateRadius,
msgBotKbOverBgAdd());
return _msgBotKbOverBgAddCorners;
}
const CornersPixmaps &ChatStyle::msgDateImgBgCorners() const {
EnsureCorners(
_msgDateImgBgCorners,
st::dateRadius,
msgDateImgBg());
return _msgDateImgBgCorners;
}
const CornersPixmaps &ChatStyle::msgDateImgBgSelectedCorners() const {
EnsureCorners(
_msgDateImgBgSelectedCorners,
st::dateRadius,
msgDateImgBgSelected());
return _msgDateImgBgSelectedCorners;
}
MessageStyle &ChatStyle::messageStyleRaw(bool outbg, bool selected) const {
return _messageStyles[(outbg ? 2 : 0) + (selected ? 1 : 0)];
}
void ChatStyle::icon(style::icon &my, const style::icon &original) {
void ChatStyle::make(style::color &my, const style::color &original) {
my = _colors[style::main_palette::indexOfColor(original)];
}
void ChatStyle::make(style::icon &my, const style::icon &original) {
my = original.withPalette(*this);
}
void ChatStyle::make(
style::TextPalette &my,
const style::TextPalette &original) {
make(my.linkFg, original.linkFg);
make(my.monoFg, original.monoFg);
make(my.selectBg, original.selectBg);
make(my.selectFg, original.selectFg);
make(my.selectLinkFg, original.selectLinkFg);
make(my.selectMonoFg, original.selectMonoFg);
make(my.selectOverlay, original.selectOverlay);
}
MessageStyle &ChatStyle::messageIn() {
return messageStyleRaw(false, false);
}
@ -98,28 +304,17 @@ MessageStyle &ChatStyle::messageOutSelected() {
return messageStyleRaw(true, true);
}
void ChatStyle::messageIcon(
style::icon MessageStyle::*my,
const style::icon &originalIn,
const style::icon &originalInSelected,
const style::icon &originalOut,
const style::icon &originalOutSelected) {
icon(messageIn().*my, originalIn);
icon(messageInSelected().*my, originalInSelected);
icon(messageOut().*my, originalOut);
icon(messageOutSelected().*my, originalOutSelected);
}
void ChatStyle::messageColor(
style::color MessageStyle::*my,
const style::color &originalIn,
const style::color &originalInSelected,
const style::color &originalOut,
const style::color &originalOutSelected) {
messageIn().*my = originalIn;
messageInSelected().*my = originalInSelected;
messageOut().*my = originalOut;
messageOutSelected().*my = originalOutSelected;
template <typename Type>
void ChatStyle::make(
Type MessageStyle::*my,
const Type &originalIn,
const Type &originalInSelected,
const Type &originalOut,
const Type &originalOutSelected) {
make(messageIn().*my, originalIn);
make(messageInSelected().*my, originalInSelected);
make(messageOut().*my, originalOut);
make(messageOutSelected().*my, originalOutSelected);
}
} // namespace Ui

View file

@ -9,17 +9,78 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/cached_round_corners.h"
#include "ui/style/style_core_palette.h"
#include "layout/layout_selection.h"
namespace Ui {
class ChatTheme;
class ChatStyle;
struct BubblePattern;
struct MessageStyle {
CornersPixmaps corners;
style::icon tailLeft = { Qt::Uninitialized };
style::icon tailRight = { Qt::Uninitialized };
style::color msgBg;
style::color msgShadow;
style::color msgServiceFg;
style::color msgDateFg;
style::color msgFileThumbLinkFg;
style::color msgFileBg;
style::color historyTextFg;
style::color msgReplyBarColor;
style::color webPageTitleFg;
style::color webPageDescriptionFg;
style::TextPalette textPalette;
style::TextPalette fwdTextPalette;
style::TextPalette replyTextPalette;
style::icon tailLeft = { Qt::Uninitialized };
style::icon tailRight = { Qt::Uninitialized };
style::icon historyRepliesIcon = { Qt::Uninitialized };
style::icon historyViewsIcon = { Qt::Uninitialized };
style::icon historyPinIcon = { Qt::Uninitialized };
style::icon historySentIcon = { Qt::Uninitialized };
style::icon historyReceivedIcon = { Qt::Uninitialized };
style::icon historyPsaIcon = { Qt::Uninitialized };
style::icon historyCommentsOpen = { Qt::Uninitialized };
style::icon historyComments = { Qt::Uninitialized };
};
struct ChatPaintContext {
not_null<const ChatStyle*> st;
const BubblePattern *bubblesPattern = nullptr;
QRect viewport;
QRect clip;
TextSelection selection;
bool outbg = false;
crl::time now = 0;
void translate(int x, int y) {
viewport.translate(x, y);
clip.translate(x, y);
}
void translate(QPoint point) {
translate(point.x(), point.y());
}
[[nodiscard]] bool selected() const {
return (selection == FullSelection);
}
[[nodiscard]] not_null<const MessageStyle*> messageStyle() const;
[[nodiscard]] ChatPaintContext translated(int x, int y) const {
auto result = *this;
result.translate(x, y);
return result;
}
[[nodiscard]] ChatPaintContext translated(QPoint point) const {
return translated(point.x(), point.y());
}
[[nodiscard]] ChatPaintContext withSelection(
TextSelection selection) const {
auto result = *this;
result.selection = selection;
return result;
}
};
class ChatStyle final : public style::palette {
@ -32,10 +93,70 @@ public:
bool outbg,
bool selected) const;
[[nodiscard]] const CornersPixmaps &msgServiceBgCorners() const;
[[nodiscard]] const CornersPixmaps &msgServiceBgSelectedCorners() const;
[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCorners() const;
[[nodiscard]] const CornersPixmaps &msgDateImgBgCorners() const;
[[nodiscard]] const CornersPixmaps &msgDateImgBgSelectedCorners() const;
[[nodiscard]] const style::TextPalette &historyPsaForwardPalette() const {
return _historyPsaForwardPalette;
}
[[nodiscard]] const style::TextPalette &imgReplyTextPalette() const {
return _imgReplyTextPalette;
}
[[nodiscard]] const style::icon &historyRepliesInvertedIcon() const {
return _historyRepliesInvertedIcon;
}
[[nodiscard]] const style::icon &historyViewsInvertedIcon() const {
return _historyViewsInvertedIcon;
}
[[nodiscard]] const style::icon &historyViewsSendingIcon() const {
return _historyViewsSendingIcon;
}
[[nodiscard]] const style::icon &historyViewsSendingInvertedIcon() const {
return _historyViewsSendingInvertedIcon;
}
[[nodiscard]] const style::icon &historyPinInvertedIcon() const {
return _historyPinInvertedIcon;
}
[[nodiscard]] const style::icon &historySendingIcon() const {
return _historySendingIcon;
}
[[nodiscard]] const style::icon &historySendingInvertedIcon() const {
return _historySendingInvertedIcon;
}
[[nodiscard]] const style::icon &historySentInvertedIcon() const {
return _historySentInvertedIcon;
}
[[nodiscard]] const style::icon &historyReceivedInvertedIcon() const {
return _historyReceivedInvertedIcon;
}
[[nodiscard]] const style::icon &msgBotKbUrlIcon() const {
return _msgBotKbUrlIcon;
}
[[nodiscard]] const style::icon &msgBotKbPaymentIcon() const {
return _msgBotKbPaymentIcon;
}
[[nodiscard]] const style::icon &msgBotKbSwitchPmIcon() const {
return _msgBotKbSwitchPmIcon;
}
[[nodiscard]] const style::icon &historyFastCommentsIcon() const {
return _historyFastCommentsIcon;
}
[[nodiscard]] const style::icon &historyFastShareIcon() const {
return _historyFastShareIcon;
}
[[nodiscard]] const style::icon &historyGoToOriginalIcon() const {
return _historyGoToOriginalIcon;
}
private:
void assignPalette(not_null<const style::palette*> palette);
void icon(style::icon &my, const style::icon &original);
void make(style::color &my, const style::color &original);
void make(style::icon &my, const style::icon &original);
void make(style::TextPalette &my, const style::TextPalette &original);
[[nodiscard]] MessageStyle &messageStyleRaw(
bool outbg,
@ -44,21 +165,41 @@ private:
[[nodiscard]] MessageStyle &messageInSelected();
[[nodiscard]] MessageStyle &messageOut();
[[nodiscard]] MessageStyle &messageOutSelected();
void messageIcon(
style::icon MessageStyle::*my,
const style::icon &originalIn,
const style::icon &originalInSelected,
const style::icon &originalOut,
const style::icon &originalOutSelected);
void messageColor(
style::color MessageStyle::*my,
const style::color &originalIn,
const style::color &originalInSelected,
const style::color &originalOut,
const style::color &originalOutSelected);
template <typename Type>
void make(
Type MessageStyle::*my,
const Type &originalIn,
const Type &originalInSelected,
const Type &originalOut,
const Type &originalOutSelected);
mutable std::array<MessageStyle, 4> _messageStyles;
mutable CornersPixmaps _msgServiceBgCorners;
mutable CornersPixmaps _msgServiceBgSelectedCorners;
mutable CornersPixmaps _msgBotKbOverBgAddCorners;
mutable CornersPixmaps _msgDateImgBgCorners;
mutable CornersPixmaps _msgDateImgBgSelectedCorners;
style::TextPalette _historyPsaForwardPalette;
style::TextPalette _imgReplyTextPalette;
style::icon _historyRepliesInvertedIcon = { Qt::Uninitialized };
style::icon _historyViewsInvertedIcon = { Qt::Uninitialized };
style::icon _historyViewsSendingIcon = { Qt::Uninitialized };
style::icon _historyViewsSendingInvertedIcon = { Qt::Uninitialized };
style::icon _historyPinInvertedIcon = { Qt::Uninitialized };
style::icon _historySendingIcon = { Qt::Uninitialized };
style::icon _historySendingInvertedIcon = { Qt::Uninitialized };
style::icon _historySentInvertedIcon = { Qt::Uninitialized };
style::icon _historyReceivedInvertedIcon = { Qt::Uninitialized };
style::icon _msgBotKbUrlIcon = { Qt::Uninitialized };
style::icon _msgBotKbPaymentIcon = { Qt::Uninitialized };
style::icon _msgBotKbSwitchPmIcon = { Qt::Uninitialized };
style::icon _historyFastCommentsIcon = { Qt::Uninitialized };
style::icon _historyFastShareIcon = { Qt::Uninitialized };
style::icon _historyGoToOriginalIcon = { Qt::Uninitialized };
rpl::lifetime _defaultPaletteChangeLifetime;
};

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h"
#include "ui/ui_utility.h"
#include "ui/chat/message_bubble.h"
#include "ui/chat/chat_style.h"
#include "ui/style/style_core_palette.h"
#include <crl/crl_async.h>

View file

@ -18,33 +18,9 @@ class palette;
namespace Ui {
class ChatStyle;
struct ChatPaintContext;
struct BubblePattern;
struct ChatPaintContext {
not_null<const ChatStyle*> st;
const BubblePattern *bubblesPattern = nullptr;
QRect viewport;
QRect clip;
TextSelection selection;
crl::time now = 0;
void translate(int x, int y) {
viewport.translate(x, y);
clip.translate(x, y);
}
void translate(QPoint point) {
translate(point.x(), point.y());
}
[[nodiscard]] ChatPaintContext translated(int x, int y) const {
auto result = *this;
result.translate(x, y);
return result;
}
[[nodiscard]] ChatPaintContext translated(QPoint point) const {
return translated(point.x(), point.y());
}
};
struct ChatThemeBackground {
QImage prepared;
QImage preparedForTiled;

View file

@ -236,7 +236,7 @@ void PaintSolidBubble(Painter &p, const SimpleBubble &args) {
}, [&](const QRect &rect) {
p.fillRect(rect, *sh);
}, [&](const QRect &rect, RectParts parts) {
Ui::FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, st.corners, sh, parts);
Ui::FillRoundRect(p, rect, bg, st.corners, sh, parts);
}, [&](const QPoint &bottomPosition) {
tail.paint(p, bottomPosition - tailShift, args.outerWidth);
return tail.width();