Moved out paint of horizontal lines for charts to separated view class.

This commit is contained in:
23rd 2023-09-11 17:14:07 +03:00 committed by John Preston
parent 83cf12b475
commit 646390141a
5 changed files with 173 additions and 85 deletions

View File

@ -1296,6 +1296,8 @@ PRIVATE
statistics/statistics_data_deserialize.cpp
statistics/statistics_data_deserialize.h
statistics/view/abstract_chart_view.h
statistics/view/chart_horizontal_lines_view.cpp
statistics/view/chart_horizontal_lines_view.h
statistics/view/chart_view_factory.cpp
statistics/view/chart_view_factory.h
statistics/view/linear_chart_view.cpp

View File

@ -37,38 +37,6 @@ inline float64 InterpolationRatio(float64 from, float64 to, float64 result) {
return (result - from) / (to - from);
};
void PaintHorizontalLines(
QPainter &p,
const ChartHorizontalLinesData &horizontalLine,
const QRect &r) {
const auto alpha = p.opacity();
p.setOpacity(horizontalLine.alpha);
for (const auto &line : horizontalLine.lines) {
const auto lineRect = QRect(
0,
r.y() + r.height() * line.relativeValue,
r.x() + r.width(),
st::lineWidth);
p.fillRect(lineRect, st::windowSubTextFg);
}
p.setOpacity(alpha);
}
void PaintCaptionsToHorizontalLines(
QPainter &p,
const ChartHorizontalLinesData &horizontalLine,
const QRect &r) {
const auto alpha = p.opacity();
p.setOpacity(horizontalLine.alpha);
p.setFont(st::statisticsDetailsBottomCaptionStyle.font);
p.setPen(st::windowSubTextFg);
const auto offset = r.y() - st::statisticsChartHorizontalLineCaptionSkip;
for (const auto &line : horizontalLine.lines) {
p.drawText(0, offset + r.height() * line.relativeValue, line.caption);
}
p.setOpacity(alpha);
}
void PaintBottomLine(
QPainter &p,
const std::vector<ChartWidget::BottomCaptionLineData> &dates,
@ -653,7 +621,7 @@ void ChartWidget::ChartAnimationController::restartBottomLineAlpha() {
void ChartWidget::ChartAnimationController::tick(
crl::time now,
std::vector<ChartHorizontalLinesData> &horizontalLines,
ChartHorizontalLinesView &horizontalLinesView,
std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<AbstractChartView> &chartView) {
if (!_animation.animating()) {
@ -725,7 +693,6 @@ void ChartWidget::ChartAnimationController::tick(
&& footerMinFinished
&& footerMaxFinished
&& chartView->isFinished()) {
const auto &lines = horizontalLines.back().lines;
if ((_finalHeightLimits.min == _animationValueHeightMin.to())
&& _finalHeightLimits.max == _animationValueHeightMax.to()) {
_animation.stop();
@ -755,11 +722,9 @@ void ChartWidget::ChartAnimationController::tick(
_dtHeight.current.max,
anim::easeInCubic);
for (auto &horizontalLine : horizontalLines) {
horizontalLine.computeRelative(
_animationValueHeightMax.current(),
_animationValueHeightMin.current());
}
horizontalLinesView.computeRelative(
_animationValueHeightMax.current(),
_animationValueHeightMin.current());
}
if (!footerMinFinished) {
_animationValueFooterHeightMin.update(
@ -776,22 +741,7 @@ void ChartWidget::ChartAnimationController::tick(
_animationValueHeightAlpha.update(
_dtHeight.currentAlpha,
anim::easeInCubic);
const auto value = _animationValueHeightAlpha.current();
for (auto &horizontalLine : horizontalLines) {
horizontalLine.alpha = horizontalLine.fixedAlpha * (1. - value);
}
horizontalLines.back().alpha = value;
if (value == 1.) {
while (horizontalLines.size() > 1) {
const auto startIt = begin(horizontalLines);
if (!startIt->alpha) {
horizontalLines.erase(startIt);
} else {
break;
}
}
}
horizontalLinesView.setAlpha(_animationValueHeightAlpha.current());
}
if (!bottomLineAlphaFinished) {
@ -948,7 +898,7 @@ void ChartWidget::setupChartArea() {
_animationController.tick(
now,
_horizontalLines,
_horizontalLinesView,
_bottomLine.dates,
_chartView);
@ -956,9 +906,7 @@ void ChartWidget::setupChartArea() {
p.fillRect(r, st::boxBg);
for (auto &horizontalLine : _horizontalLines) {
PaintHorizontalLines(p, horizontalLine, chartRect);
}
_horizontalLinesView.paintHorizontalLines(p, chartRect);
if (_chartData) {
// p.setRenderHint(
@ -976,9 +924,7 @@ void ChartWidget::setupChartArea() {
false);
}
for (auto &horizontalLine : _horizontalLines) {
PaintCaptionsToHorizontalLines(p, horizontalLine, chartRect);
}
_horizontalLinesView.paintCaptionsToHorizontalLines(p, chartRect);
{
const auto bottom = r
- QMargins{ 0, rect::bottom(chartRect), 0, 0 };
@ -1124,7 +1070,9 @@ void ChartWidget::setupFooter() {
_animationController.addHorizontalLineRequests(
) | rpl::start_with_next([=] {
addHorizontalLine(_animationController.finalHeightLimits(), true);
_horizontalLinesView.add(
_animationController.finalHeightLimits(),
true);
_animationController.start();
}, _footer->lifetime());
@ -1149,7 +1097,9 @@ void ChartWidget::setupFooter() {
return;
}
_lastHeightLimitsChanged = now;
addHorizontalLine(_animationController.finalHeightLimits(), true);
_horizontalLinesView.add(
_animationController.finalHeightLimits(),
true);
}, _footer->lifetime());
}
@ -1280,6 +1230,7 @@ void ChartWidget::setChartData(
_chartData = std::move(chartData);
_chartView = CreateChartView(type);
_horizontalLinesView.setChartData(_chartData, type);
setupDetails();
setupFilterButtons();
@ -1293,7 +1244,7 @@ void ChartWidget::setChartData(
updateHeader();
updateBottomDates();
_animationController.finish();
addHorizontalLine(_animationController.finalHeightLimits(), false);
_horizontalLinesView.add(_animationController.finalHeightLimits(), false);
RpWidget::showChildren();
_chartArea->update();
@ -1357,23 +1308,6 @@ void ChartWidget::setZoomedChartData(
zoomOutButton->moveToLeft(0, 0);
}
void ChartWidget::addHorizontalLine(Limits newHeight, bool animated) {
const auto newLinesData = ChartHorizontalLinesData(
newHeight.max,
newHeight.min,
true);
if (!animated) {
_horizontalLines.clear();
}
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.fixedAlpha = horizontalLine.alpha;
}
_horizontalLines.push_back(newLinesData);
if (!animated) {
_horizontalLines.back().alpha = 1.;
}
}
rpl::producer<float64> ChartWidget::zoomRequests() {
_zoomEnabled = true;
setupDetails();

View File

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "data/data_statistics.h"
#include "statistics/chart_horizontal_lines_data.h"
#include "statistics/view/chart_horizontal_lines_view.h"
#include "statistics/statistics_common.h"
#include "ui/effects/animation_value.h"
#include "ui/effects/animations.h"
@ -68,7 +68,7 @@ private:
void restartBottomLineAlpha();
void tick(
crl::time now,
std::vector<ChartHorizontalLinesData> &horizontalLines,
ChartHorizontalLinesView &horizontalLinesView,
std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<AbstractChartView> &AbstractChartView);
@ -162,7 +162,7 @@ private:
ChartAnimationController _animationController;
crl::time _lastHeightLimitsChanged = 0;
std::vector<ChartHorizontalLinesData> _horizontalLines;
ChartHorizontalLinesView _horizontalLinesView;
bool _zoomEnabled = false;
rpl::event_stream<float64> _zoomRequests;

View File

@ -0,0 +1,106 @@
/*
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/view/chart_horizontal_lines_view.h"
#include "data/data_statistics.h"
#include "statistics/statistics_common.h"
#include "styles/style_statistics.h"
namespace Statistic {
ChartHorizontalLinesView::ChartHorizontalLinesView() = default;
void ChartHorizontalLinesView::setChartData(
const Data::StatisticalChart &chartData,
ChartViewType type) {
_isDouble = (type == ChartViewType::DoubleLinear);
if (_isDouble && (chartData.lines.size() == 2)) {
_leftColor = chartData.lines.front().color;
_rightColor = chartData.lines.back().color;
}
}
void ChartHorizontalLinesView::paintHorizontalLines(
QPainter &p,
const QRect &r) {
for (auto &horizontalLine : _horizontalLines) {
const auto alpha = p.opacity();
p.setOpacity(horizontalLine.alpha);
for (const auto &line : horizontalLine.lines) {
const auto lineRect = QRect(
0,
r.y() + r.height() * line.relativeValue,
r.x() + r.width(),
st::lineWidth);
p.fillRect(lineRect, st::windowSubTextFg);
}
p.setOpacity(alpha);
}
}
void ChartHorizontalLinesView::paintCaptionsToHorizontalLines(
QPainter &p,
const QRect &r) {
for (auto &horizontalLine : _horizontalLines) {
const auto alpha = p.opacity();
p.setOpacity(horizontalLine.alpha);
p.setFont(st::statisticsDetailsBottomCaptionStyle.font);
p.setPen(st::windowSubTextFg);
const auto offset = r.y()
- st::statisticsChartHorizontalLineCaptionSkip;
for (const auto &line : horizontalLine.lines) {
const auto y = offset + r.height() * line.relativeValue;
p.drawText(0, y, line.caption);
}
p.setOpacity(alpha);
}
}
void ChartHorizontalLinesView::computeRelative(
int newMaxHeight,
int newMinHeight) {
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.computeRelative(newMaxHeight, newMinHeight);
}
}
void ChartHorizontalLinesView::setAlpha(float64 value) {
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.alpha = horizontalLine.fixedAlpha * (1. - value);
}
_horizontalLines.back().alpha = value;
if (value == 1.) {
while (_horizontalLines.size() > 1) {
const auto startIt = begin(_horizontalLines);
if (!startIt->alpha) {
_horizontalLines.erase(startIt);
} else {
break;
}
}
}
}
void ChartHorizontalLinesView::add(Limits newHeight, bool animated) {
const auto newLinesData = ChartHorizontalLinesData(
newHeight.max,
newHeight.min,
true);
if (!animated) {
_horizontalLines.clear();
}
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.fixedAlpha = horizontalLine.alpha;
}
_horizontalLines.push_back(newLinesData);
if (!animated) {
_horizontalLines.back().alpha = 1.;
}
}
} // namespace Statistic

View File

@ -0,0 +1,46 @@
/*
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 "statistics/chart_horizontal_lines_data.h"
namespace Data {
struct StatisticalChart;
} // namespace Data
namespace Statistic {
enum class ChartViewType;
struct Limits;
struct ChartHorizontalLinesView final {
public:
ChartHorizontalLinesView();
void setChartData(
const Data::StatisticalChart &chartData,
ChartViewType type);
void paintHorizontalLines(QPainter &p, const QRect &r);
void paintCaptionsToHorizontalLines(QPainter &p, const QRect &r);
void computeRelative(int newMaxHeight, int newMinHeight);
void setAlpha(float64 value);
void add(Limits newHeight, bool animated);
private:
bool _isDouble = false;
QColor _leftColor;
QColor _rightColor;
std::vector<ChartHorizontalLinesData> _horizontalLines;
};
} // namespace Statistic