cabana: use bootstrap icons (#26981)
* use bootstrap icons * typo * build into asset_obj * add to files_common old-commit-hash: c21d9408a191ba8e3303f2459d1f7476fefd35ba
This commit is contained in:
@@ -282,7 +282,7 @@ Export('envCython')
|
||||
|
||||
# Qt build environment
|
||||
qt_env = env.Clone()
|
||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus"]
|
||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus", "Xml"]
|
||||
|
||||
qt_libs = []
|
||||
if arch == "Darwin":
|
||||
|
||||
@@ -436,6 +436,7 @@ third_party/acados/larch64/**
|
||||
third_party/acados/include/**
|
||||
third_party/acados/acados_template/**
|
||||
|
||||
third_party/bootstrap/**
|
||||
third_party/qt5/larch64/bin/**
|
||||
|
||||
scripts/update_now.sh
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="bootstrap-icons.svg">../../third_party/bootstrap/bootstrap-icons.svg</file>
|
||||
<file>img_continue_triangle.svg</file>
|
||||
<file>img_circled_check.svg</file>
|
||||
<file>img_circled_slash.svg</file>
|
||||
|
||||
@@ -41,6 +41,7 @@ assets_src = "#selfdrive/assets/assets.qrc"
|
||||
qt_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET")
|
||||
qt_env.Depends(assets, Glob('#selfdrive/assets/*', exclude=[assets, assets_src, "#selfdrive/assets/assets.o"]))
|
||||
asset_obj = qt_env.Object("assets", assets)
|
||||
Export('asset_obj')
|
||||
|
||||
# build soundd
|
||||
qt_env.Program("soundd/_soundd", ["soundd/main.cc", "soundd/sound.cc"], LIBS=qt_libs)
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLayoutItem>
|
||||
#include <QStyleOption>
|
||||
#include <QPainterPath>
|
||||
#include <QTextStream>
|
||||
#include <QtXml/QDomDocument>
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/swaglog.h"
|
||||
@@ -218,3 +221,37 @@ QColor interpColor(float xv, std::vector<float> xp, std::vector<QColor> fp) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static QHash<QString, QByteArray> load_bootstrap_icons() {
|
||||
QHash<QString, QByteArray> icons;
|
||||
|
||||
QFile f(":/bootstrap-icons.svg");
|
||||
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QDomDocument xml;
|
||||
xml.setContent(&f);
|
||||
QDomNode n = xml.documentElement().firstChild();
|
||||
while (!n.isNull()) {
|
||||
QDomElement e = n.toElement();
|
||||
if (!e.isNull() && e.hasAttribute("id")) {
|
||||
QString svg_str;
|
||||
QTextStream stream(&svg_str);
|
||||
n.save(stream, 0);
|
||||
svg_str.replace("<symbol", "<svg");
|
||||
svg_str.replace("</symbol>", "</svg>");
|
||||
icons[e.attribute("id")] = svg_str.toUtf8();
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
}
|
||||
return icons;
|
||||
}
|
||||
|
||||
QPixmap bootstrapPixmap(const QString &id) {
|
||||
static QHash<QString, QByteArray> icons = load_bootstrap_icons();
|
||||
|
||||
QPixmap pixmap;
|
||||
if (auto it = icons.find(id); it != icons.end()) {
|
||||
pixmap.loadFromData(it.value(), "svg");
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, co
|
||||
void initApp(int argc, char *argv[]);
|
||||
QWidget* topWidget (QWidget* widget);
|
||||
QPixmap loadPixmap(const QString &fileName, const QSize &size = {}, Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
|
||||
QPixmap bootstrapPixmap(const QString &id);
|
||||
|
||||
QRect getTextRect(QPainter &p, int flags, const QString &text);
|
||||
void drawRoundedRect(QPainter &painter, const QRectF &rect, qreal xRadiusTop, qreal yRadiusTop, qreal xRadiusBottom, qreal yRadiusBottom);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
Import('env', 'qt_env', 'arch', 'common', 'messaging', 'visionipc', 'replay_lib',
|
||||
'cereal', 'transformations', 'widgets', 'opendbc')
|
||||
'cereal', 'transformations', 'widgets', 'opendbc', 'asset_obj')
|
||||
|
||||
base_frameworks = qt_env['FRAMEWORKS']
|
||||
base_libs = [common, messaging, cereal, visionipc, transformations, 'zmq',
|
||||
@@ -22,7 +22,7 @@ prev_moc_path = cabana_env['QT_MOCHPREFIX']
|
||||
cabana_env['QT_MOCHPREFIX'] = os.path.dirname(prev_moc_path) + '/cabana/moc_'
|
||||
cabana_lib = cabana_env.Library("cabana_lib", ['mainwin.cc', 'binaryview.cc', 'chartswidget.cc', 'historylog.cc', 'videowidget.cc', 'signaledit.cc', 'dbcmanager.cc',
|
||||
'canmessages.cc', 'commands.cc', 'messageswidget.cc', 'settings.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
cabana_env.Program('_cabana', ['cabana.cc', cabana_lib], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
cabana_env.Program('_cabana', ['cabana.cc', cabana_lib, asset_obj], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
|
||||
if GetOption('test'):
|
||||
cabana_env.Program('tests/_test_cabana', ['tests/test_runner.cc', 'tests/test_cabana.cc', cabana_lib], LIBS=[cabana_libs])
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <QToolTip>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
// ChartsWidget
|
||||
|
||||
ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
@@ -19,14 +21,15 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
|
||||
|
||||
// toolbar
|
||||
QToolBar *toolbar = new QToolBar(tr("Charts"), this);
|
||||
toolbar->setIconSize({16, 16});
|
||||
title_label = new QLabel();
|
||||
title_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
toolbar->addWidget(title_label);
|
||||
show_all_values_btn = toolbar->addAction("");
|
||||
toolbar->addWidget(range_label = new QLabel());
|
||||
reset_zoom_btn = toolbar->addAction("⟲");
|
||||
reset_zoom_btn = toolbar->addAction(bootstrapPixmap("arrow-counterclockwise"), "");
|
||||
reset_zoom_btn->setToolTip(tr("Reset zoom (drag on chart to zoom X-Axis)"));
|
||||
remove_all_btn = toolbar->addAction("✖");
|
||||
remove_all_btn = toolbar->addAction(bootstrapPixmap("x"), "");
|
||||
remove_all_btn->setToolTip(tr("Remove all charts"));
|
||||
dock_btn = toolbar->addAction("");
|
||||
main_layout->addWidget(toolbar);
|
||||
@@ -137,7 +140,7 @@ void ChartsWidget::updateToolBar() {
|
||||
reset_zoom_btn->setEnabled(is_zoomed);
|
||||
range_label->setText(is_zoomed ? tr("%1 - %2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : "");
|
||||
title_label->setText(charts.size() > 0 ? tr("Charts (%1)").arg(charts.size()) : tr("Charts"));
|
||||
dock_btn->setText(docking ? "⬈" : "⬋");
|
||||
dock_btn->setIcon(bootstrapPixmap(docking ? "arrow-up-right" : "arrow-down-left"));
|
||||
dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts"));
|
||||
}
|
||||
|
||||
@@ -223,7 +226,7 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
chart->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QToolButton *remove_btn = new QToolButton();
|
||||
remove_btn->setText("X");
|
||||
remove_btn->setIcon(bootstrapPixmap("x"));
|
||||
remove_btn->setAutoRaise(true);
|
||||
remove_btn->setToolTip(tr("Remove Chart"));
|
||||
close_btn_proxy = new QGraphicsProxyWidget(chart);
|
||||
@@ -231,7 +234,7 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
close_btn_proxy->setZValue(chart->zValue() + 11);
|
||||
|
||||
QToolButton *manage_btn = new QToolButton();
|
||||
manage_btn->setText("🔧");
|
||||
manage_btn->setIcon(bootstrapPixmap("gear"));
|
||||
manage_btn->setAutoRaise(true);
|
||||
manage_btn->setToolTip(tr("Manage series"));
|
||||
manage_btn_proxy = new QGraphicsProxyWidget(chart);
|
||||
|
||||
@@ -36,6 +36,7 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart
|
||||
|
||||
// message title
|
||||
toolbar = new QToolBar(this);
|
||||
toolbar->setIconSize({16, 16});
|
||||
toolbar->addWidget(new QLabel("time:"));
|
||||
time_label = new QLabel(this);
|
||||
time_label->setStyleSheet("font-weight:bold");
|
||||
@@ -45,8 +46,8 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart
|
||||
name_label->setAlignment(Qt::AlignCenter);
|
||||
name_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
toolbar->addWidget(name_label);
|
||||
toolbar->addAction("🖍", this, &DetailWidget::editMsg)->setToolTip(tr("Edit Message"));
|
||||
remove_msg_act = toolbar->addAction("X", this, &DetailWidget::removeMsg);
|
||||
toolbar->addAction(bootstrapPixmap("pencil"), "", this, &DetailWidget::editMsg)->setToolTip(tr("Edit Message"));
|
||||
remove_msg_act = toolbar->addAction(bootstrapPixmap("x-lg"), "", this, &DetailWidget::removeMsg);
|
||||
remove_msg_act->setToolTip(tr("Remove Message"));
|
||||
toolbar->setVisible(false);
|
||||
frame_layout->addWidget(toolbar);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
// SignalForm
|
||||
|
||||
SignalForm::SignalForm(QWidget *parent) : QWidget(parent) {
|
||||
@@ -104,13 +106,13 @@ SignalEdit::SignalEdit(int index, QWidget *parent) : form_idx(index), QWidget(pa
|
||||
title_layout->addWidget(title);
|
||||
|
||||
plot_btn = new QToolButton(this);
|
||||
plot_btn->setText("📈");
|
||||
plot_btn->setIcon(bootstrapPixmap("graph-up"));
|
||||
plot_btn->setCheckable(true);
|
||||
plot_btn->setAutoRaise(true);
|
||||
title_layout->addWidget(plot_btn);
|
||||
auto remove_btn = new QToolButton(this);
|
||||
remove_btn->setAutoRaise(true);
|
||||
remove_btn->setText("x");
|
||||
remove_btn->setIcon(bootstrapPixmap("x"));
|
||||
remove_btn->setToolTip(tr("Remove signal"));
|
||||
title_layout->addWidget(remove_btn);
|
||||
main_layout->addWidget(title_bar);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
inline QString formatTime(int seconds) {
|
||||
return QDateTime::fromTime_t(seconds).toString(seconds > 60 * 60 ? "hh:mm:ss" : "mm:ss");
|
||||
}
|
||||
@@ -43,8 +45,7 @@ VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) {
|
||||
|
||||
// btn controls
|
||||
QHBoxLayout *control_layout = new QHBoxLayout();
|
||||
play_btn = new QPushButton("⏸");
|
||||
play_btn->setStyleSheet("font-weight:bold; height:16px");
|
||||
play_btn = new QPushButton();
|
||||
control_layout->addWidget(play_btn);
|
||||
|
||||
QButtonGroup *group = new QButtonGroup(this);
|
||||
@@ -68,12 +69,13 @@ VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) {
|
||||
QObject::connect(cam_widget, &CameraWidget::clicked, []() { can->pause(!can->isPaused()); });
|
||||
QObject::connect(play_btn, &QPushButton::clicked, []() { can->pause(!can->isPaused()); });
|
||||
QObject::connect(can, &CANMessages::updated, this, &VideoWidget::updateState);
|
||||
QObject::connect(can, &CANMessages::paused, [this]() { play_btn->setText("▶"); });
|
||||
QObject::connect(can, &CANMessages::resume, [this]() { play_btn->setText("⏸"); });
|
||||
QObject::connect(can, &CANMessages::paused, this, &VideoWidget::updatePlayBtnState);
|
||||
QObject::connect(can, &CANMessages::resume, this, &VideoWidget::updatePlayBtnState);
|
||||
QObject::connect(can, &CANMessages::streamStarted, [this]() {
|
||||
end_time_label->setText(formatTime(can->totalSeconds()));
|
||||
slider->setRange(0, can->totalSeconds() * 1000);
|
||||
});
|
||||
updatePlayBtnState();
|
||||
}
|
||||
|
||||
void VideoWidget::rangeChanged(double min, double max, bool is_zoomed) {
|
||||
@@ -90,6 +92,11 @@ void VideoWidget::updateState() {
|
||||
slider->setValue(can->currentSec() * 1000);
|
||||
}
|
||||
|
||||
void VideoWidget::updatePlayBtnState() {
|
||||
play_btn->setIcon(bootstrapPixmap(can->isPaused() ? "play" : "pause"));
|
||||
play_btn->setToolTip(can->isPaused() ? tr("Play") : tr("Pause"));
|
||||
}
|
||||
|
||||
// Slider
|
||||
Slider::Slider(QWidget *parent) : QSlider(Qt::Horizontal, parent) {
|
||||
QTimer *timer = new QTimer(this);
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
protected:
|
||||
void updateState();
|
||||
void updatePlayBtnState();
|
||||
|
||||
CameraWidget *cam_widget;
|
||||
QLabel *end_time_label;
|
||||
|
||||
Reference in New Issue
Block a user