diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index 26fecd8c38..91353e9726 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -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() { diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 0f58e9ed20..060a2eef7f 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -61,6 +61,7 @@ public: void highlight(const Signal *sig); const Signal *hoveredSignal() const { return hovered_sig; } QSet getOverlappingSignals() const; + QSize sizeHint() const override; signals: void signalHovered(const Signal *sig); diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 8839cdd509..69b420483d 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -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(QObject::sender()); for (auto f : signals_container->findChildren()) { diff --git a/tools/cabana/detailwidget.h b/tools/cabana/detailwidget.h index 4ec74eca7e..3f042bf2b8 100644 --- a/tools/cabana/detailwidget.h +++ b/tools/cabana/detailwidget.h @@ -2,11 +2,21 @@ #include #include +#include #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; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index f127e5f52b..71ec873551 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -3,14 +3,13 @@ #include #include #include -#include #include #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"); 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); diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index 63f704dcc8..b77744ba9c 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #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;