From 50f87cce84f594e57f359432a8741e41d45c4375 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 18 Jan 2021 00:44:03 +0300 Subject: [PATCH] Added arcs animation to volume menu item in group calls. --- Telegram/SourceFiles/calls/calls.style | 15 ++++++ .../SourceFiles/calls/calls_volume_item.cpp | 51 +++++++++++++++++-- .../SourceFiles/calls/calls_volume_item.h | 8 +++ 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index bb5e042fdf..8f60171797 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -786,6 +786,21 @@ groupCallMuteCrossLine: CrossLineAnimation { stroke: 2px; } +groupCallMenuSpeakerArcsSkip: 1px; +groupCallMenuVolumeSkip: 5px; + +groupCallSpeakerArcsAnimation: ArcsAnimation { + fg: groupCallIconFg; + stroke: 2px; + space: 4px; + duration: 200; + deltaAngle: 60; + deltaHeight: 6px; + deltaWidth: 7px; + startHeight: 3px; + startWidth: 0px; +} + callTopBarMuteCrossLine: CrossLineAnimation { fg: callBarFg; icon: icon {{ "calls/call_record_active", callBarFg }}; diff --git a/Telegram/SourceFiles/calls/calls_volume_item.cpp b/Telegram/SourceFiles/calls/calls_volume_item.cpp index 15836eb06f..95ed0afda3 100644 --- a/Telegram/SourceFiles/calls/calls_volume_item.cpp +++ b/Telegram/SourceFiles/calls/calls_volume_item.cpp @@ -14,11 +14,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_calls.h" #include "styles/style_media_player.h" +#include "ui/paint/arcs.h" + namespace Calls { namespace { constexpr auto kMaxVolumePercent = 200; +constexpr auto kSpeakerThreshold = { + 10.0f / kMaxVolumePercent, + 50.0f / kMaxVolumePercent, + 150.0f / kMaxVolumePercent }; + } // namespace MenuVolumeItem::MenuVolumeItem( @@ -38,7 +45,12 @@ MenuVolumeItem::MenuVolumeItem( , _dummyAction(new QAction(parent)) , _st(st) , _stCross(st::groupCallMuteCrossLine) -, _crossLineMute(std::make_unique(_stCross, true)) { +, _crossLineMute(std::make_unique(_stCross, true)) +, _arcs(std::make_unique( + st::groupCallSpeakerArcsAnimation, + kSpeakerThreshold, + _localMuted ? 0. : (startVolume / float(maxVolume)), + Ui::Paint::ArcsAnimation::HorizontalDirection::Right)) { initResizeHook(parent->sizeValue()); enableMouseSelecting(); @@ -48,12 +60,18 @@ MenuVolumeItem::MenuVolumeItem( const auto geometry = QRect(QPoint(), size); _itemRect = geometry - _st.itemPadding; _speakerRect = QRect(_itemRect.topLeft(), _stCross.icon.size()); - _volumeRect = _speakerRect.translated(_stCross.icon.width(), 0); + _volumeRect = _speakerRect.translated( + _stCross.icon.width() + st::groupCallMenuVolumeSkip, + 0); + _arcPosition = _speakerRect.center() + + QPoint(0, st::groupCallMenuSpeakerArcsSkip); _slider->setGeometry(_itemRect - style::margins(0, contentHeight() / 2, 0, 0)); }, lifetime()); + setCloudVolume(startVolume); + paintRequest( ) | rpl::start_with_next([=](const QRect &clip) { Painter p(this); @@ -78,9 +96,12 @@ MenuVolumeItem::MenuVolumeItem( _speakerRect.topLeft(), muteProgress, (!muteProgress) ? std::nullopt : std::optional(mutePen)); - }, lifetime()); - setCloudVolume(startVolume); + { + p.translate(_arcPosition); + _arcs->paint(p); + } + }, lifetime()); _slider->setChangeProgressCallback([=](float64 value) { const auto newMuted = (value == 0); @@ -98,6 +119,7 @@ MenuVolumeItem::MenuVolumeItem( _changeVolumeLocallyRequests.fire(value * _maxVolume); } update(_volumeRect); + _arcs->setValue(value); }); const auto returnVolume = [=] { @@ -152,6 +174,27 @@ MenuVolumeItem::MenuVolumeItem( } _waitingForUpdateVolume = false; }, lifetime()); + + initArcsAnimation(); +} + +void MenuVolumeItem::initArcsAnimation() { + _arcsAnimation.init([=](crl::time now) { + _arcs->update(now); + update(_speakerRect); + }); + + _arcs->startUpdateRequests( + ) | rpl::start_with_next([=] { + if (!_arcsAnimation.animating()) { + _arcsAnimation.start(); + } + }, lifetime()); + + _arcs->stopUpdateRequests( + ) | rpl::start_with_next([=] { + _arcsAnimation.stop(); + }, lifetime()); } QColor MenuVolumeItem::unmuteColor() const { diff --git a/Telegram/SourceFiles/calls/calls_volume_item.h b/Telegram/SourceFiles/calls/calls_volume_item.h index a51888868c..5ba9258358 100644 --- a/Telegram/SourceFiles/calls/calls_volume_item.h +++ b/Telegram/SourceFiles/calls/calls_volume_item.h @@ -13,6 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class CrossLineAnimation; class MediaSlider; +namespace Paint { +class ArcsAnimation; +} // namespace Paint } // namespace Ui namespace Calls { @@ -45,6 +48,8 @@ protected: int contentHeight() const override; private: + void initArcsAnimation(); + void setCloudVolume(int volume); void setSliderVolume(int volume); @@ -60,6 +65,7 @@ private: QRect _itemRect; QRect _speakerRect; QRect _volumeRect; + QPoint _arcPosition; const base::unique_qptr _slider; const not_null _dummyAction; @@ -68,6 +74,8 @@ private: const std::unique_ptr _crossLineMute; Ui::Animations::Simple _crossLineAnimation; + const std::unique_ptr _arcs; + Ui::Animations::Basic _arcsAnimation; rpl::event_stream _toggleMuteRequests; rpl::event_stream _toggleMuteLocallyRequests;