Support subtext in Stars Bubble in bids.

This commit is contained in:
John Preston
2025-11-20 13:29:19 +04:00
parent 312d5f0121
commit f15b883471
7 changed files with 100 additions and 25 deletions

View File

@@ -27,6 +27,8 @@ PremiumBubble {
font: font;
additionalStyle: TextStyle;
additionalSkip: pixels;
subtextStyle: TextStyle;
subtextPadding: margins;
}
PremiumCover {
bg: color;
@@ -263,6 +265,10 @@ boostBubble: PremiumBubble(defaultPremiumBubble) {
font: font(14px semibold);
}
additionalSkip: 2px;
subtextStyle: TextStyle(defaultTextStyle) {
font: font(10px);
}
subtextPadding: margins(11px, -5px, 11px, 0px);
}
starRatingBubble: PremiumBubble(boostBubble) {
font: font(16px semibold);

View File

@@ -56,7 +56,6 @@ Bubble::Bubble(
, _icon(icon)
, _numberAnimation(_st.font, _updateCallback)
, _height(_st.height + _st.tailSize.height())
, _textTop((_height - _st.tailSize.height() - _st.font->height) / 2)
, _hasTail(hasTail) {
_numberAnimation.setDisabledMonospace(true);
_numberAnimation.setWidthChangedCallback([=] {
@@ -83,7 +82,7 @@ int Bubble::height() const {
}
int Bubble::bubbleRadius() const {
return (_height - _st.tailSize.height()) / 2 - kBubbleRadiusSubtractor;
return (_st.height / 2) - kBubbleRadiusSubtractor;
}
int Bubble::filledWidth() const {
@@ -93,7 +92,7 @@ int Bubble::filledWidth() const {
+ _st.padding.right();
}
int Bubble::width() const {
int Bubble::topTextWidth() const {
return filledWidth()
+ _numberAnimation.countWidth()
+ (_additional.isEmpty()
@@ -101,21 +100,16 @@ int Bubble::width() const {
: (_st.additionalSkip + _additional.maxWidth()));
}
int Bubble::countMaxWidth(int maxPossibleCounter) const {
auto numbers = Ui::NumbersAnimation(_st.font, [] {});
numbers.setDisabledMonospace(true);
numbers.setDuration(0);
const auto textsZero = _textFactory(0);
const auto textsMax = _textFactory(maxPossibleCounter);
numbers.setText(textsZero.counter, 0);
numbers.setText(textsMax.counter, maxPossibleCounter);
numbers.finishAnimating();
return filledWidth()
+ numbers.maxWidth()
+ (_additional.isEmpty()
? 0
: (_st.additionalSkip
+ _st.additionalStyle.font->width(textsMax.additional)));
int Bubble::bottomTextWidth() const {
return _subtext.isEmpty()
? 0
: (_st.subtextPadding.left()
+ _subtext.maxWidth()
+ _st.subtextPadding.right());
}
int Bubble::width() const {
return std::max(topTextWidth(), bottomTextWidth());
}
int Bubble::countTargetWidth(int targetCounter) const {
@@ -125,12 +119,13 @@ int Bubble::countTargetWidth(int targetCounter) const {
const auto texts = _textFactory(targetCounter);
numbers.setText(texts.counter, targetCounter);
numbers.finishAnimating();
return filledWidth()
const auto top = filledWidth()
+ numbers.maxWidth()
+ (_additional.isEmpty()
? 0
: (_st.additionalSkip
+ _st.additionalStyle.font->width(texts.additional)));
return std::max(top, bottomTextWidth());
}
void Bubble::setCounter(int value) {
@@ -210,6 +205,18 @@ QPainterPath Bubble::bubblePath(const QRect &r) const {
return result;
}
void Bubble::setSubtext(QString subtext) {
if (_subtext.toString() == subtext) {
return;
} else if (subtext.isEmpty()) {
_subtext = {};
} else {
_subtext.setText(_st.subtextStyle, subtext);
}
_widthChanges.fire({});
_updateCallback();
}
void Bubble::paintBubble(QPainter &p, const QRect &r, const QBrush &brush) {
if (!_counter.has_value()) {
return;
@@ -230,12 +237,25 @@ void Bubble::paintBubble(QPainter &p, const QRect &r, const QBrush &brush) {
}
p.setPen(st::activeButtonFg);
p.setFont(_st.font);
const auto iconLeft = r.x() + _st.padding.left();
const auto withSubtext = !_subtext.isEmpty();
const auto height = withSubtext
? (_st.font->height
+ _st.subtextPadding.top()
+ _st.subtextStyle.font->height)
: _st.font->height;
const auto topWidth = withSubtext ? topTextWidth() : 0;
const auto bottomWidth = withSubtext ? bottomTextWidth() : 0;
const auto iconShift = (topWidth >= bottomWidth)
? 0
: (bottomWidth - topWidth) / 2;
const auto iconLeft = r.x() + _st.padding.left() + iconShift;
const auto topShift = (_st.font->height - height) / 2;
const auto iconTop = bubbleRect.y()
+ topShift
+ (bubbleRect.height() - _icon->height()) / 2;
_icon->paint(p, iconLeft, iconTop, bubbleRect.width());
const auto numberLeft = iconLeft + _icon->width() + _st.textSkip;
const auto numberTop = r.y() + _textTop;
const auto numberTop = r.y() + (_st.height - height) / 2;
_numberAnimation.paint(p, numberLeft, numberTop, width());
if (!_additional.isEmpty()) {
p.setOpacity(0.7);
@@ -250,6 +270,22 @@ void Bubble::paintBubble(QPainter &p, const QRect &r, const QBrush &brush) {
.availableWidth = _additional.maxWidth(),
});
}
if (withSubtext) {
p.setOpacity(1.);
const auto subtextShift = (bottomWidth >= topWidth)
? 0
: (topWidth - bottomWidth) / 2;
const auto subtextLeft = r.x()
+ _st.subtextPadding.left()
+ subtextShift;
const auto subtextTop = numberTop
+ _st.font->height
+ _st.subtextPadding.top();
_subtext.draw(p, {
.position = { subtextLeft, subtextTop },
.availableWidth = _subtext.maxWidth(),
});
}
}
rpl::producer<> Bubble::widthChanges() const {
@@ -494,6 +530,10 @@ void BubbleWidget::setBrushOverride(std::optional<QBrush> brushOverride) {
update();
}
void BubbleWidget::setSubtext(QString subtext) {
_bubble.setSubtext(subtext);
}
void BubbleWidget::paintEvent(QPaintEvent *e) {
if (!_bubble.counter().has_value()) {
return;

View File

@@ -56,7 +56,6 @@ public:
[[nodiscard]] int height() const;
[[nodiscard]] int width() const;
[[nodiscard]] int bubbleRadius() const;
[[nodiscard]] int countMaxWidth(int maxPossibleCounter) const;
[[nodiscard]] int countTargetWidth(int targetCounter) const;
[[nodiscard]] QRect bubbleGeometry(const QRect &r) const;
@@ -65,11 +64,14 @@ public:
void setFlipHorizontal(bool value);
void paintBubble(QPainter &p, const QRect &r, const QBrush &brush);
[[nodiscard]] QPainterPath bubblePath(const QRect &r) const;
void setSubtext(QString subtext);
[[nodiscard]] rpl::producer<> widthChanges() const;
private:
[[nodiscard]] int filledWidth() const;
[[nodiscard]] int topTextWidth() const;
[[nodiscard]] int bottomTextWidth() const;
const style::PremiumBubble &_st;
@@ -79,8 +81,8 @@ private:
const style::icon *_icon;
NumbersAnimation _numberAnimation;
Text::String _additional;
Text::String _subtext;
const int _height;
const int _textTop;
const bool _hasTail;
std::optional<int> _counter;
@@ -120,6 +122,7 @@ public:
const style::margins &outerPadding);
void setBrushOverride(std::optional<QBrush> brushOverride);
void setSubtext(QString subtext);
protected:
void paintEvent(QPaintEvent *e) override;