You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							186 lines
						
					
					
						
							5.7 KiB
						
					
					
				
			
		
		
	
	
							186 lines
						
					
					
						
							5.7 KiB
						
					
					
				#pragma once
 | 
						|
 | 
						|
#include <QGridLayout>
 | 
						|
#include <QLabel>
 | 
						|
#include <QListWidget>
 | 
						|
#include <QGraphicsPixmapItem>
 | 
						|
#include <QGraphicsProxyWidget>
 | 
						|
#include <QStack>
 | 
						|
#include <QTimer>
 | 
						|
#include <QtCharts/QChartView>
 | 
						|
#include <QtCharts/QLegendMarker>
 | 
						|
#include <QtCharts/QLineSeries>
 | 
						|
#include <QtCharts/QScatterSeries>
 | 
						|
#include <QtCharts/QValueAxis>
 | 
						|
 | 
						|
#include "tools/cabana/dbc/dbcmanager.h"
 | 
						|
#include "tools/cabana/streams/abstractstream.h"
 | 
						|
using namespace QtCharts;
 | 
						|
 | 
						|
const int CHART_MIN_WIDTH = 300;
 | 
						|
 | 
						|
enum class SeriesType {
 | 
						|
  Line = 0,
 | 
						|
  StepLine,
 | 
						|
  Scatter
 | 
						|
};
 | 
						|
 | 
						|
class ChartView : public QChartView {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  ChartView(QWidget *parent = nullptr);
 | 
						|
  void addSeries(const MessageId &msg_id, const cabana::Signal *sig);
 | 
						|
  bool hasSeries(const MessageId &msg_id, const cabana::Signal *sig) const;
 | 
						|
  void updateSeries(const cabana::Signal *sig = nullptr);
 | 
						|
  void updatePlot(double cur, double min, double max);
 | 
						|
  void setSeriesType(SeriesType type);
 | 
						|
  void updatePlotArea(int left);
 | 
						|
 | 
						|
  struct SigItem {
 | 
						|
    MessageId msg_id;
 | 
						|
    const cabana::Signal *sig = nullptr;
 | 
						|
    QXYSeries *series = nullptr;
 | 
						|
    QVector<QPointF> vals;
 | 
						|
    QVector<QPointF> step_vals;
 | 
						|
    uint64_t last_value_mono_time = 0;
 | 
						|
    QPointF track_pt{};
 | 
						|
    SegmentTree segment_tree;
 | 
						|
  };
 | 
						|
 | 
						|
signals:
 | 
						|
  void seriesRemoved(const MessageId &id, const cabana::Signal *sig);
 | 
						|
  void seriesAdded(const MessageId &id, const cabana::Signal *sig);
 | 
						|
  void zoomIn(double min, double max);
 | 
						|
  void zoomUndo();
 | 
						|
  void remove();
 | 
						|
  void axisYLabelWidthChanged(int w);
 | 
						|
 | 
						|
private slots:
 | 
						|
  void signalUpdated(const cabana::Signal *sig);
 | 
						|
  void manageSeries();
 | 
						|
  void handleMarkerClicked();
 | 
						|
  void msgUpdated(MessageId id);
 | 
						|
  void msgRemoved(MessageId id) { removeIf([=](auto &s) { return s.msg_id == id; }); }
 | 
						|
  void signalRemoved(const cabana::Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); }
 | 
						|
 | 
						|
private:
 | 
						|
  void createToolButtons();
 | 
						|
  void mousePressEvent(QMouseEvent *event) override;
 | 
						|
  void mouseReleaseEvent(QMouseEvent *event) override;
 | 
						|
  void mouseMoveEvent(QMouseEvent *ev) override;
 | 
						|
  void dragMoveEvent(QDragMoveEvent *event) override;
 | 
						|
  void dropEvent(QDropEvent *event) override;
 | 
						|
  void leaveEvent(QEvent *event) override;
 | 
						|
  void resizeEvent(QResizeEvent *event) override;
 | 
						|
  QSize sizeHint() const override { return {CHART_MIN_WIDTH, settings.chart_height}; }
 | 
						|
  void updateAxisY();
 | 
						|
  void updateTitle();
 | 
						|
  void drawForeground(QPainter *painter, const QRectF &rect) override;
 | 
						|
  std::tuple<double, double, int> getNiceAxisNumbers(qreal min, qreal max, int tick_count);
 | 
						|
  qreal niceNumber(qreal x, bool ceiling);
 | 
						|
  QXYSeries *createSeries(SeriesType type, QColor color);
 | 
						|
  void updateSeriesPoints();
 | 
						|
  void removeIf(std::function<bool(const SigItem &)> predicate);
 | 
						|
  inline void clearTrackPoints() { for (auto &s : sigs) s.track_pt = {}; }
 | 
						|
 | 
						|
  int y_label_width = 0;
 | 
						|
  int align_to = 0;
 | 
						|
  QValueAxis *axis_x;
 | 
						|
  QValueAxis *axis_y;
 | 
						|
  QGraphicsPixmapItem *move_icon;
 | 
						|
  QGraphicsProxyWidget *close_btn_proxy;
 | 
						|
  QGraphicsProxyWidget *manage_btn_proxy;
 | 
						|
  QGraphicsRectItem *background;
 | 
						|
  QList<SigItem> sigs;
 | 
						|
  double cur_sec = 0;
 | 
						|
  const QString mime_type = "application/x-cabanachartview";
 | 
						|
  SeriesType series_type = SeriesType::Line;
 | 
						|
  bool is_scrubbing = false;
 | 
						|
  bool resume_after_scrub = false;
 | 
						|
  friend class ChartsWidget;
 | 
						|
 };
 | 
						|
 | 
						|
class ChartsWidget : public QFrame {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  ChartsWidget(QWidget *parent = nullptr);
 | 
						|
  void showChart(const MessageId &id, const cabana::Signal *sig, bool show, bool merge);
 | 
						|
  inline bool hasSignal(const MessageId &id, const cabana::Signal *sig) { return findChart(id, sig) != nullptr; }
 | 
						|
 | 
						|
public slots:
 | 
						|
  void setColumnCount(int n);
 | 
						|
  void removeAll();
 | 
						|
 | 
						|
signals:
 | 
						|
  void dock(bool floating);
 | 
						|
  void rangeChanged(double min, double max, bool is_zommed);
 | 
						|
  void seriesChanged();
 | 
						|
 | 
						|
private:
 | 
						|
  void resizeEvent(QResizeEvent *event) override;
 | 
						|
  bool event(QEvent *event) override;
 | 
						|
  void alignCharts();
 | 
						|
  void newChart();
 | 
						|
  ChartView *createChart();
 | 
						|
  void removeChart(ChartView *chart);
 | 
						|
  void eventsMerged();
 | 
						|
  void updateState();
 | 
						|
  void zoomIn(double min, double max);
 | 
						|
  void zoomReset();
 | 
						|
  void zoomUndo();
 | 
						|
  void setZoom(double min, double max);
 | 
						|
  void updateToolBar();
 | 
						|
  void setMaxChartRange(int value);
 | 
						|
  void updateLayout();
 | 
						|
  void settingChanged();
 | 
						|
  bool eventFilter(QObject *obj, QEvent *event) override;
 | 
						|
  ChartView *findChart(const MessageId &id, const cabana::Signal *sig);
 | 
						|
 | 
						|
  QLabel *title_label;
 | 
						|
  QLabel *range_lb;
 | 
						|
  LogSlider *range_slider;
 | 
						|
  QAction *range_lb_action;
 | 
						|
  QAction *range_slider_action;
 | 
						|
  bool docking = true;
 | 
						|
  QAction *dock_btn;
 | 
						|
  QAction *undo_zoom_action;
 | 
						|
  QAction *reset_zoom_action;
 | 
						|
  QAction *remove_all_btn;
 | 
						|
  QGridLayout *charts_layout;
 | 
						|
  QList<ChartView *> charts;
 | 
						|
  uint32_t max_chart_range = 0;
 | 
						|
  bool is_zoomed = false;
 | 
						|
  std::pair<double, double> display_range;
 | 
						|
  std::pair<double, double> zoomed_range;
 | 
						|
  QStack<QPair<double, double>> zoom_stack;
 | 
						|
  bool use_dark_theme = false;
 | 
						|
  QAction *columns_action;
 | 
						|
  int column_count = 1;
 | 
						|
  int current_column_count = 0;
 | 
						|
  QTimer align_timer;
 | 
						|
};
 | 
						|
 | 
						|
class SeriesSelector : public QDialog {
 | 
						|
public:
 | 
						|
  struct ListItem : public QListWidgetItem {
 | 
						|
    ListItem(const MessageId &msg_id, const cabana::Signal *sig, QListWidget *parent) : msg_id(msg_id), sig(sig), QListWidgetItem(parent) {}
 | 
						|
    MessageId msg_id;
 | 
						|
    const cabana::Signal *sig;
 | 
						|
  };
 | 
						|
 | 
						|
  SeriesSelector(QString title, QWidget *parent);
 | 
						|
  QList<ListItem *> seletedItems();
 | 
						|
  inline void addSelected(const MessageId &id, const cabana::Signal *sig) { addItemToList(selected_list, id, sig, true); }
 | 
						|
 | 
						|
private:
 | 
						|
  void updateAvailableList(int index);
 | 
						|
  void addItemToList(QListWidget *parent, const MessageId id, const cabana::Signal *sig, bool show_msg_name = false);
 | 
						|
  void add(QListWidgetItem *item);
 | 
						|
  void remove(QListWidgetItem *item);
 | 
						|
 | 
						|
  QComboBox *msgs_combo;
 | 
						|
  QListWidget *available_list;
 | 
						|
  QListWidget *selected_list;
 | 
						|
};
 | 
						|
 |