Skip to content

Commit 74a1f1a

Browse files
committed
replace hardcoded margins, colors, spacing
improve performance of MessageBytesDelegate
1 parent 608ac25 commit 74a1f1a

8 files changed

+68
-38
lines changed

tools/cabana/binaryview.cc

+2-5
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ void BinaryViewModel::updateState() {
293293
double max_f = 255.0;
294294
double factor = 0.25;
295295
double scaler = max_f / log2(1.0 + factor);
296-
char hex[3] = {'\0'};
297296
for (int i = 0; i < binary.size(); ++i) {
298297
for (int j = 0; j < 8; ++j) {
299298
auto &item = items[i * column_count + j];
@@ -305,9 +304,7 @@ void BinaryViewModel::updateState() {
305304
double alpha = std::clamp(offset + log2(1.0 + factor * (double)n / (double)last_msg.count) * scaler, min_f, max_f);
306305
item.bg_color.setAlpha(alpha);
307306
}
308-
hex[0] = toHex(binary[i] >> 4);
309-
hex[1] = toHex(binary[i] & 0xf);
310-
items[i * column_count + 8].val = hex;
307+
items[i * column_count + 8].val = toHex(binary[i]);
311308
items[i * column_count + 8].bg_color = last_msg.colors[i];
312309
}
313310
for (int i = binary.size() * column_count; i < items.size(); ++i) {
@@ -375,7 +372,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
375372
bg.setAlpha(std::max(50, bg.alpha()));
376373
}
377374
painter->fillRect(option.rect, bg);
378-
painter->setPen(Qt::black);
375+
painter->setPen(option.palette.color(QPalette::Text));
379376
}
380377
}
381378

tools/cabana/chartswidget.cc

+12-9
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
2525

2626
// toolbar
2727
QToolBar *toolbar = new QToolBar(tr("Charts"), this);
28-
toolbar->setIconSize({16, 16});
28+
int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize);
29+
toolbar->setIconSize({icon_size, icon_size});
2930

3031
QAction *new_plot_btn = toolbar->addAction(utils::icon("file-plus"), tr("New Plot"));
3132
toolbar->addWidget(title_label = new QLabel());
32-
title_label->setContentsMargins(0, 0, 12, 0);
33+
title_label->setContentsMargins(0, 0, style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0);
3334

3435
QMenu *menu = new QMenu(this);
3536
for (int i = 0; i < MAX_COLUMN_COUNT; ++i) {
@@ -77,8 +78,8 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
7778
main_layout->addWidget(charts_scroll);
7879

7980
// init settings
80-
use_dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() >
81-
QApplication::style()->standardPalette().color(QPalette::Background).value();
81+
use_dark_theme = QApplication::palette().color(QPalette::WindowText).value() >
82+
QApplication::palette().color(QPalette::Background).value();
8283
column_count = std::clamp(settings.chart_column_count, 1, MAX_COLUMN_COUNT);
8384
max_chart_range = std::clamp(settings.chart_range, 1, settings.max_cached_minutes * 60);
8485
display_range = {0, max_chart_range};
@@ -322,7 +323,7 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
322323
chart->setMargins({0, 0, 0, 0});
323324

324325
background = new QGraphicsRectItem(chart);
325-
background->setBrush(Qt::white);
326+
background->setBrush(QApplication::palette().color(QPalette::Base));
326327
background->setPen(Qt::NoPen);
327328
background->setZValue(chart->zValue() - 1);
328329

@@ -443,10 +444,12 @@ void ChartView::manageSeries() {
443444

444445
void ChartView::resizeEvent(QResizeEvent *event) {
445446
updatePlotArea(align_to);
446-
int x = event->size().width() - close_btn_proxy->size().width() - 11;
447-
close_btn_proxy->setPos(x, 8);
448-
manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - 5, 8);
449-
move_icon->setPos(11, 8);
447+
int top_margin = style()->pixelMetric(QStyle::PM_LayoutTopMargin);
448+
int spacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
449+
int x = event->size().width() - close_btn_proxy->size().width() - style()->pixelMetric(QStyle::PM_LayoutRightMargin);
450+
close_btn_proxy->setPos(x, top_margin);
451+
manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - spacing, top_margin);
452+
move_icon->setPos(style()->pixelMetric(QStyle::PM_LayoutLeftMargin), top_margin);
450453
QChartView::resizeEvent(event);
451454
}
452455

tools/cabana/historylog.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ QVariant HistoryLogModel::data(const QModelIndex &index, int role) const {
1515
return QString::number((m.mono_time / (double)1e9) - can->routeStartTime(), 'f', 2);
1616
}
1717
return show_signals ? QString::number(m.sig_values[index.column() - 1]) : toHex(m.data);
18-
} else if (role == Qt::UserRole && index.column() == 1 && !show_signals) {
18+
} else if (role == ColorsRole) {
1919
return QVariant::fromValue(m.colors);
20+
} else if (role == BytesRole) {
21+
return m.data;
2022
}
2123
return {};
2224
}

tools/cabana/mainwin.cc

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ MainWindow::MainWindow() : QMainWindow() {
5858
fingerprint_to_dbc = QJsonDocument::fromJson(json_file.readAll());
5959
}
6060

61+
setStyleSheet(QString(R"(QMainWindow::separator {
62+
width: %1px; /* when vertical */
63+
height: %1px; /* when horizontal */
64+
})").arg(style()->pixelMetric(QStyle::PM_SplitterWidth)));
65+
6166
QObject::connect(this, &MainWindow::showMessage, statusBar(), &QStatusBar::showMessage);
6267
QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress);
6368
QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, center_widget, &CenterWidget::setMessage);

tools/cabana/messageswidget.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const {
129129
case 4: return can_data.count;
130130
case 5: return toHex(can_data.dat);
131131
}
132-
} else if (role == Qt::UserRole && index.column() == 5) {
132+
} else if (role == ColorsRole) {
133133
QVector<QColor> colors = can_data.colors;
134134
if (!suppressed_bytes.empty()) {
135135
for (int i = 0; i < colors.size(); i++) {
@@ -139,6 +139,8 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const {
139139
}
140140
}
141141
return QVariant::fromValue(colors);
142+
} else if (role == BytesRole) {
143+
return can_data.dat;
142144
}
143145
return {};
144146
}

tools/cabana/signaledit.cc

+13-7
Original file line numberDiff line numberDiff line change
@@ -322,19 +322,22 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
322322

323323
// color label
324324
auto bg_color = getColor(item->sig);
325-
QRect rc{option.rect.left(), option.rect.top(), color_label_width, option.rect.height()};
325+
int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
326+
int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
327+
QRect rc{option.rect.left() + h_margin, option.rect.top(), color_label_width, option.rect.height()};
326328
painter->setPen(Qt::NoPen);
327329
painter->setBrush(item->highlight ? bg_color.darker(125) : bg_color);
328-
painter->drawRoundedRect(rc.adjusted(0, 2, 0, -2), 3, 3);
330+
painter->drawRoundedRect(rc.adjusted(0, v_margin, 0, -v_margin), 3, 3);
329331
painter->setPen(item->highlight ? Qt::white : Qt::black);
330332
painter->setFont(small_font);
331333
painter->drawText(rc, Qt::AlignCenter, QString::number(item->row() + 1));
332334

333335
// signal name
334336
painter->setFont(option.font);
335-
painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color());
337+
painter->setPen(option.palette.color(option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text));
336338
QString text = index.data(Qt::DisplayRole).toString();
337-
QRect text_rect = option.rect.adjusted(rc.width() + 6, 0, 0, 0);
339+
QRect text_rect = option.rect;
340+
text_rect.setLeft(rc.right() + h_margin * 2);
338341
text = painter->fontMetrics().elidedText(text, Qt::ElideRight, text_rect.width());
339342
painter->drawText(text_rect, option.displayAlignment, text);
340343
painter->restore();
@@ -343,7 +346,7 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
343346
if (option.state & QStyle::State_Selected) {
344347
painter->fillRect(option.rect, option.palette.highlight());
345348
}
346-
painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color());
349+
painter->setPen(option.palette.color(option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text));
347350
QRect rc = option.rect.adjusted(0, 0, -70, 0);
348351
auto text = painter->fontMetrics().elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, rc.width());
349352
painter->drawText(rc, Qt::AlignRight | Qt::AlignVCenter, text);
@@ -442,8 +445,11 @@ void SignalView::rowsChanged() {
442445
if (!tree->indexWidget(index)) {
443446
QWidget *w = new QWidget(this);
444447
QHBoxLayout *h = new QHBoxLayout(w);
445-
h->setContentsMargins(0, 2, 0, 2);
446-
h->addStretch(1);
448+
int v_margin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
449+
int h_margin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
450+
h->setContentsMargins(0, v_margin, -h_margin, v_margin);
451+
h->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing));
452+
h->addStretch(0);
447453

448454
auto remove_btn = toolButton("x", tr("Remove signal"));
449455
auto plot_btn = toolButton("graph-up", "");

tools/cabana/util.cc

+23-13
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,26 @@ void ChangeTracker::clear() {
7171

7272
MessageBytesDelegate::MessageBytesDelegate(QObject *parent) : QStyledItemDelegate(parent) {
7373
fixed_font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
74+
byte_width = QFontMetrics(fixed_font).width("00 ");
7475
}
7576

7677
void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
78+
auto colors = index.data(ColorsRole).value<QVector<QColor>>();
79+
auto byte_list = index.data(BytesRole).toByteArray();
80+
81+
int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
82+
int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
83+
QRect rc{option.rect.left() + h_margin, option.rect.top() + v_margin, byte_width, option.rect.height() - 2 * v_margin};
84+
7785
auto color_role = option.state & QStyle::State_Selected ? QPalette::HighlightedText: QPalette::Text;
7886
painter->setPen(option.palette.color(color_role));
7987
painter->setFont(fixed_font);
80-
int space = painter->boundingRect(option.rect, option.displayAlignment, " ").width();
81-
QRect pos = painter->boundingRect(option.rect, option.displayAlignment, "00").adjusted(0, 0, 2, 0);
82-
pos.moveLeft(pos.x() + space);
83-
int m = space / 2;
84-
const QMargins margins(m, m, m, m);
85-
86-
auto colors = index.data(Qt::UserRole).value<QVector<QColor>>();
87-
auto byte_list = index.data(Qt::DisplayRole).toString().split(" ");
8888
for (int i = 0; i < byte_list.size(); ++i) {
8989
if (i < colors.size() && colors[i].alpha() > 0) {
90-
painter->fillRect(pos.marginsAdded(margins), colors[i]);
90+
painter->fillRect(rc, colors[i]);
9191
}
92-
painter->drawText(pos, Qt::AlignCenter, byte_list[i]);
93-
pos.moveLeft(pos.right() + space);
92+
painter->drawText(rc, Qt::AlignCenter, toHex(byte_list[i]));
93+
rc.moveLeft(rc.right() + 1);
9494
}
9595
}
9696

@@ -114,8 +114,8 @@ QValidator::State NameValidator::validate(QString &input, int &pos) const {
114114

115115
namespace utils {
116116
QPixmap icon(const QString &id) {
117-
static bool dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() >
118-
QApplication::style()->standardPalette().color(QPalette::Background).value();
117+
static bool dark_theme = QApplication::palette().color(QPalette::WindowText).value() >
118+
QApplication::palette().color(QPalette::Background).value();
119119
QPixmap pm;
120120
QString key = "bootstrap_" % id % (dark_theme ? "1" : "0");
121121
if (!QPixmapCache::find(key, &pm)) {
@@ -138,3 +138,13 @@ QToolButton *toolButton(const QString &icon, const QString &tooltip) {
138138
btn->setAutoRaise(true);
139139
return btn;
140140
};
141+
142+
143+
QString toHex(uint8_t byte) {
144+
static std::array<QString, 256> hex = []() {
145+
std::array<QString, 256> ret;
146+
for (int i = 0; i < 256; ++i) ret[i] = QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper();
147+
return ret;
148+
}();
149+
return hex[byte];
150+
}

tools/cabana/util.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "tools/cabana/dbcmanager.h"
1515
using namespace dbcmanager;
1616

17-
1817
class ChangeTracker {
1918
public:
2019
void compute(const QByteArray &dat, double ts, uint32_t freq);
@@ -31,16 +30,22 @@ class ChangeTracker {
3130
QByteArray prev_dat;
3231
};
3332

33+
enum {
34+
ColorsRole = Qt::UserRole + 1,
35+
BytesRole = Qt::UserRole + 2
36+
};
37+
3438
class MessageBytesDelegate : public QStyledItemDelegate {
3539
Q_OBJECT
3640
public:
3741
MessageBytesDelegate(QObject *parent);
3842
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
3943
QFont fixed_font;
44+
int byte_width;
4045
};
4146

4247
inline QString toHex(const QByteArray &dat) { return dat.toHex(' ').toUpper(); }
43-
inline char toHex(uint value) { return "0123456789ABCDEF"[value & 0xF]; }
48+
QString toHex(uint8_t byte);
4449
QColor getColor(const dbcmanager::Signal *sig);
4550

4651
class NameValidator : public QRegExpValidator {

0 commit comments

Comments
 (0)