From d3a01b6235160285319ebf83fa323d975ae801d8 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 29 May 2024 03:50:40 +0300 Subject: [PATCH] Improved style of list of credits history entries for entry photo. --- Telegram/CMakeLists.txt | 2 + .../info_statistics_list_controllers.cpp | 20 ++++++- .../settings/settings_credits_graphics.cpp | 36 ++---------- .../ui/effects/credits_graphics.cpp | 55 +++++++++++++++++++ .../SourceFiles/ui/effects/credits_graphics.h | 6 ++ Telegram/cmake/td_ui.cmake | 2 - 6 files changed, 85 insertions(+), 36 deletions(-) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index d1171a5ef..6e786a6cd 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1467,6 +1467,8 @@ PRIVATE ui/controls/silent_toggle.h ui/controls/userpic_button.cpp ui/controls/userpic_button.h + ui/effects/credits_graphics.cpp + ui/effects/credits_graphics.h ui/effects/emoji_fly_animation.cpp ui/effects/emoji_fly_animation.h ui/effects/message_sending_animation_common.h diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index 0028e0fab..51dcc203b 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -713,6 +713,7 @@ public: Data::CreditsHistoryEntry entry; not_null<QImage*> creditIcon; int rowHeight = 0; + Fn<void(not_null<PeerListRow*>)> updateCallback; }; CreditsRow(not_null<PeerData*> peer, const Descriptor &descriptor); @@ -752,6 +753,14 @@ CreditsRow::CreditsRow(not_null<PeerData*> peer, const Descriptor &descriptor) , _entry(descriptor.entry) , _creditIcon(descriptor.creditIcon) , _rowHeight(descriptor.rowHeight) { + const auto photo = _entry.photoId + ? peer->session().data().photo(_entry.photoId).get() + : nullptr; + if (photo) { + _paintUserpicCallback = Ui::GenerateCreditsPaintEntryCallback( + photo, + [this, update = descriptor.updateCallback] { update(this); }); + } init(); } @@ -772,9 +781,11 @@ void CreditsRow::init() { (!_entry.bareId ? QChar('+') : kMinus) + Lang::FormatCountDecimal(std::abs(int64(_entry.credits)))); } - _paintUserpicCallback = !PeerListRow::special() - ? PeerListRow::generatePaintUserpicCallback(false) - : Ui::GenerateCreditsPaintUserpicCallback(_entry); + if (!_paintUserpicCallback) { + _paintUserpicCallback = !PeerListRow::special() + ? PeerListRow::generatePaintUserpicCallback(false) + : Ui::GenerateCreditsPaintUserpicCallback(_entry); + } } const Data::CreditsHistoryEntry &CreditsRow::entry() const { @@ -912,6 +923,9 @@ void CreditsController::applySlice(const Data::CreditsStatusSlice &slice) { .entry = item, .creditIcon = _creditIcon, .rowHeight = computeListSt().item.height, + .updateCallback = [=](not_null<PeerListRow*> row) { + delegate()->peerListUpdateRow(row); + }, }; using Type = Data::CreditsHistoryEntry::PeerType; if (item.bareId) { diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 16c15e44e..b855121a4 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -568,44 +568,18 @@ object_ptr<Ui::RpWidget> HistoryEntryPhoto( not_null<Ui::RpWidget*> parent, not_null<PhotoData*> photo, int photoSize) { - struct State { - std::shared_ptr<Data::PhotoMedia> view; - Image *image = nullptr; - rpl::lifetime downloadLifetime; - }; - const auto state = parent->lifetime().make_state<State>(); auto owned = object_ptr<Ui::RpWidget>(parent); const auto widget = owned.data(); - state->view = photo->createMediaView(); - photo->load(Data::PhotoSize::Thumbnail, {}); - widget->resize(Size(photoSize)); - rpl::single(rpl::empty_value()) | rpl::then( - photo->owner().session().downloaderTaskFinished() - ) | rpl::start_with_next([=] { - using Size = Data::PhotoSize; - if (const auto large = state->view->image(Size::Large)) { - state->image = large; - } else if (const auto small = state->view->image(Size::Small)) { - state->image = small; - } else if (const auto t = state->view->image(Size::Thumbnail)) { - state->image = t; - } - widget->update(); - if (state->view->loaded()) { - state->downloadLifetime.destroy(); - } - }, state->downloadLifetime); + const auto draw = Ui::GenerateCreditsPaintEntryCallback( + photo, + [=] { widget->update(); }); widget->paintRequest( ) | rpl::start_with_next([=] { - auto p = QPainter(widget); - if (state->image) { - p.drawPixmap(0, 0, state->image->pix(widget->width(), { - .options = Images::Option::RoundCircle, - })); - } + auto p = Painter(widget); + draw(p, 0, 0, photoSize, photoSize); }, widget->lifetime()); return owned; diff --git a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp index 44e82195a..3c7a714f7 100644 --- a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp +++ b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp @@ -10,7 +10,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include <QtCore/QDateTime> #include "data/data_credits.h" +#include "data/data_file_origin.h" +#include "data/data_photo.h" +#include "data/data_photo_media.h" +#include "data/data_session.h" #include "lang/lang_keys.h" +#include "main/main_session.h" #include "ui/empty_userpic.h" #include "ui/painter.h" #include "styles/style_credits.h" @@ -67,6 +72,56 @@ PaintRoundImageCallback GenerateCreditsPaintUserpicCallback( }; } +Fn<void(Painter &, int, int, int, int)> GenerateCreditsPaintEntryCallback( + not_null<PhotoData*> photo, + Fn<void()> update) { + struct State { + std::shared_ptr<Data::PhotoMedia> view; + Image *imagePtr = nullptr; + QImage image; + rpl::lifetime downloadLifetime; + bool entryImageLoaded = false; + }; + const auto state = std::make_shared<State>(); + state->view = photo->createMediaView(); + photo->load(Data::PhotoSize::Thumbnail, {}); + + rpl::single(rpl::empty_value()) | rpl::then( + photo->owner().session().downloaderTaskFinished() + ) | rpl::start_with_next([=] { + using Size = Data::PhotoSize; + if (const auto large = state->view->image(Size::Large)) { + state->imagePtr = large; + } else if (const auto small = state->view->image(Size::Small)) { + state->imagePtr = small; + } else if (const auto t = state->view->image(Size::Thumbnail)) { + state->imagePtr = t; + } + update(); + if (state->view->loaded()) { + state->entryImageLoaded = true; + state->downloadLifetime.destroy(); + } + }, state->downloadLifetime); + + return [=](Painter &p, int x, int y, int outerWidth, int size) { + if (state->imagePtr + && (!state->entryImageLoaded || state->image.isNull())) { + const auto image = state->imagePtr->original(); + const auto minSize = std::min(image.width(), image.height()); + state->image = Images::Prepare( + image.copy( + (image.width() - minSize) / 2, + (image.height() - minSize) / 2, + minSize, + minSize), + size * style::DevicePixelRatio(), + { .options = Images::Option::RoundCircle }); + } + p.drawImage(x, y, state->image); + }; +} + TextWithEntities GenerateEntryName(const Data::CreditsHistoryEntry &entry) { return ((entry.peerType == Data::CreditsHistoryEntry::PeerType::Fragment) ? tr::lng_bot_username_description1_link diff --git a/Telegram/SourceFiles/ui/effects/credits_graphics.h b/Telegram/SourceFiles/ui/effects/credits_graphics.h index 44d848748..ddfbea07c 100644 --- a/Telegram/SourceFiles/ui/effects/credits_graphics.h +++ b/Telegram/SourceFiles/ui/effects/credits_graphics.h @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +class PhotoData; + namespace Data { struct CreditsHistoryEntry; } // namespace Data @@ -16,6 +18,10 @@ namespace Ui { Fn<void(Painter &, int, int, int, int)> GenerateCreditsPaintUserpicCallback( const Data::CreditsHistoryEntry &entry); +Fn<void(Painter &, int, int, int, int)> GenerateCreditsPaintEntryCallback( + not_null<PhotoData*> photo, + Fn<void()> update); + [[nodiscard]] TextWithEntities GenerateEntryName( const Data::CreditsHistoryEntry &entry); diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index 3c0c026a3..29a2c10b0 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -358,8 +358,6 @@ PRIVATE ui/effects/fireworks_animation.h ui/effects/glare.cpp ui/effects/glare.h - ui/effects/credits_graphics.cpp - ui/effects/credits_graphics.h ui/effects/loading_element.cpp ui/effects/loading_element.h ui/effects/outline_segments.cpp