mirror of https://github.com/procxx/kepka.git
Use new animations engine in all Basic-s.
This commit is contained in:
parent
cd3c1c6dc0
commit
a6e96f9a28
|
@ -400,7 +400,7 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
||||||
lang(lng_background_text2),
|
lang(lng_background_text2),
|
||||||
true))
|
true))
|
||||||
, _paper(paper)
|
, _paper(paper)
|
||||||
, _radial(animation(this, &BackgroundPreviewBox::step_radial)) {
|
, _radial([=](crl::time now) { return radialAnimationCallback(now); }) {
|
||||||
subscribe(Auth().downloaderTaskFinished(), [=] { update(); });
|
subscribe(Auth().downloaderTaskFinished(), [=] { update(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,13 +549,8 @@ void BackgroundPreviewBox::paintImage(Painter &p, crl::time ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::paintRadial(Painter &p, crl::time ms) {
|
void BackgroundPreviewBox::paintRadial(Painter &p, crl::time ms) {
|
||||||
bool radial = false;
|
const auto radial = _radial.animating();
|
||||||
float64 radialOpacity = 0;
|
const auto radialOpacity = radial ? _radial.opacity() : 0.;
|
||||||
if (_radial.animating()) {
|
|
||||||
_radial.step(ms);
|
|
||||||
radial = _radial.animating();
|
|
||||||
radialOpacity = _radial.opacity();
|
|
||||||
}
|
|
||||||
if (!radial) {
|
if (!radial) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +618,7 @@ void BackgroundPreviewBox::paintDate(Painter &p) {
|
||||||
p.drawText(bubbleLeft + st::msgServicePadding.left(), bubbleTop + st::msgServicePadding.top() + st::msgServiceFont->ascent, text);
|
p.drawText(bubbleLeft + st::msgServicePadding.left(), bubbleTop + st::msgServicePadding.top() + st::msgServiceFont->ascent, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::step_radial(crl::time ms, bool timer) {
|
void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
|
||||||
Expects(_paper.document() != nullptr);
|
Expects(_paper.document() != nullptr);
|
||||||
|
|
||||||
const auto document = _paper.document();
|
const auto document = _paper.document();
|
||||||
|
@ -631,9 +626,8 @@ void BackgroundPreviewBox::step_radial(crl::time ms, bool timer) {
|
||||||
const auto updated = _radial.update(
|
const auto updated = _radial.update(
|
||||||
document->progress(),
|
document->progress(),
|
||||||
!document->loading(),
|
!document->loading(),
|
||||||
ms);
|
now);
|
||||||
if (timer
|
if ((wasAnimating || _radial.animating())
|
||||||
&& (wasAnimating || _radial.animating())
|
|
||||||
&& (!anim::Disabled() || updated)) {
|
&& (!anim::Disabled() || updated)) {
|
||||||
update(radialRect());
|
update(radialRect());
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ private:
|
||||||
|
|
||||||
void apply();
|
void apply();
|
||||||
void share();
|
void share();
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback(crl::time now);
|
||||||
QRect radialRect() const;
|
QRect radialRect() const;
|
||||||
|
|
||||||
void checkLoadedDocument();
|
void checkLoadedDocument();
|
||||||
|
|
|
@ -52,7 +52,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
void setupControls(View &&view);
|
void setupControls(View &&view);
|
||||||
int countAvailableWidth() const;
|
int countAvailableWidth() const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback();
|
||||||
void paintCheck(Painter &p, crl::time ms);
|
void paintCheck(Painter &p, crl::time ms);
|
||||||
void showMenu();
|
void showMenu();
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ void ProxyRow::updateFields(View &&view) {
|
||||||
if (state == State::Connecting) {
|
if (state == State::Connecting) {
|
||||||
if (!_progress) {
|
if (!_progress) {
|
||||||
_progress = std::make_unique<Ui::InfiniteRadialAnimation>(
|
_progress = std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &ProxyRow::step_radial),
|
[=] { radialAnimationCallback(); },
|
||||||
st::proxyCheckingAnimation);
|
st::proxyCheckingAnimation);
|
||||||
}
|
}
|
||||||
_progress->start();
|
_progress->start();
|
||||||
|
@ -219,7 +219,7 @@ void ProxyRow::updateFields(View &&view) {
|
||||||
if (state == State::Checking) {
|
if (state == State::Checking) {
|
||||||
if (!_checking) {
|
if (!_checking) {
|
||||||
_checking = std::make_unique<Ui::InfiniteRadialAnimation>(
|
_checking = std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &ProxyRow::step_radial),
|
[=] { radialAnimationCallback(); },
|
||||||
st::proxyCheckingAnimation);
|
st::proxyCheckingAnimation);
|
||||||
_checking->start();
|
_checking->start();
|
||||||
}
|
}
|
||||||
|
@ -241,8 +241,8 @@ void ProxyRow::updateFields(View &&view) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyRow::step_radial(crl::time ms, bool timer) {
|
void ProxyRow::radialAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,28 +323,22 @@ void ProxyRow::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
auto statusLeft = left;
|
auto statusLeft = left;
|
||||||
if (_checking) {
|
if (_checking) {
|
||||||
_checking->step(ms);
|
_checking->draw(
|
||||||
if (_checking) {
|
p,
|
||||||
_checking->draw(
|
{
|
||||||
p,
|
st::proxyCheckingPosition.x() + statusLeft,
|
||||||
{
|
st::proxyCheckingPosition.y() + top
|
||||||
st::proxyCheckingPosition.x() + statusLeft,
|
},
|
||||||
st::proxyCheckingPosition.y() + top
|
width());
|
||||||
},
|
statusLeft += st::proxyCheckingPosition.x()
|
||||||
width());
|
+ st::proxyCheckingAnimation.size.width()
|
||||||
statusLeft += st::proxyCheckingPosition.x()
|
+ st::proxyCheckingSkip;
|
||||||
+ st::proxyCheckingAnimation.size.width()
|
|
||||||
+ st::proxyCheckingSkip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p.drawTextLeft(statusLeft, top, width(), status);
|
p.drawTextLeft(statusLeft, top, width(), status);
|
||||||
top += st::normalFont->height + st::proxyRowPadding.bottom();
|
top += st::normalFont->height + st::proxyRowPadding.bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyRow::paintCheck(Painter &p, crl::time ms) {
|
void ProxyRow::paintCheck(Painter &p, crl::time ms) {
|
||||||
if (_progress) {
|
|
||||||
_progress->step(ms);
|
|
||||||
}
|
|
||||||
const auto loading = _progress
|
const auto loading = _progress
|
||||||
? _progress->computeState()
|
? _progress->computeState()
|
||||||
: Ui::RadialState{ 0., 0, FullArcLength };
|
: Ui::RadialState{ 0., 0, FullArcLength };
|
||||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
QString titleText(const Database::TaggedSummary &data) const;
|
QString titleText(const Database::TaggedSummary &data) const;
|
||||||
QString sizeText(const Database::TaggedSummary &data) const;
|
QString sizeText(const Database::TaggedSummary &data) const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback();
|
||||||
|
|
||||||
Fn<QString(size_type)> _titleFactory;
|
Fn<QString(size_type)> _titleFactory;
|
||||||
object_ptr<Ui::FlatLabel> _title;
|
object_ptr<Ui::FlatLabel> _title;
|
||||||
|
@ -186,7 +186,7 @@ void LocalStorageBox::Row::toggleProgress(bool shown) {
|
||||||
_clearing.destroy();
|
_clearing.destroy();
|
||||||
} else if (!_progress) {
|
} else if (!_progress) {
|
||||||
_progress = std::make_unique<Ui::InfiniteRadialAnimation>(
|
_progress = std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &Row::step_radial),
|
[=] { radialAnimationCallback(); },
|
||||||
st::proxyCheckingAnimation);
|
st::proxyCheckingAnimation);
|
||||||
_progress->start();
|
_progress->start();
|
||||||
_clearing = object_ptr<Ui::FlatLabel>(
|
_clearing = object_ptr<Ui::FlatLabel>(
|
||||||
|
@ -201,8 +201,8 @@ void LocalStorageBox::Row::toggleProgress(bool shown) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStorageBox::Row::step_radial(crl::time ms, bool timer) {
|
void LocalStorageBox::Row::radialAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
RpWidget::update();
|
RpWidget::update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,6 @@ void LocalStorageBox::Row::paintEvent(QPaintEvent *e) {
|
||||||
const auto padding = st::localStorageRowPadding;
|
const auto padding = st::localStorageRowPadding;
|
||||||
const auto height = st::localStorageRowHeight;
|
const auto height = st::localStorageRowHeight;
|
||||||
const auto bottom = height - padding.bottom() - _description->height();
|
const auto bottom = height - padding.bottom() - _description->height();
|
||||||
_progress->step(crl::now());
|
|
||||||
_progress->draw(
|
_progress->draw(
|
||||||
p,
|
p,
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,8 +44,8 @@ int stickerPacksCount(bool includeArchivedOfficial) {
|
||||||
auto result = 0;
|
auto result = 0;
|
||||||
auto &order = Auth().data().stickerSetsOrder();
|
auto &order = Auth().data().stickerSetsOrder();
|
||||||
auto &sets = Auth().data().stickerSets();
|
auto &sets = Auth().data().stickerSets();
|
||||||
for (auto i = 0, l = order.size(); i < l; ++i) {
|
for (const auto setId : order) {
|
||||||
auto it = sets.constFind(order.at(i));
|
const auto it = sets.constFind(setId);
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
if (!(it->flags & MTPDstickerSet::Flag::f_archived) || ((it->flags & MTPDstickerSet::Flag::f_official) && includeArchivedOfficial)) {
|
if (!(it->flags & MTPDstickerSet::Flag::f_archived) || ((it->flags & MTPDstickerSet::Flag::f_official) && includeArchivedOfficial)) {
|
||||||
++result;
|
++result;
|
||||||
|
@ -653,7 +653,9 @@ StickersBox::Inner::Row::~Row() = default;
|
||||||
StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidget(parent)
|
StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidget(parent)
|
||||||
, _section(section)
|
, _section(section)
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _a_shifting(animation(this, &Inner::step_shifting))
|
, _shiftingAnimation([=](crl::time now) {
|
||||||
|
return shiftingAnimationCallback(now);
|
||||||
|
})
|
||||||
, _itemsTop(st::membersMarginTop)
|
, _itemsTop(st::membersMarginTop)
|
||||||
, _addText(lang(lng_stickers_featured_add).toUpper())
|
, _addText(lang(lng_stickers_featured_add).toUpper())
|
||||||
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
||||||
|
@ -665,7 +667,9 @@ StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidg
|
||||||
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup) : TWidget(parent)
|
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup) : TWidget(parent)
|
||||||
, _section(StickersBox::Section::Installed)
|
, _section(StickersBox::Section::Installed)
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _a_shifting(animation(this, &Inner::step_shifting))
|
, _shiftingAnimation([=](crl::time now) {
|
||||||
|
return shiftingAnimationCallback(now);
|
||||||
|
})
|
||||||
, _itemsTop(st::membersMarginTop)
|
, _itemsTop(st::membersMarginTop)
|
||||||
, _megagroupSet(megagroup)
|
, _megagroupSet(megagroup)
|
||||||
, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet)
|
, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet)
|
||||||
|
@ -710,10 +714,6 @@ void StickersBox::Inner::setInnerFocus() {
|
||||||
void StickersBox::Inner::paintEvent(QPaintEvent *e) {
|
void StickersBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
if (_a_shifting.animating()) {
|
|
||||||
_a_shifting.step();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto clip = e->rect();
|
auto clip = e->rect();
|
||||||
auto ms = crl::now();
|
auto ms = crl::now();
|
||||||
p.fillRect(clip, st::boxBg);
|
p.fillRect(clip, st::boxBg);
|
||||||
|
@ -1071,7 +1071,7 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
auto local = mapFromGlobal(_mouse);
|
auto local = mapFromGlobal(_mouse);
|
||||||
if (_dragging >= 0) {
|
if (_dragging >= 0) {
|
||||||
auto shift = 0;
|
auto shift = 0;
|
||||||
auto ms = crl::now();
|
auto now = crl::now();
|
||||||
int firstSetIndex = 0;
|
int firstSetIndex = 0;
|
||||||
if (_rows.at(firstSetIndex)->isRecentSet()) {
|
if (_rows.at(firstSetIndex)->isRecentSet()) {
|
||||||
++firstSetIndex;
|
++firstSetIndex;
|
||||||
|
@ -1081,27 +1081,27 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
|
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
|
||||||
qSwap(_rows[from], _rows[from - 1]);
|
qSwap(_rows[from], _rows[from - 1]);
|
||||||
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() - _rowHeight, 0);
|
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() - _rowHeight, 0);
|
||||||
_animStartTimes[from] = ms;
|
_shiftingStartTimes[from] = now;
|
||||||
}
|
}
|
||||||
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
|
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
|
||||||
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
|
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
|
||||||
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
|
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
|
||||||
qSwap(_rows[from], _rows[from + 1]);
|
qSwap(_rows[from], _rows[from + 1]);
|
||||||
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() + _rowHeight, 0);
|
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() + _rowHeight, 0);
|
||||||
_animStartTimes[from] = ms;
|
_shiftingStartTimes[from] = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shift) {
|
if (shift) {
|
||||||
_dragging += shift;
|
_dragging += shift;
|
||||||
_above = _dragging;
|
_above = _dragging;
|
||||||
_dragStart.setY(_dragStart.y() + shift * _rowHeight);
|
_dragStart.setY(_dragStart.y() + shift * _rowHeight);
|
||||||
if (!_a_shifting.animating()) {
|
if (!_shiftingAnimation.animating()) {
|
||||||
_a_shifting.start();
|
_shiftingAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_rows[_dragging]->yadd = anim::value(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
_rows[_dragging]->yadd = anim::value(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
||||||
_animStartTimes[_dragging] = 0;
|
_shiftingStartTimes[_dragging] = 0;
|
||||||
_a_shifting.step(ms, true);
|
shiftingAnimationCallback(now);
|
||||||
|
|
||||||
auto countDraggingScrollDelta = [this, local] {
|
auto countDraggingScrollDelta = [this, local] {
|
||||||
if (local.y() < _visibleTop) {
|
if (local.y() < _visibleTop) {
|
||||||
|
@ -1181,10 +1181,10 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
} else if (_dragging >= 0) {
|
} else if (_dragging >= 0) {
|
||||||
QPoint local(mapFromGlobal(_mouse));
|
QPoint local(mapFromGlobal(_mouse));
|
||||||
_rows[_dragging]->yadd.start(0.);
|
_rows[_dragging]->yadd.start(0.);
|
||||||
_aboveShadowFadeStart = _animStartTimes[_dragging] = crl::now();
|
_aboveShadowFadeStart = _shiftingStartTimes[_dragging] = crl::now();
|
||||||
_aboveShadowFadeOpacity = anim::value(aboveShadowOpacity(), 0);
|
_aboveShadowFadeOpacity = anim::value(aboveShadowOpacity(), 0);
|
||||||
if (!_a_shifting.animating()) {
|
if (!_shiftingAnimation.animating()) {
|
||||||
_a_shifting.start();
|
_shiftingAnimation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
_dragging = _started = -1;
|
_dragging = _started = -1;
|
||||||
|
@ -1262,64 +1262,64 @@ void StickersBox::Inner::leaveToChildEvent(QEvent *e, QWidget *child) {
|
||||||
onUpdateSelected();
|
onUpdateSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::step_shifting(crl::time ms, bool timer) {
|
bool StickersBox::Inner::shiftingAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += st::stickersRowDuration;
|
now += st::stickersRowDuration;
|
||||||
}
|
}
|
||||||
auto animating = false;
|
auto animating = false;
|
||||||
auto updateMin = -1;
|
auto updateMin = -1;
|
||||||
auto updateMax = 0;
|
auto updateMax = 0;
|
||||||
for (auto i = 0, l = _animStartTimes.size(); i < l; ++i) {
|
for (auto i = 0, count = int(_shiftingStartTimes.size()); i != count; ++i) {
|
||||||
auto start = _animStartTimes.at(i);
|
const auto start = _shiftingStartTimes[i];
|
||||||
if (start) {
|
if (start) {
|
||||||
if (updateMin < 0) updateMin = i;
|
if (updateMin < 0) {
|
||||||
|
updateMin = i;
|
||||||
|
}
|
||||||
updateMax = i;
|
updateMax = i;
|
||||||
if (start + st::stickersRowDuration > ms && ms >= start) {
|
if (start + st::stickersRowDuration > now && now >= start) {
|
||||||
_rows[i]->yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
|
_rows[i]->yadd.update(float64(now - start) / st::stickersRowDuration, anim::sineInOut);
|
||||||
animating = true;
|
animating = true;
|
||||||
} else {
|
} else {
|
||||||
_rows[i]->yadd.finish();
|
_rows[i]->yadd.finish();
|
||||||
_animStartTimes[i] = 0;
|
_shiftingStartTimes[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_aboveShadowFadeStart) {
|
if (_aboveShadowFadeStart) {
|
||||||
if (updateMin < 0 || updateMin > _above) updateMin = _above;
|
if (updateMin < 0 || updateMin > _above) updateMin = _above;
|
||||||
if (updateMax < _above) updateMin = _above;
|
if (updateMax < _above) updateMin = _above;
|
||||||
if (_aboveShadowFadeStart + st::stickersRowDuration > ms && ms > _aboveShadowFadeStart) {
|
if (_aboveShadowFadeStart + st::stickersRowDuration > now && now > _aboveShadowFadeStart) {
|
||||||
_aboveShadowFadeOpacity.update(float64(ms - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut);
|
_aboveShadowFadeOpacity.update(float64(now - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut);
|
||||||
animating = true;
|
animating = true;
|
||||||
} else {
|
} else {
|
||||||
_aboveShadowFadeOpacity.finish();
|
_aboveShadowFadeOpacity.finish();
|
||||||
_aboveShadowFadeStart = 0;
|
_aboveShadowFadeStart = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timer) {
|
if (_dragging >= 0) {
|
||||||
if (_dragging >= 0) {
|
if (updateMin < 0 || updateMin > _dragging) {
|
||||||
if (updateMin < 0 || updateMin > _dragging) {
|
updateMin = _dragging;
|
||||||
updateMin = _dragging;
|
|
||||||
}
|
|
||||||
if (updateMax < _dragging) updateMax = _dragging;
|
|
||||||
}
|
|
||||||
if (updateMin == 1 && _rows[0]->isRecentSet()) {
|
|
||||||
updateMin = 0; // Repaint from the very top of the content.
|
|
||||||
}
|
|
||||||
if (updateMin >= 0) {
|
|
||||||
update(0, _itemsTop + _rowHeight * (updateMin - 1), width(), _rowHeight * (updateMax - updateMin + 3));
|
|
||||||
}
|
}
|
||||||
|
if (updateMax < _dragging) updateMax = _dragging;
|
||||||
|
}
|
||||||
|
if (updateMin == 1 && _rows[0]->isRecentSet()) {
|
||||||
|
updateMin = 0; // Repaint from the very top of the content.
|
||||||
|
}
|
||||||
|
if (updateMin >= 0) {
|
||||||
|
update(0, _itemsTop + _rowHeight * (updateMin - 1), width(), _rowHeight * (updateMax - updateMin + 3));
|
||||||
}
|
}
|
||||||
if (!animating) {
|
if (!animating) {
|
||||||
_above = _dragging;
|
_above = _dragging;
|
||||||
_a_shifting.stop();
|
|
||||||
}
|
}
|
||||||
|
return animating;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::clear() {
|
void StickersBox::Inner::clear() {
|
||||||
_rows.clear();
|
_rows.clear();
|
||||||
_animStartTimes.clear();
|
_shiftingStartTimes.clear();
|
||||||
_aboveShadowFadeStart = 0;
|
_aboveShadowFadeStart = 0;
|
||||||
_aboveShadowFadeOpacity = anim::value();
|
_aboveShadowFadeOpacity = anim::value();
|
||||||
_a_shifting.stop();
|
_shiftingAnimation.stop();
|
||||||
_above = _dragging = _started = -1;
|
_above = _dragging = _started = -1;
|
||||||
setSelected(SelectedRow());
|
setSelected(SelectedRow());
|
||||||
setPressed(SelectedRow());
|
setPressed(SelectedRow());
|
||||||
|
@ -1476,7 +1476,7 @@ void StickersBox::Inner::rebuild() {
|
||||||
return Auth().data().archivedStickerSetsOrder();
|
return Auth().data().archivedStickerSetsOrder();
|
||||||
})();
|
})();
|
||||||
_rows.reserve(order.size() + 1);
|
_rows.reserve(order.size() + 1);
|
||||||
_animStartTimes.reserve(order.size() + 1);
|
_shiftingStartTimes.reserve(order.size() + 1);
|
||||||
|
|
||||||
auto &sets = Auth().data().stickerSets();
|
auto &sets = Auth().data().stickerSets();
|
||||||
if (_megagroupSet) {
|
if (_megagroupSet) {
|
||||||
|
@ -1625,7 +1625,7 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW
|
||||||
removed,
|
removed,
|
||||||
pixw,
|
pixw,
|
||||||
pixh));
|
pixh));
|
||||||
_animStartTimes.push_back(0);
|
_shiftingStartTimes.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::Inner::fillSetCover(const Stickers::Set &set, ImagePtr *thumbnail, DocumentData **outSticker, int *outWidth, int *outHeight) const {
|
void StickersBox::Inner::fillSetCover(const Stickers::Set &set, ImagePtr *thumbnail, DocumentData **outSticker, int *outWidth, int *outHeight) const {
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
|
||||||
class ConfirmBox;
|
class ConfirmBox;
|
||||||
|
@ -270,7 +271,7 @@ private:
|
||||||
QRect relativeButtonRect(bool removeButton) const;
|
QRect relativeButtonRect(bool removeButton) const;
|
||||||
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
|
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
|
||||||
|
|
||||||
void step_shifting(crl::time ms, bool timer);
|
bool shiftingAnimationCallback(crl::time now);
|
||||||
void paintRow(Painter &p, Row *set, int index, crl::time ms);
|
void paintRow(Painter &p, Row *set, int index, crl::time ms);
|
||||||
void paintFakeButton(Painter &p, Row *set, int index, crl::time ms);
|
void paintFakeButton(Painter &p, Row *set, int index, crl::time ms);
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -297,10 +298,10 @@ private:
|
||||||
int32 _rowHeight;
|
int32 _rowHeight;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Row>> _rows;
|
std::vector<std::unique_ptr<Row>> _rows;
|
||||||
QList<crl::time> _animStartTimes;
|
std::vector<crl::time> _shiftingStartTimes;
|
||||||
crl::time _aboveShadowFadeStart = 0;
|
crl::time _aboveShadowFadeStart = 0;
|
||||||
anim::value _aboveShadowFadeOpacity;
|
anim::value _aboveShadowFadeOpacity;
|
||||||
BasicAnimation _a_shifting;
|
Ui::Animations::Basic _shiftingAnimation;
|
||||||
|
|
||||||
Fn<void(uint64 setId)> _installSetCallback;
|
Fn<void(uint64 setId)> _installSetCallback;
|
||||||
Fn<void()> _loadMoreCallback;
|
Fn<void()> _loadMoreCallback;
|
||||||
|
|
|
@ -124,7 +124,7 @@ private:
|
||||||
void setupHandler();
|
void setupHandler();
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback();
|
||||||
|
|
||||||
int _id = 0;
|
int _id = 0;
|
||||||
bool _switching = false;
|
bool _switching = false;
|
||||||
|
@ -582,8 +582,8 @@ void Row::setupPreview(const Set &set) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::step_radial(crl::time ms, bool timer) {
|
void Row::radialAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,7 @@ void Row::updateAnimation(crl::time ms) {
|
||||||
: 0.;
|
: 0.;
|
||||||
if (!_loading) {
|
if (!_loading) {
|
||||||
_loading = std::make_unique<Ui::RadialAnimation>(
|
_loading = std::make_unique<Ui::RadialAnimation>(
|
||||||
animation(this, &Row::step_radial));
|
[=] { radialAnimationCallback(); });
|
||||||
_loading->start(progress);
|
_loading->start(progress);
|
||||||
} else {
|
} else {
|
||||||
_loading->update(progress, false, crl::now());
|
_loading->update(progress, false, crl::now());
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
|
@ -105,7 +106,7 @@ private:
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void enumerateVisibleIcons(Callback callback);
|
void enumerateVisibleIcons(Callback callback);
|
||||||
|
|
||||||
void step_icons(crl::time ms, bool timer);
|
bool iconsAnimationCallback(crl::time now);
|
||||||
void setSelectedIcon(
|
void setSelectedIcon(
|
||||||
int newSelected,
|
int newSelected,
|
||||||
ValidateIconAnimations animations);
|
ValidateIconAnimations animations);
|
||||||
|
@ -134,7 +135,7 @@ private:
|
||||||
int _iconSel = 0;
|
int _iconSel = 0;
|
||||||
OverState _iconDown = SpecialOver::None;
|
OverState _iconDown = SpecialOver::None;
|
||||||
bool _iconsDragging = false;
|
bool _iconsDragging = false;
|
||||||
BasicAnimation _a_icons;
|
Ui::Animations::Basic _iconsAnimation;
|
||||||
QPoint _iconsMousePos, _iconsMouseDown;
|
QPoint _iconsMousePos, _iconsMouseDown;
|
||||||
int _iconsLeft = 0;
|
int _iconsLeft = 0;
|
||||||
int _iconsRight = 0;
|
int _iconsRight = 0;
|
||||||
|
@ -180,7 +181,9 @@ StickersListWidget::Set::~Set() = default;
|
||||||
|
|
||||||
StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent) : InnerFooter(parent)
|
StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent) : InnerFooter(parent)
|
||||||
, _pan(parent)
|
, _pan(parent)
|
||||||
, _a_icons(animation(this, &Footer::step_icons)) {
|
, _iconsAnimation([=](crl::time now) {
|
||||||
|
return iconsAnimationCallback(now);
|
||||||
|
}) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
|
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
|
||||||
|
@ -323,11 +326,11 @@ void StickersListWidget::Footer::setSelectedIcon(
|
||||||
_iconsMax);
|
_iconsMax);
|
||||||
if (animations == ValidateIconAnimations::None) {
|
if (animations == ValidateIconAnimations::None) {
|
||||||
_iconsX = anim::value(iconsXFinal, iconsXFinal);
|
_iconsX = anim::value(iconsXFinal, iconsXFinal);
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
} else {
|
} else {
|
||||||
_iconsX.start(iconsXFinal);
|
_iconsX.start(iconsXFinal);
|
||||||
_iconsStartAnim = crl::now();
|
_iconsStartAnim = crl::now();
|
||||||
_a_icons.start();
|
_iconsAnimation.start();
|
||||||
}
|
}
|
||||||
updateSelected();
|
updateSelected();
|
||||||
update();
|
update();
|
||||||
|
@ -336,7 +339,7 @@ void StickersListWidget::Footer::setSelectedIcon(
|
||||||
void StickersListWidget::Footer::processHideFinished() {
|
void StickersListWidget::Footer::processHideFinished() {
|
||||||
_iconOver = _iconDown = SpecialOver::None;
|
_iconOver = _iconDown = SpecialOver::None;
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
_iconsX.finish();
|
_iconsX.finish();
|
||||||
_iconSelX.finish();
|
_iconSelX.finish();
|
||||||
_horizontal = false;
|
_horizontal = false;
|
||||||
|
@ -469,7 +472,7 @@ void StickersListWidget::Footer::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if (newX != qRound(_iconsX.current())) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::value(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,7 +507,7 @@ void StickersListWidget::Footer::finishDragging() {
|
||||||
if (newX != qRound(_iconsX.current())) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::value(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
_iconsDragging = false;
|
_iconsDragging = false;
|
||||||
|
@ -539,7 +542,7 @@ void StickersListWidget::Footer::scrollByWheelEvent(
|
||||||
if (newX != qRound(_iconsX.current())) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::value(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -601,7 +604,7 @@ void StickersListWidget::Footer::refreshIconsGeometry(
|
||||||
_iconsX.finish();
|
_iconsX.finish();
|
||||||
_iconSelX.finish();
|
_iconSelX.finish();
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_iconsAnimation.stop();
|
||||||
_iconsMax = std::max(
|
_iconsMax = std::max(
|
||||||
_iconsLeft + int(_icons.size()) * st::stickerIconWidth + _iconsRight - width(),
|
_iconsLeft + int(_icons.size()) * st::stickerIconWidth + _iconsRight - width(),
|
||||||
0);
|
0);
|
||||||
|
@ -673,13 +676,13 @@ void StickersListWidget::Footer::paintSetIcon(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::Footer::step_icons(crl::time ms, bool timer) {
|
bool StickersListWidget::Footer::iconsAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += st::stickerIconMove;
|
now += st::stickerIconMove;
|
||||||
}
|
}
|
||||||
if (_iconsStartAnim) {
|
if (_iconsStartAnim) {
|
||||||
auto dt = (ms - _iconsStartAnim) / float64(st::stickerIconMove);
|
const auto dt = (now - _iconsStartAnim) / float64(st::stickerIconMove);
|
||||||
if (dt >= 1) {
|
if (dt >= 1.) {
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_iconsX.finish();
|
_iconsX.finish();
|
||||||
_iconSelX.finish();
|
_iconSelX.finish();
|
||||||
|
@ -689,11 +692,9 @@ void StickersListWidget::Footer::step_icons(crl::time ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer) update();
|
update();
|
||||||
|
|
||||||
if (!_iconsStartAnim) {
|
return (_iconsStartAnim != 0);
|
||||||
_a_icons.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
||||||
|
|
|
@ -46,7 +46,6 @@ enum {
|
||||||
MediaOverviewStartPerPage = 5,
|
MediaOverviewStartPerPage = 5,
|
||||||
|
|
||||||
AudioVoiceMsgMaxLength = 100 * 60, // 100 minutes
|
AudioVoiceMsgMaxLength = 100 * 60, // 100 minutes
|
||||||
AudioVoiceMsgUpdateView = 100, // 100ms
|
|
||||||
AudioVoiceMsgChannels = 2, // stereo
|
AudioVoiceMsgChannels = 2, // stereo
|
||||||
|
|
||||||
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
||||||
|
|
|
@ -71,7 +71,9 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
|
||||||
, _dialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
, _dialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
||||||
, _contactsNoDialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contactsNoDialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, _a_pinnedShifting(animation(this, &DialogsInner::step_pinnedShifting))
|
, _pinnedShiftAnimation([=](crl::time now) {
|
||||||
|
return pinnedShiftAnimationCallback(now);
|
||||||
|
})
|
||||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
||||||
|
@ -255,10 +257,6 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
auto fullWidth = getFullWidth();
|
auto fullWidth = getFullWidth();
|
||||||
auto ms = crl::now();
|
auto ms = crl::now();
|
||||||
if (_state == State::Default) {
|
if (_state == State::Default) {
|
||||||
if (_a_pinnedShifting.animating()) {
|
|
||||||
_a_pinnedShifting.step(ms, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rows = shownDialogs();
|
auto rows = shownDialogs();
|
||||||
auto dialogsClip = r;
|
auto dialogsClip = r;
|
||||||
if (_dialogsImportant) {
|
if (_dialogsImportant) {
|
||||||
|
@ -855,7 +853,7 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||||
} else if (_pressed) {
|
} else if (_pressed) {
|
||||||
auto row = _pressed;
|
auto row = _pressed;
|
||||||
row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [this, row] {
|
row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [this, row] {
|
||||||
if (!_a_pinnedShifting.animating()) {
|
if (!_pinnedShiftAnimation.animating()) {
|
||||||
row->entry()->updateChatListEntry();
|
row->entry()->updateChatListEntry();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -901,7 +899,7 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) {
|
||||||
_pinnedOrder = Auth().data().pinnedDialogsOrder();
|
_pinnedOrder = Auth().data().pinnedDialogsOrder();
|
||||||
_pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y());
|
_pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y());
|
||||||
_pinnedRows[_draggingIndex].animStartTime = crl::now();
|
_pinnedRows[_draggingIndex].animStartTime = crl::now();
|
||||||
_a_pinnedShifting.start();
|
_pinnedShiftAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -959,7 +957,7 @@ void DialogsInner::finishReorderPinned() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_draggingIndex = -1;
|
_draggingIndex = -1;
|
||||||
if (!_a_pinnedShifting.animating()) {
|
if (!_pinnedShiftAnimation.animating()) {
|
||||||
_pinnedRows.clear();
|
_pinnedRows.clear();
|
||||||
_aboveIndex = -1;
|
_aboveIndex = -1;
|
||||||
}
|
}
|
||||||
|
@ -969,7 +967,7 @@ void DialogsInner::finishReorderPinned() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::stopReorderPinned() {
|
void DialogsInner::stopReorderPinned() {
|
||||||
_a_pinnedShifting.stop();
|
_pinnedShiftAnimation.stop();
|
||||||
finishReorderPinned();
|
finishReorderPinned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,7 +988,7 @@ int DialogsInner::updateReorderIndexGetCount() {
|
||||||
_draggingIndex = index;
|
_draggingIndex = index;
|
||||||
_aboveIndex = _draggingIndex;
|
_aboveIndex = _draggingIndex;
|
||||||
while (count > _pinnedRows.size()) {
|
while (count > _pinnedRows.size()) {
|
||||||
_pinnedRows.push_back(PinnedRow());
|
_pinnedRows.emplace_back();
|
||||||
}
|
}
|
||||||
while (count < _pinnedRows.size()) {
|
while (count < _pinnedRows.size()) {
|
||||||
_pinnedRows.pop_back();
|
_pinnedRows.pop_back();
|
||||||
|
@ -1007,7 +1005,7 @@ bool DialogsInner::updateReorderPinned(QPoint localPosition) {
|
||||||
|
|
||||||
auto yaddWas = _pinnedRows[_draggingIndex].yadd.current();
|
auto yaddWas = _pinnedRows[_draggingIndex].yadd.current();
|
||||||
auto shift = 0;
|
auto shift = 0;
|
||||||
auto ms = crl::now();
|
auto now = crl::now();
|
||||||
auto rowHeight = st::dialogsRowHeight;
|
auto rowHeight = st::dialogsRowHeight;
|
||||||
if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) {
|
if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) {
|
||||||
shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex);
|
shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex);
|
||||||
|
@ -1016,7 +1014,7 @@ bool DialogsInner::updateReorderPinned(QPoint localPosition) {
|
||||||
shownDialogs()->movePinned(_dragging, -1);
|
shownDialogs()->movePinned(_dragging, -1);
|
||||||
std::swap(_pinnedRows[from], _pinnedRows[from - 1]);
|
std::swap(_pinnedRows[from], _pinnedRows[from - 1]);
|
||||||
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() - rowHeight, 0);
|
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() - rowHeight, 0);
|
||||||
_pinnedRows[from].animStartTime = ms;
|
_pinnedRows[from].animStartTime = now;
|
||||||
}
|
}
|
||||||
} else if (_dragStart.y() < localPosition.y() && _draggingIndex + 1 < pinnedCount) {
|
} else if (_dragStart.y() < localPosition.y() && _draggingIndex + 1 < pinnedCount) {
|
||||||
shift = floorclamp(localPosition.y() - _dragStart.y() + (rowHeight / 2), rowHeight, 0, pinnedCount - _draggingIndex - 1);
|
shift = floorclamp(localPosition.y() - _dragStart.y() + (rowHeight / 2), rowHeight, 0, pinnedCount - _draggingIndex - 1);
|
||||||
|
@ -1025,15 +1023,15 @@ bool DialogsInner::updateReorderPinned(QPoint localPosition) {
|
||||||
shownDialogs()->movePinned(_dragging, 1);
|
shownDialogs()->movePinned(_dragging, 1);
|
||||||
std::swap(_pinnedRows[from], _pinnedRows[from + 1]);
|
std::swap(_pinnedRows[from], _pinnedRows[from + 1]);
|
||||||
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() + rowHeight, 0);
|
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() + rowHeight, 0);
|
||||||
_pinnedRows[from].animStartTime = ms;
|
_pinnedRows[from].animStartTime = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shift) {
|
if (shift) {
|
||||||
_draggingIndex += shift;
|
_draggingIndex += shift;
|
||||||
_aboveIndex = _draggingIndex;
|
_aboveIndex = _draggingIndex;
|
||||||
_dragStart.setY(_dragStart.y() + shift * rowHeight);
|
_dragStart.setY(_dragStart.y() + shift * rowHeight);
|
||||||
if (!_a_pinnedShifting.animating()) {
|
if (!_pinnedShiftAnimation.animating()) {
|
||||||
_a_pinnedShifting.start();
|
_pinnedShiftAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
_aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
||||||
|
@ -1041,22 +1039,22 @@ bool DialogsInner::updateReorderPinned(QPoint localPosition) {
|
||||||
if (!_pinnedRows[_draggingIndex].animStartTime) {
|
if (!_pinnedRows[_draggingIndex].animStartTime) {
|
||||||
_pinnedRows[_draggingIndex].yadd.finish();
|
_pinnedRows[_draggingIndex].yadd.finish();
|
||||||
}
|
}
|
||||||
_a_pinnedShifting.step(ms, true);
|
pinnedShiftAnimationCallback(now);
|
||||||
|
|
||||||
auto countDraggingScrollDelta = [this, localPosition] {
|
const auto delta = [&] {
|
||||||
if (localPosition.y() < _visibleTop) {
|
if (localPosition.y() < _visibleTop) {
|
||||||
return localPosition.y() - _visibleTop;
|
return localPosition.y() - _visibleTop;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}();
|
||||||
|
|
||||||
emit draggingScrollDelta(countDraggingScrollDelta());
|
emit draggingScrollDelta(delta);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::step_pinnedShifting(crl::time ms, bool timer) {
|
bool DialogsInner::pinnedShiftAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += st::stickersRowDuration;
|
now += st::stickersRowDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto wasAnimating = false;
|
auto wasAnimating = false;
|
||||||
|
@ -1069,8 +1067,8 @@ void DialogsInner::step_pinnedShifting(crl::time ms, bool timer) {
|
||||||
wasAnimating = true;
|
wasAnimating = true;
|
||||||
if (updateMin < 0) updateMin = i;
|
if (updateMin < 0) updateMin = i;
|
||||||
updateMax = i;
|
updateMax = i;
|
||||||
if (start + st::stickersRowDuration > ms && ms >= start) {
|
if (start + st::stickersRowDuration > now && now >= start) {
|
||||||
_pinnedRows[i].yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
|
_pinnedRows[i].yadd.update(float64(now - start) / st::stickersRowDuration, anim::sineInOut);
|
||||||
animating = true;
|
animating = true;
|
||||||
} else {
|
} else {
|
||||||
_pinnedRows[i].yadd.finish();
|
_pinnedRows[i].yadd.finish();
|
||||||
|
@ -1078,33 +1076,31 @@ void DialogsInner::step_pinnedShifting(crl::time ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timer || (wasAnimating && !animating)) {
|
updateReorderIndexGetCount();
|
||||||
updateReorderIndexGetCount();
|
if (_draggingIndex >= 0) {
|
||||||
if (_draggingIndex >= 0) {
|
if (updateMin < 0 || updateMin > _draggingIndex) {
|
||||||
if (updateMin < 0 || updateMin > _draggingIndex) {
|
updateMin = _draggingIndex;
|
||||||
updateMin = _draggingIndex;
|
|
||||||
}
|
|
||||||
if (updateMax < _draggingIndex) updateMax = _draggingIndex;
|
|
||||||
}
|
}
|
||||||
if (updateMin >= 0) {
|
if (updateMax < _draggingIndex) updateMax = _draggingIndex;
|
||||||
auto top = pinnedOffset();
|
}
|
||||||
auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1);
|
if (updateMin >= 0) {
|
||||||
auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3);
|
auto top = pinnedOffset();
|
||||||
if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) {
|
auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1);
|
||||||
// Always include currently dragged chat in its current and old positions.
|
auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3);
|
||||||
auto aboveRowBottom = top + (_aboveIndex + 1) * st::dialogsRowHeight;
|
if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) {
|
||||||
auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
// Always include currently dragged chat in its current and old positions.
|
||||||
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift);
|
auto aboveRowBottom = top + (_aboveIndex + 1) * st::dialogsRowHeight;
|
||||||
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift);
|
auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
||||||
_aboveTopShift = aboveTopShift;
|
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift);
|
||||||
}
|
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift);
|
||||||
update(0, updateFrom, getFullWidth(), updateHeight);
|
_aboveTopShift = aboveTopShift;
|
||||||
}
|
}
|
||||||
|
update(0, updateFrom, getFullWidth(), updateHeight);
|
||||||
}
|
}
|
||||||
if (!animating) {
|
if (!animating) {
|
||||||
_aboveIndex = _draggingIndex;
|
_aboveIndex = _draggingIndex;
|
||||||
_a_pinnedShifting.stop();
|
|
||||||
}
|
}
|
||||||
|
return animating;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::mouseReleaseEvent(QMouseEvent *e) {
|
void DialogsInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
@ -1120,8 +1116,8 @@ void DialogsInner::mousePressReleased(
|
||||||
if (_draggingIndex >= 0) {
|
if (_draggingIndex >= 0) {
|
||||||
_pinnedRows[_draggingIndex].yadd.start(0.);
|
_pinnedRows[_draggingIndex].yadd.start(0.);
|
||||||
_pinnedRows[_draggingIndex].animStartTime = crl::now();
|
_pinnedRows[_draggingIndex].animStartTime = crl::now();
|
||||||
if (!_a_pinnedShifting.animating()) {
|
if (!_pinnedShiftAnimation.animating()) {
|
||||||
_a_pinnedShifting.start();
|
_pinnedShiftAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finishReorderPinned();
|
finishReorderPinned();
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "dialogs/dialogs_widget.h"
|
#include "dialogs/dialogs_widget.h"
|
||||||
#include "dialogs/dialogs_key.h"
|
#include "dialogs/dialogs_key.h"
|
||||||
#include "data/data_messages.h"
|
#include "data/data_messages.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
@ -283,7 +284,7 @@ private:
|
||||||
void stopReorderPinned();
|
void stopReorderPinned();
|
||||||
int countPinnedIndex(Dialogs::Row *ofRow);
|
int countPinnedIndex(Dialogs::Row *ofRow);
|
||||||
void savePinnedOrder();
|
void savePinnedOrder();
|
||||||
void step_pinnedShifting(crl::time ms, bool timer);
|
bool pinnedShiftAnimationCallback(crl::time now);
|
||||||
void handleChatMigration(not_null<ChatData*> chat);
|
void handleChatMigration(not_null<ChatData*> chat);
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
not_null<Window::Controller*> _controller;
|
||||||
|
@ -313,7 +314,7 @@ private:
|
||||||
crl::time animStartTime = 0;
|
crl::time animStartTime = 0;
|
||||||
};
|
};
|
||||||
std::vector<PinnedRow> _pinnedRows;
|
std::vector<PinnedRow> _pinnedRows;
|
||||||
BasicAnimation _a_pinnedShifting;
|
Ui::Animations::Basic _pinnedShiftAnimation;
|
||||||
std::deque<Dialogs::Key> _pinnedOrder;
|
std::deque<Dialogs::Key> _pinnedOrder;
|
||||||
|
|
||||||
// Remember the last currently dragged row top shift for updating area.
|
// Remember the last currently dragged row top shift for updating area.
|
||||||
|
|
|
@ -66,7 +66,7 @@ protected:
|
||||||
void onStateChanged(State was, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback();
|
||||||
|
|
||||||
QString _text;
|
QString _text;
|
||||||
const style::FlatButton &_st;
|
const style::FlatButton &_st;
|
||||||
|
@ -95,8 +95,8 @@ void DialogsWidget::BottomButton::setText(const QString &text) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::BottomButton::step_radial(crl::time ms, bool timer) {
|
void DialogsWidget::BottomButton::radialAnimationCallback() {
|
||||||
if (timer && !anim::Disabled() && width() < st::columnMinimalWidthLeft) {
|
if (!anim::Disabled() && width() < st::columnMinimalWidthLeft) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ void DialogsWidget::BottomButton::onStateChanged(State was, StateChangeSource so
|
||||||
if ((was & StateFlag::Disabled) != (state() & StateFlag::Disabled)) {
|
if ((was & StateFlag::Disabled) != (state() & StateFlag::Disabled)) {
|
||||||
_loading = isDisabled()
|
_loading = isDisabled()
|
||||||
? std::make_unique<Ui::InfiniteRadialAnimation>(
|
? std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &BottomButton::step_radial),
|
[=] { radialAnimationCallback(); },
|
||||||
st::dialogsLoadMoreLoading)
|
st::dialogsLoadMoreLoading)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (_loading) {
|
if (_loading) {
|
||||||
|
|
|
@ -396,7 +396,9 @@ ReplyKeyboard::ReplyKeyboard(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
std::unique_ptr<Style> &&s)
|
std::unique_ptr<Style> &&s)
|
||||||
: _item(item)
|
: _item(item)
|
||||||
, _a_selected(animation(this, &ReplyKeyboard::step_selected))
|
, _selectedAnimation([=](crl::time now) {
|
||||||
|
return selectedAnimationCallback(now);
|
||||||
|
})
|
||||||
, _st(std::move(s)) {
|
, _st(std::move(s)) {
|
||||||
if (const auto markup = _item->Get<HistoryMessageReplyMarkup>()) {
|
if (const auto markup = _item->Get<HistoryMessageReplyMarkup>()) {
|
||||||
const auto context = _item->fullId();
|
const auto context = _item->fullId();
|
||||||
|
@ -640,20 +642,20 @@ void ReplyKeyboard::startAnimation(int i, int j, int direction) {
|
||||||
_animations.emplace(indexForAnimation, crl::now());
|
_animations.emplace(indexForAnimation, crl::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notStarted && !_a_selected.animating()) {
|
if (notStarted && !_selectedAnimation.animating()) {
|
||||||
_a_selected.start();
|
_selectedAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyKeyboard::step_selected(crl::time ms, bool timer) {
|
bool ReplyKeyboard::selectedAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += st::botKbDuration;
|
now += st::botKbDuration;
|
||||||
}
|
}
|
||||||
for (auto i = _animations.begin(); i != _animations.end();) {
|
for (auto i = _animations.begin(); i != _animations.end();) {
|
||||||
const auto index = std::abs(i->first) - 1;
|
const auto index = std::abs(i->first) - 1;
|
||||||
const auto row = (index / MatrixRowShift);
|
const auto row = (index / MatrixRowShift);
|
||||||
const auto col = index % MatrixRowShift;
|
const auto col = index % MatrixRowShift;
|
||||||
const auto dt = float64(ms - i->second) / st::botKbDuration;
|
const auto dt = float64(now - i->second) / st::botKbDuration;
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
_rows[row][col].howMuchOver = (i->first > 0) ? 1 : 0;
|
_rows[row][col].howMuchOver = (i->first > 0) ? 1 : 0;
|
||||||
i = _animations.erase(i);
|
i = _animations.erase(i);
|
||||||
|
@ -662,10 +664,8 @@ void ReplyKeyboard::step_selected(crl::time ms, bool timer) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timer) _st->repaint(_item);
|
_st->repaint(_item);
|
||||||
if (_animations.empty()) {
|
return !_animations.empty();
|
||||||
_a_selected.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyKeyboard::clearSelection() {
|
void ReplyKeyboard::clearSelection() {
|
||||||
|
@ -676,7 +676,7 @@ void ReplyKeyboard::clearSelection() {
|
||||||
_rows[row][col].howMuchOver = 0;
|
_rows[row][col].howMuchOver = 0;
|
||||||
}
|
}
|
||||||
_animations.clear();
|
_animations.clear();
|
||||||
_a_selected.stop();
|
_selectedAnimation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReplyKeyboard::Style::buttonSkip() const {
|
int ReplyKeyboard::Style::buttonSkip() const {
|
||||||
|
@ -857,19 +857,24 @@ HistoryDocumentCaptioned::HistoryDocumentCaptioned()
|
||||||
: _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
: _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(const HistoryDocument *that)
|
HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(
|
||||||
: a_progress(0., 0.)
|
const HistoryDocument *that)
|
||||||
, _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
|
: progress(0., 0.)
|
||||||
|
, progressAnimation([=](crl::time now) {
|
||||||
|
const auto nonconst = const_cast<HistoryDocument*>(that);
|
||||||
|
return nonconst->voiceProgressAnimationCallback(now);
|
||||||
|
}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const {
|
void HistoryDocumentVoice::ensurePlayback(
|
||||||
|
const HistoryDocument *that) const {
|
||||||
if (!_playback) {
|
if (!_playback) {
|
||||||
_playback = std::make_unique<HistoryDocumentVoicePlayback>(that);
|
_playback = std::make_unique<HistoryDocumentVoicePlayback>(that);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocumentVoice::checkPlaybackFinished() const {
|
void HistoryDocumentVoice::checkPlaybackFinished() const {
|
||||||
if (_playback && !_playback->_a_progress.animating()) {
|
if (_playback && !_playback->progressAnimation.animating()) {
|
||||||
_playback.reset();
|
_playback.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
|
||||||
class HistoryDocument;
|
class HistoryDocument;
|
||||||
struct WebPageData;
|
struct WebPageData;
|
||||||
|
@ -329,7 +330,7 @@ private:
|
||||||
|
|
||||||
ButtonCoords findButtonCoordsByClickHandler(const ClickHandlerPtr &p);
|
ButtonCoords findButtonCoordsByClickHandler(const ClickHandlerPtr &p);
|
||||||
|
|
||||||
void step_selected(crl::time ms, bool timer);
|
bool selectedAnimationCallback(crl::time now);
|
||||||
|
|
||||||
const not_null<const HistoryItem*> _item;
|
const not_null<const HistoryItem*> _item;
|
||||||
int _width = 0;
|
int _width = 0;
|
||||||
|
@ -337,7 +338,7 @@ private:
|
||||||
std::vector<std::vector<Button>> _rows;
|
std::vector<std::vector<Button>> _rows;
|
||||||
|
|
||||||
base::flat_map<int, crl::time> _animations;
|
base::flat_map<int, crl::time> _animations;
|
||||||
BasicAnimation _a_selected;
|
Ui::Animations::Basic _selectedAnimation;
|
||||||
std::unique_ptr<Style> _st;
|
std::unique_ptr<Style> _st;
|
||||||
|
|
||||||
ClickHandlerPtr _savedPressed;
|
ClickHandlerPtr _savedPressed;
|
||||||
|
@ -383,9 +384,9 @@ struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed, Hist
|
||||||
struct HistoryDocumentVoicePlayback {
|
struct HistoryDocumentVoicePlayback {
|
||||||
HistoryDocumentVoicePlayback(const HistoryDocument *that);
|
HistoryDocumentVoicePlayback(const HistoryDocument *that);
|
||||||
|
|
||||||
int32 _position = 0;
|
int32 position = 0;
|
||||||
anim::value a_progress;
|
anim::value progress;
|
||||||
BasicAnimation _a_progress;
|
Ui::Animations::Basic progressAnimation;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice, HistoryDocument> {
|
class HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice, HistoryDocument> {
|
||||||
|
|
|
@ -105,6 +105,7 @@ constexpr auto kCancelTypingActionTimeout = crl::time(5000);
|
||||||
constexpr auto kSaveDraftTimeout = 1000;
|
constexpr auto kSaveDraftTimeout = 1000;
|
||||||
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
||||||
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
||||||
|
constexpr auto kRecordingUpdateDelta = crl::time(100);
|
||||||
|
|
||||||
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
||||||
return [](ChannelData *channel, MsgId msgId) {
|
return [](ChannelData *channel, MsgId msgId) {
|
||||||
|
@ -189,7 +190,10 @@ HistoryWidget::HistoryWidget(
|
||||||
, _send(this)
|
, _send(this)
|
||||||
, _unblock(this, lang(lng_unblock_button).toUpper(), st::historyUnblock)
|
, _unblock(this, lang(lng_unblock_button).toUpper(), st::historyUnblock)
|
||||||
, _botStart(this, lang(lng_bot_start).toUpper(), st::historyComposeButton)
|
, _botStart(this, lang(lng_bot_start).toUpper(), st::historyComposeButton)
|
||||||
, _joinChannel(this, lang(lng_profile_join_channel).toUpper(), st::historyComposeButton)
|
, _joinChannel(
|
||||||
|
this,
|
||||||
|
lang(lng_profile_join_channel).toUpper(),
|
||||||
|
st::historyComposeButton)
|
||||||
, _muteUnmute(this, lang(lng_channel_mute).toUpper(), st::historyComposeButton)
|
, _muteUnmute(this, lang(lng_channel_mute).toUpper(), st::historyComposeButton)
|
||||||
, _attachToggle(this, st::historyAttach)
|
, _attachToggle(this, st::historyAttach)
|
||||||
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
||||||
|
@ -202,7 +206,9 @@ HistoryWidget::HistoryWidget(
|
||||||
Ui::InputField::Mode::MultiLine,
|
Ui::InputField::Mode::MultiLine,
|
||||||
langFactory(lng_message_ph))
|
langFactory(lng_message_ph))
|
||||||
, _recordCancelWidth(st::historyRecordFont->width(lang(lng_record_cancel)))
|
, _recordCancelWidth(st::historyRecordFont->width(lang(lng_record_cancel)))
|
||||||
, _a_recording(animation(this, &HistoryWidget::step_recording))
|
, _recordingAnimation([=](crl::time now) {
|
||||||
|
return recordingAnimationCallback(now);
|
||||||
|
})
|
||||||
, _kbScroll(this, st::botKbScroll)
|
, _kbScroll(this, st::botKbScroll)
|
||||||
, _tabbedPanel(this, controller)
|
, _tabbedPanel(this, controller)
|
||||||
, _tabbedSelector(_tabbedPanel->getSelector())
|
, _tabbedSelector(_tabbedPanel->getSelector())
|
||||||
|
@ -1235,8 +1241,8 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_recordingLevel.start(level);
|
_recordingLevel.start(level);
|
||||||
_a_recording.start();
|
_recordingAnimation.start();
|
||||||
_recordingSamples = samples;
|
_recordingSamples = samples;
|
||||||
if (samples < 0 || samples >= Media::Player::kDefaultFrequency * AudioVoiceMsgMaxLength) {
|
if (samples < 0 || samples >= Media::Player::kDefaultFrequency * AudioVoiceMsgMaxLength) {
|
||||||
stopRecording(_peer && samples > 0 && _inField);
|
stopRecording(_peer && samples > 0 && _inField);
|
||||||
|
@ -1364,7 +1370,7 @@ void HistoryWidget::setReplyReturns(PeerId peer, const QList<MsgId> &replyReturn
|
||||||
|
|
||||||
_replyReturns = replyReturns;
|
_replyReturns = replyReturns;
|
||||||
if (_replyReturns.isEmpty()) {
|
if (_replyReturns.isEmpty()) {
|
||||||
_replyReturn = 0;
|
_replyReturn = nullptr;
|
||||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||||
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1373,7 +1379,7 @@ void HistoryWidget::setReplyReturns(PeerId peer, const QList<MsgId> &replyReturn
|
||||||
while (!_replyReturns.isEmpty() && !_replyReturn) {
|
while (!_replyReturns.isEmpty() && !_replyReturn) {
|
||||||
_replyReturns.pop_back();
|
_replyReturns.pop_back();
|
||||||
if (_replyReturns.isEmpty()) {
|
if (_replyReturns.isEmpty()) {
|
||||||
_replyReturn = 0;
|
_replyReturn = nullptr;
|
||||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||||
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1383,11 +1389,11 @@ void HistoryWidget::setReplyReturns(PeerId peer, const QList<MsgId> &replyReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::calcNextReplyReturn() {
|
void HistoryWidget::calcNextReplyReturn() {
|
||||||
_replyReturn = 0;
|
_replyReturn = nullptr;
|
||||||
while (!_replyReturns.isEmpty() && !_replyReturn) {
|
while (!_replyReturns.isEmpty() && !_replyReturn) {
|
||||||
_replyReturns.pop_back();
|
_replyReturns.pop_back();
|
||||||
if (_replyReturns.isEmpty()) {
|
if (_replyReturns.isEmpty()) {
|
||||||
_replyReturn = 0;
|
_replyReturn = nullptr;
|
||||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||||
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
_replyReturn = App::histItemById(0, -_replyReturns.back());
|
||||||
} else {
|
} else {
|
||||||
|
@ -2784,7 +2790,7 @@ bool HistoryWidget::saveEditMsgFail(History *history, const RPCError &error, mtp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString err = error.type();
|
const auto &err = error.type();
|
||||||
if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
|
if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
|
||||||
Ui::show(Box<InformBox>(lang(lng_edit_error)));
|
Ui::show(Box<InformBox>(lang(lng_edit_error)));
|
||||||
} else if (err == qstr("MESSAGE_NOT_MODIFIED")) {
|
} else if (err == qstr("MESSAGE_NOT_MODIFIED")) {
|
||||||
|
@ -2989,17 +2995,20 @@ void HistoryWidget::unreadMentionsAnimationFinish() {
|
||||||
updateUnreadMentionsPosition();
|
updateUnreadMentionsPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::step_recording(float64 ms, bool timer) {
|
bool HistoryWidget::recordingAnimationCallback(crl::time now) {
|
||||||
const auto dt = anim::Disabled() ? 1. : (ms / AudioVoiceMsgUpdateView);
|
const auto dt = anim::Disabled()
|
||||||
if (dt >= 1) {
|
? 1.
|
||||||
_a_recording.stop();
|
: ((now - _recordingAnimation.started())
|
||||||
a_recordingLevel.finish();
|
/ float64(kRecordingUpdateDelta));
|
||||||
|
if (dt >= 1.) {
|
||||||
|
_recordingLevel.finish();
|
||||||
} else {
|
} else {
|
||||||
a_recordingLevel.update(dt, anim::linear);
|
_recordingLevel.update(dt, anim::linear);
|
||||||
}
|
}
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update(_attachToggle->geometry());
|
update(_attachToggle->geometry());
|
||||||
}
|
}
|
||||||
|
return (dt < 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::chooseAttach() {
|
void HistoryWidget::chooseAttach() {
|
||||||
|
@ -3080,7 +3089,9 @@ void HistoryWidget::leaveEventHook(QEvent *e) {
|
||||||
_attachDragState = DragState::None;
|
_attachDragState = DragState::None;
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
}
|
}
|
||||||
if (hasMouseTracking()) mouseMoveEvent(0);
|
if (hasMouseTracking()) {
|
||||||
|
mouseMoveEvent(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
@ -3158,8 +3169,8 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
void HistoryWidget::stopRecording(bool send) {
|
void HistoryWidget::stopRecording(bool send) {
|
||||||
emit Media::Capture::instance()->stop(send);
|
emit Media::Capture::instance()->stop(send);
|
||||||
|
|
||||||
a_recordingLevel = anim::value();
|
_recordingLevel = anim::value();
|
||||||
_a_recording.stop();
|
_recordingAnimation.stop();
|
||||||
|
|
||||||
_recording = false;
|
_recording = false;
|
||||||
_recordingSamples = 0;
|
_recordingSamples = 0;
|
||||||
|
@ -3581,7 +3592,7 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||||
|
|
||||||
_field->setMaxHeight(st::historyComposeFieldMaxHeight);
|
_field->setMaxHeight(st::historyComposeFieldMaxHeight);
|
||||||
|
|
||||||
_kbReplyTo = 0;
|
_kbReplyTo = nullptr;
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_editMsgId && !_replyToId) {
|
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_editMsgId && !_replyToId) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
|
@ -3604,7 +3615,9 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||||
|
|
||||||
_field->setMaxHeight(st::historyComposeFieldMaxHeight);
|
_field->setMaxHeight(st::historyComposeFieldMaxHeight);
|
||||||
|
|
||||||
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0;
|
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply())
|
||||||
|
? App::histItemById(_keyboard->forMsgId())
|
||||||
|
: nullptr;
|
||||||
if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) {
|
if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) {
|
||||||
updateReplyToName();
|
updateReplyToName();
|
||||||
updateReplyEditText(_kbReplyTo);
|
updateReplyEditText(_kbReplyTo);
|
||||||
|
@ -3621,7 +3634,9 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||||
int32 maxh = qMin(_keyboard->height(), st::historyComposeFieldMaxHeight - (st::historyComposeFieldMaxHeight / 2));
|
int32 maxh = qMin(_keyboard->height(), st::historyComposeFieldMaxHeight - (st::historyComposeFieldMaxHeight / 2));
|
||||||
_field->setMaxHeight(st::historyComposeFieldMaxHeight - maxh);
|
_field->setMaxHeight(st::historyComposeFieldMaxHeight - maxh);
|
||||||
|
|
||||||
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0;
|
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply())
|
||||||
|
? App::histItemById(_keyboard->forMsgId())
|
||||||
|
: nullptr;
|
||||||
if (_kbReplyTo && !_editMsgId && !_replyToId) {
|
if (_kbReplyTo && !_editMsgId && !_replyToId) {
|
||||||
updateReplyToName();
|
updateReplyToName();
|
||||||
updateReplyEditText(_kbReplyTo);
|
updateReplyEditText(_kbReplyTo);
|
||||||
|
@ -6461,7 +6476,7 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::historyRecordSignalColor);
|
p.setBrush(st::historyRecordSignalColor);
|
||||||
|
|
||||||
auto delta = qMin(a_recordingLevel.current() / 0x4000, 1.);
|
auto delta = qMin(_recordingLevel.current() / 0x4000, 1.);
|
||||||
auto d = 2 * qRound(st::historyRecordSignalMin + (delta * (st::historyRecordSignalMax - st::historyRecordSignalMin)));
|
auto d = 2 * qRound(st::historyRecordSignalMin + (delta * (st::historyRecordSignalMax - st::historyRecordSignalMin)));
|
||||||
{
|
{
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "chat_helpers/field_autocomplete.h"
|
#include "chat_helpers/field_autocomplete.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
@ -219,7 +220,7 @@ public:
|
||||||
void updatePreview();
|
void updatePreview();
|
||||||
void previewCancel();
|
void previewCancel();
|
||||||
|
|
||||||
void step_recording(float64 ms, bool timer);
|
bool recordingAnimationCallback(crl::time now);
|
||||||
void stopRecording(bool send);
|
void stopRecording(bool send);
|
||||||
|
|
||||||
void onListEscapePressed();
|
void onListEscapePressed();
|
||||||
|
@ -768,9 +769,9 @@ private:
|
||||||
rpl::lifetime _uploaderSubscriptions;
|
rpl::lifetime _uploaderSubscriptions;
|
||||||
|
|
||||||
// This can animate for a very long time (like in music playing),
|
// This can animate for a very long time (like in music playing),
|
||||||
// so it should be a BasicAnimation, not an Animation.
|
// so it should be a Basic, not a Simple animation.
|
||||||
BasicAnimation _a_recording;
|
Ui::Animations::Basic _recordingAnimation;
|
||||||
anim::value a_recordingLevel;
|
anim::value _recordingLevel;
|
||||||
|
|
||||||
bool kbWasHidden() const;
|
bool kbWasHidden() const;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kAudioVoiceMsgUpdateView = crl::time(100);
|
||||||
|
|
||||||
using TextState = HistoryView::TextState;
|
using TextState = HistoryView::TextState;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -364,7 +366,7 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
if (voice->seeking()) {
|
if (voice->seeking()) {
|
||||||
return voice->seekingCurrent();
|
return voice->seekingCurrent();
|
||||||
} else if (voice->_playback) {
|
} else if (voice->_playback) {
|
||||||
return voice->_playback->a_progress.current();
|
return voice->_playback->progress.current();
|
||||||
}
|
}
|
||||||
return 0.;
|
return 0.;
|
||||||
})();
|
})();
|
||||||
|
@ -707,15 +709,15 @@ bool HistoryDocument::updateStatusText() const {
|
||||||
if (auto voice = Get<HistoryDocumentVoice>()) {
|
if (auto voice = Get<HistoryDocumentVoice>()) {
|
||||||
bool was = (voice->_playback != nullptr);
|
bool was = (voice->_playback != nullptr);
|
||||||
voice->ensurePlayback(this);
|
voice->ensurePlayback(this);
|
||||||
if (!was || state.position != voice->_playback->_position) {
|
if (!was || state.position != voice->_playback->position) {
|
||||||
auto prg = state.length ? snap(float64(state.position) / state.length, 0., 1.) : 0.;
|
auto prg = state.length ? snap(float64(state.position) / state.length, 0., 1.) : 0.;
|
||||||
if (voice->_playback->_position < state.position) {
|
if (voice->_playback->position < state.position) {
|
||||||
voice->_playback->a_progress.start(prg);
|
voice->_playback->progress.start(prg);
|
||||||
} else {
|
} else {
|
||||||
voice->_playback->a_progress = anim::value(0., prg);
|
voice->_playback->progress = anim::value(0., prg);
|
||||||
}
|
}
|
||||||
voice->_playback->_position = state.position;
|
voice->_playback->position = state.position;
|
||||||
voice->_playback->_a_progress.start();
|
voice->_playback->progressAnimation.start();
|
||||||
}
|
}
|
||||||
voice->_lastDurationMs = static_cast<int>((state.length * 1000LL) / state.frequency); // Bad :(
|
voice->_lastDurationMs = static_cast<int>((state.length * 1000LL) / state.frequency); // Bad :(
|
||||||
}
|
}
|
||||||
|
@ -759,24 +761,25 @@ bool HistoryDocument::hideForwardedFrom() const {
|
||||||
return _data->isSong();
|
return _data->isSong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::step_voiceProgress(float64 ms, bool timer) {
|
bool HistoryDocument::voiceProgressAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += (2 * AudioVoiceMsgUpdateView);
|
now += (2 * kAudioVoiceMsgUpdateView);
|
||||||
}
|
}
|
||||||
if (auto voice = Get<HistoryDocumentVoice>()) {
|
if (const auto voice = Get<HistoryDocumentVoice>()) {
|
||||||
if (voice->_playback) {
|
if (voice->_playback) {
|
||||||
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
|
const auto dt = (now - voice->_playback->progressAnimation.started())
|
||||||
if (dt >= 1) {
|
/ float64(2 * kAudioVoiceMsgUpdateView);
|
||||||
voice->_playback->_a_progress.stop();
|
if (dt >= 1.) {
|
||||||
voice->_playback->a_progress.finish();
|
voice->_playback->progressAnimation.stop();
|
||||||
|
voice->_playback->progress.finish();
|
||||||
} else {
|
} else {
|
||||||
voice->_playback->a_progress.update(qMin(dt, 1.), anim::linear);
|
voice->_playback->progress.update(qMin(dt, 1.), anim::linear);
|
||||||
}
|
|
||||||
if (timer) {
|
|
||||||
history()->owner().requestViewRepaint(_parent);
|
|
||||||
}
|
}
|
||||||
|
history()->owner().requestViewRepaint(_parent);
|
||||||
|
return (dt < 1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) {
|
void HistoryDocument::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) {
|
||||||
|
@ -793,8 +796,8 @@ void HistoryDocument::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool
|
||||||
currentProgress);
|
currentProgress);
|
||||||
|
|
||||||
voice->ensurePlayback(this);
|
voice->ensurePlayback(this);
|
||||||
voice->_playback->_position = 0;
|
voice->_playback->position = 0;
|
||||||
voice->_playback->a_progress = anim::value(currentProgress, currentProgress);
|
voice->_playback->progress = anim::value(currentProgress, currentProgress);
|
||||||
}
|
}
|
||||||
voice->stopSeeking();
|
voice->stopSeeking();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
QMargins bubbleMargins() const override;
|
QMargins bubbleMargins() const override;
|
||||||
bool hideForwardedFrom() const override;
|
bool hideForwardedFrom() const override;
|
||||||
|
|
||||||
void step_voiceProgress(float64 ms, bool timer);
|
bool voiceProgressAnimationCallback(crl::time now);
|
||||||
|
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
|
||||||
|
|
||||||
|
|
|
@ -67,28 +67,28 @@ void HistoryFileMedia::setStatusSize(int newSize, int fullSize, int duration, qi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryFileMedia::step_radial(crl::time ms, bool timer) {
|
bool HistoryFileMedia::radialAnimationCallback(crl::time now) const {
|
||||||
const auto updateRadial = [&] {
|
const auto radialUpdated = [&] {
|
||||||
return _animation->radial.update(
|
return _animation->radial.update(
|
||||||
dataProgress(),
|
dataProgress(),
|
||||||
dataFinished(),
|
dataFinished(),
|
||||||
ms);
|
now);
|
||||||
};
|
}();
|
||||||
if (timer) {
|
if (!anim::Disabled() || radialUpdated) {
|
||||||
if (!anim::Disabled() || updateRadial()) {
|
history()->owner().requestViewRepaint(_parent);
|
||||||
history()->owner().requestViewRepaint(_parent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateRadial();
|
|
||||||
if (!_animation->radial.animating()) {
|
|
||||||
checkAnimationFinished();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!_animation->radial.animating()) {
|
||||||
|
checkAnimationFinished();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryFileMedia::ensureAnimation() const {
|
void HistoryFileMedia::ensureAnimation() const {
|
||||||
if (!_animation) {
|
if (!_animation) {
|
||||||
_animation = std::make_unique<AnimationData>(animation(const_cast<HistoryFileMedia*>(this), &HistoryFileMedia::step_radial));
|
_animation = std::make_unique<AnimationData>([=](crl::time now) {
|
||||||
|
return radialAnimationCallback(now);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,17 +62,16 @@ protected:
|
||||||
// duration = -1 - no duration, duration = -2 - "GIF" duration
|
// duration = -1 - no duration, duration = -2 - "GIF" duration
|
||||||
void setStatusSize(int newSize, int fullSize, int duration, qint64 realDuration) const;
|
void setStatusSize(int newSize, int fullSize, int duration, qint64 realDuration) const;
|
||||||
|
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now) const;
|
||||||
void thumbAnimationCallback();
|
void thumbAnimationCallback();
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
void checkAnimationFinished() const;
|
void checkAnimationFinished() const;
|
||||||
|
|
||||||
bool isRadialAnimation(crl::time ms) const {
|
bool isRadialAnimation(crl::time now) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
return _animation
|
||||||
|
&& _animation->radial.animating()
|
||||||
_animation->radial.step(ms);
|
&& radialAnimationCallback(now);
|
||||||
return _animation && _animation->radial.animating();
|
|
||||||
}
|
}
|
||||||
bool isThumbAnimation(crl::time ms) const {
|
bool isThumbAnimation(crl::time ms) const {
|
||||||
if (_animation) {
|
if (_animation) {
|
||||||
|
@ -89,9 +88,11 @@ protected:
|
||||||
virtual bool dataLoaded() const = 0;
|
virtual bool dataLoaded() const = 0;
|
||||||
|
|
||||||
struct AnimationData {
|
struct AnimationData {
|
||||||
AnimationData(AnimationCallbacks &&radialCallbacks)
|
template <typename Callback>
|
||||||
: radial(std::move(radialCallbacks)) {
|
AnimationData(Callback &&radialCallback)
|
||||||
|
: radial(std::forward<Callback>(radialCallback)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Animation a_thumbOver;
|
Animation a_thumbOver;
|
||||||
Ui::RadialAnimation radial;
|
Ui::RadialAnimation radial;
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,9 +142,10 @@ struct HistoryPoll::AnswersAnimation {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryPoll::SendingAnimation {
|
struct HistoryPoll::SendingAnimation {
|
||||||
|
template <typename Callback>
|
||||||
SendingAnimation(
|
SendingAnimation(
|
||||||
const QByteArray &option,
|
const QByteArray &option,
|
||||||
AnimationCallbacks &&callbacks);
|
Callback &&callback);
|
||||||
|
|
||||||
QByteArray option;
|
QByteArray option;
|
||||||
Ui::InfiniteRadialAnimation animation;
|
Ui::InfiniteRadialAnimation animation;
|
||||||
|
@ -167,11 +168,14 @@ struct HistoryPoll::Answer {
|
||||||
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
HistoryPoll::SendingAnimation::SendingAnimation(
|
HistoryPoll::SendingAnimation::SendingAnimation(
|
||||||
const QByteArray &option,
|
const QByteArray &option,
|
||||||
AnimationCallbacks &&callbacks)
|
Callback &&callback)
|
||||||
: option(option)
|
: option(option)
|
||||||
, animation(std::move(callbacks), st::historyPollRadialAnimation) {
|
, animation(
|
||||||
|
std::forward<Callback>(callback),
|
||||||
|
st::historyPollRadialAnimation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryPoll::Answer::Answer() : text(st::msgMinWidth / 2) {
|
HistoryPoll::Answer::Answer() : text(st::msgMinWidth / 2) {
|
||||||
|
@ -397,9 +401,7 @@ void HistoryPoll::checkSendingAnimation() const {
|
||||||
}
|
}
|
||||||
_sendingAnimation = std::make_unique<SendingAnimation>(
|
_sendingAnimation = std::make_unique<SendingAnimation>(
|
||||||
sending,
|
sending,
|
||||||
animation(
|
[=] { radialAnimationCallback(); });
|
||||||
const_cast<HistoryPoll*>(this),
|
|
||||||
&HistoryPoll::step_radial));
|
|
||||||
_sendingAnimation->animation.start();
|
_sendingAnimation->animation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,8 +563,8 @@ void HistoryPoll::resetAnswersAnimation() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryPoll::step_radial(crl::time ms, bool timer) {
|
void HistoryPoll::radialAnimationCallback() const {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
history()->owner().requestViewRepaint(_parent);
|
history()->owner().requestViewRepaint(_parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ private:
|
||||||
void saveStateInAnimation() const;
|
void saveStateInAnimation() const;
|
||||||
void startAnswersAnimation() const;
|
void startAnswersAnimation() const;
|
||||||
void resetAnswersAnimation() const;
|
void resetAnswersAnimation() const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback() const;
|
||||||
|
|
||||||
void toggleRipple(Answer &answer, bool pressed);
|
void toggleRipple(Answer &answer, bool pressed);
|
||||||
|
|
||||||
|
|
|
@ -154,15 +154,15 @@ void TopBarWidget::updateConnectingState() {
|
||||||
}
|
}
|
||||||
} else if (!_connecting) {
|
} else if (!_connecting) {
|
||||||
_connecting = std::make_unique<Ui::InfiniteRadialAnimation>(
|
_connecting = std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &TopBarWidget::step_connecting),
|
[=] { connectingAnimationCallback(); },
|
||||||
st::topBarConnectingAnimation);
|
st::topBarConnectingAnimation);
|
||||||
_connecting->start();
|
_connecting->start();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBarWidget::step_connecting(crl::time ms, bool timer) {
|
void TopBarWidget::connectingAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,9 +362,6 @@ bool TopBarWidget::paintConnectingState(
|
||||||
int top,
|
int top,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
crl::time ms) {
|
crl::time ms) {
|
||||||
if (_connecting) {
|
|
||||||
_connecting->step(ms);
|
|
||||||
}
|
|
||||||
if (!_connecting) {
|
if (!_connecting) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ private:
|
||||||
void updateConnectingState();
|
void updateConnectingState();
|
||||||
void updateAdaptiveLayout();
|
void updateAdaptiveLayout();
|
||||||
int countSelectedButtonsTop(float64 selectedShown);
|
int countSelectedButtonsTop(float64 selectedShown);
|
||||||
void step_connecting(crl::time ms, bool timer);
|
void connectingAnimationCallback();
|
||||||
|
|
||||||
void paintTopBar(Painter &p, crl::time ms);
|
void paintTopBar(Painter &p, crl::time ms);
|
||||||
void paintStatus(
|
void paintStatus(
|
||||||
|
|
|
@ -321,35 +321,34 @@ void Gif::prepareThumbnail(QSize size, QSize frame) const {
|
||||||
|
|
||||||
void Gif::ensureAnimation() const {
|
void Gif::ensureAnimation() const {
|
||||||
if (!_animation) {
|
if (!_animation) {
|
||||||
_animation = std::make_unique<AnimationData>(animation(const_cast<Gif*>(this), &Gif::step_radial));
|
_animation = std::make_unique<AnimationData>([=](crl::time now) {
|
||||||
|
return radialAnimationCallback(now);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gif::isRadialAnimation(crl::time ms) const {
|
bool Gif::isRadialAnimation(crl::time now) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
return _animation
|
||||||
|
&& _animation->radial.animating()
|
||||||
_animation->radial.step(ms);
|
&& radialAnimationCallback(now);
|
||||||
return _animation && _animation->radial.animating();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::step_radial(crl::time ms, bool timer) {
|
bool Gif::radialAnimationCallback(crl::time now) const {
|
||||||
const auto document = getShownDocument();
|
const auto document = getShownDocument();
|
||||||
const auto updateRadial = [&] {
|
const auto radialUpdated = [&] {
|
||||||
return _animation->radial.update(
|
return _animation->radial.update(
|
||||||
document->progress(),
|
document->progress(),
|
||||||
!document->loading() || document->loaded(),
|
!document->loading() || document->loaded(),
|
||||||
ms);
|
now);
|
||||||
};
|
}();
|
||||||
if (timer) {
|
if (!anim::Disabled() || radialUpdated) {
|
||||||
if (!anim::Disabled() || updateRadial()) {
|
update();
|
||||||
update();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateRadial();
|
|
||||||
if (!_animation->radial.animating() && document->loaded()) {
|
|
||||||
_animation.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!_animation->radial.animating() && document->loaded()) {
|
||||||
|
_animation.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::clipCallback(Media::Clip::Notification notification) {
|
void Gif::clipCallback(Media::Clip::Notification notification) {
|
||||||
|
@ -845,28 +844,28 @@ void File::thumbAnimationCallback() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::step_radial(crl::time ms, bool timer) {
|
bool File::radialAnimationCallback(crl::time now) const {
|
||||||
const auto updateRadial = [&] {
|
const auto radialUpdated = [&] {
|
||||||
return _animation->radial.update(
|
return _animation->radial.update(
|
||||||
_document->progress(),
|
_document->progress(),
|
||||||
!_document->loading() || _document->loaded(),
|
!_document->loading() || _document->loaded(),
|
||||||
ms);
|
now);
|
||||||
};
|
}();
|
||||||
if (timer) {
|
if (!anim::Disabled() || radialUpdated) {
|
||||||
if (!anim::Disabled() || updateRadial()) {
|
update();
|
||||||
update();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateRadial();
|
|
||||||
if (!_animation->radial.animating()) {
|
|
||||||
checkAnimationFinished();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!_animation->radial.animating()) {
|
||||||
|
checkAnimationFinished();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::ensureAnimation() const {
|
void File::ensureAnimation() const {
|
||||||
if (!_animation) {
|
if (!_animation) {
|
||||||
_animation = std::make_unique<AnimationData>(animation(const_cast<File*>(this), &File::step_radial));
|
_animation = std::make_unique<AnimationData>([=](crl::time now) {
|
||||||
|
return radialAnimationCallback(now);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1251,7 +1250,9 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
bool animating = (_gif && _gif->started());
|
bool animating = (_gif && _gif->started());
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
if (!_radial) {
|
if (!_radial) {
|
||||||
_radial = std::make_unique<Ui::RadialAnimation>(animation(const_cast<Game*>(this), &Game::step_radial));
|
_radial = std::make_unique<Ui::RadialAnimation>([=](crl::time now) {
|
||||||
|
return radialAnimationCallback(now);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!_radial->animating()) {
|
if (!_radial->animating()) {
|
||||||
_radial->start(document->progress());
|
_radial->start(document->progress());
|
||||||
|
@ -1360,31 +1361,28 @@ void Game::validateThumbnail(Image *image, QSize size, bool good) const {
|
||||||
size.height());
|
size.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::isRadialAnimation(crl::time ms) const {
|
bool Game::isRadialAnimation(crl::time now) const {
|
||||||
if (!_radial || !_radial->animating()) return false;
|
return _radial
|
||||||
|
&& _radial->animating()
|
||||||
_radial->step(ms);
|
&& radialAnimationCallback(now);
|
||||||
return _radial && _radial->animating();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::step_radial(crl::time ms, bool timer) {
|
bool Game::radialAnimationCallback(crl::time now) const {
|
||||||
const auto document = getResultDocument();
|
const auto document = getResultDocument();
|
||||||
const auto updateRadial = [&] {
|
const auto radialUpdated = [&] {
|
||||||
return _radial->update(
|
return _radial->update(
|
||||||
document->progress(),
|
document->progress(),
|
||||||
!document->loading() || document->loaded(),
|
!document->loading() || document->loaded(),
|
||||||
ms);
|
now);
|
||||||
};
|
}();
|
||||||
if (timer) {
|
if (!anim::Disabled() || radialUpdated) {
|
||||||
if (!anim::Disabled() || updateRadial()) {
|
update();
|
||||||
update();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateRadial();
|
|
||||||
if (!_radial->animating() && document->loaded()) {
|
|
||||||
_radial.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!_radial->animating() && document->loaded()) {
|
||||||
|
_radial.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::clipCallback(Media::Clip::Notification notification) {
|
void Game::clipCallback(Media::Clip::Notification notification) {
|
||||||
|
|
|
@ -92,17 +92,17 @@ private:
|
||||||
void prepareThumbnail(QSize size, QSize frame) const;
|
void prepareThumbnail(QSize size, QSize frame) const;
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
bool isRadialAnimation(crl::time ms) const;
|
bool isRadialAnimation(crl::time now) const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now) const;
|
||||||
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
struct AnimationData {
|
struct AnimationData {
|
||||||
AnimationData(AnimationCallbacks &&callbacks)
|
template <typename Callback>
|
||||||
: over(false)
|
AnimationData(Callback &&callback)
|
||||||
, radial(std::move(callbacks)) {
|
: radial(std::forward<Callback>(callback)) {
|
||||||
}
|
}
|
||||||
bool over;
|
bool over = false;
|
||||||
Animation _a_over;
|
Animation _a_over;
|
||||||
Ui::RadialAnimation radial;
|
Ui::RadialAnimation radial;
|
||||||
};
|
};
|
||||||
|
@ -250,17 +250,16 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void thumbAnimationCallback();
|
void thumbAnimationCallback();
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now) const;
|
||||||
|
|
||||||
void ensureAnimation() const;
|
void ensureAnimation() const;
|
||||||
void checkAnimationFinished() const;
|
void checkAnimationFinished() const;
|
||||||
bool updateStatusText() const;
|
bool updateStatusText() const;
|
||||||
|
|
||||||
bool isRadialAnimation(crl::time ms) const {
|
bool isRadialAnimation(crl::time now) const {
|
||||||
if (!_animation || !_animation->radial.animating()) return false;
|
return _animation
|
||||||
|
&& _animation->radial.animating()
|
||||||
_animation->radial.step(ms);
|
&& radialAnimationCallback(now);
|
||||||
return _animation && _animation->radial.animating();
|
|
||||||
}
|
}
|
||||||
bool isThumbAnimation(crl::time ms) const {
|
bool isThumbAnimation(crl::time ms) const {
|
||||||
if (_animation) {
|
if (_animation) {
|
||||||
|
@ -273,7 +272,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnimationData {
|
struct AnimationData {
|
||||||
AnimationData(AnimationCallbacks &&radialCallbacks) : radial(std::move(radialCallbacks)) {
|
template <typename Callback>
|
||||||
|
AnimationData(Callback &&radialCallback)
|
||||||
|
: radial(std::forward<Callback>(radialCallback)) {
|
||||||
}
|
}
|
||||||
Animation a_thumbOver;
|
Animation a_thumbOver;
|
||||||
Ui::RadialAnimation radial;
|
Ui::RadialAnimation radial;
|
||||||
|
@ -360,8 +361,8 @@ private:
|
||||||
void prepareThumbnail(QSize size) const;
|
void prepareThumbnail(QSize size) const;
|
||||||
void validateThumbnail(Image *image, QSize size, bool good) const;
|
void validateThumbnail(Image *image, QSize size, bool good) const;
|
||||||
|
|
||||||
bool isRadialAnimation(crl::time ms) const;
|
bool isRadialAnimation(crl::time now) const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now) const;
|
||||||
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ void ItemBase::preload() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemBase::update() {
|
void ItemBase::update() const {
|
||||||
if (_position >= 0) {
|
if (_position >= 0) {
|
||||||
context()->inlineItemRepaint(this);
|
context()->inlineItemRepaint(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
|
|
||||||
virtual void preload() const;
|
virtual void preload() const;
|
||||||
|
|
||||||
void update();
|
void update() const;
|
||||||
void layoutChanged();
|
void layoutChanged();
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
|
|
|
@ -23,6 +23,7 @@ constexpr auto kCaptureFrequency = Player::kDefaultFrequency;
|
||||||
constexpr auto kCaptureSkipDuration = crl::time(400);
|
constexpr auto kCaptureSkipDuration = crl::time(400);
|
||||||
constexpr auto kCaptureFadeInDuration = crl::time(300);
|
constexpr auto kCaptureFadeInDuration = crl::time(300);
|
||||||
constexpr auto kCaptureBufferSlice = 256 * 1024;
|
constexpr auto kCaptureBufferSlice = 256 * 1024;
|
||||||
|
constexpr auto kCaptureUpdateDelta = crl::time(100);
|
||||||
|
|
||||||
Instance *CaptureInstance = nullptr;
|
Instance *CaptureInstance = nullptr;
|
||||||
|
|
||||||
|
@ -517,7 +518,7 @@ void Instance::Inner::onTimeout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qint32 samplesFull = d->fullSamples + _captured.size() / sizeof(short), samplesSinceUpdate = samplesFull - d->lastUpdate;
|
qint32 samplesFull = d->fullSamples + _captured.size() / sizeof(short), samplesSinceUpdate = samplesFull - d->lastUpdate;
|
||||||
if (samplesSinceUpdate > AudioVoiceMsgUpdateView * kCaptureFrequency / 1000) {
|
if (samplesSinceUpdate > kCaptureUpdateDelta * kCaptureFrequency / 1000) {
|
||||||
emit updated(d->levelMax, samplesFull);
|
emit updated(d->levelMax, samplesFull);
|
||||||
d->lastUpdate = samplesFull;
|
d->lastUpdate = samplesFull;
|
||||||
d->levelMax = 0;
|
d->levelMax = 0;
|
||||||
|
|
|
@ -147,12 +147,13 @@ struct OverlayWidget::Collage {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OverlayWidget::Streamed {
|
struct OverlayWidget::Streamed {
|
||||||
|
template <typename Callback>
|
||||||
Streamed(
|
Streamed(
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
std::unique_ptr<Streaming::Loader> loader,
|
std::unique_ptr<Streaming::Loader> loader,
|
||||||
QWidget *controlsParent,
|
QWidget *controlsParent,
|
||||||
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
||||||
AnimationCallbacks loadingCallbacks);
|
Callback &&loadingCallback);
|
||||||
|
|
||||||
Streaming::Player player;
|
Streaming::Player player;
|
||||||
Streaming::Information info;
|
Streaming::Information info;
|
||||||
|
@ -160,22 +161,25 @@ struct OverlayWidget::Streamed {
|
||||||
|
|
||||||
bool waiting = false;
|
bool waiting = false;
|
||||||
Ui::InfiniteRadialAnimation radial;
|
Ui::InfiniteRadialAnimation radial;
|
||||||
Animation fading;
|
Ui::Animations::Simple fading;
|
||||||
base::Timer timer;
|
base::Timer timer;
|
||||||
QImage frameForDirectPaint;
|
QImage frameForDirectPaint;
|
||||||
|
|
||||||
bool resumeOnCallEnd = false;
|
bool resumeOnCallEnd = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
OverlayWidget::Streamed::Streamed(
|
OverlayWidget::Streamed::Streamed(
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
std::unique_ptr<Streaming::Loader> loader,
|
std::unique_ptr<Streaming::Loader> loader,
|
||||||
QWidget *controlsParent,
|
QWidget *controlsParent,
|
||||||
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
||||||
AnimationCallbacks loadingCallbacks)
|
Callback &&loadingCallback)
|
||||||
: player(owner, std::move(loader))
|
: player(owner, std::move(loader))
|
||||||
, controls(controlsParent, controlsDelegate)
|
, controls(controlsParent, controlsDelegate)
|
||||||
, radial(std::move(loadingCallbacks), st::mediaviewStreamingRadial) {
|
, radial(
|
||||||
|
std::forward<Callback>(loadingCallback),
|
||||||
|
st::mediaviewStreamingRadial) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayWidget::OverlayWidget()
|
OverlayWidget::OverlayWidget()
|
||||||
|
@ -184,7 +188,7 @@ OverlayWidget::OverlayWidget()
|
||||||
, _docDownload(this, lang(lng_media_download), st::mediaviewFileLink)
|
, _docDownload(this, lang(lng_media_download), st::mediaviewFileLink)
|
||||||
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
|
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
|
||||||
, _docCancel(this, lang(lng_cancel), st::mediaviewFileLink)
|
, _docCancel(this, lang(lng_cancel), st::mediaviewFileLink)
|
||||||
, _radial(animation(this, &OverlayWidget::step_radial))
|
, _radial([=](crl::time now) { return radialAnimationCallback(now); })
|
||||||
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
|
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
|
||||||
, _stateAnimation([=](crl::time now) { return stateAnimationCallback(now); })
|
, _stateAnimation([=](crl::time now) { return stateAnimationCallback(now); })
|
||||||
, _dropdown(this, st::mediaviewDropdownMenu)
|
, _dropdown(this, st::mediaviewDropdownMenu)
|
||||||
|
@ -704,8 +708,8 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) {
|
||||||
return (dt < 1);
|
return (dt < 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::step_waiting(crl::time ms, bool timer) {
|
void OverlayWidget::waitingAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update(radialRect());
|
update(radialRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,17 +806,17 @@ crl::time OverlayWidget::radialTimeShift() const {
|
||||||
return _photo ? st::radialDuration : 0;
|
return _photo ? st::radialDuration : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::step_radial(crl::time ms, bool timer) {
|
bool OverlayWidget::radialAnimationCallback(crl::time now) {
|
||||||
if ((!_doc && !_photo) || _streamed) {
|
if ((!_doc && !_photo) || _streamed) {
|
||||||
_radial.stop();
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const auto wasAnimating = _radial.animating();
|
const auto wasAnimating = _radial.animating();
|
||||||
const auto updated = _radial.update(
|
const auto updated = _radial.update(
|
||||||
radialProgress(),
|
radialProgress(),
|
||||||
!radialLoading(),
|
!radialLoading(),
|
||||||
ms + radialTimeShift());
|
now + radialTimeShift());
|
||||||
if (timer && (wasAnimating || _radial.animating()) && (!anim::Disabled() || updated)) {
|
if ((wasAnimating || _radial.animating())
|
||||||
|
&& (!anim::Disabled() || updated)) {
|
||||||
update(radialRect());
|
update(radialRect());
|
||||||
}
|
}
|
||||||
const auto ready = _doc && _doc->loaded();
|
const auto ready = _doc && _doc->loaded();
|
||||||
|
@ -833,6 +837,7 @@ void OverlayWidget::step_radial(crl::time ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::zoomIn() {
|
void OverlayWidget::zoomIn() {
|
||||||
|
@ -1986,7 +1991,7 @@ void OverlayWidget::createStreamingObjects() {
|
||||||
_doc->createStreamingLoader(fileOrigin()),
|
_doc->createStreamingLoader(fileOrigin()),
|
||||||
this,
|
this,
|
||||||
static_cast<PlaybackControls::Delegate*>(this),
|
static_cast<PlaybackControls::Delegate*>(this),
|
||||||
animation(this, &OverlayWidget::step_waiting));
|
[=] { waitingAnimationCallback(); });
|
||||||
|
|
||||||
if (videoIsGifv()) {
|
if (videoIsGifv()) {
|
||||||
_streamed->controls.hide();
|
_streamed->controls.hide();
|
||||||
|
@ -2449,13 +2454,8 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool radial = false;
|
const auto radial = _radial.animating();
|
||||||
float64 radialOpacity = 0;
|
const auto radialOpacity = radial ? _radial.opacity() : 0.;
|
||||||
if (_radial.animating()) {
|
|
||||||
_radial.step(ms);
|
|
||||||
radial = _radial.animating();
|
|
||||||
radialOpacity = _radial.opacity();
|
|
||||||
}
|
|
||||||
paintRadialLoading(p, radial, radialOpacity);
|
paintRadialLoading(p, radial, radialOpacity);
|
||||||
}
|
}
|
||||||
if (_saveMsgStarted && _saveMsg.intersects(r)) {
|
if (_saveMsgStarted && _saveMsg.intersects(r)) {
|
||||||
|
@ -2491,13 +2491,8 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (_docRect.intersects(r)) {
|
if (_docRect.intersects(r)) {
|
||||||
p.fillRect(_docRect, st::mediaviewFileBg);
|
p.fillRect(_docRect, st::mediaviewFileBg);
|
||||||
if (_docIconRect.intersects(r)) {
|
if (_docIconRect.intersects(r)) {
|
||||||
bool radial = false;
|
const auto radial = _radial.animating();
|
||||||
float64 radialOpacity = 0;
|
const auto radialOpacity = radial ? _radial.opacity() : 0.;
|
||||||
if (_radial.animating()) {
|
|
||||||
_radial.step(ms);
|
|
||||||
radial = _radial.animating();
|
|
||||||
radialOpacity = _radial.opacity();
|
|
||||||
}
|
|
||||||
if (!_doc || !_doc->hasThumbnail()) {
|
if (!_doc || !_doc->hasThumbnail()) {
|
||||||
p.fillRect(_docIconRect, _docIconColor);
|
p.fillRect(_docIconRect, _docIconColor);
|
||||||
if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) {
|
if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) {
|
||||||
|
@ -2721,12 +2716,9 @@ void OverlayWidget::paintRadialLoading(
|
||||||
bool radial,
|
bool radial,
|
||||||
float64 radialOpacity) {
|
float64 radialOpacity) {
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
const auto ms = crl::now();
|
|
||||||
_streamed->radial.step(ms);
|
|
||||||
if (!_streamed->radial.animating()) {
|
if (!_streamed->radial.animating()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_streamed->fading.step(ms);
|
|
||||||
if (!_streamed->fading.animating() && !_streamed->waiting) {
|
if (!_streamed->fading.animating() && !_streamed->waiting) {
|
||||||
if (!_streamed->waiting) {
|
if (!_streamed->waiting) {
|
||||||
_streamed->radial.stop(anim::type::instant);
|
_streamed->radial.stop(anim::type::instant);
|
||||||
|
@ -2783,7 +2775,7 @@ void OverlayWidget::paintRadialLoadingContent(
|
||||||
|
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
paintBg(
|
paintBg(
|
||||||
_streamed->fading.current(_streamed->waiting ? 1. : 0.),
|
_streamed->fading.value(_streamed->waiting ? 1. : 0.),
|
||||||
st::radialBg);
|
st::radialBg);
|
||||||
_streamed->radial.draw(p, arc.topLeft(), arc.size(), width());
|
_streamed->radial.draw(p, arc.topLeft(), arc.size(), width());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -276,8 +276,8 @@ private:
|
||||||
|
|
||||||
void clearControlsState();
|
void clearControlsState();
|
||||||
bool stateAnimationCallback(crl::time ms);
|
bool stateAnimationCallback(crl::time ms);
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now);
|
||||||
void step_waiting(crl::time ms, bool timer);
|
void waitingAnimationCallback();
|
||||||
bool updateControlsAnimation(crl::time now);
|
bool updateControlsAnimation(crl::time now);
|
||||||
|
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
|
|
|
@ -218,29 +218,29 @@ void RadialProgressItem::setLinks(
|
||||||
_cancell = std::move(cancell);
|
_cancell = std::move(cancell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialProgressItem::step_radial(crl::time ms, bool timer) {
|
bool RadialProgressItem::radialAnimationCallback(crl::time now) const {
|
||||||
const auto updateRadial = [&] {
|
const auto radialUpdated = [&] {
|
||||||
return _radial->update(dataProgress(), dataFinished(), ms);
|
return _radial->update(dataProgress(), dataFinished(), now);
|
||||||
};
|
}();
|
||||||
if (timer) {
|
if (!anim::Disabled() || radialUpdated) {
|
||||||
if (!anim::Disabled() || updateRadial()) {
|
Auth().data().requestItemRepaint(parent());
|
||||||
Auth().data().requestItemRepaint(parent());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateRadial();
|
|
||||||
if (!_radial->animating()) {
|
|
||||||
checkRadialFinished();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!_radial->animating()) {
|
||||||
|
checkRadialFinished();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialProgressItem::ensureRadial() {
|
void RadialProgressItem::ensureRadial() {
|
||||||
if (!_radial) {
|
if (!_radial) {
|
||||||
_radial = std::make_unique<Ui::RadialAnimation>(animation(const_cast<RadialProgressItem*>(this), &RadialProgressItem::step_radial));
|
_radial = std::make_unique<Ui::RadialAnimation>([=](crl::time now) {
|
||||||
|
return radialAnimationCallback(now);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialProgressItem::checkRadialFinished() {
|
void RadialProgressItem::checkRadialFinished() const {
|
||||||
if (_radial && !_radial->animating() && dataLoaded()) {
|
if (_radial && !_radial->animating() && dataLoaded()) {
|
||||||
_radial.reset();
|
_radial.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,16 +129,15 @@ protected:
|
||||||
ClickHandlerPtr &&cancell);
|
ClickHandlerPtr &&cancell);
|
||||||
void setDocumentLinks(not_null<DocumentData*> document);
|
void setDocumentLinks(not_null<DocumentData*> document);
|
||||||
|
|
||||||
void step_radial(crl::time ms, bool timer);
|
bool radialAnimationCallback(crl::time now) const;
|
||||||
|
|
||||||
void ensureRadial();
|
void ensureRadial();
|
||||||
void checkRadialFinished();
|
void checkRadialFinished() const;
|
||||||
|
|
||||||
bool isRadialAnimation(crl::time ms) const {
|
bool isRadialAnimation(crl::time now) const {
|
||||||
if (!_radial || !_radial->animating()) return false;
|
return _radial
|
||||||
|
&& _radial->animating()
|
||||||
_radial->step(ms);
|
&& radialAnimationCallback(now);
|
||||||
return _radial && _radial->animating();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual float64 dataProgress() const = 0;
|
virtual float64 dataProgress() const = 0;
|
||||||
|
@ -148,7 +147,7 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Ui::RadialAnimation> _radial;
|
mutable std::unique_ptr<Ui::RadialAnimation> _radial;
|
||||||
Animation _a_iconOver;
|
Animation _a_iconOver;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@ private:
|
||||||
QRect radialRect() const;
|
QRect radialRect() const;
|
||||||
void radialStart();
|
void radialStart();
|
||||||
crl::time radialTimeShift() const;
|
crl::time radialTimeShift() const;
|
||||||
void step_radial(crl::time ms, bool timer);
|
void radialAnimationCallback(crl::time now);
|
||||||
|
|
||||||
QPixmap _background;
|
QPixmap _background;
|
||||||
object_ptr<Ui::LinkButton> _chooseFromGallery;
|
object_ptr<Ui::LinkButton> _chooseFromGallery;
|
||||||
|
@ -114,7 +114,7 @@ BackgroundRow::BackgroundRow(QWidget *parent) : RpWidget(parent)
|
||||||
lang(lng_settings_bg_from_gallery),
|
lang(lng_settings_bg_from_gallery),
|
||||||
st::settingsLink)
|
st::settingsLink)
|
||||||
, _chooseFromFile(this, lang(lng_settings_bg_from_file), st::settingsLink)
|
, _chooseFromFile(this, lang(lng_settings_bg_from_file), st::settingsLink)
|
||||||
, _radial(animation(this, &BackgroundRow::step_radial)) {
|
, _radial([=](crl::time now) { radialAnimationCallback(now); }) {
|
||||||
updateImage();
|
updateImage();
|
||||||
|
|
||||||
_chooseFromGallery->addClickHandler([] {
|
_chooseFromGallery->addClickHandler([] {
|
||||||
|
@ -139,13 +139,8 @@ BackgroundRow::BackgroundRow(QWidget *parent) : RpWidget(parent)
|
||||||
void BackgroundRow::paintEvent(QPaintEvent *e) {
|
void BackgroundRow::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
bool radial = false;
|
const auto radial = _radial.animating();
|
||||||
float64 radialOpacity = 0;
|
const auto radialOpacity = radial ? _radial.opacity() : 0.;
|
||||||
if (_radial.animating()) {
|
|
||||||
_radial.step(crl::now());
|
|
||||||
radial = _radial.animating();
|
|
||||||
radialOpacity = _radial.opacity();
|
|
||||||
}
|
|
||||||
if (radial) {
|
if (radial) {
|
||||||
const auto backThumb = App::main()->newBackgroundThumb();
|
const auto backThumb = App::main()->newBackgroundThumb();
|
||||||
if (!backThumb) {
|
if (!backThumb) {
|
||||||
|
@ -249,12 +244,12 @@ crl::time BackgroundRow::radialTimeShift() const {
|
||||||
return st::radialDuration;
|
return st::radialDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundRow::step_radial(crl::time ms, bool timer) {
|
void BackgroundRow::radialAnimationCallback(crl::time now) {
|
||||||
const auto updated = _radial.update(
|
const auto updated = _radial.update(
|
||||||
radialProgress(),
|
radialProgress(),
|
||||||
!radialLoading(),
|
!radialLoading(),
|
||||||
ms + radialTimeShift());
|
now + radialTimeShift());
|
||||||
if (timer && _radial.animating() && (!anim::Disabled() || updated)) {
|
if (!anim::Disabled() || updated) {
|
||||||
rtlupdate(radialRect());
|
rtlupdate(radialRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
RadialAnimation::RadialAnimation(AnimationCallbacks &&callbacks)
|
|
||||||
: a_arcStart(0, FullArcLength)
|
|
||||||
, _animation(std::move(callbacks)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void RadialAnimation::start(float64 prg) {
|
void RadialAnimation::start(float64 prg) {
|
||||||
_firstStart = _lastStart = _lastTime = crl::now();
|
_firstStart = _lastStart = _lastTime = crl::now();
|
||||||
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength), iprgstrict = qRound(prg * AlmostFullArcLength);
|
const auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
||||||
a_arcEnd = anim::value(iprgstrict, iprg);
|
const auto iprgstrict = qRound(prg * AlmostFullArcLength);
|
||||||
|
_arcEnd = anim::value(iprgstrict, iprg);
|
||||||
_animation.start();
|
_animation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RadialAnimation::update(float64 prg, bool finished, crl::time ms) {
|
bool RadialAnimation::update(float64 prg, bool finished, crl::time ms) {
|
||||||
const auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
const auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
||||||
const auto result = (iprg != qRound(a_arcEnd.to()));
|
const auto result = (iprg != qRound(_arcEnd.to()));
|
||||||
if (_finished != finished) {
|
if (_finished != finished) {
|
||||||
a_arcEnd.start(iprg);
|
_arcEnd.start(iprg);
|
||||||
_finished = finished;
|
_finished = finished;
|
||||||
_lastStart = _lastTime;
|
_lastStart = _lastTime;
|
||||||
} else if (result) {
|
} else if (result) {
|
||||||
a_arcEnd.start(iprg);
|
_arcEnd.start(iprg);
|
||||||
_lastStart = _lastTime;
|
_lastStart = _lastTime;
|
||||||
}
|
}
|
||||||
_lastTime = ms;
|
_lastTime = ms;
|
||||||
|
@ -43,35 +39,31 @@ bool RadialAnimation::update(float64 prg, bool finished, crl::time ms) {
|
||||||
: fulldt;
|
: fulldt;
|
||||||
_opacity = qMin(opacitydt / st::radialDuration, 1.);
|
_opacity = qMin(opacitydt / st::radialDuration, 1.);
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
a_arcEnd.update(1., anim::linear);
|
_arcEnd.update(1., anim::linear);
|
||||||
if (finished) {
|
if (finished) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
} else if (!finished) {
|
} else if (!finished) {
|
||||||
a_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
|
_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
|
||||||
} else if (dt >= st::radialDuration) {
|
} else if (dt >= st::radialDuration) {
|
||||||
a_arcEnd.update(1., anim::linear);
|
_arcEnd.update(1., anim::linear);
|
||||||
stop();
|
stop();
|
||||||
} else {
|
} else {
|
||||||
auto r = dt / st::radialDuration;
|
auto r = dt / st::radialDuration;
|
||||||
a_arcEnd.update(r, anim::linear);
|
_arcEnd.update(r, anim::linear);
|
||||||
_opacity *= 1 - r;
|
_opacity *= 1 - r;
|
||||||
}
|
}
|
||||||
auto fromstart = fulldt / st::radialPeriod;
|
auto fromstart = fulldt / st::radialPeriod;
|
||||||
a_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
|
_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::stop() {
|
void RadialAnimation::stop() {
|
||||||
_firstStart = _lastStart = _lastTime = 0;
|
_firstStart = _lastStart = _lastTime = 0;
|
||||||
a_arcEnd = anim::value();
|
_arcEnd = anim::value();
|
||||||
_animation.stop();
|
_animation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::step(crl::time ms) {
|
|
||||||
_animation.step(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RadialAnimation::draw(
|
void RadialAnimation::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &inner,
|
const QRect &inner,
|
||||||
|
@ -98,10 +90,10 @@ void RadialAnimation::draw(
|
||||||
}
|
}
|
||||||
|
|
||||||
RadialState RadialAnimation::computeState() const {
|
RadialState RadialAnimation::computeState() const {
|
||||||
auto length = MinArcLength + qRound(a_arcEnd.current());
|
auto length = MinArcLength + qRound(_arcEnd.current());
|
||||||
auto from = QuarterArcLength
|
auto from = QuarterArcLength
|
||||||
- length
|
- length
|
||||||
- (anim::Disabled() ? 0 : qRound(a_arcStart.current()));
|
- (anim::Disabled() ? 0 : qRound(_arcStart.current()));
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
from = QuarterArcLength - (from - QuarterArcLength) - length;
|
from = QuarterArcLength - (from - QuarterArcLength) - length;
|
||||||
if (from < 0) from += FullArcLength;
|
if (from < 0) from += FullArcLength;
|
||||||
|
@ -109,13 +101,6 @@ RadialState RadialAnimation::computeState() const {
|
||||||
return { _opacity, from, length };
|
return { _opacity, from, length };
|
||||||
}
|
}
|
||||||
|
|
||||||
InfiniteRadialAnimation::InfiniteRadialAnimation(
|
|
||||||
AnimationCallbacks &&callbacks,
|
|
||||||
const style::InfiniteRadialAnimation &st)
|
|
||||||
: _st(st)
|
|
||||||
, _animation(std::move(callbacks)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfiniteRadialAnimation::start(crl::time skip) {
|
void InfiniteRadialAnimation::start(crl::time skip) {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
if (_workFinished <= now && (_workFinished || !_workStarted)) {
|
if (_workFinished <= now && (_workFinished || !_workStarted)) {
|
||||||
|
@ -145,10 +130,6 @@ void InfiniteRadialAnimation::stop(anim::type animated) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfiniteRadialAnimation::step(crl::time ms) {
|
|
||||||
_animation.step(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfiniteRadialAnimation::draw(
|
void InfiniteRadialAnimation::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct InfiniteRadialAnimation;
|
struct InfiniteRadialAnimation;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
@ -21,7 +23,8 @@ struct RadialState {
|
||||||
|
|
||||||
class RadialAnimation {
|
class RadialAnimation {
|
||||||
public:
|
public:
|
||||||
RadialAnimation(AnimationCallbacks &&callbacks);
|
template <typename Callback>
|
||||||
|
RadialAnimation(Callback &&callback);
|
||||||
|
|
||||||
float64 opacity() const {
|
float64 opacity() const {
|
||||||
return _opacity;
|
return _opacity;
|
||||||
|
@ -34,11 +37,6 @@ public:
|
||||||
bool update(float64 prg, bool finished, crl::time ms);
|
bool update(float64 prg, bool finished, crl::time ms);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void step(crl::time ms);
|
|
||||||
void step() {
|
|
||||||
step(crl::now());
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &inner,
|
const QRect &inner,
|
||||||
|
@ -52,17 +50,25 @@ private:
|
||||||
crl::time _lastStart = 0;
|
crl::time _lastStart = 0;
|
||||||
crl::time _lastTime = 0;
|
crl::time _lastTime = 0;
|
||||||
float64 _opacity = 0.;
|
float64 _opacity = 0.;
|
||||||
anim::value a_arcEnd;
|
anim::value _arcEnd;
|
||||||
anim::value a_arcStart;
|
anim::value _arcStart;
|
||||||
BasicAnimation _animation;
|
Ui::Animations::Basic _animation;
|
||||||
bool _finished = false;
|
bool _finished = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
inline RadialAnimation::RadialAnimation(Callback &&callback)
|
||||||
|
: _arcStart(0, FullArcLength)
|
||||||
|
, _animation(std::forward<Callback>(callback)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class InfiniteRadialAnimation {
|
class InfiniteRadialAnimation {
|
||||||
public:
|
public:
|
||||||
|
template <typename Callback>
|
||||||
InfiniteRadialAnimation(
|
InfiniteRadialAnimation(
|
||||||
AnimationCallbacks &&callbacks,
|
Callback &&callback,
|
||||||
const style::InfiniteRadialAnimation &st);
|
const style::InfiniteRadialAnimation &st);
|
||||||
|
|
||||||
bool animating() const {
|
bool animating() const {
|
||||||
|
@ -72,11 +78,6 @@ public:
|
||||||
void start(crl::time skip = 0);
|
void start(crl::time skip = 0);
|
||||||
void stop(anim::type animated = anim::type::normal);
|
void stop(anim::type animated = anim::type::normal);
|
||||||
|
|
||||||
void step(crl::time ms);
|
|
||||||
void step() {
|
|
||||||
step(crl::now());
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
@ -93,8 +94,16 @@ private:
|
||||||
const style::InfiniteRadialAnimation &_st;
|
const style::InfiniteRadialAnimation &_st;
|
||||||
crl::time _workStarted = 0;
|
crl::time _workStarted = 0;
|
||||||
crl::time _workFinished = 0;
|
crl::time _workFinished = 0;
|
||||||
BasicAnimation _animation;
|
Ui::Animations::Basic _animation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
inline InfiniteRadialAnimation::InfiniteRadialAnimation(
|
||||||
|
Callback &&callback,
|
||||||
|
const style::InfiniteRadialAnimation &st)
|
||||||
|
: _st(st)
|
||||||
|
, _animation(std::forward<Callback>(callback)) {
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -242,8 +242,8 @@ void EmojiButton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiButton::step_loading(crl::time ms, bool timer) {
|
void EmojiButton::loadingAnimationCallback() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ void EmojiButton::step_loading(crl::time ms, bool timer) {
|
||||||
void EmojiButton::setLoading(bool loading) {
|
void EmojiButton::setLoading(bool loading) {
|
||||||
if (loading && !_loading) {
|
if (loading && !_loading) {
|
||||||
_loading = std::make_unique<Ui::InfiniteRadialAnimation>(
|
_loading = std::make_unique<Ui::InfiniteRadialAnimation>(
|
||||||
animation(this, &EmojiButton::step_loading),
|
[=] { loadingAnimationCallback(); },
|
||||||
st::defaultInfiniteRadialAnimation);
|
st::defaultInfiniteRadialAnimation);
|
||||||
}
|
}
|
||||||
if (loading) {
|
if (loading) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ protected:
|
||||||
QPoint prepareRippleStartPosition() const override;
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void step_loading(crl::time ms, bool timer);
|
void loadingAnimationCallback();
|
||||||
|
|
||||||
const style::IconButton &_st;
|
const style::IconButton &_st;
|
||||||
|
|
||||||
|
|
|
@ -277,10 +277,11 @@ void Manager::removeWidget(internal::Widget *remove) {
|
||||||
if (remove == _hideAll.get()) {
|
if (remove == _hideAll.get()) {
|
||||||
_hideAll.reset();
|
_hideAll.reset();
|
||||||
} else if (remove) {
|
} else if (remove) {
|
||||||
auto it = std::find_if(_notifications.cbegin(), _notifications.cend(), [remove](auto &item) {
|
const auto it = ranges::find(
|
||||||
return item.get() == remove;
|
_notifications,
|
||||||
});
|
remove,
|
||||||
if (it != _notifications.cend()) {
|
&std::unique_ptr<Notification>::get);
|
||||||
|
if (it != end(_notifications)) {
|
||||||
_notifications.erase(it);
|
_notifications.erase(it);
|
||||||
_positionsOutdated = true;
|
_positionsOutdated = true;
|
||||||
}
|
}
|
||||||
|
@ -289,13 +290,13 @@ void Manager::removeWidget(internal::Widget *remove) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::doShowNotification(HistoryItem *item, int forwardedCount) {
|
void Manager::doShowNotification(HistoryItem *item, int forwardedCount) {
|
||||||
_queuedNotifications.push_back(QueuedNotification(item, forwardedCount));
|
_queuedNotifications.emplace_back(item, forwardedCount);
|
||||||
showNextFromQueue();
|
showNextFromQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::doClearAll() {
|
void Manager::doClearAll() {
|
||||||
_queuedNotifications.clear();
|
_queuedNotifications.clear();
|
||||||
for_const (auto ¬ification, _notifications) {
|
for (const auto ¬ification : _notifications) {
|
||||||
notification->unlinkHistory();
|
notification->unlinkHistory();
|
||||||
}
|
}
|
||||||
showNextFromQueue();
|
showNextFromQueue();
|
||||||
|
@ -356,8 +357,10 @@ Widget::Widget(Manager *manager, QPoint startPosition, int shift, Direction shif
|
||||||
, _manager(manager)
|
, _manager(manager)
|
||||||
, _startPosition(startPosition)
|
, _startPosition(startPosition)
|
||||||
, _direction(shiftDirection)
|
, _direction(shiftDirection)
|
||||||
, a_shift(shift)
|
, _shift(shift)
|
||||||
, _a_shift(animation(this, &Widget::step_shift)) {
|
, _shiftAnimation([=](crl::time now) {
|
||||||
|
return shiftAnimationCallback(now);
|
||||||
|
}) {
|
||||||
setWindowOpacity(0.);
|
setWindowOpacity(0.);
|
||||||
|
|
||||||
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint)
|
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint)
|
||||||
|
@ -392,17 +395,19 @@ void Widget::opacityAnimationCallback() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::step_shift(float64 ms, bool timer) {
|
bool Widget::shiftAnimationCallback(crl::time now) {
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled()) {
|
||||||
ms += st::notifyFastAnim;
|
now += st::notifyFastAnim;
|
||||||
}
|
}
|
||||||
float64 dt = ms / float64(st::notifyFastAnim);
|
const auto dt = (now - _shiftAnimation.started())
|
||||||
if (dt >= 1) {
|
/ float64(st::notifyFastAnim);
|
||||||
a_shift.finish();
|
if (dt >= 1.) {
|
||||||
|
_shift.finish();
|
||||||
} else {
|
} else {
|
||||||
a_shift.update(dt, anim::linear);
|
_shift.update(dt, anim::linear);
|
||||||
}
|
}
|
||||||
moveByShift();
|
moveByShift();
|
||||||
|
return (dt < 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::hideSlow() {
|
void Widget::hideSlow() {
|
||||||
|
@ -443,8 +448,8 @@ void Widget::updateOpacity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::changeShift(int top) {
|
void Widget::changeShift(int top) {
|
||||||
a_shift.start(top);
|
_shift.start(top);
|
||||||
_a_shift.start();
|
_shiftAnimation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updatePosition(QPoint startPosition, Direction shiftDirection) {
|
void Widget::updatePosition(QPoint startPosition, Direction shiftDirection) {
|
||||||
|
@ -466,7 +471,7 @@ void Widget::updateGeometry(int x, int y, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::addToShift(int add) {
|
void Widget::addToShift(int add) {
|
||||||
a_shift.add(add);
|
_shift.add(add);
|
||||||
moveByShift();
|
moveByShift();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +480,7 @@ void Widget::moveByShift() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint Widget::computePosition(int height) const {
|
QPoint Widget::computePosition(int height) const {
|
||||||
auto realShift = qRound(a_shift.current());
|
auto realShift = qRound(_shift.current());
|
||||||
if (_direction == Direction::Up) {
|
if (_direction == Direction::Up) {
|
||||||
realShift = -realShift - height;
|
realShift = -realShift - height;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +683,7 @@ void Notification::updateNotifyDisplay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.hideMessageText) {
|
if (!options.hideMessageText) {
|
||||||
const HistoryItem *textCachedFor = 0;
|
const HistoryItem *textCachedFor = nullptr;
|
||||||
Text itemTextCache(itemWidth);
|
Text itemTextCache(itemWidth);
|
||||||
QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height);
|
QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height);
|
||||||
if (_item) {
|
if (_item) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -115,7 +116,7 @@ public:
|
||||||
void updateOpacity();
|
void updateOpacity();
|
||||||
void changeShift(int top);
|
void changeShift(int top);
|
||||||
int currentShift() const {
|
int currentShift() const {
|
||||||
return a_shift.current();
|
return _shift.current();
|
||||||
}
|
}
|
||||||
void updatePosition(QPoint startPosition, Direction shiftDirection);
|
void updatePosition(QPoint startPosition, Direction shiftDirection);
|
||||||
void addToHeight(int add);
|
void addToHeight(int add);
|
||||||
|
@ -139,7 +140,7 @@ private:
|
||||||
void destroyDelayed();
|
void destroyDelayed();
|
||||||
void moveByShift();
|
void moveByShift();
|
||||||
void hideAnimated(float64 duration, const anim::transition &func);
|
void hideAnimated(float64 duration, const anim::transition &func);
|
||||||
void step_shift(float64 ms, bool timer);
|
bool shiftAnimationCallback(crl::time now);
|
||||||
|
|
||||||
Manager *_manager = nullptr;
|
Manager *_manager = nullptr;
|
||||||
|
|
||||||
|
@ -150,8 +151,8 @@ private:
|
||||||
|
|
||||||
QPoint _startPosition;
|
QPoint _startPosition;
|
||||||
Direction _direction;
|
Direction _direction;
|
||||||
anim::value a_shift;
|
anim::value _shift;
|
||||||
BasicAnimation _a_shift;
|
Ui::Animations::Basic _shiftAnimation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void step(crl::time ms, bool timer);
|
void animationStep();
|
||||||
|
|
||||||
Ui::InfiniteRadialAnimation _animation;
|
Ui::InfiniteRadialAnimation _animation;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ private:
|
||||||
|
|
||||||
Progress::Progress(QWidget *parent)
|
Progress::Progress(QWidget *parent)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _animation(animation(this, &Progress::step), st::connectingRadial) {
|
, _animation([=] { animationStep(); }, st::connectingRadial) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
resize(st::connectingRadial.size);
|
resize(st::connectingRadial.size);
|
||||||
|
@ -58,8 +58,8 @@ void Progress::paintEvent(QPaintEvent *e) {
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Progress::step(crl::time ms, bool timer) {
|
void Progress::animationStep() {
|
||||||
if (timer && !anim::Disabled()) {
|
if (!anim::Disabled()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue