diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 6432cb7079..9a8d95633c 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -2,9 +2,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -13,7 +13,6 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); - main_layout->setContentsMargins(0, 0, 0, 0); // title bar title_bar = new QWidget(this); @@ -120,14 +119,14 @@ void ChartsWidget::updateState() { if (prev_range != display_range) { QFutureSynchronizer future_synchronizer; for (auto c : charts) - future_synchronizer.addFuture(QtConcurrent::run(c->chart_view, &ChartView::updateSeries, display_range)); + future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::updateSeries, display_range)); } } const auto &range = is_zoomed ? zoomed_range : display_range; for (auto c : charts) { - c->chart_view->setRange(range.first, range.second); - c->chart_view->updateLineMarker(current_sec); + c->setRange(range.first, range.second); + c->updateLineMarker(current_sec); } } @@ -150,11 +149,11 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show) { if (it != charts.end()) { if (!show) removeChart((*it)); } else if (show) { - auto chart = new ChartWidget(id, sig, this); - chart->chart_view->updateSeries(display_range); - QObject::connect(chart, &ChartWidget::remove, [=]() { removeChart(chart); }); - QObject::connect(chart->chart_view, &ChartView::zoomIn, this, &ChartsWidget::zoomIn); - QObject::connect(chart->chart_view, &ChartView::zoomReset, this, &ChartsWidget::zoomReset); + auto chart = new ChartView(id, sig, this); + chart->updateSeries(display_range); + QObject::connect(chart, &ChartView::remove, [=]() { removeChart(chart); }); + QObject::connect(chart, &ChartView::zoomIn, this, &ChartsWidget::zoomIn); + QObject::connect(chart, &ChartView::zoomReset, this, &ChartsWidget::zoomReset); charts_layout->insertWidget(0, chart); charts.push_back(chart); emit chartOpened(chart->id, chart->signal); @@ -168,7 +167,7 @@ bool ChartsWidget::isChartOpened(const QString &id, const Signal *sig) { return it != charts.end(); } -void ChartsWidget::removeChart(ChartWidget *chart) { +void ChartsWidget::removeChart(ChartView *chart) { charts.removeOne(chart); chart->deleteLater(); updateTitleBar(); @@ -184,8 +183,8 @@ void ChartsWidget::signalUpdated(const Signal *sig) { for (auto c : charts) { if (c->signal == sig) { c->updateTitle(); - c->chart_view->updateSeries(display_range); - c->chart_view->setRange(display_range.first, display_range.second, true); + c->updateSeries(display_range); + c->setRange(display_range.first, display_range.second, true); } } } @@ -198,54 +197,6 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) { return false; } -// ChartWidget - -ChartWidget::ChartWidget(const QString &id, const Signal *sig, QWidget *parent) : id(id), signal(sig), QWidget(parent) { - QVBoxLayout *main_layout = new QVBoxLayout(this); - main_layout->setSpacing(0); - main_layout->setContentsMargins(0, 0, 0, 0); - - header = new QWidget(this); - QGridLayout *header_layout = new QGridLayout(header); - header_layout->setContentsMargins(11, 11, 11, 0); - msg_name_label = new QLabel(this); - msg_name_label->setTextFormat(Qt::RichText); - header_layout->addWidget(msg_name_label, 0, 0, Qt::AlignLeft); - sig_name_label = new QLabel(this); - header_layout->addWidget(sig_name_label, 0, 1, Qt::AlignCenter); //, 0, Qt::AlignCenter); - - remove_btn = new QPushButton("✖", this); - remove_btn->setFixedSize(20, 20); - remove_btn->setToolTip(tr("Remove chart")); - header_layout->addWidget(remove_btn, 0, 2, Qt::AlignRight); - main_layout->addWidget(header); - - chart_view = new ChartView(id, sig, this); - main_layout->addWidget(chart_view); - main_layout->addStretch(); - - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - updateTitle(); - updateFromSettings(); - - QObject::connect(remove_btn, &QPushButton::clicked, [=]() { emit remove(id, sig); }); - QObject::connect(&settings, &Settings::changed, this, &ChartWidget::updateFromSettings); -} - -void ChartWidget::updateTitle() { - msg_name_label->setText(tr("%1 %2").arg(dbc()->msg(id)->name.c_str()).arg(id)); - sig_name_label->setText(signal->name.c_str()); -} - -void ChartWidget::updateFromSettings() { - header->setStyleSheet(settings.chart_theme == 0 ? "background-color:white" : "background-color:#23242c"); - QString color_style = settings.chart_theme == 0 ? "color:black" : "color:white"; - sig_name_label->setStyleSheet("font-weight:bold;" + color_style); - msg_name_label->setStyleSheet(color_style); - remove_btn->setStyleSheet(color_style); - chart_view->updateFromSettings(); -} - // ChartView ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent) @@ -256,7 +207,6 @@ ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent) chart->addSeries(series); chart->createDefaultAxes(); chart->legend()->hide(); - chart->setMargins({0, 0, 0, 0}); chart->layout()->setContentsMargins(0, 0, 0, 0); line_marker = new QGraphicsLineItem(chart); @@ -270,26 +220,51 @@ ChartView::ChartView(const QString &id, const Signal *sig, QWidget *parent) item_group = scene()->createItemGroup({track_line, track_ellipse, value_text}); item_group->setZValue(chart->zValue() + 10); - setChart(chart); + // title + msg_title = new QGraphicsTextItem(chart); + QToolButton *remove_btn = new QToolButton(); + remove_btn->setText("X"); + remove_btn->setAutoRaise(true); + remove_btn->setToolTip(tr("Remove Chart")); + close_btn_proxy = new QGraphicsProxyWidget(chart); + close_btn_proxy->setWidget(remove_btn); + setChart(chart); setRenderHint(QPainter::Antialiasing); setRubberBand(QChartView::HorizontalRubberBand); + updateFromSettings(); + updateTitle(); QTimer *timer = new QTimer(this); timer->setInterval(100); timer->setSingleShot(true); timer->callOnTimeout(this, &ChartView::adjustChartMargins); + QObject::connect(&settings, &Settings::changed, this, &ChartView::updateFromSettings); + QObject::connect(remove_btn, &QToolButton::clicked, [=]() { emit remove(id, sig); }); QObject::connect(chart, &QChart::plotAreaChanged, [=](const QRectF &plotArea) { // use a singleshot timer to avoid recursion call. timer->start(); }); } +void ChartView::resizeEvent(QResizeEvent *event) { + QChartView::resizeEvent(event); + msg_title->setPos(11, 6); + close_btn_proxy->setPos(event->size().width() - close_btn_proxy->size().width() - 11, 8); +} + +void ChartView::updateTitle() { + chart()->setTitle(signal->name.c_str()); + msg_title->setHtml(tr("%1 %2").arg(dbc()->msg(id)->name.c_str()).arg(id)); +} + void ChartView::updateFromSettings() { setFixedHeight(settings.chart_height); chart()->setTheme(settings.chart_theme == 0 ? QChart::ChartThemeLight : QChart::QChart::ChartThemeDark); - line_marker->setPen(QPen(settings.chart_theme == 0 ? Qt::black : Qt::white, 2)); + auto color = chart()->titleBrush().color(); + line_marker->setPen(QPen(color, 2)); + msg_title->setDefaultTextColor(color); } void ChartView::setRange(double min, double max, bool force_update) { @@ -305,7 +280,7 @@ void ChartView::adjustChartMargins() { const int aligned_pos = 60; if (chart()->plotArea().left() != aligned_pos) { const float left_margin = chart()->margins().left() + aligned_pos - chart()->plotArea().left(); - chart()->setMargins(QMargins(left_margin, 0, 0, 0)); + chart()->setMargins(QMargins(left_margin, 11, 0, 0)); } } @@ -314,7 +289,7 @@ void ChartView::updateLineMarker(double current_sec) { int x = chart()->plotArea().left() + chart()->plotArea().width() * (current_sec - axis_x->min()) / (axis_x->max() - axis_x->min()); if (int(line_marker->line().x1()) != x) { - line_marker->setLine(x, 0, x, height()); + line_marker->setLine(x, chart()->plotArea().top() - chart()->margins().top() + 3, x, height()); } } @@ -402,7 +377,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { if (!is_zooming) { const auto plot_area = chart()->plotArea(); auto axis_x = dynamic_cast(chart()->axisX()); - double x = std::clamp((double)ev->pos().x(), plot_area.left(), plot_area.right()-1); + double x = std::clamp((double)ev->pos().x(), plot_area.left(), plot_area.right() - 1); double sec = axis_x->min() + (axis_x->max() - axis_x->min()) * (x - plot_area.left()) / plot_area.width(); auto value = std::upper_bound(vals.begin(), vals.end(), sec, [](double x, auto &p) { return x < p.x(); }); if (value != vals.end()) { diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 70e0774c3e..4d33e91cb9 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -1,10 +1,9 @@ #pragma once -#include - #include #include #include +#include #include #include #include @@ -24,48 +23,31 @@ public: void setRange(double min, double max, bool force_update = false); void updateLineMarker(double current_sec); void updateFromSettings(); + void updateTitle(); + + QString id; + const Signal *signal; signals: void zoomIn(double min, double max); void zoomReset(); + void remove(const QString &msg_id, const Signal *sig); private: void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *ev) override; void leaveEvent(QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; void adjustChartMargins(); void updateAxisY(); QGraphicsItemGroup *item_group; - QGraphicsLineItem *track_line; + QGraphicsLineItem *line_marker, *track_line; QGraphicsEllipseItem *track_ellipse; - QGraphicsTextItem *value_text; - QGraphicsLineItem *line_marker; + QGraphicsTextItem *value_text, *msg_title; + QGraphicsProxyWidget *close_btn_proxy; QVector vals; - QString id; - const Signal *signal; -}; - -class ChartWidget : public QWidget { -Q_OBJECT - -public: - ChartWidget(const QString &id, const Signal *sig, QWidget *parent); - void updateTitle(); - void updateFromSettings(); - -signals: - void remove(const QString &msg_id, const Signal *sig); - -public: - QString id; - const Signal *signal; - QWidget *header; - QLabel *msg_name_label; - QLabel *sig_name_label; - QPushButton *remove_btn; - ChartView *chart_view = nullptr; -}; + }; class ChartsWidget : public QWidget { Q_OBJECT @@ -73,7 +55,7 @@ class ChartsWidget : public QWidget { public: ChartsWidget(QWidget *parent = nullptr); void showChart(const QString &id, const Signal *sig, bool show); - void removeChart(ChartWidget *chart); + void removeChart(ChartView *chart); bool isChartOpened(const QString &id, const Signal *sig); signals: @@ -100,8 +82,7 @@ private: QPushButton *reset_zoom_btn; QPushButton *remove_all_btn; QVBoxLayout *charts_layout; - QList charts; - + QList charts; bool is_zoomed = false; std::pair event_range; std::pair display_range;