diff --git a/ui/effects/cross_line.cpp b/ui/effects/cross_line.cpp index 5bede5b..a653ea3 100644 --- a/ui/effects/cross_line.cpp +++ b/ui/effects/cross_line.cpp @@ -21,6 +21,13 @@ CrossLineAnimation::CrossLineAnimation( _line.setAngle(angle); } +void CrossLineAnimation::paint( + Painter &p, + QPoint position, + float64 progress) { + paint(p, position.x(), position.y(), progress); +} + void CrossLineAnimation::paint( Painter &p, int left, diff --git a/ui/effects/cross_line.h b/ui/effects/cross_line.h index eb6edb5..0cf8d99 100644 --- a/ui/effects/cross_line.h +++ b/ui/effects/cross_line.h @@ -18,6 +18,7 @@ public: const style::CrossLineAnimation &st, float angle = 315); + void paint(Painter &p, QPoint position, float64 progress); void paint(Painter &p, int left, int top, float64 progress); private: diff --git a/ui/widgets/call_mute_button.cpp b/ui/widgets/call_mute_button.cpp index 857d65b..1ad8109 100644 --- a/ui/widgets/call_mute_button.cpp +++ b/ui/widgets/call_mute_button.cpp @@ -6,6 +6,7 @@ // #include "ui/widgets/call_mute_button.h" +#include "base/event_filter.h" #include "ui/paint/blobs.h" #include "ui/painter.h" @@ -148,7 +149,12 @@ CallMuteButton::CallMuteButton( : _state(initial) , _blobs(base::make_unique_q(parent)) , _content(parent, st::callMuteButtonActive, &st::callMuteButtonMuted) -, _connecting(parent, st::callMuteButtonConnecting) { +, _connecting(parent, st::callMuteButtonConnecting) +, _crossLineMuteAnimation(st::callMuteCrossLine) { + init(); +} + +void CallMuteButton::init() { if (_state.type == CallMuteButtonType::Connecting || _state.type == CallMuteButtonType::ForceMuted) { _connecting.setText(rpl::single(_state.text)); @@ -161,6 +167,37 @@ CallMuteButton::CallMuteButton( _content.show(); } _connecting.setAttribute(Qt::WA_TransparentForMouseEvents); + + _content.sizeValue( + ) | rpl::start_with_next([=](QSize size) { + const auto &icon = st::callMuteButtonActive.button.icon; + const auto &pos = st::callMuteButtonActive.button.iconPosition; + + _muteIconPosition = QPoint( + (pos.x() < 0) ? ((size.width() - icon.width()) / 2) : pos.x(), + (pos.y() < 0) ? ((size.height() - icon.height()) / 2) : pos.y()); + }, lifetime()); + + auto filterCallback = [=](not_null e) { + if (e->type() != QEvent::Paint) { + return base::EventFilterResult::Continue; + } + contentPaint(); + return base::EventFilterResult::Cancel; + }; + + auto filter = base::install_event_filter( + &_content, + std::move(filterCallback)); + + lifetime().make_state>(std::move(filter)); +} + +void CallMuteButton::contentPaint() { + Painter p(&_content); + + const auto progress = 1. - _crossLineProgress; + _crossLineMuteAnimation.paint(p, _muteIconPosition, progress); } void CallMuteButton::setState(const CallMuteButtonState &state) { @@ -185,7 +222,11 @@ void CallMuteButton::setState(const CallMuteButtonState &state) { const auto from = _switchAnimation.value(isWasActive ? 1. : 0.); const auto to = isActive ? 1. : 0.; _switchAnimation.start( - [=](auto value) { _blobs->requestPaintProgress(value); }, + [=](auto value) { + _blobs->requestPaintProgress(value); + _crossLineProgress = value; + _content.update(); + }, from, to, kSwitchStateDuration); diff --git a/ui/widgets/call_mute_button.h b/ui/widgets/call_mute_button.h index 45d1239..9df8504 100644 --- a/ui/widgets/call_mute_button.h +++ b/ui/widgets/call_mute_button.h @@ -8,6 +8,7 @@ #include "base/unique_qptr.h" #include "ui/effects/animations.h" +#include "ui/effects/cross_line.h" #include "ui/widgets/call_button.h" namespace Ui { @@ -53,13 +54,19 @@ public: [[nodiscard]] rpl::lifetime &lifetime(); private: + void init(); + void contentPaint(); + CallMuteButtonState _state; float _level = 0.; + float64 _crossLineProgress = 0.; + QPoint _muteIconPosition; const base::unique_qptr _blobs; CallButton _content; CallButton _connecting; + CrossLineAnimation _crossLineMuteAnimation; Animations::Simple _switchAnimation; }; diff --git a/ui/widgets/widgets.style b/ui/widgets/widgets.style index 0d2ffcd..db95ef1 100644 --- a/ui/widgets/widgets.style +++ b/ui/widgets/widgets.style @@ -1405,12 +1405,13 @@ defaultToast: Toast { durationSlide: 160; } +callMuteButtonActiveIcon: icon {{ "calls/voice_unmuted_large", groupCallIconFg }}; callMuteButtonActiveInner: IconButton { width: 136px; height: 151px; iconPosition: point(-1px, 50px); - icon: icon {{ "calls/voice_unmuted_large", groupCallIconFg }}; + icon: callMuteButtonActiveIcon; } callMuteButtonLabel: FlatLabel(defaultFlatLabel) { textFg: callNameFg; @@ -1444,6 +1445,14 @@ callMuteButtonConnecting: CallButton(callMuteButtonMuted) { label: callMuteButtonLabel; } +callMuteCrossLine: CrossLineAnimation { + fg: groupCallIconFg; + icon: callMuteButtonActiveIcon; + startPosition: point(7px, 2px); + endPosition: point(34px, 30px); + stroke: 4px; +} + // Windows specific title windowTitleButton: IconButton {