diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index c72d2f289..17201f416 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -587,9 +587,9 @@ bool InnerWidget::elementUnderCursor( return (Element::Hovered() == view); } -crl::time InnerWidget::elementHighlightTime( - not_null item) { - return crl::time(0); +float64 InnerWidget::elementHighlightOpacity( + not_null item) const { + return 0.; } bool InnerWidget::elementInSelectionMode() { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h index 1c0a7b42e..256342756 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h @@ -101,8 +101,8 @@ public: HistoryView::Element *replacing = nullptr) override; bool elementUnderCursor( not_null view) override; - crl::time elementHighlightTime( - not_null item) override; + [[nodiscard]] float64 elementHighlightOpacity( + not_null item) const override; bool elementInSelectionMode() override; bool elementIntersectsRange( not_null view, diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index a10436dd9..594ef07d8 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -158,9 +158,9 @@ public: not_null view) override { return (Element::Moused() == view); } - crl::time elementHighlightTime( - not_null item) override { - return _widget ? _widget->elementHighlightTime(item) : 0; + [[nodiscard]] float64 elementHighlightOpacity( + not_null item) const override { + return _widget ? _widget->elementHighlightOpacity(item) : 0.; } bool elementInSelectionMode() override { return _widget ? _widget->inSelectionMode() : false; @@ -3156,9 +3156,9 @@ void HistoryInner::elementStartStickerLoop( _animatedStickersPlayed.emplace(view->data()); } -crl::time HistoryInner::elementHighlightTime( - not_null item) { - return _widget->highlightStartTime(item); +float64 HistoryInner::elementHighlightOpacity( + not_null item) const { + return _widget->highlightOpacity(item); } void HistoryInner::elementShowPollResults( diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index beefbfa80..eaae7ccf7 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -124,8 +124,8 @@ public: int from, int till) const; void elementStartStickerLoop(not_null view); - [[nodiscard]] crl::time elementHighlightTime( - not_null item); + [[nodiscard]] float64 elementHighlightOpacity( + not_null item) const; void elementShowPollResults( not_null poll, FullMsgId context); diff --git a/Telegram/SourceFiles/history/history_view_highlight_manager.cpp b/Telegram/SourceFiles/history/history_view_highlight_manager.cpp index 40fd10ec6..d4cf0905a 100644 --- a/Telegram/SourceFiles/history/history_view_highlight_manager.cpp +++ b/Telegram/SourceFiles/history/history_view_highlight_manager.cpp @@ -20,13 +20,14 @@ ElementHighlighter::ElementHighlighter( : _data(data) , _viewForItem(std::move(viewForItem)) , _repaintView(std::move(repaintView)) -, _timer([=] { updateMessage(); }) { +, _timer([=] { updateMessage(); }) +, _animation(*this) { } void ElementHighlighter::enqueue(not_null view) { const auto item = view->data(); const auto fullId = item->fullId(); - if (_queue.empty() && !_timer.isActive()) { + if (_queue.empty() && !_animation.animating()) { highlight(fullId); } else if (_highlightedMessageId != fullId && !base::contains(_queue, fullId)) { @@ -36,7 +37,7 @@ void ElementHighlighter::enqueue(not_null view) { } void ElementHighlighter::checkNextHighlight() { - if (_timer.isActive()) { + if (_animation.animating()) { return; } const auto nextHighlight = [&] { @@ -57,14 +58,16 @@ void ElementHighlighter::checkNextHighlight() { highlight(nextHighlight); } -crl::time ElementHighlighter::elementTime( +float64 ElementHighlighter::progress( not_null item) const { if (item->fullId() == _highlightedMessageId) { - if (_timer.isActive()) { - return crl::now() - _highlightStart; - } + const auto progress = _animation.progress(); + 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) { @@ -72,7 +75,7 @@ void ElementHighlighter::highlight(FullMsgId itemId) { if (const auto view = _viewForItem(item)) { _highlightStart = crl::now(); _highlightedMessageId = itemId; - _timer.callEach(AnimationTimerDelta); + _animation.start(); repaintHighlightedItem(view); } @@ -105,7 +108,7 @@ void ElementHighlighter::updateMessage() { } } } - _timer.cancel(); + _animation.cancel(); _highlightedMessageId = FullMsgId(); checkNextHighlight(); } @@ -115,4 +118,30 @@ void ElementHighlighter::clear() { 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 diff --git a/Telegram/SourceFiles/history/history_view_highlight_manager.h b/Telegram/SourceFiles/history/history_view_highlight_manager.h index e28a0b9d4..d78fd3e24 100644 --- a/Telegram/SourceFiles/history/history_view_highlight_manager.h +++ b/Telegram/SourceFiles/history/history_view_highlight_manager.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "base/timer.h" +#include "ui/effects/animations.h" class HistoryItem; @@ -32,14 +33,25 @@ public: void highlight(FullMsgId itemId); void clear(); - [[nodiscard]] crl::time elementTime( - not_null item) const; + [[nodiscard]] float64 progress(not_null item) const; private: void checkNextHighlight(); void repaintHighlightedItem(not_null view); 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; const ViewForItem _viewForItem; const RepaintView _repaintView; @@ -49,6 +61,7 @@ private: base::Timer _timer; crl::time _highlightStart = 0; + AnimationManager _animation; }; } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 9f5a1c948..65dc82c9a 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -1266,9 +1266,9 @@ void HistoryWidget::enqueueMessageHighlight( _highlighter.enqueue(view); } -crl::time HistoryWidget::highlightStartTime( +float64 HistoryWidget::highlightOpacity( not_null item) const { - return _highlighter.elementTime(item); + return _highlighter.progress(item); } int HistoryWidget::itemTopForHighlight( diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 3f8b7c006..f6bd61df0 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -191,7 +191,8 @@ public: bool touchScroll(const QPoint &delta); void enqueueMessageHighlight(not_null view); - crl::time highlightStartTime(not_null item) const; + [[nodiscard]] float64 highlightOpacity( + not_null item) const; MessageIdsList getSelectedItems() const; void itemEdited(not_null item); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 40f7575c0..15ae45fab 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -124,9 +124,9 @@ bool SimpleElementDelegate::elementUnderCursor( return false; } -crl::time SimpleElementDelegate::elementHighlightTime( - not_null item) { - return crl::time(0); +float64 SimpleElementDelegate::elementHighlightOpacity( + not_null item) const { + return 0.; } bool SimpleElementDelegate::elementInSelectionMode() { @@ -442,26 +442,13 @@ void Element::paintHighlight( paintCustomHighlight(p, context, skiptop, fillheight, data()); } -float64 Element::highlightOpacity(not_null 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( Painter &p, const PaintContext &context, int y, int height, not_null item) const { - const auto opacity = highlightOpacity(item); + const auto opacity = delegate()->elementHighlightOpacity(item); if (opacity == 0.) { return; } diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index 46130dae3..2bf5c29d4 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -72,8 +72,8 @@ public: not_null message, Element *replacing = nullptr) = 0; virtual bool elementUnderCursor(not_null view) = 0; - virtual crl::time elementHighlightTime( - not_null item) = 0; + [[nodiscard]] virtual float64 elementHighlightOpacity( + not_null item) const = 0; virtual bool elementInSelectionMode() = 0; virtual bool elementIntersectsRange( not_null view, @@ -134,8 +134,8 @@ public: not_null message, Element *replacing = nullptr) override; bool elementUnderCursor(not_null view) override; - crl::time elementHighlightTime( - not_null item) override; + [[nodiscard]] float64 elementHighlightOpacity( + not_null item) const override; bool elementInSelectionMode() override; bool elementIntersectsRange( not_null view, @@ -410,7 +410,6 @@ public: int y, int height, not_null item) const; - float64 highlightOpacity(not_null item) const; // Legacy blocks structure. HistoryBlock *block(); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 1a1632839..7561a3f72 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -1397,9 +1397,9 @@ bool ListWidget::elementUnderCursor( return (_overElement == view); } -crl::time ListWidget::elementHighlightTime( - not_null item) { - return _highlighter.elementTime(item); +float64 ListWidget::elementHighlightOpacity( + not_null item) const { + return _highlighter.progress(item); } bool ListWidget::elementInSelectionMode() { diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index 53fa0b787..e125502c2 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -261,8 +261,8 @@ public: not_null message, Element *replacing = nullptr) override; bool elementUnderCursor(not_null view) override; - crl::time elementHighlightTime( - not_null item) override; + [[nodiscard]] float64 elementHighlightOpacity( + not_null item) const override; bool elementInSelectionMode() override; bool elementIntersectsRange( not_null view, diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index e5325fdbd..faf675dc2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -313,7 +313,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const { selection = part.content->skipSelection(selection); } const auto highlightOpacity = (_mode == Mode::Grid) - ? _parent->highlightOpacity(part.item) + ? _parent->delegate()->elementHighlightOpacity(part.item) : 0.; if (!part.cache.isNull()) { wasCache = true;