Replaced CallButton with AbstractButton in mute button.

This commit is contained in:
23rd 2020-12-11 09:54:22 +03:00
parent d61e1a7bde
commit 37d939a650
2 changed files with 76 additions and 64 deletions

View file

@ -6,12 +6,14 @@
// //
#include "ui/widgets/call_mute_button.h" #include "ui/widgets/call_mute_button.h"
#include "base/event_filter.h"
#include "base/flat_map.h" #include "base/flat_map.h"
#include "ui/abstract_button.h"
#include "ui/effects/gradient.h" #include "ui/effects/gradient.h"
#include "ui/effects/radial_animation.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"
#include "ui/widgets/call_button.h"
#include "ui/widgets/labels.h"
#include "styles/palette.h" #include "styles/palette.h"
#include "styles/style_widgets.h" #include "styles/style_widgets.h"
@ -46,8 +48,8 @@ constexpr auto kOverrideColorRippleAlpha = 50;
constexpr auto kSwitchStateDuration = 120; constexpr auto kSwitchStateDuration = 120;
auto MuteBlobs() -> std::array<Paint::Blobs::BlobData, 3> { auto MuteBlobs() {
return {{ return std::vector<Paint::Blobs::BlobData>{
{ {
.segmentsCount = 6, .segmentsCount = 6,
.minScale = 1., .minScale = 1.,
@ -82,7 +84,7 @@ auto MuteBlobs() -> std::array<Paint::Blobs::BlobData, 3> {
.speedScale = 1., .speedScale = 1.,
.alpha = (76. / 255.), .alpha = (76. / 255.),
}, },
}}; };
} }
auto Colors() { auto Colors() {
@ -158,7 +160,7 @@ BlobsWidget::BlobsWidget(
not_null<RpWidget*> parent, not_null<RpWidget*> parent,
rpl::producer<bool> &&hideBlobs) rpl::producer<bool> &&hideBlobs)
: RpWidget(parent) : RpWidget(parent)
, _blobs(MuteBlobs() | ranges::to_vector, kLevelDuration, kMaxLevel) , _blobs(MuteBlobs(), kLevelDuration, kMaxLevel)
, _blobBrush(Qt::transparent) , _blobBrush(Qt::transparent)
, _glowBrush(Qt::transparent) , _glowBrush(Qt::transparent)
, _blobsLastTime(crl::now()) { , _blobsLastTime(crl::now()) {
@ -278,6 +280,7 @@ CallMuteButton::CallMuteButton(
rpl::producer<bool> &&hideBlobs, rpl::producer<bool> &&hideBlobs,
CallMuteButtonState initial) CallMuteButtonState initial)
: _state(initial) : _state(initial)
, _st(st::callMuteButtonActive)
, _blobs(base::make_unique_q<BlobsWidget>( , _blobs(base::make_unique_q<BlobsWidget>(
parent, parent,
rpl::combine( rpl::combine(
@ -290,25 +293,40 @@ CallMuteButton::CallMuteButton(
) | rpl::map([](bool animDisabled, bool hide, bool isConnecting) { ) | rpl::map([](bool animDisabled, bool hide, bool isConnecting) {
return isConnecting || !(!animDisabled && !hide); return isConnecting || !(!animDisabled && !hide);
}))) })))
, _content(parent, st::callMuteButtonActive, &st::callMuteButtonMuted) , _content(base::make_unique_q<AbstractButton>(parent))
, _label(base::make_unique_q<FlatLabel>(
_content,
_state.value(
) | rpl::map([](const CallMuteButtonState &state) {
return state.text;
}),
_st.label))
, _radial(nullptr) , _radial(nullptr)
, _colors(Colors()) , _colors(Colors())
, _crossLineMuteAnimation(st::callMuteCrossLine) { , _crossLineMuteAnimation(st::callMuteCrossLine) {
init(); init();
}
void CallMuteButton::init() {
_content->resize(_st.button.width, _st.button.height);
style::PaletteChanged( style::PaletteChanged(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
_crossLineMuteAnimation.invalidate(); _crossLineMuteAnimation.invalidate();
}, lifetime()); }, lifetime());
}
void CallMuteButton::init() {
// Label text. // Label text.
auto text = _state.value( _label->show();
) | rpl::map([](const CallMuteButtonState &state) { rpl::combine(
return state.text; _content->sizeValue(),
}); _label->sizeValue()
_content.setText(std::move(text)); ) | rpl::start_with_next([=](QSize my, QSize label) {
_label->moveToLeft(
(my.width() - label.width()) / 2,
my.height() - label.height(),
my.width());
}, _label->lifetime());
_label->setAttribute(Qt::WA_TransparentForMouseEvents);
_radialShowProgress.value( _radialShowProgress.value(
) | rpl::start_with_next([=](float64 value) { ) | rpl::start_with_next([=](float64 value) {
@ -319,7 +337,7 @@ void CallMuteButton::init() {
} }
if ((value > 0.) && !anim::Disabled() && !_radial) { if ((value > 0.) && !anim::Disabled() && !_radial) {
_radial = std::make_unique<InfiniteRadialAnimation>( _radial = std::make_unique<InfiniteRadialAnimation>(
[=] { _content.update(); }, [=] { _content->update(); },
st::callConnectingRadial); st::callConnectingRadial);
_radial->start(); _radial->start();
} }
@ -387,7 +405,7 @@ void CallMuteButton::init() {
: InterpolateF(crossFrom, crossTo, value); : 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) const auto radialShowProgress = (radialShowFrom == radialShowTo)
@ -412,10 +430,10 @@ void CallMuteButton::init() {
}, lifetime()); }, lifetime());
// Icon rect. // Icon rect.
_content.sizeValue( _content->sizeValue(
) | rpl::start_with_next([=](QSize size) { ) | rpl::start_with_next([=](QSize size) {
const auto &icon = st::callMuteButtonActive.button.icon; const auto &icon = _st.button.icon;
const auto &pos = st::callMuteButtonActive.button.iconPosition; const auto &pos = _st.button.iconPosition;
_muteIconPosition = QRect( _muteIconPosition = QRect(
(pos.x() < 0) ? ((size.width() - icon.width()) / 2) : pos.x(), (pos.x() < 0) ? ((size.width() - icon.width()) / 2) : pos.x(),
@ -425,34 +443,23 @@ void CallMuteButton::init() {
}, lifetime()); }, lifetime());
// Paint. // Paint.
auto filterCallback = [=](not_null<QEvent*> e) { _content->paintRequest(
if (e->type() != QEvent::Paint) { ) | rpl::start_with_next([=](QRect clip) {
return base::EventFilterResult::Continue; Painter p(_content);
}
contentPaint();
return base::EventFilterResult::Cancel;
};
auto filter = base::install_event_filter( _crossLineMuteAnimation.paint(
&_content,
std::move(filterCallback));
lifetime().make_state<base::unique_qptr<QObject>>(std::move(filter));
}
void CallMuteButton::contentPaint() {
Painter p(&_content);
const auto progress = 1. - _crossLineProgress;
_crossLineMuteAnimation.paint(p, _muteIconPosition.topLeft(), progress);
if (_radial) {
p.setOpacity(_radialShowProgress.current());
_radial->draw(
p, p,
st::callMuteButtonActive.bgPosition, _muteIconPosition.topLeft(),
_content.width()); 1. - _crossLineProgress);
}
if (_radial) {
p.setOpacity(_radialShowProgress.current());
_radial->draw(
p,
_st.bgPosition,
_content->width());
}
}, _content->lifetime());
} }
void CallMuteButton::setState(const CallMuteButtonState &state) { void CallMuteButton::setState(const CallMuteButtonState &state) {
@ -465,7 +472,7 @@ void CallMuteButton::setLevel(float level) {
} }
rpl::producer<Qt::MouseButton> CallMuteButton::clicks() const { rpl::producer<Qt::MouseButton> CallMuteButton::clicks() const {
return _content.clicks(); return _content->clicks();
} }
QSize CallMuteButton::innerSize() const { QSize CallMuteButton::innerSize() const {
@ -473,43 +480,43 @@ QSize CallMuteButton::innerSize() const {
} }
QRect CallMuteButton::innerGeometry() const { QRect CallMuteButton::innerGeometry() const {
const auto skip = st::callMuteButtonActive.outerRadius; const auto &skip = _st.outerRadius;
return QRect( return QRect(
_content.x(), _content->x(),
_content.y(), _content->y(),
_content.width() - 2 * skip, _content->width() - 2 * skip,
_content.width() - 2 * skip); _content->width() - 2 * skip);
} }
void CallMuteButton::moveInner(QPoint position) { void CallMuteButton::moveInner(QPoint position) {
const auto skip = st::callMuteButtonActive.outerRadius; const auto &skip = _st.outerRadius;
_content.move(position - QPoint(skip, skip)); _content->move(position - QPoint(skip, skip));
{ {
const auto offset = QPoint( const auto offset = QPoint(
(_blobs->width() - _content.width()) / 2, (_blobs->width() - _content->width()) / 2,
(_blobs->height() - _content.width()) / 2); (_blobs->height() - _content->width()) / 2);
_blobs->move(_content.pos() - offset); _blobs->move(_content->pos() - offset);
} }
} }
void CallMuteButton::setVisible(bool visible) { void CallMuteButton::setVisible(bool visible) {
_content.setVisible(visible); _content->setVisible(visible);
_blobs->setVisible(visible); _blobs->setVisible(visible);
} }
void CallMuteButton::raise() { void CallMuteButton::raise() {
_blobs->raise(); _blobs->raise();
_content.raise(); _content->raise();
} }
void CallMuteButton::lower() { void CallMuteButton::lower() {
_content.lower(); _content->lower();
_blobs->lower(); _blobs->lower();
} }
void CallMuteButton::setEnableMouse(bool value) { void CallMuteButton::setEnableMouse(bool value) {
_content.setAttribute(Qt::WA_TransparentForMouseEvents, !value); _content->setAttribute(Qt::WA_TransparentForMouseEvents, !value);
} }
void CallMuteButton::overridesColors( void CallMuteButton::overridesColors(

View file

@ -9,14 +9,17 @@
#include "base/unique_qptr.h" #include "base/unique_qptr.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/effects/cross_line.h" #include "ui/effects/cross_line.h"
#include "ui/widgets/call_button.h"
#include <unordered_map>
namespace Ui { namespace Ui {
class BlobsWidget; class BlobsWidget;
class AbstractButton;
class FlatLabel;
class InfiniteRadialAnimation; class InfiniteRadialAnimation;
class RpWidget;
struct CallButtonColors;
enum class CallMuteButtonType { enum class CallMuteButtonType {
Connecting, Connecting,
@ -62,7 +65,6 @@ public:
private: private:
void init(); void init();
void contentPaint();
void overridesColors( void overridesColors(
CallMuteButtonType fromType, CallMuteButtonType fromType,
CallMuteButtonType toType, CallMuteButtonType toType,
@ -76,8 +78,11 @@ private:
rpl::variable<float64> _radialShowProgress = 0.; rpl::variable<float64> _radialShowProgress = 0.;
QRect _muteIconPosition; QRect _muteIconPosition;
const style::CallButton &_st;
const base::unique_qptr<BlobsWidget> _blobs; const base::unique_qptr<BlobsWidget> _blobs;
CallButton _content; const base::unique_qptr<AbstractButton> _content;
const base::unique_qptr<FlatLabel> _label;
std::unique_ptr<InfiniteRadialAnimation> _radial; std::unique_ptr<InfiniteRadialAnimation> _radial;
const base::flat_map<CallMuteButtonType, std::vector<QColor>> _colors; const base::flat_map<CallMuteButtonType, std::vector<QColor>> _colors;