mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-08 08:04:08 +02:00
Replaced recording animation with simple red circle animation.
This commit is contained in:
parent
ba3862e70f
commit
cab22c07a5
3 changed files with 40 additions and 44 deletions
|
@ -405,10 +405,7 @@ VoiceRecordBar::VoiceRecordBar(
|
||||||
, _level(std::make_unique<RecordLevel>(
|
, _level(std::make_unique<RecordLevel>(
|
||||||
parent,
|
parent,
|
||||||
_controller->widget()->leaveEvents()))
|
_controller->widget()->leaveEvents()))
|
||||||
, _cancelFont(st::historyRecordFont)
|
, _cancelFont(st::historyRecordFont) {
|
||||||
, _recordingAnimation([=](crl::time now) {
|
|
||||||
return recordingAnimationCallback(now);
|
|
||||||
}) {
|
|
||||||
resize(QSize(parent->width(), recorderHeight));
|
resize(QSize(parent->width(), recorderHeight));
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -470,8 +467,8 @@ void VoiceRecordBar::init() {
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
_centerY = size.height() / 2;
|
_centerY = size.height() / 2;
|
||||||
{
|
{
|
||||||
const auto maxD = st::historyRecordSignalMax * 2;
|
const auto maxD = st::historyRecordSignalRadius * 2;
|
||||||
const auto point = _centerY - st::historyRecordSignalMax;
|
const auto point = _centerY - st::historyRecordSignalRadius;
|
||||||
_redCircleRect = { point, point, maxD, maxD };
|
_redCircleRect = { point, point, maxD, maxD };
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -494,7 +491,7 @@ void VoiceRecordBar::init() {
|
||||||
) | rpl::start_with_next([=](const QRect &clip) {
|
) | rpl::start_with_next([=](const QRect &clip) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
if (_showAnimation.animating()) {
|
if (_showAnimation.animating()) {
|
||||||
p.setOpacity(_showAnimation.value(1.));
|
p.setOpacity(showAnimationRatio());
|
||||||
}
|
}
|
||||||
p.fillRect(clip, st::historyComposeAreaBg);
|
p.fillRect(clip, st::historyComposeAreaBg);
|
||||||
|
|
||||||
|
@ -502,12 +499,13 @@ void VoiceRecordBar::init() {
|
||||||
// The message should be painted first to avoid flickering.
|
// The message should be painted first to avoid flickering.
|
||||||
drawMessage(p, activeAnimationRatio());
|
drawMessage(p, activeAnimationRatio());
|
||||||
}
|
}
|
||||||
if (clip.intersects(_redCircleRect)) {
|
|
||||||
drawRecording(p);
|
|
||||||
}
|
|
||||||
if (clip.intersects(_durationRect)) {
|
if (clip.intersects(_durationRect)) {
|
||||||
drawDuration(p);
|
drawDuration(p);
|
||||||
}
|
}
|
||||||
|
if (clip.intersects(_redCircleRect)) {
|
||||||
|
// Should be the last to be drawn.
|
||||||
|
drawRedCircle(p);
|
||||||
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_inField.changes(
|
_inField.changes(
|
||||||
|
@ -635,6 +633,7 @@ void VoiceRecordBar::startRecording() {
|
||||||
// Show the lock widget after the first successful update.
|
// Show the lock widget after the first successful update.
|
||||||
*shown = true;
|
*shown = true;
|
||||||
_lockShowing = true;
|
_lockShowing = true;
|
||||||
|
startRedCircleAnimation();
|
||||||
}
|
}
|
||||||
recordUpdated(update.level, update.samples);
|
recordUpdated(update.level, update.samples);
|
||||||
}, [=] {
|
}, [=] {
|
||||||
|
@ -673,26 +672,8 @@ void VoiceRecordBar::startRecording() {
|
||||||
}, _recordingLifetime);
|
}, _recordingLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoiceRecordBar::recordingAnimationCallback(crl::time now) {
|
|
||||||
const auto dt = anim::Disabled()
|
|
||||||
? 1.
|
|
||||||
: ((now - _recordingAnimation.started())
|
|
||||||
/ float64(kRecordingUpdateDelta));
|
|
||||||
if (dt >= 1.) {
|
|
||||||
_recordingLevel.finish();
|
|
||||||
} else {
|
|
||||||
_recordingLevel.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (!anim::Disabled()) {
|
|
||||||
update(_redCircleRect);
|
|
||||||
}
|
|
||||||
return (dt < 1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoiceRecordBar::recordUpdated(quint16 level, int samples) {
|
void VoiceRecordBar::recordUpdated(quint16 level, int samples) {
|
||||||
_level->requestPaintLevel(level);
|
_level->requestPaintLevel(level);
|
||||||
_recordingLevel.start(level);
|
|
||||||
_recordingAnimation.start();
|
|
||||||
_recordingSamples = samples;
|
_recordingSamples = samples;
|
||||||
if (samples < 0 || samples >= kMaxSamples) {
|
if (samples < 0 || samples >= kMaxSamples) {
|
||||||
stop(samples > 0 && _inField.current());
|
stop(samples > 0 && _inField.current());
|
||||||
|
@ -711,8 +692,7 @@ void VoiceRecordBar::stop(bool send) {
|
||||||
|
|
||||||
stopRecording(send);
|
stopRecording(send);
|
||||||
|
|
||||||
_recordingLevel = anim::value();
|
_redCircleProgress = 0.;
|
||||||
_recordingAnimation.stop();
|
|
||||||
|
|
||||||
_inField = false;
|
_inField = false;
|
||||||
|
|
||||||
|
@ -754,17 +734,31 @@ void VoiceRecordBar::drawDuration(Painter &p) {
|
||||||
p.drawText(_durationRect, style::al_left, duration);
|
p.drawText(_durationRect, style::al_left, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceRecordBar::drawRecording(Painter &p) {
|
void VoiceRecordBar::startRedCircleAnimation() {
|
||||||
|
if (anim::Disabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto animation = _recordingLifetime
|
||||||
|
.make_state<Ui::Animations::Basic>();
|
||||||
|
animation->init([=](crl::time now) {
|
||||||
|
const auto diffTime = now - animation->started();
|
||||||
|
_redCircleProgress = std::abs(std::sin(diffTime / 400.));
|
||||||
|
update(_redCircleRect);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
animation->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoiceRecordBar::drawRedCircle(Painter &p) {
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::historyRecordSignalColor);
|
p.setBrush(st::historyRecordSignalColor);
|
||||||
|
|
||||||
const auto min = st::historyRecordSignalMin;
|
p.setOpacity(1. - _redCircleProgress);
|
||||||
const auto max = st::historyRecordSignalMax;
|
const int radii = st::historyRecordSignalRadius * showAnimationRatio();
|
||||||
const auto delta = std::min(_recordingLevel.current() / 0x4000, 1.);
|
|
||||||
const auto radii = qRound(min + (delta * (max - min)));
|
|
||||||
const auto center = _redCircleRect.center() + QPoint(1, 1);
|
const auto center = _redCircleRect.center() + QPoint(1, 1);
|
||||||
p.drawEllipse(center, radii, radii);
|
p.drawEllipse(center, radii, radii);
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) {
|
void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) {
|
||||||
|
@ -795,7 +789,6 @@ bool VoiceRecordBar::isRecording() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceRecordBar::finishAnimating() {
|
void VoiceRecordBar::finishAnimating() {
|
||||||
_recordingAnimation.stop();
|
|
||||||
_showAnimation.stop();
|
_showAnimation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,6 +822,12 @@ float64 VoiceRecordBar::activeAnimationRatio() const {
|
||||||
return _activeAnimation.value(_inField.current() ? 1. : 0.);
|
return _activeAnimation.value(_inField.current() ? 1. : 0.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float64 VoiceRecordBar::showAnimationRatio() const {
|
||||||
|
// There is no reason to set the final value to zero,
|
||||||
|
// because at zero this widget is hidden.
|
||||||
|
return _showAnimation.value(1.);
|
||||||
|
}
|
||||||
|
|
||||||
QString VoiceRecordBar::cancelMessage() const {
|
QString VoiceRecordBar::cancelMessage() const {
|
||||||
return _lock->isLocked()
|
return _lock->isLocked()
|
||||||
? tr::lng_record_lock_cancel(tr::now)
|
? tr::lng_record_lock_cancel(tr::now)
|
||||||
|
|
|
@ -70,15 +70,17 @@ private:
|
||||||
|
|
||||||
bool showRecordButton() const;
|
bool showRecordButton() const;
|
||||||
void drawDuration(Painter &p);
|
void drawDuration(Painter &p);
|
||||||
void drawRecording(Painter &p);
|
void drawRedCircle(Painter &p);
|
||||||
void drawMessage(Painter &p, float64 recordActive);
|
void drawMessage(Painter &p, float64 recordActive);
|
||||||
void updateOverStates(QPoint pos);
|
void updateOverStates(QPoint pos);
|
||||||
|
|
||||||
|
void startRedCircleAnimation();
|
||||||
void installClickOutsideFilter();
|
void installClickOutsideFilter();
|
||||||
|
|
||||||
bool isTypeRecord() const;
|
bool isTypeRecord() const;
|
||||||
|
|
||||||
void activeAnimate(bool active);
|
void activeAnimate(bool active);
|
||||||
|
float64 showAnimationRatio() const;
|
||||||
float64 activeAnimationRatio() const;
|
float64 activeAnimationRatio() const;
|
||||||
|
|
||||||
void computeAndSetLockProgress(QPoint globalPos);
|
void computeAndSetLockProgress(QPoint globalPos);
|
||||||
|
@ -105,6 +107,7 @@ private:
|
||||||
rpl::variable<bool> _recording = false;
|
rpl::variable<bool> _recording = false;
|
||||||
rpl::variable<bool> _inField = false;
|
rpl::variable<bool> _inField = false;
|
||||||
int _recordingSamples = 0;
|
int _recordingSamples = 0;
|
||||||
|
float64 _redCircleProgress = 0.;
|
||||||
|
|
||||||
const style::font &_cancelFont;
|
const style::font &_cancelFont;
|
||||||
|
|
||||||
|
@ -113,13 +116,8 @@ private:
|
||||||
rpl::variable<bool> _lockShowing = false;
|
rpl::variable<bool> _lockShowing = false;
|
||||||
|
|
||||||
Ui::Animations::Simple _showLockAnimation;
|
Ui::Animations::Simple _showLockAnimation;
|
||||||
|
|
||||||
// This can animate for a very long time (like in music playing),
|
|
||||||
// so it should be a Basic, not a Simple animation.
|
|
||||||
Ui::Animations::Basic _recordingAnimation;
|
|
||||||
Ui::Animations::Simple _activeAnimation;
|
Ui::Animations::Simple _activeAnimation;
|
||||||
Ui::Animations::Simple _showAnimation;
|
Ui::Animations::Simple _showAnimation;
|
||||||
anim::value _recordingLevel;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -337,8 +337,7 @@ historyRecordVoiceCancel: icon {{ "send_control_record_active", attentionButtonF
|
||||||
historyRecordVoiceRippleBgActive: lightButtonBgOver;
|
historyRecordVoiceRippleBgActive: lightButtonBgOver;
|
||||||
historyRecordVoiceRippleBgCancel: attentionButtonBgRipple;
|
historyRecordVoiceRippleBgCancel: attentionButtonBgRipple;
|
||||||
historyRecordSignalColor: attentionButtonFg;
|
historyRecordSignalColor: attentionButtonFg;
|
||||||
historyRecordSignalMin: 5px;
|
historyRecordSignalRadius: 5px;
|
||||||
historyRecordSignalMax: 12px;
|
|
||||||
historyRecordCancel: windowSubTextFg;
|
historyRecordCancel: windowSubTextFg;
|
||||||
historyRecordCancelActive: windowActiveTextFg;
|
historyRecordCancelActive: windowActiveTextFg;
|
||||||
historyRecordFont: font(13px);
|
historyRecordFont: font(13px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue