mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
feat: avatar corners
This commit is contained in:
@@ -131,6 +131,8 @@ set(ayugram_files
|
||||
ayu/utils/taptic_engine/platform/taptic_engine_mac.h
|
||||
ayu/ui/ayu_logo.cpp
|
||||
ayu/ui/ayu_logo.h
|
||||
ayu/ui/ayu_userpic.cpp
|
||||
ayu/ui/ayu_userpic.h
|
||||
ayu/ui/utils/ayu_profile_values.cpp
|
||||
ayu/ui/utils/ayu_profile_values.h
|
||||
ayu/ui/utils/color_cut_quantizer.cpp
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 53 KiB |
@@ -2,7 +2,7 @@
|
||||
<svg width="126px" height="126px" viewBox="0 0 126 126" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Ava 162 Rexy</title>
|
||||
<defs>
|
||||
<circle id="path-1" cx="63" cy="63" r="63"></circle>
|
||||
<rect id="path-1" x="0" y="0" width="126" height="126"></rect>
|
||||
</defs>
|
||||
<g id="Ava-162-Rexy" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -7709,6 +7709,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_HideNotificationCounters" = "Hide Notification Counters";
|
||||
"ayu_HideNotificationBadge" = "Hide Notification Badge";
|
||||
"ayu_HideNotificationBadgeDescription" = "Hides the notification counter on the app icon in the taskbar and tray.";
|
||||
"ayu_AvatarCorners" = "Avatar Corners";
|
||||
"ayu_AvatarCornersCircle" = "Circle";
|
||||
"ayu_AvatarCornersSquare" = "Square";
|
||||
"ayu_SingleCornerRadius" = "Single Corner Radius";
|
||||
"ayu_SingleCornerRadiusDescription" = "Forums will have the same avatar shape as chats.";
|
||||
"ayu_HideAllChats" = "Hide \"All Chats\" Tab";
|
||||
"ayu_ChannelBottomButton" = "Channel Bottom Button";
|
||||
"ayu_ChannelBottomButtonHide" = "Hide";
|
||||
|
||||
@@ -34,6 +34,7 @@ void initUiSettings() {
|
||||
AyuUiSettings::setMonoFont(settings.monoFont());
|
||||
AyuUiSettings::setWideMultiplier(settings.wideMultiplier());
|
||||
AyuUiSettings::setMaterialSwitches(settings.materialSwitches());
|
||||
AyuUiSettings::setAvatarCorners(settings.avatarCorners());
|
||||
}
|
||||
|
||||
void initDatabase() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "main/main_domain.h"
|
||||
#include "main/main_session.h"
|
||||
#include "rpl/combine.h"
|
||||
#include "ui/ayu_userpic.h"
|
||||
#include "window/window_controller.h"
|
||||
|
||||
#include <fstream>
|
||||
@@ -466,6 +467,7 @@ void AyuSettings::validate() {
|
||||
|
||||
validateRange(_wideMultiplier, 0.5, 4.0, defaults._wideMultiplier);
|
||||
validateRange(_recentStickersCount, 1, 200, defaults._recentStickersCount);
|
||||
validateRange(_avatarCorners, 0, AyuUserpic::kMaxAvatarCorners, defaults._avatarCorners);
|
||||
|
||||
const auto embeddedType = _messageShotSettings._embeddedThemeType.current();
|
||||
auto embeddedTypeValid = (embeddedType == -1) || (embeddedType >= 0 && embeddedType <= 3); // from Window::Theme::EmbeddedType::DayBlue to Window::Theme::EmbeddedType::NightGreen
|
||||
@@ -948,6 +950,20 @@ void AyuSettings::setCrashReporting(bool val) {
|
||||
save();
|
||||
}
|
||||
|
||||
void AyuSettings::setAvatarCorners(int val) {
|
||||
if (_avatarCorners.current() == val) return;
|
||||
_avatarCorners = val;
|
||||
AyuUiSettings::setAvatarCorners(val);
|
||||
save();
|
||||
}
|
||||
|
||||
void AyuSettings::setSingleCornerRadius(bool val) {
|
||||
if (_singleCornerRadius.current() == val) return;
|
||||
_singleCornerRadius = val;
|
||||
repaintApp();
|
||||
save();
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const AyuSettings &s) {
|
||||
std::map<std::string, GhostModeAccountSettings> ghostAccounts;
|
||||
for (const auto &[key, value] : s._ghostAccounts) {
|
||||
@@ -1034,6 +1050,8 @@ void to_json(nlohmann::json &j, const AyuSettings &s) {
|
||||
{"adaptiveCoverColor", s._adaptiveCoverColor.current()},
|
||||
{"improveLinkPreviews", s._improveLinkPreviews.current()},
|
||||
{"crashReporting", s._crashReporting.current()},
|
||||
{"avatarCorners", s._avatarCorners.current()},
|
||||
{"singleCornerRadius", s._singleCornerRadius.current()},
|
||||
{"messageShotSettings", s._messageShotSettings}
|
||||
};
|
||||
}
|
||||
@@ -1128,6 +1146,8 @@ void from_json(const nlohmann::json &j, AyuSettings &s) {
|
||||
s._adaptiveCoverColor = j.value("adaptiveCoverColor", defaults._adaptiveCoverColor.current());
|
||||
s._improveLinkPreviews = j.value("improveLinkPreviews", defaults._improveLinkPreviews.current());
|
||||
s._crashReporting = j.value("crashReporting", defaults._crashReporting.current());
|
||||
s._avatarCorners = j.value("avatarCorners", defaults._avatarCorners.current());
|
||||
s._singleCornerRadius = j.value("singleCornerRadius", defaults._singleCornerRadius.current());
|
||||
|
||||
if (j.contains("messageShotSettings") && j["messageShotSettings"].is_object()) {
|
||||
j["messageShotSettings"].get_to(s._messageShotSettings);
|
||||
|
||||
@@ -302,6 +302,8 @@ public:
|
||||
[[nodiscard]] bool adaptiveCoverColor() const { return _adaptiveCoverColor.current(); }
|
||||
[[nodiscard]] bool improveLinkPreviews() const { return _improveLinkPreviews.current(); }
|
||||
[[nodiscard]] bool crashReporting() const { return _crashReporting.current(); }
|
||||
[[nodiscard]] int avatarCorners() const { return _avatarCorners.current(); }
|
||||
[[nodiscard]] bool singleCornerRadius() const { return _singleCornerRadius.current(); }
|
||||
|
||||
void setSaveDeletedMessages(bool val);
|
||||
void setSaveMessagesHistory(bool val);
|
||||
@@ -379,6 +381,8 @@ public:
|
||||
void setAdaptiveCoverColor(bool val);
|
||||
void setImproveLinkPreviews(bool val);
|
||||
void setCrashReporting(bool val);
|
||||
void setAvatarCorners(int val);
|
||||
void setSingleCornerRadius(bool val);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> useGlobalGhostModeChanges() const { return _useGlobalGhostMode.value(); }
|
||||
[[nodiscard]] rpl::producer<bool> saveDeletedMessagesChanges() const { return _saveDeletedMessages.value(); }
|
||||
@@ -457,6 +461,8 @@ public:
|
||||
[[nodiscard]] rpl::producer<bool> adaptiveCoverColorChanges() const { return _adaptiveCoverColor.value(); }
|
||||
[[nodiscard]] rpl::producer<bool> improveLinkPreviewsChanges() const { return _improveLinkPreviews.value(); }
|
||||
[[nodiscard]] rpl::producer<bool> crashReportingChanges() const { return _crashReporting.value(); }
|
||||
[[nodiscard]] rpl::producer<int> avatarCornersChanges() const { return _avatarCorners.value(); }
|
||||
[[nodiscard]] rpl::producer<bool> singleCornerRadiusChanges() const { return _singleCornerRadius.value(); }
|
||||
|
||||
friend void to_json(nlohmann::json &j, const AyuSettings &s);
|
||||
friend void from_json(const nlohmann::json &j, AyuSettings &s);
|
||||
@@ -543,6 +549,8 @@ private:
|
||||
rpl::variable<bool> _adaptiveCoverColor = true;
|
||||
rpl::variable<bool> _improveLinkPreviews = false;
|
||||
rpl::variable<bool> _crashReporting = true;
|
||||
rpl::variable<int> _avatarCorners = 23;
|
||||
rpl::variable<bool> _singleCornerRadius = false;
|
||||
|
||||
rpl::variable<bool> _useGlobalGhostMode = true;
|
||||
std::map<uint64, std::unique_ptr<GhostModeAccountSettings>> _ghostAccounts;
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
// This is the source code of AyuGram for Desktop.
|
||||
//
|
||||
// We do not and cannot prevent the use of our code,
|
||||
// but be respectful and credit the original author.
|
||||
//
|
||||
// Copyright @Radolyn, 2026
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/ayu_ui_settings.h"
|
||||
#include "media/streaming/media_streaming_common.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/style/style_core.h"
|
||||
|
||||
#include <QRectF>
|
||||
|
||||
namespace AyuUserpic {
|
||||
|
||||
bool ShouldOverrideShape(Ui::PeerUserpicShape shape) {
|
||||
using Shape = Ui::PeerUserpicShape;
|
||||
switch (shape) {
|
||||
case Shape::Circle:
|
||||
case Shape::Auto:
|
||||
return true;
|
||||
case Shape::Monoforum:
|
||||
case Shape::Forum:
|
||||
return AyuSettings::getInstance().singleCornerRadius();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ComputeRadius(int pixelSize) {
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
if (corners >= kMaxAvatarCorners) return pixelSize / 2;
|
||||
if (corners <= 0) return 0;
|
||||
return int(double(corners) / kMaxAvatarCorners * pixelSize / 2.0);
|
||||
}
|
||||
|
||||
double ComputeRadiusF(double size) {
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
if (corners >= kMaxAvatarCorners) return size / 2.0;
|
||||
if (corners <= 0) return 0.0;
|
||||
return double(corners) / kMaxAvatarCorners * size / 2.0;
|
||||
}
|
||||
|
||||
bool IsCircle() {
|
||||
return AyuUiSettings::getAvatarCorners() >= kMaxAvatarCorners;
|
||||
}
|
||||
|
||||
uint8 PackedState() {
|
||||
return uint8(AyuUiSettings::getAvatarCorners() & 0x1F)
|
||||
| (AyuSettings::getInstance().singleCornerRadius() ? 0x20 : 0);
|
||||
}
|
||||
|
||||
void PaintShape(QPainter &p, int x, int y, int size) {
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
if (corners >= kMaxAvatarCorners) {
|
||||
p.drawEllipse(x, y, size, size);
|
||||
} else if (corners <= 0) {
|
||||
p.drawRect(x, y, size, size);
|
||||
} else {
|
||||
const auto r = double(corners) / kMaxAvatarCorners * size / 2.0;
|
||||
p.drawRoundedRect(x, y, size, size, r, r);
|
||||
}
|
||||
}
|
||||
|
||||
void PaintShape(QPainter &p, const QRectF &rect) {
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
if (corners >= kMaxAvatarCorners) {
|
||||
p.drawEllipse(rect);
|
||||
} else if (corners <= 0) {
|
||||
p.drawRect(rect);
|
||||
} else {
|
||||
const auto r = double(corners) / kMaxAvatarCorners
|
||||
* std::min(rect.width(), rect.height()) / 2.0;
|
||||
p.drawRoundedRect(rect, r, r);
|
||||
}
|
||||
}
|
||||
|
||||
QPointF OnlineBadgePosition(int photoSize, double badgeSize) {
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
const auto r = double(corners) / kMaxAvatarCorners * photoSize / 2.0;
|
||||
const auto edge = photoSize - r * (1.0 - std::cos(M_PI / 4.0));
|
||||
const auto pos = std::min(edge - badgeSize / 2.0, photoSize - badgeSize);
|
||||
return QPointF(pos, pos);
|
||||
}
|
||||
|
||||
void ApplyFrameRounding(
|
||||
::Media::Streaming::FrameRequest &request,
|
||||
std::array<QImage, 4> &cornersCache,
|
||||
QImage &ellipseCache,
|
||||
QSize size) {
|
||||
const auto minSide = std::min(size.width(), size.height());
|
||||
const auto r = ComputeRadius(minSide);
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
if (r > 0 && r < minSide / 2) {
|
||||
if (cornersCache[0].width() != r * ratio) {
|
||||
cornersCache = Images::CornersMask(r);
|
||||
}
|
||||
request.rounding = Images::CornersMaskRef(cornersCache);
|
||||
} else if (r >= minSide / 2) {
|
||||
if (ellipseCache.size() != request.outer) {
|
||||
ellipseCache = Images::EllipseMask(size);
|
||||
}
|
||||
request.mask = ellipseCache;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AyuUserpic
|
||||
@@ -0,0 +1,35 @@
|
||||
// This is the source code of AyuGram for Desktop.
|
||||
//
|
||||
// We do not and cannot prevent the use of our code,
|
||||
// but be respectful and credit the original author.
|
||||
//
|
||||
// Copyright @Radolyn, 2026
|
||||
#pragma once
|
||||
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Media::Streaming { struct FrameRequest; }
|
||||
|
||||
namespace AyuUserpic {
|
||||
|
||||
inline constexpr int kMaxAvatarCorners = 23;
|
||||
|
||||
[[nodiscard]] bool ShouldOverrideShape(Ui::PeerUserpicShape shape);
|
||||
[[nodiscard]] int ComputeRadius(int pixelSize);
|
||||
[[nodiscard]] double ComputeRadiusF(double size);
|
||||
[[nodiscard]] bool IsCircle();
|
||||
|
||||
[[nodiscard]] uint8 PackedState();
|
||||
|
||||
void PaintShape(QPainter &p, int x, int y, int size);
|
||||
void PaintShape(QPainter &p, const QRectF &rect);
|
||||
|
||||
[[nodiscard]] QPointF OnlineBadgePosition(int photoSize, double badgeSize);
|
||||
|
||||
void ApplyFrameRounding(
|
||||
::Media::Streaming::FrameRequest &request,
|
||||
std::array<QImage, 4> &cornersCache,
|
||||
QImage &ellipseCache,
|
||||
QSize size);
|
||||
|
||||
} // namespace AyuUserpic
|
||||
@@ -183,18 +183,20 @@ void AyuSectionBuilder::addSlider(SliderArgs &&args) {
|
||||
_builder.add([&](const Builder::BuildContext &ctx) {
|
||||
v::match(ctx, [&](const Builder::WidgetContext &wctx) {
|
||||
const auto container = wctx.container;
|
||||
container->add(
|
||||
object_ptr<Button>(container,
|
||||
std::move(args.title),
|
||||
st::settingsButtonNoIcon)
|
||||
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
if (args.showTitle) {
|
||||
container->add(
|
||||
object_ptr<Button>(container,
|
||||
std::move(args.title),
|
||||
st::settingsButtonNoIcon)
|
||||
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
}
|
||||
|
||||
auto sliderWithLabel = MakeSliderWithLabel(
|
||||
container,
|
||||
st::autoDownloadLimitSlider,
|
||||
st::settingsScaleLabel,
|
||||
0,
|
||||
st::settingsScaleLabel.style.font->width("8%%%"));
|
||||
args.showTitle ? st::settingsScaleLabel.style.font->width("8%%%") : 0);
|
||||
container->add(
|
||||
std::move(sliderWithLabel.widget),
|
||||
st::recentStickersLimitPadding);
|
||||
@@ -233,7 +235,7 @@ void AyuSectionBuilder::addSlider(SliderArgs &&args) {
|
||||
}
|
||||
});
|
||||
}, [&](const Builder::SearchContext &sctx) {
|
||||
if (!id.isEmpty()) {
|
||||
if (!id.isEmpty() && args.showTitle) {
|
||||
sctx.entries->push_back({
|
||||
.id = id,
|
||||
.title = resolvedTitle,
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
struct SliderArgs {
|
||||
QString id;
|
||||
rpl::producer<QString> title;
|
||||
bool showTitle = true;
|
||||
int steps;
|
||||
int current;
|
||||
Fn<int(int)> indexToValue;
|
||||
|
||||
@@ -7,21 +7,39 @@
|
||||
#include "settings_appearance.h"
|
||||
|
||||
#include "lang_auto.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/ayu_ui_settings.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
#include "ayu/ui/boxes/font_selector.h"
|
||||
#include "ayu/ui/components/icon_picker.h"
|
||||
#include "ayu/ui/settings/ayu_builder.h"
|
||||
#include "ayu/ui/settings/settings_main.h"
|
||||
#include "core/application.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_peer_id.h"
|
||||
#include "data/data_session.h"
|
||||
#include "inline_bots/bot_attach_web_view.h"
|
||||
#include "main/main_session.h"
|
||||
#include "settings/settings_builder.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "styles/style_ayu_icons.h"
|
||||
#include "styles/style_ayu_styles.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_session_controller_link_info.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
@@ -78,6 +96,246 @@ void BuildAppIcon(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||
#endif
|
||||
}
|
||||
|
||||
class AvatarCornersPreview final : public Ui::RpWidget {
|
||||
public:
|
||||
AvatarCornersPreview(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _emptyUserpic(
|
||||
Ui::EmptyUserpic::UserpicColor(
|
||||
Data::DecideColorIndex(
|
||||
peerFromChannel(ChannelId(2331068091)))),
|
||||
u"AyuGram Releases"_q) {
|
||||
const auto &row = st::defaultDialogRow;
|
||||
setFixedHeight(row.height);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
resolveChannel();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override {
|
||||
auto p = Painter(this);
|
||||
|
||||
const auto &row = st::defaultDialogRow;
|
||||
const auto photoSize = row.photoSize;
|
||||
const auto xShift = st::settingsButtonNoIcon.padding.left()
|
||||
- row.padding.left();
|
||||
const auto userpicX = row.padding.left() + xShift;
|
||||
const auto userpicY = (height() - photoSize) / 2;
|
||||
|
||||
p.fillRect(rect(), st::windowBg);
|
||||
|
||||
if (_ripple) {
|
||||
_ripple->paint(p, 0, 0, width());
|
||||
if (_ripple->empty()) {
|
||||
_ripple.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (_peer) {
|
||||
_peer->paintUserpicLeft(
|
||||
p, _userpicView, userpicX, userpicY, width(), photoSize);
|
||||
} else {
|
||||
_emptyUserpic.paintCircle(p, userpicX, userpicY, width(), photoSize);
|
||||
}
|
||||
|
||||
const auto nameText = u"AyuGram Releases"_q;
|
||||
p.setPen(st::dialogsNameFg);
|
||||
p.setFont(st::semiboldFont);
|
||||
p.drawText(row.nameLeft + xShift, row.nameTop + st::semiboldFont->ascent, nameText);
|
||||
|
||||
const auto nameWidth = st::semiboldFont->width(nameText);
|
||||
const auto &badge = st::dialogsExteraOfficialIcon.icon;
|
||||
badge.paint(p, row.nameLeft + xShift + nameWidth, row.nameTop, width());
|
||||
|
||||
p.setPen(st::dialogsTextFg);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.drawText(row.textLeft + xShift, row.textTop + st::dialogsTextFont->ascent, u"Better late than never"_q);
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override {
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
if (!_ripple) {
|
||||
auto mask = Ui::RippleAnimation::RectMask(size());
|
||||
_ripple = std::make_unique<Ui::RippleAnimation>(
|
||||
st::defaultRippleAnimation,
|
||||
std::move(mask),
|
||||
[=] { update(); });
|
||||
}
|
||||
_ripple->add(e->pos());
|
||||
}
|
||||
}
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *e) override {
|
||||
if (_ripple) {
|
||||
_ripple->lastStop();
|
||||
}
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
_controller->showPeerByLink(Window::PeerByLinkInfo{
|
||||
.usernameOrId = u"AyuGramReleases"_q,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void resolveChannel() {
|
||||
const auto session = &_controller->session();
|
||||
_peer = session->data().peerByUsername(u"AyuGramReleases"_q);
|
||||
if (_peer) {
|
||||
_peer->loadUserpic();
|
||||
subscribeToUpdates();
|
||||
return;
|
||||
}
|
||||
const auto weak = base::make_weak(this);
|
||||
session->api().request(MTPcontacts_ResolveUsername(
|
||||
MTP_flags(0),
|
||||
MTP_string(u"AyuGramReleases"_q),
|
||||
MTP_string()
|
||||
)).done([=](const MTPcontacts_ResolvedPeer &result) {
|
||||
if (const auto strong = weak.get()) {
|
||||
session->data().processUsers(result.data().vusers());
|
||||
session->data().processChats(result.data().vchats());
|
||||
strong->_peer = session->data().peerLoaded(
|
||||
peerFromMTP(result.data().vpeer()));
|
||||
if (strong->_peer) {
|
||||
strong->_peer->loadUserpic();
|
||||
strong->subscribeToUpdates();
|
||||
}
|
||||
strong->update();
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void subscribeToUpdates() {
|
||||
if (!_peer) return;
|
||||
_peer->session().downloaderTaskFinished(
|
||||
) | rpl::on_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
Ui::EmptyUserpic _emptyUserpic;
|
||||
PeerData *_peer = nullptr;
|
||||
Ui::PeerUserpicView _userpicView;
|
||||
std::unique_ptr<Ui::RippleAnimation> _ripple;
|
||||
};
|
||||
|
||||
void BuildAvatarCorners(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||
auto *settings = &AyuSettings::getInstance();
|
||||
const auto controller = builder.controller();
|
||||
|
||||
const auto mapRadius = [](int val)
|
||||
{
|
||||
if (val == 0) {
|
||||
return tr::ayu_AvatarCornersSquare(tr::now);
|
||||
} else if (val == AyuUserpic::kMaxAvatarCorners) {
|
||||
return tr::ayu_AvatarCornersCircle(tr::now);
|
||||
}
|
||||
return QString::number(val);
|
||||
};
|
||||
|
||||
builder.add([=](const WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||
const auto container = ctx.container;
|
||||
auto title = object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
tr::ayu_AvatarCorners(),
|
||||
st::defaultSubsectionTitle);
|
||||
const auto titleRaw = title.data();
|
||||
|
||||
const auto badge = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
container,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
settings->avatarCornersChanges() | rpl::map(mapRadius),
|
||||
st::settingsPremiumNewBadge),
|
||||
st::ayuBetaBadgePadding);
|
||||
badge->show();
|
||||
badge->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
badge->paintRequest() | rpl::on_next([=] {
|
||||
auto p = QPainter(badge);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::windowBgActive);
|
||||
const auto r = st::ayuBetaBadgePadding.left();
|
||||
p.drawRoundedRect(badge->rect(), r, r);
|
||||
}, badge->lifetime());
|
||||
|
||||
titleRaw->geometryValue() | rpl::on_next([=](QRect geometry) {
|
||||
badge->moveToLeft(
|
||||
geometry.x()
|
||||
+ titleRaw->textMaxWidth()
|
||||
+ st::settingsPremiumNewBadgePosition.x(),
|
||||
geometry.y()
|
||||
+ (geometry.height() - badge->height()) / 2);
|
||||
}, badge->lifetime());
|
||||
|
||||
return {
|
||||
.widget = std::move(title),
|
||||
.margin = st::defaultSubsectionTitlePadding,
|
||||
};
|
||||
}, [] {
|
||||
return SearchEntry{
|
||||
.id = u"ayu/avatarCorners"_q,
|
||||
.title = tr::ayu_AvatarCorners(tr::now),
|
||||
.keywords = { u"avatar"_q, u"corners"_q, u"radius"_q },
|
||||
};
|
||||
});
|
||||
|
||||
auto *previewRaw = static_cast<AvatarCornersPreview*>(nullptr);
|
||||
builder.add([&](const Builder::WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||
auto preview = object_ptr<AvatarCornersPreview>(
|
||||
ctx.container,
|
||||
controller);
|
||||
previewRaw = preview.data();
|
||||
const auto vMargin = st::settingsButtonNoIcon.padding
|
||||
- st::defaultDialogRow.padding;
|
||||
return {
|
||||
.widget = std::move(preview),
|
||||
.margin = QMargins(0, vMargin.top(), 0, vMargin.bottom()),
|
||||
};
|
||||
});
|
||||
|
||||
ayu.addSlider({
|
||||
.id = u"ayu/avatarCornersSlider"_q,
|
||||
.title = rpl::single(QString()),
|
||||
.showTitle = false,
|
||||
.steps = AyuUserpic::kMaxAvatarCorners + 1,
|
||||
.current = settings->avatarCorners(),
|
||||
.onChanged = [=](int val) {
|
||||
AyuSettings::getInstance().setAvatarCorners(val);
|
||||
if (previewRaw) {
|
||||
previewRaw->update();
|
||||
}
|
||||
},
|
||||
.onFinalChanged = [=](int val) {
|
||||
AyuSettings::getInstance().setAvatarCorners(val);
|
||||
crl::on_main([=] {
|
||||
controller->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_settings_need_restart(),
|
||||
.confirmed = [] { Core::Restart(); },
|
||||
.confirmText = tr::lng_settings_restart_now(),
|
||||
.cancelText = tr::lng_settings_restart_later(),
|
||||
}));
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
ayu.addSettingToggle({
|
||||
.id = u"ayu/singleCornerRadius"_q,
|
||||
.title = tr::ayu_SingleCornerRadius(),
|
||||
.getter = &AyuSettings::singleCornerRadius,
|
||||
.setter = &AyuSettings::setSingleCornerRadius,
|
||||
.keywords = { u"single"_q, u"corner"_q, u"radius"_q },
|
||||
});
|
||||
|
||||
builder.addSkip();
|
||||
builder.addDividerText(tr::ayu_SingleCornerRadiusDescription());
|
||||
builder.addSkip();
|
||||
}
|
||||
|
||||
void BuildAppearance(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||
auto *settings = &AyuSettings::getInstance();
|
||||
|
||||
@@ -296,6 +554,7 @@ const auto kMeta = BuildHelper({
|
||||
|
||||
builder.addSkip();
|
||||
BuildAppIcon(builder, ayu);
|
||||
BuildAvatarCorners(builder, ayu);
|
||||
BuildAppearance(builder, ayu);
|
||||
BuildChatFolders(builder, ayu);
|
||||
BuildTrayElements(builder, ayu);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "lang_auto.h"
|
||||
#include "settings_ayu_utils.h"
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
#include "ayu/ui/settings/ayu_builder.h"
|
||||
#include "ayu/ui/settings/settings_main.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
@@ -181,7 +182,7 @@ private:
|
||||
});
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(gradient);
|
||||
p.drawEllipse(rect);
|
||||
AyuUserpic::PaintShape(p, rect);
|
||||
}
|
||||
{
|
||||
const auto fontsize = (photoSize * 13) / 33;
|
||||
|
||||
@@ -25,6 +25,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using Flag = Data::ChatFilter::Flag;
|
||||
@@ -371,7 +375,7 @@ void PaintFilterChatsTypeIcon(
|
||||
bg.setStops({ { 0., color1->c }, { 1., color2->c } });
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(rect);
|
||||
AyuUserpic::PaintShape(p, rect);
|
||||
icon.paintInCenter(p, rect);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
// AyuGram includes
|
||||
#include "styles/style_ayu_icons.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
[[nodiscard]] PeerListRowId UniqueRowIdFromString(const QString &d) {
|
||||
@@ -956,7 +957,7 @@ void PeerListRow::paintDisabledCheckUserpic(
|
||||
* Ui::ForumUserpicRadiusMultiplier();
|
||||
p.drawRoundedRect(userpicEllipse, radius, radius);
|
||||
} else {
|
||||
p.drawEllipse(userpicEllipse);
|
||||
AyuUserpic::PaintShape(p, userpicEllipse);
|
||||
}
|
||||
|
||||
p.setPen(iconBorderPen);
|
||||
|
||||
@@ -29,6 +29,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwidget.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Data {
|
||||
namespace {
|
||||
|
||||
@@ -269,7 +273,7 @@ void Folder::paintUserpic(
|
||||
p.setBrush(overrideBg ? *overrideBg : st::historyPeerArchiveUserpicBg);
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
}
|
||||
if (size == st::defaultDialogRow.photoSize) {
|
||||
const auto rect = QRect{ x, y, size, size };
|
||||
|
||||
@@ -54,6 +54,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kUpdateFullPeerTimeout = crl::time(5000); // Not more than once in 5 seconds.
|
||||
@@ -484,6 +488,14 @@ QImage PeerData::GenerateUserpicImage(
|
||||
Ui::PeerUserpicView &view,
|
||||
int size,
|
||||
std::optional<int> radius) {
|
||||
if (!radius) {
|
||||
const auto shape = peer->isForum()
|
||||
? Ui::PeerUserpicShape::Forum
|
||||
: Ui::PeerUserpicShape::Circle;
|
||||
if (AyuUserpic::ShouldOverrideShape(shape)) {
|
||||
radius = AyuUserpic::ComputeRadius(size);
|
||||
}
|
||||
}
|
||||
if (const auto userpic = peer->userpicCloudImage(view)) {
|
||||
auto image = userpic->scaled(
|
||||
{ size, size },
|
||||
|
||||
@@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Dialogs {
|
||||
@@ -482,8 +483,11 @@ void Row::PaintCornerBadgeFrame(
|
||||
}
|
||||
}
|
||||
if (peer && (peer->forum() || peer->monoforum())) {
|
||||
const auto radius = context.st->photoSize
|
||||
* Ui::ForumUserpicRadiusMultiplier();
|
||||
const auto &settings = AyuSettings::getInstance();
|
||||
const auto singleRadius = settings.singleCornerRadius();
|
||||
const auto radius = singleRadius
|
||||
? AyuUserpic::ComputeRadiusF(context.st->photoSize)
|
||||
: (context.st->photoSize * Ui::ForumUserpicRadiusMultiplier());
|
||||
Ui::PaintOutlineSegments(q, outline, radius, segments);
|
||||
} else {
|
||||
Ui::PaintOutlineSegments(q, outline, segments);
|
||||
@@ -549,9 +553,10 @@ void Row::PaintCornerBadgeFrame(
|
||||
q.setBrush(data->active
|
||||
? st::dialogsOnlineBadgeFgActive
|
||||
: st::dialogsOnlineBadgeFg);
|
||||
const auto badge = AyuUserpic::OnlineBadgePosition(photoSize, size);
|
||||
q.drawEllipse(QRectF(
|
||||
photoSize - skip.x() - size,
|
||||
photoSize - skip.y() - size,
|
||||
badge.x(),
|
||||
badge.y(),
|
||||
size,
|
||||
size
|
||||
).marginsRemoved({ shrink, shrink, shrink, shrink }));
|
||||
|
||||
@@ -29,6 +29,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "base/debug_log.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Dialogs::Stories {
|
||||
namespace {
|
||||
|
||||
@@ -590,7 +594,7 @@ void List::paint(
|
||||
p.setPen(QPen(gradient, line));
|
||||
}
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawEllipse(outer);
|
||||
AyuUserpic::PaintShape(p, outer);
|
||||
} else {
|
||||
validateSegments(itemFull, gradient, line, true);
|
||||
Ui::PaintOutlineSegments(
|
||||
@@ -635,7 +639,7 @@ void List::paint(
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::transparent);
|
||||
p.drawEllipse(rect);
|
||||
AyuUserpic::PaintShape(p, rect);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
}
|
||||
if (hasReadLine) {
|
||||
|
||||
@@ -101,7 +101,7 @@ Media::Clip::FrameRequest VideoUserpic::request(int size) const {
|
||||
.frame = { size, size },
|
||||
.outer = { size, size },
|
||||
.factor = style::DevicePixelRatio(),
|
||||
.radius = ImageRoundRadius::Ellipse,
|
||||
.radius = ImageRoundRadius::AyuUserpic,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
struct TopPeersStrip::Entry {
|
||||
@@ -837,9 +841,10 @@ void TopPeersStrip::paintUserpic(
|
||||
pen.setWidthF(stroke * online);
|
||||
q.setPen(pen);
|
||||
q.setBrush(st::dialogsOnlineBadgeFg);
|
||||
const auto badge = AyuUserpic::OnlineBadgePosition(size, onlineSize);
|
||||
q.drawEllipse(QRectF(
|
||||
size - skip.x() - onlineSize,
|
||||
size - skip.y() - onlineSize,
|
||||
badge.x(),
|
||||
badge.y(),
|
||||
onlineSize,
|
||||
onlineSize
|
||||
).marginsRemoved({ shrink, shrink, shrink, shrink }));
|
||||
|
||||
@@ -22,6 +22,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
void GenerateUserpicsInRow(
|
||||
@@ -60,7 +64,7 @@ void GenerateUserpicsInRow(
|
||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
q.setBrush(Qt::NoBrush);
|
||||
q.setPen(pen);
|
||||
q.drawEllipse(x, 0, single, single);
|
||||
AyuUserpic::PaintShape(q, QRectF(x, 0, single, single));
|
||||
x -= single - shift;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
// AyuGran includes
|
||||
// AyuGram includes
|
||||
#include "ayu/features/message_shot/message_shot.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace HistoryView {
|
||||
@@ -471,13 +472,18 @@ void Photo::validateUserpicImageCache(QSize size, bool forum) const {
|
||||
args = args.blurred();
|
||||
}
|
||||
original = Images::Prepare(std::move(original), size * ratio, args);
|
||||
if (forumValue) {
|
||||
const auto shape = forumValue
|
||||
? Ui::PeerUserpicShape::Forum
|
||||
: Ui::PeerUserpicShape::Circle;
|
||||
if (AyuUserpic::ShouldOverrideShape(shape)) {
|
||||
original = Images::Round(
|
||||
std::move(original),
|
||||
ImageRoundRadius::AyuUserpic);
|
||||
} else {
|
||||
original = Images::Round(
|
||||
std::move(original),
|
||||
Images::CornersMask(std::min(size.width(), size.height())
|
||||
* Ui::ForumUserpicRadiusMultiplier()));
|
||||
} else {
|
||||
original = Images::Circle(std::move(original));
|
||||
}
|
||||
_imageCache = std::move(original);
|
||||
_imageCacheForum = forumValue;
|
||||
@@ -565,7 +571,16 @@ void Photo::paintUserpicFrame(
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
auto request = ::Media::Streaming::FrameRequest();
|
||||
request.outer = request.resize = size * ratio;
|
||||
if (forum) {
|
||||
const auto shape = forum
|
||||
? Ui::PeerUserpicShape::Forum
|
||||
: Ui::PeerUserpicShape::Circle;
|
||||
if (AyuUserpic::ShouldOverrideShape(shape)) {
|
||||
AyuUserpic::ApplyFrameRounding(
|
||||
request,
|
||||
_streamed->roundingCorners,
|
||||
_streamed->roundingMask,
|
||||
size);
|
||||
} else if (forum) {
|
||||
const auto radius = int(std::min(size.width(), size.height())
|
||||
* Ui::ForumUserpicRadiusMultiplier());
|
||||
if (_streamed->roundingCorners[0].width() != radius * ratio) {
|
||||
|
||||
@@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
// AyuGram includes
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/features/message_shot/message_shot.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace HistoryView::Reactions {
|
||||
@@ -680,7 +681,7 @@ void InlineList::paintSingleBg(
|
||||
float64 opacity) const {
|
||||
p.setOpacity(opacity);
|
||||
if (!areTags()) {
|
||||
const auto radius = fill.height() / 2.;
|
||||
const auto radius = AyuUserpic::ComputeRadiusF(fill.height());
|
||||
p.setBrush(color);
|
||||
p.drawRoundedRect(fill, radius, radius);
|
||||
return;
|
||||
|
||||
@@ -26,6 +26,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace HistoryView::Reactions {
|
||||
namespace {
|
||||
|
||||
@@ -633,7 +637,7 @@ void Manager::paintButton(
|
||||
if (expanded) {
|
||||
q->fillRect(QRect(QPoint(), size), context.st->windowBg());
|
||||
} else {
|
||||
const auto radius = _inner.height() / 2.;
|
||||
const auto radius = AyuUserpic::ComputeRadiusF(_inner.height());
|
||||
const auto frame = _cachedRound.validateFrame(
|
||||
frameIndex,
|
||||
scale,
|
||||
@@ -706,8 +710,8 @@ void Manager::paintButton(
|
||||
}
|
||||
|
||||
if (expanded) {
|
||||
const auto radiusMin = _inner.height() / 2.;
|
||||
const auto radiusMax = _inner.width() / 2.;
|
||||
const auto radiusMin = AyuUserpic::ComputeRadiusF(_inner.height());
|
||||
const auto radiusMax = AyuUserpic::ComputeRadiusF(_inner.width());
|
||||
_cachedRound.overlayExpandedBorder(
|
||||
*q,
|
||||
size,
|
||||
|
||||
@@ -43,6 +43,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_premium.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ayu_ui_settings.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Info::PeerGifts {
|
||||
namespace {
|
||||
|
||||
@@ -817,7 +822,9 @@ void GiftButton::paint(QPainter &p, float64 craftProgress) {
|
||||
_userpic->subscribeToUpdates([=] { update(); });
|
||||
}
|
||||
const auto image = _userpic->image(st::giftBoxUserpicSize);
|
||||
const auto skip = st::giftBoxUserpicSkip;
|
||||
const auto corners = AyuUiSettings::getAvatarCorners();
|
||||
const auto extraSkip = int(double(AyuUserpic::kMaxAvatarCorners - corners) / AyuUserpic::kMaxAvatarCorners * 6.0);
|
||||
const auto skip = st::giftBoxUserpicSkip + extraSkip;
|
||||
p.drawImage(extend.left() + skip, extend.top() + skip, image);
|
||||
} else if (_check) {
|
||||
const auto skip = st::giftBoxUserpicSkip;
|
||||
|
||||
@@ -70,6 +70,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtCore/QBuffer>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Settings {
|
||||
namespace {
|
||||
|
||||
@@ -797,7 +801,7 @@ void SetupAccountsWrap(
|
||||
pen.setWidthF(line);
|
||||
p.setPen(pen);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawEllipse(rect);
|
||||
AyuUserpic::PaintShape(p, rect);
|
||||
}
|
||||
}, state->userpic.lifetime());
|
||||
|
||||
|
||||
@@ -59,6 +59,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtGui/QScreen>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Settings {
|
||||
|
||||
using ChangeType = Window::Notifications::ChangeType;
|
||||
@@ -372,7 +376,7 @@ void NotificationsCount::prepareNotificationSampleSmall() {
|
||||
auto padding = height / 8;
|
||||
auto userpicSize = height - 2 * padding;
|
||||
p.setBrush(st::notificationSampleUserpicFg);
|
||||
p.drawEllipse(style::rtlrect(padding, padding, userpicSize, userpicSize, width));
|
||||
AyuUserpic::PaintShape(p, QRectF(style::rtlrect(padding, padding, userpicSize, userpicSize, width)));
|
||||
|
||||
auto rowLeft = height;
|
||||
auto rowHeight = padding;
|
||||
@@ -729,7 +733,13 @@ void NotifyPreview::paint(Painter &p, int x, int y) {
|
||||
QSize{ st::notifyPreviewUserpicSize, st::notifyPreviewUserpicSize });
|
||||
|
||||
if (_nameShown) {
|
||||
const auto r = AyuUserpic::ComputeRadiusF(userpic.width());
|
||||
auto clip = QPainterPath();
|
||||
clip.addRoundedRect(QRectF(userpic), r, r);
|
||||
p.save();
|
||||
p.setClipPath(clip);
|
||||
_userpic.render(&p, QRectF(userpic));
|
||||
p.restore();
|
||||
} else {
|
||||
p.drawImage(userpic.topLeft(), _logo);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
|
||||
int _oldCount;
|
||||
|
||||
std::vector<SampleWidget*> _cornerSamples[4];
|
||||
std::vector<SampleWidget*> _cornerSamples[5];
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1182,7 +1182,7 @@ object_ptr<Ui::RpWidget> ProfilePhotoPrivacyController::setupMiddleWidget(
|
||||
Qt::SmoothTransformation);
|
||||
result = Images::Round(
|
||||
std::move(result),
|
||||
ImageRoundRadius::Ellipse);
|
||||
ImageRoundRadius::AyuUserpic);
|
||||
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
(local ? localPhoto : photo) = std::move(result);
|
||||
if (local) {
|
||||
|
||||
@@ -31,6 +31,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Settings {
|
||||
namespace {
|
||||
|
||||
@@ -745,10 +749,19 @@ void Preview::validateUserpicCache() {
|
||||
|| _userpic.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
_userpicImage = Images::Circle(_userpicOriginal.scaled(
|
||||
auto scaled = _userpicOriginal.scaled(
|
||||
_userpic.size() * _ratio,
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation));
|
||||
Qt::SmoothTransformation);
|
||||
if (AyuUserpic::IsCircle()) {
|
||||
_userpicImage = Images::Circle(std::move(scaled));
|
||||
} else {
|
||||
const auto r = AyuUserpic::ComputeRadius(
|
||||
std::min(scaled.width(), scaled.height()));
|
||||
_userpicImage = Images::Round(
|
||||
std::move(scaled),
|
||||
Images::CornersMask(r));
|
||||
}
|
||||
_userpicImage.setDevicePixelRatio(_ratio);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -273,7 +277,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);
|
||||
AyuUserpic::PaintShape(p, QRectF(skip - size + shift, skip, size, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -144,7 +148,7 @@ void SetupSubButtonBackground(
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(st::boxBg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(background->rect());
|
||||
AyuUserpic::PaintShape(p, QRectF(background->rect()));
|
||||
}, background->lifetime());
|
||||
|
||||
upload->positionValue(
|
||||
@@ -674,7 +678,14 @@ 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 (_shape == PeerUserpicShape::Monoforum) {
|
||||
const auto ayuOverride = AyuUserpic::ShouldOverrideShape(_shape);
|
||||
if (ayuOverride) {
|
||||
AyuUserpic::ApplyFrameRounding(
|
||||
request,
|
||||
_roundingCorners,
|
||||
_ellipseMask,
|
||||
size);
|
||||
} else if (_shape == PeerUserpicShape::Monoforum) {
|
||||
} else if (useForumShape()) {
|
||||
const auto radius = int(_st.photoSize
|
||||
* Ui::ForumUserpicRadiusMultiplier());
|
||||
@@ -1067,7 +1078,11 @@ void UserpicButton::showCustom(QImage &&image) {
|
||||
size * style::DevicePixelRatio(),
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
_userpic = Ui::PixmapFromImage(useForumShape()
|
||||
const auto ayuOverride = AyuUserpic::ShouldOverrideShape(_shape);
|
||||
_userpic = Ui::PixmapFromImage(
|
||||
ayuOverride
|
||||
? Images::Round(std::move(small), ImageRoundRadius::AyuUserpic)
|
||||
: useForumShape()
|
||||
? Images::Round(
|
||||
std::move(small),
|
||||
Images::CornersMask(_st.photoSize
|
||||
@@ -1121,7 +1136,10 @@ void UserpicButton::fillShape(QPainter &p, QBrush brush) const {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(brush);
|
||||
const auto size = _st.photoSize;
|
||||
if (useForumShape()) {
|
||||
const auto ayuOverride = AyuUserpic::ShouldOverrideShape(_shape);
|
||||
if (ayuOverride) {
|
||||
AyuUserpic::PaintShape(p, 0, 0, size);
|
||||
} else if (useForumShape()) {
|
||||
const auto radius = size * Ui::ForumUserpicRadiusMultiplier();
|
||||
p.drawRoundedRect(0, 0, size, size, radius, radius);
|
||||
} else {
|
||||
@@ -1157,12 +1175,19 @@ void UserpicButton::prepareUserpicPixmap() {
|
||||
QSize(size, size) * ratio,
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
image = useForumShape()
|
||||
? Images::Round(
|
||||
const auto ayuNP = AyuUserpic::ShouldOverrideShape(_shape);
|
||||
if (ayuNP) {
|
||||
image = Images::Round(
|
||||
std::move(image),
|
||||
ImageRoundRadius::AyuUserpic);
|
||||
} else if (useForumShape()) {
|
||||
image = Images::Round(
|
||||
std::move(image),
|
||||
Images::CornersMask(size
|
||||
* Ui::ForumUserpicRadiusMultiplier()))
|
||||
: Images::Circle(std::move(image));
|
||||
* Ui::ForumUserpicRadiusMultiplier()));
|
||||
} else {
|
||||
image = Images::Circle(std::move(image));
|
||||
}
|
||||
image.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
p.drawImage(0, 0, image);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Lang {
|
||||
namespace {
|
||||
|
||||
@@ -825,11 +829,11 @@ void WhoReactedEntryAction::paint(Painter &&p) {
|
||||
auto bgPen = bg->p;
|
||||
bgPen.setWidthF(st::lineWidth * 6.);
|
||||
p.setPen(bgPen);
|
||||
p.drawEllipse(photoLeft, photoTop, photoSize, photoSize);
|
||||
AyuUserpic::PaintShape(p, photoLeft, photoTop, photoSize);
|
||||
auto fgPen = st::windowBgActive->p;
|
||||
fgPen.setWidthF(st::lineWidth * 2.);
|
||||
p.setPen(fgPen);
|
||||
p.drawEllipse(photoLeft, photoTop, photoSize, photoSize);
|
||||
AyuUserpic::PaintShape(p, photoLeft, photoTop, photoSize);
|
||||
}
|
||||
} else if (!_custom) {
|
||||
st::menuIconReactions.paintInCenter(
|
||||
|
||||
@@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/effects/outline_segments.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
|
||||
void PaintOutlineSegments(
|
||||
@@ -16,6 +20,12 @@ void PaintOutlineSegments(
|
||||
float64 fromFullProgress) {
|
||||
Expects(!segments.empty());
|
||||
|
||||
if (!AyuUserpic::IsCircle()) {
|
||||
const auto r = AyuUserpic::ComputeRadiusF(std::min(ellipse.width(), ellipse.height()));
|
||||
PaintOutlineSegments(p, ellipse, r, segments);
|
||||
return;
|
||||
}
|
||||
|
||||
p.setBrush(Qt::NoBrush);
|
||||
const auto count = std::min(int(segments.size()), kOutlineSegmentsMax);
|
||||
if (count == 1) {
|
||||
|
||||
@@ -18,6 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -459,7 +463,7 @@ void RoundImageCheckbox::paintFrame(
|
||||
segments ? _segments.front().width : _st.selectWidth);
|
||||
p.setPen(pen);
|
||||
if (!radius) {
|
||||
p.drawEllipse(outline);
|
||||
AyuUserpic::PaintShape(p, outline);
|
||||
} else {
|
||||
p.drawRoundedRect(outline, *radius, *radius);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtSvg/QSvgRenderer>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -340,7 +345,7 @@ void EmptyUserpic::paintCircle(
|
||||
int outerWidth,
|
||||
int size) const {
|
||||
paint(p, x, y, outerWidth, size, [&] {
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -352,7 +357,11 @@ void EmptyUserpic::paintRounded(
|
||||
int size,
|
||||
int radius) const {
|
||||
paint(p, x, y, outerWidth, size, [&] {
|
||||
p.drawRoundedRect(x, y, size, size, radius, radius);
|
||||
if (AyuSettings::getInstance().singleCornerRadius()) {
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
} else {
|
||||
p.drawRoundedRect(x, y, size, size, radius, radius);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -363,7 +372,7 @@ void EmptyUserpic::paintSquare(
|
||||
int outerWidth,
|
||||
int size) const {
|
||||
paint(p, x, y, outerWidth, size, [&] {
|
||||
p.fillRect(x, y, size, size, p.brush());
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -374,7 +383,11 @@ void EmptyUserpic::paintMonoforum(
|
||||
int outerWidth,
|
||||
int size) const {
|
||||
paint(p, x, y, outerWidth, size, [&] {
|
||||
PaintMonoforumShape(p, QRect(x, y, size, size));
|
||||
if (AyuSettings::getInstance().singleCornerRadius()) {
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
} else {
|
||||
PaintMonoforumShape(p, QRect(x, y, size, size));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -406,7 +419,7 @@ void EmptyUserpic::PaintSavedMessages(
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(std::move(bg));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
|
||||
PaintSavedMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
@@ -445,7 +458,7 @@ void EmptyUserpic::PaintRepliesMessages(
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
|
||||
PaintRepliesMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
@@ -484,7 +497,7 @@ void EmptyUserpic::PaintHiddenAuthor(
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
|
||||
PaintHiddenAuthorInner(p, x, y, size, fg);
|
||||
}
|
||||
@@ -523,7 +536,7 @@ void EmptyUserpic::PaintMyNotes(
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
AyuUserpic::PaintShape(p, x, y, size);
|
||||
|
||||
PaintMyNotesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/painter.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
|
||||
VideoUserpicPlayer::VideoUserpicPlayer() = default;
|
||||
@@ -59,8 +63,20 @@ QImage VideoUserpicPlayer::frame(QSize size, not_null<PeerData*> peer) {
|
||||
request.outer = request.resize = size * ratio;
|
||||
|
||||
const auto broadcast = peer->monoforumBroadcast();
|
||||
const auto peerShape = broadcast
|
||||
? Ui::PeerUserpicShape::Monoforum
|
||||
: peer->isForum()
|
||||
? Ui::PeerUserpicShape::Forum
|
||||
: Ui::PeerUserpicShape::Circle;
|
||||
const auto ayuOverride = AyuUserpic::ShouldOverrideShape(peerShape);
|
||||
|
||||
if (broadcast) {
|
||||
if (ayuOverride) {
|
||||
AyuUserpic::ApplyFrameRounding(
|
||||
request,
|
||||
_roundingCorners,
|
||||
_ellipseMask,
|
||||
size);
|
||||
} else if (broadcast) {
|
||||
if (_monoforumMask.isNull()) {
|
||||
_monoforumMask = Ui::MonoforumShapeMask(request.resize);
|
||||
}
|
||||
@@ -79,7 +95,7 @@ QImage VideoUserpicPlayer::frame(QSize size, not_null<PeerData*> peer) {
|
||||
}
|
||||
|
||||
auto result = _streamed->frame(request);
|
||||
if (broadcast) {
|
||||
if (!ayuOverride && broadcast) {
|
||||
constexpr auto kFormat = QImage::Format_ARGB32_Premultiplied;
|
||||
if (result.format() != kFormat) {
|
||||
result = std::move(result).convertToFormat(kFormat);
|
||||
|
||||
@@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/painter.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
|
||||
float64 ForumUserpicRadiusMultiplier() {
|
||||
@@ -32,8 +36,10 @@ void ValidateUserpicCache(
|
||||
const auto full = QSize(size, size);
|
||||
const auto version = style::PaletteVersion();
|
||||
const auto shapeValue = static_cast<uint32>(shape) & 3;
|
||||
const auto ayuState = AyuUserpic::PackedState();
|
||||
const auto regenerate = (view.cached.size() != QSize(size, size))
|
||||
|| (view.shape != shapeValue)
|
||||
|| (view.ayuState != ayuState)
|
||||
|| (cloud && !view.empty.null())
|
||||
|| (empty && empty != view.empty.get())
|
||||
|| (empty && view.paletteVersion != version);
|
||||
@@ -43,13 +49,20 @@ void ValidateUserpicCache(
|
||||
view.empty = empty;
|
||||
view.shape = shapeValue;
|
||||
view.paletteVersion = version;
|
||||
view.ayuState = ayuState;
|
||||
|
||||
const auto ayuOverride = AyuUserpic::ShouldOverrideShape(shape);
|
||||
|
||||
if (cloud) {
|
||||
view.cached = cloud->scaled(
|
||||
full,
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
if (shape == PeerUserpicShape::Monoforum) {
|
||||
if (ayuOverride) {
|
||||
view.cached = Images::Round(
|
||||
std::move(view.cached),
|
||||
ImageRoundRadius::AyuUserpic);
|
||||
} else if (shape == PeerUserpicShape::Monoforum) {
|
||||
view.cached = Ui::ApplyMonoforumShape(std::move(view.cached));
|
||||
} else if (shape == PeerUserpicShape::Forum) {
|
||||
view.cached = Images::Round(
|
||||
@@ -67,7 +80,9 @@ void ValidateUserpicCache(
|
||||
view.cached.fill(Qt::transparent);
|
||||
|
||||
auto p = QPainter(&view.cached);
|
||||
if (shape == PeerUserpicShape::Monoforum) {
|
||||
if (ayuOverride) {
|
||||
empty->paintCircle(p, 0, 0, size, size);
|
||||
} else if (shape == PeerUserpicShape::Monoforum) {
|
||||
empty->paintMonoforum(p, 0, 0, size, size);
|
||||
} else if (shape == PeerUserpicShape::Forum) {
|
||||
empty->paintRounded(
|
||||
|
||||
@@ -34,6 +34,7 @@ struct PeerUserpicView {
|
||||
base::weak_ptr<const EmptyUserpic> empty;
|
||||
uint32 paletteVersion : 30 = 0;
|
||||
uint32 shape : 2 = 0;
|
||||
uint8 ayuState = 0xFF;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool PeerUserpicLoading(const PeerUserpicView &view);
|
||||
|
||||
@@ -19,6 +19,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <set>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ui/ayu_userpic.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -177,7 +181,9 @@ void Item::paintOnce(Painter &p, int x, int y, int outerWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto radius = _st.height / 2;
|
||||
auto radius = std::min(
|
||||
AyuUserpic::ComputeRadius(_st.height),
|
||||
_st.height / 2);
|
||||
auto inner = style::rtlrect(
|
||||
x + radius,
|
||||
y,
|
||||
@@ -236,8 +242,9 @@ void Item::paintDeleteButton(
|
||||
p.setBrush(_color);
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(
|
||||
style::rtlrect(x, y, _st.height, _st.height, outerWidth));
|
||||
const auto rect = style::rtlrect(
|
||||
x, y, _st.height, _st.height, outerWidth);
|
||||
AyuUserpic::PaintShape(p, rect);
|
||||
}
|
||||
|
||||
CrossAnimation::paint(
|
||||
|
||||
+1
-1
Submodule Telegram/lib_ui updated: 9b329c5f50...f53d31f7a8
Reference in New Issue
Block a user