139 lines
4.4 KiB
C++
139 lines
4.4 KiB
C++
//
|
|
// Created by Lenn on 2025/10/17.
|
|
//
|
|
|
|
#ifndef TOUCHSENSOR_HEATMAP_H
|
|
#define TOUCHSENSOR_HEATMAP_H
|
|
|
|
#include "creeper-qt/utility/theme/theme.hh"
|
|
#include "creeper-qt/utility/wrapper/common.hh"
|
|
#include "creeper-qt/utility/wrapper/pimpl.hh"
|
|
#include "creeper-qt/utility/wrapper/property.hh"
|
|
#include "qcustomplot/qcustomplot.h"
|
|
#include "creeper-qt/utility/wrapper/widget.hh"
|
|
#include <concepts>
|
|
#include <qcontainerfwd.h>
|
|
#include <qvector.h>
|
|
|
|
struct point_data {
|
|
double x;
|
|
double y;
|
|
double z;
|
|
explicit point_data(double x, double y, double z) : x{x}, y{y}, z{z} {}
|
|
};
|
|
using PointData = struct point_data;
|
|
namespace creeper {
|
|
class HeatMapPlot;
|
|
|
|
namespace plot_widget::internal {
|
|
class BasicPlot : public QCustomPlot {
|
|
CREEPER_PIMPL_DEFINITION(BasicPlot)
|
|
friend class HeatMapPlot;
|
|
public:
|
|
// BasicPlot();
|
|
// ~BasicPlot();
|
|
// BasicPlot(const BasicPlot&) = delete;
|
|
// BasicPlot& operator=(const BasicPlot&) = delete;
|
|
|
|
void init_plot()const;
|
|
void load_theme_manager(ThemeManager&)const;
|
|
void set_xlabel_text(const QString&)const;
|
|
void set_ylabel_text(const QString&)const;
|
|
void set_matrix_size(const QSize&)const;
|
|
void set_matrix_size(const int& w, const int& h)const;
|
|
void set_data(const QVector<PointData>& data)const;
|
|
void set_color_gradient_range(const double& min, const double& max)const;
|
|
QSize get_matrix_size() const;
|
|
bool is_initialized() const;
|
|
|
|
public slots:
|
|
void update_dynamic_heatmap(const QVector<PointData>& map)const;
|
|
void dataChanged(const QVector<PointData>& map)const;
|
|
void dataRangeChanged(const double& min, const double& max)const;
|
|
|
|
protected:
|
|
void paintEvent(QPaintEvent*) override;
|
|
|
|
private:
|
|
friend struct Impl;
|
|
|
|
};
|
|
} // namespace plot_widget::internal
|
|
|
|
namespace plot_widget::pro {
|
|
using Token = common::Token<plot_widget::internal::BasicPlot>;
|
|
|
|
using XLabelText = common::pro::String<Token,
|
|
[](auto& self, const auto& string) {
|
|
self.set_xlabel_text(string);
|
|
}>;
|
|
|
|
using YLabelText = common::pro::String<Token,
|
|
[](auto& self, const auto& string) {
|
|
self.set_ylabel_text(string);
|
|
}>;
|
|
|
|
struct MatrixSize : Token {
|
|
QSize size;
|
|
explicit MatrixSize(const int& w, const int& h) : size{w, h} {}
|
|
explicit MatrixSize(const QSize& s) : size{s} {}
|
|
void apply(auto& self) const {
|
|
self.set_matrix_size(size);
|
|
}
|
|
};
|
|
|
|
// using Data = common::pro::Vector<Token, PointData,
|
|
// [](auto& self, const auto& data) {
|
|
// self.set_data(data);
|
|
// }>;
|
|
using Data = DerivedProp<Token, QVector<QString>, [](auto& self, const auto& data) {
|
|
self.set_data(data);
|
|
}>;
|
|
|
|
struct ColorRange : Token {
|
|
double min;
|
|
double max;
|
|
explicit ColorRange(double min, double max) : min{min}, max{max} {}
|
|
void apply(auto& self) const {
|
|
self.set_color_gradient_range(min, max);
|
|
}
|
|
};
|
|
|
|
template <typename F>
|
|
using OnDataChanged =
|
|
common::pro::SignalInjection<F, Token, &internal::BasicPlot::dataChanged>;
|
|
|
|
template <typename F>
|
|
using OnDataRangeChanged =
|
|
common::pro::SignalInjection<F, Token, &internal::BasicPlot::dataRangeChanged>;
|
|
|
|
template<class PlotWidget>
|
|
concept trait = std::derived_from<PlotWidget, Token>;
|
|
|
|
// using PlotData = common::pro::Vector<Token, PointData, [](auto& self, const auto& vec) {
|
|
// self.set_data(vec);
|
|
// }>;
|
|
using PlotData = DerivedProp<Token, QVector<PointData>, [](auto& self, const auto& vec){self.set_data(vec);}>;
|
|
|
|
// using DataRange = common::pro::Array<Token, int, 2, [](auto& self, const auto& arr) {
|
|
// self.set_color_gradient_range(arr[0], arr[1]);
|
|
// }>;
|
|
using DataRange = DerivedProp<Token, std::array<int, 2>, [](auto& self, const auto& arr) {
|
|
self.set_color_gradient_range(arr[0], arr[1]);
|
|
}>;
|
|
|
|
CREEPER_DEFINE_CHECKER(trait);
|
|
using namespace widget::pro;
|
|
using namespace theme::pro;
|
|
}
|
|
|
|
struct HeatMapPlot
|
|
: public Declarative<plot_widget::internal::BasicPlot,
|
|
CheckerOr<plot_widget::pro::checker, widget::pro::checker, theme::pro::checker>> {
|
|
using Declarative::Declarative;
|
|
void paintEvent(QPaintEvent*) override;
|
|
};
|
|
}
|
|
|
|
#endif // TOUCHSENSOR_HEATMAP_H
|