From 8ded88baf56ef632fb7ddffe32511dcd88a9f037 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Sep 2023 14:43:37 +0300 Subject: [PATCH] Moved out control of animations for line filtering to separated class. --- Telegram/CMakeLists.txt | 2 + .../chart_lines_filter_controller.cpp | 71 +++++++++++ .../chart_lines_filter_controller.h | 39 ++++++ .../SourceFiles/statistics/chart_widget.cpp | 45 ++++--- .../SourceFiles/statistics/chart_widget.h | 9 +- .../statistics/view/abstract_chart_view.h | 21 ++-- .../statistics/view/linear_chart_view.cpp | 67 ++--------- .../statistics/view/linear_chart_view.h | 16 --- .../statistics/view/stack_chart_view.cpp | 92 ++------------ .../statistics/view/stack_chart_view.h | 19 --- .../view/stack_linear_chart_view.cpp | 113 ++++-------------- .../statistics/view/stack_linear_chart_view.h | 19 --- 12 files changed, 195 insertions(+), 318 deletions(-) create mode 100644 Telegram/SourceFiles/statistics/chart_lines_filter_controller.cpp create mode 100644 Telegram/SourceFiles/statistics/chart_lines_filter_controller.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 5c6c7e7713..7dfa0a84ba 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1286,6 +1286,8 @@ PRIVATE statistics/chart_header_widget.h statistics/chart_horizontal_lines_data.cpp statistics/chart_horizontal_lines_data.h + statistics/chart_lines_filter_controller.cpp + statistics/chart_lines_filter_controller.h statistics/chart_widget.cpp statistics/chart_widget.h statistics/point_details_widget.cpp diff --git a/Telegram/SourceFiles/statistics/chart_lines_filter_controller.cpp b/Telegram/SourceFiles/statistics/chart_lines_filter_controller.cpp new file mode 100644 index 0000000000..40c3b6129b --- /dev/null +++ b/Telegram/SourceFiles/statistics/chart_lines_filter_controller.cpp @@ -0,0 +1,71 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "statistics/chart_lines_filter_controller.h" + +namespace Statistic { + +LinesFilterController::LinesFilterController() = default; + +void LinesFilterController::setEnabled(int id, bool enabled, crl::time now) { + const auto it = _entries.find(id); + if (it == end(_entries)) { + _entries[id] = Entry{ + .enabled = enabled, + .startedAt = now, + .anim = anim::value(enabled ? 0. : 1., enabled ? 1. : 0.), + }; + } else if (it->second.enabled != enabled) { + auto &entry = it->second; + entry.enabled = enabled; + entry.startedAt = now; + entry.dtCurrent = 0.; + entry.anim.start(enabled ? 1. : 0.); + } + _isFinished = false; +} + +bool LinesFilterController::isFinished() const { + return _isFinished; +} + +bool LinesFilterController::isEnabled(int id) const { + const auto it = _entries.find(id); + return (it == end(_entries)) ? true : it->second.enabled; +} + +float64 LinesFilterController::alpha(int id) const { + const auto it = _entries.find(id); + return (it == end(_entries)) ? 1. : it->second.alpha; +} + +void LinesFilterController::tick(float64 dtSpeed) { + auto finishedCount = 0; + auto idsToRemove = std::vector(); + for (auto &[id, entry] : _entries) { + if (!entry.startedAt) { + continue; + } + entry.dtCurrent = std::min(entry.dtCurrent + dtSpeed, 1.); + entry.anim.update(entry.dtCurrent, anim::easeInCubic); + const auto progress = entry.anim.current(); + entry.alpha = std::clamp(progress, 0., 1.); + if ((entry.alpha == 1.) && entry.enabled) { + idsToRemove.push_back(id); + } + if (entry.anim.current() == entry.anim.to()) { + finishedCount++; + entry.anim.finish(); + } + } + _isFinished = (finishedCount == _entries.size()); + for (const auto &id : idsToRemove) { + _entries.remove(id); + } +} + +} // namespace Statistic diff --git a/Telegram/SourceFiles/statistics/chart_lines_filter_controller.h b/Telegram/SourceFiles/statistics/chart_lines_filter_controller.h new file mode 100644 index 0000000000..417cb23f35 --- /dev/null +++ b/Telegram/SourceFiles/statistics/chart_lines_filter_controller.h @@ -0,0 +1,39 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/effects/animation_value.h" + +namespace Statistic { + +class LinesFilterController final { +public: + LinesFilterController(); + + void setEnabled(int id, bool enabled, crl::time now); + [[nodiscard]] bool isEnabled(int id) const; + [[nodiscard]] bool isFinished() const; + [[nodiscard]] float64 alpha(int id) const; + + void tick(float64 dtSpeed); + +private: + struct Entry final { + bool enabled = false; + crl::time startedAt = 0; + float64 alpha = 1.; + anim::value anim; + float64 dtCurrent = 0.; + }; + + base::flat_map _entries; + bool _isFinished = true; + +}; + +} // namespace Statistic diff --git a/Telegram/SourceFiles/statistics/chart_widget.cpp b/Telegram/SourceFiles/statistics/chart_widget.cpp index 83119a6463..a4c65045a7 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.cpp +++ b/Telegram/SourceFiles/statistics/chart_widget.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/qt/qt_key_modifiers.h" #include "lang/lang_keys.h" #include "statistics/chart_header_widget.h" +#include "statistics/chart_lines_filter_controller.h" #include "statistics/chart_lines_filter_widget.h" #include "statistics/point_details_widget.h" #include "statistics/view/abstract_chart_view.h" @@ -505,10 +506,11 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits( Data::StatisticalChart &chartData, Limits xPercentageLimits, const std::unique_ptr &chartView, + const std::shared_ptr &linesFilter, crl::time now) { if ((_animationValueXMin.to() == xPercentageLimits.min) && (_animationValueXMax.to() == xPercentageLimits.max) - && chartView->isFinished()) { + && linesFilter->isFinished()) { return; } start(); @@ -535,7 +537,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits( if (!_previousFullHeightLimits.max) { _previousFullHeightLimits = _finalHeightLimits; } - if (!chartView->isFinished()) { + if (!linesFilter->isFinished()) { _animationValueFooterHeightMin = anim::value( _animationValueFooterHeightMin.current(), heightLimits.full.min); @@ -583,7 +585,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits( _dtHeight.currentAlpha = 0.; _addHorizontalLineRequests.fire({}); } - _dtHeight.speed = (!chartView->isFinished()) + _dtHeight.speed = (!linesFilter->isFinished()) ? kDtHeightSpeedFilter : (k > kDtHeightSpeedThreshold1) ? kDtHeightSpeed1 @@ -629,7 +631,8 @@ void ChartWidget::ChartAnimationController::tick( crl::time now, ChartHorizontalLinesView &horizontalLinesView, std::vector &dateLines, - const std::unique_ptr &chartView) { + const std::unique_ptr &chartView, + const std::shared_ptr &linesFilter) { if (!_animation.animating()) { return; } @@ -652,6 +655,7 @@ void ChartWidget::ChartAnimationController::tick( // Speed up to reduce ugly frames count. * (_benchmark.lastFPSSlow ? 2. : 1.); const auto speed = _dtHeight.speed * k; + linesFilter->tick(speed); _dtHeight.current.min = std::min(_dtHeight.current.min + speed, 1.); _dtHeight.current.max = std::min(_dtHeight.current.max + speed, 1.); _dtHeight.currentAlpha = std::min(_dtHeight.currentAlpha + speed, 1.); @@ -680,25 +684,13 @@ void ChartWidget::ChartAnimationController::tick( const auto footerMinFinished = isFinished(_animationValueFooterHeightMin); const auto footerMaxFinished = isFinished(_animationValueFooterHeightMax); - // chartView->tick(now); - { - constexpr auto kDtHeightSpeed1 = 0.03 * 2; - constexpr auto kDtHeightSpeed2 = 0.03 * 2; - constexpr auto kDtHeightSpeed3 = 0.045 * 2; - if (_dtHeight.current.max > 0 && _dtHeight.current.max < 1) { - chartView->update(_dtHeight.current.max); - } else { - chartView->tick(now); - } - } - if (xFinished && yFinished && alphaFinished && bottomLineAlphaFinished && footerMinFinished && footerMaxFinished - && chartView->isFinished()) { + && linesFilter->isFinished()) { if ((_finalHeightLimits.min == _animationValueHeightMin.to()) && _finalHeightLimits.max == _animationValueHeightMax.to()) { _animation.stop(); @@ -735,12 +727,12 @@ void ChartWidget::ChartAnimationController::tick( if (!footerMinFinished) { _animationValueFooterHeightMin.update( _dtHeight.current.min, - anim::sineInOut); + anim::easeInCubic); } if (!footerMaxFinished) { _animationValueFooterHeightMax.update( _dtHeight.current.max, - anim::sineInOut); + anim::easeInCubic); } if (!alphaFinished) { @@ -816,9 +808,11 @@ ChartWidget::ChartWidget(not_null parent) , _chartArea(base::make_unique_q(this)) , _header(std::make_unique
(this)) , _footer(std::make_unique