diff --git a/Telegram/SourceFiles/boxes/choose_filter_box.cpp b/Telegram/SourceFiles/boxes/choose_filter_box.cpp index 60d4c537d..43a4d2ea4 100644 --- a/Telegram/SourceFiles/boxes/choose_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/choose_filter_box.cpp @@ -17,16 +17,97 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "ui/empty_userpic.h" +#include "ui/filter_icons.h" +#include "ui/painter.h" +#include "ui/rect.h" #include "ui/text/text_utilities.h" // Ui::Text::Bold #include "ui/widgets/buttons.h" +#include "ui/widgets/menu/menu_action.h" #include "ui/widgets/popup_menu.h" #include "window/window_controller.h" #include "window/window_session_controller.h" +#include "styles/style_dialogs.h" #include "styles/style_media_player.h" // mediaPlayerMenuCheck #include "styles/style_menu_icons.h" +#include "styles/style_settings.h" namespace { +[[nodiscard]] QImage Icon(const Data::ChatFilter &f) { + constexpr auto kScale = 0.75; + const auto icon = Ui::LookupFilterIcon(Ui::ComputeFilterIcon(f)).normal; + const auto originalWidth = icon->width(); + const auto originalHeight = icon->height(); + + const auto scaledWidth = int(originalWidth * kScale); + const auto scaledHeight = int(originalHeight * kScale); + + auto image = QImage( + scaledWidth * style::DevicePixelRatio(), + scaledHeight * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + image.setDevicePixelRatio(style::DevicePixelRatio()); + image.fill(Qt::transparent); + + { + auto p = QPainter(&image); + auto hq = PainterHighQualityEnabler(p); + + const auto x = int((scaledWidth - originalWidth * kScale) / 2); + const auto y = int((scaledHeight - originalHeight * kScale) / 2); + + p.scale(kScale, kScale); + icon->paint(p, x, y, scaledWidth, st::dialogsUnreadBgMuted->c); + if (const auto color = f.colorIndex()) { + p.resetTransform(); + const auto circleSize = scaledWidth / 3.; + const auto r = QRectF( + x + scaledWidth - circleSize, + y + scaledHeight - circleSize - circleSize / 3., + circleSize, + circleSize); + p.setPen(Qt::NoPen); + p.setCompositionMode(QPainter::CompositionMode_Clear); + p.setBrush(Qt::transparent); + p.drawEllipse(r + Margins(st::lineWidth * 1.5)); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.setBrush(Ui::EmptyUserpic::UserpicColor(*color).color2); + p.drawEllipse(r); + } + } + + return image; +} + +class FilterAction : public Ui::Menu::Action { +public: + using Ui::Menu::Action::Action; + + void setIcon(QImage &&image) { + _icon = std::move(image); + } + +protected: + void paintEvent(QPaintEvent *event) override { + Ui::Menu::Action::paintEvent(event); + if (!_icon.isNull()) { + const auto size = _icon.size() / style::DevicePixelRatio(); + auto p = QPainter(this); + p.drawImage( + width() + - size.width() + - st::menuWithIcons.itemPadding.right(), + (height() - size.height()) / 2, + _icon); + } + } + +private: + QImage _icon; + +}; + Data::ChatFilter ChangedFilter( const Data::ChatFilter &filter, not_null history, @@ -166,14 +247,14 @@ void FillChooseFilterMenu( const auto weak = base::make_weak(controller); const auto validator = ChooseFilterValidator(history); const auto &list = history->owner().chatsFilters().list(); + const auto showColors = history->owner().chatsFilters().tagsEnabled(); for (const auto &filter : list) { const auto id = filter.id(); if (!id) { continue; } - const auto contains = filter.contains(history); - const auto action = menu->addAction(filter.title(), [=] { + auto callback = [=] { const auto toAdd = !filter.contains(history); const auto r = validator.limitReached(id, toAdd); if (r.reached) { @@ -190,7 +271,23 @@ void FillChooseFilterMenu( validator.remove(id); } } - }, contains ? &st::mediaPlayerMenuCheck : nullptr); + }; + + const auto contains = filter.contains(history); + auto item = base::make_unique_q( + menu.get(), + menu->st().menu, + Ui::Menu::CreateAction( + menu.get(), + Ui::Text::FixAmpersandInAction(filter.title()), + std::move(callback)), + contains ? &st::mediaPlayerMenuCheck : nullptr, + contains ? &st::mediaPlayerMenuCheck : nullptr); + + item->setIcon(Icon(showColors ? filter : filter.withColorIndex({}))); + const auto &p = st::menuWithIcons.itemPadding; + item->setMinWidth(item->minWidth() + p.left() - p.right() - p.top()); + const auto action = menu->addAction(std::move(item)); action->setEnabled(contains ? validator.canRemove(id) : validator.canAdd());