mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-09-09 00:43:43 +08:00
[TIZI/TICI] ui: label the Model Status slots small and big and scroll long names
This commit is contained in:
@@ -13,7 +13,7 @@ from openpilot.cereal import custom
|
||||
from openpilot.sunnypilot.models.helpers import ACTIVE_BUNDLE_KEYS, get_selected_bundle, resolve_bundle_by_ref
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.selfdrive.ui.ui_state import device, ui_state
|
||||
from openpilot.selfdrive.ui.sunnypilot.model_info import active_source, bundles_for_source, default_model_name, model_info
|
||||
from openpilot.selfdrive.ui.sunnypilot.model_info import active_source, bundles_for_source, default_model, default_model_name, model_info
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.widgets import DialogResult, Widget
|
||||
@@ -163,26 +163,23 @@ class ModelsLayout(Widget):
|
||||
|
||||
state = self._download_row_state(progresses, bundle.internalName)
|
||||
if queued := self._queued_name(bundle.ref):
|
||||
state["name"] += f" · {queued} {tr('queued')}"
|
||||
state["name"] += f" | {queued} {tr('queued')}"
|
||||
self.download_item.action_item.update(**state)
|
||||
self._downloading = self.download_item.action_item.downloading
|
||||
ds = custom.ModelManagerSP.DownloadStatus
|
||||
self._verifying = any(getattr(p.status, 'raw', p.status) == ds.verifying for p in progresses)
|
||||
|
||||
def _slot_segments(self):
|
||||
"""One segment per slot: name, downloaded check or empty-slot mark, active in green."""
|
||||
"""small and big slots side by side; the active side is green, an empty slot shows its default."""
|
||||
active = active_source()
|
||||
segments = []
|
||||
for source in ("qcom", "usbgpu"):
|
||||
for source, label in (("qcom", tr("small")), ("usbgpu", tr("big"))):
|
||||
if segments:
|
||||
segments.append(("|", rl.GRAY, None, None))
|
||||
bundle = get_selected_bundle(ui_state.params, source)
|
||||
name = bundle.internalName if bundle else tr("Default")
|
||||
if source == active:
|
||||
name += f" ({tr('active')})"
|
||||
color = ON_COLOR if source == active else rl.GRAY
|
||||
if bundle:
|
||||
segments.append((name, color, "icons/checkmark.png", None))
|
||||
else:
|
||||
segments.append((name, color, "icons/circled_slash.png", rl.WHITE))
|
||||
name = bundle.internalName if bundle else default_model(source)
|
||||
segments.append((label, rl.GRAY, None, None))
|
||||
segments.append((name, ON_COLOR if source == active else rl.LIGHTGRAY, "icons/checkmark.png", None))
|
||||
return segments
|
||||
|
||||
def _queued_name(self, current_ref):
|
||||
|
||||
@@ -22,8 +22,12 @@ def bundles_for_source(source: str):
|
||||
return get_cached_bundles(ui_state.params, source)
|
||||
|
||||
|
||||
def default_model(source: str) -> str:
|
||||
return DEFAULT_BIG_MODEL if source == 'usbgpu' else DEFAULT_MODEL
|
||||
|
||||
|
||||
def default_model_name(source: str) -> str:
|
||||
return f"{DEFAULT_BIG_MODEL if source == 'usbgpu' else DEFAULT_MODEL} (Default)"
|
||||
return f"{default_model(source)} (Default)"
|
||||
|
||||
|
||||
def model_info() -> tuple[str, str, str]:
|
||||
|
||||
@@ -25,6 +25,7 @@ ICON_PADDING = 12
|
||||
BAR_WIDTH = 1100
|
||||
BAR_HEIGHT = 20
|
||||
SEGMENT_GAP = 24
|
||||
SEGMENT_NAME_MAX_WIDTH = 380
|
||||
BAR_GAP = 16
|
||||
BAR_RADIUS = BAR_HEIGHT / 2
|
||||
CAPSULE_POINTS = 24
|
||||
@@ -47,6 +48,7 @@ class DownloadStatusAction(ItemAction):
|
||||
self.name = ""
|
||||
self.status_text = ""
|
||||
self.segments: list[tuple[str, rl.Color, str | None, rl.Color | None]] | None = None
|
||||
self._segment_labels: list[UnifiedLabel] = []
|
||||
self.downloading = False
|
||||
self.text_color = rl.GRAY
|
||||
self.icon: str | None = None
|
||||
@@ -99,7 +101,7 @@ class DownloadStatusAction(ItemAction):
|
||||
"""[(segment, text width, total width incl. icon and gap)]"""
|
||||
out = []
|
||||
for i, seg in enumerate(self.segments or []):
|
||||
text_width = measure_text_cached(self._font, seg[0], FONT_SIZE).x
|
||||
text_width = min(measure_text_cached(self._font, seg[0], FONT_SIZE).x, SEGMENT_NAME_MAX_WIDTH)
|
||||
total = text_width + (ICON_PADDING + ICON_SIZE if seg[2] else 0) + (SEGMENT_GAP if i else 0)
|
||||
out.append((seg, text_width, total))
|
||||
return out
|
||||
@@ -182,12 +184,20 @@ class DownloadStatusAction(ItemAction):
|
||||
|
||||
def _render_segments(self, rect: rl.Rectangle):
|
||||
measured = self._measured_segments()
|
||||
while len(self._segment_labels) < len(measured):
|
||||
self._segment_labels.append(UnifiedLabel("", font_size=FONT_SIZE, max_width=SEGMENT_NAME_MAX_WIDTH,
|
||||
scroll=True, wrap_text=False))
|
||||
x = rect.x + rect.width - sum(total for _, _, total in measured)
|
||||
for i, ((text, color, icon, icon_color), text_width, _) in enumerate(measured):
|
||||
if i:
|
||||
x += SEGMENT_GAP
|
||||
label = self._segment_labels[i]
|
||||
if label.text != text:
|
||||
label.set_text(text)
|
||||
label.set_text_color(color)
|
||||
text_height = measure_text_cached(self._font, text, FONT_SIZE).y
|
||||
rl.draw_text_ex(self._font, text, rl.Vector2(x, rect.y + (rect.height - text_height) / 2), FONT_SIZE, 0, color)
|
||||
label.set_position(x, rect.y + (rect.height - text_height) / 2)
|
||||
label.render()
|
||||
x += text_width
|
||||
if icon:
|
||||
texture = gui_app.texture(icon, ICON_SIZE, ICON_SIZE, keep_aspect_ratio=True)
|
||||
|
||||
Reference in New Issue
Block a user