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) {
_allLoaded = true;
_requestId = 0;
if (error.type() == u"CHANNEL_FORUM_MISSING"_q) {
const auto flags = channel()->flags() & ~ChannelDataFlag::Forum;
channel()->setFlags(flags);
}
}).send();
}

View File

@ -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<Data::CloudImageView> &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<Data::CloudImageView> &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();

View File

@ -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);

View File

@ -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);