mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve locked premium stickers design.
This commit is contained in:
parent
0bf58936e3
commit
719190d570
3 changed files with 90 additions and 33 deletions
|
@ -58,7 +58,7 @@ constexpr auto kPreloadOfficialPages = 4;
|
||||||
constexpr auto kOfficialLoadLimit = 40;
|
constexpr auto kOfficialLoadLimit = 40;
|
||||||
constexpr auto kMinRepaintDelay = crl::time(33);
|
constexpr auto kMinRepaintDelay = crl::time(33);
|
||||||
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
||||||
constexpr auto kPremiumLockedOpacity = 0.5;
|
constexpr auto kGrayLockOpacity = 0.3;
|
||||||
|
|
||||||
using Data::StickersSet;
|
using Data::StickersSet;
|
||||||
using Data::StickersPack;
|
using Data::StickersPack;
|
||||||
|
@ -69,6 +69,47 @@ using SetFlag = Data::StickersSetFlag;
|
||||||
return (flags & SetFlag::Installed) && !(flags & SetFlag::Archived);
|
return (flags & SetFlag::Installed) && !(flags & SetFlag::Archived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<QColor> ComputeImageColor(const QImage &frame) {
|
||||||
|
if (frame.isNull()
|
||||||
|
|| frame.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto sr = int64();
|
||||||
|
auto sg = int64();
|
||||||
|
auto sb = int64();
|
||||||
|
auto sa = int64();
|
||||||
|
const auto factor = frame.devicePixelRatio();
|
||||||
|
const auto size = st::stickersPremiumLock.size() * factor;
|
||||||
|
const auto width = std::min(frame.width(), size.width());
|
||||||
|
const auto height = std::min(frame.height(), size.height());
|
||||||
|
const auto skipx = (frame.width() - width) / 2;
|
||||||
|
const auto radius = st::roundRadiusSmall;
|
||||||
|
const auto skipy = std::max(frame.height() - height - radius, 0);
|
||||||
|
const auto perline = frame.bytesPerLine();
|
||||||
|
const auto addperline = perline - (width * 4);
|
||||||
|
auto bits = static_cast<const uchar*>(frame.bits())
|
||||||
|
+ perline * skipy
|
||||||
|
+ sizeof(uint32) * skipx;
|
||||||
|
for (auto y = 0; y != height; ++y) {
|
||||||
|
for (auto x = 0; x != width; ++x) {
|
||||||
|
sb += int(*bits++);
|
||||||
|
sg += int(*bits++);
|
||||||
|
sr += int(*bits++);
|
||||||
|
sa += int(*bits++);
|
||||||
|
}
|
||||||
|
bits += addperline;
|
||||||
|
}
|
||||||
|
if (!sa) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return QColor(sr * 255 / sa, sg * 255 / sa, sb * 255 / sa, 255);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QColor ComputeLockColor(const QImage &frame) {
|
||||||
|
return ComputeImageColor(frame).value_or(st::windowSubTextFg->c);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct StickerIcon {
|
struct StickerIcon {
|
||||||
|
@ -236,6 +277,7 @@ struct StickersListWidget::Sticker {
|
||||||
Media::Clip::ReaderPointer webm;
|
Media::Clip::ReaderPointer webm;
|
||||||
QPixmap savedFrame;
|
QPixmap savedFrame;
|
||||||
QSize savedFrameFor;
|
QSize savedFrameFor;
|
||||||
|
QImage premiumLock;
|
||||||
|
|
||||||
void ensureMediaCreated();
|
void ensureMediaCreated();
|
||||||
};
|
};
|
||||||
|
@ -1182,7 +1224,7 @@ StickersListWidget::StickersListWidget(
|
||||||
|
|
||||||
style::PaletteChanged(
|
style::PaletteChanged(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
_premiumLock = QImage();
|
_premiumLockGray = QImage();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
Data::AmPremiumValue(
|
Data::AmPremiumValue(
|
||||||
|
@ -2317,18 +2359,18 @@ void StickersListWidget::paintSticker(
|
||||||
(_singleSize.width() - size.width()) / 2,
|
(_singleSize.width() - size.width()) / 2,
|
||||||
(_singleSize.height() - size.height()) / 2);
|
(_singleSize.height() - size.height()) / 2);
|
||||||
|
|
||||||
if (locked) {
|
auto lottieFrame = QImage();
|
||||||
p.setOpacity(kPremiumLockedOpacity);
|
|
||||||
}
|
|
||||||
if (sticker.lottie && sticker.lottie->ready()) {
|
if (sticker.lottie && sticker.lottie->ready()) {
|
||||||
auto request = Lottie::FrameRequest();
|
auto request = Lottie::FrameRequest();
|
||||||
request.box = boundingBoxSize() * cIntRetinaFactor();
|
request.box = boundingBoxSize() * cIntRetinaFactor();
|
||||||
const auto frame = sticker.lottie->frame(request);
|
lottieFrame = sticker.lottie->frame(request);
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
QRect(ppos, frame.size() / cIntRetinaFactor()),
|
QRect(ppos, lottieFrame.size() / cIntRetinaFactor()),
|
||||||
frame);
|
lottieFrame);
|
||||||
if (sticker.savedFrame.isNull()) {
|
if (sticker.savedFrame.isNull()) {
|
||||||
sticker.savedFrame = QPixmap::fromImage(frame, Qt::ColorOnly);
|
sticker.savedFrame = QPixmap::fromImage(
|
||||||
|
lottieFrame,
|
||||||
|
Qt::ColorOnly);
|
||||||
sticker.savedFrame.setDevicePixelRatio(cRetinaFactor());
|
sticker.savedFrame.setDevicePixelRatio(cRetinaFactor());
|
||||||
sticker.savedFrameFor = _singleSize;
|
sticker.savedFrameFor = _singleSize;
|
||||||
}
|
}
|
||||||
|
@ -2358,6 +2400,10 @@ void StickersListWidget::paintSticker(
|
||||||
sticker.savedFrame = pixmap;
|
sticker.savedFrame = pixmap;
|
||||||
sticker.savedFrameFor = _singleSize;
|
sticker.savedFrameFor = _singleSize;
|
||||||
}
|
}
|
||||||
|
if (locked) {
|
||||||
|
lottieFrame = pixmap.toImage().convertToFormat(
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
PaintStickerThumbnailPath(
|
PaintStickerThumbnailPath(
|
||||||
|
@ -2378,37 +2424,45 @@ void StickersListWidget::paintSticker(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locked) {
|
if (locked) {
|
||||||
p.setOpacity(1.);
|
validatePremiumLock(set, index, lottieFrame);
|
||||||
|
const auto &bg = lottieFrame.isNull()
|
||||||
validatePremiumLock();
|
? _premiumLockGray
|
||||||
|
: sticker.premiumLock;
|
||||||
const auto factor = style::DevicePixelRatio();
|
const auto factor = style::DevicePixelRatio();
|
||||||
const auto point = pos
|
const auto radius = st::roundRadiusSmall;
|
||||||
+ QPoint(
|
const auto point = pos + QPoint(
|
||||||
_singleSize.width() - (_premiumLock.width() / factor),
|
(_singleSize.width() - (bg.width() / factor)) / 2,
|
||||||
_singleSize.height() - (_premiumLock.height() / factor));
|
_singleSize.height() - (bg.height() / factor) - radius);
|
||||||
p.drawImage(point, _premiumLock);
|
p.drawImage(point, bg);
|
||||||
|
|
||||||
|
st::stickersPremiumLock.paint(p, point, width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::validatePremiumLock() {
|
const QImage &StickersListWidget::validatePremiumLock(
|
||||||
if (!_premiumLock.isNull()) {
|
Set &set,
|
||||||
return;
|
int index,
|
||||||
|
const QImage &frame) {
|
||||||
|
auto &sticker = set.stickers[index];
|
||||||
|
auto &image = frame.isNull() ? _premiumLockGray : sticker.premiumLock;
|
||||||
|
if (!image.isNull()) {
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
const auto factor = style::DevicePixelRatio();
|
const auto factor = style::DevicePixelRatio();
|
||||||
const auto size = st::stickersPremiumLock.size();
|
const auto size = st::stickersPremiumLock.size();
|
||||||
_premiumLock = QImage(
|
image = QImage(
|
||||||
size * factor,
|
size * factor,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
_premiumLock.setDevicePixelRatio(factor);
|
image.setDevicePixelRatio(factor);
|
||||||
auto p = QPainter(&_premiumLock);
|
auto p = QPainter(&image);
|
||||||
auto gradient = QLinearGradient(
|
const auto color = ComputeLockColor(frame);
|
||||||
QPoint(0, size.height()),
|
p.fillRect(
|
||||||
QPoint(size.width(), 0));
|
QRect(QPoint(), size),
|
||||||
gradient.setStops(Ui::Premium::LockGradientStops());
|
anim::color(color, st::windowSubTextFg, kGrayLockOpacity));
|
||||||
p.fillRect(QRect(QPoint(), size), gradient);
|
|
||||||
st::stickersPremiumLock.paint(p, 0, 0, size.width());
|
|
||||||
p.end();
|
p.end();
|
||||||
_premiumLock = Images::Circle(std::move(_premiumLock));
|
|
||||||
|
image = Images::Circle(std::move(image));
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickersListWidget::stickersRight() const {
|
int StickersListWidget::stickersRight() const {
|
||||||
|
|
|
@ -330,7 +330,10 @@ private:
|
||||||
void addSearchRow(not_null<Data::StickersSet*> set);
|
void addSearchRow(not_null<Data::StickersSet*> set);
|
||||||
|
|
||||||
void showPreview();
|
void showPreview();
|
||||||
void validatePremiumLock();
|
const QImage &validatePremiumLock(
|
||||||
|
Set &set,
|
||||||
|
int index,
|
||||||
|
const QImage &frame);
|
||||||
|
|
||||||
Ui::MessageSendingAnimationFrom messageSentAnimationInfo(
|
Ui::MessageSendingAnimationFrom messageSentAnimationInfo(
|
||||||
int section,
|
int section,
|
||||||
|
@ -391,7 +394,7 @@ private:
|
||||||
base::Timer _previewTimer;
|
base::Timer _previewTimer;
|
||||||
bool _previewShown = false;
|
bool _previewShown = false;
|
||||||
|
|
||||||
QImage _premiumLock;
|
QImage _premiumLockGray;
|
||||||
|
|
||||||
std::map<QString, std::vector<uint64>> _searchCache;
|
std::map<QString, std::vector<uint64>> _searchCache;
|
||||||
std::vector<std::pair<uint64, QStringList>> _searchIndex;
|
std::vector<std::pair<uint64, QStringList>> _searchIndex;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0a713c1c7b9d1890b98eb7c6d1e29bd199914ad7
|
Subproject commit 72940a25e30e34361c9ad294007a5d707404d856
|
Loading…
Add table
Reference in a new issue