mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-29 02:43:47 +08:00
raylib: split out HTML renderer (#36244)
* stash * ok chatter is useful for once * why doesn't it understand?! * rm that * clean up
This commit is contained in:
@@ -11,7 +11,7 @@ from openpilot.system.hardware import TICI
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.widgets import Widget, DialogResult
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
from openpilot.system.ui.widgets.html_render import HtmlRenderer
|
||||
from openpilot.system.ui.widgets.html_render import HtmlModal
|
||||
from openpilot.system.ui.widgets.list_view import text_item, button_item, dual_button_item
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.system.ui.widgets.scroller import Scroller
|
||||
@@ -36,7 +36,7 @@ class DeviceLayout(Widget):
|
||||
self._select_language_dialog: MultiOptionDialog | None = None
|
||||
self._driver_camera: DriverCameraDialog | None = None
|
||||
self._pair_device_dialog: PairingDialog | None = None
|
||||
self._fcc_dialog: HtmlRenderer | None = None
|
||||
self._fcc_dialog: HtmlModal | None = None
|
||||
self._training_guide: TrainingGuide | None = None
|
||||
|
||||
items = self._initialize_items()
|
||||
@@ -140,7 +140,7 @@ class DeviceLayout(Widget):
|
||||
|
||||
def _on_regulatory(self):
|
||||
if not self._fcc_dialog:
|
||||
self._fcc_dialog = HtmlRenderer(os.path.join(BASEDIR, "selfdrive/assets/offroad/fcc.html"))
|
||||
self._fcc_dialog = HtmlModal(os.path.join(BASEDIR, "selfdrive/assets/offroad/fcc.html"))
|
||||
gui_app.set_modal_overlay(self._fcc_dialog)
|
||||
|
||||
def _on_review_training_guide(self):
|
||||
|
||||
@@ -10,6 +10,7 @@ from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.lib.wrap_text import wrap_text
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.html_render import HtmlRenderer
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import OFFROAD_ALERTS
|
||||
|
||||
|
||||
@@ -306,6 +307,7 @@ class UpdateAlert(AbstractAlert):
|
||||
self.release_notes = ""
|
||||
self._wrapped_release_notes = ""
|
||||
self._cached_content_height: float = 0.0
|
||||
self._html_renderer: HtmlRenderer | None = None
|
||||
|
||||
def refresh(self) -> bool:
|
||||
update_available: bool = self.params.get_bool("UpdateAvailable")
|
||||
|
||||
@@ -34,13 +34,11 @@ class HtmlElement:
|
||||
|
||||
|
||||
class HtmlRenderer(Widget):
|
||||
def __init__(self, file_path: str):
|
||||
def __init__(self, file_path: str | None = None, text: str | None = None):
|
||||
super().__init__()
|
||||
self.elements: list[HtmlElement] = []
|
||||
self._normal_font = gui_app.font(FontWeight.NORMAL)
|
||||
self._bold_font = gui_app.font(FontWeight.BOLD)
|
||||
self._scroll_panel = GuiScrollPanel()
|
||||
self._ok_button = Button("OK", click_callback=lambda: gui_app.set_modal_overlay(None), button_style=ButtonStyle.PRIMARY)
|
||||
|
||||
self.styles: dict[ElementType, dict[str, Any]] = {
|
||||
ElementType.H1: {"size": 68, "weight": FontWeight.BOLD, "color": rl.BLACK, "margin_top": 20, "margin_bottom": 16},
|
||||
@@ -53,7 +51,12 @@ class HtmlRenderer(Widget):
|
||||
ElementType.BR: {"size": 0, "weight": FontWeight.NORMAL, "color": rl.BLACK, "margin_top": 0, "margin_bottom": 12},
|
||||
}
|
||||
|
||||
self.parse_html_file(file_path)
|
||||
if file_path is not None:
|
||||
self.parse_html_file(file_path)
|
||||
elif text is not None:
|
||||
self.parse_html_content(text)
|
||||
else:
|
||||
raise ValueError("Either file_path or text must be provided")
|
||||
|
||||
def parse_html_file(self, file_path: str) -> None:
|
||||
with open(file_path, encoding='utf-8') as file:
|
||||
@@ -106,33 +109,7 @@ class HtmlRenderer(Widget):
|
||||
self.elements.append(element)
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
margin = 50
|
||||
content_rect = rl.Rectangle(rect.x + margin, rect.y + margin, rect.width - (margin * 2), rect.height - (margin * 2))
|
||||
|
||||
button_height = 160
|
||||
button_spacing = 20
|
||||
scrollable_height = content_rect.height - button_height - button_spacing
|
||||
|
||||
scrollable_rect = rl.Rectangle(content_rect.x, content_rect.y, content_rect.width, scrollable_height)
|
||||
|
||||
total_height = self.get_total_height(int(scrollable_rect.width))
|
||||
scroll_content_rect = rl.Rectangle(scrollable_rect.x, scrollable_rect.y, scrollable_rect.width, total_height)
|
||||
scroll_offset = self._scroll_panel.update(scrollable_rect, scroll_content_rect)
|
||||
|
||||
rl.begin_scissor_mode(int(scrollable_rect.x), int(scrollable_rect.y), int(scrollable_rect.width), int(scrollable_rect.height))
|
||||
self._render_content(scrollable_rect, scroll_offset)
|
||||
rl.end_scissor_mode()
|
||||
|
||||
button_width = (rect.width - 3 * 50) // 3
|
||||
button_x = content_rect.x + content_rect.width - button_width
|
||||
button_y = content_rect.y + content_rect.height - button_height
|
||||
button_rect = rl.Rectangle(button_x, button_y, button_width, button_height)
|
||||
self._ok_button.render(button_rect)
|
||||
|
||||
return -1
|
||||
|
||||
def _render_content(self, rect: rl.Rectangle, scroll_offset: float = 0) -> float:
|
||||
current_y = rect.y + scroll_offset
|
||||
current_y = rect.y
|
||||
padding = 20
|
||||
content_width = rect.width - (padding * 2)
|
||||
|
||||
@@ -164,7 +141,7 @@ class HtmlRenderer(Widget):
|
||||
# Apply bottom margin
|
||||
current_y += element.margin_bottom
|
||||
|
||||
return current_y - rect.y - scroll_offset # Return total content height
|
||||
return current_y - rect.y
|
||||
|
||||
def get_total_height(self, content_width: int) -> float:
|
||||
total_height = 0.0
|
||||
@@ -193,3 +170,38 @@ class HtmlRenderer(Widget):
|
||||
if weight == FontWeight.BOLD:
|
||||
return self._bold_font
|
||||
return self._normal_font
|
||||
|
||||
|
||||
class HtmlModal(Widget):
|
||||
def __init__(self, file_path: str | None = None, text: str | None = None):
|
||||
super().__init__()
|
||||
self._content = HtmlRenderer(file_path=file_path, text=text)
|
||||
self._scroll_panel = GuiScrollPanel()
|
||||
self._ok_button = Button("OK", click_callback=lambda: gui_app.set_modal_overlay(None), button_style=ButtonStyle.PRIMARY)
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
margin = 50
|
||||
content_rect = rl.Rectangle(rect.x + margin, rect.y + margin, rect.width - (margin * 2), rect.height - (margin * 2))
|
||||
|
||||
button_height = 160
|
||||
button_spacing = 20
|
||||
scrollable_height = content_rect.height - button_height - button_spacing
|
||||
|
||||
scrollable_rect = rl.Rectangle(content_rect.x, content_rect.y, content_rect.width, scrollable_height)
|
||||
|
||||
total_height = self._content.get_total_height(int(scrollable_rect.width))
|
||||
scroll_content_rect = rl.Rectangle(scrollable_rect.x, scrollable_rect.y, scrollable_rect.width, total_height)
|
||||
scroll_offset = self._scroll_panel.update(scrollable_rect, scroll_content_rect)
|
||||
scroll_content_rect.y += scroll_offset
|
||||
|
||||
rl.begin_scissor_mode(int(scrollable_rect.x), int(scrollable_rect.y), int(scrollable_rect.width), int(scrollable_rect.height))
|
||||
self._content.render(scroll_content_rect)
|
||||
rl.end_scissor_mode()
|
||||
|
||||
button_width = (rect.width - 3 * 50) // 3
|
||||
button_x = content_rect.x + content_rect.width - button_width
|
||||
button_y = content_rect.y + content_rect.height - button_height
|
||||
button_rect = rl.Rectangle(button_x, button_y, button_width, button_height)
|
||||
self._ok_button.render(button_rect)
|
||||
|
||||
return -1
|
||||
|
||||
Reference in New Issue
Block a user