Rounded square userpics for forums.

This commit is contained in:
John Preston 2022-10-12 17:42:35 +04:00
parent 8561893e2e
commit 24843e3acd
4 changed files with 71 additions and 35 deletions

View file

@ -103,6 +103,10 @@ void Forum::requestTopics() {
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
_allLoaded = true; _allLoaded = true;
_requestId = 0; _requestId = 0;
if (error.type() == u"CHANNEL_FORUM_MISSING"_q) {
const auto flags = channel()->flags() & ~ChannelDataFlag::Forum;
channel()->setFlags(flags);
}
}).send(); }).send();
} }

View file

@ -307,11 +307,13 @@ void PeerData::paintUserpic(
int y, int y,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
const auto circled = Images::Option::RoundCircle; const auto rounding = isForum()
? Images::Option::RoundLarge
: Images::Option::RoundCircle;
p.drawPixmap( p.drawPixmap(
x, x,
y, y,
userpic->pix(size, size, { .options = circled })); userpic->pix(size, size, { .options = rounding }));
} else { } else {
ensureEmptyUserpic()->paint(p, x, y, x + size + x, size); ensureEmptyUserpic()->paint(p, x, y, x + size + x, size);
} }
@ -371,8 +373,10 @@ QPixmap PeerData::genUserpic(
std::shared_ptr<Data::CloudImageView> &view, std::shared_ptr<Data::CloudImageView> &view,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
const auto circle = Images::Option::RoundCircle; const auto rounding = isForum()
return userpic->pix(size, size, { .options = circle }); ? Images::Option::RoundLarge
: Images::Option::RoundCircle;
return userpic->pix(size, size, { .options = rounding });
} }
const auto ratio = style::DevicePixelRatio(); const auto ratio = style::DevicePixelRatio();
auto result = QImage( auto result = QImage(
@ -390,7 +394,10 @@ QPixmap PeerData::genUserpic(
QImage PeerData::generateUserpicImage( QImage PeerData::generateUserpicImage(
std::shared_ptr<Data::CloudImageView> &view, std::shared_ptr<Data::CloudImageView> &view,
int size) const { int size) const {
return generateUserpicImage(view, size, ImageRoundRadius::Ellipse); return generateUserpicImage(
view,
size,
isForum() ? ImageRoundRadius::Large : ImageRoundRadius::Ellipse);
} }
QImage PeerData::generateUserpicImage( QImage PeerData::generateUserpicImage(
@ -400,9 +407,11 @@ QImage PeerData::generateUserpicImage(
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
const auto options = (radius == ImageRoundRadius::Ellipse) const auto options = (radius == ImageRoundRadius::Ellipse)
? Images::Option::RoundCircle ? Images::Option::RoundCircle
: (radius == ImageRoundRadius::None) : (radius == ImageRoundRadius::Large)
? Images::Option() ? Images::Option::RoundLarge
: Images::Option::RoundSmall; : (radius == ImageRoundRadius::Small)
? Images::Option::RoundSmall
: Images::Option();
return userpic->pixNoCache( return userpic->pixNoCache(
{ size, size }, { size, size },
{ .options = options }).toImage(); { .options = options }).toImage();

View file

@ -44,8 +44,9 @@ using Data::PhotoSize;
struct Photo::Streamed { struct Photo::Streamed {
explicit Streamed(std::shared_ptr<::Media::Streaming::Document> shared); explicit Streamed(std::shared_ptr<::Media::Streaming::Document> shared);
::Media::Streaming::Instance instance; ::Media::Streaming::Instance instance;
QImage roundingMask; ::Media::Streaming::FrameRequest frozenRequest;
QImage frozenFrame; QImage frozenFrame;
QImage roundingMask;
}; };
Photo::Streamed::Streamed( Photo::Streamed::Streamed(
@ -411,12 +412,20 @@ void Photo::paintUserpicFrame(
auto request = ::Media::Streaming::FrameRequest(); auto request = ::Media::Streaming::FrameRequest();
request.outer = size * cIntRetinaFactor(); request.outer = size * cIntRetinaFactor();
request.resize = size * cIntRetinaFactor(); request.resize = size * cIntRetinaFactor();
if (_streamed->roundingMask.size() != request.outer) { const auto forum = _parent->data()->history()->peer->isForum();
_streamed->roundingMask = Images::EllipseMask(size); 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->instance.playerLocked()) {
if (_streamed->frozenFrame.isNull()) { if (_streamed->frozenFrame.isNull()
|| _streamed->frozenRequest != request) {
_streamed->frozenRequest = request;
_streamed->frozenFrame = _streamed->instance.frame(request); _streamed->frozenFrame = _streamed->instance.frame(request);
} }
p.drawImage(rect, _streamed->frozenFrame); p.drawImage(rect, _streamed->frozenFrame);

View file

@ -388,20 +388,34 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
paintUserpicFrame(p, photoPosition); paintUserpicFrame(p, photoPosition);
} }
if (_role == Role::ChangePhoto || _role == Role::ChoosePhoto) { const auto fillShape = [&](const style::color &color) {
auto over = isOver() || isDown(); PainterHighQualityEnabler hq(p);
if (over) { p.setPen(Qt::NoPen);
PainterHighQualityEnabler hq(p); p.setBrush(color);
p.setPen(Qt::NoPen); if (_peer && _peer->isForum()) {
p.setBrush(_userpicHasImage p.drawRoundedRect(
? st::msgDateImgBg photoLeft,
: _st.changeButton.textBgOver); photoTop,
_st.photoSize,
_st.photoSize,
st::roundRadiusLarge,
st::roundRadiusLarge);
} else {
p.drawEllipse( p.drawEllipse(
photoLeft, photoLeft,
photoTop, photoTop,
_st.photoSize, _st.photoSize,
_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( paintRipple(
p, p,
photoLeft, photoLeft,
@ -438,16 +452,7 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
_st.photoSize, _st.photoSize,
barHeight); barHeight);
p.setClipRect(rect); p.setClipRect(rect);
{ fillShape(_st.uploadBg);
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(_st.uploadBg);
p.drawEllipse(
photoLeft,
photoTop,
_st.photoSize,
_st.photoSize);
}
auto iconLeft = (_st.uploadIconPosition.x() < 0) auto iconLeft = (_st.uploadIconPosition.x() < 0)
? (_st.photoSize - _st.uploadIcon.width()) / 2 ? (_st.photoSize - _st.uploadIcon.width()) / 2
: _st.uploadIconPosition.x(); : _st.uploadIconPosition.x();
@ -478,10 +483,16 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) {
auto size = QSize{ _st.photoSize, _st.photoSize }; auto size = QSize{ _st.photoSize, _st.photoSize };
request.outer = size * cIntRetinaFactor(); request.outer = size * cIntRetinaFactor();
request.resize = size * cIntRetinaFactor(); request.resize = size * cIntRetinaFactor();
if (_ellipseMask.size() != request.outer) { const auto forum = _peer && _peer->isForum();
_ellipseMask = Images::EllipseMask(size); 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)); p.drawImage(QRect(photoPosition, size), _streamed->frame(request));
if (!paused) { if (!paused) {
_streamed->markFrameShown(); _streamed->markFrameShown();
@ -778,7 +789,10 @@ void UserpicButton::setImage(QImage &&image) {
size * cIntRetinaFactor(), size * cIntRetinaFactor(),
Qt::IgnoreAspectRatio, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation); 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()); _userpic.setDevicePixelRatio(cRetinaFactor());
_userpicCustom = _userpicHasImage = true; _userpicCustom = _userpicHasImage = true;
_result = std::move(image); _result = std::move(image);