mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-27 19:11:09 +00:00
Display date in background preview.
This commit is contained in:
parent
5ca12a73c3
commit
58cf0fa2b1
@ -154,7 +154,8 @@ QImage PrepareScaledFromFull(
|
||||
std::move(result),
|
||||
Data::PatternColor(*patternBackground));
|
||||
}
|
||||
return result;
|
||||
return std::move(result).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -380,6 +381,7 @@ void BackgroundPreviewBox::prepare() {
|
||||
if (_paper.hasShareUrl()) {
|
||||
addLeftButton(langFactory(lng_background_share), [=] { share(); });
|
||||
}
|
||||
updateServiceBg(_paper.backgroundColor());
|
||||
|
||||
_paper.loadThumbnail();
|
||||
_paper.loadDocument();
|
||||
@ -493,12 +495,33 @@ void BackgroundPreviewBox::paintTexts(Painter &p, TimeMs ms) {
|
||||
- height2
|
||||
- st::historyPaddingBottom;
|
||||
p.translate(0, top);
|
||||
paintDate(p);
|
||||
_text1->draw(p, rect(), TextSelection(), ms);
|
||||
p.translate(0, height1);
|
||||
_text2->draw(p, rect(), TextSelection(), ms);
|
||||
p.translate(0, height2);
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::paintDate(Painter &p) {
|
||||
const auto date = _text1->Get<HistoryView::DateBadge>();
|
||||
if (!date || !_serviceBg) {
|
||||
return;
|
||||
}
|
||||
const auto text = date->text;
|
||||
const auto bubbleHeight = st::msgServicePadding.top() + st::msgServiceFont->height + st::msgServicePadding.bottom();
|
||||
const auto bubbleTop = st::msgServiceMargin.top();
|
||||
const auto textWidth = st::msgServiceFont->width(text);
|
||||
const auto bubbleWidth = st::msgServicePadding.left() + textWidth + st::msgServicePadding.right();
|
||||
const auto bubbleLeft = (width() - bubbleWidth) / 2;
|
||||
const auto radius = bubbleHeight / 2;
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(*_serviceBg);
|
||||
p.drawRoundedRect(bubbleLeft, bubbleTop, bubbleWidth, bubbleHeight, radius, radius);
|
||||
p.setPen(st::msgServiceFg);
|
||||
p.setFont(st::msgServiceFont);
|
||||
p.drawText(bubbleLeft + st::msgServicePadding.left(), bubbleTop + st::msgServicePadding.top() + st::msgServiceFont->ascent, text);
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) {
|
||||
Expects(_paper.document() != nullptr);
|
||||
|
||||
@ -531,9 +554,18 @@ bool BackgroundPreviewBox::setScaledFromThumb() {
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::setScaledFromImage(QImage &&image) {
|
||||
updateServiceBg(Window::Theme::CountAverageColor(image));
|
||||
_scaled = App::pixmapFromImageInPlace(std::move(image));
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::updateServiceBg(std::optional<QColor> background) {
|
||||
if (background) {
|
||||
_serviceBg = Window::Theme::AdjustedColor(
|
||||
st::msgServiceBg->c,
|
||||
*background);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<QColor> BackgroundPreviewBox::patternBackgroundColor() const {
|
||||
return _paper.isPattern() ? _paper.backgroundColor() : std::nullopt;
|
||||
}
|
||||
|
@ -70,10 +70,12 @@ private:
|
||||
void checkLoadedDocument();
|
||||
bool setScaledFromThumb();
|
||||
void setScaledFromImage(QImage &&image);
|
||||
void updateServiceBg(std::optional<QColor> background);
|
||||
std::optional<QColor> patternBackgroundColor() const;
|
||||
void paintImage(Painter &p);
|
||||
void paintRadial(Painter &p, TimeMs ms);
|
||||
void paintTexts(Painter &p, TimeMs ms);
|
||||
void paintDate(Painter &p);
|
||||
|
||||
AdminLog::OwnedItem _text1;
|
||||
AdminLog::OwnedItem _text2;
|
||||
@ -82,5 +84,6 @@ private:
|
||||
QPixmap _scaled;
|
||||
Ui::RadialAnimation _radial;
|
||||
base::binary_guard _generating;
|
||||
std::optional<QColor> _serviceBg;
|
||||
|
||||
};
|
||||
|
@ -6361,7 +6361,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
if (drawWebPagePreview) {
|
||||
auto previewLeft = st::historyReplySkip + st::webPageLeft;
|
||||
p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor);
|
||||
if ((_previewData->photo && !_previewData->photo->isNull()) || (_previewData->document && _previewData->document->hasThumbnail())) {
|
||||
if ((_previewData->photo && !_previewData->photo->isNull()) || (_previewData->document && _previewData->document->hasThumbnail() && !_previewData->document->isPatternWallPaper())) {
|
||||
const auto preview = _previewData->photo
|
||||
? _previewData->photo->getReplyPreview(Data::FileOrigin())
|
||||
: _previewData->document->getReplyPreview(Data::FileOrigin());
|
||||
|
@ -104,6 +104,21 @@ std::optional<QColor> ColorFromString(const QString &string) {
|
||||
255);
|
||||
}
|
||||
|
||||
QString StringFromColor(QColor color) {
|
||||
const auto component = [](int value) {
|
||||
const auto hex = [](int value) {
|
||||
value = std::clamp(value, 0, 15);
|
||||
return (value > 9)
|
||||
? ('a' + (value - 10))
|
||||
: ('0' + value);
|
||||
};
|
||||
return QString() + hex(value / 16) + hex(value % 16);
|
||||
};
|
||||
return component(color.red())
|
||||
+ component(color.green())
|
||||
+ component(color.blue());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WallPaper::WallPaper(WallPaperId id) : _id(id) {
|
||||
@ -155,9 +170,32 @@ bool WallPaper::hasShareUrl() const {
|
||||
}
|
||||
|
||||
QString WallPaper::shareUrl() const {
|
||||
return hasShareUrl()
|
||||
? Core::App().createInternalLinkFull("bg/" + _slug)
|
||||
: QString();
|
||||
if (!hasShareUrl()) {
|
||||
return QString();
|
||||
}
|
||||
const auto base = Core::App().createInternalLinkFull("bg/" + _slug);
|
||||
auto params = QStringList();
|
||||
if (isPattern()) {
|
||||
if (_backgroundColor) {
|
||||
params.push_back("bg_color=" + StringFromColor(*_backgroundColor));
|
||||
}
|
||||
if (_intensity) {
|
||||
params.push_back("intensity=" + QString::number(_intensity));
|
||||
}
|
||||
}
|
||||
auto mode = QStringList();
|
||||
if (_settings & MTPDwallPaperSettings::Flag::f_blur) {
|
||||
mode.push_back("blur");
|
||||
}
|
||||
if (_settings & MTPDwallPaperSettings::Flag::f_motion) {
|
||||
mode.push_back("motion");
|
||||
}
|
||||
if (!mode.isEmpty()) {
|
||||
params.push_back("mode=" + mode.join('+'));
|
||||
}
|
||||
return params.isEmpty()
|
||||
? base
|
||||
: base + '?' + params.join('&');
|
||||
}
|
||||
|
||||
void WallPaper::loadThumbnail() const {
|
||||
@ -815,12 +853,6 @@ QImage validateBackgroundImage(QImage image) {
|
||||
return image;
|
||||
}
|
||||
|
||||
void adjustColor(style::color color, float64 hue, float64 saturation) {
|
||||
auto original = color->c;
|
||||
original.setHslF(hue, saturation, original.lightnessF(), original.alphaF());
|
||||
color.set(original.red(), original.green(), original.blue(), original.alpha());
|
||||
}
|
||||
|
||||
void WriteAppliedTheme() {
|
||||
auto saved = Saved();
|
||||
saved.pathRelative = GlobalApplying.pathRelative;
|
||||
@ -1029,34 +1061,18 @@ bool ChatBackground::adjustPaletteRequired() {
|
||||
}
|
||||
|
||||
void ChatBackground::adjustPaletteUsingBackground(const QImage &image) {
|
||||
uint64 components[3] = { 0 };
|
||||
uint64 componentsScroll[3] = { 0 };
|
||||
const auto w = image.width();
|
||||
const auto h = image.height();
|
||||
const auto size = w * h;
|
||||
if (const auto pix = image.constBits()) {
|
||||
for (auto i = 0, l = size * 4; i != l; i += 4) {
|
||||
components[2] += pix[i + 0];
|
||||
components[1] += pix[i + 1];
|
||||
components[0] += pix[i + 2];
|
||||
}
|
||||
}
|
||||
|
||||
if (size) {
|
||||
for (auto i = 0; i != 3; ++i) {
|
||||
components[i] /= size;
|
||||
}
|
||||
}
|
||||
|
||||
adjustPaletteUsingColor(
|
||||
QColor(components[0], components[1], components[2]));
|
||||
adjustPaletteUsingColor(CountAverageColor(image));
|
||||
}
|
||||
|
||||
void ChatBackground::adjustPaletteUsingColor(QColor color) {
|
||||
const auto hue = color.hslHueF();
|
||||
const auto saturation = color.hslSaturationF();
|
||||
for (const auto &color : _adjustableColors) {
|
||||
adjustColor(color.item, hue, saturation);
|
||||
const auto prepared = color.toHsl();
|
||||
for (const auto &adjustable : _adjustableColors) {
|
||||
const auto adjusted = AdjustedColor(adjustable.item->c, prepared);
|
||||
adjustable.item.set(
|
||||
adjusted.red(),
|
||||
adjusted.green(),
|
||||
adjusted.blue(),
|
||||
adjusted.alpha());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1530,6 +1546,38 @@ bool IsPaletteTestingPath(const QString &path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QColor CountAverageColor(const QImage &image) {
|
||||
Expects(image.format() == QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
uint64 components[3] = { 0 };
|
||||
uint64 componentsScroll[3] = { 0 };
|
||||
const auto w = image.width();
|
||||
const auto h = image.height();
|
||||
const auto size = w * h;
|
||||
if (const auto pix = image.constBits()) {
|
||||
for (auto i = 0, l = size * 4; i != l; i += 4) {
|
||||
components[2] += pix[i + 0];
|
||||
components[1] += pix[i + 1];
|
||||
components[0] += pix[i + 2];
|
||||
}
|
||||
}
|
||||
if (size) {
|
||||
for (auto i = 0; i != 3; ++i) {
|
||||
components[i] /= size;
|
||||
}
|
||||
}
|
||||
return QColor(components[0], components[1], components[2]);
|
||||
}
|
||||
|
||||
QColor AdjustedColor(QColor original, QColor background) {
|
||||
return QColor::fromHslF(
|
||||
background.hslHueF(),
|
||||
background.hslSaturationF(),
|
||||
original.lightnessF(),
|
||||
original.alphaF()
|
||||
).toRgb();
|
||||
}
|
||||
|
||||
void ComputeBackgroundRects(QRect wholeFill, QSize imageSize, QRect &to, QRect &from) {
|
||||
if (uint64(imageSize.width()) * wholeFill.height() > uint64(imageSize.height()) * wholeFill.width()) {
|
||||
float64 pxsize = wholeFill.height() / float64(imageSize.height());
|
||||
|
@ -153,6 +153,8 @@ void Revert();
|
||||
|
||||
bool LoadFromFile(const QString &file, Instance *out, QByteArray *outContent);
|
||||
bool IsPaletteTestingPath(const QString &path);
|
||||
QColor CountAverageColor(const QImage &image);
|
||||
QColor AdjustedColor(QColor original, QColor background);
|
||||
|
||||
struct BackgroundUpdate {
|
||||
enum class Type {
|
||||
|
Loading…
Reference in New Issue
Block a user