mirror of
https://gitlvb.teallvbs.xyz/IQ.Lvbs/IQ.Pilot.git
synced 2026-08-21 19:33:43 +08:00
IQ.Pilot Release Commit @ 4fcea4d
This commit is contained in:
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import pyray as rl
|
||||
from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.system.ui.lib.application import BIG_UI, gui_app
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.button import Button, ButtonStyle
|
||||
|
||||
if BIG_UI:
|
||||
MARGIN = 50
|
||||
SPACING = 40
|
||||
FONT_SIZE = 72
|
||||
LINE_HEIGHT = 80
|
||||
BUTTON_SIZE = rl.Vector2(560, 160)
|
||||
else:
|
||||
MARGIN = 20
|
||||
SPACING = 30
|
||||
FONT_SIZE = 25
|
||||
LINE_HEIGHT = 25
|
||||
BUTTON_SIZE = rl.Vector2(280, 80)
|
||||
|
||||
DEMO_TEXT = """This is a sample text that will be wrapped and scrolled if necessary.
|
||||
The text is long enough to demonstrate scrolling and word wrapping.""" * 30
|
||||
|
||||
|
||||
def wrap_text(text, font_size, max_width):
|
||||
lines = []
|
||||
font = gui_app.font()
|
||||
|
||||
for paragraph in text.split("\n"):
|
||||
if not paragraph.strip():
|
||||
# Don't add empty lines first, ensuring wrap_text("") returns []
|
||||
if lines:
|
||||
lines.append("")
|
||||
continue
|
||||
indent = re.match(r"^\s*", paragraph).group()
|
||||
current_line = indent
|
||||
words = re.split(r"(\s+|-)", paragraph[len(indent):])
|
||||
while len(words):
|
||||
word = words.pop(0)
|
||||
test_line = current_line + word + (words.pop(0) if words else "")
|
||||
if measure_text_cached(font, test_line, font_size).x <= max_width:
|
||||
current_line = test_line
|
||||
else:
|
||||
lines.append(current_line)
|
||||
current_line = word + " "
|
||||
current_line = current_line.rstrip()
|
||||
if current_line:
|
||||
lines.append(current_line)
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
class TextWindow(Widget):
|
||||
def __init__(self, text: str):
|
||||
super().__init__()
|
||||
self._textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2)
|
||||
self._wrapped_lines = wrap_text(text, FONT_SIZE, self._textarea_rect.width - 20)
|
||||
self._content_rect = rl.Rectangle(0, 0, self._textarea_rect.width - 20, len(self._wrapped_lines) * LINE_HEIGHT)
|
||||
self._scroll_panel = GuiScrollPanel()
|
||||
self._scroll_panel._offset_filter_y.x = -max(self._content_rect.height - self._textarea_rect.height, 0)
|
||||
|
||||
button_text = "Exit" if PC else "Update & Reboot"
|
||||
self._button = Button(button_text, click_callback=self._on_button_clicked, button_style=ButtonStyle.TRANSPARENT_WHITE_BORDER, font_size=FONT_SIZE)
|
||||
|
||||
@staticmethod
|
||||
def _on_button_clicked():
|
||||
if PC:
|
||||
gui_app.request_close()
|
||||
return
|
||||
|
||||
try:
|
||||
basedir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..")
|
||||
# Detect current branch and its remote tracking ref
|
||||
branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=basedir, timeout=10).decode().strip()
|
||||
remote = subprocess.check_output(
|
||||
["git", "config", f"branch.{branch}.remote"], cwd=basedir, timeout=10
|
||||
).decode().strip() or "origin"
|
||||
subprocess.run(["git", "fetch", remote], cwd=basedir, timeout=60)
|
||||
subprocess.run(["git", "reset", "--hard", f"{remote}/{branch}"], cwd=basedir, timeout=30)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
gui_app.request_close()
|
||||
HARDWARE.reboot()
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
scroll = self._scroll_panel.update(self._textarea_rect, self._content_rect)
|
||||
rl.begin_scissor_mode(int(self._textarea_rect.x), int(self._textarea_rect.y), int(self._textarea_rect.width), int(self._textarea_rect.height))
|
||||
for i, line in enumerate(self._wrapped_lines):
|
||||
position = rl.Vector2(self._textarea_rect.x, self._textarea_rect.y + scroll + i * LINE_HEIGHT)
|
||||
if position.y + LINE_HEIGHT < self._textarea_rect.y or position.y > self._textarea_rect.y + self._textarea_rect.height:
|
||||
continue
|
||||
rl.draw_text_ex(gui_app.font(), line, position, FONT_SIZE, 0, rl.WHITE)
|
||||
rl.end_scissor_mode()
|
||||
|
||||
button_bounds = rl.Rectangle(rect.width - MARGIN - BUTTON_SIZE.x - SPACING, rect.height - MARGIN - BUTTON_SIZE.y, BUTTON_SIZE.x, BUTTON_SIZE.y)
|
||||
self._button.render(button_bounds)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
text = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT
|
||||
gui_app.init_window("Text Viewer")
|
||||
text_window = TextWindow(text)
|
||||
for _ in gui_app.render():
|
||||
text_window.render(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
|
||||
Reference in New Issue
Block a user