Migrated from frequency timer to simple animation for item highlighting.

This commit is contained in:
23rd 2022-06-05 02:44:08 +03:00
parent ba7422805b
commit c9ef5e47fe
13 changed files with 85 additions and 56 deletions

View file

@ -587,9 +587,9 @@ bool InnerWidget::elementUnderCursor(
return (Element::Hovered() == view); return (Element::Hovered() == view);
} }
crl::time InnerWidget::elementHighlightTime( float64 InnerWidget::elementHighlightOpacity(
not_null<const HistoryItem*> item) { not_null<const HistoryItem*> item) const {
return crl::time(0); return 0.;
} }
bool InnerWidget::elementInSelectionMode() { bool InnerWidget::elementInSelectionMode() {

View file

@ -101,8 +101,8 @@ public:
HistoryView::Element *replacing = nullptr) override; HistoryView::Element *replacing = nullptr) override;
bool elementUnderCursor( bool elementUnderCursor(
not_null<const HistoryView::Element*> view) override; not_null<const HistoryView::Element*> view) override;
crl::time elementHighlightTime( [[nodiscard]] float64 elementHighlightOpacity(
not_null<const HistoryItem*> item) override; not_null<const HistoryItem*> item) const override;
bool elementInSelectionMode() override; bool elementInSelectionMode() override;
bool elementIntersectsRange( bool elementIntersectsRange(
not_null<const HistoryView::Element*> view, not_null<const HistoryView::Element*> view,

View file

@ -158,9 +158,9 @@ public:
not_null<const Element*> view) override { not_null<const Element*> view) override {
return (Element::Moused() == view); return (Element::Moused() == view);
} }
crl::time elementHighlightTime( [[nodiscard]] float64 elementHighlightOpacity(
not_null<const HistoryItem*> item) override { not_null<const HistoryItem*> item) const override {
return _widget ? _widget->elementHighlightTime(item) : 0; return _widget ? _widget->elementHighlightOpacity(item) : 0.;
} }
bool elementInSelectionMode() override { bool elementInSelectionMode() override {
return _widget ? _widget->inSelectionMode() : false; return _widget ? _widget->inSelectionMode() : false;
@ -3156,9 +3156,9 @@ void HistoryInner::elementStartStickerLoop(
_animatedStickersPlayed.emplace(view->data()); _animatedStickersPlayed.emplace(view->data());
} }
crl::time HistoryInner::elementHighlightTime( float64 HistoryInner::elementHighlightOpacity(
not_null<const HistoryItem*> item) { not_null<const HistoryItem*> item) const {
return _widget->highlightStartTime(item); return _widget->highlightOpacity(item);
} }
void HistoryInner::elementShowPollResults( void HistoryInner::elementShowPollResults(

View file

@ -124,8 +124,8 @@ public:
int from, int from,
int till) const; int till) const;
void elementStartStickerLoop(not_null<const Element*> view); void elementStartStickerLoop(not_null<const Element*> view);
[[nodiscard]] crl::time elementHighlightTime( [[nodiscard]] float64 elementHighlightOpacity(
not_null<const HistoryItem*> item); not_null<const HistoryItem*> item) const;
void elementShowPollResults( void elementShowPollResults(
not_null<PollData*> poll, not_null<PollData*> poll,
FullMsgId context); FullMsgId context);

View file

@ -20,13 +20,14 @@ ElementHighlighter::ElementHighlighter(
: _data(data) : _data(data)
, _viewForItem(std::move(viewForItem)) , _viewForItem(std::move(viewForItem))
, _repaintView(std::move(repaintView)) , _repaintView(std::move(repaintView))
, _timer([=] { updateMessage(); }) { , _timer([=] { updateMessage(); })
, _animation(*this) {
} }
void ElementHighlighter::enqueue(not_null<Element*> view) { void ElementHighlighter::enqueue(not_null<Element*> view) {
const auto item = view->data(); const auto item = view->data();
const auto fullId = item->fullId(); const auto fullId = item->fullId();
if (_queue.empty() && !_timer.isActive()) { if (_queue.empty() && !_animation.animating()) {
highlight(fullId); highlight(fullId);
} else if (_highlightedMessageId != fullId } else if (_highlightedMessageId != fullId
&& !base::contains(_queue, fullId)) { && !base::contains(_queue, fullId)) {
@ -36,7 +37,7 @@ void ElementHighlighter::enqueue(not_null<Element*> view) {
} }
void ElementHighlighter::checkNextHighlight() { void ElementHighlighter::checkNextHighlight() {
if (_timer.isActive()) { if (_animation.animating()) {
return; return;
} }
const auto nextHighlight = [&] { const auto nextHighlight = [&] {
@ -57,14 +58,16 @@ void ElementHighlighter::checkNextHighlight() {
highlight(nextHighlight); highlight(nextHighlight);
} }
crl::time ElementHighlighter::elementTime( float64 ElementHighlighter::progress(
not_null<const HistoryItem*> item) const { not_null<const HistoryItem*> item) const {
if (item->fullId() == _highlightedMessageId) { if (item->fullId() == _highlightedMessageId) {
if (_timer.isActive()) { const auto progress = _animation.progress();
return crl::now() - _highlightStart; const auto firstPart = st::activeFadeInDuration
} / float64(st::activeFadeInDuration + st::activeFadeOutDuration);
return std::min(progress / firstPart, 1.)
- ((progress - firstPart) / (1. - firstPart));
} }
return crl::time(0); return 0.;
} }
void ElementHighlighter::highlight(FullMsgId itemId) { void ElementHighlighter::highlight(FullMsgId itemId) {
@ -72,7 +75,7 @@ void ElementHighlighter::highlight(FullMsgId itemId) {
if (const auto view = _viewForItem(item)) { if (const auto view = _viewForItem(item)) {
_highlightStart = crl::now(); _highlightStart = crl::now();
_highlightedMessageId = itemId; _highlightedMessageId = itemId;
_timer.callEach(AnimationTimerDelta); _animation.start();
repaintHighlightedItem(view); repaintHighlightedItem(view);
} }
@ -105,7 +108,7 @@ void ElementHighlighter::updateMessage() {
} }
} }
} }
_timer.cancel(); _animation.cancel();
_highlightedMessageId = FullMsgId(); _highlightedMessageId = FullMsgId();
checkNextHighlight(); checkNextHighlight();
} }
@ -115,4 +118,30 @@ void ElementHighlighter::clear() {
updateMessage(); updateMessage();
} }
ElementHighlighter::AnimationManager::AnimationManager(
ElementHighlighter &parent)
: _parent(parent) {
}
bool ElementHighlighter::AnimationManager::animating() const {
return _simple.animating();
}
float64 ElementHighlighter::AnimationManager::progress() const {
return _simple.value(0.);
}
void ElementHighlighter::AnimationManager::start() {
_simple.stop();
_simple.start(
[=] { _parent.updateMessage(); },
0.,
1.,
st::activeFadeInDuration + st::activeFadeOutDuration);
}
void ElementHighlighter::AnimationManager::cancel() {
_simple.stop();
}
} // namespace HistoryView } // namespace HistoryView

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "base/timer.h" #include "base/timer.h"
#include "ui/effects/animations.h"
class HistoryItem; class HistoryItem;
@ -32,14 +33,25 @@ public:
void highlight(FullMsgId itemId); void highlight(FullMsgId itemId);
void clear(); void clear();
[[nodiscard]] crl::time elementTime( [[nodiscard]] float64 progress(not_null<const HistoryItem*> item) const;
not_null<const HistoryItem*> item) const;
private: private:
void checkNextHighlight(); void checkNextHighlight();
void repaintHighlightedItem(not_null<const Element*> view); void repaintHighlightedItem(not_null<const Element*> view);
void updateMessage(); void updateMessage();
class AnimationManager final {
public:
AnimationManager(ElementHighlighter &parent);
[[nodiscard]] bool animating() const;
[[nodiscard]] float64 progress() const;
void start();
void cancel();
private:
ElementHighlighter &_parent;
Ui::Animations::Simple _simple;
};
const not_null<Data::Session*> _data; const not_null<Data::Session*> _data;
const ViewForItem _viewForItem; const ViewForItem _viewForItem;
const RepaintView _repaintView; const RepaintView _repaintView;
@ -49,6 +61,7 @@ private:
base::Timer _timer; base::Timer _timer;
crl::time _highlightStart = 0; crl::time _highlightStart = 0;
AnimationManager _animation;
}; };
} // namespace HistoryView } // namespace HistoryView

View file

@ -1266,9 +1266,9 @@ void HistoryWidget::enqueueMessageHighlight(
_highlighter.enqueue(view); _highlighter.enqueue(view);
} }
crl::time HistoryWidget::highlightStartTime( float64 HistoryWidget::highlightOpacity(
not_null<const HistoryItem*> item) const { not_null<const HistoryItem*> item) const {
return _highlighter.elementTime(item); return _highlighter.progress(item);
} }
int HistoryWidget::itemTopForHighlight( int HistoryWidget::itemTopForHighlight(

View file

@ -191,7 +191,8 @@ public:
bool touchScroll(const QPoint &delta); bool touchScroll(const QPoint &delta);
void enqueueMessageHighlight(not_null<HistoryView::Element*> view); void enqueueMessageHighlight(not_null<HistoryView::Element*> view);
crl::time highlightStartTime(not_null<const HistoryItem*> item) const; [[nodiscard]] float64 highlightOpacity(
not_null<const HistoryItem*> item) const;
MessageIdsList getSelectedItems() const; MessageIdsList getSelectedItems() const;
void itemEdited(not_null<HistoryItem*> item); void itemEdited(not_null<HistoryItem*> item);

View file

@ -124,9 +124,9 @@ bool SimpleElementDelegate::elementUnderCursor(
return false; return false;
} }
crl::time SimpleElementDelegate::elementHighlightTime( float64 SimpleElementDelegate::elementHighlightOpacity(
not_null<const HistoryItem*> item) { not_null<const HistoryItem*> item) const {
return crl::time(0); return 0.;
} }
bool SimpleElementDelegate::elementInSelectionMode() { bool SimpleElementDelegate::elementInSelectionMode() {
@ -442,26 +442,13 @@ void Element::paintHighlight(
paintCustomHighlight(p, context, skiptop, fillheight, data()); paintCustomHighlight(p, context, skiptop, fillheight, data());
} }
float64 Element::highlightOpacity(not_null<const HistoryItem*> item) const {
const auto animms = delegate()->elementHighlightTime(item);
if (!animms
|| animms >= st::activeFadeInDuration + st::activeFadeOutDuration) {
return 0.;
}
return (animms > st::activeFadeInDuration)
? (1. - (animms - st::activeFadeInDuration)
/ float64(st::activeFadeOutDuration))
: (animms / float64(st::activeFadeInDuration));
}
void Element::paintCustomHighlight( void Element::paintCustomHighlight(
Painter &p, Painter &p,
const PaintContext &context, const PaintContext &context,
int y, int y,
int height, int height,
not_null<const HistoryItem*> item) const { not_null<const HistoryItem*> item) const {
const auto opacity = highlightOpacity(item); const auto opacity = delegate()->elementHighlightOpacity(item);
if (opacity == 0.) { if (opacity == 0.) {
return; return;
} }

View file

@ -72,8 +72,8 @@ public:
not_null<HistoryService*> message, not_null<HistoryService*> message,
Element *replacing = nullptr) = 0; Element *replacing = nullptr) = 0;
virtual bool elementUnderCursor(not_null<const Element*> view) = 0; virtual bool elementUnderCursor(not_null<const Element*> view) = 0;
virtual crl::time elementHighlightTime( [[nodiscard]] virtual float64 elementHighlightOpacity(
not_null<const HistoryItem*> item) = 0; not_null<const HistoryItem*> item) const = 0;
virtual bool elementInSelectionMode() = 0; virtual bool elementInSelectionMode() = 0;
virtual bool elementIntersectsRange( virtual bool elementIntersectsRange(
not_null<const Element*> view, not_null<const Element*> view,
@ -134,8 +134,8 @@ public:
not_null<HistoryService*> message, not_null<HistoryService*> message,
Element *replacing = nullptr) override; Element *replacing = nullptr) override;
bool elementUnderCursor(not_null<const Element*> view) override; bool elementUnderCursor(not_null<const Element*> view) override;
crl::time elementHighlightTime( [[nodiscard]] float64 elementHighlightOpacity(
not_null<const HistoryItem*> item) override; not_null<const HistoryItem*> item) const override;
bool elementInSelectionMode() override; bool elementInSelectionMode() override;
bool elementIntersectsRange( bool elementIntersectsRange(
not_null<const Element*> view, not_null<const Element*> view,
@ -410,7 +410,6 @@ public:
int y, int y,
int height, int height,
not_null<const HistoryItem*> item) const; not_null<const HistoryItem*> item) const;
float64 highlightOpacity(not_null<const HistoryItem*> item) const;
// Legacy blocks structure. // Legacy blocks structure.
HistoryBlock *block(); HistoryBlock *block();

View file

@ -1397,9 +1397,9 @@ bool ListWidget::elementUnderCursor(
return (_overElement == view); return (_overElement == view);
} }
crl::time ListWidget::elementHighlightTime( float64 ListWidget::elementHighlightOpacity(
not_null<const HistoryItem*> item) { not_null<const HistoryItem*> item) const {
return _highlighter.elementTime(item); return _highlighter.progress(item);
} }
bool ListWidget::elementInSelectionMode() { bool ListWidget::elementInSelectionMode() {

View file

@ -261,8 +261,8 @@ public:
not_null<HistoryService*> message, not_null<HistoryService*> message,
Element *replacing = nullptr) override; Element *replacing = nullptr) override;
bool elementUnderCursor(not_null<const Element*> view) override; bool elementUnderCursor(not_null<const Element*> view) override;
crl::time elementHighlightTime( [[nodiscard]] float64 elementHighlightOpacity(
not_null<const HistoryItem*> item) override; not_null<const HistoryItem*> item) const override;
bool elementInSelectionMode() override; bool elementInSelectionMode() override;
bool elementIntersectsRange( bool elementIntersectsRange(
not_null<const Element*> view, not_null<const Element*> view,

View file

@ -313,7 +313,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
selection = part.content->skipSelection(selection); selection = part.content->skipSelection(selection);
} }
const auto highlightOpacity = (_mode == Mode::Grid) const auto highlightOpacity = (_mode == Mode::Grid)
? _parent->highlightOpacity(part.item) ? _parent->delegate()->elementHighlightOpacity(part.item)
: 0.; : 0.;
if (!part.cache.isNull()) { if (!part.cache.isNull()) {
wasCache = true; wasCache = true;