Added animation of voice recording lock with dummy lock icons.
BIN
Telegram/Resources/icons/lock/record_lock_body.png
Normal file
After Width: | Height: | Size: 107 B |
BIN
Telegram/Resources/icons/lock/record_lock_body@2x.png
Normal file
After Width: | Height: | Size: 122 B |
BIN
Telegram/Resources/icons/lock/record_lock_body@3x.png
Normal file
After Width: | Height: | Size: 176 B |
BIN
Telegram/Resources/icons/lock/record_lock_body_shadow.png
Normal file
After Width: | Height: | Size: 122 B |
BIN
Telegram/Resources/icons/lock/record_lock_body_shadow@2x.png
Normal file
After Width: | Height: | Size: 199 B |
BIN
Telegram/Resources/icons/lock/record_lock_body_shadow@3x.png
Normal file
After Width: | Height: | Size: 341 B |
BIN
Telegram/Resources/icons/lock/record_lock_bottom.png
Normal file
After Width: | Height: | Size: 369 B |
BIN
Telegram/Resources/icons/lock/record_lock_bottom@2x.png
Normal file
After Width: | Height: | Size: 657 B |
BIN
Telegram/Resources/icons/lock/record_lock_bottom@3x.png
Normal file
After Width: | Height: | Size: 1,012 B |
BIN
Telegram/Resources/icons/lock/record_lock_bottom_shadow.png
Normal file
After Width: | Height: | Size: 576 B |
BIN
Telegram/Resources/icons/lock/record_lock_bottom_shadow@2x.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Telegram/Resources/icons/lock/record_lock_bottom_shadow@3x.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
Telegram/Resources/icons/lock/record_lock_top.png
Normal file
After Width: | Height: | Size: 359 B |
BIN
Telegram/Resources/icons/lock/record_lock_top@2x.png
Normal file
After Width: | Height: | Size: 661 B |
BIN
Telegram/Resources/icons/lock/record_lock_top@3x.png
Normal file
After Width: | Height: | Size: 1,010 B |
BIN
Telegram/Resources/icons/lock/record_lock_top_shadow.png
Normal file
After Width: | Height: | Size: 557 B |
BIN
Telegram/Resources/icons/lock/record_lock_top_shadow@2x.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Telegram/Resources/icons/lock/record_lock_top_shadow@3x.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
|
@ -722,7 +722,7 @@ void HistoryWidget::initVoiceRecordBar() {
|
||||||
_scroll->topValue(),
|
_scroll->topValue(),
|
||||||
_scroll->heightValue()
|
_scroll->heightValue()
|
||||||
) | rpl::map([=](int top, int height) {
|
) | rpl::map([=](int top, int height) {
|
||||||
return top + height;
|
return top + height - st::historyRecordLockPosition.y();
|
||||||
});
|
});
|
||||||
_voiceRecordBar->setLockBottom(std::move(scrollHeight));
|
_voiceRecordBar->setLockBottom(std::move(scrollHeight));
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,18 @@ public:
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
void drawProgress(Painter &p);
|
||||||
|
|
||||||
Ui::Animations::Simple _lockAnimation;
|
Ui::Animations::Simple _lockAnimation;
|
||||||
|
|
||||||
rpl::variable<float64> _progress = 0.;
|
rpl::variable<float64> _progress = 0.;
|
||||||
};
|
};
|
||||||
|
|
||||||
RecordLock::RecordLock(not_null<Ui::RpWidget*> parent) : RpWidget(parent) {
|
RecordLock::RecordLock(not_null<Ui::RpWidget*> parent) : RpWidget(parent) {
|
||||||
resize(st::historyRecordLockSize);
|
resize(
|
||||||
|
st::historyRecordLockTopShadow.width(),
|
||||||
|
st::historyRecordLockSize.height());
|
||||||
|
// resize(st::historyRecordLockSize);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,23 +95,101 @@ void RecordLock::init() {
|
||||||
) | rpl::start_with_next([=](const QRect &clip) {
|
) | rpl::start_with_next([=](const QRect &clip) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
if (isLocked()) {
|
if (isLocked()) {
|
||||||
const auto color = anim::color(
|
const auto top = anim::interpolate(
|
||||||
Qt::red,
|
0,
|
||||||
Qt::green,
|
height() - st::historyRecordLockTopShadow.height() * 2,
|
||||||
_lockAnimation.value(1.));
|
_lockAnimation.value(1.));
|
||||||
p.fillRect(clip, color);
|
p.translate(0, top);
|
||||||
|
drawProgress(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p.fillRect(clip, anim::color(Qt::blue, Qt::red, _progress.current()));
|
drawProgress(p);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
locks(
|
locks(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
const auto duration = st::historyRecordVoiceShowDuration * 3;
|
const auto duration = st::historyRecordVoiceShowDuration;
|
||||||
_lockAnimation.start([=] { update(); }, 0., 1., duration);
|
_lockAnimation.start([=] { update(); }, 0., 1., duration);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RecordLock::drawProgress(Painter &p) {
|
||||||
|
const auto progress = _progress.current();
|
||||||
|
|
||||||
|
const auto &originTop = st::historyRecordLockTop;
|
||||||
|
const auto &originBottom = st::historyRecordLockBottom;
|
||||||
|
const auto &originBody = st::historyRecordLockBody;
|
||||||
|
const auto &shadowTop = st::historyRecordLockTopShadow;
|
||||||
|
const auto &shadowBottom = st::historyRecordLockBottomShadow;
|
||||||
|
const auto &shadowBody = st::historyRecordLockBodyShadow;
|
||||||
|
const auto &shadowMargins = st::historyRecordLockMargin;
|
||||||
|
|
||||||
|
const auto bottomMargin = anim::interpolate(
|
||||||
|
0,
|
||||||
|
rect().height() - shadowTop.height() - shadowBottom.height(),
|
||||||
|
progress);
|
||||||
|
|
||||||
|
const auto topMargin = anim::interpolate(
|
||||||
|
rect().height() / 4,
|
||||||
|
0,
|
||||||
|
progress);
|
||||||
|
|
||||||
|
const auto full = rect().marginsRemoved(
|
||||||
|
style::margins(0, topMargin, 0, bottomMargin));
|
||||||
|
const auto inner = full.marginsRemoved(shadowMargins);
|
||||||
|
const auto content = inner.marginsRemoved(style::margins(
|
||||||
|
0,
|
||||||
|
originTop.height(),
|
||||||
|
0,
|
||||||
|
originBottom.height()));
|
||||||
|
const auto contentShadow = full.marginsRemoved(style::margins(
|
||||||
|
0,
|
||||||
|
shadowTop.height(),
|
||||||
|
0,
|
||||||
|
shadowBottom.height()));
|
||||||
|
|
||||||
|
const auto w = full.width();
|
||||||
|
{
|
||||||
|
shadowTop.paint(p, full.topLeft(), w);
|
||||||
|
originTop.paint(p, inner.topLeft(), w);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto shadowPos = QPoint(
|
||||||
|
full.x(),
|
||||||
|
contentShadow.y() + contentShadow.height());
|
||||||
|
const auto originPos = QPoint(
|
||||||
|
inner.x(),
|
||||||
|
content.y() + content.height());
|
||||||
|
shadowBottom.paint(p, shadowPos, w);
|
||||||
|
originBottom.paint(p, originPos, w);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
shadowBody.fill(p, contentShadow);
|
||||||
|
originBody.fill(p, content);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto &arrow = st::historyRecordLockArrow;
|
||||||
|
const auto arrowRect = QRect(
|
||||||
|
inner.x(),
|
||||||
|
content.y() + content.height() - arrow.height() / 2,
|
||||||
|
inner.width(),
|
||||||
|
arrow.height());
|
||||||
|
p.setOpacity(1. - progress);
|
||||||
|
arrow.paintInCenter(p, arrowRect);
|
||||||
|
p.setOpacity(1.);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto &icon = isLocked()
|
||||||
|
? st::historyRecordLockIcon
|
||||||
|
: st::historyRecordUnlockIcon;
|
||||||
|
icon.paint(
|
||||||
|
p,
|
||||||
|
inner.x() + (inner.width() - icon.width()) / 2,
|
||||||
|
inner.y() + (originTop.height() * 2 - icon.height()) / 2,
|
||||||
|
inner.width());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RecordLock::requestPaintProgress(float64 progress) {
|
void RecordLock::requestPaintProgress(float64 progress) {
|
||||||
if (isHidden() || isLocked()) {
|
if (isHidden() || isLocked()) {
|
||||||
return;
|
return;
|
||||||
|
@ -230,7 +313,7 @@ void VoiceRecordBar::init() {
|
||||||
auto callback = [=](auto value) {
|
auto callback = [=](auto value) {
|
||||||
const auto right = anim::interpolate(
|
const auto right = anim::interpolate(
|
||||||
-_lock->width(),
|
-_lock->width(),
|
||||||
0,
|
st::historyRecordLockPosition.x(),
|
||||||
value);
|
value);
|
||||||
_lock->moveToRight(right, _lock->y());
|
_lock->moveToRight(right, _lock->y());
|
||||||
if (value == 0. && !show) {
|
if (value == 0. && !show) {
|
||||||
|
|
|
@ -345,7 +345,21 @@ historyRecordDurationFg: historyComposeAreaFg;
|
||||||
historyRecordTextTop: 14px;
|
historyRecordTextTop: 14px;
|
||||||
|
|
||||||
historyRecordLockShowDuration: historyToDownDuration;
|
historyRecordLockShowDuration: historyToDownDuration;
|
||||||
historyRecordLockSize: size(50px, 150px);
|
historyRecordLockSize: size(75px, 150px);
|
||||||
|
|
||||||
|
historyRecordLockTopShadow: icon {{ "lock/record_lock_top_shadow", historyToDownShadow }};
|
||||||
|
historyRecordLockTop: icon {{ "lock/record_lock_top", historyToDownBg }};
|
||||||
|
historyRecordLockBottomShadow: icon {{ "lock/record_lock_bottom_shadow", historyToDownShadow }};
|
||||||
|
historyRecordLockBottom: icon {{ "lock/record_lock_bottom", historyToDownBg }};
|
||||||
|
historyRecordLockBodyShadow: icon {{ "lock/record_lock_body_shadow", historyToDownShadow }};
|
||||||
|
historyRecordLockBody: icon {{ "lock/record_lock_body", historyToDownBg }};
|
||||||
|
historyRecordLockMargin: margins(4px, 4px, 4px, 4px);
|
||||||
|
historyRecordLockArrow: icon {{ "history_down_arrow-flip_vertical", historyToDownFg }};
|
||||||
|
|
||||||
|
historyRecordLockPosition: historyToDownPosition;
|
||||||
|
|
||||||
|
historyRecordLockIcon: icon {{ "dialogs_unlock", historyToDownFg, point(1px, 0px) }};
|
||||||
|
historyRecordUnlockIcon: icon {{ "dialogs_lock", historyToDownFg, point(0px, 0px) }};
|
||||||
|
|
||||||
historySilentToggle: IconButton(historyBotKeyboardShow) {
|
historySilentToggle: IconButton(historyBotKeyboardShow) {
|
||||||
icon: icon {{ "send_control_silent_off", historyComposeIconFg }};
|
icon: icon {{ "send_control_silent_off", historyComposeIconFg }};
|
||||||
|
|