From f506a5ea6c12d9ebbbe7a6d6d03b415da0ba45b3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 28 Jan 2019 16:59:49 +0300 Subject: [PATCH] Save wallpaper settings locally. --- Telegram/SourceFiles/apiwrap.cpp | 23 +- Telegram/SourceFiles/apiwrap.h | 2 +- Telegram/SourceFiles/boxes/background_box.cpp | 110 ++--- Telegram/SourceFiles/boxes/background_box.h | 1 + Telegram/SourceFiles/data/data_session.cpp | 32 +- Telegram/SourceFiles/data/data_session.h | 2 +- Telegram/SourceFiles/mainwidget.cpp | 61 ++- Telegram/SourceFiles/mainwidget.h | 2 +- .../SourceFiles/settings/settings_chat.cpp | 2 +- Telegram/SourceFiles/storage/localstorage.cpp | 101 ++-- Telegram/SourceFiles/storage/localstorage.h | 2 +- .../window/themes/window_theme.cpp | 442 +++++++++++++++--- .../SourceFiles/window/themes/window_theme.h | 107 +++-- .../window/themes/window_theme_preview.cpp | 3 +- 14 files changed, 624 insertions(+), 266 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 361d5756b0..6ff21a1ed0 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -884,24 +884,13 @@ void ApiWrap::requestWallPaper( )).done([=](const MTPWallPaper &result) { _wallPaperRequestId = 0; _wallPaperSlug = QString(); - result.match([&](const MTPDwallPaper &data) { - const auto document = _session->data().processDocument( - data.vdocument); - if (document->checkWallPaperProperties()) { - if (const auto done = base::take(_wallPaperDone)) { - done({ - data.vid.v, - data.vaccess_hash.v, - data.vflags.v, - qs(data.vslug), - document->thumbnail(), - document - }); - } - } else if (const auto fail = base::take(_wallPaperFail)) { - fail(RPCError::Local("BAD_DOCUMENT", "In a wallpaper.")); + if (const auto paper = Data::WallPaper::Create(result)) { + if (const auto done = base::take(_wallPaperDone)) { + done(*paper); } - }); + } else if (const auto fail = base::take(_wallPaperFail)) { + fail(RPCError::Local("BAD_DOCUMENT", "In a wallpaper.")); + } }).fail([=](const RPCError &error) { _wallPaperRequestId = 0; _wallPaperSlug = QString(); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 31695e9bc9..8b206d2450 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -25,7 +25,7 @@ class mtpFileLoader; namespace Data { struct UpdatedFileReferences; -struct WallPaper; +class WallPaper; } // namespace Data namespace InlineBots { diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index c239cfac96..1874531273 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -95,11 +95,11 @@ QImage PrepareScaledFromFull( size); } -QPixmap PrepareScaledFromThumb(not_null thumb) { +QPixmap PrepareScaledFromThumb(not_null thumb, bool good) { return thumb->loaded() ? App::pixmapFromImageInPlace(PrepareScaledFromFull( thumb->original(), - Images::Option::Blurred)) + good ? Images::Option(0) : Images::Option::Blurred)) : QPixmap(); } @@ -126,6 +126,11 @@ protected: private: void updateWallpapers(); + void paintPaper( + Painter &p, + const Data::WallPaper &paper, + int column, + int row) const; Fn _backgroundChosenCallback; @@ -196,7 +201,7 @@ void BackgroundBox::Inner::updateWallpapers() { const auto preload = kBackgroundsInRow * 3; for (const auto &paper : papers | ranges::view::take(preload)) { - paper.thumb->load(Data::FileOrigin()); + paper.loadThumbnail(); } } @@ -223,24 +228,32 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) { }); if ((st::backgroundSize.height() + st::backgroundPadding) * (row + 1) <= r.top()) { continue; + } else if ((st::backgroundSize.height() + st::backgroundPadding) * row >= r.top() + r.height()) { + break; } + paintPaper(p, paper, column, row); + } +} - paper.thumb->load(Data::FileOrigin()); +void BackgroundBox::Inner::paintPaper( + Painter &p, + const Data::WallPaper &paper, + int column, + int row) const { + Expects(paper.thumbnail() != nullptr); - int x = st::backgroundPadding + column * (st::backgroundSize.width() + st::backgroundPadding); - int y = st::backgroundPadding + row * (st::backgroundSize.height() + st::backgroundPadding); + const auto x = st::backgroundPadding + column * (st::backgroundSize.width() + st::backgroundPadding); + const auto y = st::backgroundPadding + row * (st::backgroundSize.height() + st::backgroundPadding); + const auto &pixmap = paper.thumbnail()->pix( + paper.fileOrigin(), + st::backgroundSize.width(), + st::backgroundSize.height()); + p.drawPixmap(x, y, pixmap); - const auto &pix = paper.thumb->pix( - Data::FileOrigin(), - st::backgroundSize.width(), - st::backgroundSize.height()); - p.drawPixmap(x, y, pix); - - if (paper.id == Window::Theme::Background()->id()) { - auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size; - auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size; - _check->paint(p, getms(), checkLeft, checkTop, width()); - } + if (paper.id() == Window::Theme::Background()->id()) { + const auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size; + const auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size; + _check->paint(p, getms(), checkLeft, checkTop, width()); } } @@ -300,6 +313,8 @@ BackgroundPreviewBox::BackgroundPreviewBox( true)) , _paper(paper) , _radial(animation(this, &BackgroundPreviewBox::step_radial)) { + Expects(_paper.thumbnail() != nullptr); + subscribe(Auth().downloaderTaskFinished(), [=] { update(); }); } @@ -308,27 +323,18 @@ void BackgroundPreviewBox::prepare() { addButton(langFactory(lng_background_apply), [=] { apply(); }); addButton(langFactory(lng_cancel), [=] { closeBox(); }); - if (!_paper.slug.isEmpty()) { + if (_paper.hasShareUrl()) { addLeftButton(langFactory(lng_background_share), [=] { share(); }); } - _scaled = PrepareScaledFromThumb(_paper.thumb); + _paper.loadThumbnail(); + _paper.loadDocument(); + if (_paper.document() && _paper.document()->loading()) { + _radial.start(_paper.document()->progress()); + } + setScaledFromThumb(); checkLoadedDocument(); - if (!_paper.thumb->loaded()) { - _paper.thumb->loadEvenCancelled(Data::FileOriginWallpaper( - _paper.id, - _paper.accessHash)); - } - if (_paper.document) { - _paper.document->save(Data::FileOriginWallpaper( - _paper.id, - _paper.accessHash), QString()); - if (_paper.document->loading()) { - _radial.start(_paper.document->progress()); - } - } - _text1->setDisplayDate(true); _text1->initDimensions(); _text1->resizeGetHeight(st::boxWideWidth); @@ -344,10 +350,7 @@ void BackgroundPreviewBox::apply() { } void BackgroundPreviewBox::share() { - Expects(!_paper.slug.isEmpty()); - - QApplication::clipboard()->setText( - Core::App().createInternalLinkFull("bg/" + _paper.slug)); + QApplication::clipboard()->setText(_paper.shareUrl()); Ui::Toast::Show(lang(lng_background_link_copied)); } @@ -356,15 +359,12 @@ void BackgroundPreviewBox::paintEvent(QPaintEvent *e) { const auto ms = getms(); - if (const auto color = Window::Theme::GetWallPaperColor(_paper.slug)) { + if (const auto color = _paper.backgroundColor()) { p.fillRect(e->rect(), *color); } else { - if (_scaled.isNull()) { - _scaled = PrepareScaledFromThumb(_paper.thumb); - if (_scaled.isNull()) { - p.fillRect(e->rect(), st::boxBg); - return; - } + if (_scaled.isNull() && !setScaledFromThumb()) { + p.fillRect(e->rect(), st::boxBg); + return; } paintImage(p); paintRadial(p, ms); @@ -440,9 +440,9 @@ void BackgroundPreviewBox::paintTexts(Painter &p, TimeMs ms) { } void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) { - Expects(_paper.document != nullptr); + Expects(_paper.document() != nullptr); - const auto document = _paper.document; + const auto document = _paper.document(); const auto wasAnimating = _radial.animating(); const auto updated = _radial.update( document->progress(), @@ -456,8 +456,15 @@ void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) { checkLoadedDocument(); } +bool BackgroundPreviewBox::setScaledFromThumb() { + _scaled = PrepareScaledFromThumb( + _paper.thumbnail(), + !_paper.document()); + return !_scaled.isNull(); +} + void BackgroundPreviewBox::checkLoadedDocument() { - const auto document = _paper.document; + const auto document = _paper.document(); if (!document || !document->loaded(DocumentData::FilePathResolveChecked) || _generating) { @@ -491,13 +498,8 @@ void BackgroundPreviewBox::checkLoadedDocument() { } bool BackgroundPreviewBox::Start(const QString &slug, const QString &mode) { - if (Window::Theme::GetWallPaperColor(slug)) { - Ui::show(Box(Data::WallPaper{ - Window::Theme::kCustomBackground, - 0ULL, // accessHash - MTPDwallPaper::Flags(0), - slug, - })); + if (const auto paper = Data::WallPaper::FromColorSlug(slug)) { + Ui::show(Box(*paper)); return true; } if (!IsValidWallPaperSlug(slug)) { diff --git a/Telegram/SourceFiles/boxes/background_box.h b/Telegram/SourceFiles/boxes/background_box.h index 64c0844edd..401521dd95 100644 --- a/Telegram/SourceFiles/boxes/background_box.h +++ b/Telegram/SourceFiles/boxes/background_box.h @@ -66,6 +66,7 @@ private: QRect radialRect() const; void checkLoadedDocument(); + bool setScaledFromThumb(); void paintImage(Painter &p); void paintRadial(Painter &p, TimeMs ms); void paintTexts(Painter &p, TimeMs ms); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 02d7b17106..a73ca490b4 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3070,41 +3070,23 @@ void Session::setWallpapers(const QVector &data, int32 hash) { qsl(":/gui/art/bg.jpg"), "JPG"); if (defaultBackground) { - _wallpapers.push_back({ - Window::Theme::kDefaultBackground, - 0ULL, // access_hash - MTPDwallPaper::Flags(0), - QString(), // slug - defaultBackground.get() - }); + _wallpapers.push_back(Data::DefaultWallPaper()); + _wallpapers.back().setLocalImageAsThumbnail( + defaultBackground.get()); } const auto oldBackground = Images::Create( qsl(":/gui/art/bg_initial.jpg"), "JPG"); if (oldBackground) { - _wallpapers.push_back({ - Window::Theme::kInitialBackground, - 0ULL, // access_hash - MTPDwallPaper::Flags(0), - QString(), // slug - oldBackground.get() - }); + _wallpapers.push_back(Data::Legacy1DefaultWallPaper()); + _wallpapers.back().setLocalImageAsThumbnail(oldBackground.get()); } for (const auto &paper : data) { paper.match([&](const MTPDwallPaper &paper) { if (paper.is_pattern()) { return; - } - const auto document = processDocument(paper.vdocument); - if (document->checkWallPaperProperties()) { - _wallpapers.push_back({ - paper.vid.v, - paper.vaccess_hash.v, - paper.vflags.v, - qs(paper.vslug), - document->thumbnail(), - document, - }); + } else if (const auto parsed = Data::WallPaper::Create(paper)) { + _wallpapers.push_back(*parsed); } }); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 310578ad1e..a9e23d3dd2 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -51,7 +51,7 @@ class Feed; enum class FeedUpdateFlag; struct FeedUpdate; -struct WallPaper; +class WallPaper; class Session final { public: diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 14124b55e0..d1be15b0d8 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -345,10 +345,17 @@ StackItemSection::StackItemSection( } struct MainWidget::SettingBackground { + explicit SettingBackground(const Data::WallPaper &data); + Data::WallPaper data; base::binary_guard generating; }; +MainWidget::SettingBackground::SettingBackground( + const Data::WallPaper &data) +: data(data) { +} + MainWidget::MainWidget( QWidget *parent, not_null controller) @@ -1554,16 +1561,11 @@ void MainWidget::setChatBackground( return; } - _background = std::make_unique(); - _background->data = background; - _background->data.document->save( - Data::FileOriginWallpaper( - _background->data.id, - _background->data.accessHash), - QString()); + _background = std::make_unique(background); + _background->data.loadDocument(); checkChatBackground(); - const auto tile = (background.id == Window::Theme::kInitialBackground); + const auto tile = Data::IsLegacy1DefaultWallPaper(background); using Update = Window::Theme::BackgroundUpdate; Window::Theme::Background()->notify(Update(Update::Type::Start, tile)); } @@ -1571,9 +1573,7 @@ void MainWidget::setChatBackground( bool MainWidget::isReadyChatBackground( const Data::WallPaper &background, const QImage &image) const { - return !image.isNull() - || !background.document - || Window::Theme::GetWallPaperColor(background.slug); + return !image.isNull() || !background.document(); } void MainWidget::setReadyChatBackground( @@ -1582,22 +1582,22 @@ void MainWidget::setReadyChatBackground( using namespace Window::Theme; if (image.isNull() - && !background.document - && background.thumb - && background.thumb->loaded()) { - image = background.thumb->pixNoCache(Data::FileOrigin()).toImage(); + && !background.document() + && background.thumbnail() + && background.thumbnail()->loaded()) { + image = background.thumbnail()->original(); } const auto resetToDefault = image.isNull() - && !background.document - && !GetWallPaperColor(background.slug) - && (background.id != kInitialBackground); + && !background.document() + && !background.backgroundColor() + && !Data::IsLegacy1DefaultWallPaper(background); const auto ready = resetToDefault - ? Data::WallPaper{ kDefaultBackground } + ? Data::DefaultWallPaper() : background; Background()->setImage(ready, std::move(image)); - const auto tile = (ready.id == kInitialBackground); + const auto tile = Data::IsLegacy1DefaultWallPaper(ready); Background()->setTile(tile); Ui::ForceFullRepaint(this); } @@ -1610,10 +1610,10 @@ float64 MainWidget::chatBackgroundProgress() const { if (_background) { if (_background->generating) { return 1.; - } else if (_background->data.document) { - return _background->data.document->progress(); - } else if (_background->data.thumb) { - return _background->data.thumb->progress(); + } else if (const auto document = _background->data.document()) { + return document->progress(); + } else if (const auto thumbnail = _background->data.thumbnail()) { + return thumbnail->progress(); } } return 1.; @@ -1623,10 +1623,9 @@ void MainWidget::checkChatBackground() { if (!_background || _background->generating) { return; } - const auto document = _background->data.document; - if (document && !document->loaded()) { - return; - } else if (!document && !_background->data.thumb->loaded()) { + const auto document = _background->data.document(); + Assert(document != nullptr); + if (!document->loaded()) { return; } @@ -1634,14 +1633,14 @@ void MainWidget::checkChatBackground() { QImage &&image) { const auto background = base::take(_background); const auto ready = image.isNull() - ? Data::WallPaper{ Window::Theme::kDefaultBackground } + ? Data::DefaultWallPaper() : background->data; - setChatBackground(ready, std::move(image)); + setReadyChatBackground(ready, std::move(image)); }); } Image *MainWidget::newBackgroundThumb() { - return _background ? _background->data.thumb : nullptr; + return _background ? _background->data.thumbnail() : nullptr; } void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 56282a1a62..3b39af1537 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -27,7 +27,7 @@ struct PeerUpdate; } // namespace Notify namespace Data { -struct WallPaper; +class WallPaper; } // namespace Data namespace Dialogs { diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 42b73a0952..e701ecf50d 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -410,7 +410,7 @@ void ChooseFromFile(not_null parent) { } Window::Theme::Background()->setImage( - { Window::Theme::kCustomBackground }, + Data::CustomWallPaper(), std::move(image)); Window::Theme::Background()->setTile(false); }; diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 6dbb8cb415..383478ddde 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -49,6 +49,9 @@ constexpr auto kDefaultStickerInstallDate = TimeId(1); constexpr auto kProxyTypeShift = 1024; constexpr auto kWriteMapTimeout = TimeMs(1000); +constexpr auto kWallPaperLegacySerializeTagId = int32(-111); +constexpr auto kWallPaperSerializeTagId = int32(-112); + constexpr auto kSinglePeerTypeUser = qint32(1); constexpr auto kSinglePeerTypeChat = qint32(2); constexpr auto kSinglePeerTypeChannel = qint32(3); @@ -3982,19 +3985,23 @@ void writeBackground(const Data::WallPaper &paper, const QImage &img) { _mapChanged = true; _writeMap(WriteMapWhen::Fast); } + const auto serialized = paper.serialize(); quint32 size = sizeof(qint32) - + 2 * sizeof(quint64) - + sizeof(quint32) - + Serialize::stringSize(paper.slug) + + Serialize::bytearraySize(serialized) + Serialize::bytearraySize(bmp); EncryptedDescriptor data(size); data.stream - << qint32(Window::Theme::details::kLegacyBackgroundId) - << quint64(paper.id) - << quint64(paper.accessHash) - << quint32(paper.flags.value()) - << paper.slug + << qint32(kWallPaperSerializeTagId) + << serialized << bmp; + //+2 * sizeof(quint64) + // + sizeof(quint32) + // + Serialize::stringSize(paper.slug) + + // << quint64(paper.id) + // << quint64(paper.accessHash) + // << quint32(paper.flags.value()) + // << paper.slug FileWriteDescriptor file(backgroundKey); file.writeEncrypted(data); @@ -4015,61 +4022,67 @@ bool readBackground() { return false; } - QByteArray bmpData; qint32 legacyId = 0; - quint64 id = 0; - quint64 accessHash = 0; - quint32 flags = 0; - QString slug; bg.stream >> legacyId; - if (legacyId == Window::Theme::details::kLegacyBackgroundId) { - bg.stream - >> id - >> accessHash - >> flags - >> slug; - } else { - id = Window::Theme::details::FromLegacyBackgroundId(legacyId); - accessHash = 0; - if (id != Window::Theme::kCustomBackground) { - flags = static_cast(MTPDwallPaper::Flag::f_default); + const auto paper = [&] { + if (legacyId == kWallPaperLegacySerializeTagId) { + quint64 id = 0; + quint64 accessHash = 0; + quint32 flags = 0; + QString slug; + bg.stream + >> id + >> accessHash + >> flags + >> slug; + return Data::WallPaper::FromLegacySerialized( + id, + accessHash, + flags, + slug); + } else if (legacyId == kWallPaperSerializeTagId) { + QByteArray serialized; + bg.stream >> serialized; + return Data::WallPaper::FromSerialized(serialized); + } else { + return Data::WallPaper::FromLegacyId(legacyId); } + }(); + if (bg.stream.status() != QDataStream::Ok || !paper) { + return false; } - bg.stream >> bmpData; - auto oldEmptyImage = (bg.stream.status() != QDataStream::Ok); - if (oldEmptyImage - || id == Window::Theme::kInitialBackground - || id == Window::Theme::kDefaultBackground) { + + QByteArray bmp; + bg.stream >> bmp; + const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok); + if (isOldEmptyImage + || Data::IsLegacy1DefaultWallPaper(*paper) + || Data::IsDefaultWallPaper(*paper)) { _backgroundCanWrite = false; - if (oldEmptyImage || bg.version < 8005) { - Window::Theme::Background()->setImage({ Window::Theme::kDefaultBackground }); + if (isOldEmptyImage || bg.version < 8005) { + Window::Theme::Background()->setImage(Data::DefaultWallPaper()); Window::Theme::Background()->setTile(false); } else { - Window::Theme::Background()->setImage({ id }); + Window::Theme::Background()->setImage(*paper); } _backgroundCanWrite = true; return true; - } else if (id == Window::Theme::kThemeBackground && bmpData.isEmpty()) { + } else if (Data::IsThemeWallPaper(*paper) && bmp.isEmpty()) { _backgroundCanWrite = false; - Window::Theme::Background()->setImage({ id }); + Window::Theme::Background()->setImage(*paper); _backgroundCanWrite = true; return true; } - QImage image; - QBuffer buf(&bmpData); - QImageReader reader(&buf); + auto image = QImage(); + auto buffer = QBuffer(&bmp); + auto reader = QImageReader(&buffer); #ifndef OS_MAC_OLD reader.setAutoTransform(true); #endif // OS_MAC_OLD - if (reader.read(&image) || Window::Theme::GetWallPaperColor(slug)) { + if (reader.read(&image) || paper->backgroundColor()) { _backgroundCanWrite = false; - Window::Theme::Background()->setImage({ - id, - accessHash, - MTPDwallPaper::Flags::from_raw(flags), - slug - }, std::move(image)); + Window::Theme::Background()->setImage(*paper, std::move(image)); _backgroundCanWrite = true; return true; } diff --git a/Telegram/SourceFiles/storage/localstorage.h b/Telegram/SourceFiles/storage/localstorage.h index 183c95d630..6b562eedbb 100644 --- a/Telegram/SourceFiles/storage/localstorage.h +++ b/Telegram/SourceFiles/storage/localstorage.h @@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "auth_session.h" namespace Data { -struct WallPaper; +class WallPaper; } // namespace Data namespace Lang { diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 941c0e3db1..a53fed9deb 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -9,12 +9,333 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/themes/window_theme_preview.h" #include "mainwidget.h" +#include "auth_session.h" +#include "core/application.h" +#include "storage/serialize_common.h" +#include "data/data_document.h" +#include "data/data_session.h" #include "storage/localstorage.h" #include "base/parse_helper.h" #include "base/zlib_help.h" +#include "ui/image/image.h" +#include "boxes/background_box.h" #include "styles/style_widgets.h" #include "styles/style_history.h" -#include "boxes/background_box.h" + +namespace Data { +namespace { + +constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId { + return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId)); +} + +constexpr auto kUninitializedBackground = FromLegacyBackgroundId(-999); +constexpr auto kTestingThemeBackground = FromLegacyBackgroundId(-666); +constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665); +constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664); +constexpr auto kThemeBackground = FromLegacyBackgroundId(-2); +constexpr auto kCustomBackground = FromLegacyBackgroundId(-1); +constexpr auto kLegacy1DefaultBackground = FromLegacyBackgroundId(0); +constexpr auto kDefaultBackground = FromLegacyBackgroundId(105); + +[[nodiscard]] bool ValidateFlags(MTPDwallPaper::Flags flags) { + using Flag = MTPDwallPaper::Flag; + const auto all = Flag(0) + | Flag::f_creator + | Flag::f_default + | Flag::f_pattern + | Flag::f_settings; + return !(flags & ~all); +} + +[[nodiscard]] bool ValidateFlags(MTPDwallPaperSettings::Flags flags) { + using Flag = MTPDwallPaperSettings::Flag; + const auto all = Flag(0) + | Flag::f_background_color + | Flag::f_blur + | Flag::f_intensity + | Flag::f_motion; + return !(flags & ~all); +} + +quint32 SerializeMaybeColor(std::optional color) { + return color + ? ((quint32(std::clamp(color->red(), 0, 255)) << 16) + | (quint32(std::clamp(color->green(), 0, 255)) << 8) + | quint32(std::clamp(color->blue(), 0, 255))) + : quint32(-1); +} + +std::optional MaybeColorFromSerialized(quint32 serialized) { + return (serialized == quint32(-1)) + ? std::nullopt + : std::make_optional(QColor( + int((serialized >> 16) & 0xFFU), + int((serialized >> 8) & 0xFFU), + int(serialized & 0xFFU))); +} + +} // namespace + +WallPaper::WallPaper(WallPaperId id) : _id(id) { +} + +void WallPaper::setLocalImageAsThumbnail(not_null image) { + Expects(IsDefaultWallPaper(*this) + || IsLegacy1DefaultWallPaper(*this) + || IsCustomWallPaper(*this)); + Expects(_thumbnail == nullptr); + + _thumbnail = image; +} + +WallPaperId WallPaper::id() const { + return _id; +} + +std::optional WallPaper::backgroundColor() const { + return _backgroundColor; +} + +DocumentData *WallPaper::document() const { + return _document; +} + +Image *WallPaper::thumbnail() const { + return _thumbnail; +} + +bool WallPaper::hasShareUrl() const { + return !_slug.isEmpty(); +} + +QString WallPaper::shareUrl() const { + return hasShareUrl() + ? Core::App().createInternalLinkFull("bg/" + _slug) + : QString(); +} + +void WallPaper::loadThumbnail() const { + if (_thumbnail) { + _thumbnail->load(fileOrigin()); + } +} + +void WallPaper::loadDocument() const { + if (_document) { + _document->save(fileOrigin(), QString()); + } +} + +FileOrigin WallPaper::fileOrigin() const { + return FileOriginWallpaper(_id, _accessHash); +} + +std::optional WallPaper::Create(const MTPWallPaper &data) { + return data.match([](const MTPDwallPaper &data) { + return Create(data); + }); +} + +std::optional WallPaper::Create(const MTPDwallPaper &data) { + const auto document = Auth().data().processDocument( + data.vdocument); + if (!document->checkWallPaperProperties()) { + return std::nullopt; + } + auto result = WallPaper(data.vid.v); + result._accessHash = data.vaccess_hash.v; + result._flags = data.vflags.v; + result._slug = qs(data.vslug); + result._document = document; + result._thumbnail = document->thumbnail(); + if (data.has_settings()) { + data.vsettings.match([&](const MTPDwallPaperSettings &data) { + result._settings = data.vflags.v; + if (data.has_background_color()) { + result._backgroundColor = MaybeColorFromSerialized( + data.vbackground_color.v); + } + if (data.has_intensity()) { + result._intensity = data.vintensity.v; + } + }); + } + return result; +} + +QByteArray WallPaper::serialize() const { + auto size = sizeof(quint64) // _id + + sizeof(quint64) // _accessHash + + sizeof(qint32) // _flags + + Serialize::stringSize(_slug) + + sizeof(qint32) // _settings + + sizeof(quint32) // _backgroundColor + + sizeof(qint32); // _intensity + + auto result = QByteArray(); + result.reserve(size); + { + auto stream = QDataStream(&result, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_5_1); + stream + << quint64(_id) + << quint64(_accessHash) + << qint32(_flags) + << _slug + << qint32(_settings) + << SerializeMaybeColor(_backgroundColor) + << qint32(_intensity); + } + return result; +} + +std::optional WallPaper::FromSerialized( + const QByteArray &serialized) { + if (serialized.isEmpty()) { + return std::nullopt; + } + + auto id = quint64(); + auto accessHash = quint64(); + auto flags = qint32(); + auto slug = QString(); + auto settings = qint32(); + auto backgroundColor = quint32(); + auto intensity = qint32(); + auto documentId = quint64(); + + auto stream = QDataStream(serialized); + stream.setVersion(QDataStream::Qt_5_1); + stream + >> id + >> accessHash + >> flags + >> slug + >> settings + >> backgroundColor + >> intensity + >> documentId; + if (stream.status() != QDataStream::Ok) { + return std::nullopt; + } else if (intensity < 0 || intensity > 100) { + return std::nullopt; + } + auto result = WallPaper(id); + result._accessHash = accessHash; + result._flags = MTPDwallPaper::Flags::from_raw(flags); + result._slug = slug; + result._settings = MTPDwallPaperSettings::Flags::from_raw(settings); + result._backgroundColor = MaybeColorFromSerialized(backgroundColor); + result._intensity = intensity; + if (!ValidateFlags(result._flags) || !ValidateFlags(result._settings)) { + return std::nullopt; + } + return result; +} + +std::optional WallPaper::FromLegacySerialized( + quint64 id, + quint64 accessHash, + quint32 flags, + QString slug) { + auto result = WallPaper(id); + result._accessHash = accessHash; + result._flags = MTPDwallPaper::Flags::from_raw(flags); + result._slug = slug; + result._backgroundColor = Window::Theme::GetWallPaperColor(slug); + if (!ValidateFlags(result._flags)) { + return std::nullopt; + } + return result; +} + +std::optional WallPaper::FromLegacyId(qint32 legacyId) { + auto result = WallPaper(FromLegacyBackgroundId(legacyId)); + if (!IsCustomWallPaper(result)) { + result._flags = MTPDwallPaper::Flag::f_default; + } + return result; +} + +std::optional WallPaper::FromColorSlug(const QString &slug) { + if (const auto color = Window::Theme::GetWallPaperColor(slug)) { + auto result = CustomWallPaper(); + result._slug = slug; + result._backgroundColor = color; + return result; + } + return std::nullopt; +} + +WallPaper ThemeWallPaper() { + return WallPaper(kThemeBackground); +} + +bool IsThemeWallPaper(const WallPaper &paper) { + return (paper.id() == kThemeBackground); +} + +WallPaper CustomWallPaper() { + return WallPaper(kCustomBackground); +} + +bool IsCustomWallPaper(const WallPaper &paper) { + return (paper.id() == kCustomBackground); +} + +WallPaper Legacy1DefaultWallPaper() { + return WallPaper(kLegacy1DefaultBackground); +} + +bool IsLegacy1DefaultWallPaper(const WallPaper &paper) { + return (paper.id() == kLegacy1DefaultBackground); +} + +WallPaper DefaultWallPaper() { + return WallPaper(kDefaultBackground); +} + +bool IsDefaultWallPaper(const WallPaper &paper) { + return (paper.id() == kDefaultBackground); +} + +namespace details { + +WallPaper UninitializedWallPaper() { + return WallPaper(kUninitializedBackground); +} + +bool IsUninitializedWallPaper(const WallPaper &paper) { + return (paper.id() == kUninitializedBackground); +} + +WallPaper TestingThemeWallPaper() { + return WallPaper(kTestingThemeBackground); +} + +bool IsTestingThemeWallPaper(const WallPaper &paper) { + return (paper.id() == kTestingThemeBackground); +} + +WallPaper TestingDefaultWallPaper() { + return WallPaper(kTestingDefaultBackground); +} + +bool IsTestingDefaultWallPaper(const WallPaper &paper) { + return (paper.id() == kTestingDefaultBackground); +} + +WallPaper TestingEditorWallPaper() { + return WallPaper(kTestingEditorBackground); +} + +bool IsTestingEditorWallPaper(const WallPaper &paper) { + return (paper.id() == kTestingEditorBackground); +} + +} // namespace details +} // namespace Data namespace Window { namespace Theme { @@ -376,9 +697,9 @@ void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) { } void ChatBackground::start() { - if (_paper.id == details::kUninitializedBackground) { + if (Data::details::IsUninitializedWallPaper(_paper)) { if (!Local::readBackground()) { - setImage({ kThemeBackground }); + setImage(Data::ThemeWallPaper()); } } } @@ -386,12 +707,12 @@ void ChatBackground::start() { void ChatBackground::setImage( const Data::WallPaper &paper, QImage &&image) { - const auto needResetAdjustable = (paper.id == kDefaultBackground) - && (id() != kDefaultBackground) + const auto needResetAdjustable = Data::IsDefaultWallPaper(paper) + && !Data::IsDefaultWallPaper(_paper) && !nightMode() && _themeAbsolutePath.isEmpty(); - if (paper.id == kThemeBackground && _themeImage.isNull()) { - setPaper({ kDefaultBackground }); + if (Data::IsThemeWallPaper(paper) && _themeImage.isNull()) { + setPaper(Data::DefaultWallPaper()); } else { setPaper(paper); if (needResetAdjustable) { @@ -402,19 +723,19 @@ void ChatBackground::setImage( restoreAdjustableColors(); } } - if (_paper.id == kThemeBackground) { + if (Data::IsThemeWallPaper(_paper)) { (nightMode() ? _tileNightValue : _tileDayValue) = _themeTile; setPreparedImage(QImage(_themeImage)); - } else if (id() == details::kTestingThemeBackground - || id() == details::kTestingDefaultBackground - || id() == details::kTestingEditorBackground) { - if (id() == details::kTestingDefaultBackground || image.isNull()) { + } else if (Data::details::IsTestingThemeWallPaper(_paper) + || Data::details::IsTestingDefaultWallPaper(_paper) + || Data::details::IsTestingEditorWallPaper(_paper)) { + if (Data::details::IsTestingDefaultWallPaper(_paper) || image.isNull()) { image.load(qsl(":/gui/art/bg.jpg")); - setPaper({ details::kTestingDefaultBackground }); + setPaper(Data::details::TestingDefaultWallPaper()); } setPreparedImage(prepareBackgroundImage(std::move(image))); } else { - if (id() == kInitialBackground) { + if (Data::IsLegacy1DefaultWallPaper(_paper)) { image.load(qsl(":/gui/art/bg_initial.jpg")); const auto scale = cScale() * cIntRetinaFactor(); if (scale != 100) { @@ -422,14 +743,15 @@ void ChatBackground::setImage( ConvertScale(image.width(), scale), Qt::SmoothTransformation); } - } else if (id() == kDefaultBackground + } else if (Data::IsDefaultWallPaper(_paper) || (!color() && image.isNull())) { - setPaper({ kDefaultBackground }); + setPaper(Data::DefaultWallPaper()); image.load(qsl(":/gui/art/bg.jpg")); } Local::writeBackground( _paper, - ((id() == kDefaultBackground || id() == kInitialBackground) + ((Data::IsDefaultWallPaper(_paper) + || Data::IsLegacy1DefaultWallPaper(_paper)) ? QImage() : image)); if (const auto fill = color()) { @@ -490,17 +812,16 @@ void ChatBackground::setPreparedImage(QImage &&image) { void ChatBackground::setPaper(const Data::WallPaper &paper) { _paper = paper; - _paperColor = GetWallPaperColor(_paper.slug); } bool ChatBackground::adjustPaletteRequired() { const auto usingThemeBackground = [&] { - return (id() == kThemeBackground) - || (id() == details::kTestingThemeBackground); + return Data::IsThemeWallPaper(_paper) + || Data::details::IsTestingThemeWallPaper(_paper); }; const auto usingDefaultBackground = [&] { - return (id() == kDefaultBackground) - || (id() == details::kTestingDefaultBackground); + return Data::IsDefaultWallPaper(_paper) + || Data::details::IsTestingDefaultWallPaper(_paper); }; const auto testingPalette = [&] { const auto path = AreTestingTheme() @@ -551,10 +872,6 @@ void ChatBackground::adjustPaletteUsingColor(QColor color) { } } -WallPaperId ChatBackground::id() const { - return _paper.id; -} - QImage ChatBackground::createCurrentImage() const { if (const auto fill = color()) { auto result = QImage( @@ -572,8 +889,8 @@ bool ChatBackground::tile() const { } bool ChatBackground::tileDay() const { - if (id() == details::kTestingThemeBackground || - id() == details::kTestingDefaultBackground) { + if (Data::details::IsTestingThemeWallPaper(_paper) || + Data::details::IsTestingDefaultWallPaper(_paper)) { if (!nightMode()) { return _tileForRevert; } @@ -582,8 +899,8 @@ bool ChatBackground::tileDay() const { } bool ChatBackground::tileNight() const { - if (id() == details::kTestingThemeBackground || - id() == details::kTestingDefaultBackground) { + if (Data::details::IsTestingThemeWallPaper(_paper) || + Data::details::IsTestingDefaultWallPaper(_paper)) { if (nightMode()) { return _tileForRevert; } @@ -608,8 +925,8 @@ void ChatBackground::setTile(bool tile) { setTileDayValue(tile); } if (this->tile() != old) { - if (id() != details::kTestingThemeBackground - && id() != details::kTestingDefaultBackground) { + if (!Data::details::IsTestingThemeWallPaper(_paper) + && !Data::details::IsTestingDefaultWallPaper(_paper)) { Local::writeUserSettings(); } notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile)); @@ -635,19 +952,19 @@ QString ChatBackground::themeAbsolutePath() const { } void ChatBackground::reset() { - if (id() == details::kTestingThemeBackground - || id() == details::kTestingDefaultBackground) { + if (Data::details::IsTestingThemeWallPaper(_paper) + || Data::details::IsTestingDefaultWallPaper(_paper)) { if (_themeImage.isNull()) { - _paperForRevert = { kDefaultBackground }; + _paperForRevert = Data::DefaultWallPaper(); _imageForRevert = QImage(); _tileForRevert = false; } else { - _paperForRevert = { kThemeBackground }; + _paperForRevert = Data::ThemeWallPaper(); _imageForRevert = _themeImage; _tileForRevert = _themeTile; } } else { - setImage({ kThemeBackground }); + setImage(Data::ThemeWallPaper()); restoreAdjustableColors(); notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true); @@ -656,8 +973,8 @@ void ChatBackground::reset() { void ChatBackground::saveForRevert() { ensureStarted(); - if (id() != details::kTestingThemeBackground - && id() != details::kTestingDefaultBackground) { + if (!Data::details::IsTestingThemeWallPaper(_paper) + && !Data::details::IsTestingDefaultWallPaper(_paper)) { _paperForRevert = _paper; _imageForRevert = std::move(_pixmap).toImage(); _tileForRevert = tile(); @@ -682,19 +999,23 @@ void ChatBackground::setTestingTheme(Instance &&theme) { saveAdjustableColors(); auto switchToThemeBackground = !theme.background.isNull() - || (id() == kThemeBackground) - || (id() == kDefaultBackground + || Data::IsThemeWallPaper(_paper) + || (Data::IsDefaultWallPaper(_paper) && !nightMode() && _themeAbsolutePath.isEmpty()); if (AreTestingTheme() && IsPaletteTestingPath(GlobalApplying.pathAbsolute)) { // Grab current background image if it is not already custom - if (id() != kCustomBackground) { + if (!Data::IsCustomWallPaper(_paper)) { saveForRevert(); - setImage({ details::kTestingEditorBackground }, std::move(_pixmap).toImage()); + setImage( + Data::details::TestingEditorWallPaper(), + std::move(_pixmap).toImage()); } } else if (switchToThemeBackground) { saveForRevert(); - setImage({ details::kTestingThemeBackground }, std::move(theme.background)); + setImage( + Data::details::TestingThemeWallPaper(), + std::move(theme.background)); setTile(theme.tiled); } else { // Apply current background image so that service bg colors are recounted. @@ -708,29 +1029,29 @@ void ChatBackground::setTestingDefaultTheme() { saveAdjustableColors(); saveForRevert(); - setImage({ details::kTestingDefaultBackground }); + setImage(Data::details::TestingDefaultWallPaper()); setTile(false); notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true); } void ChatBackground::keepApplied(const QString &path, bool write) { setThemeAbsolutePath(path); - if (id() == details::kTestingEditorBackground) { - setPaper({ kCustomBackground }); + if (Data::details::IsTestingEditorWallPaper(_paper)) { + setPaper(Data::CustomWallPaper()); _themeImage = QImage(); _themeTile = false; if (write) { writeNewBackgroundSettings(); } - } else if (id() == details::kTestingThemeBackground) { - setPaper({ kThemeBackground }); + } else if (Data::details::IsTestingThemeWallPaper(_paper)) { + setPaper(Data::ThemeWallPaper()); _themeImage = prepareBackgroundImage(_pixmap.toImage()); _themeTile = tile(); if (write) { writeNewBackgroundSettings(); } - } else if (id() == details::kTestingDefaultBackground) { - setPaper({ kDefaultBackground }); + } else if (Data::details::IsTestingDefaultWallPaper(_paper)) { + setPaper(Data::DefaultWallPaper()); _themeImage = QImage(); _themeTile = false; if (write) { @@ -744,16 +1065,16 @@ bool ChatBackground::isNonDefaultThemeOrBackground() { start(); return nightMode() ? (_themeAbsolutePath != NightThemePath() - || id() != kThemeBackground) + || !Data::IsThemeWallPaper(_paper)) : (!_themeAbsolutePath.isEmpty() - || id() != kDefaultBackground); + || !Data::IsDefaultWallPaper(_paper)); } bool ChatBackground::isNonDefaultBackground() { start(); return _themeAbsolutePath.isEmpty() - ? (id() != kDefaultBackground) - : (id() != kThemeBackground); + ? !Data::IsDefaultWallPaper(_paper) + : !Data::IsThemeWallPaper(_paper); } void ChatBackground::writeNewBackgroundSettings() { @@ -762,15 +1083,16 @@ void ChatBackground::writeNewBackgroundSettings() { } Local::writeBackground( _paper, - ((id() == kThemeBackground || id() == kDefaultBackground) + ((Data::IsThemeWallPaper(_paper) + || Data::IsDefaultWallPaper(_paper)) ? QImage() : _pixmap.toImage())); } void ChatBackground::revert() { - if (id() == details::kTestingThemeBackground - || id() == details::kTestingDefaultBackground - || id() == details::kTestingEditorBackground) { + if (Data::details::IsTestingThemeWallPaper(_paper) + || Data::details::IsTestingDefaultWallPaper(_paper) + || Data::details::IsTestingEditorWallPaper(_paper)) { setTile(_tileForRevert); setImage(_paperForRevert, std::move(_imageForRevert)); } else { @@ -843,7 +1165,7 @@ void ChatBackground::toggleNightMode(std::optional themePath) { } Local::writeSettings(); if (!settingDefault && !Local::readBackground()) { - setImage({ kThemeBackground }); + setImage(Data::ThemeWallPaper()); } }; } diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index bff5055e9b..a8cd498dfc 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -11,37 +11,83 @@ class Image; namespace Data { -struct WallPaper { - WallPaperId id = WallPaperId(); - uint64 accessHash = 0; - MTPDwallPaper::Flags flags; - QString slug; - Image *thumb = nullptr; - DocumentData *document = nullptr; +struct FileOrigin; + +class WallPaper { +public: + explicit WallPaper(WallPaperId id); + + void setLocalImageAsThumbnail(not_null image); + + [[nodiscard]] WallPaperId id() const; + [[nodiscard]] std::optional backgroundColor() const; + [[nodiscard]] DocumentData *document() const; + [[nodiscard]] Image *thumbnail() const; + [[nodiscard]] bool hasShareUrl() const; + [[nodiscard]] QString shareUrl() const; + + void loadDocument() const; + void loadThumbnail() const; + [[nodiscard]] FileOrigin fileOrigin() const; + + [[nodiscard]] static std::optional Create( + const MTPWallPaper &data); + [[nodiscard]] static std::optional Create( + const MTPDwallPaper &data); + + [[nodiscard]] QByteArray serialize() const; + [[nodiscard]] static std::optional FromSerialized( + const QByteArray &serialized); + [[nodiscard]] static std::optional FromLegacySerialized( + quint64 id, + quint64 accessHash, + quint32 flags, + QString slug); + [[nodiscard]] static std::optional FromLegacyId( + qint32 legacyId); + [[nodiscard]] static std::optional FromColorSlug( + const QString &slug); + +private: + WallPaperId _id = WallPaperId(); + uint64 _accessHash = 0; + MTPDwallPaper::Flags _flags; + QString _slug; + + MTPDwallPaperSettings::Flags _settings; + std::optional _backgroundColor; + int _intensity = 40; + + DocumentData *_document = nullptr; + Image *_thumbnail = nullptr; + }; +[[nodiscard]] WallPaper ThemeWallPaper(); +[[nodiscard]] bool IsThemeWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper CustomWallPaper(); +[[nodiscard]] bool IsCustomWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper Legacy1DefaultWallPaper(); +[[nodiscard]] bool IsLegacy1DefaultWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper DefaultWallPaper(); +[[nodiscard]] bool IsDefaultWallPaper(const WallPaper &paper); + +namespace details { + +[[nodiscard]] WallPaper UninitializedWallPaper(); +[[nodiscard]] bool IsUninitializedWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper TestingThemeWallPaper(); +[[nodiscard]] bool IsTestingThemeWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper TestingDefaultWallPaper(); +[[nodiscard]] bool IsTestingDefaultWallPaper(const WallPaper &paper); +[[nodiscard]] WallPaper TestingEditorWallPaper(); +[[nodiscard]] bool IsTestingEditorWallPaper(const WallPaper &paper); + +} // namespace details } // namespace Data namespace Window { namespace Theme { -namespace details { - -constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId { - return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId)); -} - -constexpr auto kUninitializedBackground = FromLegacyBackgroundId(-999); -constexpr auto kTestingThemeBackground = FromLegacyBackgroundId(-666); -constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665); -constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664); -constexpr auto kLegacyBackgroundId = int32(-111); - -} // namespace details - -constexpr auto kThemeBackground = details::FromLegacyBackgroundId(-2); -constexpr auto kCustomBackground = details::FromLegacyBackgroundId(-1); -constexpr auto kInitialBackground = details::FromLegacyBackgroundId(0); -constexpr auto kDefaultBackground = details::FromLegacyBackgroundId(105); constexpr auto kMinimumTiledSize = 512; @@ -135,7 +181,9 @@ public: void setTestingDefaultTheme(); void revert(); - [[nodiscard]] WallPaperId id() const; + [[nodiscard]] WallPaperId id() const { + return _paper.id(); + } [[nodiscard]] const QPixmap &pixmap() const { return _pixmap; } @@ -143,7 +191,7 @@ public: return _pixmapForTiled; } [[nodiscard]] std::optional color() const { - return _paperColor; + return _paper.backgroundColor(); } [[nodiscard]] QImage createCurrentImage() const; [[nodiscard]] bool tile() const; @@ -183,7 +231,7 @@ private: friend void KeepApplied(); friend bool IsNonDefaultBackground(); - Data::WallPaper _paper = { details::kUninitializedBackground }; + Data::WallPaper _paper = Data::details::UninitializedWallPaper(); std::optional _paperColor; QPixmap _pixmap; QPixmap _pixmapForTiled; @@ -195,7 +243,8 @@ private: QImage _themeImage; bool _themeTile = false; - Data::WallPaper _paperForRevert = { details::kUninitializedBackground }; + Data::WallPaper _paperForRevert + = Data::details::UninitializedWallPaper(); QImage _imageForRevert; bool _tileForRevert = false; diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index 2091becd8d..0803e830db 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -395,7 +395,8 @@ void Generator::paintHistoryBackground() { auto background = _theme.background; auto tiled = _theme.tiled; if (background.isNull()) { - if (_current.backgroundId == Window::Theme::kThemeBackground) { + const auto fakePaper = Data::WallPaper(_current.backgroundId); + if (Data::IsThemeWallPaper(fakePaper)) { background.load(qsl(":/gui/art/bg.jpg")); tiled = false; } else {