diff --git a/Telegram/SourceFiles/statistics/chart_widget.cpp b/Telegram/SourceFiles/statistics/chart_widget.cpp index cd61fdbce2..4fecc711b5 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.cpp +++ b/Telegram/SourceFiles/statistics/chart_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "statistics/chart_widget.h" +#include "ui/effects/show_animation.h" #include "base/qt/qt_key_modifiers.h" #include "statistics/chart_lines_filter_widget.h" #include "statistics/linear_chart_view.h" @@ -18,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/round_rect.h" #include "ui/effects/ripple_animation.h" #include "ui/image/image_prepare.h" +#include "ui/widgets/buttons.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_statistics.h" @@ -1131,7 +1133,12 @@ void ChartWidget::setupDetails() { this, _chartData, maxAbsoluteValue, - false); + _zoomEnabled); + _details.widget->setClickedCallback([=] { + if (const auto index = _details.widget->xIndex(); index >= 0) { + _zoomRequests.fire_copy(_chartData.x[index]); + } + }); _details.widget->shownValue( ) | rpl::start_with_next([=](bool shown) { @@ -1233,6 +1240,36 @@ void ChartWidget::setChartData(Data::StatisticalChart chartData) { _footer->update(); } +void ChartWidget::setZoomedChartData(Data::StatisticalChart chartData) { + _zoomedChartWidget = base::make_unique_q( + dynamic_cast(parentWidget())); + _zoomedChartWidget->setChartData(std::move(chartData)); + geometryValue( + ) | rpl::start_with_next([=](const QRect &geometry) { + _zoomedChartWidget->moveToLeft(geometry.x(), geometry.y()); + }, _zoomedChartWidget->lifetime()); + _zoomedChartWidget->show(); + _zoomedChartWidget->resizeToWidth(width()); + + const auto zoomOutButton = Ui::CreateChild( + _zoomedChartWidget.get(), + rpl::single(QString("Zoom Out")), + st::defaultActiveButton); + Ui::Animations::ShowWidgets({ _zoomedChartWidget.get(), zoomOutButton }); + Ui::Animations::HideWidgets({ this }); + zoomOutButton->moveToLeft(0, 0); + zoomOutButton->setClickedCallback([=] { + shownValue( + ) | rpl::start_with_next([=](bool shown) { + if (shown) { + _zoomedChartWidget = nullptr; + } + }, _zoomedChartWidget->lifetime()); + Ui::Animations::ShowWidgets({ this }); + Ui::Animations::HideWidgets({ _zoomedChartWidget.get() }); + }); +} + void ChartWidget::addHorizontalLine(Limits newHeight, bool animated) { const auto newLinesData = ChartHorizontalLinesData( newHeight.max, @@ -1250,4 +1287,10 @@ void ChartWidget::addHorizontalLine(Limits newHeight, bool animated) { } } +rpl::producer ChartWidget::zoomRequests() { + _zoomEnabled = true; + setupDetails(); + return _zoomRequests.events(); +} + } // namespace Statistic diff --git a/Telegram/SourceFiles/statistics/chart_widget.h b/Telegram/SourceFiles/statistics/chart_widget.h index 1b043f650c..2db03e5b64 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.h +++ b/Telegram/SourceFiles/statistics/chart_widget.h @@ -26,8 +26,11 @@ public: ChartWidget(not_null parent); void setChartData(Data::StatisticalChart chartData); + void setZoomedChartData(Data::StatisticalChart chartData); void addHorizontalLine(Limits newHeight, bool animated); + [[nodiscard]] rpl::producer zoomRequests(); + struct BottomCaptionLineData final { int step = 0; int stepMax = 0; @@ -133,6 +136,8 @@ private: base::unique_qptr _filterButtons; Data::StatisticalChart _chartData; + base::unique_qptr _zoomedChartWidget; + std::unique_ptr _linearChartView; struct { @@ -155,6 +160,9 @@ private: std::vector _horizontalLines; + bool _zoomEnabled = false; + rpl::event_stream _zoomRequests; + }; } // namespace Statistic diff --git a/Telegram/SourceFiles/statistics/statistics_box.cpp b/Telegram/SourceFiles/statistics/statistics_box.cpp index 3476220d7c..03f5361c7a 100644 --- a/Telegram/SourceFiles/statistics/statistics_box.cpp +++ b/Telegram/SourceFiles/statistics/statistics_box.cpp @@ -23,6 +23,28 @@ void StatisticsBox(not_null box, not_null peer) { const auto api = chartWidget->lifetime().make_state( &peer->session().api()); + const auto processZoom = [=]( + not_null widget, + const QString &zoomToken) { + if (!zoomToken.isEmpty()) { + widget->zoomRequests( + ) | rpl::start_with_next([=](float64 x) { + api->requestZoom( + peer, + zoomToken, + x + ) | rpl::start_with_next_error_done([=]( + const Data::StatisticalGraph &graph) { + if (graph.chart) { + widget->setZoomedChartData(graph.chart); + } + }, [=](const QString &error) { + }, [=] { + }, widget->lifetime()); + }, widget->lifetime()); + } + }; + api->request( peer ) | rpl::start_with_done([=] {