mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-03-02 00:53:53 +08:00
cabana: fix chart value tip flickers when the mouse moves over it (#32796)
fix chart value tip flickers
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user