cabana: fix chart value tip flickers when the mouse moves over it (#32796)

fix chart value tip flickers
pull/214/head
Dean Lee 11 months ago committed by GitHub
parent 442e9f4ae4
commit 5aac2e5a89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 9
      tools/cabana/chart/chart.cc
  2. 1
      tools/cabana/chart/chart.h
  3. 62
      tools/cabana/chart/chartswidget.cc
  4. 7
      tools/cabana/chart/chartswidget.h
  5. 6
      tools/cabana/chart/tiplabel.cc
  6. 27
      tools/cabana/mainwin.cc
  7. 3
      tools/cabana/mainwin.h

@ -421,13 +421,6 @@ qreal ChartView::niceNumber(qreal x, bool ceiling) {
return q * z;
}
void ChartView::leaveEvent(QEvent *event) {
if (tip_label->isVisible()) {
charts_widget->showValueTip(-1);
}
QChartView::leaveEvent(event);
}
QPixmap getBlankShadowPixmap(const QPixmap &px, int radius) {
QGraphicsDropShadowEffect *e = new QGraphicsDropShadowEffect;
e->setColor(QColor(40, 40, 40, 245));
@ -546,7 +539,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) {
bool is_zooming = rubber && rubber->isVisible();
clearTrackPoints();
if (!is_zooming && plot_area.contains(ev->pos())) {
if (!is_zooming && plot_area.contains(ev->pos()) && isActiveWindow()) {
const double sec = chart()->mapToValue(ev->pos()).x();
charts_widget->showValueTip(sec);
} else if (tip_label->isVisible()) {

@ -76,7 +76,6 @@ private:
void dragLeaveEvent(QDragLeaveEvent *event) override { drawDropIndicator(false); }
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void leaveEvent(QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
QSize sizeHint() const override;
void updateAxisY();

@ -116,13 +116,12 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
QObject::connect(tabbar, &QTabBar::currentChanged, [this](int index) {
if (index != -1) updateLayout(true);
});
QObject::connect(dock_btn, &QToolButton::clicked, [this]() {
emit dock(!docking);
docking = !docking;
updateToolBar();
});
QObject::connect(dock_btn, &QToolButton::clicked, this, &ChartsWidget::toggleChartsDocking);
setIsDocked(true);
newTab();
qApp->installEventFilter(this);
setWhatsThis(tr(R"(
<b>Chart view</b><br />
<!-- TODO: add descprition here -->
@ -177,8 +176,11 @@ QRect ChartsWidget::chartVisibleRect(ChartView *chart) {
}
void ChartsWidget::showValueTip(double sec) {
if (sec < 0 && !value_tip_visible_) return;
value_tip_visible_ = sec >= 0;
for (auto c : currentCharts()) {
sec >= 0 ? c->showTip(sec) : c->hideTip();
value_tip_visible_ ? c->showTip(sec) : c->hideTip();
}
}
@ -209,6 +211,12 @@ void ChartsWidget::setMaxChartRange(int value) {
updateState();
}
void ChartsWidget::setIsDocked(bool docked) {
is_docked = docked;
dock_btn->setIcon(is_docked ? "arrow-up-right-square" : "arrow-down-left-square");
dock_btn->setToolTip(is_docked ? tr("Float the charts window") : tr("Dock the charts window"));
}
void ChartsWidget::updateToolBar() {
title_label->setText(tr("Charts: %1").arg(charts.size()));
columns_action->setText(tr("Column: %1").arg(column_count));
@ -222,8 +230,6 @@ void ChartsWidget::updateToolBar() {
reset_zoom_action->setVisible(is_zoomed);
reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(can->timeRange()->first, 0, 'f', 2).arg(can->timeRange()->second, 0, 'f', 2) : "");
remove_all_btn->setEnabled(!charts.isEmpty());
dock_btn->setIcon(docking ? "arrow-up-right-square" : "arrow-down-left-square");
dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts"));
}
void ChartsWidget::settingChanged() {
@ -375,11 +381,6 @@ QSize ChartsWidget::minimumSizeHint() const {
return QSize(CHART_MIN_WIDTH, QWidget::minimumSizeHint().height());
}
void ChartsWidget::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
updateLayout();
}
void ChartsWidget::newChart() {
SignalSelector dlg(tr("New Chart"), this);
if (dlg.exec() == QDialog::Accepted) {
@ -432,10 +433,16 @@ void ChartsWidget::alignCharts() {
}
}
bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) {
if (obj != this && event->type() == QEvent::Close) {
emit dock_btn->clicked();
return true;
bool ChartsWidget::eventFilter(QObject *o, QEvent *e) {
if (value_tip_visible_ && e->type() == QEvent::MouseMove) {
auto pos = static_cast<QMouseEvent *>(e)->globalPos();
bool outside_plot_area =std::none_of(charts.begin(), charts.end(), [&pos](auto c) {
return c->chart()->plotArea().contains(c->mapFromGlobal(pos));
});
if (outside_plot_area) {
showValueTip(-1);
}
}
return false;
}
@ -443,30 +450,25 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) {
bool ChartsWidget::event(QEvent *event) {
bool back_button = false;
switch (event->type()) {
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(event);
back_button = ev->button() == Qt::BackButton;
case QEvent::Resize:
updateLayout();
break;
}
case QEvent::NativeGesture: {
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent *>(event);
back_button = (ev->value() == 180);
case QEvent::MouseButtonPress:
back_button = static_cast<QMouseEvent *>(event)->button() == Qt::BackButton;
break;
case QEvent::NativeGesture:
back_button = (static_cast<QNativeGestureEvent *>(event)->value() == 180);
break;
}
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
case QEvent::FocusIn:
case QEvent::FocusOut:
case QEvent::Leave:
showValueTip(-1);
break;
default:
break;
}
if (back_button) {
zoom_undo_stack->undo();
return true;
return true; // Return true since the event has been handled
}
return QFrame::event(event);
}

@ -47,14 +47,14 @@ public slots:
void setColumnCount(int n);
void removeAll();
void timeRangeChanged(const std::optional<std::pair<double, double>> &time_range);
void setIsDocked(bool dock);
signals:
void dock(bool floating);
void toggleChartsDocking();
void seriesChanged();
private:
QSize minimumSizeHint() const override;
void resizeEvent(QResizeEvent *event) override;
bool event(QEvent *event) override;
void alignCharts();
void newChart();
@ -85,7 +85,7 @@ private:
LogSlider *range_slider;
QAction *range_lb_action;
QAction *range_slider_action;
bool docking = true;
bool is_docked = true;
ToolButton *dock_btn;
QAction *undo_zoom_action;
@ -109,6 +109,7 @@ private:
QTimer *auto_scroll_timer;
QTimer *align_timer;
int current_theme = 0;
bool value_tip_visible_ = false;
friend class ZoomCommand;
friend class ChartView;
friend class ChartsContainer;

@ -9,8 +9,12 @@
#include "tools/cabana/settings.h"
TipLabel::TipLabel(QWidget *parent) : QLabel(parent, Qt::ToolTip | Qt::FramelessWindowHint) {
setAttribute(Qt::WA_ShowWithoutActivating);
setAttribute(Qt::WA_TransparentForMouseEvents);
setForegroundRole(QPalette::ToolTipText);
setBackgroundRole(QPalette::ToolTipBase);
QFont font;
font.setPointSizeF(8.34563465);
setFont(font);
@ -22,9 +26,7 @@ TipLabel::TipLabel(QWidget *parent) : QLabel(parent, Qt::ToolTip | Qt::Frameless
setPalette(palette);
ensurePolished();
setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, nullptr, this));
setAttribute(Qt::WA_ShowWithoutActivating);
setTextFormat(Qt::RichText);
setVisible(false);
}
void TipLabel::showText(const QPoint &pt, const QString &text, QWidget *w, const QRect &rect) {

@ -198,7 +198,7 @@ void MainWindow::createDockWidgets() {
video_splitter->restoreState(settings.video_splitter_state);
video_splitter->handle(1)->setEnabled(!can->liveStreaming());
video_dock->setWidget(video_splitter);
QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts);
QObject::connect(charts_widget, &ChartsWidget::toggleChartsDocking, this, &MainWindow::toggleChartsDocking);
}
void MainWindow::createStatusBar() {
@ -577,20 +577,31 @@ void MainWindow::updateStatus() {
status_label->setText(tr("Cached Minutes:%1 FPS:%2").arg(settings.max_cached_minutes).arg(settings.fps));
}
void MainWindow::dockCharts(bool dock) {
if (dock && floating_window) {
floating_window->removeEventFilter(charts_widget);
bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
if (obj == floating_window && event->type() == QEvent::Close) {
toggleChartsDocking();
return true;
}
return QMainWindow::eventFilter(obj, event);
}
void MainWindow::toggleChartsDocking() {
if (floating_window) {
// Dock the charts widget back to the main window
floating_window->removeEventFilter(this);
charts_layout->insertWidget(0, charts_widget, 1);
floating_window->deleteLater();
floating_window = nullptr;
} else if (!dock && !floating_window) {
floating_window = new QWidget(this);
floating_window->setWindowFlags(Qt::Window);
charts_widget->setIsDocked(true);
} else {
// Float the charts widget in a separate window
floating_window = new QWidget(this, Qt::Window);
floating_window->setWindowTitle("Charts");
floating_window->setLayout(new QVBoxLayout());
floating_window->layout()->addWidget(charts_widget);
floating_window->installEventFilter(charts_widget);
floating_window->installEventFilter(this);
floating_window->showMaximized();
charts_widget->setIsDocked(false);
}
}

@ -21,7 +21,7 @@ class MainWindow : public QMainWindow {
public:
MainWindow();
void dockCharts(bool dock);
void toggleChartsDocking();
void showStatusMessage(const QString &msg, int timeout = 0) { statusBar()->showMessage(msg, timeout); }
void loadFile(const QString &fn, SourceSet s = SOURCE_ALL);
ChartsWidget *charts_widget = nullptr;
@ -46,6 +46,7 @@ signals:
void updateProgressBar(uint64_t cur, uint64_t total, bool success);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void remindSaveChanges();
void closeFile(SourceSet s = SOURCE_ALL);
void closeFile(DBCFile *dbc_file);

Loading…
Cancel
Save