diff --git a/ui/widgets/call_mute_button.cpp b/ui/widgets/call_mute_button.cpp index d820f07..3801b75 100644 --- a/ui/widgets/call_mute_button.cpp +++ b/ui/widgets/call_mute_button.cpp @@ -7,6 +7,7 @@ #include "ui/widgets/call_mute_button.h" #include "base/event_filter.h" +#include "ui/effects/radial_animation.h" #include "ui/paint/blobs.h" #include "ui/painter.h" @@ -92,6 +93,10 @@ bool IsMuted(CallMuteButtonType type) { return (type != CallMuteButtonType::Active); } +bool IsConnecting(CallMuteButtonType type) { + return (type == CallMuteButtonType::Connecting); +} + } // namespace class BlobsWidget final : public RpWidget { @@ -179,6 +184,7 @@ CallMuteButton::CallMuteButton( : _state(initial) , _blobs(base::make_unique_q(parent)) , _content(parent, st::callMuteButtonActive, &st::callMuteButtonMuted) +, _radial(nullptr) , _colors(Colors()) , _crossLineMuteAnimation(st::callMuteCrossLine) { init(); @@ -192,6 +198,21 @@ void CallMuteButton::init() { }); _content.setText(std::move(text)); + _radialShowProgress.value( + ) | rpl::start_with_next([=](float64 value) { + if (((value == 0.) || anim::Disabled()) && _radial) { + _radial->stop(); + _radial = nullptr; + return; + } + if ((value > 0.) && !anim::Disabled() && !_radial) { + _radial = std::make_unique( + [=] { _content.update(); }, + st::callConnectingRadial); + _radial->start(); + } + }, lifetime()); + // State type. const auto previousType = lifetime().make_state(_state.current().type); @@ -206,6 +227,9 @@ void CallMuteButton::init() { const auto crossFrom = IsMuted(previous) ? 0. : 1.; const auto crossTo = IsMuted(type) ? 0. : 1.; + const auto radialShowFrom = IsConnecting(previous) ? 1. : 0.; + const auto radialShowTo = IsConnecting(type) ? 1. : 0.; + const auto gradient = anim::linear_gradient( _colors.at(previous), _colors.at(type), @@ -218,12 +242,20 @@ void CallMuteButton::init() { auto callback = [=](float64 value) { _blobs->setBrush(QBrush(gradient.gradient(value))); - const auto crossProgress = - InterpolateF(crossFrom, crossTo, value); + const auto crossProgress = (crossFrom == crossTo) + ? crossTo + : InterpolateF(crossFrom, crossTo, value); if (crossProgress != _crossLineProgress) { _crossLineProgress = crossProgress; _content.update(_muteIconPosition); } + + const auto radialShowProgress = (radialShowFrom == radialShowTo) + ? radialShowTo + : InterpolateF(radialShowFrom, radialShowTo, value); + if (radialShowProgress != _radialShowProgress.current()) { + _radialShowProgress = radialShowProgress; + } }; _switchAnimation.stop(); @@ -265,6 +297,14 @@ void CallMuteButton::contentPaint() { const auto progress = 1. - _crossLineProgress; _crossLineMuteAnimation.paint(p, _muteIconPosition.topLeft(), progress); + + if (_radial) { + p.setOpacity(_radialShowProgress.current()); + _radial->draw( + p, + st::callMuteButtonActive.bgPosition, + _content.width()); + } } void CallMuteButton::setState(const CallMuteButtonState &state) { @@ -321,7 +361,9 @@ void CallMuteButton::lower() { } rpl::lifetime &CallMuteButton::lifetime() { - return _content.lifetime(); + return _blobs->lifetime(); } +CallMuteButton::~CallMuteButton() = default; + } // namespace Ui diff --git a/ui/widgets/call_mute_button.h b/ui/widgets/call_mute_button.h index 92f72ef..6d59e30 100644 --- a/ui/widgets/call_mute_button.h +++ b/ui/widgets/call_mute_button.h @@ -16,6 +16,7 @@ namespace Ui { class BlobsWidget; +class InfiniteRadialAnimation; enum class CallMuteButtonType { Connecting, @@ -34,6 +35,7 @@ public: explicit CallMuteButton( not_null parent, CallMuteButtonState initial = CallMuteButtonState()); + ~CallMuteButton(); void setState(const CallMuteButtonState &state); void setLevel(float level); @@ -62,11 +64,13 @@ private: rpl::variable _state; float _level = 0.; float64 _crossLineProgress = 0.; + rpl::variable _radialShowProgress = 0.; QRect _muteIconPosition; const base::unique_qptr _blobs; CallButton _content; + std::unique_ptr _radial; const std::unordered_map> _colors; CrossLineAnimation _crossLineMuteAnimation; diff --git a/ui/widgets/widgets.style b/ui/widgets/widgets.style index db95ef1..662ea2b 100644 --- a/ui/widgets/widgets.style +++ b/ui/widgets/widgets.style @@ -1453,6 +1453,12 @@ callMuteCrossLine: CrossLineAnimation { stroke: 4px; } +callConnectingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) { + color: lightButtonFg; + thickness: 4px; + size: size(100px, 100px); +} + // Windows specific title windowTitleButton: IconButton {