diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp index bb521bd9bd..4c5d4519fa 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/prepare_short_info_box.h" #include "boxes/premium_preview_box.h" +#include "calls/group/ui/calls_group_stars_coloring.h" #include "calls/group/calls_group_messages.h" #include "chat_helpers/compose/compose_show.h" #include "chat_helpers/emoji_suggestions_widget.h" @@ -33,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_utilities.h" #include "ui/widgets/fields/input_field.h" #include "ui/widgets/elastic_scroll.h" +#include "ui/color_int_conversion.h" #include "ui/painter.h" #include "ui/ui_utility.h" #include "ui/userpic_view.h" @@ -49,6 +51,7 @@ namespace Calls::Group { namespace { constexpr auto kMessageBgOpacity = 0.8; +constexpr auto kColoredMessageBgOpacity = 0.6; [[nodiscard]] int CountMessageRadius() { const auto minHeight = st::groupCallMessagePadding.top() @@ -57,6 +60,10 @@ constexpr auto kMessageBgOpacity = 0.8; return minHeight / 2; } +[[nodiscard]] uint64 ColoringKey(const Ui::StarsColoring &value) { + return (uint64(uint32(value.bg1)) << 32) | uint64(uint32(value.bg2)); +} + void ReceiveSomeMouseEvents( not_null scroll, Fn handleClick) { @@ -165,6 +172,11 @@ struct MessagesUi::MessageView { bool failed = false; }; +MessagesUi::PayedBg::PayedBg(const Ui::StarsColoring &coloring) +: color(Ui::ColorFromSerialized(coloring.bg2)) +, rounded(CountMessageRadius(), color.color()) { +} + MessagesUi::MessagesUi( not_null parent, std::shared_ptr show, @@ -181,7 +193,6 @@ MessagesUi::MessagesUi( return result; }) , _messageBgRect(CountMessageRadius(), _messageBg.color()) -, _payedBgRect(CountMessageRadius(), st::creditsBg3) , _fadeHeight(st::normalFont->height) , _streamMode(_mode == MessagesMode::VideoStream) { setupList(std::move(messages), std::move(shown)); @@ -732,7 +743,14 @@ void MessagesUi::setupMessagesWidget() { if (!_streamMode) { _messageBgRect.paint(p, { x, y, width, use }); } else if (entry.stars) { - _payedBgRect.paint(p, { x, y, width, use }); + const auto coloring = Ui::StarsColoringForCount(entry.stars); + auto &bg = _bgs[ColoringKey(coloring)]; + if (!bg) { + bg = std::make_unique(coloring); + } + p.setOpacity(kColoredMessageBgOpacity); + bg->rounded.paint(p, { x, y, width, use }); + p.setOpacity(1.); } auto leftSkip = padding.left(); diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h index 5298a5740a..b3a55502e7 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h +++ b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h @@ -29,6 +29,11 @@ class SendButton; class RpWidget; } // namespace Ui +namespace Calls::Group::Ui { +using namespace ::Ui; +struct StarsColoring; +} // namespace Calls::Group::Ui + namespace Calls::Group { struct Message; @@ -57,6 +62,12 @@ public: private: struct MessageView; + struct PayedBg { + PayedBg(const Ui::StarsColoring &coloring); + + style::owned_color color; + Ui::RoundRect rounded; + }; void setupList( rpl::producer> messages, @@ -98,7 +109,7 @@ private: style::complex_color _messageBg; Ui::RoundRect _messageBgRect; - Ui::RoundRect _payedBgRect; + base::flat_map> _bgs; QPoint _reactionBasePosition; rpl::lifetime _effectsLifetime; diff --git a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp index deca77d454..6dfd7efb00 100644 --- a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp +++ b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp @@ -70,14 +70,56 @@ namespace { } // namespace StarsColoring StarsColoringForCount(int stars) { + //name: "Purple" [STRING], + //center_color: 11431086 [INT], + //edge_color: 8669060 [INT], + //pattern_color: 4656199 [INT], + //text_color: 15977459 [INT], + + //name: "Celtic Blue" [STRING], + //center_color: 4569325 [INT], + //edge_color: 3704537 [INT], + //pattern_color: 16005 [INT], + //text_color: 12773375 [INT], + + //name: "Mint Green" [STRING], + //center_color: 8309634 [INT], + //edge_color: 4562522 [INT], + //pattern_color: 158498 [INT], + //text_color: 12451788 [INT], + + //name: "Pure Gold" [STRING], + //center_color: 13413185 [INT], + //edge_color: 9993010 [INT], + //pattern_color: 7355392 [INT], + //text_color: 16770475 [INT], + + //name: "Orange" [STRING], + //center_color: 13736506 [INT], + //edge_color: 12611399 [INT], + //pattern_color: 10303751 [INT], + //text_color: 16769475 [INT], + + //name: "Strawberry" [STRING], + //center_color: 14519919 [INT], + //edge_color: 12016224 [INT], + //pattern_color: 11078668 [INT], + //text_color: 16765907 [INT], + + //name: "Steel Grey" [STRING], + //center_color: 9937580 [INT], + //edge_color: 6517372 [INT], + //pattern_color: 3360082 [INT], + //text_color: 14673128 [INT], + const auto list = std::vector{ - { st::creditsBg3->c, st::creditsBg2->c, 50, 1, 60, 1 }, - { st::creditsBg3->c, st::creditsBg2->c, 100, 1, 80, 2 }, - { st::creditsBg3->c, st::creditsBg2->c, 250, 5, 110, 3 }, - { st::creditsBg3->c, st::creditsBg2->c, 500, 10, 150, 4 }, - { st::creditsBg3->c, st::creditsBg2->c, 2000, 15, 200, 7 }, - { st::creditsBg3->c, st::creditsBg2->c, 7500, 30, 280, 10 }, - { st::creditsBg3->c, st::creditsBg2->c, 0, 60, 400, 20 }, + { 11431086, 8669060, 50, 1, 60, 1 }, + { 4569325, 3704537, 100, 1, 80, 2 }, + { 8309634, 4562522, 250, 5, 110, 3 }, + { 13413185, 9993010, 500, 10, 150, 4 }, + { 13736506, 12611399, 2000, 15, 200, 7 }, + { 14519919, 12016224, 7500, 30, 280, 10 }, + { 9937580, 6517372, 0, 60, 400, 20 }, }; for (const auto &entry : list) { if (!entry.tillStars || stars < entry.tillStars) { diff --git a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h index e821e21d75..51a0e695cb 100644 --- a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h +++ b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h @@ -16,8 +16,8 @@ namespace Calls::Group::Ui { using namespace ::Ui; struct StarsColoring { - QColor bg1; - QColor bg2; + int bg1 = 0; + int bg2 = 0; int tillStars = 0; int minutesPin = 0; int charactersMax = 0; diff --git a/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp b/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp index e97f7a3dcb..708d08b4a3 100644 --- a/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/continuous_sliders.h" #include "ui/widgets/popup_menu.h" #include "ui/wrap/slide_wrap.h" +#include "ui/color_int_conversion.h" #include "ui/dynamic_image.h" #include "ui/painter.h" #include "ui/vertical_list.h" @@ -126,16 +127,24 @@ struct Discreter { void PaidReactionSlider( not_null container, + const style::MediaSlider &st, int current, int max, - Fn changed) { + Fn changed, + Fn activeFgOverride = nullptr) { Expects(current >= 1 && current <= max); const auto slider = container->add( - object_ptr(container, st::paidReactSlider), + object_ptr(container, st), st::boxRowPadding + QMargins(0, st::paidReactSliderTop, 0, 0)); slider->resize(slider->width(), st::paidReactSlider.seekSize.height()); + const auto update = [=](int count) { + if (activeFgOverride) { + slider->setActiveFgOverride(activeFgOverride(count)); + } + }; + const auto discreter = DiscreterForMax(max); slider->setAlwaysDisplayMarker(true); slider->setDirection(ContinuousSlider::Direction::Horizontal); @@ -144,12 +153,14 @@ void PaidReactionSlider( return discreter.valueToRatio(discreter.ratioToValue(ratio)); }); const auto ratioToValue = discreter.ratioToValue; - slider->setChangeProgressCallback([=](float64 value) { - changed(ratioToValue(value)); - }); - slider->setChangeFinishedCallback([=](float64 value) { - changed(ratioToValue(value)); - }); + const auto callback = [=](float64 value) { + const auto count = ratioToValue(value); + update(count); + changed(count); + }; + slider->setChangeProgressCallback(callback); + slider->setChangeFinishedCallback(callback); + update(current); struct State { StarParticles particles = StarParticles( @@ -527,7 +538,12 @@ void PaidReactionsBox( .ratio = correct / full, }; }); - Premium::AddBubbleRow( + const auto activeFgOverride = [=](int count) { + const auto coloring = Calls::Group::Ui::StarsColoringForCount(count); + return Ui::ColorFromSerialized(coloring.bg2); + }; + + const auto bubble = Premium::AddBubbleRow( content, st::boostBubble, BoxShowFinishes(box), @@ -536,12 +552,23 @@ void PaidReactionsBox( nullptr, &st::paidReactBubbleIcon, st::boxRowPadding); + if (args.videoStreamChoosing) { + state->chosen.value() | rpl::start_with_next([=](int count) { + bubble->setBrushOverride(activeFgOverride(count)); + }, bubble->lifetime()); + } const auto already = ranges::find( args.top, true, &PaidReactionTop::my)->count; - PaidReactionSlider(content, args.chosen, args.max, changed); + PaidReactionSlider( + content, + (dark ? st::darkEditStarsSlider : st::paidReactSlider), + args.chosen, + args.max, + changed, + args.videoStreamChoosing ? activeFgOverride : Fn()); box->addTopButton( dark ? st::darkEditStarsClose : st::boxTitleClose, diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index 48466390e0..bbaee12c9d 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -436,6 +436,11 @@ paidReactSlider: MediaSlider(defaultContinuousSlider) { borderFg: creditsBg3; borderWidth: 2px; } +darkEditStarsSlider: MediaSlider(paidReactSlider) { + inactiveFg: groupCallMembersBgOver; + inactiveFgOver: groupCallMembersBgOver; + inactiveFgDisabled: groupCallMembersBgOver; +} paidReactTitleSkip: 23px; paidReactTopTitleMargin: margins(10px, 26px, 10px, 12px); paidReactTopMargin: margins(0px, 12px, 0px, 11px); diff --git a/Telegram/SourceFiles/ui/effects/premium_bubble.cpp b/Telegram/SourceFiles/ui/effects/premium_bubble.cpp index 7e5025cc70..7f7eb798bf 100644 --- a/Telegram/SourceFiles/ui/effects/premium_bubble.cpp +++ b/Telegram/SourceFiles/ui/effects/premium_bubble.cpp @@ -487,6 +487,11 @@ void BubbleWidget::animateTo(BubbleRowState state) { anim::easeOutCirc); } +void BubbleWidget::setBrushOverride(std::optional brushOverride) { + _brushOverride = std::move(brushOverride); + update(); +} + void BubbleWidget::paintEvent(QPaintEvent *e) { if (!_bubble.counter().has_value()) { return; @@ -545,6 +550,9 @@ void BubbleWidget::paintEvent(QPaintEvent *e) { _bubble.paintBubble(p, bubbleRect, [&] { + if (_brushOverride) { + return *_brushOverride; + } switch (_type) { case BubbleType::NoPremium: case BubbleType::UpgradePrice: @@ -561,7 +569,7 @@ void BubbleWidget::resizeEvent(QResizeEvent *e) { RpWidget::resizeEvent(e); } -void AddBubbleRow( +not_null AddBubbleRow( not_null parent, const style::PremiumBubble &st, rpl::producer<> showFinishes, @@ -571,7 +579,7 @@ void AddBubbleRow( BubbleType type, std::optional> phrase, const style::icon *icon) { - AddBubbleRow( + return AddBubbleRow( parent, st, std::move(showFinishes), @@ -585,7 +593,7 @@ void AddBubbleRow( st::boxRowPadding); } -void AddBubbleRow( +not_null AddBubbleRow( not_null parent, const style::PremiumBubble &st, rpl::producer<> showFinishes, @@ -612,6 +620,7 @@ void AddBubbleRow( container->resize(parentSize.width(), size.height()); }, bubble->lifetime()); bubble->show(); + return bubble; } } // namespace Ui::Premium diff --git a/Telegram/SourceFiles/ui/effects/premium_bubble.h b/Telegram/SourceFiles/ui/effects/premium_bubble.h index ec3e83a7ec..8937519700 100644 --- a/Telegram/SourceFiles/ui/effects/premium_bubble.h +++ b/Telegram/SourceFiles/ui/effects/premium_bubble.h @@ -118,6 +118,8 @@ public: const style::icon *icon, const style::margins &outerPadding); + void setBrushOverride(std::optional brushOverride); + protected: void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; @@ -142,6 +144,7 @@ private: float64 _animatingFromBubbleEdge = 0.; rpl::variable _state; Bubble _bubble; + std::optional _brushOverride; const BubbleType _type; const style::margins _outerPadding; @@ -163,7 +166,7 @@ private: }; -void AddBubbleRow( +not_null AddBubbleRow( not_null parent, const style::PremiumBubble &st, rpl::producer<> showFinishes, @@ -174,7 +177,7 @@ void AddBubbleRow( std::optional> phrase, const style::icon *icon); -void AddBubbleRow( +not_null AddBubbleRow( not_null parent, const style::PremiumBubble &st, rpl::producer<> showFinishes,