// // Created by Codex on 2025/12/05. // #pragma once #include "components/charts/heatmap.hh" // for PointData definition #include "creeper-qt/utility/theme/theme.hh" #include "creeper-qt/utility/wrapper/common.hh" #include "creeper-qt/utility/wrapper/property.hh" #include "creeper-qt/utility/wrapper/widget.hh" #include "qcustomplot/qcustomplot.h" #include #include #include #include #include namespace creeper { class VectorFieldPlot; namespace vector_widget::internal { class VectorPlot : public QCustomPlot { public: VectorPlot(); ~VectorPlot() override; void load_theme_manager(ThemeManager& mgr); void set_matrix_size(const QSize& size); void set_data(const QVector& data); protected: void paintEvent(QPaintEvent* event) override; private: void initialize_plot(); void reset_plot(); void update_vectors(); void ensure_arrows(); void apply_color_scheme(); QSize matrix_size_{ 3, 4 }; QVector data_points_; bool initialized_ = false; std::optional scheme_; QColor arrow_color_{ 16, 54, 128 }; // 深蓝色 QCPItemLine* primary_arrow_ = nullptr; void ensure_primary_arrow(); }; } // namespace vector_widget::internal namespace vector_widget::pro { using Token = common::Token; struct MatrixSize : Token { QSize size; explicit MatrixSize(const QSize& s) : size{ s } { } explicit MatrixSize(int w, int h) : size{ w, h } { } void apply(auto& self) const { self.set_matrix_size(size); } }; using PlotData = DerivedProp, [](auto& self, const auto& vec) { self.set_data(vec); }>; template concept trait = std::derived_from; CREEPER_DEFINE_CHECKER(trait); using namespace widget::pro; using namespace theme::pro; } // namespace vector_widget::pro struct VectorFieldPlot : public Declarative> { using Declarative::Declarative; void paintEvent(QPaintEvent* event) override; }; } // namespace creeper