Improved code style in chart widget.

This commit is contained in:
23rd 2023-06-09 13:42:29 +03:00 committed by John Preston
parent 629dd6f9de
commit 59f61586a9
4 changed files with 64 additions and 74 deletions

View File

@ -19,6 +19,10 @@ namespace {
constexpr auto kHeightLimitsUpdateTimeout = crl::time(320); constexpr auto kHeightLimitsUpdateTimeout = crl::time(320);
[[nodiscard]] bool AnimFinished(const anim::value &anim) {
return anim.current() == anim.to();
}
[[nodiscard]] int FindMaxValue( [[nodiscard]] int FindMaxValue(
Data::StatisticalChart &chartData, Data::StatisticalChart &chartData,
int startXIndex, int startXIndex,
@ -75,12 +79,14 @@ public:
Footer(not_null<Ui::RpWidget*> parent); Footer(not_null<Ui::RpWidget*> parent);
[[nodiscard]] rpl::producer<Limits> xPercentageLimitsChange() const; [[nodiscard]] rpl::producer<Limits> xPercentageLimitsChange() const;
[[nodiscard]] rpl::producer<> userInteractionFinished() const;
private: private:
not_null<Ui::AbstractButton*> _left; not_null<Ui::AbstractButton*> _left;
not_null<Ui::AbstractButton*> _right; not_null<Ui::AbstractButton*> _right;
rpl::event_stream<Limits> _xPercentageLimitsChange; rpl::event_stream<Limits> _xPercentageLimitsChange;
rpl::event_stream<> _userInteractionFinished;
struct { struct {
int x = 0; int x = 0;
@ -148,6 +154,7 @@ ChartWidget::Footer::Footer(not_null<Ui::RpWidget*> parent)
.min = _left->x() / float64(width()), .min = _left->x() / float64(width()),
.max = rect::right(_right) / float64(width()), .max = rect::right(_right) / float64(width()),
}); });
_userInteractionFinished.fire({});
_start = {}; _start = {};
} break; } break;
} }
@ -167,6 +174,10 @@ rpl::producer<Limits> ChartWidget::Footer::xPercentageLimitsChange() const {
return _xPercentageLimitsChange.events(); return _xPercentageLimitsChange.events();
} }
rpl::producer<> ChartWidget::Footer::userInteractionFinished() const {
return _userInteractionFinished.events();
}
ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent) ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
: Ui::RpWidget(parent) : Ui::RpWidget(parent)
, _footer(std::make_unique<Footer>(this)) { , _footer(std::make_unique<Footer>(this)) {
@ -195,46 +206,51 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
{}, {},
limits, limits,
limitsY, limitsY,
1.,
_footer->rect()); _footer->rect());
} }
}, _footer->lifetime()); }, _footer->lifetime());
constexpr auto kExpandingDelay = crl::time(400);
constexpr auto kXExpandingDuration = 200.;
constexpr auto kYExpandingDuration = 400.;
_xPercentage.animation.init([=](crl::time now) { _xPercentage.animation.init([=](crl::time now) {
const auto timeDiff = (now - _xPercentage.lastUserInteracted); if (!_xPercentage.yAnimationStartedAt
const auto dt = (now - _xPercentage.animation.started()) && (now - _xPercentage.lastUserInteracted) >= kExpandingDelay) {
/ float64(200); _xPercentage.yAnimationStartedAt = _xPercentage.lastUserInteracted
+ kExpandingDelay;
if (!_yAnimStarted && timeDiff >= 400) {
_yAnimStarted = _xPercentage.lastUserInteracted;
} }
const auto dt2 = (now - _yAnimStarted - 400) const auto dtY = std::min(
/ float64(2000); (now - _xPercentage.yAnimationStartedAt) / kYExpandingDuration,
1.);
const auto dtX = std::min(
(now - _xPercentage.animation.started()) / kXExpandingDuration,
1.);
const auto progress = timeDiff / float64(2000.); const auto xFinished = AnimFinished(_xPercentage.animValueXMin)
_xPercentage.progress = progress; && AnimFinished(_xPercentage.animValueXMax);
if ((_animValueXMin.to() == _animValueXMin.current()) const auto yFinished = AnimFinished(_xPercentage.animValueYMin)
&& (_animValueXMax.to() == _animValueXMax.current()) && AnimFinished(_xPercentage.animValueYMax);
&& (_animValueYMin.to() == _animValueYMin.current()) if (xFinished && yFinished) {
&& (_animValueYMax.to() == _animValueYMax.current())) {
// if (progress > 1.) {
_xPercentage.animation.stop(); _xPercentage.animation.stop();
}
if (xFinished) {
_xPercentage.animValueXMin.finish();
_xPercentage.animValueXMax.finish();
_xPercentage.was = _xPercentage.now; _xPercentage.was = _xPercentage.now;
_animValueXMin.finish();
_animValueXMax.finish();
_animValueYMin.finish();
_animValueYMax.finish();
_yAnimStarted = 0;
} else { } else {
_animValueXMin.update(std::min(dt, 1.), anim::linear); _xPercentage.animValueXMin.update(dtX, anim::linear);
_animValueXMax.update(std::min(dt, 1.), anim::linear); _xPercentage.animValueXMax.update(dtX, anim::linear);
}
if (yFinished) {
_xPercentage.animValueYMin.finish();
_xPercentage.animValueYMax.finish();
if (_yAnimStarted) { _xPercentage.yAnimationStartedAt = 0;
_animValueYMin.update(std::min(dt2, 1.), anim::sineInOut); }
_animValueYMax.update(std::min(dt2, 1.), anim::sineInOut); if (_xPercentage.yAnimationStartedAt) {
} _xPercentage.animValueYMin.update(dtY, anim::sineInOut);
_xPercentage.animValueYMax.update(dtY, anim::sineInOut);
} }
const auto startXIndex = _chartData.findStartIndex( const auto startXIndex = _chartData.findStartIndex(
_xPercentage.now.min); _xPercentage.now.min);
@ -250,14 +266,18 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
update(); update();
}); });
_footer->userInteractionFinished(
) | rpl::start_with_next([=] {
_xPercentage.yAnimationStartedAt = crl::now();
}, _footer->lifetime());
_footer->xPercentageLimitsChange( _footer->xPercentageLimitsChange(
) | rpl::start_with_next([=](Limits xPercentageLimits) { ) | rpl::start_with_next([=](Limits xPercentageLimits) {
if (!_xPercentage.animation.animating()) { if (!_xPercentage.animation.animating()) {
_xPercentage.animation.start(); _xPercentage.animation.start();
// _xPercentage.was = base::take(_xPercentage.now);
} }
_animValueXMin.start(xPercentageLimits.min); _xPercentage.animValueXMin.start(xPercentageLimits.min);
_animValueXMax.start(xPercentageLimits.max); _xPercentage.animValueXMax.start(xPercentageLimits.max);
_xPercentage.now = xPercentageLimits; _xPercentage.now = xPercentageLimits;
_xPercentage.lastUserInteracted = crl::now(); _xPercentage.lastUserInteracted = crl::now();
@ -293,8 +313,8 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
} }
} }
} }
_animValueYMin.start(minY); _xPercentage.animValueYMin.start(minY);
_animValueYMax.start(maxY); _xPercentage.animValueYMax.start(maxY);
} }
// _xPercentage.animation.stop(); // _xPercentage.animation.stop();
// const auto was = _xPercentageLimits; // const auto was = _xPercentageLimits;
@ -374,10 +394,9 @@ void ChartWidget::paintEvent(QPaintEvent *e) {
p, p,
_chartData, _chartData,
_xPercentage.was, _xPercentage.was,
{ _animValueXMin.current(), _animValueXMax.current() }, { _xPercentage.animValueXMin.current(), _xPercentage.animValueXMax.current() },
{ _animValueYMin.current(), _animValueYMax.current() }, { _xPercentage.animValueYMin.current(), _xPercentage.animValueYMax.current() },
// _xPercentage.now, // _xPercentage.now,
_xPercentage.progress,
chartRect); chartRect);
} }

View File

@ -46,15 +46,15 @@ private:
Limits was; Limits was;
Limits now; Limits now;
Ui::Animations::Basic animation; Ui::Animations::Basic animation;
crl::time lastUserInteracted = 0;
float64 progress = 0.;
} _xPercentage;
anim::value _animValueXMin;
anim::value _animValueXMax;
anim::value _animValueYMin;
anim::value _animValueYMax;
crl::time _yAnimStarted = 0; crl::time lastUserInteracted = 0;
crl::time yAnimationStartedAt = 0;
anim::value animValueXMin;
anim::value animValueXMax;
anim::value animValueYMin;
anim::value animValueYMax;
} _xPercentage;
float64 _minMaxUpdateStep = 0.; float64 _minMaxUpdateStep = 0.;

View File

@ -20,7 +20,6 @@ void PaintLinearChartView(
const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsWas,
const Limits &xPercentageLimitsNow, const Limits &xPercentageLimitsNow,
const Limits &xPercentageLimitsNowY, const Limits &xPercentageLimitsNowY,
float64 progress,
const QRect &rect) { const QRect &rect) {
const auto offset = 0; const auto offset = 0;
const auto currentMinHeight = rect.y(); // const auto currentMinHeight = rect.y(); //
@ -50,33 +49,6 @@ void PaintLinearChartView(
auto minY = std::numeric_limits<float64>::max(); auto minY = std::numeric_limits<float64>::max();
auto maxY = 0.; auto maxY = 0.;
auto minYIndex = 0;
auto maxYIndex = 0;
const auto tempXPercentage = Limits{
.min = *ranges::lower_bound(
chartData.xPercentage,
anim::interpolateF(xPercentageLimitsWas.min, xPercentageLimitsNow.min, progress)),
.max = *ranges::lower_bound(
chartData.xPercentage,
anim::interpolateF(xPercentageLimitsWas.max, xPercentageLimitsNow.max, progress)),
};
for (auto i = 0; i < chartData.xPercentage.size(); i++) {
if (chartData.xPercentage[i] == tempXPercentage.min) {
minYIndex = i;
}
if (chartData.xPercentage[i] == tempXPercentage.max) {
maxYIndex = i;
}
}
for (auto i = minYIndex; i < maxYIndex; i++) {
if (line.y[i] > maxY) {
maxY = line.y[i];
}
if (line.y[i] < minY) {
minY = line.y[i];
}
}
minY = xPercentageLimitsNowY.min; minY = xPercentageLimitsNowY.min;
maxY = xPercentageLimitsNowY.max; maxY = xPercentageLimitsNowY.max;

View File

@ -21,7 +21,6 @@ void PaintLinearChartView(
const Limits &xPercentageLimitsWas, const Limits &xPercentageLimitsWas,
const Limits &xPercentageLimitsNow, const Limits &xPercentageLimitsNow,
const Limits &xPercentageLimitsNowY, const Limits &xPercentageLimitsNowY,
float64 progress,
const QRect &rect); const QRect &rect);
} // namespace Statistic } // namespace Statistic