From a27ef55ff85275dfe847cfd17b441d22dfd05bf8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 19 Apr 2023 13:33:07 +0400 Subject: [PATCH] Improve chat theme selector design. --- Telegram/Resources/langs/lang.strings | 3 +- Telegram/SourceFiles/settings/settings.style | 12 +++ .../ui/chat/choose_theme_controller.cpp | 89 +++++++++++-------- .../SourceFiles/window/window_peer_menu.cpp | 2 +- 4 files changed, 67 insertions(+), 39 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6fbf8a573..fb2bd7567 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3653,9 +3653,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_bar_view#other" = "Click here to view them"; "lng_chat_theme_change" = "Change colors"; +"lng_chat_theme_wallpaper" = "Set Wallpaper"; "lng_chat_theme_none" = "No\nTheme"; "lng_chat_theme_apply" = "Apply Theme"; -"lng_chat_theme_title" = "Select theme"; +"lng_chat_theme_title" = "Choose theme"; "lng_chat_theme_cant_voice" = "Sorry, you can't change the chat theme while you're having an unsent voice message."; "lng_photo_editor_menu_delete" = "Delete"; diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index e5da33b9b..17aa1c405 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -269,6 +269,18 @@ settingsThemeMinSkip: 4px; settingsThemeNotSupportedBg: windowBgOver; settingsThemeNotSupportedIcon: icon {{ "theme_preview", menuIconFg }}; +chatThemeTitlePadding: margins(22px, 13px, 22px, 9px); +chatThemePreviewSize: size(80px, 108px); +chatThemeBubbleSize: size(48px, 22px); +chatThemeBubbleRadius: 10px; +chatThemeBubblePosition: point(6px, 12px); +chatThemeBubbleSkip: 6px; +chatThemeEntrySkip: 10px; +chatThemeEntryMargin: margins(16px, 10px, 16px, 8px); +chatThemeEmptyPreviewTop: 16px; +chatThemeEmojiBottom: 12px; +chatThemeButtonMargin: margins(10px, 0px, 10px, 8px); + autoDownloadLimitButton: SettingsButton(settingsButtonNoIcon) { padding: margins(22px, 10px, 22px, 0px); } diff --git a/Telegram/SourceFiles/ui/chat/choose_theme_controller.cpp b/Telegram/SourceFiles/ui/chat/choose_theme_controller.cpp index 25930adc9..47d3233b9 100644 --- a/Telegram/SourceFiles/ui/chat/choose_theme_controller.cpp +++ b/Telegram/SourceFiles/ui/chat/choose_theme_controller.cpp @@ -41,7 +41,7 @@ const auto kDisableElement = [] { return u"disable"_q; }; [[nodiscard]] QImage GeneratePreview(not_null theme) { const auto &background = theme->background(); const auto &colors = background.colors; - const auto size = st::settingsThemePreviewSize; + const auto size = st::chatThemePreviewSize; auto prepared = background.prepared; const auto paintPattern = [&](QPainter &p, bool inverted) { if (prepared.isNull()) { @@ -91,16 +91,16 @@ const auto kDisableElement = [] { return u"disable"_q; }; const auto sent = QRect( QPoint( (size.width() - - st::settingsThemeBubbleSize.width() - - st::settingsThemeBubblePosition.x()), - st::settingsThemeBubblePosition.y()), - st::settingsThemeBubbleSize); + - st::chatThemeBubbleSize.width() + - st::chatThemeBubblePosition.x()), + st::chatThemeBubblePosition.y()), + st::chatThemeBubbleSize); const auto received = QRect( - st::settingsThemeBubblePosition.x(), - sent.y() + sent.height() + st::settingsThemeBubbleSkip, + st::chatThemeBubblePosition.x(), + sent.y() + sent.height() + st::chatThemeBubbleSkip, sent.width(), sent.height()); - const auto radius = st::settingsThemeBubbleRadius; + const auto radius = st::chatThemeBubbleRadius; PainterHighQualityEnabler hq(p); p.setPen(Qt::NoPen); @@ -124,7 +124,7 @@ const auto kDisableElement = [] { return u"disable"_q; }; [[nodiscard]] QImage GenerateEmptyPreview() { auto result = QImage( - st::settingsThemePreviewSize * style::DevicePixelRatio(), + st::chatThemePreviewSize * style::DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); result.fill(st::settingsThemeNotSupportedBg->c); result.setDevicePixelRatio(style::DevicePixelRatio()); @@ -132,9 +132,9 @@ const auto kDisableElement = [] { return u"disable"_q; }; auto p = QPainter(&result); p.setPen(st::menuIconFg); p.setFont(st::semiboldFont); - const auto top = st::normalFont->height / 2; - const auto width = st::settingsThemePreviewSize.width(); - const auto height = st::settingsThemePreviewSize.height() - top; + const auto top = st::chatThemeEmptyPreviewTop; + const auto width = st::chatThemePreviewSize.width(); + const auto height = st::chatThemePreviewSize.height() - top; p.drawText( QRect(0, top, width, height), tr::lng_chat_theme_none(tr::now), @@ -194,7 +194,8 @@ void ChooseThemeController::init(rpl::producer outer) { 0, object_ptr( _wrap.get(), - skip + st::boxTitle.style.font->height + skip)); + st::boxTitle.style.font->height), + st::chatThemeTitlePadding); auto title = CreateChild( titleWrap, tr::lng_chat_theme_title(), @@ -204,12 +205,23 @@ void ChooseThemeController::init(rpl::producer outer) { QPainter(_wrap.get()).fillRect(clip, st::windowBg); }, lifetime()); + const auto close = Ui::CreateChild( + _wrap.get(), + st::boxTitleClose); + close->setClickedCallback([=] { this->close(); }); + rpl::combine( + _wrap->widthValue(), + titleWrap->positionValue() + ) | rpl::start_with_next([=](int width, QPoint position) { + close->moveToRight(0, 0, width); + }, close->lifetime()); + initButtons(); initList(); _inner->positionValue( ) | rpl::start_with_next([=](QPoint position) { - title->move(std::max(position.x(), skip) + skip, skip); + title->move(std::max(position.x(), 0), 0); }, title->lifetime()); std::move( @@ -233,31 +245,28 @@ void ChooseThemeController::init(rpl::producer outer) { void ChooseThemeController::initButtons() { const auto controls = _wrap->add(object_ptr(_wrap.get())); - const auto cancel = CreateChild( - controls, - tr::lng_cancel(), - st::defaultLightButton); const auto apply = CreateChild( controls, tr::lng_chat_theme_apply(), - st::defaultActiveButton); + st::defaultLightButton); + apply->setTextTransform(Ui::RoundButton::TextTransform::NoTransform); const auto choose = CreateChild( controls, rpl::single(u"Change Wallpaper"_q), - st::defaultActiveButton); - const auto skip = st::normalFont->spacew * 2; + st::defaultLightButton); + choose->setTextTransform(Ui::RoundButton::TextTransform::NoTransform); + + const auto &margin = st::chatThemeButtonMargin; controls->resize( - skip + cancel->width() + skip + choose->width() + skip, - apply->height() + skip * 2); + margin.left() + choose->width() + margin.right(), + margin.top() + choose->height() + margin.bottom()); rpl::combine( controls->widthValue(), - cancel->widthValue(), apply->widthValue(), choose->widthValue(), _chosen.value() ) | rpl::start_with_next([=]( int outer, - int cancelWidth, int applyWidth, int chooseWidth, QString chosen) { @@ -268,13 +277,11 @@ void ChooseThemeController::initButtons() { choose->setVisible(!changed); const auto shown = changed ? apply : choose; const auto shownWidth = changed ? applyWidth : chooseWidth; - const auto inner = skip + cancelWidth + skip + shownWidth + skip; + const auto inner = margin.left() + shownWidth + margin.right(); const auto left = (outer - inner) / 2; - cancel->moveToLeft(left, 0); - shown->moveToRight(left, 0); + shown->moveToLeft(left, margin.top()); }, controls->lifetime()); - cancel->setClickedCallback([=] { close(); }); apply->setClickedCallback([=] { if (const auto chosen = findChosen()) { const auto was = _peer->themeEmoji(); @@ -326,7 +333,7 @@ void ChooseThemeController::paintEntry(QPainter &p, const Entry &entry) { const auto emojiTop = geometry.y() + geometry.height() - (size / factor) - - (st::normalFont->spacew * 2); + - st::chatThemeEmojiBottom; Ui::Emoji::Draw(p, entry.emoji, size, emojiLeft, emojiTop); if (entry.chosen) { @@ -346,7 +353,9 @@ void ChooseThemeController::paintEntry(QPainter &p, const Entry &entry) { void ChooseThemeController::initList() { _content->resize( _content->width(), - 8 * st::normalFont->spacew + st::settingsThemePreviewSize.height()); + (st::chatThemeEntryMargin.top() + + st::chatThemePreviewSize.height() + + st::chatThemeEntryMargin.bottom())); _inner->setMouseTracking(true); _inner->paintRequest( @@ -524,10 +533,16 @@ void ChooseThemeController::fill( return; } const auto count = int(themes.size()) + 1; - const auto single = st::settingsThemePreviewSize; - const auto skip = st::normalFont->spacew * 2; - const auto full = single.width() * count + skip * (count + 3); - _inner->resize(full, skip + single.height() + skip); + const auto single = st::chatThemePreviewSize; + const auto skip = st::chatThemeEntrySkip; + const auto &margin = st::chatThemeEntryMargin; + const auto full = margin.left() + + single.width() * count + + skip * (count - 1) + + margin.right(); + _inner->resize( + full, + margin.top() + single.height() + margin.bottom()); const auto initial = Ui::Emoji::Find(_peer->themeEmoji()); if (!initial) { @@ -543,11 +558,11 @@ void ChooseThemeController::fill( _cachingLifetime.destroy(); const auto old = base::take(_entries); - auto x = skip * 2; + auto x = margin.left(); _entries.push_back({ .preview = GenerateEmptyPreview(), .emoji = _disabledEmoji, - .geometry = QRect(QPoint(x, skip), single), + .geometry = QRect(QPoint(x, margin.top()), single), .chosen = (_chosen.current() == kDisableElement()), }); Assert(_entries.front().emoji != nullptr); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 4224fd4a3..ba06bf54d 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1038,7 +1038,7 @@ void Filler::addThemeEdit() { } const auto controller = _controller; _addAction( - tr::lng_chat_theme_change(tr::now), + tr::lng_chat_theme_wallpaper(tr::now), [=] { controller->toggleChooseChatTheme(user); }, &st::menuIconChangeColors); }