diff --git a/Telegram/SourceFiles/ui/controls/stars_rating.cpp b/Telegram/SourceFiles/ui/controls/stars_rating.cpp index 16a211a231..3f58d668e5 100644 --- a/Telegram/SourceFiles/ui/controls/stars_rating.cpp +++ b/Telegram/SourceFiles/ui/controls/stars_rating.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/labels.h" #include "ui/widgets/tooltip.h" #include "ui/painter.h" +#include "ui/rect.h" #include "ui/rp_widget.h" #include "ui/ui_utility.h" #include "styles/style_chat.h" // textMoreIconEmoji @@ -503,15 +504,15 @@ void StarsRating::updateData(Data::StarsRating rating) { if (!rating) { _shape = nullptr; _widthValue = 0; + _currentLevel = 0; } else { _shape = SelectShape(rating.level); - _collapsedText.setText( - st::levelStyle, - (rating.level < 0 - ? QString() - : Lang::FormatCountDecimal(rating.level))); + _collapsedText = (rating.level < 0 + ? QString() + : Lang::FormatCountDecimal(rating.level)); const auto &margin = st::levelMargin; _widthValue = _shape->icon.width() + margin.right() - margin.left(); + _currentLevel = rating.level; } updateWidth(); } @@ -538,14 +539,30 @@ void StarsRating::paint(QPainter &p) { if (!_shape) { return; } - _shape->icon.paint(p, 0, 0, _widget->width()); - const auto x = (_widget->width() - _collapsedText.maxWidth()) / 2; - p.setPen(st::levelTextFg); - _collapsedText.draw(p, { - .position = QPoint(x, 0) + _shape->position, - .availableWidth = _collapsedText.maxWidth(), - }); + if (_cachedLevel != _currentLevel) { + const auto ratio = style::DevicePixelRatio(); + const auto size = _widget->size() * ratio; + _cache = QImage(size, QImage::Format_ARGB32_Premultiplied); + _cache.setDevicePixelRatio(ratio); + _cache.fill(Qt::transparent); + + auto q = QPainter(&_cache); + _shape->icon.paint(q, 0, 0, _widget->width()); + + if (!_collapsedText.isEmpty()) { + q.setPen(st::levelTextFg); + q.setFont(st::levelStyle.font); + q.drawText( + Rect(_shape->icon.size()), + Qt::AlignCenter, + _collapsedText); + } + + _cachedLevel = _currentLevel; + } + + p.drawImage(0, 0, _cache); } rpl::producer StarsRating::widthValue() const { diff --git a/Telegram/SourceFiles/ui/controls/stars_rating.h b/Telegram/SourceFiles/ui/controls/stars_rating.h index a803810c47..ab24d6f16d 100644 --- a/Telegram/SourceFiles/ui/controls/stars_rating.h +++ b/Telegram/SourceFiles/ui/controls/stars_rating.h @@ -53,13 +53,18 @@ private: const std::shared_ptr _show; const QString _name; - Ui::Text::String _collapsedText; + QString _collapsedText; rpl::variable _value; Fn _pending; rpl::variable _widthValue; const style::LevelShape *_shape = nullptr; + QImage _cache; + int _cachedLevel = std::numeric_limits::min(); + + int _currentLevel = 0; + }; } // namespace Ui