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