mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-17 22:57:11 +02:00
Version 5.10.2: Improve gifts layout.
This commit is contained in:
parent
658cb438f8
commit
1ac33d30bd
8 changed files with 144 additions and 64 deletions
|
@ -298,48 +298,6 @@ auto GenerateGiftMedia(
|
|||
};
|
||||
}
|
||||
|
||||
struct PatternPoint {
|
||||
QPointF position;
|
||||
float64 scale = 1.;
|
||||
float64 opacity = 1.;
|
||||
};
|
||||
[[nodiscard]] const std::vector<PatternPoint> &PatternPoints() {
|
||||
static const auto kSmall = 0.7;
|
||||
static const auto kFaded = 0.3;
|
||||
static const auto kLarge = 0.85;
|
||||
static const auto kOpaque = 0.5;
|
||||
static const auto result = std::vector<PatternPoint>{
|
||||
{ { 0.5, 0.066 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.177, 0.168 }, kSmall, kFaded },
|
||||
{ { 0.822, 0.168 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.37, 0.168 }, kLarge, kOpaque },
|
||||
{ { 0.63, 0.168 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.277, 0.308 }, kSmall, kOpaque },
|
||||
{ { 0.723, 0.308 }, kSmall, kOpaque },
|
||||
|
||||
{ { 0.13, 0.42 }, kSmall, kFaded },
|
||||
{ { 0.87, 0.42 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.27, 0.533 }, kLarge, kOpaque },
|
||||
{ { 0.73, 0.533 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.2, 0.73 }, kSmall, kFaded },
|
||||
{ { 0.8, 0.73 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.302, 0.825 }, kLarge, kOpaque },
|
||||
{ { 0.698, 0.825 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.5, 0.876 }, kLarge, kFaded },
|
||||
|
||||
{ { 0.144, 0.936 }, kSmall, kFaded },
|
||||
{ { 0.856, 0.936 }, kSmall, kFaded },
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage CreateGradient(
|
||||
QSize size,
|
||||
const Data::UniqueGift &gift) {
|
||||
|
@ -2108,6 +2066,7 @@ void AddUniqueGiftCover(
|
|||
|
||||
PaintPoints(
|
||||
p,
|
||||
PatternPoints(),
|
||||
gift.emojis,
|
||||
gift.emoji.get(),
|
||||
*gift.gift,
|
||||
|
@ -2383,8 +2342,83 @@ void UpgradeBox(
|
|||
AddUniqueCloseButton(box);
|
||||
}
|
||||
|
||||
const std::vector<PatternPoint> &PatternPoints() {
|
||||
static const auto kSmall = 0.7;
|
||||
static const auto kFaded = 0.2;
|
||||
static const auto kLarge = 0.85;
|
||||
static const auto kOpaque = 0.3;
|
||||
static const auto result = std::vector<PatternPoint>{
|
||||
{ { 0.5, 0.066 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.177, 0.168 }, kSmall, kFaded },
|
||||
{ { 0.822, 0.168 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.37, 0.168 }, kLarge, kOpaque },
|
||||
{ { 0.63, 0.168 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.277, 0.308 }, kSmall, kOpaque },
|
||||
{ { 0.723, 0.308 }, kSmall, kOpaque },
|
||||
|
||||
{ { 0.13, 0.42 }, kSmall, kFaded },
|
||||
{ { 0.87, 0.42 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.27, 0.533 }, kLarge, kOpaque },
|
||||
{ { 0.73, 0.533 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.2, 0.73 }, kSmall, kFaded },
|
||||
{ { 0.8, 0.73 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.302, 0.825 }, kLarge, kOpaque },
|
||||
{ { 0.698, 0.825 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.5, 0.876 }, kLarge, kFaded },
|
||||
|
||||
{ { 0.144, 0.936 }, kSmall, kFaded },
|
||||
{ { 0.856, 0.936 }, kSmall, kFaded },
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<PatternPoint> &PatternPointsSmall() {
|
||||
static const auto kSmall = 0.45;
|
||||
static const auto kFaded = 0.2;
|
||||
static const auto kLarge = 0.55;
|
||||
static const auto kOpaque = 0.3;
|
||||
static const auto result = std::vector<PatternPoint>{
|
||||
{ { 0.5, 0.066 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.177, 0.168 }, kSmall, kFaded },
|
||||
{ { 0.822, 0.168 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.37, 0.168 }, kLarge, kOpaque },
|
||||
{ { 0.63, 0.168 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.277, 0.308 }, kSmall, kOpaque },
|
||||
{ { 0.723, 0.308 }, kSmall, kOpaque },
|
||||
|
||||
{ { 0.13, 0.42 }, kSmall, kFaded },
|
||||
{ { 0.87, 0.42 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.27, 0.533 }, kLarge, kOpaque },
|
||||
{ { 0.73, 0.533 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.2, 0.73 }, kSmall, kFaded },
|
||||
{ { 0.8, 0.73 }, kSmall, kFaded },
|
||||
|
||||
{ { 0.302, 0.825 }, kLarge, kOpaque },
|
||||
{ { 0.698, 0.825 }, kLarge, kOpaque },
|
||||
|
||||
{ { 0.5, 0.876 }, kLarge, kFaded },
|
||||
|
||||
{ { 0.144, 0.936 }, kSmall, kFaded },
|
||||
{ { 0.856, 0.936 }, kSmall, kFaded },
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
void PaintPoints(
|
||||
QPainter &p,
|
||||
const std::vector<PatternPoint> &points,
|
||||
base::flat_map<float64, QImage> &cache,
|
||||
not_null<Text::CustomEmoji*> emoji,
|
||||
const Data::UniqueGift &gift,
|
||||
|
@ -2417,7 +2451,7 @@ void PaintPoints(
|
|||
}
|
||||
}
|
||||
};
|
||||
for (const auto point : PatternPoints()) {
|
||||
for (const auto &point : points) {
|
||||
paintPoint(point);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,17 @@ void AddUniqueGiftCover(
|
|||
rpl::producer<Data::UniqueGift> data,
|
||||
rpl::producer<QString> subtitleOverride = nullptr);
|
||||
|
||||
struct PatternPoint {
|
||||
QPointF position;
|
||||
float64 scale = 1.;
|
||||
float64 opacity = 1.;
|
||||
};
|
||||
[[nodiscard]] const std::vector<PatternPoint> &PatternPoints();
|
||||
[[nodiscard]] const std::vector<PatternPoint> &PatternPointsSmall();
|
||||
|
||||
void PaintPoints(
|
||||
QPainter &p,
|
||||
const std::vector<PatternPoint> &points,
|
||||
base::flat_map<float64, QImage> &cache,
|
||||
not_null<Text::CustomEmoji*> emoji,
|
||||
const Data::UniqueGift &gift,
|
||||
|
|
|
@ -312,7 +312,8 @@ QImage PremiumGift::cornerTag(const PaintContext &context) {
|
|||
if (_data.unique) {
|
||||
badge = {
|
||||
.text = tr::lng_gift_collectible_tag(tr::now),
|
||||
.bg = _data.unique->backdrop.patternColor,
|
||||
.bg1 = _data.unique->backdrop.edgeColor,
|
||||
.bg2 = _data.unique->backdrop.patternColor,
|
||||
.fg = QColor(255, 255, 255),
|
||||
};
|
||||
} else if (const auto count = _data.limitedCount) {
|
||||
|
@ -325,7 +326,7 @@ QImage PremiumGift::cornerTag(const PaintContext &context) {
|
|||
(((count % 1000) && (count < 10'000))
|
||||
? Lang::FormatCountDecimal(count)
|
||||
: Lang::FormatCountToShort(count).string))),
|
||||
.bg = context.st->msgServiceBg()->c,
|
||||
.bg1 = context.st->msgServiceBg()->c,
|
||||
.fg = context.st->msgServiceFg()->c,
|
||||
};
|
||||
} else {
|
||||
|
|
|
@ -525,7 +525,13 @@ Fn<void(Painter&, const Ui::ChatPaintContext &)> UniqueGiftBg(
|
|||
const auto doubled = width + 2 * shift;
|
||||
const auto outer = QRect(-shift, -shift, doubled, doubled);
|
||||
p.setClipRect(inner);
|
||||
Ui::PaintPoints(p, state->cache, state->pattern.get(), *gift, outer);
|
||||
Ui::PaintPoints(
|
||||
p,
|
||||
Ui::PatternPoints(),
|
||||
state->cache,
|
||||
state->pattern.get(),
|
||||
*gift,
|
||||
outer);
|
||||
p.setClipping(false);
|
||||
|
||||
const auto add = style::ConvertScale(2);
|
||||
|
@ -536,7 +542,8 @@ Fn<void(Painter&, const Ui::ChatPaintContext &)> UniqueGiftBg(
|
|||
inner.height() + 2 * add);
|
||||
auto badge = Info::PeerGifts::GiftBadge{
|
||||
.text = tr::lng_gift_collectible_tag(tr::now),
|
||||
.bg = gift->backdrop.patternColor,
|
||||
.bg1 = gift->backdrop.edgeColor,
|
||||
.bg2 = gift->backdrop.patternColor,
|
||||
.fg = gift->backdrop.textColor,
|
||||
};
|
||||
if (state->badgeCache.isNull() || state->badgeKey != badge) {
|
||||
|
|
|
@ -42,10 +42,14 @@ std::strong_ordering operator<=>(const GiftBadge &a, const GiftBadge &b) {
|
|||
if (result1 != std::strong_ordering::equal) {
|
||||
return result1;
|
||||
}
|
||||
const auto result2 = (a.bg.rgb() <=> b.bg.rgb());
|
||||
const auto result2 = (a.bg1.rgb() <=> b.bg1.rgb());
|
||||
if (result2 != std::strong_ordering::equal) {
|
||||
return result2;
|
||||
}
|
||||
const auto result3 = (a.bg2.rgb() <=> b.bg2.rgb());
|
||||
if (result3 != std::strong_ordering::equal) {
|
||||
return result3;
|
||||
}
|
||||
return a.fg.rgb() <=> b.fg.rgb();
|
||||
}
|
||||
|
||||
|
@ -148,6 +152,7 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
|||
|
||||
if (mode != Mode::Full) {
|
||||
_button = QRect();
|
||||
_small = true;
|
||||
return;
|
||||
}
|
||||
const auto buttonw = _price.maxWidth();
|
||||
|
@ -263,11 +268,11 @@ void GiftButton::cacheUniqueBackground(
|
|||
if (!_patterned && _uniquePatternEmoji->ready()) {
|
||||
_patterned = true;
|
||||
auto p = QPainter(&_uniqueBackgroundCache);
|
||||
p.setOpacity(0.5);
|
||||
p.setClipRect(inner);
|
||||
const auto skip = inner.width() / 3;
|
||||
Ui::PaintPoints(
|
||||
p,
|
||||
Ui::PatternPointsSmall(),
|
||||
_uniquePatternCache,
|
||||
_uniquePatternEmoji.get(),
|
||||
*unique,
|
||||
|
@ -338,7 +343,9 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
p.drawImage(
|
||||
QRect(
|
||||
(width - size.width()) / 2,
|
||||
(_text.isEmpty()
|
||||
(_small
|
||||
? st::giftBoxSmallStickerTop
|
||||
: _text.isEmpty()
|
||||
? st::giftBoxStickerStarTop
|
||||
: st::giftBoxStickerTop),
|
||||
size.width(),
|
||||
|
@ -348,7 +355,9 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
if (hidden) {
|
||||
const auto topleft = QPoint(
|
||||
(width - st::giftBoxStickerSize.width()) / 2,
|
||||
(_text.isEmpty()
|
||||
(_small
|
||||
? st::giftBoxSmallStickerTop
|
||||
: _text.isEmpty()
|
||||
? st::giftBoxStickerStarTop
|
||||
: st::giftBoxStickerTop));
|
||||
_delegate->hiddenMark()->paint(
|
||||
|
@ -372,8 +381,9 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
const auto kMinus = QChar(0x2212);
|
||||
return GiftBadge{
|
||||
.text = kMinus + QString::number(data.discountPercent) + '%',
|
||||
.bg = st::attentionButtonFg->c,
|
||||
.bg1 = st::attentionButtonFg->c,
|
||||
.fg = st::windowBg->c,
|
||||
.small = true,
|
||||
};
|
||||
}
|
||||
return GiftBadge();
|
||||
|
@ -383,7 +393,7 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
return GiftBadge{
|
||||
.text = (soldOut
|
||||
? tr::lng_gift_stars_sold_out(tr::now)
|
||||
: !data.userpic
|
||||
: (!data.userpic && !data.info.unique)
|
||||
? tr::lng_gift_stars_limited(tr::now)
|
||||
: (count == 1)
|
||||
? tr::lng_gift_limited_of_one(tr::now)
|
||||
|
@ -393,19 +403,23 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
(((count % 1000) && (count < 10'000))
|
||||
? Lang::FormatCountDecimal(count)
|
||||
: Lang::FormatCountToShort(count).string))),
|
||||
.bg = (unique
|
||||
? unique->backdrop.patternColor
|
||||
.bg1 = (unique
|
||||
? unique->backdrop.edgeColor
|
||||
: soldOut
|
||||
? st::attentionButtonFg->c
|
||||
: st::windowActiveTextFg->c),
|
||||
.bg2 = (unique
|
||||
? unique->backdrop.patternColor
|
||||
: QColor(0, 0, 0, 0)),
|
||||
.fg = unique ? QColor(255, 255, 255) : st::windowBg->c,
|
||||
.small = true,
|
||||
};
|
||||
}
|
||||
return GiftBadge();
|
||||
});
|
||||
|
||||
if (badge) {
|
||||
const auto rubberOut = _extend.top();
|
||||
const auto rubberOut = st::lineWidth;
|
||||
const auto inner = rect().marginsRemoved(_extend);
|
||||
p.setClipRect(inner.marginsAdded(
|
||||
{ rubberOut, rubberOut, rubberOut, rubberOut }));
|
||||
|
@ -413,8 +427,8 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
const auto cached = _delegate->cachedBadge(badge);
|
||||
const auto width = cached.width() / cached.devicePixelRatio();
|
||||
p.drawImage(
|
||||
position.x() + singlew + _extend.top() - width,
|
||||
position.y() - _extend.top(),
|
||||
position.x() + singlew + rubberOut - width,
|
||||
position.y() - rubberOut,
|
||||
cached);
|
||||
}
|
||||
if (!_button.isEmpty()) {
|
||||
|
@ -633,7 +647,9 @@ rpl::producer<not_null<DocumentData*>> GiftStickerValue(
|
|||
}
|
||||
|
||||
QImage ValidateRotatedBadge(const GiftBadge &badge, int added) {
|
||||
const auto &font = st::semiboldFont;
|
||||
const auto &font = badge.small
|
||||
? st::giftBoxGiftBadgeFont
|
||||
: st::semiboldFont;
|
||||
const auto twidth = font->width(badge.text) + 2 * added;
|
||||
const auto skip = int(std::ceil(twidth / M_SQRT2));
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
|
@ -670,12 +686,19 @@ QImage ValidateRotatedBadge(const GiftBadge &badge, int added) {
|
|||
auto p = QPainter(&result);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(badge.bg);
|
||||
p.setBrush(badge.bg1);
|
||||
|
||||
p.save();
|
||||
p.translate(textpos);
|
||||
p.rotate(45.);
|
||||
p.drawRect(-5 * twidth, 0, twidth * 12, font->height);
|
||||
const auto rect = QRect(-5 * twidth, 0, twidth * 12, font->height);
|
||||
p.drawRect(rect);
|
||||
if (badge.bg2.alpha() > 0) {
|
||||
p.setOpacity(0.5);
|
||||
p.setBrush(badge.bg2);
|
||||
p.drawRect(rect);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
p.restore();
|
||||
|
||||
p.drawImage(0, 0, scaled);
|
||||
|
|
|
@ -74,8 +74,10 @@ struct GiftDescriptor : std::variant<GiftTypePremium, GiftTypeStars> {
|
|||
|
||||
struct GiftBadge {
|
||||
QString text;
|
||||
QColor bg;
|
||||
QColor bg1;
|
||||
QColor bg2 = QColor(0, 0, 0, 0);
|
||||
QColor fg;
|
||||
bool small = false;
|
||||
|
||||
explicit operator bool() const {
|
||||
return !text.isEmpty();
|
||||
|
@ -148,6 +150,7 @@ private:
|
|||
std::optional<Ui::Premium::ColoredMiniStars> _stars;
|
||||
bool _subscribed = false;
|
||||
bool _patterned = false;
|
||||
bool _small = false;
|
||||
|
||||
QRect _button;
|
||||
QMargins _extend;
|
||||
|
|
|
@ -1348,6 +1348,7 @@ void ReceiptCreditsBox(
|
|||
};
|
||||
const auto canUpgrade = e.stargiftId
|
||||
&& e.canUpgradeGift
|
||||
&& (e.in || giftToSelf)
|
||||
&& !e.uniqueGift;
|
||||
const auto canUpgradeFree = canUpgrade && (e.starsUpgradedBySender > 0);
|
||||
|
||||
|
|
|
@ -109,11 +109,12 @@ giftBoxTabStyle: semiboldTextStyle;
|
|||
giftBoxTabFg: windowSubTextFg;
|
||||
giftBoxTabFgActive: windowBoldFg;
|
||||
giftBoxTabBgActive: windowBgRipple;
|
||||
giftBoxPadding: margins(20px, 4px, 20px, 24px);
|
||||
giftBoxPadding: margins(11px, 4px, 11px, 24px);
|
||||
giftBoxGiftSkip: point(10px, 8px);
|
||||
giftBoxGiftHeight: 164px;
|
||||
giftBoxGiftSmall: 124px;
|
||||
giftBoxGiftSmall: 108px;
|
||||
giftBoxGiftRadius: 12px;
|
||||
giftBoxGiftBadgeFont: font(10px semibold);
|
||||
giftBoxPremiumIconSize: 64px;
|
||||
giftBoxPremiumIconTop: 10px;
|
||||
giftBoxPremiumTextTop: 84px;
|
||||
|
@ -125,6 +126,7 @@ giftBoxPreviewTextPadding: margins(12px, 4px, 12px, 4px);
|
|||
giftBoxButtonMargin: margins(12px, 8px, 12px, 12px);
|
||||
giftBoxStickerTop: 0px;
|
||||
giftBoxStickerStarTop: 24px;
|
||||
giftBoxSmallStickerTop: 16px;
|
||||
giftBoxStickerSize: size(80px, 80px);
|
||||
giftBoxUserpicSize: 24px;
|
||||
giftBoxUserpicSkip: 2px;
|
||||
|
|
Loading…
Add table
Reference in a new issue