Display date in background preview.

This commit is contained in:
John Preston 2019-01-29 20:03:51 +03:00
parent 5ca12a73c3
commit 58cf0fa2b1
5 changed files with 121 additions and 36 deletions

View File

@ -154,7 +154,8 @@ QImage PrepareScaledFromFull(
std::move(result), std::move(result),
Data::PatternColor(*patternBackground)); Data::PatternColor(*patternBackground));
} }
return result; return std::move(result).convertToFormat(
QImage::Format_ARGB32_Premultiplied);
} }
} // namespace } // namespace
@ -380,6 +381,7 @@ void BackgroundPreviewBox::prepare() {
if (_paper.hasShareUrl()) { if (_paper.hasShareUrl()) {
addLeftButton(langFactory(lng_background_share), [=] { share(); }); addLeftButton(langFactory(lng_background_share), [=] { share(); });
} }
updateServiceBg(_paper.backgroundColor());
_paper.loadThumbnail(); _paper.loadThumbnail();
_paper.loadDocument(); _paper.loadDocument();
@ -493,12 +495,33 @@ void BackgroundPreviewBox::paintTexts(Painter &p, TimeMs ms) {
- height2 - height2
- st::historyPaddingBottom; - st::historyPaddingBottom;
p.translate(0, top); p.translate(0, top);
paintDate(p);
_text1->draw(p, rect(), TextSelection(), ms); _text1->draw(p, rect(), TextSelection(), ms);
p.translate(0, height1); p.translate(0, height1);
_text2->draw(p, rect(), TextSelection(), ms); _text2->draw(p, rect(), TextSelection(), ms);
p.translate(0, height2); 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) { void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) {
Expects(_paper.document() != nullptr); Expects(_paper.document() != nullptr);
@ -531,9 +554,18 @@ bool BackgroundPreviewBox::setScaledFromThumb() {
} }
void BackgroundPreviewBox::setScaledFromImage(QImage &&image) { void BackgroundPreviewBox::setScaledFromImage(QImage &&image) {
updateServiceBg(Window::Theme::CountAverageColor(image));
_scaled = App::pixmapFromImageInPlace(std::move(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 { std::optional<QColor> BackgroundPreviewBox::patternBackgroundColor() const {
return _paper.isPattern() ? _paper.backgroundColor() : std::nullopt; return _paper.isPattern() ? _paper.backgroundColor() : std::nullopt;
} }

View File

@ -70,10 +70,12 @@ private:
void checkLoadedDocument(); void checkLoadedDocument();
bool setScaledFromThumb(); bool setScaledFromThumb();
void setScaledFromImage(QImage &&image); void setScaledFromImage(QImage &&image);
void updateServiceBg(std::optional<QColor> background);
std::optional<QColor> patternBackgroundColor() const; std::optional<QColor> patternBackgroundColor() const;
void paintImage(Painter &p); void paintImage(Painter &p);
void paintRadial(Painter &p, TimeMs ms); void paintRadial(Painter &p, TimeMs ms);
void paintTexts(Painter &p, TimeMs ms); void paintTexts(Painter &p, TimeMs ms);
void paintDate(Painter &p);
AdminLog::OwnedItem _text1; AdminLog::OwnedItem _text1;
AdminLog::OwnedItem _text2; AdminLog::OwnedItem _text2;
@ -82,5 +84,6 @@ private:
QPixmap _scaled; QPixmap _scaled;
Ui::RadialAnimation _radial; Ui::RadialAnimation _radial;
base::binary_guard _generating; base::binary_guard _generating;
std::optional<QColor> _serviceBg;
}; };

View File

@ -6361,7 +6361,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (drawWebPagePreview) { if (drawWebPagePreview) {
auto previewLeft = st::historyReplySkip + st::webPageLeft; auto previewLeft = st::historyReplySkip + st::webPageLeft;
p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor); 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 const auto preview = _previewData->photo
? _previewData->photo->getReplyPreview(Data::FileOrigin()) ? _previewData->photo->getReplyPreview(Data::FileOrigin())
: _previewData->document->getReplyPreview(Data::FileOrigin()); : _previewData->document->getReplyPreview(Data::FileOrigin());

View File

@ -104,6 +104,21 @@ std::optional<QColor> ColorFromString(const QString &string) {
255); 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 } // namespace
WallPaper::WallPaper(WallPaperId id) : _id(id) { WallPaper::WallPaper(WallPaperId id) : _id(id) {
@ -155,9 +170,32 @@ bool WallPaper::hasShareUrl() const {
} }
QString WallPaper::shareUrl() const { QString WallPaper::shareUrl() const {
return hasShareUrl() if (!hasShareUrl()) {
? Core::App().createInternalLinkFull("bg/" + _slug) return QString();
: 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 { void WallPaper::loadThumbnail() const {
@ -815,12 +853,6 @@ QImage validateBackgroundImage(QImage image) {
return 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() { void WriteAppliedTheme() {
auto saved = Saved(); auto saved = Saved();
saved.pathRelative = GlobalApplying.pathRelative; saved.pathRelative = GlobalApplying.pathRelative;
@ -1029,34 +1061,18 @@ bool ChatBackground::adjustPaletteRequired() {
} }
void ChatBackground::adjustPaletteUsingBackground(const QImage &image) { void ChatBackground::adjustPaletteUsingBackground(const QImage &image) {
uint64 components[3] = { 0 }; adjustPaletteUsingColor(CountAverageColor(image));
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]));
} }
void ChatBackground::adjustPaletteUsingColor(QColor color) { void ChatBackground::adjustPaletteUsingColor(QColor color) {
const auto hue = color.hslHueF(); const auto prepared = color.toHsl();
const auto saturation = color.hslSaturationF(); for (const auto &adjustable : _adjustableColors) {
for (const auto &color : _adjustableColors) { const auto adjusted = AdjustedColor(adjustable.item->c, prepared);
adjustColor(color.item, hue, saturation); adjustable.item.set(
adjusted.red(),
adjusted.green(),
adjusted.blue(),
adjusted.alpha());
} }
} }
@ -1530,6 +1546,38 @@ bool IsPaletteTestingPath(const QString &path) {
return false; 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) { void ComputeBackgroundRects(QRect wholeFill, QSize imageSize, QRect &to, QRect &from) {
if (uint64(imageSize.width()) * wholeFill.height() > uint64(imageSize.height()) * wholeFill.width()) { if (uint64(imageSize.width()) * wholeFill.height() > uint64(imageSize.height()) * wholeFill.width()) {
float64 pxsize = wholeFill.height() / float64(imageSize.height()); float64 pxsize = wholeFill.height() / float64(imageSize.height());

View File

@ -153,6 +153,8 @@ void Revert();
bool LoadFromFile(const QString &file, Instance *out, QByteArray *outContent); bool LoadFromFile(const QString &file, Instance *out, QByteArray *outContent);
bool IsPaletteTestingPath(const QString &path); bool IsPaletteTestingPath(const QString &path);
QColor CountAverageColor(const QImage &image);
QColor AdjustedColor(QColor original, QColor background);
struct BackgroundUpdate { struct BackgroundUpdate {
enum class Type { enum class Type {