mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Support two-color quote outlines.
This commit is contained in:
parent
8c28ce4c99
commit
4709e11e46
18 changed files with 290 additions and 142 deletions
|
@ -682,15 +682,19 @@ void HistoryMessageReply::paint(
|
||||||
const auto hasQuote = !_fields.quote.empty();
|
const auto hasQuote = !_fields.quote.empty();
|
||||||
const auto selected = context.selected();
|
const auto selected = context.selected();
|
||||||
const auto colorIndexPlusOne = context.outbg ? 0 : _colorIndexPlusOne;
|
const auto colorIndexPlusOne = context.outbg ? 0 : _colorIndexPlusOne;
|
||||||
|
const auto twoColored = colorIndexPlusOne
|
||||||
|
&& Ui::ColorIndexTwoColored(colorIndexPlusOne - 1);
|
||||||
const auto cache = !inBubble
|
const auto cache = !inBubble
|
||||||
? (hasQuote
|
? (hasQuote
|
||||||
? st->serviceQuoteCache()
|
? st->serviceQuoteCache(twoColored)
|
||||||
: st->serviceReplyCache()).get()
|
: st->serviceReplyCache(twoColored)).get()
|
||||||
: colorIndexPlusOne
|
: colorIndexPlusOne
|
||||||
? (hasQuote
|
? (hasQuote
|
||||||
? st->coloredQuoteCache(selected, colorIndexPlusOne - 1)
|
? st->coloredQuoteCache(selected, colorIndexPlusOne - 1)
|
||||||
: st->coloredReplyCache(selected, colorIndexPlusOne - 1)).get()
|
: st->coloredReplyCache(selected, colorIndexPlusOne - 1)).get()
|
||||||
: (hasQuote ? stm->quoteCache : stm->replyCache).get();
|
: (hasQuote
|
||||||
|
? (twoColored ? stm->quoteCacheTwo : stm->quoteCache)
|
||||||
|
: (twoColored ? stm->replyCacheTwo : stm->replyCache)).get();
|
||||||
const auto "eSt = hasQuote
|
const auto "eSt = hasQuote
|
||||||
? st::messageTextStyle.blockquote
|
? st::messageTextStyle.blockquote
|
||||||
: st::messageQuoteStyle;
|
: st::messageQuoteStyle;
|
||||||
|
@ -763,12 +767,10 @@ void HistoryMessageReply::paint(
|
||||||
if (w > textLeft + st::historyReplyPadding.right()) {
|
if (w > textLeft + st::historyReplyPadding.right()) {
|
||||||
w -= textLeft + st::historyReplyPadding.right();
|
w -= textLeft + st::historyReplyPadding.right();
|
||||||
p.setPen(!inBubble
|
p.setPen(!inBubble
|
||||||
? st->msgImgReplyBarColor()
|
? st->msgImgReplyBarColor()->c
|
||||||
: colorIndexPlusOne
|
: colorIndexPlusOne
|
||||||
? HistoryView::FromNameFg(
|
? FromNameFg(context, colorIndexPlusOne - 1)
|
||||||
context,
|
: stm->msgServiceFg->c);
|
||||||
colorIndexPlusOne - 1)
|
|
||||||
: stm->msgServiceFg);
|
|
||||||
_name.drawLeftElided(p, x + textLeft, y + st::historyReplyPadding.top(), w, w + 2 * x + 2 * textLeft);
|
_name.drawLeftElided(p, x + textLeft, y + st::historyReplyPadding.top(), w, w + 2 * x + 2 * textLeft);
|
||||||
if (originalVia && w > _name.maxWidth() + st::msgServiceFont->spacew) {
|
if (originalVia && w > _name.maxWidth() + st::msgServiceFont->spacew) {
|
||||||
p.setFont(st::msgServiceFont);
|
p.setFont(st::msgServiceFont);
|
||||||
|
@ -802,7 +804,7 @@ void HistoryMessageReply::paint(
|
||||||
auto copy = std::optional<style::TextPalette>();
|
auto copy = std::optional<style::TextPalette>();
|
||||||
if (inBubble && _colorIndexPlusOne) {
|
if (inBubble && _colorIndexPlusOne) {
|
||||||
copy.emplace(*replyToTextPalette);
|
copy.emplace(*replyToTextPalette);
|
||||||
owned.emplace(cache->outline);
|
owned.emplace(cache->icon);
|
||||||
copy->linkFg = owned->color();
|
copy->linkFg = owned->color();
|
||||||
replyToTextPalette = &*copy;
|
replyToTextPalette = &*copy;
|
||||||
}
|
}
|
||||||
|
@ -821,7 +823,7 @@ void HistoryMessageReply::paint(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
p.drawTextLeft(
|
p.drawTextLeft(
|
||||||
x + textLeft,
|
x + textLeft,
|
||||||
(y + (_height - st::msgDateFont->height) / 2),
|
(y + (_height - st::msgDateFont->height) / 2),
|
||||||
|
|
|
@ -467,6 +467,7 @@ Element::Element(
|
||||||
| (IsItemScheduledUntilOnline(data)
|
| (IsItemScheduledUntilOnline(data)
|
||||||
? Flag::ScheduledUntilOnline
|
? Flag::ScheduledUntilOnline
|
||||||
: Flag()))
|
: Flag()))
|
||||||
|
, _colorIndex(data->computeColorIndex())
|
||||||
, _context(delegate->elementContext()) {
|
, _context(delegate->elementContext()) {
|
||||||
history()->owner().registerItemView(this);
|
history()->owner().registerItemView(this);
|
||||||
refreshMedia(replacing);
|
refreshMedia(replacing);
|
||||||
|
@ -490,6 +491,10 @@ not_null<History*> Element::history() const {
|
||||||
return _data->history();
|
return _data->history();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 Element::colorIndex() const {
|
||||||
|
return _colorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
QDateTime Element::dateTime() const {
|
QDateTime Element::dateTime() const {
|
||||||
return _dateTime;
|
return _dateTime;
|
||||||
}
|
}
|
||||||
|
@ -557,8 +562,8 @@ void Element::prepareCustomEmojiPaint(
|
||||||
}
|
}
|
||||||
clearCustomEmojiRepaint();
|
clearCustomEmojiRepaint();
|
||||||
p.setInactive(context.paused);
|
p.setInactive(context.paused);
|
||||||
if (!_heavyCustomEmoji) {
|
if (!(_flags & Flag::HeavyCustomEmoji)) {
|
||||||
_heavyCustomEmoji = true;
|
_flags |= Flag::HeavyCustomEmoji;
|
||||||
history()->owner().registerHeavyViewPart(const_cast<Element*>(this));
|
history()->owner().registerHeavyViewPart(const_cast<Element*>(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,8 +577,8 @@ void Element::prepareCustomEmojiPaint(
|
||||||
}
|
}
|
||||||
clearCustomEmojiRepaint();
|
clearCustomEmojiRepaint();
|
||||||
p.setInactive(context.paused);
|
p.setInactive(context.paused);
|
||||||
if (!_heavyCustomEmoji) {
|
if (!(_flags & Flag::HeavyCustomEmoji)) {
|
||||||
_heavyCustomEmoji = true;
|
_flags |= Flag::HeavyCustomEmoji;
|
||||||
history()->owner().registerHeavyViewPart(const_cast<Element*>(this));
|
history()->owner().registerHeavyViewPart(const_cast<Element*>(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1411,7 +1416,7 @@ auto Element::verticalRepaintRange() const -> VerticalRepaintRange {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Element::hasHeavyPart() const {
|
bool Element::hasHeavyPart() const {
|
||||||
return _heavyCustomEmoji;
|
return (_flags & Flag::HeavyCustomEmoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Element::checkHeavyPart() {
|
void Element::checkHeavyPart() {
|
||||||
|
@ -1445,8 +1450,8 @@ void Element::unloadHeavyPart() {
|
||||||
if (_media) {
|
if (_media) {
|
||||||
_media->unloadHeavyPart();
|
_media->unloadHeavyPart();
|
||||||
}
|
}
|
||||||
if (_heavyCustomEmoji) {
|
if (_flags & Flag::HeavyCustomEmoji) {
|
||||||
_heavyCustomEmoji = false;
|
_flags &= ~Flag::HeavyCustomEmoji;
|
||||||
_text.unloadPersistentAnimation();
|
_text.unloadPersistentAnimation();
|
||||||
if (const auto reply = data()->Get<HistoryMessageReply>()) {
|
if (const auto reply = data()->Get<HistoryMessageReply>()) {
|
||||||
reply->unloadPersistentAnimation();
|
reply->unloadPersistentAnimation();
|
||||||
|
@ -1623,8 +1628,8 @@ Element::~Element() {
|
||||||
// Delete media while owner still exists.
|
// Delete media while owner still exists.
|
||||||
clearSpecialOnlyEmoji();
|
clearSpecialOnlyEmoji();
|
||||||
base::take(_media);
|
base::take(_media);
|
||||||
if (_heavyCustomEmoji) {
|
if (_flags & Flag::HeavyCustomEmoji) {
|
||||||
_heavyCustomEmoji = false;
|
_flags &= ~Flag::HeavyCustomEmoji;
|
||||||
_text.unloadPersistentAnimation();
|
_text.unloadPersistentAnimation();
|
||||||
checkHeavyPart();
|
checkHeavyPart();
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,18 +277,19 @@ class Element
|
||||||
, public base::has_weak_ptr {
|
, public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
enum class Flag : uint16 {
|
enum class Flag : uint16 {
|
||||||
ServiceMessage = 0x0001,
|
ServiceMessage = 0x0001,
|
||||||
NeedsResize = 0x0002,
|
NeedsResize = 0x0002,
|
||||||
AttachedToPrevious = 0x0004,
|
AttachedToPrevious = 0x0004,
|
||||||
AttachedToNext = 0x0008,
|
AttachedToNext = 0x0008,
|
||||||
BubbleAttachedToPrevious = 0x0010,
|
BubbleAttachedToPrevious = 0x0010,
|
||||||
BubbleAttachedToNext = 0x0020,
|
BubbleAttachedToNext = 0x0020,
|
||||||
HiddenByGroup = 0x0040,
|
HiddenByGroup = 0x0040,
|
||||||
SpecialOnlyEmoji = 0x0080,
|
SpecialOnlyEmoji = 0x0080,
|
||||||
CustomEmojiRepainting = 0x0100,
|
CustomEmojiRepainting = 0x0100,
|
||||||
ScheduledUntilOnline = 0x0200,
|
ScheduledUntilOnline = 0x0200,
|
||||||
TopicRootReply = 0x0400,
|
TopicRootReply = 0x0400,
|
||||||
MediaOverriden = 0x0800,
|
MediaOverriden = 0x0800,
|
||||||
|
HeavyCustomEmoji = 0x1000,
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||||
|
@ -306,6 +307,7 @@ public:
|
||||||
[[nodiscard]] Context context() const;
|
[[nodiscard]] Context context() const;
|
||||||
void refreshDataId();
|
void refreshDataId();
|
||||||
|
|
||||||
|
[[nodiscard]] uint8 colorIndex() const;
|
||||||
[[nodiscard]] QDateTime dateTime() const;
|
[[nodiscard]] QDateTime dateTime() const;
|
||||||
|
|
||||||
[[nodiscard]] int y() const;
|
[[nodiscard]] int y() const;
|
||||||
|
@ -592,9 +594,11 @@ private:
|
||||||
int _indexInBlock = -1;
|
int _indexInBlock = -1;
|
||||||
|
|
||||||
mutable Flags _flags = Flag(0);
|
mutable Flags _flags = Flag(0);
|
||||||
mutable bool _heavyCustomEmoji = false;
|
uint8 _colorIndex = 0;
|
||||||
Context _context = Context();
|
Context _context = Context();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto size = sizeof(Element);
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -366,12 +366,6 @@ QString FastReplyText() {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
style::color FromNameFg(
|
|
||||||
const Ui::ChatPaintContext &context,
|
|
||||||
uint8 colorIndex) {
|
|
||||||
return Ui::FromNameFg(context.st, context.selected(), colorIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Message::CommentsButton {
|
struct Message::CommentsButton {
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
std::vector<UserpicInRow> userpics;
|
std::vector<UserpicInRow> userpics;
|
||||||
|
@ -1358,8 +1352,8 @@ void Message::paintFromName(
|
||||||
Assert(from || info);
|
Assert(from || info);
|
||||||
const auto st = context.st;
|
const auto st = context.st;
|
||||||
const auto nameFg = !context.outbg
|
const auto nameFg = !context.outbg
|
||||||
? FromNameFg(context, from ? from->colorIndex() : info->colorIndex)
|
? FromNameFg(context, colorIndex())
|
||||||
: stm->msgServiceFg;
|
: stm->msgServiceFg->c;
|
||||||
const auto nameText = [&] {
|
const auto nameText = [&] {
|
||||||
if (from) {
|
if (from) {
|
||||||
validateFromNameText(from);
|
validateFromNameText(from);
|
||||||
|
@ -1374,11 +1368,8 @@ void Message::paintFromName(
|
||||||
const auto x = availableLeft
|
const auto x = availableLeft
|
||||||
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
||||||
const auto y = trect.top();
|
const auto y = trect.top();
|
||||||
const auto color = QColor(
|
auto color = nameFg;
|
||||||
nameFg->c.red(),
|
color.setAlpha(115);
|
||||||
nameFg->c.green(),
|
|
||||||
nameFg->c.blue(),
|
|
||||||
nameFg->c.alpha() * 115 / 255);
|
|
||||||
const auto user = from->asUser();
|
const auto user = from->asUser();
|
||||||
const auto id = user ? user->emojiStatusId() : 0;
|
const auto id = user ? user->emojiStatusId() : 0;
|
||||||
if (_fromNameStatus->id != id) {
|
if (_fromNameStatus->id != id) {
|
||||||
|
@ -1630,7 +1621,7 @@ void Message::paintText(
|
||||||
.availableWidth = trect.width(),
|
.availableWidth = trect.width(),
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
@ -3064,14 +3055,13 @@ void Message::updateViewButtonExistence() {
|
||||||
} else if (_viewButton) {
|
} else if (_viewButton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto repainter = [=] { repaint(); };
|
auto make = [=](auto &&from) {
|
||||||
const auto index = item->computeColorIndex();
|
return std::make_unique<ViewButton>(
|
||||||
_viewButton = sponsored
|
std::forward<decltype(from)>(from),
|
||||||
? std::make_unique<ViewButton>(
|
colorIndex(),
|
||||||
sponsored,
|
[=] { repaint(); });
|
||||||
index,
|
};
|
||||||
std::move(repainter))
|
_viewButton = sponsored ? make(sponsored) : make(media);
|
||||||
: std::make_unique<ViewButton>(media, index, std::move(repainter));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Message::initLogEntryOriginal() {
|
void Message::initLogEntryOriginal() {
|
||||||
|
|
|
@ -56,10 +56,6 @@ struct BottomRippleMask {
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] style::color FromNameFg(
|
|
||||||
const Ui::ChatPaintContext &context,
|
|
||||||
uint8 colorIndex);
|
|
||||||
|
|
||||||
class Message final : public Element {
|
class Message final : public Element {
|
||||||
public:
|
public:
|
||||||
Message(
|
Message(
|
||||||
|
|
|
@ -235,8 +235,9 @@ void ViewButton::draw(
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
|
|
||||||
const auto selected = context.selected();
|
const auto selected = context.selected();
|
||||||
|
const auto twoColored = Ui::ColorIndexTwoColored(_inner->colorIndex);
|
||||||
const auto cache = context.outbg
|
const auto cache = context.outbg
|
||||||
? stm->replyCache.get()
|
? (twoColored ? stm->replyCacheTwo : stm->replyCache).get()
|
||||||
: context.st->coloredReplyCache(selected, _inner->colorIndex).get();
|
: context.st->coloredReplyCache(selected, _inner->colorIndex).get();
|
||||||
const auto radius = st::historyPagePreview.radius;
|
const auto radius = st::historyPagePreview.radius;
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ void ViewButton::draw(
|
||||||
p.setBrush(cache->bg);
|
p.setBrush(cache->bg);
|
||||||
p.drawRoundedRect(r, radius, radius);
|
p.drawRoundedRect(r, radius, radius);
|
||||||
|
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
_inner->text.drawElided(
|
_inner->text.drawElided(
|
||||||
p,
|
p,
|
||||||
r.left(),
|
r.left(),
|
||||||
|
@ -266,7 +267,7 @@ void ViewButton::draw(
|
||||||
r.left() + r.width() - icon.width() - padding,
|
r.left() + r.width() - icon.width() - padding,
|
||||||
r.top() + padding,
|
r.top() + padding,
|
||||||
r.width(),
|
r.width(),
|
||||||
cache->outline);
|
cache->icon);
|
||||||
}
|
}
|
||||||
if (_inner->lastWidth != r.width()) {
|
if (_inner->lastWidth != r.width()) {
|
||||||
_inner->lastWidth = r.width();
|
_inner->lastWidth = r.width();
|
||||||
|
|
|
@ -749,7 +749,7 @@ void Document::draw(
|
||||||
.availableWidth = captionw,
|
.availableWidth = captionw,
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(parent()->colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
|
|
@ -236,7 +236,7 @@ void ExtendedPreview::draw(Painter &p, const PaintContext &context) const {
|
||||||
.availableWidth = captionw,
|
.availableWidth = captionw,
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(parent()->colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
|
|
@ -220,15 +220,16 @@ void Game::draw(Painter &p, const PaintContext &context) const {
|
||||||
auto paintw = inner.width();
|
auto paintw = inner.width();
|
||||||
|
|
||||||
const auto selected = context.selected();
|
const auto selected = context.selected();
|
||||||
|
const auto twoColored = Ui::ColorIndexTwoColored(_colorIndex);
|
||||||
const auto cache = context.outbg
|
const auto cache = context.outbg
|
||||||
? stm->replyCache.get()
|
? (twoColored ? stm->replyCacheTwo : stm->replyCache).get()
|
||||||
: st->coloredReplyCache(selected, _colorIndex).get();
|
: st->coloredReplyCache(selected, _colorIndex).get();
|
||||||
Ui::Text::ValidateQuotePaintCache(*cache, _st);
|
Ui::Text::ValidateQuotePaintCache(*cache, _st);
|
||||||
Ui::Text::FillQuotePaint(p, outer, *cache, _st);
|
Ui::Text::FillQuotePaint(p, outer, *cache, _st);
|
||||||
|
|
||||||
auto lineHeight = UnitedLineHeight();
|
auto lineHeight = UnitedLineHeight();
|
||||||
if (_titleLines) {
|
if (_titleLines) {
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
p.setTextPalette(context.outbg
|
p.setTextPalette(context.outbg
|
||||||
? stm->semiboldPalette
|
? stm->semiboldPalette
|
||||||
: st->coloredTextPalette(selected, _colorIndex));
|
: st->coloredTextPalette(selected, _colorIndex));
|
||||||
|
|
|
@ -721,7 +721,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
.availableWidth = captionw,
|
.availableWidth = captionw,
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(parent()->colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
|
|
@ -347,8 +347,9 @@ void Giveaway::paintChannels(
|
||||||
const auto ratio = style::DevicePixelRatio();
|
const auto ratio = style::DevicePixelRatio();
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
const auto selected = context.selected();
|
const auto selected = context.selected();
|
||||||
|
const auto twoColored = Ui::ColorIndexTwoColored(_colorIndex);
|
||||||
const auto cache = context.outbg
|
const auto cache = context.outbg
|
||||||
? stm->replyCache.get()
|
? (twoColored ? stm->replyCacheTwo : stm->replyCache).get()
|
||||||
: context.st->coloredReplyCache(selected, _colorIndex).get();
|
: context.st->coloredReplyCache(selected, _colorIndex).get();
|
||||||
if (_channelCorners[0].isNull() || _channelBg != cache->bg) {
|
if (_channelCorners[0].isNull() || _channelBg != cache->bg) {
|
||||||
_channelBg = cache->bg;
|
_channelBg = cache->bg;
|
||||||
|
@ -357,7 +358,7 @@ void Giveaway::paintChannels(
|
||||||
style::colorizeImage(image, cache->bg, &image);
|
style::colorizeImage(image, cache->bg, &image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
const auto padding = st::chatGiveawayChannelPadding;
|
const auto padding = st::chatGiveawayChannelPadding;
|
||||||
for (const auto &channel : _channels) {
|
for (const auto &channel : _channels) {
|
||||||
const auto &thumbnail = channel.thumbnail;
|
const auto &thumbnail = channel.thumbnail;
|
||||||
|
|
|
@ -368,7 +368,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||||
.availableWidth = captionw,
|
.availableWidth = captionw,
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(parent()->colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
|
|
@ -406,7 +406,7 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
||||||
.availableWidth = captionw,
|
.availableWidth = captionw,
|
||||||
.palette = &stm->textPalette,
|
.palette = &stm->textPalette,
|
||||||
.pre = stm->preCache.get(),
|
.pre = stm->preCache.get(),
|
||||||
.blockquote = stm->quoteCache.get(),
|
.blockquote = context.quoteCache(parent()->colorIndex()),
|
||||||
.colors = context.st->highlightColors(),
|
.colors = context.st->highlightColors(),
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
|
|
|
@ -546,8 +546,9 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
auto attachAdditionalInfoText = _attach ? _attach->additionalInfoString() : QString();
|
auto attachAdditionalInfoText = _attach ? _attach->additionalInfoString() : QString();
|
||||||
|
|
||||||
const auto selected = context.selected();
|
const auto selected = context.selected();
|
||||||
|
const auto twoColored = Ui::ColorIndexTwoColored(_colorIndex);
|
||||||
const auto cache = context.outbg
|
const auto cache = context.outbg
|
||||||
? stm->replyCache.get()
|
? (twoColored ? stm->replyCacheTwo : stm->replyCache).get()
|
||||||
: st->coloredReplyCache(selected, _colorIndex).get();
|
: st->coloredReplyCache(selected, _colorIndex).get();
|
||||||
Ui::Text::ValidateQuotePaintCache(*cache, _st);
|
Ui::Text::ValidateQuotePaintCache(*cache, _st);
|
||||||
Ui::Text::FillQuotePaint(p, outer, *cache, _st);
|
Ui::Text::FillQuotePaint(p, outer, *cache, _st);
|
||||||
|
@ -601,7 +602,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
paintw -= pw + st::webPagePhotoDelta;
|
paintw -= pw + st::webPagePhotoDelta;
|
||||||
}
|
}
|
||||||
if (_siteNameLines) {
|
if (_siteNameLines) {
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
p.setTextPalette(context.outbg
|
p.setTextPalette(context.outbg
|
||||||
? stm->semiboldPalette
|
? stm->semiboldPalette
|
||||||
: st->coloredTextPalette(selected, _colorIndex));
|
: st->coloredTextPalette(selected, _colorIndex));
|
||||||
|
@ -703,10 +704,10 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
|
|
||||||
if (_openButtonWidth) {
|
if (_openButtonWidth) {
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.setPen(cache->outline);
|
p.setPen(cache->icon);
|
||||||
const auto end = inner.y() + inner.height() + _st.padding.bottom();
|
const auto end = inner.y() + inner.height() + _st.padding.bottom();
|
||||||
const auto line = st::historyPageButtonLine;
|
const auto line = st::historyPageButtonLine;
|
||||||
auto color = cache->outline;
|
auto color = cache->icon;
|
||||||
color.setAlphaF(color.alphaF() * 0.3);
|
color.setAlphaF(color.alphaF() * 0.3);
|
||||||
p.fillRect(inner.x(), end, inner.width(), line, color);
|
p.fillRect(inner.x(), end, inner.width(), line, color);
|
||||||
const auto top = end + st::historyPageButtonPadding.top();
|
const auto top = end + st::historyPageButtonPadding.top();
|
||||||
|
|
|
@ -31,16 +31,16 @@ void EnsureCorners(
|
||||||
|
|
||||||
void EnsureBlockquoteCache(
|
void EnsureBlockquoteCache(
|
||||||
std::unique_ptr<Text::QuotePaintCache> &cache,
|
std::unique_ptr<Text::QuotePaintCache> &cache,
|
||||||
const style::color &color) {
|
Fn<ColorIndexValues()> values) {
|
||||||
if (cache) {
|
if (cache) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cache = std::make_unique<Text::QuotePaintCache>();
|
cache = std::make_unique<Text::QuotePaintCache>();
|
||||||
cache->bg = color->c;
|
const auto &colors = values();
|
||||||
cache->bg.setAlphaF(0.12);
|
cache->bg = colors.bg;
|
||||||
cache->outline = color->c;
|
cache->outline1 = colors.outline1;
|
||||||
cache->outline.setAlphaF(0.9);
|
cache->outline2 = colors.outline2;
|
||||||
cache->icon = cache->outline;
|
cache->icon = colors.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsurePreCache(
|
void EnsurePreCache(
|
||||||
|
@ -56,11 +56,12 @@ void EnsurePreCache(
|
||||||
if (!bg) {
|
if (!bg) {
|
||||||
cache->bg.setAlphaF(0.12);
|
cache->bg.setAlphaF(0.12);
|
||||||
}
|
}
|
||||||
cache->outline = color->c;
|
cache->outline1 = color->c;
|
||||||
cache->outline.setAlphaF(0.9);
|
cache->outline1.setAlphaF(0.9);
|
||||||
|
cache->outline2 = cache->outline1;
|
||||||
cache->header = color->c;
|
cache->header = color->c;
|
||||||
cache->header.setAlphaF(0.25);
|
cache->header.setAlphaF(0.25);
|
||||||
cache->icon = cache->outline;
|
cache->icon = cache->outline1;
|
||||||
cache->icon.setAlphaF(0.6);
|
cache->icon.setAlphaF(0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +75,15 @@ not_null<const MessageImageStyle*> ChatPaintContext::imageStyle() const {
|
||||||
return &st->imageStyle(selected());
|
return &st->imageStyle(selected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_null<Text::QuotePaintCache*> ChatPaintContext::quoteCache(
|
||||||
|
uint8 colorIndex) const {
|
||||||
|
return !outbg
|
||||||
|
? st->coloredQuoteCache(selected(), colorIndex).get()
|
||||||
|
: ColorIndexTwoColored(colorIndex)
|
||||||
|
? messageStyle()->quoteCacheTwo.get()
|
||||||
|
: messageStyle()->quoteCache.get();
|
||||||
|
}
|
||||||
|
|
||||||
int HistoryServiceMsgRadius() {
|
int HistoryServiceMsgRadius() {
|
||||||
static const auto result = [] {
|
static const auto result = [] {
|
||||||
const auto minMessageHeight = st::msgServicePadding.top()
|
const auto minMessageHeight = st::msgServicePadding.top()
|
||||||
|
@ -99,6 +109,87 @@ int HistoryServiceMsgInvertedShrink() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColorIndexValues ComputeColorIndexValues(
|
||||||
|
not_null<const ChatStyle*> st,
|
||||||
|
bool selected,
|
||||||
|
uint8 colorIndex) {
|
||||||
|
if (colorIndex < kSimpleColorIndexCount) {
|
||||||
|
const style::color list[] = {
|
||||||
|
st->historyPeer1NameFg(),
|
||||||
|
st->historyPeer2NameFg(),
|
||||||
|
st->historyPeer3NameFg(),
|
||||||
|
st->historyPeer4NameFg(),
|
||||||
|
st->historyPeer5NameFg(),
|
||||||
|
st->historyPeer6NameFg(),
|
||||||
|
st->historyPeer7NameFg(),
|
||||||
|
st->historyPeer8NameFg(),
|
||||||
|
};
|
||||||
|
const style::color listSelected[] = {
|
||||||
|
st->historyPeer1NameFgSelected(),
|
||||||
|
st->historyPeer2NameFgSelected(),
|
||||||
|
st->historyPeer3NameFgSelected(),
|
||||||
|
st->historyPeer4NameFgSelected(),
|
||||||
|
st->historyPeer5NameFgSelected(),
|
||||||
|
st->historyPeer6NameFgSelected(),
|
||||||
|
st->historyPeer7NameFgSelected(),
|
||||||
|
st->historyPeer8NameFgSelected(),
|
||||||
|
};
|
||||||
|
const auto paletteIndex = ColorIndexToPaletteIndex(colorIndex);
|
||||||
|
auto result = ColorIndexValues{
|
||||||
|
.name = (selected ? listSelected : list)[paletteIndex]->c,
|
||||||
|
};
|
||||||
|
result.bg = result.name;
|
||||||
|
result.bg.setAlphaF(0.12);
|
||||||
|
result.outline1 = result.name;
|
||||||
|
result.outline1.setAlphaF(0.9);
|
||||||
|
result.outline2 = result.outline1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
struct Pair {
|
||||||
|
QColor outline1;
|
||||||
|
QColor outline2;
|
||||||
|
};
|
||||||
|
const Pair list[] = {
|
||||||
|
{ QColor(0xE1, 0x50, 0x52), QColor(0xF9, 0xAE, 0x63) }, // Red
|
||||||
|
{ QColor(0xE0, 0x80, 0x2B), QColor(0xFA, 0xC5, 0x34) }, // Orange
|
||||||
|
{ QColor(0xA0, 0x5F, 0xF3), QColor(0xF4, 0x8F, 0xFF) }, // Violet
|
||||||
|
{ QColor(0x27, 0xA9, 0x10), QColor(0xA7, 0xDC, 0x57) }, // Green
|
||||||
|
{ QColor(0x27, 0xAC, 0xCE), QColor(0x82, 0xE8, 0xD6) }, // Cyan
|
||||||
|
{ QColor(0x33, 0x91, 0xD4), QColor(0x7D, 0xD3, 0xF0) }, // Blue
|
||||||
|
{ QColor(0xD1, 0x48, 0x72), QColor(0xFF, 0xBE, 0xA0) }, // Pink
|
||||||
|
};
|
||||||
|
const auto &pair = list[colorIndex - kSimpleColorIndexCount];
|
||||||
|
auto bg = pair.outline1;
|
||||||
|
bg.setAlphaF(0.12);
|
||||||
|
return {
|
||||||
|
.name = st->dark() ? pair.outline2 : pair.outline1,
|
||||||
|
.bg = bg,
|
||||||
|
.outline1 = pair.outline1,
|
||||||
|
.outline2 = pair.outline2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorIndexTwoColored(uint8 colorIndex) {
|
||||||
|
return (colorIndex >= kSimpleColorIndexCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorIndexValues SimpleColorIndexValues(QColor color, bool twoColored) {
|
||||||
|
auto bg = color;
|
||||||
|
bg.setAlphaF(0.12);
|
||||||
|
auto outline1 = color;
|
||||||
|
outline1.setAlphaF(0.9);
|
||||||
|
auto outline2 = outline1;
|
||||||
|
if (twoColored) {
|
||||||
|
outline2.setAlphaF(0.3);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
.name = color,
|
||||||
|
.bg = bg,
|
||||||
|
.outline1 = outline1,
|
||||||
|
.outline2 = outline2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ChatStyle::ChatStyle() {
|
ChatStyle::ChatStyle() {
|
||||||
finalize();
|
finalize();
|
||||||
make(_historyPsaForwardPalette, st::historyPsaForwardPalette);
|
make(_historyPsaForwardPalette, st::historyPsaForwardPalette);
|
||||||
|
@ -453,6 +544,8 @@ ChatStyle::ChatStyle() {
|
||||||
&MessageImageStyle::historyVideoMessageMute,
|
&MessageImageStyle::historyVideoMessageMute,
|
||||||
st::historyVideoMessageMute,
|
st::historyVideoMessageMute,
|
||||||
st::historyVideoMessageMuteSelected);
|
st::historyVideoMessageMuteSelected);
|
||||||
|
|
||||||
|
updateDarkValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatStyle::ChatStyle(not_null<const style::palette*> isolated)
|
ChatStyle::ChatStyle(not_null<const style::palette*> isolated)
|
||||||
|
@ -464,6 +557,13 @@ void ChatStyle::apply(not_null<ChatTheme*> theme) {
|
||||||
applyCustomPalette(theme->palette());
|
applyCustomPalette(theme->palette());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatStyle::updateDarkValue() {
|
||||||
|
const auto withBg = [&](const QColor &color) {
|
||||||
|
return CountContrast(windowBg()->c, color);
|
||||||
|
};
|
||||||
|
_dark = (withBg({ 0, 0, 0 }) < withBg({ 255, 255, 255 }));
|
||||||
|
}
|
||||||
|
|
||||||
void ChatStyle::applyCustomPalette(const style::palette *palette) {
|
void ChatStyle::applyCustomPalette(const style::palette *palette) {
|
||||||
assignPalette(palette ? palette : style::main_palette::get().get());
|
assignPalette(palette ? palette : style::main_palette::get().get());
|
||||||
if (palette) {
|
if (palette) {
|
||||||
|
@ -547,10 +647,13 @@ void ChatStyle::assignPalette(not_null<const style::palette*> palette) {
|
||||||
= stm.semiboldPalette.linkAlwaysActive
|
= stm.semiboldPalette.linkAlwaysActive
|
||||||
= (stm.textPalette.linkFg->c == stm.historyTextFg->c);
|
= (stm.textPalette.linkFg->c == stm.historyTextFg->c);
|
||||||
}
|
}
|
||||||
|
for (auto &values : _coloredValues) {
|
||||||
for (auto &palette : _coloredTextPalettes) {
|
values.reset();
|
||||||
palette.inited = false;
|
|
||||||
}
|
}
|
||||||
|
for (auto &palette : _coloredTextPalettes) {
|
||||||
|
palette.linkFg.reset();
|
||||||
|
}
|
||||||
|
updateDarkValue();
|
||||||
|
|
||||||
_paletteChanged.fire({});
|
_paletteChanged.fire({});
|
||||||
}
|
}
|
||||||
|
@ -584,20 +687,24 @@ const MessageStyle &ChatStyle::messageStyle(bool outbg, bool selected) const {
|
||||||
BubbleRadiusLarge(),
|
BubbleRadiusLarge(),
|
||||||
result.msgBg,
|
result.msgBg,
|
||||||
&result.msgShadow);
|
&result.msgShadow);
|
||||||
|
const auto &replyBar = result.msgReplyBarColor->c;
|
||||||
EnsureBlockquoteCache(
|
EnsureBlockquoteCache(
|
||||||
result.replyCache,
|
result.replyCache,
|
||||||
result.msgReplyBarColor);
|
[&] { return SimpleColorIndexValues(replyBar, false); });
|
||||||
|
EnsureBlockquoteCache(
|
||||||
|
result.replyCacheTwo,
|
||||||
|
[&] { return SimpleColorIndexValues(replyBar, true); });
|
||||||
if (!result.quoteCache) {
|
if (!result.quoteCache) {
|
||||||
result.quoteCache = std::make_unique<Text::QuotePaintCache>(
|
result.quoteCache = std::make_unique<Text::QuotePaintCache>(
|
||||||
*result.replyCache);
|
*result.replyCache);
|
||||||
}
|
}
|
||||||
|
if (!result.quoteCacheTwo) {
|
||||||
|
result.quoteCacheTwo = std::make_unique<Text::QuotePaintCache>(
|
||||||
|
*result.replyCacheTwo);
|
||||||
|
}
|
||||||
|
|
||||||
const auto preBgOverride = [&] {
|
const auto preBgOverride = [&] {
|
||||||
const auto withBg = [&](const QColor &color) {
|
return _dark ? QColor(0, 0, 0, 192) : std::optional<QColor>();
|
||||||
return CountContrast(windowBg()->c, color);
|
|
||||||
};
|
|
||||||
const auto dark = (withBg({ 0, 0, 0 }) < withBg({ 255, 255, 255 }));
|
|
||||||
return dark ? QColor(0, 0, 0, 192) : std::optional<QColor>();
|
|
||||||
};
|
};
|
||||||
EnsurePreCache(
|
EnsurePreCache(
|
||||||
result.preCache,
|
result.preCache,
|
||||||
|
@ -634,14 +741,37 @@ const MessageImageStyle &ChatStyle::imageStyle(bool selected) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Text::QuotePaintCache*> ChatStyle::serviceQuoteCache() const {
|
not_null<Text::QuotePaintCache*> ChatStyle::serviceQuoteCache(
|
||||||
EnsureBlockquoteCache(_serviceQuoteCache, msgServiceFg());
|
bool twoColored) const {
|
||||||
return _serviceQuoteCache.get();
|
const auto index = (twoColored ? 1 : 0);
|
||||||
|
const auto &service = msgServiceFg()->c;
|
||||||
|
EnsureBlockquoteCache(
|
||||||
|
_serviceQuoteCache[index],
|
||||||
|
[&] { return SimpleColorIndexValues(service, twoColored); });
|
||||||
|
return _serviceQuoteCache[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Text::QuotePaintCache*> ChatStyle::serviceReplyCache() const {
|
not_null<Text::QuotePaintCache*> ChatStyle::serviceReplyCache(
|
||||||
EnsureBlockquoteCache(_serviceReplyCache, msgServiceFg());
|
bool twoColored) const {
|
||||||
return _serviceReplyCache.get();
|
const auto index = (twoColored ? 1 : 0);
|
||||||
|
const auto &service = msgServiceFg()->c;
|
||||||
|
EnsureBlockquoteCache(
|
||||||
|
_serviceReplyCache[index],
|
||||||
|
[&] { return SimpleColorIndexValues(service, twoColored); });
|
||||||
|
return _serviceReplyCache[index].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorIndexValues &ChatStyle::coloredValues(
|
||||||
|
bool selected,
|
||||||
|
uint8 colorIndex) const {
|
||||||
|
Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
|
||||||
|
|
||||||
|
const auto shift = (selected ? kColorIndexCount : 0);
|
||||||
|
auto &result = _coloredValues[shift + colorIndex];
|
||||||
|
if (!result) {
|
||||||
|
result.emplace(ComputeColorIndexValues(this, selected, colorIndex));
|
||||||
|
}
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const style::TextPalette &ChatStyle::coloredTextPalette(
|
const style::TextPalette &ChatStyle::coloredTextPalette(
|
||||||
|
@ -651,14 +781,14 @@ const style::TextPalette &ChatStyle::coloredTextPalette(
|
||||||
|
|
||||||
const auto shift = (selected ? kColorIndexCount : 0);
|
const auto shift = (selected ? kColorIndexCount : 0);
|
||||||
auto &result = _coloredTextPalettes[shift + colorIndex];
|
auto &result = _coloredTextPalettes[shift + colorIndex];
|
||||||
if (!result.inited) {
|
if (!result.linkFg) {
|
||||||
result.inited = true;
|
result.linkFg.emplace(FromNameFg(this, selected, colorIndex));
|
||||||
make(
|
make(
|
||||||
result.data,
|
result.data,
|
||||||
(selected
|
(selected
|
||||||
? st::inReplyTextPaletteSelected
|
? st::inReplyTextPaletteSelected
|
||||||
: st::inReplyTextPalette));
|
: st::inReplyTextPalette));
|
||||||
result.data.linkFg = FromNameFg(this, selected, colorIndex);
|
result.data.linkFg = result.linkFg->color();
|
||||||
result.data.selectLinkFg = result.data.linkFg;
|
result.data.selectLinkFg = result.data.linkFg;
|
||||||
}
|
}
|
||||||
return result.data;
|
return result.data;
|
||||||
|
@ -684,7 +814,9 @@ not_null<Text::QuotePaintCache*> ChatStyle::coloredCache(
|
||||||
|
|
||||||
const auto shift = (selected ? kColorIndexCount : 0);
|
const auto shift = (selected ? kColorIndexCount : 0);
|
||||||
auto &cache = caches[shift + colorIndex];
|
auto &cache = caches[shift + colorIndex];
|
||||||
EnsureBlockquoteCache(cache, FromNameFg(this, selected, colorIndex));
|
EnsureBlockquoteCache(cache, [&] {
|
||||||
|
return coloredValues(selected, colorIndex);
|
||||||
|
});
|
||||||
return cache.get();
|
return cache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,47 +948,21 @@ void ChatStyle::make(
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 DecideColorIndex(uint64 id) {
|
uint8 DecideColorIndex(uint64 id) {
|
||||||
return id % kColorIndexCount;
|
return id % kSimpleColorIndexCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 ColorIndexToPaletteIndex(uint8 colorIndex) {
|
uint8 ColorIndexToPaletteIndex(uint8 colorIndex) {
|
||||||
Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
|
Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
|
||||||
|
|
||||||
const int8 map[] = { 0, 7, 4, 1, 6, 3, 5 };
|
const int8 map[] = { 0, 7, 4, 1, 6, 3, 5 };
|
||||||
return map[colorIndex];
|
return map[colorIndex % kSimpleColorIndexCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
style::color FromNameFg(
|
QColor FromNameFg(
|
||||||
not_null<const ChatStyle*> st,
|
not_null<const ChatStyle*> st,
|
||||||
bool selected,
|
bool selected,
|
||||||
uint8 colorIndex) {
|
uint8 colorIndex) {
|
||||||
Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
|
return st->coloredValues(selected, colorIndex).name;
|
||||||
|
|
||||||
if (selected) {
|
|
||||||
const style::color colors[] = {
|
|
||||||
st->historyPeer1NameFgSelected(),
|
|
||||||
st->historyPeer2NameFgSelected(),
|
|
||||||
st->historyPeer3NameFgSelected(),
|
|
||||||
st->historyPeer4NameFgSelected(),
|
|
||||||
st->historyPeer5NameFgSelected(),
|
|
||||||
st->historyPeer6NameFgSelected(),
|
|
||||||
st->historyPeer7NameFgSelected(),
|
|
||||||
st->historyPeer8NameFgSelected(),
|
|
||||||
};
|
|
||||||
return colors[ColorIndexToPaletteIndex(colorIndex)];
|
|
||||||
} else {
|
|
||||||
const style::color colors[] = {
|
|
||||||
st->historyPeer1NameFg(),
|
|
||||||
st->historyPeer2NameFg(),
|
|
||||||
st->historyPeer3NameFg(),
|
|
||||||
st->historyPeer4NameFg(),
|
|
||||||
st->historyPeer5NameFg(),
|
|
||||||
st->historyPeer6NameFg(),
|
|
||||||
st->historyPeer7NameFg(),
|
|
||||||
st->historyPeer8NameFg(),
|
|
||||||
};
|
|
||||||
return colors[ColorIndexToPaletteIndex(colorIndex)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillComplexOverlayRect(
|
void FillComplexOverlayRect(
|
||||||
|
|
|
@ -27,7 +27,8 @@ class ChatTheme;
|
||||||
class ChatStyle;
|
class ChatStyle;
|
||||||
struct BubblePattern;
|
struct BubblePattern;
|
||||||
|
|
||||||
inline constexpr auto kColorIndexCount = uint8(7);
|
inline constexpr auto kColorIndexCount = uint8(14);
|
||||||
|
inline constexpr auto kSimpleColorIndexCount = uint8(7);
|
||||||
|
|
||||||
struct MessageStyle {
|
struct MessageStyle {
|
||||||
CornersPixmaps msgBgCornersSmall;
|
CornersPixmaps msgBgCornersSmall;
|
||||||
|
@ -79,7 +80,9 @@ struct MessageStyle {
|
||||||
style::icon historyTranscribeIcon = { Qt::Uninitialized };
|
style::icon historyTranscribeIcon = { Qt::Uninitialized };
|
||||||
style::icon historyTranscribeHide = { Qt::Uninitialized };
|
style::icon historyTranscribeHide = { Qt::Uninitialized };
|
||||||
std::unique_ptr<Text::QuotePaintCache> quoteCache;
|
std::unique_ptr<Text::QuotePaintCache> quoteCache;
|
||||||
|
std::unique_ptr<Text::QuotePaintCache> quoteCacheTwo;
|
||||||
std::unique_ptr<Text::QuotePaintCache> replyCache;
|
std::unique_ptr<Text::QuotePaintCache> replyCache;
|
||||||
|
std::unique_ptr<Text::QuotePaintCache> replyCacheTwo;
|
||||||
std::unique_ptr<Text::QuotePaintCache> preCache;
|
std::unique_ptr<Text::QuotePaintCache> preCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,8 +119,6 @@ struct ChatPaintContext {
|
||||||
QRect viewport;
|
QRect viewport;
|
||||||
QRect clip;
|
QRect clip;
|
||||||
TextSelection selection;
|
TextSelection selection;
|
||||||
bool outbg = false;
|
|
||||||
bool paused = false;
|
|
||||||
crl::time now = 0;
|
crl::time now = 0;
|
||||||
|
|
||||||
void translate(int x, int y) {
|
void translate(int x, int y) {
|
||||||
|
@ -133,6 +134,8 @@ struct ChatPaintContext {
|
||||||
}
|
}
|
||||||
[[nodiscard]] not_null<const MessageStyle*> messageStyle() const;
|
[[nodiscard]] not_null<const MessageStyle*> messageStyle() const;
|
||||||
[[nodiscard]] not_null<const MessageImageStyle*> imageStyle() const;
|
[[nodiscard]] not_null<const MessageImageStyle*> imageStyle() const;
|
||||||
|
[[nodiscard]] not_null<Text::QuotePaintCache*> quoteCache(
|
||||||
|
uint8 colorIndex) const;
|
||||||
|
|
||||||
[[nodiscard]] ChatPaintContext translated(int x, int y) const {
|
[[nodiscard]] ChatPaintContext translated(int x, int y) const {
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
|
@ -157,12 +160,27 @@ struct ChatPaintContext {
|
||||||
};
|
};
|
||||||
SkipDrawingParts skipDrawingParts = SkipDrawingParts::None;
|
SkipDrawingParts skipDrawingParts = SkipDrawingParts::None;
|
||||||
|
|
||||||
|
bool outbg = false;
|
||||||
|
bool paused = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] int HistoryServiceMsgRadius();
|
[[nodiscard]] int HistoryServiceMsgRadius();
|
||||||
[[nodiscard]] int HistoryServiceMsgInvertedRadius();
|
[[nodiscard]] int HistoryServiceMsgInvertedRadius();
|
||||||
[[nodiscard]] int HistoryServiceMsgInvertedShrink();
|
[[nodiscard]] int HistoryServiceMsgInvertedShrink();
|
||||||
|
|
||||||
|
struct ColorIndexValues {
|
||||||
|
QColor name;
|
||||||
|
QColor bg;
|
||||||
|
QColor outline1;
|
||||||
|
QColor outline2;
|
||||||
|
};
|
||||||
|
[[nodiscard]] ColorIndexValues ComputeColorIndexValues(
|
||||||
|
not_null<const ChatStyle*> st,
|
||||||
|
bool selected,
|
||||||
|
uint8 colorIndex);
|
||||||
|
[[nodiscard]] bool ColorIndexTwoColored(uint8 colorIndex);
|
||||||
|
|
||||||
class ChatStyle final : public style::palette {
|
class ChatStyle final : public style::palette {
|
||||||
public:
|
public:
|
||||||
ChatStyle();
|
ChatStyle();
|
||||||
|
@ -172,6 +190,10 @@ public:
|
||||||
void applyCustomPalette(const style::palette *palette);
|
void applyCustomPalette(const style::palette *palette);
|
||||||
void applyAdjustedServiceBg(QColor serviceBg);
|
void applyAdjustedServiceBg(QColor serviceBg);
|
||||||
|
|
||||||
|
[[nodiscard]] bool dark() const {
|
||||||
|
return _dark;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::span<Text::SpecialColor> highlightColors() const;
|
[[nodiscard]] std::span<Text::SpecialColor> highlightColors() const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> paletteChanged() const {
|
[[nodiscard]] rpl::producer<> paletteChanged() const {
|
||||||
|
@ -202,10 +224,13 @@ public:
|
||||||
bool selected) const;
|
bool selected) const;
|
||||||
[[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const;
|
[[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const;
|
||||||
|
|
||||||
[[nodiscard]] auto serviceQuoteCache() const
|
[[nodiscard]] auto serviceQuoteCache(bool twoColored) const
|
||||||
-> not_null<Text::QuotePaintCache*>;
|
-> not_null<Text::QuotePaintCache*>;
|
||||||
[[nodiscard]] auto serviceReplyCache() const
|
[[nodiscard]] auto serviceReplyCache(bool twoColored) const
|
||||||
-> not_null<Text::QuotePaintCache*>;
|
-> not_null<Text::QuotePaintCache*>;
|
||||||
|
[[nodiscard]] const ColorIndexValues &coloredValues(
|
||||||
|
bool selected,
|
||||||
|
uint8 colorIndex) const;
|
||||||
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredQuoteCache(
|
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredQuoteCache(
|
||||||
bool selected,
|
bool selected,
|
||||||
uint8 colorIndex) const;
|
uint8 colorIndex) const;
|
||||||
|
@ -307,11 +332,12 @@ private:
|
||||||
kColorIndexCount * 2>;
|
kColorIndexCount * 2>;
|
||||||
|
|
||||||
struct ColoredPalette {
|
struct ColoredPalette {
|
||||||
|
std::optional<style::owned_color> linkFg;
|
||||||
style::TextPalette data;
|
style::TextPalette data;
|
||||||
bool inited = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void assignPalette(not_null<const style::palette*> palette);
|
void assignPalette(not_null<const style::palette*> palette);
|
||||||
|
void updateDarkValue();
|
||||||
|
|
||||||
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredCache(
|
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredCache(
|
||||||
ColoredQuotePaintCaches &caches,
|
ColoredQuotePaintCaches &caches,
|
||||||
|
@ -368,8 +394,15 @@ private:
|
||||||
int(CachedCornerRadius::kCount)];
|
int(CachedCornerRadius::kCount)];
|
||||||
|
|
||||||
mutable std::vector<Text::SpecialColor> _highlightColors;
|
mutable std::vector<Text::SpecialColor> _highlightColors;
|
||||||
mutable std::unique_ptr<Text::QuotePaintCache> _serviceQuoteCache;
|
mutable std::array<
|
||||||
mutable std::unique_ptr<Text::QuotePaintCache> _serviceReplyCache;
|
std::unique_ptr<Text::QuotePaintCache>,
|
||||||
|
2> _serviceQuoteCache;
|
||||||
|
mutable std::array<
|
||||||
|
std::unique_ptr<Text::QuotePaintCache>,
|
||||||
|
2> _serviceReplyCache;
|
||||||
|
mutable std::array<
|
||||||
|
std::optional<ColorIndexValues>,
|
||||||
|
2 * kColorIndexCount> _coloredValues;
|
||||||
mutable ColoredQuotePaintCaches _coloredQuoteCaches;
|
mutable ColoredQuotePaintCaches _coloredQuoteCaches;
|
||||||
mutable ColoredQuotePaintCaches _coloredReplyCaches;
|
mutable ColoredQuotePaintCaches _coloredReplyCaches;
|
||||||
mutable std::array<
|
mutable std::array<
|
||||||
|
@ -403,6 +436,8 @@ private:
|
||||||
style::icon _historyPollChoiceRight = { Qt::Uninitialized };
|
style::icon _historyPollChoiceRight = { Qt::Uninitialized };
|
||||||
style::icon _historyPollChoiceWrong = { Qt::Uninitialized };
|
style::icon _historyPollChoiceWrong = { Qt::Uninitialized };
|
||||||
|
|
||||||
|
bool _dark = false;
|
||||||
|
|
||||||
rpl::event_stream<> _paletteChanged;
|
rpl::event_stream<> _paletteChanged;
|
||||||
|
|
||||||
rpl::lifetime _defaultPaletteChangeLifetime;
|
rpl::lifetime _defaultPaletteChangeLifetime;
|
||||||
|
@ -412,11 +447,17 @@ private:
|
||||||
[[nodiscard]] uint8 DecideColorIndex(uint64 id);
|
[[nodiscard]] uint8 DecideColorIndex(uint64 id);
|
||||||
[[nodiscard]] uint8 ColorIndexToPaletteIndex(uint8 colorIndex);
|
[[nodiscard]] uint8 ColorIndexToPaletteIndex(uint8 colorIndex);
|
||||||
|
|
||||||
[[nodiscard]] style::color FromNameFg(
|
[[nodiscard]] QColor FromNameFg(
|
||||||
not_null<const ChatStyle*> st,
|
not_null<const ChatStyle*> st,
|
||||||
bool selected,
|
bool selected,
|
||||||
uint8 colorIndex);
|
uint8 colorIndex);
|
||||||
|
|
||||||
|
[[nodiscard]] inline QColor FromNameFg(
|
||||||
|
const ChatPaintContext &context,
|
||||||
|
uint8 colorIndex) {
|
||||||
|
return FromNameFg(context.st, context.selected(), colorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void FillComplexOverlayRect(
|
void FillComplexOverlayRect(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QRect rect,
|
QRect rect,
|
||||||
|
|
|
@ -489,8 +489,8 @@ ChatPaintContext ChatTheme::preparePaintContext(
|
||||||
.bubblesPattern = _bubblesBackgroundPattern.get(),
|
.bubblesPattern = _bubblesBackgroundPattern.get(),
|
||||||
.viewport = viewport,
|
.viewport = viewport,
|
||||||
.clip = clip,
|
.clip = clip,
|
||||||
.paused = paused,
|
|
||||||
.now = now,
|
.now = now,
|
||||||
|
.paused = paused,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4d1a5686a7620b163639492e1b81101b677d2472
|
Subproject commit 71d24af3a840d15a6cc0a3a8a1e9cbe77a604739
|
Loading…
Add table
Reference in a new issue