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),
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;
}

View File

@ -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;
};

View File

@ -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());

View File

@ -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());

View File

@ -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 {