diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index 6b5971b555..c8e9af0fce 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -167,9 +167,8 @@ class BackgroundBox::Inner public: Inner(QWidget *parent); - void setBackgroundChosenCallback(Fn callback) { - _backgroundChosenCallback = std::move(callback); - } + void setBackgroundChosenCallback( + Fn callback); ~Inner(); @@ -180,14 +179,16 @@ protected: void mouseReleaseEvent(QMouseEvent *e) override; private: - void updateWallpapers(); + void updatePapers(); + void sortPapers(); void paintPaper( Painter &p, const Data::WallPaper &paper, int column, int row) const; - Fn _backgroundChosenCallback; + Fn _backgroundChosenCallback; + std::vector _papers; int _over = -1; int _overDown = -1; @@ -207,18 +208,11 @@ void BackgroundBox::prepare() { setDimensions(st::boxWideWidth, st::boxMaxListHeight); _inner = setInnerWidget(object_ptr(this), st::backgroundScroll); - _inner->setBackgroundChosenCallback([=](int index) { - backgroundChosen(index); - }); -} - -void BackgroundBox::backgroundChosen(int index) { - const auto &papers = Auth().data().wallpapers(); - if (index >= 0 && index < papers.size()) { + _inner->setBackgroundChosenCallback([](const Data::WallPaper &paper) { Ui::show( - Box(papers[index]), + Box(paper), LayerOption::KeepOther); - } + }); } BackgroundBox::Inner::Inner(QWidget *parent) : RpWidget(parent) @@ -227,35 +221,58 @@ BackgroundBox::Inner::Inner(QWidget *parent) : RpWidget(parent) if (Auth().data().wallpapers().empty()) { resize(kBackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); } else { - updateWallpapers(); + updatePapers(); } request(MTPaccount_GetWallPapers( MTP_int(Auth().data().wallpapersHash()) )).done([=](const MTPaccount_WallPapers &result) { if (Auth().data().updateWallpapers(result)) { - updateWallpapers(); + updatePapers(); } }).send(); subscribe(Auth().downloaderTaskFinished(), [=] { update(); }); - subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &update) { + using Update = Window::Theme::BackgroundUpdate; + subscribe(Window::Theme::Background(), [=](const Update &update) { if (update.paletteChanged()) { _check->invalidateCache(); + } else if (update.type == Update::Type::New) { + sortPapers(); + this->update(); } }); setMouseTracking(true); } -void BackgroundBox::Inner::updateWallpapers() { - const auto &papers = Auth().data().wallpapers(); - const auto count = papers.size(); +void BackgroundBox::Inner::setBackgroundChosenCallback( + Fn callback) { + _backgroundChosenCallback = std::move(callback); +} + +void BackgroundBox::Inner::sortPapers() { + using Paper = Data::WallPaper; + const auto current = Window::Theme::Background()->id(); + const auto night = Window::Theme::IsNightMode(); + ranges::stable_sort(_papers, std::greater<>(), [&](const Paper &paper) { + return std::make_tuple( + paper.id() == current, + night ? paper.isDark() : !paper.isDark(), + !paper.isDefault() && !paper.isLocal(), + !paper.isDefault() && paper.isLocal()); + }); +} + +void BackgroundBox::Inner::updatePapers() { + _papers = Auth().data().wallpapers(); + sortPapers(); + const auto count = _papers.size(); const auto rows = (count / kBackgroundsInRow) + (count % kBackgroundsInRow ? 1 : 0); resize(kBackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, rows * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); const auto preload = kBackgroundsInRow * 3; - for (const auto &paper : papers | ranges::view::take(preload)) { + for (const auto &paper : _papers | ranges::view::take(preload)) { paper.loadThumbnail(); } } @@ -264,8 +281,7 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) { QRect r(e->rect()); Painter p(this); - const auto &papers = Auth().data().wallpapers(); - if (papers.empty()) { + if (_papers.empty()) { p.setFont(st::noContactsFont); p.setPen(st::noContactsColor); p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center); @@ -273,7 +289,7 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) { } auto row = 0; auto column = 0; - for (const auto &paper : papers) { + for (const auto &paper : _papers) { const auto increment = gsl::finally([&] { ++column; if (column == kBackgroundsInRow) { @@ -327,7 +343,7 @@ void BackgroundBox::Inner::mouseMoveEvent(QMouseEvent *e) { return -1; } const auto result = row * kBackgroundsInRow + column; - return (result < Auth().data().wallpapers().size()) ? result : -1; + return (result < _papers.size()) ? result : -1; }(); if (_over != newOver) { _over = newOver; @@ -342,9 +358,9 @@ void BackgroundBox::Inner::mousePressEvent(QMouseEvent *e) { } void BackgroundBox::Inner::mouseReleaseEvent(QMouseEvent *e) { - if (_overDown == _over && _over >= 0) { + if (_overDown == _over && _over >= 0 && _over < _papers.size()) { if (_backgroundChosenCallback) { - _backgroundChosenCallback(_over); + _backgroundChosenCallback(_papers[_over]); } } else if (_over < 0) { setCursor(style::cur_default); diff --git a/Telegram/SourceFiles/boxes/background_box.h b/Telegram/SourceFiles/boxes/background_box.h index 46ecb45b64..50052d1ec8 100644 --- a/Telegram/SourceFiles/boxes/background_box.h +++ b/Telegram/SourceFiles/boxes/background_box.h @@ -26,8 +26,6 @@ protected: void prepare() override; private: - void backgroundChosen(int index); - class Inner; QPointer _inner; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index a73ca490b4..939372bd59 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3064,23 +3064,13 @@ void Session::setWallpapers(const QVector &data, int32 hash) { _wallpapersHash = hash; _wallpapers.clear(); - _wallpapers.reserve(data.size() + 1); + _wallpapers.reserve(data.size() + 2); - const auto defaultBackground = Images::Create( - qsl(":/gui/art/bg.jpg"), - "JPG"); - if (defaultBackground) { - _wallpapers.push_back(Data::DefaultWallPaper()); - _wallpapers.back().setLocalImageAsThumbnail( - defaultBackground.get()); - } - const auto oldBackground = Images::Create( + _wallpapers.push_back(Data::Legacy1DefaultWallPaper()); + _wallpapers.back().setLocalImageAsThumbnail(Images::Create( qsl(":/gui/art/bg_initial.jpg"), - "JPG"); - if (oldBackground) { - _wallpapers.push_back(Data::Legacy1DefaultWallPaper()); - _wallpapers.back().setLocalImageAsThumbnail(oldBackground.get()); - } + "JPG" + ).get()); for (const auto &paper : data) { paper.match([&](const MTPDwallPaper &paper) { if (paper.is_pattern()) { @@ -3090,6 +3080,16 @@ void Session::setWallpapers(const QVector &data, int32 hash) { } }); } + const auto defaultFound = ranges::find_if( + _wallpapers, + Data::IsDefaultWallPaper); + if (defaultFound == end(_wallpapers)) { + _wallpapers.push_back(Data::DefaultWallPaper()); + _wallpapers.back().setLocalImageAsThumbnail(Images::Create( + qsl(":/gui/arg/bg.jpg"), + "JPG" + ).get()); + } } const std::vector &Session::wallpapers() const { diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 6f76102170..aaa232fd92 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -36,7 +36,8 @@ 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); +constexpr auto kDefaultBackground = 5947530738516623361; +constexpr auto kIncorrectDefaultBackground = FromLegacyBackgroundId(105); quint32 SerializeMaybeColor(std::optional color) { return color @@ -141,6 +142,14 @@ bool WallPaper::isCreator() const { return _flags & MTPDwallPaper::Flag::f_creator; } +bool WallPaper::isDark() const { + return _flags & MTPDwallPaper::Flag::f_dark; +} + +bool WallPaper::isLocal() const { + return !document() && thumbnail(); +} + int WallPaper::patternIntensity() const { return _intensity; } @@ -394,7 +403,8 @@ WallPaper DefaultWallPaper() { } bool IsDefaultWallPaper(const WallPaper &paper) { - return (paper.id() == kDefaultBackground); + return (paper.id() == kDefaultBackground) + || (paper.id() == kIncorrectDefaultBackground); } QColor PatternColor(QColor background) { diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index 6e965f7458..d8e3e55e15 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -26,6 +26,8 @@ public: [[nodiscard]] bool isPattern() const; [[nodiscard]] bool isDefault() const; [[nodiscard]] bool isCreator() const; + [[nodiscard]] bool isDark() const; + [[nodiscard]] bool isLocal() const; [[nodiscard]] int patternIntensity() const; [[nodiscard]] bool hasShareUrl() const; [[nodiscard]] QString shareUrl() const;