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.
|
@ -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)
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 115 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 86 KiB |
|
@ -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
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -335,6 +335,7 @@ void ui_update_frogpilot_params(UIState *s, Params ¶ms) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|