diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index b034282985..6330641c88 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1009,6 +1009,8 @@ PRIVATE kotato/boxes/kotato_unpin_box.h kotato/kotato_lang.cpp kotato/kotato_lang.h + kotato/kotato_radius.cpp + kotato/kotato_radius.h kotato/kotato_settings.cpp kotato/kotato_settings.h kotato/kotato_settings_menu.cpp diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index debc10016a..03a36b4ff4 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "boxes/peer_list_box.h" +#include "kotato/kotato_radius.h" #include "kotato/kotato_lang.h" #include "history/history.h" // chatListNameSortKey. #include "main/session/session_show.h" @@ -904,9 +905,7 @@ void PeerListRow::createCheckbox( const style::RoundImageCheckbox &st, Fn updateCallback) { const auto generateRadius = [=](int size) { - return (!special() && peer()->isForum()) - ? int(size * Ui::ForumUserpicRadiusMultiplier()) - : std::optional(); + return int(size * Kotato::UserpicRadius(!special() && peer()->isForum())); }; _checkbox = std::make_unique( st, diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index b43742dd38..46b5010ac9 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "core/launcher.h" +#include "kotato/kotato_radius.h" #include "kotato/kotato_settings.h" #include "kotato/kotato_version.h" #include "platform/platform_launcher.h" @@ -375,6 +376,7 @@ int Launcher::exec() { Logs::start(); base::options::init(cWorkingDir() + "tdata/experimental_options.json"); Kotato::JsonSettings::Load(); + Kotato::RefreshRadius(); // Must be called after options are inited. initHighDpi(); diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 78c2051a05..6abdc2fccb 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "data/data_peer.h" +#include "kotato/kotato_radius.h" #include "data/data_user.h" #include "data/data_chat.h" #include "data/data_chat_participant_status.h" @@ -382,6 +383,7 @@ QImage PeerData::generateUserpicImage( Ui::PeerUserpicView &view, int size, std::optional radius) const { + const auto radiusOption = Kotato::UserpicRadius(isForum()); if (const auto userpic = userpicCloudImage(view)) { auto image = userpic->scaled( { size, size }, @@ -393,7 +395,13 @@ QImage PeerData::generateUserpicImage( Images::CornersMask(radius / style::DevicePixelRatio())); }; if (radius == 0) { - return image; + if (radiusOption == 0.0) { + return image; + } else if (radiusOption) { + return round(size * radiusOption); + } else { + return Images::Circle(std::move(image)); + } } else if (radius) { return round(*radius); } else if (isForum()) { @@ -409,7 +417,19 @@ QImage PeerData::generateUserpicImage( Painter p(&result); if (radius == 0) { - ensureEmptyUserpic()->paintSquare(p, 0, 0, size, size); + if (radiusOption == 0.0) { + ensureEmptyUserpic()->paintSquare(p, 0, 0, size, size); + } else if (radiusOption) { + ensureEmptyUserpic()->paintRounded( + p, + 0, + 0, + size, + size, + size * radiusOption); + } else { + ensureEmptyUserpic()->paintCircle(p, 0, 0, size, size); + } } else if (radius) { ensureEmptyUserpic()->paintRounded(p, 0, 0, size, size, *radius); } else if (isForum()) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 9ecddf88fa..4a45f34756 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "dialogs/dialogs_row.h" +#include "kotato/kotato_radius.h" #include "ui/chat/chat_theme.h" // CountAverageColor. #include "ui/color_contrast.h" #include "ui/effects/outline_segments.h" @@ -416,7 +417,7 @@ void Row::PaintCornerBadgeFrame( : st::dialogsCallBadgeSize; const auto stroke = st::dialogsOnlineBadgeStroke; const auto skip = online - ? st::dialogsOnlineBadgeSkip + ? Kotato::UserpicOnlineBadgeSkip() : st::dialogsCallBadgeSkip; const auto shrink = (size / 2) * (1. - topLayerProgress); diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp index f615f4fb39..911230ed56 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "dialogs/ui/dialogs_stories_list.h" +#include "kotato/kotato_radius.h" #include "base/event_filter.h" #include "base/qt_signal_producer.h" #include "lang/lang_keys.h" @@ -528,7 +529,7 @@ void List::paint( if (!fullUnreadCount) { p.setPen(QPen(gradient, line)); p.setBrush(Qt::NoBrush); - p.drawEllipse(outer); + Kotato::DrawUserpicShape(p, outer, outerAdd); } else { validateSegments(itemFull, gradient, line, true); Ui::PaintOutlineSegments( @@ -569,7 +570,7 @@ void List::paint( p.setCompositionMode(QPainter::CompositionMode_Source); p.setPen(Qt::NoPen); p.setBrush(st::transparent); - p.drawEllipse(rect); + Kotato::DrawUserpicShape(p, rect, add); p.setCompositionMode(QPainter::CompositionMode_SourceOver); } if (hasReadLine) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp index bfc0562431..3cbaf75863 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "dialogs/ui/dialogs_video_userpic.h" +#include "kotato/kotato_radius.h" #include "core/file_location.h" #include "data/data_peer.h" #include "data/data_photo.h" @@ -100,7 +101,7 @@ Media::Clip::FrameRequest VideoUserpic::request(int size) const { .frame = { size, size }, .outer = { size, size }, .factor = cIntRetinaFactor(), - .radius = ImageRoundRadius::Ellipse, + .radius = Kotato::UserpicRadius(), }; } diff --git a/Telegram/SourceFiles/history/view/history_view_group_call_bar.cpp b/Telegram/SourceFiles/history/view/history_view_group_call_bar.cpp index 7fc19532a0..e6b1926193 100644 --- a/Telegram/SourceFiles/history/view/history_view_group_call_bar.cpp +++ b/Telegram/SourceFiles/history/view/history_view_group_call_bar.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "history/view/history_view_group_call_bar.h" +#include "kotato/kotato_radius.h" #include "data/data_channel.h" #include "data/data_user.h" #include "data/data_changes.h" @@ -59,7 +60,7 @@ void GenerateUserpicsInRow( q.setCompositionMode(QPainter::CompositionMode_Source); q.setBrush(Qt::NoBrush); q.setPen(pen); - q.drawEllipse(x, 0, single, single); + Kotato::DrawUserpicShape(q, x, 0, single, single, single); x -= single - shift; } } diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions.cpp index 328a8749a1..3c951cc6c1 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "history/view/reactions/history_view_reactions.h" +#include "kotato/kotato_radius.h" #include "history/history_item.h" #include "history/history.h" #include "history/view/history_view_message.h" @@ -623,7 +624,7 @@ void InlineList::paintSingleBg( float64 opacity) const { p.setOpacity(opacity); if (!areTags()) { - const auto radius = fill.height() / 2.; + const auto radius = fill.height() * Kotato::UserpicRadius(); p.setBrush(color); p.drawRoundedRect(fill, radius, radius); return; diff --git a/Telegram/SourceFiles/kotato/kotato_radius.cpp b/Telegram/SourceFiles/kotato/kotato_radius.cpp new file mode 100644 index 0000000000..3cf70c5dfc --- /dev/null +++ b/Telegram/SourceFiles/kotato/kotato_radius.cpp @@ -0,0 +1,143 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#include "kotato/kotato_radius.h" + +#include "kotato/kotato_settings.h" +#include "ui/painter.h" +#include "styles/style_chat.h" +#include "styles/style_dialogs.h" + +namespace Kotato { +namespace { + +struct Radius { + float64 userpicRadius = 0.5; + float64 forumUserpicRadius = 0.3; + bool useDefaultRadiusForForum = false; + style::point onlineBadgeSkip = st::dialogsOnlineBadgeSkip; +}; + +Radius radius; + +} // namespace + +void RefreshRadius() { + radius.userpicRadius = float64(JsonSettings::GetInt("userpic_corner_radius")) / 100.0; + radius.forumUserpicRadius = float64(JsonSettings::GetInt("userpic_corner_radius_forum")) / 100.0; + radius.useDefaultRadiusForForum = JsonSettings::GetBool("userpic_corner_radius_forum_use_default"); + radius.onlineBadgeSkip = { + style::ConvertScale(int(2 * radius.userpicRadius) - 1), + style::ConvertScale(int(6 * radius.userpicRadius) - 1), + }; +} + +float64 UserpicRadius(bool isForum) { + if (isForum && !radius.useDefaultRadiusForForum) { + return radius.forumUserpicRadius; + } + return radius.userpicRadius; +} + +void DrawUserpicShape( + QPainter &p, + QRect rect, + float64 size, + bool isForum) { + const auto r = UserpicRadius(isForum); + if (r >= 0.5) { + p.drawEllipse(rect); + } else if (r) { + p.drawRoundedRect(rect, size * r, size * r); + } else { + p.fillRect(rect, p.brush()); + } +} + +void DrawUserpicShape( + QPainter &p, + QRectF rect, + float64 size, + bool isForum) { + const auto r = UserpicRadius(isForum); + if (r >= 0.5) { + p.drawEllipse(rect); + } else if (r) { + p.drawRoundedRect(rect, size * r, size * r); + } else { + p.fillRect(rect, p.brush()); + } +} + +void DrawUserpicShape( + QPainter &p, + int x, + int y, + int w, + int h, + float64 size, + bool isForum) { + const auto r = UserpicRadius(isForum); + if (r >= 0.5) { + p.drawEllipse(x, y, w, h); + } else if (r) { + p.drawRoundedRect(x, y, w, h, size * r, size * r); + } else { + p.fillRect(x, y, w, h, p.brush()); + } +} + +style::point UserpicOnlineBadgeSkip() { + return radius.onlineBadgeSkip; +} + +QPixmap MessageTailLeft(style::color color) { + const auto tail = st::historyBubbleTailInLeft; + QImage rect(tail.width(), tail.height(), QImage::Format_ARGB32_Premultiplied); + rect.fill(color->c); + { + auto p = QPainter(&rect); + PainterHighQualityEnabler hq(p); + + p.setCompositionMode(QPainter::CompositionMode_Source); + p.setPen(Qt::NoPen); + p.setBrush(Qt::transparent); + p.drawRoundedRect( + tail.width()-st::msgPhotoSize+style::ConvertScale(1), + tail.height()-st::msgPhotoSize+style::ConvertScale(2), + st::msgPhotoSize, + st::msgPhotoSize, + st::msgPhotoSize * radius.userpicRadius, + st::msgPhotoSize * radius.userpicRadius); + } + return QPixmap::fromImage(rect); +} + +QPixmap MessageTailRight(style::color color) { + const auto tail = st::historyBubbleTailInRight; + QImage rect(tail.width(), tail.height(), QImage::Format_ARGB32_Premultiplied); + rect.fill(color->c); + { + auto p = QPainter(&rect); + PainterHighQualityEnabler hq(p); + + p.setCompositionMode(QPainter::CompositionMode_Source); + p.setPen(Qt::NoPen); + p.setBrush(Qt::transparent); + p.drawRoundedRect( + -style::ConvertScale(1), + tail.height()-st::msgPhotoSize+style::ConvertScale(2), + st::msgPhotoSize, + st::msgPhotoSize, + st::msgPhotoSize * radius.userpicRadius, + st::msgPhotoSize * radius.userpicRadius); + } + return QPixmap::fromImage(rect); +} + + +} // namespace Kotato \ No newline at end of file diff --git a/Telegram/SourceFiles/kotato/kotato_radius.h b/Telegram/SourceFiles/kotato/kotato_radius.h new file mode 100644 index 0000000000..2d80492fd3 --- /dev/null +++ b/Telegram/SourceFiles/kotato/kotato_radius.h @@ -0,0 +1,38 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#pragma once + +namespace Kotato { + +void RefreshRadius(); +float64 UserpicRadius(bool isForum = false); +void DrawUserpicShape( + QPainter &p, + QRect rect, + float64 size, + bool isForum = false); +void DrawUserpicShape( + QPainter &p, + QRectF rect, + float64 size, + bool isForum = false); +void DrawUserpicShape( + QPainter &p, + int x, + int y, + int w, + int h, + float64 size, + bool isForum = false); + +style::point UserpicOnlineBadgeSkip(); + +QPixmap MessageTailLeft(style::color color); +QPixmap MessageTailRight(style::color color); + +} // namespace Kotato \ No newline at end of file diff --git a/Telegram/SourceFiles/kotato/kotato_settings.cpp b/Telegram/SourceFiles/kotato/kotato_settings.cpp index 67431dfc85..38ff305e53 100644 --- a/Telegram/SourceFiles/kotato/kotato_settings.cpp +++ b/Telegram/SourceFiles/kotato/kotato_settings.cpp @@ -333,6 +333,17 @@ const std::map> DefinitionMap { .type = SettingType::IntSetting, .defaultValue = 20, .limitHandler = IntLimit(0, 200, 20), }}, + { "userpic_corner_radius", { + .type = SettingType::IntSetting, + .defaultValue = 50, + .limitHandler = IntLimit(0, 50), }}, + { "userpic_corner_radius_forum", { + .type = SettingType::IntSetting, + .defaultValue = 30, + .limitHandler = IntLimit(0, 50), }}, + { "userpic_corner_radius_forum_use_default", { + .type = SettingType::BoolSetting, + .defaultValue = false, }}, { "always_show_top_userpic", { .type = SettingType::BoolSetting, .defaultValue = false, }}, diff --git a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp index ee7487269b..bbcbf420e9 100644 --- a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp +++ b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp @@ -45,7 +45,7 @@ QImage PrepareFrame( const auto needResize = (original.size() != request.frame); const auto needOuterFill = request.outer.isValid() && (request.outer != request.frame); - const auto needRounding = (request.radius != ImageRoundRadius::None); + const auto needRounding = (request.radius > 0.0); const auto colorizing = (request.colored.alpha() != 0); if (!needResize && !needOuterFill @@ -98,8 +98,7 @@ QImage PrepareFrame( if (needRounding) { cache = Images::Round( std::move(cache), - request.radius, - request.corners); + Images::CornersMask((cache.width() * request.radius) / style::DevicePixelRatio())); } if (colorizing) { cache = Images::Colored(std::move(cache), request.colored); diff --git a/Telegram/SourceFiles/media/clip/media_clip_reader.h b/Telegram/SourceFiles/media/clip/media_clip_reader.h index faa3f24a14..356a5cc6d2 100644 --- a/Telegram/SourceFiles/media/clip/media_clip_reader.h +++ b/Telegram/SourceFiles/media/clip/media_clip_reader.h @@ -37,7 +37,7 @@ struct FrameRequest { QSize frame; QSize outer; int factor = 0; - ImageRoundRadius radius = ImageRoundRadius::None; + float64 radius = 0.0; RectParts corners = RectPart::AllCorners; QColor colored = QColor(0, 0, 0, 0); bool keepAlpha = false; diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 99cd1b9074..3b314311bb 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -94,7 +94,7 @@ crl::time LastSettingsQueryMs/* = 0*/; - + diff --git a/Telegram/SourceFiles/settings/settings_information.cpp b/Telegram/SourceFiles/settings/settings_information.cpp index a2de6ea04c..f0789dca15 100644 --- a/Telegram/SourceFiles/settings/settings_information.cpp +++ b/Telegram/SourceFiles/settings/settings_information.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "settings/settings_information.h" +#include "kotato/kotato_radius.h" #include "kotato/kotato_lang.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout_reorder.h" @@ -639,7 +640,7 @@ void SetupAccountsWrap( pen.setWidthF(line); p.setPen(pen); p.setBrush(Qt::NoBrush); - p.drawEllipse(rect); + Kotato::DrawUserpicShape(p, rect, size); } }, state->userpic.lifetime()); diff --git a/Telegram/SourceFiles/ui/chat/choose_send_as.cpp b/Telegram/SourceFiles/ui/chat/choose_send_as.cpp index 0856b044a8..dd37fa0019 100644 --- a/Telegram/SourceFiles/ui/chat/choose_send_as.cpp +++ b/Telegram/SourceFiles/ui/chat/choose_send_as.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "ui/chat/choose_send_as.h" +#include "kotato/kotato_radius.h" #include "boxes/peer_list_box.h" #include "data/data_peer.h" #include "data/data_channel.h" @@ -283,7 +284,8 @@ void SetupSendAsButton( ) | rpl::map([=](not_null chosen) { return Data::PeerUserpicImageValue( chosen, - st::sendAsButton.size * style::DevicePixelRatio()); + st::sendAsButton.size * style::DevicePixelRatio(), + st::sendAsButton.size * Kotato::UserpicRadius()); }) | rpl::flatten_latest(); }) | rpl::flatten_latest(); diff --git a/Telegram/SourceFiles/ui/chat/group_call_userpics.cpp b/Telegram/SourceFiles/ui/chat/group_call_userpics.cpp index 4044c7d26f..fa1ac47c2a 100644 --- a/Telegram/SourceFiles/ui/chat/group_call_userpics.cpp +++ b/Telegram/SourceFiles/ui/chat/group_call_userpics.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "ui/chat/group_call_userpics.h" +#include "kotato/kotato_radius.h" #include "ui/paint/blobs.h" #include "ui/painter.h" #include "ui/power_saving.h" @@ -273,7 +274,7 @@ void GroupCallUserpics::validateCache(Userpic &userpic) { p.setCompositionMode(QPainter::CompositionMode_Source); p.setBrush(Qt::transparent); p.setPen(pen); - p.drawEllipse(skip - size + shift, skip, size, size); + Kotato::DrawUserpicShape(p, skip - size + shift, skip, size, size, size); } } } diff --git a/Telegram/SourceFiles/ui/chat/message_bubble.cpp b/Telegram/SourceFiles/ui/chat/message_bubble.cpp index 8d398e51c5..8fa7bd8751 100644 --- a/Telegram/SourceFiles/ui/chat/message_bubble.cpp +++ b/Telegram/SourceFiles/ui/chat/message_bubble.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "ui/chat/message_bubble.h" +#include "kotato/kotato_radius.h" #include "ui/cached_round_corners.h" #include "ui/image/image_prepare.h" #include "ui/chat/chat_style.h" @@ -240,7 +241,11 @@ void PaintSolidBubble(QPainter &p, const SimpleBubble &args) { : st.msgBgCornersSmall; p.drawPixmap(x, y, corners.p[index]); }, [&](const QPoint &bottomPosition) { - tail.paint(p, bottomPosition - tailShift, args.outerWidth); + p.drawPixmap( + bottomPosition - tailShift, + (args.rounding.bottomRight == Corner::Tail) + ? Kotato::MessageTailRight(bg) + : Kotato::MessageTailLeft(bg)); return tail.width(); }); } diff --git a/Telegram/SourceFiles/ui/controls/userpic_button.cpp b/Telegram/SourceFiles/ui/controls/userpic_button.cpp index c1d0965b83..cda25367f0 100644 --- a/Telegram/SourceFiles/ui/controls/userpic_button.cpp +++ b/Telegram/SourceFiles/ui/controls/userpic_button.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "ui/controls/userpic_button.h" +#include "kotato/kotato_radius.h" #include "base/call_delayed.h" #include "ui/effects/ripple_animation.h" #include "ui/empty_userpic.h" @@ -135,7 +136,7 @@ void SetupSubButtonBackground( auto hq = PainterHighQualityEnabler(p); p.setBrush(st::boxBg); p.setPen(Qt::NoPen); - p.drawEllipse(background->rect()); + Kotato::DrawUserpicShape(p, background->rect(), background->rect().width()); }, background->lifetime()); upload->positionValue( @@ -579,9 +580,9 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) { auto size = QSize{ _st.photoSize, _st.photoSize }; const auto ratio = style::DevicePixelRatio(); request.outer = request.resize = size * ratio; - if (useForumShape()) { - const auto radius = int(_st.photoSize - * Ui::ForumUserpicRadiusMultiplier()); + const auto radiusOption = Kotato::UserpicRadius(useForumShape()); + if (radiusOption < 0.5) { + const auto radius = int(_st.photoSize * radiusOption); if (_roundingCorners[0].width() != radius * ratio) { _roundingCorners = Images::CornersMask(radius); } @@ -988,8 +989,9 @@ void UserpicButton::fillShape(QPainter &p, const style::color &color) const { p.setPen(Qt::NoPen); p.setBrush(color); const auto size = _st.photoSize; - if (useForumShape()) { - const auto radius = size * Ui::ForumUserpicRadiusMultiplier(); + const auto radiusOption = Kotato::UserpicRadius(useForumShape()); + if (radiusOption < 0.5) { + const auto radius = size * radiusOption; p.drawRoundedRect(0, 0, size, size, radius, radius); } else { p.drawEllipse(0, 0, size, size); diff --git a/Telegram/SourceFiles/ui/empty_userpic.cpp b/Telegram/SourceFiles/ui/empty_userpic.cpp index 9d536f15cd..e5f556c122 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.cpp +++ b/Telegram/SourceFiles/ui/empty_userpic.cpp @@ -8,6 +8,7 @@ For license and copyright information please follow this link: #include "ui/empty_userpic.h" #include "ui/chat/chat_style.h" +#include "kotato/kotato_radius.h" #include "ui/effects/animation_value.h" #include "ui/emoji_config.h" #include "ui/painter.h" @@ -378,7 +379,7 @@ void EmptyUserpic::PaintSavedMessages( PainterHighQualityEnabler hq(p); p.setBrush(std::move(bg)); p.setPen(Qt::NoPen); - p.drawEllipse(x, y, size, size); + Kotato::DrawUserpicShape(p, x, y, size, size, size); PaintSavedMessagesInner(p, x, y, size, fg); } @@ -417,7 +418,7 @@ void EmptyUserpic::PaintRepliesMessages( PainterHighQualityEnabler hq(p); p.setBrush(bg); p.setPen(Qt::NoPen); - p.drawEllipse(x, y, size, size); + Kotato::DrawUserpicShape(p, x, y, size, size, size); PaintRepliesMessagesInner(p, x, y, size, fg); } diff --git a/Telegram/SourceFiles/ui/userpic_view.cpp b/Telegram/SourceFiles/ui/userpic_view.cpp index f14ac76e80..e558aab8ff 100644 --- a/Telegram/SourceFiles/ui/userpic_view.cpp +++ b/Telegram/SourceFiles/ui/userpic_view.cpp @@ -7,6 +7,7 @@ For license and copyright information please follow this link: */ #include "ui/userpic_view.h" +#include "kotato/kotato_radius.h" #include "ui/empty_userpic.h" #include "ui/image/image_prepare.h" @@ -28,10 +29,12 @@ void ValidateUserpicCache( bool forum) { Expects(cloud != nullptr || empty != nullptr); + const auto radius = Kotato::UserpicRadius(forum); const auto full = QSize(size, size); const auto version = style::PaletteVersion(); const auto forumValue = forum ? 1 : 0; const auto regenerate = (view.cached.size() != QSize(size, size)) + || (view.radius != radius) || (view.forum != forumValue) || (cloud && !view.empty.null()) || (empty && empty != view.empty.get()) @@ -48,14 +51,14 @@ void ValidateUserpicCache( full, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - if (forum) { + if (radius >= 0.5) { + view.cached = Images::Circle(std::move(view.cached)); + } else if (radius) { view.cached = Images::Round( std::move(view.cached), Images::CornersMask(size - * Ui::ForumUserpicRadiusMultiplier() + * radius / style::DevicePixelRatio())); - } else { - view.cached = Images::Circle(std::move(view.cached)); } } else { if (view.cached.size() != full) { @@ -64,16 +67,23 @@ void ValidateUserpicCache( view.cached.fill(Qt::transparent); auto p = QPainter(&view.cached); - if (forum) { + if (radius >= 0.5) { + empty->paintCircle(p, 0, 0, size, size); + } else if (radius) { empty->paintRounded( p, 0, 0, size, size, - size * Ui::ForumUserpicRadiusMultiplier()); + size * radius); } else { - empty->paintCircle(p, 0, 0, size, size); + empty->paintSquare( + p, + 0, + 0, + size, + size); } } } diff --git a/Telegram/SourceFiles/ui/userpic_view.h b/Telegram/SourceFiles/ui/userpic_view.h index 6e50127d74..d3f0a6ca89 100644 --- a/Telegram/SourceFiles/ui/userpic_view.h +++ b/Telegram/SourceFiles/ui/userpic_view.h @@ -27,6 +27,7 @@ struct PeerUserpicView { base::weak_ptr empty; uint32 paletteVersion : 31 = 0; uint32 forum : 1 = 0; + float64 radius = -1.0; }; [[nodiscard]] bool PeerUserpicLoading(const PeerUserpicView &view);