SLC abbreviated icons

Gives the options to display SLC sources as abbreviated and the option to only show sources with data in them to give a cleaner UI look.
This commit is contained in:
whoisdomi
2026-05-14 10:28:36 -05:00
committed by firestar5683
parent 2f5aef1fb8
commit 70ccc64831
6 changed files with 71 additions and 26 deletions
+2
View File
@@ -491,6 +491,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"SignalMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
{"SignalToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
{"SimpleMode", {PERSISTENT, BOOL, "0", "0", 0}},
{"SLCAbbreviatedSources", {PERSISTENT, BOOL, "0", "0", 3}},
{"SLCActiveSourcesOnly", {PERSISTENT, BOOL, "0", "0", 3}},
{"SLCConfirmation", {PERSISTENT, BOOL, "0", "0", 0}},
{"SLCConfirmationHigher", {PERSISTENT, BOOL, "0", "0", 0}},
{"SLCConfirmationLower", {PERSISTENT, BOOL, "0", "0", 0}},
+2
View File
@@ -1162,6 +1162,8 @@ class StarPilotVariables:
toggle.speed_limit_priority_highest = toggle.speed_limit_priority1 == "Highest"
toggle.speed_limit_priority_lowest = toggle.speed_limit_priority1 == "Lowest"
toggle.speed_limit_sources = self.get_value("SpeedLimitSources", condition=speed_limit_display) or toggle.debug_mode
toggle.slc_abbreviated_sources = self.get_value("SLCAbbreviatedSources", condition=speed_limit_display)
toggle.slc_active_sources_only = self.get_value("SLCActiveSourcesOnly", condition=speed_limit_display)
toggle.speed_limit_filler = self.get_value("SpeedLimitFiller")
toggle.vision_speed_limit_detection = self.get_value("VisionSpeedLimitDetection")
@@ -210,7 +210,9 @@ StarPilotLongitudinalPanel::StarPilotLongitudinalPanel(StarPilotSettingsWindow *
{"Offset7", tr("Speed Offset (7599 mph)"), tr("<b>How much to offset posted speed-limits</b> between 75 and 99 mph."), ""},
{"SLCVisuals", tr("Visual Settings"), tr("<b>Visual \"Speed Limit Controller\" changes</b> to fine-tune how the driving screen looks."), ""},
{"ShowSLCOffset", tr("Show Speed Limit Offset"), tr("<b>Show the current offset from the posted limit</b> on the driving screen."), ""},
{"SpeedLimitSources", tr("Show Speed Limit Sources"), tr("<b>Display the speed-limit sources and their current values</b> on the driving screen."), ""}
{"SpeedLimitSources", tr("Show Speed Limit Sources"), tr("<b>Display the speed-limit sources and their current values</b> on the driving screen."), ""},
{"SLCAbbreviatedSources", tr("Show Abbreviated Icon Sources"), tr("<b>Render the speed-limit sources as compact text labels</b> (e.g. \"Dash-45\", \"MapD-30\") without icons."), ""},
{"SLCActiveSourcesOnly", tr("Only Show Sources With Speed Limits"), tr("<b>Hide source rows that have no current speed limit reading</b>. Works with both abbreviated and full display."), ""}
};
for (const auto &[param, title, desc, icon] : longitudinalToggles) {
@@ -39,7 +39,7 @@ private:
QSet<QString> speedLimitControllerKeys = {"SLCOffsets", "SLCFallback", "SLCOverride", "SLCPriority", "SLCQOL", "SLCVisuals"};
QSet<QString> speedLimitControllerOffsetsKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "Offset5", "Offset6", "Offset7"};
QSet<QString> speedLimitControllerQOLKeys = {"SetSpeedLimit", "SLCConfirmation", "SLCLookaheadHigher", "SLCLookaheadLower", "SLCMapboxFiller", "VisionSpeedLimitDetection"};
QSet<QString> speedLimitControllerVisualKeys = {"ShowSLCOffset", "SpeedLimitSources"};
QSet<QString> speedLimitControllerVisualKeys = {"ShowSLCOffset", "SLCAbbreviatedSources", "SLCActiveSourcesOnly", "SpeedLimitSources"};
QSet<QString> standardPersonalityKeys = {"StandardFollow", "StandardFollowHigh", "StandardJerkAcceleration", "StandardJerkDeceleration", "StandardJerkDanger", "StandardJerkSpeed", "StandardJerkSpeedDecrease", "ResetStandardPersonality"};
QSet<QString> trafficPersonalityKeys = {"TrafficFollow", "TrafficJerkAcceleration", "TrafficJerkDeceleration", "TrafficJerkDanger", "TrafficJerkSpeed", "TrafficJerkSpeedDecrease", "ResetTrafficPersonality"};
QSet<QString> weatherKeys = {"LowVisibilityOffsets", "RainOffsets", "RainStormOffsets", "SetWeatherKey", "SnowOffsets"};
@@ -167,6 +167,8 @@ void StarPilotAnnotatedCameraWidget::updateState(const UIState &s, const StarPil
cachedSimpleMode = starpilot_toggles.value("simple_mode").toBool();
cachedSpeedLimitController = starpilot_toggles.value("speed_limit_controller").toBool();
cachedSpeedLimitSources = starpilot_toggles.value("speed_limit_sources").toBool();
cachedSlcAbbreviatedSources = starpilot_toggles.value("slc_abbreviated_sources").toBool();
cachedSlcActiveSourcesOnly = starpilot_toggles.value("slc_active_sources_only").toBool();
cachedSpeedLimitVienna = starpilot_toggles.value("speed_limit_vienna").toBool();
cachedStaticPedalsOnUi = starpilot_toggles.value("static_pedals_on_ui").toBool();
cachedStoppedTimer = starpilot_toggles.value("stopped_timer").toBool();
@@ -1030,7 +1032,11 @@ void StarPilotAnnotatedCameraWidget::paintSpeedLimit(QPainter &p) {
void StarPilotAnnotatedCameraWidget::paintSpeedLimitSources(QPainter &p) {
p.save();
std::function<void(QRect&, QPixmap&, const QString&, const double)> drawSource = [&](QRect &rect, QPixmap &icon, const QString &title, double speedLimitValue) {
const bool abbreviated = cachedSlcAbbreviatedSources;
const bool activeOnly = cachedSlcActiveSourcesOnly;
std::function<void(QRect&, QPixmap&, const QString&, const QString&, const double)> drawSource =
[&](QRect &rect, QPixmap &icon, const QString &title, const QString &abbrev, double speedLimitValue) {
bool isActive = QString::fromUtf8(speedLimitSource.c_str()) == title && speedLimitValue != 0;
if (isActive) {
@@ -1043,29 +1049,38 @@ void StarPilotAnnotatedCameraWidget::paintSpeedLimitSources(QPainter &p) {
p.setPen(QPen(blackColor(), 10));
}
QSize size(img_size / 4, img_size / 4);
QRect iconRect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignLeft | Qt::AlignVCenter, size, rect.adjusted(20, 0, 0, 0));
QString speedText;
if (speedLimitValue != 0) {
speedText = QString::number(std::nearbyint(speedLimitValue)) + speedUnit;
QString fullText;
if (abbreviated) {
if (speedLimitValue != 0) {
fullText = abbrev + "-" + QString::number(std::nearbyint(speedLimitValue));
} else {
fullText = abbrev + "-X";
}
} else {
speedText = "N/A";
QString speedText = (speedLimitValue != 0)
? QString::number(std::nearbyint(speedLimitValue)) + speedUnit
: "N/A";
fullText = tr(title.toUtf8().constData()) + " - " + speedText;
}
QString fullText = tr(title.toUtf8().constData()) + " - " + speedText;
p.setOpacity(1.0);
p.drawRoundedRect(rect, 24, 24);
p.drawPixmap(iconRect, icon);
QRect textRect;
if (abbreviated) {
textRect = QRect(rect.x() + 20, rect.y(), rect.width() - 40, rect.height());
} else {
QSize size(img_size / 4, img_size / 4);
QRect iconRect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignLeft | Qt::AlignVCenter, size, rect.adjusted(20, 0, 0, 0));
p.drawPixmap(iconRect, icon);
textRect = QRect(iconRect.right() + 10, rect.y(), rect.width() - iconRect.width() - 30, rect.height());
}
p.setPen(QPen(whiteColor(), 6));
QRect textRect(iconRect.right() + 10, rect.y(), rect.width() - iconRect.width() - 30, rect.height());
if (isActive) {
QFontMetrics fm(p.font());
int textYPosition = textRect.y() + (textRect.height() - fm.height()) / 2 + fm.ascent();
QPainterPath path;
path.addText(textRect.x(), textYPosition, p.font(), fullText);
p.strokePath(path, QPen(Qt::black, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
@@ -1075,19 +1090,41 @@ void StarPilotAnnotatedCameraWidget::paintSpeedLimitSources(QPainter &p) {
}
};
int signMargin = 12;
struct SrcEntry { QPixmap *icon; QString title; QString abbrev; double value; };
std::vector<SrcEntry> sources = {
{&dashboardIcon, "Dashboard", "Dash", dashboardSpeedLimit * speedConversion},
{&mapDataIcon, "Map Data", "MapD", mapSpeedLimit * speedConversion},
{&visionIcon, "Vision", "Vision", visionSpeedLimit * speedConversion},
{&mapboxIcon, "Mapbox", "MapB", mapboxSpeedLimit * speedConversion},
{&nextMapsIcon, "Upcoming", "Next", nextSpeedLimit * speedConversion},
};
QRect dashboardRect(speedLimitRect.x() - signMargin, speedLimitRect.y() + speedLimitRect.height() + UI_BORDER_SIZE, 450, 60);
QRect mapDataRect(dashboardRect.x(), dashboardRect.y() + dashboardRect.height() + UI_BORDER_SIZE / 2, 450, 60);
QRect visionRect(mapDataRect.x(), mapDataRect.y() + mapDataRect.height() + UI_BORDER_SIZE / 2, 450, 60);
QRect mapboxRect(visionRect.x(), visionRect.y() + visionRect.height() + UI_BORDER_SIZE / 2, 450, 60);
QRect nextLimitRect(mapboxRect.x(), mapboxRect.y() + mapboxRect.height() + UI_BORDER_SIZE / 2, 450, 60);
const int signMargin = 12;
const int rectH = 60;
const int gap = UI_BORDER_SIZE / 2;
const int xPos = abbreviated ? speedLimitRect.x() : speedLimitRect.x() - signMargin;
int yPos = speedLimitRect.y() + speedLimitRect.height() + UI_BORDER_SIZE;
drawSource(dashboardRect, dashboardIcon, "Dashboard", dashboardSpeedLimit * speedConversion);
drawSource(mapDataRect, mapDataIcon, "Map Data", mapSpeedLimit * speedConversion);
drawSource(visionRect, visionIcon, "Vision", visionSpeedLimit * speedConversion);
drawSource(mapboxRect, mapboxIcon, "Mapbox", mapboxSpeedLimit * speedConversion);
drawSource(nextLimitRect, nextMapsIcon, "Upcoming", nextSpeedLimit * speedConversion);
int rectW = abbreviated ? speedLimitRect.width() : 450;
if (abbreviated) {
// Pre-compute the widest label across all visible rows so every box is the same width.
QFontMetrics fm(InterFont(35, QFont::DemiBold));
for (auto &s : sources) {
if (activeOnly && s.value == 0) continue;
QString label = s.value != 0
? s.abbrev + "-" + QString::number(std::nearbyint(s.value))
: s.abbrev + "-na";
int needed = fm.horizontalAdvance(label) + 40;
if (needed > rectW) rectW = needed;
}
}
for (auto &s : sources) {
if (activeOnly && s.value == 0) continue;
QRect rect(xPos, yPos, rectW, rectH);
drawSource(rect, *s.icon, s.title, s.abbrev, s.value);
yPos += rectH + gap;
}
p.restore();
}
@@ -114,6 +114,8 @@ private:
bool cachedSimpleMode = false;
bool cachedSpeedLimitController = false;
bool cachedSpeedLimitSources = false;
bool cachedSlcAbbreviatedSources = false;
bool cachedSlcActiveSourcesOnly = false;
bool cachedSpeedLimitVienna = false;
bool cachedStaticPedalsOnUi = false;
bool cachedStoppedTimer = false;