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: 5aa0d211f075681e18395d0fd7dd73d8cc44573c
This commit is contained in:
@@ -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);
|
||||
|
||||
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
|
||||
QFrame *title_frame = new QFrame();
|
||||
main_layout->addWidget(title_frame);
|
||||
QVBoxLayout *frame_layout = new QVBoxLayout(title_frame);
|
||||
title_frame->setFrameShape(QFrame::StyledPanel);
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user