Added radial animation to mute button for connecting state.
This commit is contained in:
parent
4fdd0d19e6
commit
c9f003546a
3 changed files with 55 additions and 3 deletions
|
|
@ -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<BlobsWidget>(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<InfiniteRadialAnimation>(
|
||||
[=] { _content.update(); },
|
||||
st::callConnectingRadial);
|
||||
_radial->start();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
// State type.
|
||||
const auto previousType =
|
||||
lifetime().make_state<CallMuteButtonType>(_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
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
namespace Ui {
|
||||
|
||||
class BlobsWidget;
|
||||
class InfiniteRadialAnimation;
|
||||
|
||||
enum class CallMuteButtonType {
|
||||
Connecting,
|
||||
|
|
@ -34,6 +35,7 @@ public:
|
|||
explicit CallMuteButton(
|
||||
not_null<RpWidget*> parent,
|
||||
CallMuteButtonState initial = CallMuteButtonState());
|
||||
~CallMuteButton();
|
||||
|
||||
void setState(const CallMuteButtonState &state);
|
||||
void setLevel(float level);
|
||||
|
|
@ -62,11 +64,13 @@ private:
|
|||
rpl::variable<CallMuteButtonState> _state;
|
||||
float _level = 0.;
|
||||
float64 _crossLineProgress = 0.;
|
||||
rpl::variable<float64> _radialShowProgress = 0.;
|
||||
QRect _muteIconPosition;
|
||||
|
||||
const base::unique_qptr<BlobsWidget> _blobs;
|
||||
CallButton _content;
|
||||
|
||||
std::unique_ptr<InfiniteRadialAnimation> _radial;
|
||||
const std::unordered_map<CallMuteButtonType, std::vector<QColor>> _colors;
|
||||
|
||||
CrossLineAnimation _crossLineMuteAnimation;
|
||||
|
|
|
|||
|
|
@ -1453,6 +1453,12 @@ callMuteCrossLine: CrossLineAnimation {
|
|||
stroke: 4px;
|
||||
}
|
||||
|
||||
callConnectingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||
color: lightButtonFg;
|
||||
thickness: 4px;
|
||||
size: size(100px, 100px);
|
||||
}
|
||||
|
||||
// Windows specific title
|
||||
|
||||
windowTitleButton: IconButton {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue