From 24843e3acd67183da970640c8dfd666eb7d49d58 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 12 Oct 2022 17:42:35 +0400 Subject: [PATCH] Rounded square userpics for forums. --- Telegram/SourceFiles/data/data_forum.cpp | 4 ++ Telegram/SourceFiles/data/data_peer.cpp | 25 +++++--- .../history/view/media/history_view_photo.cpp | 19 ++++-- Telegram/SourceFiles/ui/special_buttons.cpp | 58 ++++++++++++------- 4 files changed, 71 insertions(+), 35 deletions(-) diff --git a/Telegram/SourceFiles/data/data_forum.cpp b/Telegram/SourceFiles/data/data_forum.cpp index ab39ca9b22..11fb05413f 100644 --- a/Telegram/SourceFiles/data/data_forum.cpp +++ b/Telegram/SourceFiles/data/data_forum.cpp @@ -103,6 +103,10 @@ void Forum::requestTopics() { }).fail([=](const MTP::Error &error) { _allLoaded = true; _requestId = 0; + if (error.type() == u"CHANNEL_FORUM_MISSING"_q) { + const auto flags = channel()->flags() & ~ChannelDataFlag::Forum; + channel()->setFlags(flags); + } }).send(); } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 03292e0b5b..14663a5b94 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -307,11 +307,13 @@ void PeerData::paintUserpic( int y, int size) const { if (const auto userpic = currentUserpic(view)) { - const auto circled = Images::Option::RoundCircle; + const auto rounding = isForum() + ? Images::Option::RoundLarge + : Images::Option::RoundCircle; p.drawPixmap( x, y, - userpic->pix(size, size, { .options = circled })); + userpic->pix(size, size, { .options = rounding })); } else { ensureEmptyUserpic()->paint(p, x, y, x + size + x, size); } @@ -371,8 +373,10 @@ QPixmap PeerData::genUserpic( std::shared_ptr &view, int size) const { if (const auto userpic = currentUserpic(view)) { - const auto circle = Images::Option::RoundCircle; - return userpic->pix(size, size, { .options = circle }); + const auto rounding = isForum() + ? Images::Option::RoundLarge + : Images::Option::RoundCircle; + return userpic->pix(size, size, { .options = rounding }); } const auto ratio = style::DevicePixelRatio(); auto result = QImage( @@ -390,7 +394,10 @@ QPixmap PeerData::genUserpic( QImage PeerData::generateUserpicImage( std::shared_ptr &view, int size) const { - return generateUserpicImage(view, size, ImageRoundRadius::Ellipse); + return generateUserpicImage( + view, + size, + isForum() ? ImageRoundRadius::Large : ImageRoundRadius::Ellipse); } QImage PeerData::generateUserpicImage( @@ -400,9 +407,11 @@ QImage PeerData::generateUserpicImage( if (const auto userpic = currentUserpic(view)) { const auto options = (radius == ImageRoundRadius::Ellipse) ? Images::Option::RoundCircle - : (radius == ImageRoundRadius::None) - ? Images::Option() - : Images::Option::RoundSmall; + : (radius == ImageRoundRadius::Large) + ? Images::Option::RoundLarge + : (radius == ImageRoundRadius::Small) + ? Images::Option::RoundSmall + : Images::Option(); return userpic->pixNoCache( { size, size }, { .options = options }).toImage(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 28abf6b988..4c52695fd4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -44,8 +44,9 @@ using Data::PhotoSize; struct Photo::Streamed { explicit Streamed(std::shared_ptr<::Media::Streaming::Document> shared); ::Media::Streaming::Instance instance; - QImage roundingMask; + ::Media::Streaming::FrameRequest frozenRequest; QImage frozenFrame; + QImage roundingMask; }; Photo::Streamed::Streamed( @@ -411,12 +412,20 @@ void Photo::paintUserpicFrame( auto request = ::Media::Streaming::FrameRequest(); request.outer = size * cIntRetinaFactor(); request.resize = size * cIntRetinaFactor(); - if (_streamed->roundingMask.size() != request.outer) { - _streamed->roundingMask = Images::EllipseMask(size); + const auto forum = _parent->data()->history()->peer->isForum(); + if (forum) { + request.rounding = Images::CornersMaskRef( + Images::CornersMask(ImageRoundRadius::Large)); + } else { + if (_streamed->roundingMask.size() != request.outer) { + _streamed->roundingMask = Images::EllipseMask(size); + } + request.mask = _streamed->roundingMask; } - request.mask = _streamed->roundingMask; if (_streamed->instance.playerLocked()) { - if (_streamed->frozenFrame.isNull()) { + if (_streamed->frozenFrame.isNull() + || _streamed->frozenRequest != request) { + _streamed->frozenRequest = request; _streamed->frozenFrame = _streamed->instance.frame(request); } p.drawImage(rect, _streamed->frozenFrame); diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index 4489dc6c91..a80267c1ef 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -388,20 +388,34 @@ void UserpicButton::paintEvent(QPaintEvent *e) { paintUserpicFrame(p, photoPosition); } - if (_role == Role::ChangePhoto || _role == Role::ChoosePhoto) { - auto over = isOver() || isDown(); - if (over) { - PainterHighQualityEnabler hq(p); - p.setPen(Qt::NoPen); - p.setBrush(_userpicHasImage - ? st::msgDateImgBg - : _st.changeButton.textBgOver); + const auto fillShape = [&](const style::color &color) { + PainterHighQualityEnabler hq(p); + p.setPen(Qt::NoPen); + p.setBrush(color); + if (_peer && _peer->isForum()) { + p.drawRoundedRect( + photoLeft, + photoTop, + _st.photoSize, + _st.photoSize, + st::roundRadiusLarge, + st::roundRadiusLarge); + } else { p.drawEllipse( photoLeft, photoTop, _st.photoSize, _st.photoSize); } + }; + + if (_role == Role::ChangePhoto || _role == Role::ChoosePhoto) { + auto over = isOver() || isDown(); + if (over) { + fillShape(_userpicHasImage + ? st::msgDateImgBg + : _st.changeButton.textBgOver); + } paintRipple( p, photoLeft, @@ -438,16 +452,7 @@ void UserpicButton::paintEvent(QPaintEvent *e) { _st.photoSize, barHeight); p.setClipRect(rect); - { - PainterHighQualityEnabler hq(p); - p.setPen(Qt::NoPen); - p.setBrush(_st.uploadBg); - p.drawEllipse( - photoLeft, - photoTop, - _st.photoSize, - _st.photoSize); - } + fillShape(_st.uploadBg); auto iconLeft = (_st.uploadIconPosition.x() < 0) ? (_st.photoSize - _st.uploadIcon.width()) / 2 : _st.uploadIconPosition.x(); @@ -478,10 +483,16 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) { auto size = QSize{ _st.photoSize, _st.photoSize }; request.outer = size * cIntRetinaFactor(); request.resize = size * cIntRetinaFactor(); - if (_ellipseMask.size() != request.outer) { - _ellipseMask = Images::EllipseMask(size); + const auto forum = _peer && _peer->isForum(); + if (forum) { + request.rounding = Images::CornersMaskRef( + Images::CornersMask(ImageRoundRadius::Large)); + } else { + if (_ellipseMask.size() != request.outer) { + _ellipseMask = Images::EllipseMask(size); + } + request.mask = _ellipseMask; } - request.mask = _ellipseMask; p.drawImage(QRect(photoPosition, size), _streamed->frame(request)); if (!paused) { _streamed->markFrameShown(); @@ -778,7 +789,10 @@ void UserpicButton::setImage(QImage &&image) { size * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - _userpic = Ui::PixmapFromImage(Images::Circle(std::move(small))); + const auto forum = _peer && _peer->isForum(); + _userpic = Ui::PixmapFromImage(forum + ? Images::Round(std::move(small), Images::Option::RoundLarge) + : Images::Circle(std::move(small))); _userpic.setDevicePixelRatio(cRetinaFactor()); _userpicCustom = _userpicHasImage = true; _result = std::move(image);