Added ripple animation to stop recording voice button.

This commit is contained in:
23rd 2020-11-13 05:13:49 +03:00 committed by John Preston
parent eadd952e66
commit c9314e5e5e
2 changed files with 35 additions and 13 deletions

View file

@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_layers.h" #include "styles/style_layers.h"
#include "styles/style_media_player.h" #include "styles/style_media_player.h"
#include "ui/controls/send_button.h" #include "ui/controls/send_button.h"
#include "ui/effects/ripple_animation.h"
#include "ui/text/format_values.h" #include "ui/text/format_values.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -604,15 +605,19 @@ rpl::lifetime &ListenWrap::lifetime() {
return _lifetime; return _lifetime;
} }
class RecordLock final : public Ui::RpWidget { class RecordLock final : public Ui::RippleButton {
public: public:
RecordLock(not_null<Ui::RpWidget*> parent); RecordLock(not_null<Ui::RpWidget*> parent);
void requestPaintProgress(float64 progress); void requestPaintProgress(float64 progress);
[[nodiscard]] rpl::producer<> stops() const;
[[nodiscard]] rpl::producer<> locks() const; [[nodiscard]] rpl::producer<> locks() const;
[[nodiscard]] bool isLocked() const; [[nodiscard]] bool isLocked() const;
[[nodiscard]] bool isStopState() const;
protected:
QImage prepareRippleMask() const override;
QPoint prepareRippleStartPosition() const override;
private: private:
void init(); void init();
@ -621,6 +626,7 @@ private:
void setProgress(float64 progress); void setProgress(float64 progress);
void startLockingAnimation(float64 to); void startLockingAnimation(float64 to);
const QRect _rippleRect;
const QPen _arcPen; const QPen _arcPen;
Ui::Animations::Simple _lockAnimation; Ui::Animations::Simple _lockAnimation;
@ -630,7 +636,13 @@ private:
}; };
RecordLock::RecordLock(not_null<Ui::RpWidget*> parent) RecordLock::RecordLock(not_null<Ui::RpWidget*> parent)
: RpWidget(parent) : RippleButton(parent, st::defaultRippleAnimation)
, _rippleRect(QRect(
0,
0,
st::historyRecordLockTopShadow.width(),
st::historyRecordLockTopShadow.width())
.marginsRemoved(st::historyRecordLockRippleMargin))
, _arcPen( , _arcPen(
st::historyRecordLockIconFg, st::historyRecordLockIconFg,
st::historyRecordLockIconLineWidth, st::historyRecordLockIconLineWidth,
@ -755,6 +767,9 @@ void RecordLock::drawProgress(Painter &p) {
arrow.paintInCenter(p, arrowRect); arrow.paintInCenter(p, arrowRect);
p.setOpacity(1.); p.setOpacity(1.);
} }
if (isLocked()) {
paintRipple(p, _rippleRect.x(), _rippleRect.y());
}
{ {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
const auto &size = st::historyRecordLockIconSize; const auto &size = st::historyRecordLockIconSize;
@ -833,18 +848,21 @@ bool RecordLock::isLocked() const {
return _progress.current() == 1.; return _progress.current() == 1.;
} }
bool RecordLock::isStopState() const {
return isLocked() && (_lockAnimation.value(1.) == 1.);
}
rpl::producer<> RecordLock::locks() const { rpl::producer<> RecordLock::locks() const {
return _progress.changes( return _progress.changes(
) | rpl::filter([=] { return isLocked(); }) | rpl::to_empty; ) | rpl::filter([=] { return isLocked(); }) | rpl::to_empty;
} }
rpl::producer<> RecordLock::stops() const { QImage RecordLock::prepareRippleMask() const {
return events( return Ui::RippleAnimation::ellipseMask(_rippleRect.size());
) | rpl::filter([=](not_null<QEvent*> e) { }
return isLocked()
&& (_lockAnimation.value(1.) == 1.) QPoint RecordLock::prepareRippleStartPosition() const {
&& (e->type() == QEvent::MouseButtonRelease); return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft();
}) | rpl::to_empty;
} }
VoiceRecordBar::VoiceRecordBar( VoiceRecordBar::VoiceRecordBar(
@ -996,8 +1014,11 @@ void VoiceRecordBar::init() {
_showLockAnimation.start(std::move(callback), from, to, duration); _showLockAnimation.start(std::move(callback), from, to, duration);
}, lifetime()); }, lifetime());
_lock->stops( _lock->setClickedCallback([=] {
) | rpl::start_with_next([=] { if (!_lock->isStopState()) {
return;
}
::Media::Capture::instance()->startedChanges( ::Media::Capture::instance()->startedChanges(
) | rpl::filter([=](auto capturing) { ) | rpl::filter([=](auto capturing) {
return !capturing && _listen; return !capturing && _listen;
@ -1018,7 +1039,7 @@ void VoiceRecordBar::init() {
}, lifetime()); }, lifetime());
stopRecording(StopType::Listen); stopRecording(StopType::Listen);
}, lifetime()); });
_lock->locks( _lock->locks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {

View file

@ -380,6 +380,7 @@ historyRecordLockBodyShadow: icon {{ "voice_lock/record_lock_body_shadow", histo
historyRecordLockBody: icon {{ "voice_lock/record_lock_body", historyToDownBg }}; historyRecordLockBody: icon {{ "voice_lock/record_lock_body", historyToDownBg }};
historyRecordLockMargin: margins(4px, 4px, 4px, 4px); historyRecordLockMargin: margins(4px, 4px, 4px, 4px);
historyRecordLockArrow: icon {{ "voice_lock/voice_arrow", historyToDownFg }}; historyRecordLockArrow: icon {{ "voice_lock/voice_arrow", historyToDownFg }};
historyRecordLockRippleMargin: margins(5px, 5px, 5px, 5px);
historyRecordDelete: IconButton(historyAttach) { historyRecordDelete: IconButton(historyAttach) {
icon: icon {{ "info_media_delete", historyComposeIconFg }}; icon: icon {{ "info_media_delete", historyComposeIconFg }};