dragonpilot - 基於 openpilot 的開源駕駛輔助系統
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.9 KiB

#include "selfdrive/ui/qt/util.h"
#include <QApplication>
UI: Internationalization support (#21212) * rough multiple language demo * more wrappings * stash * add some bad translations * updates * map from french to spanish still has same problem of needing to call setText on everything * add files * restart UI * use return code * relative path * more translations * don't loop restart * Toggle and prime translations * try on device * try QComboBox with readable style * stash * not yet scrollable * stash * dynamic translations (doesn't work for dynamic widget strings yet) * clean up multiple option selector * store languages in json * try transparent * Try transparent popup * see how this looks * tweaks * clean up * update names * Add Chinese (Simplified) translations * Do missing French translations * unit tests caught that :) * fix test * fix other test (on PC) * add entries to dialog to test * add cancel button, clean up a bit * just chinese * some clean up * use quotes * clean up * Just quit, set timeout to 0 * half a second * use exitcode * don't print if it's expected * this comment is outdated * update translations * Update translations * re-order input classes * Update line numbers * use enabled property for button style * Get rid of ListWidget * Update line numbers * Log failed to load language * Log failed to load language * Move to utils and fix english logging extra line * Update translations * spacing * looks a bit better * try this instead of exitcode fixes fix * only one function * comment * Update line numbers * fixup some japanese translations * clean up multi option dialog * Update line numbers
3 years ago
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLayoutItem>
#include <QStyleOption>
#include <QPainterPath>
#include "common/params.h"
#include "common/swaglog.h"
#include "system/hardware/hw.h"
QString getVersion() {
static QString version = QString::fromStdString(Params().get("Version"));
return version;
}
QString getBrand() {
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("openpilot");
}
QString getBrandVersion() {
return getBrand() + " v" + getVersion().left(14).trimmed();
}
QString getUserAgent() {
return "openpilot-" + getVersion();
}
std::optional<QString> getDongleId() {
std::string id = Params().get("DongleId");
if (!id.empty() && (id != "UnregisteredDevice")) {
return QString::fromStdString(id);
} else {
return {};
}
}
UI: Internationalization support (#21212) * rough multiple language demo * more wrappings * stash * add some bad translations * updates * map from french to spanish still has same problem of needing to call setText on everything * add files * restart UI * use return code * relative path * more translations * don't loop restart * Toggle and prime translations * try on device * try QComboBox with readable style * stash * not yet scrollable * stash * dynamic translations (doesn't work for dynamic widget strings yet) * clean up multiple option selector * store languages in json * try transparent * Try transparent popup * see how this looks * tweaks * clean up * update names * Add Chinese (Simplified) translations * Do missing French translations * unit tests caught that :) * fix test * fix other test (on PC) * add entries to dialog to test * add cancel button, clean up a bit * just chinese * some clean up * use quotes * clean up * Just quit, set timeout to 0 * half a second * use exitcode * don't print if it's expected * this comment is outdated * update translations * Update translations * re-order input classes * Update line numbers * use enabled property for button style * Get rid of ListWidget * Update line numbers * Log failed to load language * Log failed to load language * Move to utils and fix english logging extra line * Update translations * spacing * looks a bit better * try this instead of exitcode fixes fix * only one function * comment * Update line numbers * fixup some japanese translations * clean up multi option dialog * Update line numbers
3 years ago
QMap<QString, QString> getSupportedLanguages() {
QFile f("translations/languages.json");
f.open(QIODevice::ReadOnly | QIODevice::Text);
QString val = f.readAll();
QJsonObject obj = QJsonDocument::fromJson(val.toUtf8()).object();
QMap<QString, QString> map;
for (auto key : obj.keys()) {
map[key] = obj[key].toString();
}
return map;
}
void configFont(QPainter &p, const QString &family, int size, const QString &style) {
QFont f(family);
f.setPixelSize(size);
f.setStyleName(style);
p.setFont(f);
}
void clearLayout(QLayout* layout) {
while (QLayoutItem* item = layout->takeAt(0)) {
if (QWidget* widget = item->widget()) {
widget->deleteLater();
}
if (QLayout* childLayout = item->layout()) {
clearLayout(childLayout);
}
delete item;
}
}
QString timeAgo(const QDateTime &date) {
int diff = date.secsTo(QDateTime::currentDateTimeUtc());
QString s;
if (diff < 60) {
s = "now";
} else if (diff < 60 * 60) {
int minutes = diff / 60;
s = QObject::tr("%n minute(s) ago", "", minutes);
} else if (diff < 60 * 60 * 24) {
int hours = diff / (60 * 60);
s = QObject::tr("%n hour(s) ago", "", hours);
} else if (diff < 3600 * 24 * 7) {
int days = diff / (60 * 60 * 24);
s = QObject::tr("%n day(s) ago", "", days);
} else {
s = date.date().toString();
}
return s;
}
void setQtSurfaceFormat() {
QSurfaceFormat fmt;
#ifdef __APPLE__
fmt.setVersion(3, 2);
fmt.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
#else
fmt.setRenderableType(QSurfaceFormat::OpenGLES);
#endif
fmt.setSamples(16);
QSurfaceFormat::setDefaultFormat(fmt);
}
void initApp(int argc, char *argv[]) {
Hardware::set_display_power(true);
Hardware::set_brightness(65);
#ifdef __APPLE__
{
// Get the devicePixelRatio, and scale accordingly to maintain 1:1 rendering
QApplication tmp(argc, argv);
qputenv("QT_SCALE_FACTOR", QString::number(1.0 / tmp.devicePixelRatio() ).toLocal8Bit());
}
#endif
setQtSurfaceFormat();
}
void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
static std::map<QtMsgType, int> levels = {
{QtMsgType::QtDebugMsg, CLOUDLOG_DEBUG},
{QtMsgType::QtInfoMsg, CLOUDLOG_INFO},
{QtMsgType::QtWarningMsg, CLOUDLOG_WARNING},
{QtMsgType::QtCriticalMsg, CLOUDLOG_ERROR},
{QtMsgType::QtSystemMsg, CLOUDLOG_ERROR},
{QtMsgType::QtFatalMsg, CLOUDLOG_CRITICAL},
};
std::string file, function;
if (context.file != nullptr) file = context.file;
if (context.function != nullptr) function = context.function;
auto bts = msg.toUtf8();
cloudlog_e(levels[type], file.c_str(), context.line, function.c_str(), "%s", bts.constData());
}
QWidget* topWidget (QWidget* widget) {
while (widget->parentWidget() != nullptr) widget=widget->parentWidget();
return widget;
}
QPixmap loadPixmap(const QString &fileName, const QSize &size, Qt::AspectRatioMode aspectRatioMode) {
if (size.isEmpty()) {
return QPixmap(fileName);
} else {
return QPixmap(fileName).scaled(size, aspectRatioMode, Qt::SmoothTransformation);
}
}
QRect getTextRect(QPainter &p, int flags, QString text) {
QFontMetrics fm(p.font());
QRect init_rect = fm.boundingRect(text);
return fm.boundingRect(init_rect, flags, text);
}
void drawRoundedRect(QPainter &painter, const QRectF &rect, qreal xRadiusTop, qreal yRadiusTop, qreal xRadiusBottom, qreal yRadiusBottom){
qreal w_2 = rect.width() / 2;
qreal h_2 = rect.height() / 2;
xRadiusTop = 100 * qMin(xRadiusTop, w_2) / w_2;
yRadiusTop = 100 * qMin(yRadiusTop, h_2) / h_2;
xRadiusBottom = 100 * qMin(xRadiusBottom, w_2) / w_2;
yRadiusBottom = 100 * qMin(yRadiusBottom, h_2) / h_2;
qreal x = rect.x();
qreal y = rect.y();
qreal w = rect.width();
qreal h = rect.height();
qreal rxx2Top = w*xRadiusTop/100;
qreal ryy2Top = h*yRadiusTop/100;
qreal rxx2Bottom = w*xRadiusBottom/100;
qreal ryy2Bottom = h*yRadiusBottom/100;
QPainterPath path;
path.arcMoveTo(x, y, rxx2Top, ryy2Top, 180);
path.arcTo(x, y, rxx2Top, ryy2Top, 180, -90);
path.arcTo(x+w-rxx2Top, y, rxx2Top, ryy2Top, 90, -90);
path.arcTo(x+w-rxx2Bottom, y+h-ryy2Bottom, rxx2Bottom, ryy2Bottom, 0, -90);
path.arcTo(x, y+h-ryy2Bottom, rxx2Bottom, ryy2Bottom, 270, -90);
path.closeSubpath();
painter.drawPath(path);
}
QColor interpColor(float xv, std::vector<float> xp, std::vector<QColor> fp) {
assert(xp.size() == fp.size());
int N = xp.size();
int hi = 0;
while (hi < N and xv > xp[hi]) hi++;
int low = hi - 1;
if (hi == N && xv > xp[low]) {
return fp[fp.size() - 1];
} else if (hi == 0){
return fp[0];
} else {
return QColor(
(xv - xp[low]) * (fp[hi].red() - fp[low].red()) / (xp[hi] - xp[low]) + fp[low].red(),
(xv - xp[low]) * (fp[hi].green() - fp[low].green()) / (xp[hi] - xp[low]) + fp[low].green(),
(xv - xp[low]) * (fp[hi].blue() - fp[low].blue()) / (xp[hi] - xp[low]) + fp[low].blue(),
(xv - xp[low]) * (fp[hi].alpha() - fp[low].alpha()) / (xp[hi] - xp[low]) + fp[low].alpha()
);
}
}