mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-07-16 02:12:06 +08:00
cabana: add a slider to adjust chart range from 1 sec to max cached seconds. (#27005)
* add slider to set chart range * set minumu to 1 sec * make chart work in any range * cleanup * rename to max_cached_minitues * more * dont draw out of plotarea * cleanup * updateLayout after chart removed * cleanup * fix clamp * usea same cur_sec to update all charts
This commit is contained in:
+86
-101
@@ -2,10 +2,11 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCompleter>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDrag>
|
||||
#include <QLineEdit>
|
||||
#include <QFutureSynchronizer>
|
||||
#include <QGraphicsLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QRubberBand>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
@@ -24,10 +25,9 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
toolbar->setIconSize({16, 16});
|
||||
|
||||
toolbar->addWidget(title_label = new QLabel());
|
||||
title_label->setContentsMargins(0 ,0, 12, 0);
|
||||
title_label->setContentsMargins(0, 0, 12, 0);
|
||||
columns_cb = new QComboBox(this);
|
||||
columns_cb->addItems({"1", "2", "3", "4"});
|
||||
columns_cb->setCurrentIndex(std::clamp(settings.chart_column_count - 1, 0, 3));
|
||||
toolbar->addWidget(new QLabel(tr("Columns:")));
|
||||
toolbar->addWidget(columns_cb);
|
||||
|
||||
@@ -35,8 +35,16 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
stretch_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
toolbar->addWidget(stretch_label);
|
||||
|
||||
show_all_values_btn = toolbar->addAction("");
|
||||
toolbar->addWidget(range_label = new QLabel());
|
||||
toolbar->addWidget(new QLabel(tr("Range:")));
|
||||
toolbar->addWidget(range_lb = new QLabel(this));
|
||||
range_slider = new QSlider(Qt::Horizontal, this);
|
||||
range_slider->setToolTip(tr("Set the chart range"));
|
||||
range_slider->setRange(1, settings.max_cached_minutes * 60);
|
||||
range_slider->setSingleStep(1);
|
||||
range_slider->setPageStep(60); // 1 min
|
||||
toolbar->addWidget(range_slider);
|
||||
|
||||
toolbar->addWidget(zoom_range_lb = new QLabel());
|
||||
reset_zoom_btn = toolbar->addAction(bootstrapPixmap("arrow-counterclockwise"), "");
|
||||
reset_zoom_btn->setToolTip(tr("Reset zoom (drag on chart to zoom X-Axis)"));
|
||||
remove_all_btn = toolbar->addAction(bootstrapPixmap("x"), "");
|
||||
@@ -48,8 +56,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
QWidget *charts_container = new QWidget(this);
|
||||
QVBoxLayout *charts_main_layout = new QVBoxLayout(charts_container);
|
||||
charts_main_layout->setContentsMargins(0, 0, 0, 0);
|
||||
charts_layout = new QGridLayout(charts_container);
|
||||
charts_main_layout->addLayout(charts_layout);
|
||||
charts_main_layout->addLayout(charts_layout = new QGridLayout);
|
||||
charts_main_layout->addStretch(0);
|
||||
|
||||
QScrollArea *charts_scroll = new QScrollArea(this);
|
||||
@@ -58,20 +65,24 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
charts_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
main_layout->addWidget(charts_scroll);
|
||||
|
||||
max_chart_range = settings.max_chart_x_range;
|
||||
use_dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() >
|
||||
QApplication::style()->standardPalette().color(QPalette::Background).value();
|
||||
updateToolBar();
|
||||
|
||||
align_charts_timer = new QTimer(this);
|
||||
align_charts_timer->setSingleShot(true);
|
||||
align_charts_timer->callOnTimeout(this, &ChartsWidget::alignCharts);
|
||||
column_count = settings.chart_column_count;
|
||||
|
||||
// init settings
|
||||
use_dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() >
|
||||
QApplication::style()->standardPalette().color(QPalette::Background).value();
|
||||
column_count = std::clamp(settings.chart_column_count, 1, columns_cb->count());
|
||||
max_chart_range = std::clamp(settings.chart_range, 1, settings.max_cached_minutes * 60);
|
||||
display_range = {0, max_chart_range};
|
||||
columns_cb->setCurrentIndex(column_count);
|
||||
range_slider->setValue(max_chart_range);
|
||||
updateToolBar();
|
||||
|
||||
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll);
|
||||
QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::updateState);
|
||||
QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::eventsMerged);
|
||||
QObject::connect(can, &AbstractStream::updated, this, &ChartsWidget::updateState);
|
||||
QObject::connect(show_all_values_btn, &QAction::triggered, this, &ChartsWidget::showAllData);
|
||||
QObject::connect(range_slider, &QSlider::valueChanged, this, &ChartsWidget::setMaxChartRange);
|
||||
QObject::connect(remove_all_btn, &QAction::triggered, this, &ChartsWidget::removeAll);
|
||||
QObject::connect(reset_zoom_btn, &QAction::triggered, this, &ChartsWidget::zoomReset);
|
||||
QObject::connect(columns_cb, SIGNAL(activated(int)), SLOT(setColumnCount(int)));
|
||||
@@ -83,34 +94,16 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
});
|
||||
}
|
||||
|
||||
void ChartsWidget::updateDisplayRange() {
|
||||
auto events = can->events();
|
||||
double min_event_sec = (events->front()->mono_time / (double)1e9) - can->routeStartTime();
|
||||
double max_event_sec = (events->back()->mono_time / (double)1e9) - can->routeStartTime();
|
||||
const double cur_sec = can->currentSec();
|
||||
if (!can->liveStreaming()) {
|
||||
auto prev_range = display_range;
|
||||
if (cur_sec < display_range.first || cur_sec >= (display_range.second - 5)) {
|
||||
// reached the end, or seeked to a timestamp out of range.
|
||||
display_range.first = cur_sec - 5;
|
||||
}
|
||||
display_range.first = std::floor(std::max(min_event_sec, display_range.first));
|
||||
display_range.second = std::floor(std::min(display_range.first + max_chart_range, max_event_sec));
|
||||
if (prev_range != display_range) {
|
||||
QFutureSynchronizer<void> future_synchronizer;
|
||||
for (auto c : charts) {
|
||||
future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::setEventsRange, display_range));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cur_sec >= (display_range.second - 5)) {
|
||||
display_range.first = std::floor(std::max(min_event_sec, cur_sec - settings.max_chart_x_range / 2.0));
|
||||
}
|
||||
display_range.second = std::floor(display_range.first + settings.max_chart_x_range);
|
||||
void ChartsWidget::eventsMerged() {
|
||||
{
|
||||
assert(!can->liveStreaming());
|
||||
QFutureSynchronizer<void> future_synchronizer;
|
||||
const auto events = can->events();
|
||||
for (auto c : charts) {
|
||||
c->updateSeries(nullptr, events, false);
|
||||
future_synchronizer.addFuture(QtConcurrent::run(c, &ChartView::updateSeries, nullptr, events, true));
|
||||
}
|
||||
}
|
||||
updateState();
|
||||
}
|
||||
|
||||
void ChartsWidget::zoomIn(double min, double max) {
|
||||
@@ -128,49 +121,61 @@ void ChartsWidget::zoomReset() {
|
||||
void ChartsWidget::updateState() {
|
||||
if (charts.isEmpty()) return;
|
||||
|
||||
if (can->liveStreaming()) {
|
||||
// appends incoming events to the end of series
|
||||
const auto events = can->events();
|
||||
for (auto c : charts) {
|
||||
c->updateSeries(nullptr, events, false);
|
||||
}
|
||||
}
|
||||
|
||||
const double cur_sec = can->currentSec();
|
||||
if (!is_zoomed) {
|
||||
updateDisplayRange();
|
||||
} else if (can->currentSec() < zoomed_range.first || can->currentSec() >= zoomed_range.second) {
|
||||
double pos = (cur_sec - display_range.first) / max_chart_range;
|
||||
if (pos > 0.8) {
|
||||
const double min_event_sec = (can->events()->front()->mono_time / (double)1e9) - can->routeStartTime();
|
||||
display_range.first = std::floor(std::max(min_event_sec, cur_sec - max_chart_range * 0.2));
|
||||
}
|
||||
display_range.second = std::floor(display_range.first + max_chart_range);
|
||||
} else if (cur_sec < zoomed_range.first || cur_sec >= zoomed_range.second) {
|
||||
// loop in zoommed range
|
||||
can->seekTo(zoomed_range.first);
|
||||
}
|
||||
|
||||
const auto &range = is_zoomed ? zoomed_range : display_range;
|
||||
setUpdatesEnabled(false);
|
||||
const auto &range = is_zoomed ? zoomed_range : display_range;
|
||||
for (auto c : charts) {
|
||||
c->setDisplayRange(range.first, range.second);
|
||||
c->scene()->invalidate({}, QGraphicsScene::ForegroundLayer);
|
||||
c->updatePlot(cur_sec, range.first, range.second);
|
||||
}
|
||||
setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void ChartsWidget::showAllData() {
|
||||
bool switch_to_show_all = max_chart_range == settings.max_chart_x_range;
|
||||
max_chart_range = switch_to_show_all ? settings.cached_segment_limit * 60
|
||||
: settings.max_chart_x_range;
|
||||
max_chart_range = std::min(max_chart_range, (uint32_t)can->totalSeconds());
|
||||
void ChartsWidget::setMaxChartRange(int value) {
|
||||
max_chart_range = settings.chart_range = value;
|
||||
double current_sec = can->currentSec();
|
||||
const double min_event_sec = (can->events()->front()->mono_time / (double)1e9) - can->routeStartTime();
|
||||
// keep current_sec's pos
|
||||
double pos = (current_sec - display_range.first) / (display_range.second - display_range.first);
|
||||
display_range.first = std::floor(std::max(min_event_sec, current_sec - max_chart_range * (1.0 - pos)));
|
||||
display_range.second = std::floor(display_range.first + max_chart_range);
|
||||
updateToolBar();
|
||||
updateState();
|
||||
}
|
||||
|
||||
void ChartsWidget::updateToolBar() {
|
||||
int min_range = std::min(settings.max_chart_x_range, (int)can->totalSeconds());
|
||||
bool displaying_all = max_chart_range != min_range;
|
||||
show_all_values_btn->setText(tr("%1 minutes").arg(max_chart_range / 60));
|
||||
show_all_values_btn->setToolTip(tr("Click to display %1 data").arg(displaying_all ? tr("%1 minutes").arg(min_range / 60) : tr("ALL cached")));
|
||||
show_all_values_btn->setVisible(!is_zoomed && !can->liveStreaming());
|
||||
remove_all_btn->setEnabled(!charts.isEmpty());
|
||||
reset_zoom_btn->setEnabled(is_zoomed);
|
||||
range_label->setText(is_zoomed ? tr("%1 - %2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : "");
|
||||
title_label->setText(charts.size() > 0 ? tr("Charts (%1)").arg(charts.size()) : tr("Charts"));
|
||||
range_lb->setText(QString(" %1:%2 ").arg(max_chart_range / 60, 2, 10, QLatin1Char('0')).arg(max_chart_range % 60, 2, 10, QLatin1Char('0')));
|
||||
zoom_range_lb->setText(is_zoomed ? tr("Zooming: %1 - %2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : "");
|
||||
title_label->setText(tr("Charts: %1").arg(charts.size()));
|
||||
dock_btn->setIcon(bootstrapPixmap(docking ? "arrow-up-right" : "arrow-down-left"));
|
||||
dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts"));
|
||||
remove_all_btn->setEnabled(!charts.isEmpty());
|
||||
reset_zoom_btn->setEnabled(is_zoomed);
|
||||
}
|
||||
|
||||
void ChartsWidget::settingChanged() {
|
||||
range_slider->setRange(1, settings.max_cached_minutes * 60);
|
||||
for (auto c : charts) {
|
||||
c->setFixedHeight(settings.chart_height);
|
||||
columns_cb->setCurrentIndex(std::clamp(settings.chart_column_count - 1, 0, columns_cb->count() - 1));
|
||||
setColumnCount(settings.chart_column_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,11 +194,8 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
|
||||
chart = new ChartView(this);
|
||||
chart->setFixedHeight(settings.chart_height);
|
||||
chart->setMinimumWidth(CHART_MIN_WIDTH);
|
||||
chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
chart->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
chart->chart()->setTheme(use_dark_theme ? QChart::QChart::ChartThemeDark : QChart::ChartThemeLight);
|
||||
chart->setEventsRange(display_range);
|
||||
auto range = is_zoomed ? zoomed_range : display_range;
|
||||
chart->setDisplayRange(range.first, range.second);
|
||||
QObject::connect(chart, &ChartView::remove, [=]() { removeChart(chart); });
|
||||
QObject::connect(chart, &ChartView::zoomIn, this, &ChartsWidget::zoomIn);
|
||||
QObject::connect(chart, &ChartView::zoomReset, this, &ChartsWidget::zoomReset);
|
||||
@@ -204,6 +206,7 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
|
||||
updateLayout();
|
||||
}
|
||||
chart->addSeries(id, sig);
|
||||
updateState();
|
||||
} else if (!show && chart) {
|
||||
chart->removeSeries(id, sig);
|
||||
}
|
||||
@@ -214,7 +217,7 @@ void ChartsWidget::showChart(const QString &id, const Signal *sig, bool show, bo
|
||||
void ChartsWidget::setColumnCount(int n) {
|
||||
n = std::clamp(n + 1, 1, columns_cb->count());
|
||||
if (column_count != n) {
|
||||
column_count = n;
|
||||
column_count = settings.chart_column_count = n;
|
||||
updateLayout();
|
||||
}
|
||||
}
|
||||
@@ -239,6 +242,7 @@ void ChartsWidget::removeChart(ChartView *chart) {
|
||||
chart->deleteLater();
|
||||
updateToolBar();
|
||||
alignCharts();
|
||||
updateLayout();
|
||||
emit seriesChanged();
|
||||
}
|
||||
|
||||
@@ -440,36 +444,28 @@ void ChartView::updateTitle() {
|
||||
}
|
||||
}
|
||||
|
||||
void ChartView::setEventsRange(const std::pair<double, double> &range) {
|
||||
if (range != events_range) {
|
||||
events_range = range;
|
||||
updateSeries();
|
||||
}
|
||||
}
|
||||
|
||||
void ChartView::setDisplayRange(double min, double max) {
|
||||
void ChartView::updatePlot(double cur, double min, double max) {
|
||||
cur_sec = cur;
|
||||
if (min != axis_x->min() || max != axis_x->max()) {
|
||||
axis_x->setRange(min, max);
|
||||
updateAxisY();
|
||||
}
|
||||
scene()->invalidate({}, QGraphicsScene::ForegroundLayer);
|
||||
}
|
||||
|
||||
void ChartView::updateSeries(const Signal *sig, const std::vector<Event*> *events, bool clear) {
|
||||
if (!events) events = can->events();
|
||||
if (!events || sigs.isEmpty()) return;
|
||||
|
||||
void ChartView::updateSeries(const Signal *sig, const std::vector<Event *> *events, bool clear) {
|
||||
events = events ? events : can->events();
|
||||
for (auto &s : sigs) {
|
||||
if (!sig || s.sig == sig) {
|
||||
if (clear) {
|
||||
s.vals.clear();
|
||||
s.vals.reserve(settings.max_cached_minutes * 60 * 100); // [n]seconds * 100hz
|
||||
s.last_value_mono_time = 0;
|
||||
}
|
||||
double route_start_time = can->routeStartTime();
|
||||
uint64_t begin_ts = can->liveStreaming() ? s.last_value_mono_time : (route_start_time + events_range.first) * 1e9;
|
||||
Event begin_event(cereal::Event::Which::INIT_DATA, begin_ts);
|
||||
Event begin_event(cereal::Event::Which::INIT_DATA, s.last_value_mono_time);
|
||||
auto begin = std::upper_bound(events->begin(), events->end(), &begin_event, Event::lessThan());
|
||||
uint64_t end_ns = can->liveStreaming() ? events->back()->mono_time : (route_start_time + events_range.second) * 1e9;
|
||||
for (auto it = begin; it != events->end() && (*it)->mono_time <= end_ns; ++it) {
|
||||
for (auto it = begin; it != events->end(); ++it) {
|
||||
if ((*it)->which == cereal::Event::Which::CAN) {
|
||||
for (const auto &c : (*it)->event.getCan()) {
|
||||
if (s.source == c.getSrc() && s.address == c.getAddress()) {
|
||||
@@ -481,13 +477,8 @@ void ChartView::updateSeries(const Signal *sig, const std::vector<Event*> *event
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!s.vals.isEmpty()) {
|
||||
auto [min_v, max_v] = std::minmax_element(s.vals.begin(), s.vals.end(), [](auto &l, auto &r) { return l.y() < r.y(); });
|
||||
s.min_y = min_v->y();
|
||||
s.max_y = max_v->y();
|
||||
if (events->size()) {
|
||||
s.last_value_mono_time = events->back()->mono_time;
|
||||
} else {
|
||||
s.min_y = s.max_y = 0;
|
||||
}
|
||||
s.series->replace(s.vals);
|
||||
updateAxisY();
|
||||
@@ -501,18 +492,11 @@ void ChartView::updateAxisY() {
|
||||
|
||||
double min_y = std::numeric_limits<double>::max();
|
||||
double max_y = std::numeric_limits<double>::lowest();
|
||||
if (can->liveStreaming() || events_range == std::pair{axis_x->min(), axis_x->max()}) {
|
||||
for (auto &s : sigs) {
|
||||
if (s.min_y < min_y) min_y = s.min_y;
|
||||
if (s.max_y > max_y) max_y = s.max_y;
|
||||
}
|
||||
} else {
|
||||
for (auto &s : sigs) {
|
||||
auto begin = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; });
|
||||
for (auto it = begin; it != s.vals.end() && it->x() <= axis_x->max(); ++it) {
|
||||
if (it->y() < min_y) min_y = it->y();
|
||||
if (it->y() > max_y) max_y = it->y();
|
||||
}
|
||||
for (auto &s : sigs) {
|
||||
auto begin = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; });
|
||||
for (auto it = begin; it != s.vals.end() && it->x() <= axis_x->max(); ++it) {
|
||||
if (it->y() < min_y) min_y = it->y();
|
||||
if (it->y() > max_y) max_y = it->y();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +648,8 @@ void ChartView::dropEvent(QDropEvent *event) {
|
||||
}
|
||||
|
||||
void ChartView::drawForeground(QPainter *painter, const QRectF &rect) {
|
||||
qreal x = chart()->mapToPosition(QPointF{can->currentSec(), 0}).x();
|
||||
qreal x = chart()->mapToPosition(QPointF{cur_sec, 0}).x();
|
||||
x = std::clamp(x, chart()->plotArea().left(), chart()->plotArea().right());
|
||||
qreal y1 = chart()->plotArea().top() - 2;
|
||||
qreal y2 = chart()->plotArea().bottom() + 2;
|
||||
painter->setPen(QPen(chart()->titleBrush().color(), 2));
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QSlider>
|
||||
#include <QTimer>
|
||||
#include <QtCharts/QChartView>
|
||||
#include <QtCharts/QLineSeries>
|
||||
@@ -26,8 +26,7 @@ public:
|
||||
void removeSeries(const QString &msg_id, const Signal *sig);
|
||||
bool hasSeries(const QString &msg_id, const Signal *sig) const;
|
||||
void updateSeries(const Signal *sig = nullptr, const std::vector<Event*> *events = nullptr, bool clear = true);
|
||||
void setEventsRange(const std::pair<double, double> &range);
|
||||
void setDisplayRange(double min, double max);
|
||||
void updatePlot(double cur, double min, double max);
|
||||
void setPlotAreaLeftPosition(int pos);
|
||||
qreal getYAsixLabelWidth() const;
|
||||
|
||||
@@ -37,8 +36,6 @@ public:
|
||||
uint32_t address = 0;
|
||||
const Signal *sig = nullptr;
|
||||
QLineSeries *series = nullptr;
|
||||
double min_y = 0;
|
||||
double max_y = 0;
|
||||
QVector<QPointF> vals;
|
||||
uint64_t last_value_mono_time = 0;
|
||||
};
|
||||
@@ -79,8 +76,8 @@ private:
|
||||
QPointF track_pt;
|
||||
QGraphicsProxyWidget *close_btn_proxy;
|
||||
QGraphicsProxyWidget *manage_btn_proxy;
|
||||
std::pair<double, double> events_range = {0, 0};
|
||||
QList<SigItem> sigs;
|
||||
double cur_sec = 0;
|
||||
const QString mime_type = "application/x-cabanachartview";
|
||||
};
|
||||
|
||||
@@ -106,21 +103,21 @@ private:
|
||||
void removeChart(ChartView *chart);
|
||||
void eventsMerged();
|
||||
void updateState();
|
||||
void updateDisplayRange();
|
||||
void zoomIn(double min, double max);
|
||||
void zoomReset();
|
||||
void updateToolBar();
|
||||
void removeAll();
|
||||
void showAllData();
|
||||
void setMaxChartRange(int value);
|
||||
void updateLayout();
|
||||
void settingChanged();
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
ChartView *findChart(const QString &id, const Signal *sig);
|
||||
|
||||
QLabel *title_label;
|
||||
QLabel *range_label;
|
||||
QLabel *zoom_range_lb;
|
||||
QLabel *range_lb;
|
||||
QSlider *range_slider;
|
||||
bool docking = true;
|
||||
QAction *show_all_values_btn;
|
||||
QAction *dock_btn;
|
||||
QAction *reset_zoom_btn;
|
||||
QAction *remove_all_btn;
|
||||
|
||||
+11
-18
@@ -15,9 +15,9 @@ Settings::Settings() {
|
||||
void Settings::save() {
|
||||
QSettings s("settings", QSettings::IniFormat);
|
||||
s.setValue("fps", fps);
|
||||
s.setValue("cached_segment", cached_segment_limit);
|
||||
s.setValue("max_cached_minutes", max_cached_minutes);
|
||||
s.setValue("chart_height", chart_height);
|
||||
s.setValue("max_chart_x_range", max_chart_x_range);
|
||||
s.setValue("chart_range", chart_range);
|
||||
s.setValue("chart_column_count", chart_column_count);
|
||||
s.setValue("last_dir", last_dir);
|
||||
s.setValue("window_state", window_state);
|
||||
@@ -28,9 +28,9 @@ void Settings::save() {
|
||||
void Settings::load() {
|
||||
QSettings s("settings", QSettings::IniFormat);
|
||||
fps = s.value("fps", 10).toInt();
|
||||
cached_segment_limit = s.value("cached_segment", 5).toInt();
|
||||
max_cached_minutes = s.value("cached_minutes", 5).toInt();
|
||||
chart_height = s.value("chart_height", 200).toInt();
|
||||
max_chart_x_range = s.value("max_chart_x_range", 3 * 60).toInt();
|
||||
chart_range = s.value("chart_range", 3 * 60).toInt();
|
||||
chart_column_count = s.value("chart_column_count", 1).toInt();
|
||||
last_dir = s.value("last_dir", QDir::homePath()).toString();
|
||||
window_state = s.value("window_state").toByteArray();
|
||||
@@ -50,23 +50,17 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
|
||||
fps->setValue(settings.fps);
|
||||
form_layout->addRow("FPS", fps);
|
||||
|
||||
cached_segment = new QSpinBox(this);
|
||||
cached_segment->setRange(5, 60);
|
||||
cached_segment->setSingleStep(1);
|
||||
cached_segment->setValue(settings.cached_segment_limit);
|
||||
form_layout->addRow(tr("Cached segments limit"), cached_segment);
|
||||
|
||||
max_chart_x_range = new QSpinBox(this);
|
||||
max_chart_x_range->setRange(3, 60);
|
||||
max_chart_x_range->setSingleStep(1);
|
||||
max_chart_x_range->setValue(settings.max_chart_x_range / 60);
|
||||
form_layout->addRow(tr("Chart range (minutes)"), max_chart_x_range);
|
||||
cached_minutes = new QSpinBox(this);
|
||||
cached_minutes->setRange(5, 60);
|
||||
cached_minutes->setSingleStep(1);
|
||||
cached_minutes->setValue(settings.max_cached_minutes);
|
||||
form_layout->addRow(tr("Max Cached Minutes"), cached_minutes);
|
||||
|
||||
chart_height = new QSpinBox(this);
|
||||
chart_height->setRange(100, 500);
|
||||
chart_height->setSingleStep(10);
|
||||
chart_height->setValue(settings.chart_height);
|
||||
form_layout->addRow(tr("Chart height"), chart_height);
|
||||
form_layout->addRow(tr("Chart Height"), chart_height);
|
||||
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
form_layout->addRow(buttonBox);
|
||||
@@ -78,9 +72,8 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
|
||||
|
||||
void SettingsDlg::save() {
|
||||
settings.fps = fps->value();
|
||||
settings.cached_segment_limit = cached_segment->value();
|
||||
settings.max_cached_minutes = cached_minutes->value();
|
||||
settings.chart_height = chart_height->value();
|
||||
settings.max_chart_x_range = max_chart_x_range->value() * 60;
|
||||
settings.save();
|
||||
accept();
|
||||
emit settings.changed();
|
||||
|
||||
@@ -14,10 +14,10 @@ public:
|
||||
void load();
|
||||
|
||||
int fps = 10;
|
||||
int cached_segment_limit = 5;
|
||||
int max_cached_minutes = 5;
|
||||
int chart_height = 200;
|
||||
int chart_column_count = 1;
|
||||
int max_chart_x_range = 3 * 60; // 3 minutes
|
||||
int chart_range = 3 * 60; // e minutes
|
||||
QString last_dir;
|
||||
QByteArray geometry;
|
||||
QByteArray video_splitter_state;
|
||||
@@ -34,9 +34,8 @@ public:
|
||||
SettingsDlg(QWidget *parent);
|
||||
void save();
|
||||
QSpinBox *fps;
|
||||
QSpinBox *cached_segment;
|
||||
QSpinBox *cached_minutes;
|
||||
QSpinBox *chart_height;
|
||||
QSpinBox *max_chart_x_range;
|
||||
};
|
||||
|
||||
extern Settings settings;
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
|
||||
protected:
|
||||
void streamThread();
|
||||
void updateCachedNS() { cache_ns = (settings.cached_segment_limit * 60) * 1e9; }
|
||||
void updateCachedNS() { cache_ns = (settings.max_cached_minutes * 60) * 1e9; }
|
||||
|
||||
mutable std::mutex lock;
|
||||
mutable std::vector<Event *> events_vector;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
ReplayStream::ReplayStream(QObject *parent) : AbstractStream(parent, false) {
|
||||
QObject::connect(&settings, &Settings::changed, [this]() {
|
||||
if (replay) replay->setSegmentCacheLimit(settings.cached_segment_limit);
|
||||
if (replay) replay->setSegmentCacheLimit(settings.max_cached_minutes);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ static bool event_filter(const Event *e, void *opaque) {
|
||||
|
||||
bool ReplayStream::loadRoute(const QString &route, const QString &data_dir, uint32_t replay_flags) {
|
||||
replay = new Replay(route, {"can", "roadEncodeIdx", "wideRoadEncodeIdx", "carParams"}, {}, nullptr, replay_flags, data_dir, this);
|
||||
replay->setSegmentCacheLimit(settings.cached_segment_limit);
|
||||
replay->setSegmentCacheLimit(settings.max_cached_minutes);
|
||||
replay->installEventFilter(event_filter, this);
|
||||
QObject::connect(replay, &Replay::seekedTo, this, &AbstractStream::seekedTo);
|
||||
QObject::connect(replay, &Replay::segmentsMerged, this, &AbstractStream::eventsMerged);
|
||||
|
||||
Reference in New Issue
Block a user