mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-07-19 14:42:08 +08:00
fixes for latest merge
This commit is contained in:
@@ -38,7 +38,7 @@ class DeviceLayoutSP(DeviceLayout):
|
||||
|
||||
def _hide_item(self, item):
|
||||
return (item.title in {"Driver Camera", "Regulatory", "Review Training Guide", "Change Language"}
|
||||
or (isinstance(item.action_item, DualButtonAction) and item.action_item.left_text == "Reboot"))
|
||||
or (isinstance(item.action_item, DualButtonAction)))
|
||||
|
||||
def _initialize_items(self):
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.toggles import TogglesLayout
|
||||
from openpilot.system.ui.lib.application import gui_app,MousePos
|
||||
from openpilot.system.ui.lib.multilang import tr_noop
|
||||
from openpilot.system.ui.widgets.scroller import Scroller
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.widgets.network import WifiManagerUI
|
||||
from openpilot.system.ui.widgets.network import NetworkUI
|
||||
from openpilot.system.ui.lib.wifi_manager import WifiManager
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.models import ModelsLayout
|
||||
@@ -60,21 +61,21 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
||||
wifi_manager.set_active(False)
|
||||
|
||||
self._panels = {
|
||||
OP.PanelType.DEVICE: PanelInfo("Device", DeviceLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_home.png"),
|
||||
OP.PanelType.NETWORK: PanelInfo("Network", WifiManagerUI(wifi_manager), icon="icons/network.png"),
|
||||
OP.PanelType.SUNNYLINK: PanelInfo("sunnylink", SunnylinkLayout(), icon="icons/shell.png"),
|
||||
OP.PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
||||
OP.PanelType.SOFTWARE: PanelInfo("Software", SoftwareLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
||||
OP.PanelType.MODELS: PanelInfo("Models", ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
||||
OP.PanelType.STEERING: PanelInfo("Steering", SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
||||
OP.PanelType.CRUISE: PanelInfo("Cruise", CruiseLayout(), icon="icons/speed_limit.png"),
|
||||
OP.PanelType.VISUALS: PanelInfo("Visuals", VisualsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_visuals.png"),
|
||||
OP.PanelType.DISPLAY: PanelInfo("Display", DisplayLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_display.png"),
|
||||
OP.PanelType.OSM: PanelInfo("OSM", OSMLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
OP.PanelType.TRIPS: PanelInfo("Trips", TripsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_trips.png"),
|
||||
OP.PanelType.VEHICLE: PanelInfo("Vehicle", VehicleLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_vehicle.png"),
|
||||
OP.PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_firehose.png"),
|
||||
OP.PanelType.DEVELOPER: PanelInfo("Developer", DeveloperLayout(), icon="icons/shell.png"),
|
||||
OP.PanelType.DEVICE: PanelInfo(tr_noop("Device"), DeviceLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_home.png"),
|
||||
OP.PanelType.NETWORK: PanelInfo(tr_noop("Network"), NetworkUI(wifi_manager), icon="icons/network.png"),
|
||||
OP.PanelType.SUNNYLINK: PanelInfo(tr_noop("sunnylink"), SunnylinkLayout(), icon="icons/shell.png"),
|
||||
OP.PanelType.TOGGLES: PanelInfo(tr_noop("Toggles"), TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
||||
OP.PanelType.SOFTWARE: PanelInfo(tr_noop("Software"), SoftwareLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
||||
OP.PanelType.MODELS: PanelInfo(tr_noop("Models"), ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
||||
OP.PanelType.STEERING: PanelInfo(tr_noop("Steering"), SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
||||
OP.PanelType.CRUISE: PanelInfo(tr_noop("Cruise"), CruiseLayout(), icon="icons/speed_limit.png"),
|
||||
OP.PanelType.VISUALS: PanelInfo(tr_noop("Visuals"), VisualsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_visuals.png"),
|
||||
OP.PanelType.DISPLAY: PanelInfo(tr_noop("Display"), DisplayLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_display.png"),
|
||||
OP.PanelType.OSM: PanelInfo(tr_noop("OSM"), OSMLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
OP.PanelType.TRIPS: PanelInfo(tr_noop("Trips"), TripsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_trips.png"),
|
||||
OP.PanelType.VEHICLE: PanelInfo(tr_noop("Vehicle"), VehicleLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_vehicle.png"),
|
||||
OP.PanelType.FIREHOSE: PanelInfo(tr_noop("Firehose"), FirehoseLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_firehose.png"),
|
||||
OP.PanelType.DEVELOPER: PanelInfo(tr_noop("Developer"), DeveloperLayout(), icon="icons/shell.png"),
|
||||
}
|
||||
|
||||
def _create_nav_button(self, panel_type: OP.PanelType, panel_info: PanelInfo) -> Widget:
|
||||
@@ -108,7 +109,7 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
||||
content_x,
|
||||
rect.y + (OP.NAV_BTN_HEIGHT - text_size.y) / 2
|
||||
)
|
||||
rl.draw_text_ex(self.parent._font_medium, self.panel_info.name, text_pos, 65, 0, text_color)
|
||||
rl.draw_text_ex(self.parent._font_medium, self.panel_info.name, text_pos, 55, 0, text_color)
|
||||
|
||||
# Store button rect for click detection
|
||||
self.panel_info.button_rect = rect
|
||||
@@ -120,7 +121,7 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
||||
|
||||
# Close button
|
||||
close_btn_rect = rl.Rectangle(
|
||||
rect.x + (rect.width - OP.CLOSE_BTN_SIZE) / 2, rect.y + 45, OP.CLOSE_BTN_SIZE, OP.CLOSE_BTN_SIZE
|
||||
rect.x + (rect.width - OP.CLOSE_BTN_SIZE) / 2, rect.y + 60, OP.CLOSE_BTN_SIZE, OP.CLOSE_BTN_SIZE
|
||||
)
|
||||
|
||||
pressed = (rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT) and
|
||||
@@ -128,12 +129,21 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
||||
close_color = OP.CLOSE_BTN_PRESSED if pressed else OP.CLOSE_BTN_COLOR
|
||||
rl.draw_rectangle_rounded(close_btn_rect, 1.0, 20, close_color)
|
||||
|
||||
close_text_size = measure_text_cached(self._font_medium, OP.SETTINGS_CLOSE_TEXT, 140)
|
||||
close_text_pos = rl.Vector2(
|
||||
close_btn_rect.x + (close_btn_rect.width - close_text_size.x) / 2,
|
||||
close_btn_rect.y + (close_btn_rect.height - close_text_size.y) / 2,
|
||||
icon_color = rl.Color(255, 255, 255, 255) if not pressed else rl.Color(220, 220, 220, 255)
|
||||
icon_dest = rl.Rectangle(
|
||||
close_btn_rect.x + (close_btn_rect.width - self._close_icon.width) / 2,
|
||||
close_btn_rect.y + (close_btn_rect.height - self._close_icon.height) / 2,
|
||||
self._close_icon.width,
|
||||
self._close_icon.height,
|
||||
)
|
||||
rl.draw_text_ex(self._font_medium, OP.SETTINGS_CLOSE_TEXT, close_text_pos, 140, 0, OP.TEXT_SELECTED)
|
||||
rl.draw_texture_pro(
|
||||
self._close_icon,
|
||||
rl.Rectangle(0, 0, self._close_icon.width, self._close_icon.height),
|
||||
icon_dest,
|
||||
rl.Vector2(0, 0),
|
||||
0,
|
||||
icon_color,
|
||||
)
|
||||
|
||||
# Store close button rect for click detection
|
||||
self._close_btn_rect = close_btn_rect
|
||||
|
||||
@@ -7,9 +7,10 @@ from collections.abc import Callable
|
||||
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.ui.sunnypilot.lib.toggle import ToggleSP
|
||||
import openpilot.system.ui.sunnypilot.lib.styles as styles
|
||||
from openpilot.system.ui.sunnypilot.lib.option_control import OptionControlSP
|
||||
from openpilot.system.ui.widgets.list_view import _resolve_value
|
||||
|
||||
import openpilot.system.ui.sunnypilot.lib.styles as styles
|
||||
style = styles.Default
|
||||
|
||||
|
||||
@@ -24,29 +25,6 @@ class ListItemSP(ListItem):
|
||||
action_item: ItemAction | None = None):
|
||||
ListItem.__init__(self, title, icon, description, description_visible, callback, action_item)
|
||||
|
||||
def get_item_height(self, font: rl.Font, max_width: int) -> float:
|
||||
if not self.is_visible:
|
||||
return 0
|
||||
|
||||
total_width = self._rect.width - (2 * style.ITEM_PADDING) # Full width minus padding
|
||||
max_width = int(total_width - (2 * style.ITEM_PADDING))
|
||||
|
||||
current_description = self.get_description()
|
||||
if self.description_visible and current_description:
|
||||
if (
|
||||
not self._wrapped_description
|
||||
or current_description != self._prev_description
|
||||
or max_width != self._prev_max_width
|
||||
):
|
||||
self._prev_max_width = max_width
|
||||
self._prev_description = current_description
|
||||
|
||||
wrapped_lines = wrap_text(self._font, current_description, style.ITEM_DESC_FONT_SIZE, max_width)
|
||||
self._wrapped_description = "\n".join(wrapped_lines)
|
||||
self._description_height = len(wrapped_lines) * style.ITEM_DESC_FONT_SIZE + 10
|
||||
return style.ITEM_BASE_HEIGHT + self._description_height - (style.ITEM_BASE_HEIGHT - style.ITEM_DESC_V_OFFSET) + style.ITEM_PADDING
|
||||
return style.ITEM_BASE_HEIGHT
|
||||
|
||||
def get_right_item_rect(self, item_rect: rl.Rectangle) -> rl.Rectangle:
|
||||
if not self.action_item:
|
||||
return rl.Rectangle(0, 0, 0, 0)
|
||||
@@ -106,16 +84,16 @@ class ListItemSP(ListItem):
|
||||
self.callback()
|
||||
|
||||
# Draw description if visible
|
||||
current_description = self.get_description()
|
||||
if self.description_visible and current_description and self._wrapped_description:
|
||||
rl.draw_text_ex(
|
||||
self._font,
|
||||
self._wrapped_description,
|
||||
rl.Vector2(content_x, self._rect.y + style.ITEM_DESC_V_OFFSET),
|
||||
style.ITEM_DESC_FONT_SIZE,
|
||||
0,
|
||||
style.ITEM_DESC_TEXT_COLOR,
|
||||
if self.description_visible:
|
||||
content_width = int(self._rect.width - style.ITEM_PADDING * 2)
|
||||
description_height = self._html_renderer.get_total_height(content_width)
|
||||
description_rect = rl.Rectangle(
|
||||
self._rect.x + style.ITEM_PADDING,
|
||||
self._rect.y + style.ITEM_DESC_V_OFFSET,
|
||||
content_width,
|
||||
description_height
|
||||
)
|
||||
self._html_renderer.render(description_rect)
|
||||
|
||||
class MultipleButtonActionSP(MultipleButtonAction):
|
||||
def __init__(self, param: str | None, buttons: list[str], button_width: int, selected_index: int = 0, callback: Callable = None):
|
||||
@@ -130,14 +108,14 @@ class MultipleButtonActionSP(MultipleButtonAction):
|
||||
button_y = rect.y + (rect.height - style.BUTTON_HEIGHT) / 2
|
||||
clicked = -1
|
||||
|
||||
for i, text in enumerate(self.buttons):
|
||||
for i, _text in enumerate(self.buttons):
|
||||
button_x = rect.x + i * (self.button_width + spacing)
|
||||
button_rect = rl.Rectangle(button_x, button_y, self.button_width, style.BUTTON_HEIGHT)
|
||||
|
||||
# Check button state
|
||||
mouse_pos = rl.get_mouse_position()
|
||||
is_hovered = rl.check_collision_point_rec(mouse_pos, button_rect)
|
||||
is_pressed = is_hovered and rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT) and self._is_pressed
|
||||
is_pressed = is_hovered and rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT) and self.is_pressed
|
||||
is_selected = i == self.selected_button
|
||||
|
||||
# Button colors
|
||||
@@ -154,13 +132,14 @@ class MultipleButtonActionSP(MultipleButtonAction):
|
||||
rl.draw_rectangle_rounded(button_rect, 1.0, 20, bg_color)
|
||||
|
||||
# Draw text
|
||||
text = _resolve_value(_text, "")
|
||||
text_size = measure_text_cached(self._font, text, 40)
|
||||
text_x = button_x + (self.button_width - text_size.x) / 2
|
||||
text_y = button_y + (style.BUTTON_HEIGHT - text_size.y) / 2
|
||||
rl.draw_text_ex(self._font, text, rl.Vector2(text_x, text_y), 40, 0, style.ITEM_TEXT_COLOR)
|
||||
|
||||
# Handle click
|
||||
if is_hovered and rl.is_mouse_button_released(rl.MouseButton.MOUSE_BUTTON_LEFT) and self._is_pressed:
|
||||
if is_hovered and rl.is_mouse_button_released(rl.MouseButton.MOUSE_BUTTON_LEFT) and self.is_pressed:
|
||||
clicked = i
|
||||
|
||||
if clicked >= 0:
|
||||
|
||||
@@ -21,15 +21,6 @@ INNER_PADDING = 10
|
||||
TOP_PADDING = 25
|
||||
|
||||
class OptionControlSP(Widget):
|
||||
"""
|
||||
Raylib implementation of OptionControlSP widget for adjusting numeric values
|
||||
with increment/decrement buttons and a label showing the current value.
|
||||
|
||||
This widget provides a user interface component similar to the C++ OptionControlSP
|
||||
from the sunnypilot project, allowing users to adjust numeric values within a
|
||||
specified range.
|
||||
"""
|
||||
|
||||
def __init__(self, param: str, min_value: int, max_value: int,
|
||||
value_change_step: int = 1, enabled: bool | Callable[[], bool] = True,
|
||||
on_value_changed: Callable[[int], None] | None = None,
|
||||
|
||||
Reference in New Issue
Block a user