Added blobs widget to CallMuteButton.
This commit is contained in:
parent
df8eed9576
commit
024f777287
2 changed files with 166 additions and 3 deletions
|
|
@ -6,14 +6,147 @@
|
||||||
//
|
//
|
||||||
#include "ui/widgets/call_mute_button.h"
|
#include "ui/widgets/call_mute_button.h"
|
||||||
|
|
||||||
|
#include "ui/paint/blobs.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
|
||||||
|
#include "styles/palette.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kMaxLevel = 1.;
|
||||||
|
|
||||||
|
constexpr auto kLevelDuration = 100. + 500. * 0.33;
|
||||||
|
|
||||||
|
constexpr auto kScaleBig = 0.807 - 0.1;
|
||||||
|
constexpr auto kScaleSmall = 0.704 - 0.1;
|
||||||
|
|
||||||
|
constexpr auto kScaleBigMin = 0.878;
|
||||||
|
constexpr auto kScaleSmallMin = 0.926;
|
||||||
|
|
||||||
|
constexpr auto kScaleBigMax = kScaleBigMin + kScaleBig;
|
||||||
|
constexpr auto kScaleSmallMax = kScaleSmallMin + kScaleSmall;
|
||||||
|
|
||||||
|
constexpr auto kMainRadiusFactor = 50. / 57.;
|
||||||
|
|
||||||
|
constexpr auto kSwitchStateDuration = 120;
|
||||||
|
|
||||||
|
constexpr auto MuteBlobs() -> std::array<Paint::Blobs::BlobData, 3> {
|
||||||
|
return {{
|
||||||
|
{
|
||||||
|
.segmentsCount = 6,
|
||||||
|
.minScale = 1.,
|
||||||
|
.minRadius = 57. * kMainRadiusFactor,
|
||||||
|
.maxRadius = 63. * kMainRadiusFactor,
|
||||||
|
.speedScale = .4,
|
||||||
|
.alpha = 1.,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.segmentsCount = 9,
|
||||||
|
.minScale = kScaleSmallMin / kScaleSmallMax,
|
||||||
|
.minRadius = 62 * kScaleSmallMax * kMainRadiusFactor,
|
||||||
|
.maxRadius = 72 * kScaleSmallMax * kMainRadiusFactor,
|
||||||
|
.speedScale = 1.,
|
||||||
|
.alpha = (76. / 255.),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.segmentsCount = 12,
|
||||||
|
.minScale = kScaleBigMin / kScaleBigMax,
|
||||||
|
.minRadius = 65 * kScaleBigMax * kMainRadiusFactor,
|
||||||
|
.maxRadius = 75 * kScaleBigMax * kMainRadiusFactor,
|
||||||
|
.speedScale = 1.,
|
||||||
|
.alpha = (76. / 255.),
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class BlobsWidget final : public RpWidget {
|
||||||
|
public:
|
||||||
|
BlobsWidget(not_null<RpWidget*> parent);
|
||||||
|
|
||||||
|
void setLevel(float level);
|
||||||
|
void requestPaintProgress(float64 progress);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
Paint::Blobs _blobs;
|
||||||
|
|
||||||
|
int _center = 0;
|
||||||
|
float64 _progress = 0;
|
||||||
|
|
||||||
|
Animations::Basic _animation;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
BlobsWidget::BlobsWidget(not_null<RpWidget*> parent)
|
||||||
|
: RpWidget(parent)
|
||||||
|
, _blobs(MuteBlobs() | ranges::to_vector, kLevelDuration, kMaxLevel) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlobsWidget::init() {
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
|
const auto maxBlobDiameter = _blobs.maxRadius() * 2;
|
||||||
|
resize(maxBlobDiameter, maxBlobDiameter);
|
||||||
|
|
||||||
|
const auto gradient = anim::linear_gradient(
|
||||||
|
{ st::groupCallMuted1->c, st::groupCallMuted2->c },
|
||||||
|
{ st::groupCallLive1->c, st::groupCallLive2->c },
|
||||||
|
QPoint(0, height()),
|
||||||
|
QPoint(width(), 0));
|
||||||
|
|
||||||
|
sizeValue(
|
||||||
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
_center = size.width() / 2;
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Painter p(this);
|
||||||
|
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.translate(_center, _center);
|
||||||
|
_blobs.paint(p, QBrush(gradient.gradient(_progress)));
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
_animation.init([=](crl::time now) {
|
||||||
|
const auto dt = now - _animation.started();
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
shownValue(
|
||||||
|
) | rpl::start_with_next([=](bool shown) {
|
||||||
|
if (shown) {
|
||||||
|
_animation.start();
|
||||||
|
} else {
|
||||||
|
_animation.stop();
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlobsWidget::setLevel(float level) {
|
||||||
|
_blobs.setLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlobsWidget::requestPaintProgress(float64 progress) {
|
||||||
|
if (progress == _progress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_progress = progress;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
CallMuteButton::CallMuteButton(
|
CallMuteButton::CallMuteButton(
|
||||||
not_null<QWidget*> parent,
|
not_null<RpWidget*> parent,
|
||||||
CallMuteButtonState initial)
|
CallMuteButtonState initial)
|
||||||
: _state(initial)
|
: _state(initial)
|
||||||
|
, _blobs(base::make_unique_q<BlobsWidget>(parent))
|
||||||
, _content(parent, st::callMuteButtonActive, &st::callMuteButtonMuted)
|
, _content(parent, st::callMuteButtonActive, &st::callMuteButtonMuted)
|
||||||
, _connecting(parent, st::callMuteButtonConnecting) {
|
, _connecting(parent, st::callMuteButtonConnecting) {
|
||||||
if (_state.type == CallMuteButtonType::Connecting
|
if (_state.type == CallMuteButtonType::Connecting
|
||||||
|
|
@ -45,12 +178,25 @@ void CallMuteButton::setState(const CallMuteButtonState &state) {
|
||||||
if (_state.text != state.text) {
|
if (_state.text != state.text) {
|
||||||
_content.setText(rpl::single(state.text));
|
_content.setText(rpl::single(state.text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto isWasActive = (_state.type == CallMuteButtonType::Active);
|
||||||
|
const auto isActive = (state.type == CallMuteButtonType::Active);
|
||||||
|
{
|
||||||
|
const auto from = _switchAnimation.value(isWasActive ? 1. : 0.);
|
||||||
|
const auto to = isActive ? 1. : 0.;
|
||||||
|
_switchAnimation.start(
|
||||||
|
[=](auto value) { _blobs->requestPaintProgress(value); },
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
kSwitchStateDuration);
|
||||||
|
}
|
||||||
|
|
||||||
_content.setProgress((state.type == CallMuteButtonType::Muted) ? 1. : 0.);
|
_content.setProgress((state.type == CallMuteButtonType::Muted) ? 1. : 0.);
|
||||||
if (!_connecting.isHidden() || !_content.isHidden()) {
|
if (!_connecting.isHidden() || !_content.isHidden()) {
|
||||||
_content.show();
|
_content.show();
|
||||||
}
|
}
|
||||||
_connecting.hide();
|
_connecting.hide();
|
||||||
if (state.type == CallMuteButtonType::Active) {
|
if (isActive) {
|
||||||
_content.setOuterValue(_level);
|
_content.setOuterValue(_level);
|
||||||
} else {
|
} else {
|
||||||
_content.setOuterValue(0.);
|
_content.setOuterValue(0.);
|
||||||
|
|
@ -61,6 +207,7 @@ void CallMuteButton::setState(const CallMuteButtonState &state) {
|
||||||
|
|
||||||
void CallMuteButton::setLevel(float level) {
|
void CallMuteButton::setLevel(float level) {
|
||||||
_level = level;
|
_level = level;
|
||||||
|
_blobs->setLevel(level);
|
||||||
if (_state.type == CallMuteButtonType::Active) {
|
if (_state.type == CallMuteButtonType::Active) {
|
||||||
_content.setOuterValue(level);
|
_content.setOuterValue(level);
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +234,13 @@ void CallMuteButton::moveInner(QPoint position) {
|
||||||
const auto skip = st::callMuteButtonActive.outerRadius;
|
const auto skip = st::callMuteButtonActive.outerRadius;
|
||||||
_content.move(position - QPoint(skip, skip));
|
_content.move(position - QPoint(skip, skip));
|
||||||
_connecting.move(_content.pos());
|
_connecting.move(_content.pos());
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto offset = QPoint(
|
||||||
|
(_blobs->width() - _content.width()) / 2,
|
||||||
|
(_blobs->height() - _content.width()) / 2);
|
||||||
|
_blobs->move(_content.pos() - offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallMuteButton::setVisible(bool visible) {
|
void CallMuteButton::setVisible(bool visible) {
|
||||||
|
|
@ -102,6 +256,7 @@ void CallMuteButton::setVisible(bool visible) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallMuteButton::raise() {
|
void CallMuteButton::raise() {
|
||||||
|
_blobs->raise();
|
||||||
_content.raise();
|
_content.raise();
|
||||||
_connecting.raise();
|
_connecting.raise();
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +264,7 @@ void CallMuteButton::raise() {
|
||||||
void CallMuteButton::lower() {
|
void CallMuteButton::lower() {
|
||||||
_content.lower();
|
_content.lower();
|
||||||
_connecting.lower();
|
_connecting.lower();
|
||||||
|
_blobs->lower();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::lifetime &CallMuteButton::lifetime() {
|
rpl::lifetime &CallMuteButton::lifetime() {
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,14 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/unique_qptr.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/widgets/call_button.h"
|
#include "ui/widgets/call_button.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
class BlobsWidget;
|
||||||
|
|
||||||
enum class CallMuteButtonType {
|
enum class CallMuteButtonType {
|
||||||
Connecting,
|
Connecting,
|
||||||
Active,
|
Active,
|
||||||
|
|
@ -25,7 +29,7 @@ struct CallMuteButtonState {
|
||||||
class CallMuteButton final {
|
class CallMuteButton final {
|
||||||
public:
|
public:
|
||||||
explicit CallMuteButton(
|
explicit CallMuteButton(
|
||||||
not_null<QWidget*> parent,
|
not_null<RpWidget*> parent,
|
||||||
CallMuteButtonState initial = CallMuteButtonState());
|
CallMuteButtonState initial = CallMuteButtonState());
|
||||||
|
|
||||||
void setState(const CallMuteButtonState &state);
|
void setState(const CallMuteButtonState &state);
|
||||||
|
|
@ -52,9 +56,12 @@ private:
|
||||||
CallMuteButtonState _state;
|
CallMuteButtonState _state;
|
||||||
float _level = 0.;
|
float _level = 0.;
|
||||||
|
|
||||||
|
const base::unique_qptr<BlobsWidget> _blobs;
|
||||||
CallButton _content;
|
CallButton _content;
|
||||||
CallButton _connecting;
|
CallButton _connecting;
|
||||||
|
|
||||||
|
Animations::Simple _switchAnimation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue