Cabana: double click the title bar to move binview to a separate column (#26280)

* double click to move binview to seperate column

* cleanup

* double click frame

* continue

* rename signal

* add tooltip

* fix layout

* don't show last cell's  bottom line

* increase spliter handle size

* cleanup

* set resize mode to ResizeToContents

* add a split button

* cleanup layout&fix space

* cleanup

* remove hardcoded size

* cleanup
old-commit-hash: 5aa0d211f0
taco
Dean Lee 3 years ago committed by GitHub
parent b061e768be
commit 881273fe19
  1. 12
      tools/cabana/binaryview.cc
  2. 1
      tools/cabana/binaryview.h
  3. 52
      tools/cabana/detailwidget.cc
  4. 17
      tools/cabana/detailwidget.h
  5. 14
      tools/cabana/mainwin.cc
  6. 4
      tools/cabana/mainwin.h

@ -20,13 +20,15 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) {
setItemDelegate(delegate);
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
horizontalHeader()->hide();
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setMouseTracking(true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
}
QObject::connect(model, &QAbstractItemModel::modelReset, [this]() {
setFixedHeight((CELL_HEIGHT + 1) * std::min(model->rowCount(), 8) + 2);
});
QSize BinaryView::sizeHint() const {
QSize sz = QTableView::sizeHint();
return {sz.width(), model->rowCount() <= 8 ? ((CELL_HEIGHT + 1) * model->rowCount() + 2) : sz.height()};
}
void BinaryView::highlight(const Signal *sig) {
@ -108,9 +110,9 @@ void BinaryView::leaveEvent(QEvent *event) {
void BinaryView::setMessage(const QString &message_id) {
msg_id = message_id;
model->setMessage(message_id);
resizeRowsToContents();
clearSelection();
updateState();
updateGeometry();
}
void BinaryView::updateState() {

@ -61,6 +61,7 @@ public:
void highlight(const Signal *sig);
const Signal *hoveredSignal() const { return hovered_sig; }
QSet<const Signal*> getOverlappingSignals() const;
QSize sizeHint() const override;
signals:
void signalHovered(const Signal *sig);

@ -13,10 +13,18 @@
// DetailWidget
DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout = new QHBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
main_layout->setSpacing(0);
right_column = new QVBoxLayout();
main_layout->addLayout(right_column);
binary_view_container = new QWidget(this);
binary_view_container->setMinimumWidth(500);
binary_view_container->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
QVBoxLayout *bin_layout = new QVBoxLayout(binary_view_container);
bin_layout->setContentsMargins(0, 0, 0, 0);
bin_layout->setSpacing(0);
// tabbar
tabbar = new QTabBar(this);
tabbar->setTabsClosable(true);
@ -24,14 +32,19 @@ DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent) {
tabbar->setUsesScrollButtons(true);
tabbar->setAutoHide(true);
tabbar->setContextMenuPolicy(Qt::CustomContextMenu);
main_layout->addWidget(tabbar);
bin_layout->addWidget(tabbar);
// message title
QFrame *title_frame = new QFrame();
main_layout->addWidget(title_frame);
QVBoxLayout *frame_layout = new QVBoxLayout(title_frame);
TitleFrame *title_frame = new TitleFrame(this);
title_frame->setFrameShape(QFrame::StyledPanel);
title_frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QVBoxLayout *frame_layout = new QVBoxLayout(title_frame);
// message title
QHBoxLayout *title_layout = new QHBoxLayout();
split_btn = new QPushButton("", this);
split_btn->setFixedSize(20, 20);
split_btn->setToolTip(tr("Split to two columns"));
title_layout->addWidget(split_btn);
title_layout->addWidget(new QLabel("time:"));
time_label = new QLabel(this);
time_label->setStyleSheet("font-weight:bold");
@ -56,10 +69,12 @@ DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent) {
warning_hlayout->addWidget(warning_label, 1, Qt::AlignLeft);
warning_widget->hide();
frame_layout->addWidget(warning_widget);
bin_layout->addWidget(title_frame);
// binary view
binary_view = new BinaryView(this);
main_layout->addWidget(binary_view, 0, Qt::AlignTop);
bin_layout->addWidget(binary_view);
right_column->addWidget(binary_view_container);
// signals
signals_container = new QWidget(this);
@ -70,12 +85,14 @@ DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent) {
scroll->setWidget(signals_container);
scroll->setWidgetResizable(true);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
main_layout->addWidget(scroll);
right_column->addWidget(scroll);
// history log
history_log = new HistoryLog(this);
main_layout->addWidget(history_log);
right_column->addWidget(history_log);
QObject::connect(split_btn, &QPushButton::clicked, this, &DetailWidget::moveBinaryView);
QObject::connect(title_frame, &TitleFrame::doubleClicked, this, &DetailWidget::moveBinaryView);
QObject::connect(edit_btn, &QPushButton::clicked, this, &DetailWidget::editMsg);
QObject::connect(binary_view, &BinaryView::resizeSignal, this, &DetailWidget::resizeSignal);
QObject::connect(binary_view, &BinaryView::addSignal, this, &DetailWidget::addSignal);
@ -112,7 +129,6 @@ void DetailWidget::showTabBarContextMenu(const QPoint &pt) {
void DetailWidget::setMessage(const QString &message_id) {
if (message_id.isEmpty()) return;
qWarning() << "setmessage" << message_id;
int index = -1;
for (int i = 0; i < tabbar->count(); ++i) {
if (tabbar->tabText(i) == message_id) {
@ -182,6 +198,20 @@ void DetailWidget::updateState() {
history_log->updateState();
}
void DetailWidget::moveBinaryView() {
if (binview_in_left_col) {
right_column->insertWidget(0, binary_view_container);
emit binaryViewMoved(true);
} else {
main_layout->insertWidget(0, binary_view_container);
emit binaryViewMoved(false);
}
split_btn->setText(binview_in_left_col ? "" : "");
split_btn->setToolTip(binview_in_left_col ? tr("Split to two columns") : tr("Move back"));
binary_view->updateGeometry();
binview_in_left_col = !binview_in_left_col;
}
void DetailWidget::showForm() {
SignalEdit *sender = qobject_cast<SignalEdit *>(QObject::sender());
for (auto f : signals_container->findChildren<SignalEdit *>()) {

@ -2,11 +2,21 @@
#include <QScrollArea>
#include <QTabBar>
#include <QVBoxLayout>
#include "tools/cabana/binaryview.h"
#include "tools/cabana/historylog.h"
#include "tools/cabana/signaledit.h"
class TitleFrame : public QFrame {
Q_OBJECT
public:
TitleFrame(QWidget *parent) : QFrame(parent) {}
void mouseDoubleClickEvent(QMouseEvent *e) { emit doubleClicked(); }
signals:
void doubleClicked();
};
class EditMessageDialog : public QDialog {
Q_OBJECT
@ -37,6 +47,7 @@ public:
signals:
void showChart(const QString &msg_id, const Signal *sig);
void removeChart(const Signal *sig);
void binaryViewMoved(bool in);
private:
void showTabBarContextMenu(const QPoint &pt);
@ -47,6 +58,7 @@ private:
void editMsg();
void showForm();
void updateState();
void moveBinaryView();
QString msg_id;
QLabel *name_label, *time_label, *warning_label;
@ -54,6 +66,11 @@ private:
QPushButton *edit_btn;
QWidget *signals_container;
QTabBar *tabbar;
QHBoxLayout *main_layout;
QVBoxLayout *right_column;
bool binview_in_left_col = false;
QWidget *binary_view_container;
QPushButton *split_btn;
HistoryLog *history_log;
BinaryView *binary_view;
ScrollArea *scroll;

@ -3,14 +3,13 @@
#include <QApplication>
#include <QHBoxLayout>
#include <QScreen>
#include <QSplitter>
#include <QVBoxLayout>
#include "tools/replay/util.h"
static MainWindow *main_win = nullptr;
void qLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
if (main_win) main_win->showStatusMessage(msg);
if (main_win) emit main_win->showMessage(msg, 0);
}
MainWindow::MainWindow() : QWidget() {
@ -22,15 +21,14 @@ MainWindow::MainWindow() : QWidget() {
h_layout->setContentsMargins(0, 0, 0, 0);
main_layout->addLayout(h_layout);
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
splitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
splitter = new QSplitter(Qt::Horizontal, this);
splitter->setHandleWidth(11);
messages_widget = new MessagesWidget(this);
splitter->addWidget(messages_widget);
detail_widget = new DetailWidget(this);
splitter->addWidget(detail_widget);
splitter->setSizes({100, 500});
h_layout->addWidget(splitter);
// right widgets
@ -74,16 +72,17 @@ MainWindow::MainWindow() : QWidget() {
qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
installMessageHandler([this](ReplyMsgType type, const std::string msg) {
// use queued connection to recv the log messages from replay.
emit logMessageFromReplay(QString::fromStdString(msg), 3000);
emit showMessage(QString::fromStdString(msg), 3000);
});
installDownloadProgressHandler([this](uint64_t cur, uint64_t total, bool success) {
emit updateProgressBar(cur, total, success);
});
QObject::connect(this, &MainWindow::logMessageFromReplay, status_bar, &QStatusBar::showMessage);
QObject::connect(this, &MainWindow::showMessage, status_bar, &QStatusBar::showMessage);
QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress);
QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, detail_widget, &DetailWidget::setMessage);
QObject::connect(detail_widget, &DetailWidget::showChart, charts_widget, &ChartsWidget::addChart);
QObject::connect(detail_widget, &DetailWidget::binaryViewMoved, [this](bool in) { splitter->setSizes({in ? 100 : 0, 500}); });
QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts);
QObject::connect(charts_widget, &ChartsWidget::rangeChanged, video_widget, &VideoWidget::rangeChanged);
QObject::connect(settings_btn, &QPushButton::clicked, this, &MainWindow::setOption);
@ -103,7 +102,6 @@ void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool succe
}
}
void MainWindow::dockCharts(bool dock) {
if (dock && floating_window) {
floating_window->removeEventFilter(charts_widget);

@ -1,6 +1,7 @@
#pragma once
#include <QProgressBar>
#include <QSplitter>
#include <QStatusBar>
#include "tools/cabana/chartswidget.h"
@ -17,7 +18,7 @@ public:
void showStatusMessage(const QString &msg, int timeout = 0) { status_bar->showMessage(msg, timeout); }
signals:
void logMessageFromReplay(const QString &msg, int timeout);
void showMessage(const QString &msg, int timeout);
void updateProgressBar(uint64_t cur, uint64_t total, bool success);
protected:
@ -29,6 +30,7 @@ protected:
MessagesWidget *messages_widget;
DetailWidget *detail_widget;
ChartsWidget *charts_widget;
QSplitter *splitter;
QWidget *floating_window = nullptr;
QVBoxLayout *r_layout;
QProgressBar *progress_bar;

Loading…
Cancel
Save