Visuals - Custom Themes - Holiday Themes

The openpilot theme changes according to the current/upcoming holiday. Minor holidays last a day, while major holidays (Easter, Christmas, Halloween, etc.) last a week.
This commit is contained in:
FrogAi 2024-06-08 08:01:09 -07:00
parent feb7978839
commit a66ba24fed
86 changed files with 246 additions and 17 deletions

View File

@ -194,6 +194,7 @@ class Controls:
self.always_on_lateral_active = False
self.drive_added = False
self.holiday_theme_alerted = False
self.onroad_distance_pressed = False
self.openpilot_crashed_triggered = False
self.previous_traffic_mode = False
@ -924,6 +925,10 @@ class Controls:
else:
self.stopped_for_light = False
if not self.holiday_theme_alerted and self.frogpilot_toggles.current_holiday_theme != 0 and self.sm.frame * DT_CTRL >= 10:
self.events.add(EventName.holidayActive)
self.holiday_theme_alerted = True
if frogpilotPlan.leadDeparting:
self.events.add(EventName.leadDeparting)

View File

@ -346,6 +346,30 @@ def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster,
# FrogPilot Alerts
def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
holiday_messages = {
1: ("Happy April Fool's Day! 🤡", "aprilFoolsAlert"),
2: ("Merry Christmas! 🎄", "christmasAlert"),
3: ("¡Feliz Cinco de Mayo! 🌮", "cincoDeMayoAlert"),
4: ("Happy Easter! 🐰", "easterAlert"),
5: ("Happy Fourth of July! 🎆", "fourthOfJulyAlert"),
6: ("Happy Halloween! 🎃", "halloweenAlert"),
7: ("Happy New Year! 🎉", "newYearsDayAlert"),
8: ("Happy St. Patrick's Day! 🍀", "stPatricksDayAlert"),
9: ("Happy Thanksgiving! 🦃", "thanksgivingAlert"),
10: ("Happy Valentine's Day! ❤️", "valentinesDayAlert"),
11: ("Happy World Frog Day! 🐸", "worldFrogDayAlert"),
}
theme_id = params_memory.get_int("CurrentHolidayTheme")
message, alert_type = holiday_messages.get(theme_id, ("", ""))
return Alert(
message,
"",
AlertStatus.normal, AlertSize.small,
Priority.LOWEST, VisualAlert.none, AudibleAlert.engage, 5.)
def no_lane_available_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
lane_width = sm['frogpilotPlan'].laneWidthLeft if CS.leftBlinker else sm['frogpilotPlan'].laneWidthRight
lane_width_msg = f"{lane_width:.1f} meters" if metric else f"{lane_width * CV.METER_TO_FOOT:.1f} feet"
@ -1010,6 +1034,10 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
Priority.MID, VisualAlert.none, AudibleAlert.prompt, 3.),
},
EventName.holidayActive: {
ET.PERMANENT: holiday_alert,
},
EventName.laneChangeBlockedLoud: {
ET.WARNING: Alert(
"Car detected in blindspot",

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -0,0 +1,72 @@
import datetime
from openpilot.common.params import Params
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import update_frogpilot_toggles
class ThemeManager:
def __init__(self):
self.params_memory = Params("/dev/shm/params")
self.previous_theme_id = 0
@staticmethod
def calculate_easter(year):
a = year % 19
b = year // 100
c = year % 100
d = b // 4
e = b % 4
f = (b + 8) // 25
g = (b - f + 1) // 3
h = (19 * a + b - d - g + 15) % 30
i = c // 4
k = c % 4
l = (32 + 2 * e + 2 * i - h - k) % 7
m = (a + 11 * h + 22 * l) // 451
month = (h + l - 7 * m + 114) // 31
day = ((h + l - 7 * m + 114) % 31) + 1
return datetime.datetime(year, month, day)
@staticmethod
def calculate_thanksgiving(year):
november_first = datetime.datetime(year, 11, 1)
day_of_week = november_first.weekday()
return november_first + datetime.timedelta(days=(3 - day_of_week + 21) % 7 + 21)
@staticmethod
def is_within_week_of(target_date, current_date):
start_of_week = target_date - datetime.timedelta(days=target_date.weekday())
end_of_week = start_of_week + datetime.timedelta(days=6)
return start_of_week <= current_date <= end_of_week
def update_holiday(self):
current_date = datetime.datetime.now()
year = current_date.year
holidays = {
"april_fools": (datetime.datetime(year, 4, 1), 1),
"christmas_week": (datetime.datetime(year, 12, 25), 2),
"cinco_de_mayo": (datetime.datetime(year, 5, 5), 3),
"easter_week": (self.calculate_easter(year), 4),
"fourth_of_july": (datetime.datetime(year, 7, 4), 5),
"halloween_week": (datetime.datetime(year, 10, 31), 6),
"new_years": (datetime.datetime(year, 1, 1), 7),
"st_patricks": (datetime.datetime(year, 3, 17), 8),
"thanksgiving_week": (self.calculate_thanksgiving(year), 9),
"valentines": (datetime.datetime(year, 2, 14), 10),
"world_frog_day": (datetime.datetime(year, 3, 20), 11)
}
for holiday, (date, theme_id) in holidays.items():
if holiday.endswith("_week") and self.is_within_week_of(date, current_date) or current_date.date() == date.date():
if theme_id != self.previous_theme_id:
self.params_memory.put_int("CurrentHolidayTheme", theme_id)
update_frogpilot_toggles()
self.previous_theme_id = theme_id
return
if self.previous_theme_id != 0:
self.params_memory.put_int("CurrentHolidayTheme", "0")
update_frogpilot_toggles()
self.previous_theme_id = 0

View File

@ -12,6 +12,7 @@ from openpilot.selfdrive.frogpilot.controls.frogpilot_planner import FrogPilotPl
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import backup_toggles, is_url_pingable
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_variables import FrogPilotVariables
from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, DEFAULT_MODEL_NAME, download_all_models, download_model, update_models
from openpilot.selfdrive.frogpilot.controls.lib.theme_manager import ThemeManager
OFFLINE = log.DeviceState.NetworkType.none
@ -95,6 +96,7 @@ def frogpilot_thread():
params_storage = Params("/persist/params")
frogpilot_planner = FrogPilotPlanner()
theme_manager = ThemeManager()
run_time_checks = False
started_previously = False
@ -156,6 +158,8 @@ def frogpilot_thread():
continue
run_thread_with_lock("update_models", locks["update_models"], update_models, (params, params_memory))
theme_manager.update_holiday()
def main():
frogpilot_thread()

View File

@ -277,7 +277,9 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s, c
// lanelines
for (int i = 0; i < std::size(scene.lane_line_vertices); ++i) {
if (customColors != 0) {
if (currentHolidayTheme != 0) {
painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
} else if (customColors != 0) {
painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
} else {
painter.setBrush(QColor::fromRgbF(1.0, 1.0, 1.0, std::clamp<float>(scene.lane_line_probs[i], 0.0, 0.7)));
@ -287,7 +289,9 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s, c
// road edges
for (int i = 0; i < std::size(scene.road_edge_vertices); ++i) {
if (customColors != 0) {
if (currentHolidayTheme != 0) {
painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
} else if (customColors != 0) {
painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
} else {
painter.setBrush(QColor::fromRgbF(1.0, 0, 0, std::clamp<float>(1.0 - scene.road_edge_stds[i], 0.0, 1.0)));
@ -319,7 +323,12 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s, c
float lin_grad_point = (height() - scene.track_vertices[track_idx].y()) / height();
// If acceleration is between -0.25 and 0.25, resort to the theme color
if (std::abs(acceleration[i]) < 0.25 && (customColors != 0)) {
if (std::abs(acceleration[i]) < 0.25 && (currentHolidayTheme != 0)) {
const std::map<double, QBrush> &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
for (const std::pair<double, QBrush> &entry : colorMap) {
bg.setColorAt(entry.first, entry.second.color());
}
} else if (std::abs(acceleration[i]) < 0.25 && (customColors != 0)) {
const std::map<double, QBrush> &colorMap = std::get<2>(themeConfiguration[customColors]);
for (const std::pair<double, QBrush> &entry : colorMap) {
bg.setColorAt(entry.first, entry.second.color());
@ -339,6 +348,11 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s, c
i += (i + 2) < max_len ? 1 : 0;
}
}
} else if (currentHolidayTheme != 0) {
const std::map<double, QBrush> &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
for (const std::pair<double, QBrush> &entry : colorMap) {
bg.setColorAt(entry.first, entry.second.color());
}
} else if (customColors != 0) {
const std::map<double, QBrush> &colorMap = std::get<2>(themeConfiguration[customColors]);
for (const std::pair<double, QBrush> &entry : colorMap) {
@ -480,8 +494,8 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s)
void AnnotatedCameraWidget::drawLead(QPainter &painter, const cereal::ModelDataV2::LeadDataV3::Reader &lead_data, const QPointF &vd, const float v_ego) {
painter.save();
const float speedBuff = customColors != 0 ? 25. : 10.; // Make the center of the chevron appear sooner if a custom theme is active
const float leadBuff = customColors != 0 ? 100. : 40.; // Make the center of the chevron appear sooner if a custom theme is active
const float speedBuff = currentHolidayTheme != 0 || customColors != 0 ? 25. : 10.; // Make the center of the chevron appear sooner if a theme is active
const float leadBuff = currentHolidayTheme != 0 || customColors != 0 ? 100. : 40.; // Make the center of the chevron appear sooner if a theme is active
const float d_rel = lead_data.getX()[0];
const float v_rel = lead_data.getV()[0] - v_ego;
@ -507,7 +521,9 @@ void AnnotatedCameraWidget::drawLead(QPainter &painter, const cereal::ModelDataV
// chevron
QPointF chevron[] = {{x + (sz * 1.25), y + sz}, {x, y}, {x - (sz * 1.25), y + sz}};
if (customColors != 0) {
if (currentHolidayTheme != 0) {
painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
} else if (customColors != 0) {
painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
} else {
painter.setBrush(redColor(fillAlpha));
@ -653,6 +669,42 @@ void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
{1.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.1))}}}},
};
holidayThemeConfiguration = {
{1, {"april_fools", QColor(255, 165, 0, 255), {{0.0, QBrush(QColor::fromHslF(39 / 360., 1.0, 0.5, 0.9))},
{0.5, QBrush(QColor::fromHslF(39 / 360., 1.0, 0.5, 0.5))},
{1.0, QBrush(QColor::fromHslF(39 / 360., 1.0, 0.5, 0.1))}}}},
{2, {"christmas", QColor(0, 72, 255, 255), {{0.0, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.9))},
{0.5, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.5))},
{1.0, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.1))}}}},
{3, {"cinco_de_mayo", QColor(0, 104, 71, 255), {{0.0, QBrush(QColor::fromHslF(161 / 360., 1.0, 0.2, 0.9))},
{0.5, QBrush(QColor::fromHslF(161 / 360., 1.0, 0.2, 0.5))},
{1.0, QBrush(QColor::fromHslF(161 / 360., 1.0, 0.2, 0.1))}}}},
{4, {"easter", QColor(200, 150, 200, 255), {{0.0, QBrush(QColor::fromHslF(300 / 360., 0.31, 0.69, 0.9))},
{0.5, QBrush(QColor::fromHslF(300 / 360., 0.31, 0.69, 0.5))},
{1.0, QBrush(QColor::fromHslF(300 / 360., 0.31, 0.69, 0.1))}}}},
{5, {"fourth_of_july", QColor(10, 49, 97, 255), {{0.0, QBrush(QColor::fromHslF(213 / 360., 0.81, 0.21, 0.9))},
{0.5, QBrush(QColor::fromHslF(213 / 360., 0.81, 0.21, 0.5))},
{1.0, QBrush(QColor::fromHslF(213 / 360., 0.81, 0.21, 0.1))}}}},
{6, {"halloween", QColor(255, 0, 0, 255), {{0.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.9))},
{0.5, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.5))},
{1.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.1))}}}},
{7, {"new_years_day", QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))},
{0.5, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.5))},
{1.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.1))}}}},
{8, {"st_patricks_day", QColor(0, 128, 0, 255), {{0.0, QBrush(QColor::fromHslF(120 / 360., 1.0, 0.25, 0.9))},
{0.5, QBrush(QColor::fromHslF(120 / 360., 1.0, 0.25, 0.5))},
{1.0, QBrush(QColor::fromHslF(120 / 360., 1.0, 0.25, 0.1))}}}},
{9, {"thanksgiving", QColor(255, 0, 0, 255), {{0.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.9))},
{0.5, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.5))},
{1.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.1))}}}},
{10, {"valentines_day", QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))},
{0.5, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.5))},
{1.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.1))}}}},
{11, {"world_frog_day", QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))},
{0.5, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.5))},
{1.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.1))}}}},
};
animationTimer = new QTimer(this);
connect(animationTimer, &QTimer::timeout, this, [this] {
animationFrameIndex = (animationFrameIndex + 1) % totalFrames;
@ -763,14 +815,21 @@ void AnnotatedCameraWidget::paintFrogPilotWidgets(QPainter &painter, const UISce
animationTimer->stop();
}
if (customSignals != scene.custom_signals) {
if (currentHolidayTheme != scene.current_holiday_theme || customSignals != scene.custom_signals) {
currentHolidayTheme = scene.current_holiday_theme;
customSignals = scene.custom_signals;
QString themePath;
themePath = QString("../frogpilot/assets/custom_themes/%1/images").arg(
themeConfiguration.find(customSignals) != themeConfiguration.end() ?
std::get<0>(themeConfiguration[customSignals]) : "");
if (currentHolidayTheme != 0) {
themePath = QString("../frogpilot/assets/holiday_themes/%1/images").arg(
holidayThemeConfiguration.find(currentHolidayTheme) != holidayThemeConfiguration.end() ?
std::get<0>(holidayThemeConfiguration[currentHolidayTheme]) : "");
} else {
themePath = QString("../frogpilot/assets/custom_themes/%1/images").arg(
themeConfiguration.find(customSignals) != themeConfiguration.end() ?
std::get<0>(themeConfiguration[customSignals]) : "");
}
const QStringList imagePaths = {
themePath + "/turn_signal_1.png",

View File

@ -139,6 +139,7 @@ private:
int conditionalSpeed;
int conditionalSpeedLead;
int conditionalStatus;
int currentHolidayTheme;
int customColors;
int customSignals;
int totalFrames;
@ -152,6 +153,8 @@ private:
size_t animationFrameIndex;
std::unordered_map<int, std::tuple<QString, QColor, std::map<double, QBrush>>> themeConfiguration;
std::unordered_map<int, std::tuple<QString, QColor, std::map<double, QBrush>>> holidayThemeConfiguration;
std::vector<QPixmap> signalImgVector;
QTimer *animationTimer;

View File

@ -43,6 +43,31 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
UIState *s = uiState();
UIScene &scene = s->scene;
holidayThemeConfiguration = {
{0, {"stock", {QColor(255, 255, 255)}}},
{1, {"april_fools", {QColor(255, 165, 0)}}},
{2, {"christmas", {QColor(0, 72, 255)}}},
{3, {"cinco_de_mayo", {QColor(0, 104, 71)}}},
{4, {"easter", {QColor(200, 150, 200)}}},
{5, {"fourth_of_july", {QColor(10, 49, 97)}}},
{6, {"halloween", {QColor(255, 0, 0)}}},
{7, {"new_years_day", {QColor(23, 134, 68)}}},
{8, {"st_patricks_day", {QColor(0, 128, 0)}}},
{9, {"thanksgiving", {QColor(255, 0, 0)}}},
{10, {"valentines_day", {QColor(23, 134, 68)}}},
{11, {"world_frog_day", {QColor(23, 134, 68)}}},
};
for (auto &[key, themeData] : holidayThemeConfiguration) {
QString &themeName = themeData.first;
QString base = themeName == "stock" ? "../assets/images" : QString("../frogpilot/assets/holiday_themes/%1/images").arg(themeName);
std::vector<QString> paths = {base + "/button_home.png", base + "/button_flag.png", base + "/button_settings.png"};
holiday_home_imgs[key] = loadPixmap(paths[0], home_btn.size());
holiday_flag_imgs[key] = loadPixmap(paths[1], home_btn.size());
holiday_settings_imgs[key] = loadPixmap(paths[2], settings_btn.size(), Qt::IgnoreAspectRatio);
}
themeConfiguration = {
{0, {"stock", {QColor(255, 255, 255)}}},
{1, {"frog_theme", {QColor(23, 134, 68)}}},
@ -108,11 +133,17 @@ void Sidebar::updateState(const UIState &s) {
// FrogPilot properties
const UIScene &scene = s.scene;
home_img = home_imgs[scene.custom_icons];
flag_img = flag_imgs[scene.custom_icons];
settings_img = settings_imgs[scene.custom_icons];
currentColors = themeConfiguration[scene.custom_colors].second;
if (scene.current_holiday_theme != 0) {
home_img = holiday_home_imgs[scene.current_holiday_theme];
flag_img = holiday_flag_imgs[scene.current_holiday_theme];
settings_img = holiday_settings_imgs[scene.current_holiday_theme];
currentColors = holidayThemeConfiguration[scene.current_holiday_theme].second;
} else {
home_img = home_imgs[scene.custom_icons];
flag_img = flag_imgs[scene.custom_icons];
settings_img = settings_imgs[scene.custom_icons];
currentColors = themeConfiguration[scene.custom_colors].second;
}
auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState();

View File

@ -68,5 +68,10 @@ private:
std::unordered_map<int, QPixmap> home_imgs;
std::unordered_map<int, QPixmap> settings_imgs;
std::unordered_map<int, std::pair<QString, std::vector<QColor>>> holidayThemeConfiguration;
std::unordered_map<int, QPixmap> holiday_flag_imgs;
std::unordered_map<int, QPixmap> holiday_home_imgs;
std::unordered_map<int, QPixmap> holiday_settings_imgs;
std::vector<QColor> currentColors;
};

View File

@ -202,6 +202,20 @@ class Soundd:
AudibleAlert.goat: self.frogpilot_toggles.prompt_volume,
}
holiday_theme_configuration = {
1: "april_fools",
2: "christmas",
3: "cinco_de_mayo",
4: "easter",
5: "fourth_of_july",
6: "halloween",
7: "new_years_day",
8: "st_patricks_day",
9: "thanksgiving",
10: "valentines_day",
11: "world_frog_day",
}
theme_configuration = {
0: "stock_theme",
1: "frog_theme",
@ -209,8 +223,12 @@ class Soundd:
3: "stalin_theme"
}
theme_name = theme_configuration.get(self.frogpilot_toggles.custom_sounds)
self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/custom_themes/" + theme_name + "/sounds/" if theme_name != "stock_theme" else "/selfdrive/assets/sounds/")
if self.frogpilot_toggles.current_holiday_theme != 0:
theme_name = holiday_theme_configuration.get(self.frogpilot_toggles.current_holiday_theme)
self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/holiday_themes/" + theme_name + "/sounds/")
else:
theme_name = theme_configuration.get(self.frogpilot_toggles.custom_sounds)
self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/custom_themes/" + theme_name + "/sounds/" if theme_name != "stock_theme" else "/selfdrive/assets/sounds/")
if self.sound_directory != self.previous_sound_directory:
self.load_sounds()

View File

@ -335,6 +335,7 @@ void ui_update_frogpilot_params(UIState *s, Params &params) {
scene.custom_colors = custom_theme ? params.getInt("CustomColors") : 0;
scene.custom_icons = custom_theme ? params.getInt("CustomIcons") : 0;
scene.custom_signals = custom_theme ? params.getInt("CustomSignals") : 0;
scene.holiday_themes = custom_theme && params.getBool("HolidayThemes");
scene.disable_smoothing_mtsc = params.getBool("MTSCEnabled") && params.getBool("DisableMTSCSmoothing");
scene.disable_smoothing_vtsc = params.getBool("VisionTurnControl") && params.getBool("DisableVTSCSmoothing");
@ -459,6 +460,7 @@ void UIState::update() {
// FrogPilot variables that need to be constantly updated
scene.conditional_status = scene.conditional_experimental && scene.enabled ? paramsMemory.getInt("CEStatus") : 0;
scene.current_holiday_theme = scene.holiday_themes ? paramsMemory.getInt("CurrentHolidayTheme") : 0;
scene.started_timer = scene.started || started_prev ? scene.started_timer + 1 : 0;
}

View File

@ -139,6 +139,7 @@ typedef struct UIScene {
bool experimental_mode;
bool experimental_mode_via_screen;
bool has_lead;
bool holiday_themes;
bool map_open;
bool model_randomizer;
bool online;
@ -187,6 +188,7 @@ typedef struct UIScene {
int conditional_speed;
int conditional_speed_lead;
int conditional_status;
int current_holiday_theme;
int custom_colors;
int custom_icons;
int custom_signals;