[Option][GUI] Profile pic rounding

This commit is contained in:
Eric Kotato 2022-08-30 14:24:47 +03:00 committed by Eric Kotato
parent 6995a8baf4
commit 596b3d5594
45 changed files with 854 additions and 81 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -80,6 +80,12 @@
"ktg_settings_recent_stickers_limit_none": "Recent stickers: hide all",
"ktg_settings_filters": "Folders",
"ktg_settings_messages": "Messages",
"ktg_settings_userpic_rounding": "Profile pictures rounding",
"ktg_settings_userpic_rounding_none": "Square",
"ktg_settings_userpic_rounding_small": "Small",
"ktg_settings_userpic_rounding_big": "Big",
"ktg_settings_userpic_rounding_full": "Circle",
"ktg_settings_userpic_rounding_desc": "You'll need to restart app to save changes.",
"ktg_settings_chat_id": "Chat ID in profile",
"ktg_settings_chat_id_desc": "You can choose desired format here.\n\nTelegram API uses IDs as-is, but Bot API adds minus in the beginning for groups, and -100 for channels and supergroups to fit it in one field.\n\nIf you have profile panel opened, re-open it to see changes.",
"ktg_settings_chat_id_disable": "Hide",

View file

@ -345,13 +345,15 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
if (_photo) {
if (const auto image = _photo->image(Data::PhotoSize::Small)) {
const auto size = st::confirmInvitePhotoSize;
auto source = [=] {
const auto size = st::confirmInvitePhotoSize;
const auto roundOption = KotatoImageRoundOption();
return image->pix(size, size, { .options = roundOption });
}();
p.drawPixmap(
(width() - size) / 2,
(width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop,
image->pix(
{ size, size },
{ .options = Images::Option::RoundCircle }));
source);
}
} else if (_photoEmpty) {
_photoEmpty->paint(

View file

@ -277,7 +277,24 @@ void PaintFilterChatsTypeIcon(
auto hq = PainterHighQualityEnabler(p);
p.setBrush(color->b);
p.setPen(Qt::NoPen);
p.drawEllipse(rect);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(rect, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(rect,
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(rect,
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(rect);
}
icon.paintInCenter(p, rect);
}

View file

@ -769,7 +769,24 @@ void PeerListRow::paintDisabledCheckUserpic(
p.setPen(userpicBorderPen);
p.setBrush(Qt::NoBrush);
p.drawEllipse(userpicEllipse);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(userpicEllipse, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(userpicEllipse,
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(userpicEllipse,
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(userpicEllipse);
}
p.setPen(iconBorderPen);
p.setBrush(st.disabledCheckFg);

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "calls/calls_top_bar.h"
#include "kotato/kotato_settings.h"
#include "ui/effects/cross_line.h"
#include "ui/paint/blobs_linear.h"
#include "ui/widgets/buttons.h"
@ -253,7 +254,8 @@ TopBar::TopBar(
: std::make_unique<Ui::GroupCallUserpics>(
st::groupCallTopBarUserpics,
rpl::single(true),
[=] { updateUserpics(); }))
[=] { updateUserpics(); },
::Kotato::JsonSettings::GetInt("userpic_corner_type")))
, _durationLabel(_call
? object_ptr<Ui::LabelSimple>(this, st::callBarLabel)
: object_ptr<Ui::LabelSimple>(nullptr))

View file

@ -16,8 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo_media.h"
#include "data/data_file_origin.h"
#include "ui/empty_userpic.h"
#include "ui/rect_part.h"
#include "apiwrap.h" // requestFullPeer.
#include "styles/style_calls.h"
#include "styles/style_widgets.h"
namespace Calls {
namespace {
@ -104,7 +106,25 @@ void Userpic::paint() {
_mutePosition.y() - _muteSize / 2,
_muteSize,
_muteSize);
p.drawEllipse(rect);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(rect, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(rect,
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(rect,
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(rect);
}
st::callMutedPeerIcon.paintInCenter(p, rect);
}
}
@ -180,13 +200,10 @@ void Userpic::createCache(Image *image) {
height = qMax((height * real) / width, 1);
width = real;
}
_userPhoto = image->pixNoCache(
{ width, height },
{
.options = Images::Option::RoundCircle,
.outer = { size, size },
});
_userPhoto.setDevicePixelRatio(cRetinaFactor());
const auto roundOption = KotatoImageRoundOption();
_userPhoto = image->pix(size, size, {
.options = roundOption,
.outer = { size, size }});
} else {
auto filled = QImage(
QSize(real, real),

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "mainwidget.h"
#include "styles/style_dialogs.h"
#include "styles/style_widgets.h"
namespace Data {
namespace {
@ -252,7 +253,24 @@ void Folder::paintUserpic(
p.setBrush(overrideBg ? *overrideBg : st::historyPeerArchiveUserpicBg);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(x, y, size, size);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{ x, y, size, size }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{ x, y, size, size },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{ x, y, size, size },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(x, y, size, size);
}
}
if (size == st::dialogsPhotoSize) {
const auto rect = QRect{ x, y, size, size };

View file

@ -271,6 +271,30 @@ void PeerData::paintUserpic(
int x,
int y,
int size) const {
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
paintUserpicSquare(p, view, x, y, size);
break;
case ImageRoundRadius::Small:
paintUserpicRounded(p, view, x, y, size);
break;
case ImageRoundRadius::Large:
paintUserpicRoundedLarge(p, view, x, y, size);
break;
default:
paintUserpicCircled(p, view, x, y, size);
}
}
void PeerData::paintUserpicCircled(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
const auto circled = Images::Option::RoundCircle;
p.drawPixmap(
@ -282,6 +306,47 @@ void PeerData::paintUserpic(
}
}
void PeerData::paintUserpicRoundedLarge(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
const auto rounded = Images::Option::RoundLarge;
p.drawPixmap(x, y, userpic->pix(size, size, { .options = rounded }));
} else {
ensureEmptyUserpic()->paintRoundedLarge(p, x, y, x + size + x, size);
}
}
void PeerData::paintUserpicRounded(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
const auto rounded = Images::Option::RoundSmall;
p.drawPixmap(x, y, userpic->pix(size, size, { .options = rounded }));
} else {
ensureEmptyUserpic()->paintRounded(p, x, y, x + size + x, size);
}
}
void PeerData::paintUserpicSquare(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pix(size, size));
} else {
ensureEmptyUserpic()->paintSquare(p, x, y, x + size + x, size);
}
}
void PeerData::loadUserpic() {
_userpic.load(&session(), userpicOrigin());
}
@ -336,7 +401,7 @@ QPixmap PeerData::genUserpic(
std::shared_ptr<Data::CloudImageView> &view,
int size) const {
if (const auto userpic = currentUserpic(view)) {
const auto circle = Images::Option::RoundCircle;
const auto circle = KotatoImageRoundOption();
return userpic->pix(size, size, { .options = circle });
}
const auto ratio = style::DevicePixelRatio();
@ -355,7 +420,7 @@ 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, KotatoImageRoundRadius());
}
QImage PeerData::generateUserpicImage(
@ -365,6 +430,8 @@ QImage PeerData::generateUserpicImage(
if (const auto userpic = currentUserpic(view)) {
const auto options = (radius == ImageRoundRadius::Ellipse)
? Images::Option::RoundCircle
: (radius == ImageRoundRadius::Large)
? Images::Option::RoundLarge
: (radius == ImageRoundRadius::None)
? Images::Option()
: Images::Option::RoundSmall;
@ -380,6 +447,8 @@ QImage PeerData::generateUserpicImage(
Painter p(&result);
if (radius == ImageRoundRadius::Ellipse) {
ensureEmptyUserpic()->paint(p, 0, 0, size, size);
} else if (radius == ImageRoundRadius::Large) {
ensureEmptyUserpic()->paintRoundedLarge(p, 0, 0, size, size);
} else if (radius == ImageRoundRadius::None) {
ensureEmptyUserpic()->paintSquare(p, 0, 0, size, size);
} else {

View file

@ -274,6 +274,30 @@ public:
int size) const {
paintUserpic(p, view, rtl() ? (w - x - size) : x, y, size);
}
void paintUserpicCircled(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const;
void paintUserpicRoundedLarge(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const;
void paintUserpicRounded(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const;
void paintUserpicSquare(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const;
void loadUserpic();
[[nodiscard]] bool hasUserpic() const;
[[nodiscard]] std::shared_ptr<Data::CloudImageView> activeUserpicView();

View file

@ -469,7 +469,7 @@ bool ChannelHasActiveCall(not_null<ChannelData*> channel) {
rpl::producer<QImage> PeerUserpicImageValue(
not_null<PeerData*> peer,
int size) {
return PeerUserpicImageValue(peer, size, ImageRoundRadius::Ellipse);
return PeerUserpicImageValue(peer, size, KotatoImageRoundRadius());
}
rpl::producer<QImage> PeerUserpicImageValue(

View file

@ -282,8 +282,12 @@ void Row::PaintCornerBadgeFrame(
? st::dialogsOnlineBadgeFgActive
: st::dialogsOnlineBadgeFg);
q.drawEllipse(QRectF(
st::dialogsPhotoSize - skip.x() - size,
st::dialogsPhotoSize - skip.y() - size,
st::dialogsPhotoSize - size -
(KotatoImageRoundRadius() == ImageRoundRadius::Ellipse
? skip.x() : -(stroke / 2)),
st::dialogsPhotoSize - size -
(KotatoImageRoundRadius() == ImageRoundRadius::Ellipse
? skip.y() : -(stroke / 2)),
size,
size
).marginsRemoved({ shrink, shrink, shrink, shrink }));
@ -358,12 +362,17 @@ void Row::paintUserpic(
: st::dialogsBg;
const auto size = st::dialogsCallBadgeSize;
const auto skip = st::dialogsCallBadgeSkip;
const auto stroke = st::dialogsOnlineBadgeStroke;
p.setOpacity(shown);
p.translate(st::dialogsPadding);
actionPainter->paintSpeaking(
p,
st::dialogsPhotoSize - skip.x() - size,
st::dialogsPhotoSize - skip.y() - size,
st::dialogsPhotoSize - size -
(KotatoImageRoundRadius() == ImageRoundRadius::Ellipse
? skip.x() : -(stroke / 2)),
st::dialogsPhotoSize - size -
(KotatoImageRoundRadius() == ImageRoundRadius::Ellipse
? skip.y() : -(stroke / 2)),
fullWidth,
bg,
now);

View file

@ -2668,7 +2668,7 @@ void HistoryWidget::refreshSendAsToggle() {
} else if (_sendAs) {
return;
}
_sendAs.create(this, st::sendAsButton);
_sendAs.create(this, st::sendAsButton, ::Kotato::JsonSettings::GetInt("userpic_corner_type"));
Ui::SetupSendAsButton(_sendAs.data(), controller());
}
@ -6660,7 +6660,8 @@ void HistoryWidget::setupGroupCallBar() {
HistoryView::GroupCallBarContentByPeer(
peer,
st::historyGroupCallUserpics.size),
Core::App().appDeactivatedValue());
Core::App().appDeactivatedValue(),
::Kotato::JsonSettings::GetInt("userpic_corner_type"));
controller()->adaptive().oneColumnValue(
) | rpl::start_with_next([=](bool one) {
@ -6711,7 +6712,8 @@ void HistoryWidget::setupRequestsBar() {
this,
HistoryView::RequestsBarContentByPeer(
peer,
st::historyRequestsUserpics.size));
st::historyRequestsUserpics.size),
::Kotato::JsonSettings::GetInt("userpic_corner_type"));
controller()->adaptive().oneColumnValue(
) | rpl::start_with_next([=](bool one) {

View file

@ -2245,7 +2245,8 @@ bool ComposeControls::updateSendAsButton() {
}
_sendAs = std::make_unique<Ui::SendAsButton>(
_wrap.get(),
st::sendAsButton);
st::sendAsButton,
::Kotato::JsonSettings::GetInt("userpic_corner_type"));
Ui::SetupSendAsButton(
_sendAs.get(),
rpl::single(peer.get()),

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_context_menu.h"
#include "kotato/kotato_settings.h"
#include "api/api_attached_stickers.h"
#include "api/api_editing.h"
#include "api/api_polls.h"
@ -1164,7 +1165,8 @@ void AddWhoReactedAction(
menu.get(),
Api::WhoReacted(item, context, st::defaultWhoRead, whoReadIds),
participantChosen,
showAllChosen));
showAllChosen,
::Kotato::JsonSettings::GetInt("userpic_corner_type")));
}
void ShowWhoReactedMenu(

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "calls/calls_instance.h"
#include "core/application.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
namespace HistoryView {
@ -57,7 +58,24 @@ void GenerateUserpicsInRow(
q.setCompositionMode(QPainter::CompositionMode_Source);
q.setBrush(Qt::NoBrush);
q.setPen(pen);
q.drawEllipse(x, 0, single, single);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
q.drawRoundedRect(QRect{ x, 0, single, single }, 0, 0);
break;
case ImageRoundRadius::Small:
q.drawRoundedRect(QRect{ x, 0, single, single },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
q.drawRoundedRect(QRect{ x, 0, single, single },
st::dateRadius, st::dateRadius);
break;
default:
q.drawEllipse(x, 0, single, single);
}
x -= single - shift;
}
}

View file

@ -188,7 +188,25 @@ void Contact::draw(Painter &p, const PaintContext &context) const {
PainterHighQualityEnabler hq(p);
p.setBrush(p.textPalette().selectOverlay);
p.setPen(Qt::NoPen);
p.drawEllipse(rthumb);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(rthumb, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(rthumb,
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(rthumb,
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(rthumb);
}
}
bool over = ClickHandler::showAsActive(_linkl);

View file

@ -894,7 +894,24 @@ void Poll::paintRecentVoters(
p.setPen(pen);
p.setBrush(Qt::NoBrush);
PainterHighQualityEnabler hq(p);
p.drawEllipse(x, y, size, size);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{ x, y, size, size }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{ x, y, size, size },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{ x, y, size, size },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(x, y, size, size);
}
};
if (usesBubblePattern(context)) {
const auto add = st::lineWidth * 2;

View file

@ -363,6 +363,10 @@ const std::map<QString, Definition, std::greater<QString>> DefinitionMap {
.type = SettingType::IntSetting,
.defaultValue = 20,
.limitHandler = IntLimit(0, 200, 20), }},
{ "userpic_corner_type", {
.type = SettingType::IntSetting,
.defaultValue = 3,
.limitHandler = IntLimit(0, 3, 3), }},
};
using OldOptionKey = QString;

View file

@ -66,6 +66,26 @@ QString NetBoostLabel(int boost) {
return QString();
}
QString UserpicRoundingLabel(int rounding) {
switch (rounding) {
case 0:
return ktr("ktg_settings_userpic_rounding_none");
case 1:
return ktr("ktg_settings_userpic_rounding_small");
case 2:
return ktr("ktg_settings_userpic_rounding_big");
case 3:
return ktr("ktg_settings_userpic_rounding_full");
default:
Unexpected("Rounding in Settings::UserpicRoundingLabel.");
}
return QString();
}
QString ChatIdLabel(int option) {
switch (option) {
case 0:
@ -176,6 +196,38 @@ void SetupKotatoChats(
Ui::show(Box<FontsBox>());
});
const auto userpicCornerButton = container->add(
object_ptr<Button>(
container,
rktr("ktg_settings_userpic_rounding"),
st::settingsButtonNoIcon));
auto userpicCornerText = rpl::single(
UserpicRoundingLabel(::Kotato::JsonSettings::GetIntWithPending("userpic_corner_type"))
) | rpl::then(
::Kotato::JsonSettings::EventsWithPending(
"userpic_corner_type"
) | rpl::map([] {
return UserpicRoundingLabel(::Kotato::JsonSettings::GetIntWithPending("userpic_corner_type"));
})
);
CreateRightLabel(
userpicCornerButton,
std::move(userpicCornerText),
st::settingsButtonNoIcon,
rktr("ktg_settings_userpic_rounding"));
userpicCornerButton->addClickHandler([=] {
Ui::show(Box<::Kotato::RadioBox>(
ktr("ktg_settings_userpic_rounding"),
ktr("ktg_settings_userpic_rounding_desc"),
::Kotato::JsonSettings::GetIntWithPending("userpic_corner_type"),
4,
UserpicRoundingLabel,
[=] (int value) {
::Kotato::JsonSettings::SetAfterRestart("userpic_corner_type", value);
::Kotato::JsonSettings::Write();
}, true));
});
AddSkip(container);
AddDivider(container);

View file

@ -55,6 +55,7 @@ namespace {
[[nodiscard]] std::wstring NotificationTemplate(
QString id,
Window::Notifications::Manager::DisplayOptions options) {
const auto crop = (KotatoImageRoundRadius() == ImageRoundRadius::Ellipse) ? L"circle" : L"none";
const auto wid = id.replace('&', "&amp;").toStdWString();
const auto fastReply = LR"(
<input id="fastReply" type="text" placeHolderContent=""/>
@ -77,7 +78,7 @@ namespace {
<toast launch="action=open&amp;)" + wid + LR"(">
<visual>
<binding template="ToastGeneric">
<image placement="appLogoOverride" hint-crop="circle" src=""/>
<image placement="appLogoOverride" hint-crop=")" + crop + LR"( src=""/>
<text hint-maxLines="1"></text>
<text></text>
<text></text>

View file

@ -572,6 +572,24 @@ historyBubbleTailInRightSelected: icon {{ "bubble_tail-flip_horizontal", msgInBg
historyBubbleTailOutRight: icon {{ "bubble_tail-flip_horizontal", msgOutBg }};
historyBubbleTailOutRightSelected: icon {{ "bubble_tail-flip_horizontal", msgOutBgSelected }};
historyBubbleTail1InLeft: icon {{ "bubble_tail1", msgInBg }};
historyBubbleTail1InLeftSelected: icon {{ "bubble_tail1", msgInBgSelected }};
historyBubbleTail1OutLeft: icon {{ "bubble_tail1", msgOutBg }};
historyBubbleTail1OutLeftSelected: icon {{ "bubble_tail1", msgOutBgSelected }};
historyBubbleTail1InRight: icon {{ "bubble_tail1-flip_horizontal", msgInBg }};
historyBubbleTail1InRightSelected: icon {{ "bubble_tail1-flip_horizontal", msgInBgSelected }};
historyBubbleTail1OutRight: icon {{ "bubble_tail1-flip_horizontal", msgOutBg }};
historyBubbleTail1OutRightSelected: icon {{ "bubble_tail1-flip_horizontal", msgOutBgSelected }};
historyBubbleTail2InLeft: icon {{ "bubble_tail2", msgInBg }};
historyBubbleTail2InLeftSelected: icon {{ "bubble_tail2", msgInBgSelected }};
historyBubbleTail2OutLeft: icon {{ "bubble_tail2", msgOutBg }};
historyBubbleTail2OutLeftSelected: icon {{ "bubble_tail2", msgOutBgSelected }};
historyBubbleTail2InRight: icon {{ "bubble_tail2-flip_horizontal", msgInBg }};
historyBubbleTail2InRightSelected: icon {{ "bubble_tail2-flip_horizontal", msgInBgSelected }};
historyBubbleTail2OutRight: icon {{ "bubble_tail2-flip_horizontal", msgOutBg }};
historyBubbleTail2OutRightSelected: icon {{ "bubble_tail2-flip_horizontal", msgOutBgSelected }};
historyPeerUserpicFont: semiboldFont;
historyPsaIconIn: icon {{ "message_psa_tooltip", msgFileThumbLinkInFg }};

View file

@ -104,14 +104,16 @@ void GroupCallScheduledLeft::update() {
GroupCallBar::GroupCallBar(
not_null<QWidget*> parent,
rpl::producer<GroupCallBarContent> content,
rpl::producer<bool> &&hideBlobs)
rpl::producer<bool> &&hideBlobs,
int userpicsRadius)
: _wrap(parent, object_ptr<RpWidget>(parent))
, _inner(_wrap.entity())
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget()))
, _userpics(std::make_unique<GroupCallUserpics>(
st::historyGroupCallUserpics,
std::move(hideBlobs),
[=] { updateUserpics(); })) {
[=] { updateUserpics(); },
userpicsRadius)) {
_wrap.hide(anim::type::instant);
_shadow->hide();

View file

@ -63,7 +63,8 @@ public:
GroupCallBar(
not_null<QWidget*> parent,
rpl::producer<GroupCallBarContent> content,
rpl::producer<bool> &&hideBlobs);
rpl::producer<bool> &&hideBlobs,
int userpicsRadius);
~GroupCallBar();
void show();

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/paint/blobs.h"
#include "base/random.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
namespace Ui {
namespace {
@ -81,10 +82,12 @@ struct GroupCallUserpics::Userpic {
GroupCallUserpics::GroupCallUserpics(
const style::GroupCallUserpics &st,
rpl::producer<bool> &&hideBlobs,
Fn<void()> repaint)
Fn<void()> repaint,
int userpicRadius)
: _st(st)
, _randomSpeakingTimer([=] { sendRandomLevels(); })
, _repaint(std::move(repaint)) {
, _repaint(std::move(repaint))
, _userpicRadius(userpicRadius) {
const auto limit = kMaxUserpics;
const auto single = _st.size;
const auto shift = _st.shift;
@ -270,7 +273,20 @@ 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);
switch (_userpicRadius) {
case 0:
p.drawRoundedRect(skip - size + shift, skip, size, size, 0, 0);
break;
case 1:
p.drawRoundedRect(skip - size + shift, skip, size, size, st::buttonRadius, st::buttonRadius);
break;
case 2:
p.drawRoundedRect(skip - size + shift, skip, size, size, st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(skip - size + shift, skip, size, size);
}
}
}
}

View file

@ -27,7 +27,8 @@ public:
GroupCallUserpics(
const style::GroupCallUserpics &st,
rpl::producer<bool> &&hideBlobs,
Fn<void()> repaint);
Fn<void()> repaint,
int userpicRadius);
~GroupCallUserpics();
void update(
@ -63,6 +64,7 @@ private:
int _maxWidth = 0;
bool _skipLevelUpdate = false;
crl::time _speakingAnimationHideLastTime = 0;
int _userpicRadius = 3;
rpl::variable<int> _width;

View file

@ -22,14 +22,16 @@ namespace Ui {
RequestsBar::RequestsBar(
not_null<QWidget*> parent,
rpl::producer<RequestsBarContent> content)
rpl::producer<RequestsBarContent> content,
int userpicRadius)
: _wrap(parent, object_ptr<RpWidget>(parent))
, _inner(_wrap.entity())
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget()))
, _userpics(std::make_unique<GroupCallUserpics>(
st::historyRequestsUserpics,
rpl::single(false),
[=] { _inner->update(); })) {
[=] { _inner->update(); },
userpicRadius)) {
_wrap.hide(anim::type::instant);
_shadow->hide();

View file

@ -33,7 +33,8 @@ class RequestsBar final {
public:
RequestsBar(
not_null<QWidget*> parent,
rpl::producer<RequestsBarContent> content);
rpl::producer<RequestsBarContent> content,
int userpicRadius);
~RequestsBar();
void show();

View file

@ -6,6 +6,7 @@ For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/controls/peer_list_dummy.h"
#include "ui/image/image.h"
#include "styles/style_widgets.h"
@ -34,11 +35,39 @@ void PeerListDummy::paintEvent(QPaintEvent *e) {
p.setPen(Qt::NoPen);
for (auto i = from; i != till; ++i) {
p.setBrush(st::windowBgOver);
p.drawEllipse(
_st.item.photoPosition.x(),
_st.item.photoPosition.y(),
_st.item.photoSize,
_st.item.photoSize);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{
_st.item.photoPosition.x(),
_st.item.photoPosition.y(),
_st.item.photoSize,
_st.item.photoSize }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{
_st.item.photoPosition.x(),
_st.item.photoPosition.y(),
_st.item.photoSize,
_st.item.photoSize },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{
_st.item.photoPosition.x(),
_st.item.photoPosition.y(),
_st.item.photoSize,
_st.item.photoSize },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(_st.item.photoPosition.x(),
_st.item.photoPosition.y(),
_st.item.photoSize,
_st.item.photoSize);
}
const auto small = int(1.5 * _st.item.photoSize);
const auto large = 2 * small;

View file

@ -12,9 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
SendAsButton::SendAsButton(QWidget *parent, const style::SendAsButton &st)
SendAsButton::SendAsButton(QWidget *parent, const style::SendAsButton &st, int radius)
: AbstractButton(parent)
, _st(st) {
, _st(st)
, _radius(radius) {
resize(_st.width, _st.height);
}
@ -52,7 +53,28 @@ void SendAsButton::paintEvent(QPaintEvent *e) {
p.setBrush(_st.activeBg);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(left, top, _st.size, _st.size);
switch (_radius) {
case 0:
p.drawRoundedRect(
left, top, _st.size, _st.size,
0, 0);
break;
case 1:
p.drawRoundedRect(
left, top, _st.size, _st.size,
st::buttonRadius, st::buttonRadius);
break;
case 2:
p.drawRoundedRect(
left, top, _st.size, _st.size,
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(left, top, _st.size, _st.size);
}
}
CrossAnimation::paint(

View file

@ -18,7 +18,7 @@ namespace Ui {
class SendAsButton final : public AbstractButton {
public:
SendAsButton(QWidget *parent, const style::SendAsButton &st);
SendAsButton(QWidget *parent, const style::SendAsButton &st, int radius);
void setUserpic(QImage userpic);
@ -33,6 +33,7 @@ private:
bool _active = false;
QImage _userpic;
int _radius;
};

View file

@ -80,7 +80,8 @@ public:
not_null<PopupMenu*> parentMenu,
rpl::producer<WhoReadContent> content,
Fn<void(uint64)> participantChosen,
Fn<void()> showAllChosen);
Fn<void()> showAllChosen,
int userpicsRadius);
bool isEnabled() const override;
not_null<QAction*> action() const override;
@ -144,7 +145,8 @@ Action::Action(
not_null<PopupMenu*> parentMenu,
rpl::producer<WhoReadContent> content,
Fn<void(uint64)> participantChosen,
Fn<void()> showAllChosen)
Fn<void()> showAllChosen,
int userpicsRadius)
: ItemBase(parentMenu->menu(), parentMenu->menu()->st())
, _parentMenu(parentMenu)
, _dummyAction(CreateChild<QAction>(parentMenu->menu().get()))
@ -153,7 +155,8 @@ Action::Action(
, _userpics(std::make_unique<GroupCallUserpics>(
st::defaultWhoRead.userpics,
rpl::never<bool>(),
[=] { update(); }))
[=] { update(); },
userpicsRadius))
, _st(parentMenu->menu()->st())
, _submenu(_participantChosen, _showAllChosen)
, _height(st::defaultWhoRead.itemPadding.top()
@ -586,12 +589,14 @@ base::unique_qptr<Menu::ItemBase> WhoReactedContextAction(
not_null<PopupMenu*> menu,
rpl::producer<WhoReadContent> content,
Fn<void(uint64)> participantChosen,
Fn<void()> showAllChosen) {
Fn<void()> showAllChosen,
int userpicsRadius) {
return base::make_unique_q<Action>(
menu,
std::move(content),
std::move(participantChosen),
std::move(showAllChosen));
std::move(showAllChosen),
userpicsRadius);
}
WhoReactedListMenu::WhoReactedListMenu(

View file

@ -50,7 +50,8 @@ struct WhoReadContent {
not_null<PopupMenu*> menu,
rpl::producer<WhoReadContent> content,
Fn<void(uint64)> participantChosen,
Fn<void()> showAllChosen);
Fn<void()> showAllChosen,
int userpicsRadius);
class WhoReactedListMenu final {
public:

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/effects/round_checkbox.h"
#include "ui/image/image.h"
#include "ui/rp_widget.h"
#include "ui/ui_utility.h"
@ -389,7 +390,25 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
_fgOverride ? (*_fgOverride) : _st.selectFg->b,
_st.selectWidth);
p.setPen(pen);
p.drawEllipse(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth));
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth),
0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth),
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth),
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth));
}
p.setOpacity(1.);
}
if (_st.check.size > 0) {

View file

@ -222,8 +222,29 @@ void EmptyUserpic::paint(
int y,
int outerWidth,
int size) const {
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
paintSquare(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Small:
paintRounded(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Large:
paintRoundedLarge(p, x, y, outerWidth, size);
break;
default:
paint(p, x, y, outerWidth, size, [&p, x, y, size] {
p.drawEllipse(x, y, size, size);
});
}
}
void EmptyUserpic::paintRoundedLarge(Painter &p, int x, int y, int outerWidth, int size) const {
paint(p, x, y, outerWidth, size, [&p, x, y, size] {
p.drawEllipse(x, y, size, size);
p.drawRoundedRect(x, y, size, size, st::dateRadius, st::dateRadius);
});
}
@ -245,9 +266,35 @@ void EmptyUserpic::PaintSavedMessages(
int y,
int outerWidth,
int size) {
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
PaintSavedMessagesSquared(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Small:
PaintSavedMessagesRounded(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Large:
PaintSavedMessagesRoundedLarge(p, x, y, outerWidth, size);
break;
default:
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintSavedMessages(p, x, y, outerWidth, size, bg, fg);
}
}
void EmptyUserpic::PaintSavedMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size) {
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintSavedMessages(p, x, y, outerWidth, size, bg, fg);
PaintSavedMessagesRoundedLarge(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintSavedMessagesRounded(
@ -261,6 +308,17 @@ void EmptyUserpic::PaintSavedMessagesRounded(
PaintSavedMessagesRounded(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintSavedMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size) {
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintSavedMessagesSquared(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintSavedMessages(
Painter &p,
int x,
@ -269,12 +327,45 @@ void EmptyUserpic::PaintSavedMessages(
int size,
const style::color &bg,
const style::color &fg) {
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
PaintSavedMessagesSquared(p, x, y, outerWidth, size, bg, fg);
break;
case ImageRoundRadius::Small:
PaintSavedMessagesRounded(p, x, y, outerWidth, size, bg, fg);
break;
case ImageRoundRadius::Large:
PaintSavedMessagesRoundedLarge(p, x, y, outerWidth, size, bg, fg);
break;
default:
x = rtl() ? (outerWidth - x - size) : x;
PainterHighQualityEnabler hq(p);
p.setBrush(bg);
p.setPen(Qt::NoPen);
p.drawEllipse(x, y, size, size);
PaintSavedMessagesInner(p, x, y, size, fg);
}
}
void EmptyUserpic::PaintSavedMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg) {
x = rtl() ? (outerWidth - x - size) : x;
PainterHighQualityEnabler hq(p);
p.setBrush(bg);
p.setPen(Qt::NoPen);
p.drawEllipse(x, y, size, size);
p.drawRoundedRect(x, y, size, size, st::dateRadius, st::dateRadius);
PaintSavedMessagesInner(p, x, y, size, fg);
}
@ -297,6 +388,24 @@ void EmptyUserpic::PaintSavedMessagesRounded(
PaintSavedMessagesInner(p, x, y, size, fg);
}
void EmptyUserpic::PaintSavedMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg) {
x = rtl() ? (outerWidth - x - size) : x;
PainterHighQualityEnabler hq(p);
p.setBrush(bg);
p.setPen(Qt::NoPen);
p.drawRoundedRect(x, y, size, size, 0, 0);
PaintSavedMessagesInner(p, x, y, size, fg);
}
QPixmap EmptyUserpic::GenerateSavedMessages(int size) {
return Generate(size, [&](Painter &p) {
PaintSavedMessages(p, 0, 0, size, size);
@ -315,9 +424,35 @@ void EmptyUserpic::PaintRepliesMessages(
int y,
int outerWidth,
int size) {
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
PaintRepliesMessagesSquared(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Small:
PaintRepliesMessagesRounded(p, x, y, outerWidth, size);
break;
case ImageRoundRadius::Large:
PaintRepliesMessagesRoundedLarge(p, x, y, outerWidth, size);
break;
default:
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintRepliesMessages(p, x, y, outerWidth, size, bg, fg);
}
}
void EmptyUserpic::PaintRepliesMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size) {
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintRepliesMessages(p, x, y, outerWidth, size, bg, fg);
PaintRepliesMessagesRoundedLarge(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintRepliesMessagesRounded(
@ -331,6 +466,17 @@ void EmptyUserpic::PaintRepliesMessagesRounded(
PaintRepliesMessagesRounded(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintRepliesMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size) {
const auto &bg = st::historyPeerSavedMessagesBg;
const auto &fg = st::historyPeerUserpicFg;
PaintRepliesMessagesSquared(p, x, y, outerWidth, size, bg, fg);
}
void EmptyUserpic::PaintRepliesMessages(
Painter &p,
int x,
@ -349,6 +495,24 @@ void EmptyUserpic::PaintRepliesMessages(
PaintRepliesMessagesInner(p, x, y, size, fg);
}
void EmptyUserpic::PaintRepliesMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg) {
x = rtl() ? (outerWidth - x - size) : x;
PainterHighQualityEnabler hq(p);
p.setBrush(bg);
p.setPen(Qt::NoPen);
p.drawRoundedRect(x, y, size, size, st::dateRadius, st::dateRadius);
PaintRepliesMessagesInner(p, x, y, size, fg);
}
void EmptyUserpic::PaintRepliesMessagesRounded(
Painter &p,
int x,
@ -367,6 +531,24 @@ void EmptyUserpic::PaintRepliesMessagesRounded(
PaintRepliesMessagesInner(p, x, y, size, fg);
}
void EmptyUserpic::PaintRepliesMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg) {
x = rtl() ? (outerWidth - x - size) : x;
PainterHighQualityEnabler hq(p);
p.setBrush(bg);
p.setPen(Qt::NoPen);
p.drawRoundedRect(x, y, size, size, 0, 0);
PaintRepliesMessagesInner(p, x, y, size, fg);
}
QPixmap EmptyUserpic::GenerateRepliesMessages(int size) {
return Generate(size, [&](Painter &p) {
PaintRepliesMessages(p, 0, 0, size, size);

View file

@ -21,6 +21,12 @@ public:
int y,
int outerWidth,
int size) const;
void paintRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size) const;
void paintRounded(
Painter &p,
int x,
@ -42,12 +48,24 @@ public:
int y,
int outerWidth,
int size);
static void PaintSavedMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintSavedMessagesRounded(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintSavedMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintSavedMessages(
Painter &p,
int x,
@ -56,6 +74,14 @@ public:
int size,
const style::color &bg,
const style::color &fg);
static void PaintSavedMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg);
static void PaintSavedMessagesRounded(
Painter &p,
int x,
@ -64,6 +90,14 @@ public:
int size,
const style::color &bg,
const style::color &fg);
static void PaintSavedMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg);
static QPixmap GenerateSavedMessages(int size);
static QPixmap GenerateSavedMessagesRounded(int size);
@ -73,12 +107,24 @@ public:
int y,
int outerWidth,
int size);
static void PaintRepliesMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintRepliesMessagesRounded(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintRepliesMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size);
static void PaintRepliesMessages(
Painter &p,
int x,
@ -87,6 +133,14 @@ public:
int size,
const style::color &bg,
const style::color &fg);
static void PaintRepliesMessagesRoundedLarge(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg);
static void PaintRepliesMessagesRounded(
Painter &p,
int x,
@ -95,6 +149,14 @@ public:
int size,
const style::color &bg,
const style::color &fg);
static void PaintRepliesMessagesSquared(
Painter &p,
int x,
int y,
int outerWidth,
int size,
const style::color &bg,
const style::color &fg);
static QPixmap GenerateRepliesMessages(int size);
static QPixmap GenerateRepliesMessagesRounded(int size);

View file

@ -7,11 +7,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/image/image.h"
#include "kotato/kotato_settings.h"
#include "storage/cache/storage_cache_database.h"
#include "data/data_session.h"
#include "main/main_session.h"
#include "ui/ui_utility.h"
ImageRoundRadius KotatoImageRoundRadius() {
switch (::Kotato::JsonSettings::GetInt("userpic_corner_type")) {
case 0: return ImageRoundRadius::None;
case 1: return ImageRoundRadius::Small;
case 2: return ImageRoundRadius::Large;
default: return ImageRoundRadius::Ellipse;
}
}
Images::Option KotatoImageRoundOption() {
switch (::Kotato::JsonSettings::GetInt("userpic_corner_type")) {
case 0: return Images::Option::None;
case 1: return Images::Option::RoundSmall;
case 2: return Images::Option::RoundLarge;
default: return Images::Option::RoundCircle;
}
}
using namespace Images;
namespace Images {

View file

@ -9,6 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h"
ImageRoundRadius KotatoImageRoundRadius();
Images::Option KotatoImageRoundOption();
class QPainterPath;
namespace Images {

View file

@ -395,11 +395,24 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
p.setBrush(_userpicHasImage
? st::msgDateImgBg
: _st.changeButton.textBgOver);
p.drawEllipse(
photoLeft,
photoTop,
_st.photoSize,
_st.photoSize);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(photoLeft, photoTop, _st.photoSize, _st.photoSize);
}
}
paintRipple(
p,
@ -441,11 +454,24 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(_st.uploadBg);
p.drawEllipse(
photoLeft,
photoTop,
_st.photoSize,
_st.photoSize);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{ photoLeft, photoTop, _st.photoSize, _st.photoSize },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(photoLeft, photoTop, _st.photoSize, _st.photoSize);
}
}
auto iconLeft = (_st.uploadIconPosition.x() < 0)
? (_st.photoSize - _st.uploadIcon.width()) / 2
@ -477,7 +503,7 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) {
auto size = QSize{ _st.photoSize, _st.photoSize };
request.outer = size * cIntRetinaFactor();
request.resize = size * cIntRetinaFactor();
request.radius = ImageRoundRadius::Ellipse;
request.radius = KotatoImageRoundRadius();
p.drawImage(QRect(photoPosition, size), _streamed->frame(request));
if (!paused) {
_streamed->markFrameShown();
@ -498,9 +524,21 @@ QPoint UserpicButton::countPhotoPosition() const {
}
QImage UserpicButton::prepareRippleMask() const {
return Ui::RippleAnimation::ellipseMask(QSize(
_st.photoSize,
_st.photoSize));
const auto size = QSize(_st.photoSize, _st.photoSize);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
return Ui::RippleAnimation::rectMask(size);
case ImageRoundRadius::Small:
return Ui::RippleAnimation::roundRectMask(size, st::buttonRadius);
case ImageRoundRadius::Large:
return Ui::RippleAnimation::roundRectMask(size, st::dateRadius);
default:
return Ui::RippleAnimation::ellipseMask(size);
}
}
QPoint UserpicButton::prepareRippleStartPosition() const {
@ -774,7 +812,9 @@ void UserpicButton::setImage(QImage &&image) {
size * cIntRetinaFactor(),
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
_userpic = Ui::PixmapFromImage(Images::Circle(std::move(small)));
small = Images::Round(std::move(small), KotatoImageRoundRadius());
_userpic = Ui::PixmapFromImage(std::move(small));
_userpic.setDevicePixelRatio(cRetinaFactor());
_userpicCustom = _userpicHasImage = true;
_result = std::move(image);
@ -791,7 +831,24 @@ void UserpicButton::prepareUserpicPixmap() {
PainterHighQualityEnabler hq(p);
p.setBrush(color);
p.setPen(Qt::NoPen);
p.drawEllipse(0, 0, size, size);
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(QRect{ 0, 0, size, size }, 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(QRect{ 0, 0, size, size },
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(QRect{ 0, 0, size, size },
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(0, 0, size, size);
}
};
_userpicHasImage = _peer
? (_peer->currentUserpic(_userpicView) || _role != Role::ChangePhoto)

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/widgets/multi_select.h"
#include "ui/image/image.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/scroll_area.h"
@ -177,6 +178,20 @@ void Item::paintOnce(Painter &p, int x, int y, int outerWidth) {
}
auto radius = _st.height / 2;
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
radius = 0;
break;
case ImageRoundRadius::Small:
radius = st::buttonRadius;
break;
case ImageRoundRadius::Large:
radius = st::dateRadius;
break;
}
auto inner = style::rtlrect(
x + radius,
y,
@ -235,8 +250,28 @@ void Item::paintDeleteButton(
p.setBrush(_color);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(
style::rtlrect(x, y, _st.height, _st.height, outerWidth));
switch (KotatoImageRoundRadius()) {
case ImageRoundRadius::None:
p.drawRoundedRect(
style::rtlrect(x, y, _st.height, _st.height, outerWidth), 0, 0);
break;
case ImageRoundRadius::Small:
p.drawRoundedRect(
style::rtlrect(x, y, _st.height, _st.height, outerWidth),
st::buttonRadius, st::buttonRadius);
break;
case ImageRoundRadius::Large:
p.drawRoundedRect(
style::rtlrect(x, y, _st.height, _st.height, outerWidth),
st::dateRadius, st::dateRadius);
break;
default:
p.drawEllipse(
style::rtlrect(x, y, _st.height, _st.height, outerWidth));
}
}
CrossAnimation::paint(