mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-10 03:42:09 +08:00
BigUI WIP: Kiełbasa Polska
This commit is contained in:
@@ -253,6 +253,19 @@ def draw_rounded_stroke(rect: rl.Rectangle, color: rl.Color, thickness: int = 1,
|
||||
rl.draw_rectangle_rounded_lines_ex(snapped, _roundness_for(snapped, radius_px), segments or _segments_for(snapped, radius_px), thickness, color)
|
||||
|
||||
|
||||
def truncate_text_ellipsis(
|
||||
font: rl.Font, text: str, max_width: float, font_size: int
|
||||
) -> str:
|
||||
if measure_text_cached(font, text, font_size).x <= max_width:
|
||||
return text
|
||||
shortened = text.rstrip()
|
||||
candidate = f"{shortened}..."
|
||||
while shortened and measure_text_cached(font, candidate, font_size).x > max_width:
|
||||
shortened = shortened[:-1].rstrip()
|
||||
candidate = f"{shortened}..." if shortened else "..."
|
||||
return candidate
|
||||
|
||||
|
||||
class AetherListColors:
|
||||
PANEL_BG = rl.Color(8, 8, 10, 255)
|
||||
PANEL_BORDER = rl.Color(255, 255, 255, 22)
|
||||
@@ -307,8 +320,7 @@ class AetherListMetrics:
|
||||
adjustor_preset_height: int = 64
|
||||
adjustor_preset_gap: int = 14
|
||||
adjustor_scrubber_height: int = 75
|
||||
adjustor_value_pill_height: int = 52
|
||||
adjustor_value_pill_width: int = 209
|
||||
|
||||
utility_value_right: int = 391
|
||||
utility_value_width: int = 319
|
||||
utility_chevron_right: int = 90
|
||||
@@ -1016,8 +1028,6 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
|
||||
class BreadcrumbController:
|
||||
EXPAND_DURATION: float = 2.5
|
||||
TRIGGER_DEPTH: int = 4
|
||||
RECENT_KEEP: int = 3
|
||||
|
||||
def __init__(self):
|
||||
self._rects: dict[str, rl.Rectangle] = {}
|
||||
@@ -1167,8 +1177,8 @@ class BreadcrumbController:
|
||||
target = 1.0 if self._expanded else 0.0
|
||||
self._expand_alpha += (target - self._expand_alpha) * ANIM_LERP
|
||||
|
||||
ACTIVE_SIZE = 64
|
||||
PAST_SIZE = 52
|
||||
ACTIVE_SIZE = 58
|
||||
PAST_SIZE = 50
|
||||
CHEVRON_SIZE = 38
|
||||
CHEVRON_W = 32
|
||||
GAP = 23
|
||||
@@ -1188,23 +1198,56 @@ class BreadcrumbController:
|
||||
|
||||
mouse_pos = gui_app.last_mouse_event.pos
|
||||
|
||||
depth = len(path)
|
||||
has_overflow = depth > self.TRIGGER_DEPTH
|
||||
MIN_ACTIVE_SIZE = 34
|
||||
CAPSULE_W = 102
|
||||
capsule_need = CAPSULE_W + GAP + CHEVRON_W + GAP
|
||||
|
||||
if not has_overflow:
|
||||
# Shallow path: render everything, no ellipsis.
|
||||
display_path = list(path)
|
||||
overflow_alpha = 1.0
|
||||
elif self._expanded:
|
||||
# Expanded: reveal the entire path and allow it to overflow.
|
||||
# The overflow will be cleanly masked by a scissor clip and fade out gradient.
|
||||
active_size = ACTIVE_SIZE
|
||||
|
||||
if self._expanded:
|
||||
display_path = list(path)
|
||||
overflow_alpha = 0.0
|
||||
else:
|
||||
# Collapsed: single … at front, most-recent RECENT_KEEP crumbs visible.
|
||||
recent = path[-self.RECENT_KEEP:]
|
||||
display_path = [("...", "action:breadcrumb_history")] + recent
|
||||
overflow_alpha = 1.0
|
||||
active = path[-1]
|
||||
med_font = gui_app.font(FontWeight.MEDIUM)
|
||||
active_ts = measure_text_cached(gui_app.font(FontWeight.BOLD), active[0], ACTIVE_SIZE)
|
||||
remaining = rect.width - 20 - active_ts.x - GAP
|
||||
|
||||
while remaining < capsule_need and active_size > MIN_ACTIVE_SIZE:
|
||||
active_size -= 6
|
||||
active_ts = measure_text_cached(gui_app.font(FontWeight.BOLD), active[0], active_size)
|
||||
remaining = rect.width - 20 - active_ts.x - GAP
|
||||
|
||||
if remaining < capsule_need:
|
||||
display_path = [active]
|
||||
overflow_alpha = 0.0
|
||||
else:
|
||||
budget = remaining - capsule_need
|
||||
sep = GAP + CHEVRON_W + GAP
|
||||
before = []
|
||||
for i in range(len(path) - 2, -1, -1):
|
||||
slot = budget - sep
|
||||
if slot <= 0:
|
||||
break
|
||||
full_text, action = path[i]
|
||||
full_ts = measure_text_cached(med_font, full_text, PAST_SIZE)
|
||||
if full_ts.x <= slot:
|
||||
before.insert(0, (full_text, action))
|
||||
budget -= full_ts.x + sep
|
||||
else:
|
||||
trunc = truncate_text_ellipsis(med_font, full_text, slot, PAST_SIZE)
|
||||
visible = trunc.removesuffix("...").rstrip()
|
||||
if len(visible) < 3:
|
||||
break
|
||||
before.insert(0, (trunc, action))
|
||||
budget -= measure_text_cached(med_font, trunc, PAST_SIZE).x + sep
|
||||
|
||||
hidden = len(path) - 1 - len(before)
|
||||
if hidden > 0:
|
||||
display_path = [("...", "action:breadcrumb_history")] + before + [active]
|
||||
else:
|
||||
display_path = before + [active]
|
||||
overflow_alpha = 1.0
|
||||
|
||||
current_x = rect.x + 20
|
||||
|
||||
@@ -1221,7 +1264,7 @@ class BreadcrumbController:
|
||||
current_x += GAP
|
||||
continue
|
||||
|
||||
capsule_w, capsule_h = 102, 58
|
||||
capsule_w, capsule_h = CAPSULE_W, 58
|
||||
cap_rect = rl.Rectangle(current_x, center_y - capsule_h / 2, capsule_w, capsule_h)
|
||||
hovered = point_hits(mouse_pos, cap_rect, None, pad_x=4, pad_y=6)
|
||||
|
||||
@@ -1265,7 +1308,7 @@ class BreadcrumbController:
|
||||
|
||||
if is_last:
|
||||
font = gui_app.font(FontWeight.BOLD)
|
||||
font_size = ACTIVE_SIZE
|
||||
font_size = active_size
|
||||
c_normal = rl.Color(252, 252, 255, item_alpha)
|
||||
c_hover = rl.Color(252, 252, 255, item_alpha)
|
||||
c_pressed = rl.Color(200, 200, 200, item_alpha)
|
||||
@@ -1318,6 +1361,7 @@ PANEL_HEADER_TITLE_FONT_SIZE: int = 58
|
||||
PANEL_HEADER_SUBTITLE_FONT_SIZE: int = 29
|
||||
PANEL_HEADER_TITLE_FONT: FontWeight = FontWeight.SEMI_BOLD
|
||||
PANEL_HEADER_SUBTITLE_FONT: FontWeight = FontWeight.NORMAL
|
||||
PANEL_HEADER_SUBTITLE_LINE_HEIGHT: float = 33.0 # subtitle_size(29) + interline_gap(4)
|
||||
|
||||
|
||||
def draw_settings_panel_header(header_rect: rl.Rectangle, title: str, subtitle: str | None = None,
|
||||
@@ -1879,16 +1923,16 @@ def draw_metric_strip(
|
||||
)
|
||||
|
||||
|
||||
GROUP_HEADER_HEIGHT = 20.0
|
||||
GROUP_HEADER_GAP = 2.0
|
||||
GROUP_HEADER_LINE_GAP = 2.0
|
||||
GROUP_HEADER_HEIGHT = 26.0
|
||||
GROUP_HEADER_GAP = 1.0
|
||||
GROUP_HEADER_LINE_GAP = 1.0
|
||||
GROUP_OVERHEAD = 8.0 + GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
GROUP_HAIRLINE_COLOR = rl.Color(255, 255, 255, 30)
|
||||
GROUP_HEADER_COLOR = AetherListColors.HEADER
|
||||
|
||||
|
||||
def draw_group_header(x: float, y: float, width: float, label: str) -> float:
|
||||
gui_label(rl.Rectangle(x, y, max(1.0, width), GROUP_HEADER_HEIGHT), label, 16, GROUP_HEADER_COLOR, FontWeight.MEDIUM)
|
||||
gui_label(rl.Rectangle(x, y, max(1.0, width), GROUP_HEADER_HEIGHT), label, 20, GROUP_HEADER_COLOR, FontWeight.MEDIUM)
|
||||
y += GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP
|
||||
rl.draw_line(int(x), int(y), int(x + width), int(y), GROUP_HAIRLINE_COLOR)
|
||||
return y + GROUP_HEADER_GAP
|
||||
@@ -2420,8 +2464,7 @@ class AetherAdjustorRow(Widget):
|
||||
self._pressed_zone: str | None = None
|
||||
self._is_last = False
|
||||
self._header_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._value_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._hint_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._progress_bar_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._preset_rects: list[tuple[float, rl.Rectangle]] = []
|
||||
self._scrubber_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._scrubber = self._child(
|
||||
@@ -2493,7 +2536,7 @@ class AetherAdjustorRow(Widget):
|
||||
self._pressed_zone = "scrubber"
|
||||
return
|
||||
|
||||
if rl.check_collision_point_rec(mouse_pos, self._header_rect) or rl.check_collision_point_rec(mouse_pos, self._value_rect) or rl.check_collision_point_rec(mouse_pos, self._hint_rect):
|
||||
if rl.check_collision_point_rec(mouse_pos, self._header_rect):
|
||||
self._pressed_zone = "header"
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
@@ -2520,7 +2563,7 @@ class AetherAdjustorRow(Widget):
|
||||
|
||||
if pressed_zone == "header":
|
||||
active = self._active()
|
||||
if rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._header_rect, 6, 4)) or rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._value_rect, 6, 4)) or rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._hint_rect, 6, 4)):
|
||||
if rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._header_rect, 6, 4)):
|
||||
self._set_active_state(not active)
|
||||
|
||||
def _handle_mouse_event(self, mouse_event: MouseEvent):
|
||||
@@ -2577,65 +2620,51 @@ class AetherAdjustorRow(Widget):
|
||||
current_border=current_border,
|
||||
)
|
||||
|
||||
title_fs = 24
|
||||
sub_fs = 20
|
||||
val_fs = 20
|
||||
|
||||
value_pill_w = min(float(AETHER_LIST_METRICS.adjustor_value_pill_width), max(118.0, rect.width * 0.22))
|
||||
value_pill_h = float(AETHER_LIST_METRICS.adjustor_value_pill_height)
|
||||
value_y = rect.y + 14
|
||||
|
||||
self._header_rect = rl.Rectangle(rect.x, rect.y, rect.width, min(rect.height, 78))
|
||||
self._value_rect = snap_rect(rl.Rectangle(rect.x + rect.width - value_pill_w - 18, value_y, value_pill_w, value_pill_h))
|
||||
content_right = self._value_rect.x - 18
|
||||
title_fs = 28
|
||||
sub_fs = 24
|
||||
bar_val_fs = 20
|
||||
|
||||
content_left = rect.x + 24
|
||||
content_width = max(120.0, rect.width - 48)
|
||||
|
||||
content_width = max(120.0, content_right - content_left)
|
||||
|
||||
title_y = rect.y + 14
|
||||
title_h = 28
|
||||
title_y = rect.y + 10
|
||||
title_h = 30
|
||||
gui_label(rl.Rectangle(content_left, title_y, content_width, title_h), self._title, title_fs, self._style.title_color, FontWeight.MEDIUM)
|
||||
|
||||
sub_y = rect.y + 44
|
||||
sub_h = 28
|
||||
if self._subtitle:
|
||||
sub_y = rect.y + 44
|
||||
sub_h = 22
|
||||
gui_label(rl.Rectangle(content_left, sub_y, content_width, sub_h), self._subtitle, sub_fs, self._style.subtitle_color, FontWeight.NORMAL)
|
||||
|
||||
pill_fill = rl.Color(255, 255, 255, 5)
|
||||
pill_border = rl.Color(255, 255, 255, 14)
|
||||
if active:
|
||||
pill_fill = mix_colors(rl.Color(18, 22, 28, 255), self._color, 0.20, alpha=255)
|
||||
pill_border = with_alpha(self._color, 64)
|
||||
draw_rounded_fill(self._value_rect, pill_fill, radius_px=16)
|
||||
draw_rounded_stroke(self._value_rect, pill_border, radius_px=16)
|
||||
val_text_y = self._value_rect.y + (self._value_rect.height - val_fs) / 2 - 2
|
||||
bar_h = 30
|
||||
bar_y = (sub_y + sub_h + 6) if self._subtitle else (title_y + title_h + 8)
|
||||
bar_rect = snap_rect(rl.Rectangle(content_left, bar_y, rect.x + rect.width - 24 - content_left, bar_h))
|
||||
self._progress_bar_rect = bar_rect
|
||||
self._header_rect = rl.Rectangle(rect.x, rect.y, rect.width, min(rect.height, bar_y + bar_h - rect.y))
|
||||
|
||||
draw_rounded_fill(bar_rect, rl.Color(255, 255, 255, 8), radius_px=bar_h // 2)
|
||||
draw_rounded_stroke(bar_rect, rl.Color(255, 255, 255, 14), radius_px=bar_h // 2)
|
||||
|
||||
fill_frac = self._scrubber._value_fraction(self._current_value())
|
||||
if fill_frac > 0:
|
||||
fill_rect = snap_rect(rl.Rectangle(bar_rect.x, bar_rect.y, max(1.0, bar_rect.width * fill_frac), bar_h))
|
||||
draw_rounded_fill(fill_rect, with_alpha(self._color, 180 if active else 120), radius_px=bar_h // 2)
|
||||
|
||||
draw_text_fit_common(
|
||||
self._font_value,
|
||||
self.formatted_value(),
|
||||
rl.Vector2(self._value_rect.x + 10, val_text_y),
|
||||
max(1.0, self._value_rect.width - 20),
|
||||
val_fs,
|
||||
rl.Vector2(bar_rect.x + 12, bar_rect.y + (bar_h - bar_val_fs) / 2),
|
||||
max(1.0, bar_rect.width - 24),
|
||||
bar_val_fs,
|
||||
align_center=True,
|
||||
color=self._style.title_color,
|
||||
)
|
||||
|
||||
hint_h = 8
|
||||
value_bottom = self._value_rect.y + self._value_rect.height
|
||||
gap_below = (rect.y + rect.height) - value_bottom
|
||||
hint_y = value_bottom + gap_below / 2 - hint_h / 2
|
||||
self._hint_rect = snap_rect(rl.Rectangle(content_left, hint_y, rect.x + rect.width - 24 - content_left, hint_h + 4))
|
||||
hint_track = snap_rect(rl.Rectangle(self._hint_rect.x, self._hint_rect.y + 2, self._hint_rect.width, hint_h))
|
||||
rl.draw_rectangle_rounded(hint_track, 1.0, 10, rl.Color(255, 255, 255, 10))
|
||||
fill_w = hint_track.width * self._scrubber._value_fraction(self._current_value())
|
||||
if fill_w > 0:
|
||||
rl.draw_rectangle_rounded(snap_rect(rl.Rectangle(hint_track.x, hint_track.y, fill_w, hint_track.height)), 1.0, 10, with_alpha(self._color, 180 if active else 120))
|
||||
|
||||
if not active:
|
||||
return
|
||||
|
||||
tray_alpha = max(0, min(255, int(255 * self._focus_progress)))
|
||||
tray_top = rect.y + 92 - (1.0 - self._focus_progress) * 6
|
||||
tray_top = self._progress_bar_rect.y + self._progress_bar_rect.height + 10
|
||||
current_y = tray_top
|
||||
self._preset_rects.clear()
|
||||
|
||||
@@ -3066,7 +3095,7 @@ class AetherSettingsView(PanelManagerView):
|
||||
if not self._has_header:
|
||||
return 0.0
|
||||
if self._parent_toggle:
|
||||
h = max(42.0, 40.0) # toggle (42px at header top) vs title area (32px + 8px gap)
|
||||
h = max(float(AETHER_LIST_METRICS.toggle_height), 54.0) # toggle vs title(46px + 8px gap)
|
||||
subtitle_text = tr(self._parent_toggle.subtitle) if self._parent_toggle.subtitle else ""
|
||||
if self._header_subtitle:
|
||||
subtitle_text = tr(self._header_subtitle)
|
||||
@@ -3074,18 +3103,18 @@ class AetherSettingsView(PanelManagerView):
|
||||
toggle_take = AETHER_LIST_METRICS.toggle_width + AETHER_LIST_METRICS.toggle_right_inset + 16
|
||||
col_w = max(100.0, content_width + AETHER_LIST_METRICS.content_right_gutter - toggle_take)
|
||||
desc_font = gui_app.font(FontWeight.NORMAL)
|
||||
desc_lines = wrap_text(desc_font, subtitle_text, col_w, 20, max_lines=4)
|
||||
h += len(desc_lines) * 24.0 + 12.0
|
||||
desc_lines = wrap_text(desc_font, subtitle_text, col_w, 29, max_lines=4)
|
||||
h += len(desc_lines) * PANEL_HEADER_SUBTITLE_LINE_HEIGHT + 12.0
|
||||
h += SECTION_GAP
|
||||
return h
|
||||
h = 40.0 # title (32px) + inner gap (8px)
|
||||
h = 54.0 # title (46px) + inner gap (8px)
|
||||
if self._header_subtitle:
|
||||
subtitle_text = tr(self._header_subtitle)
|
||||
if subtitle_text:
|
||||
desc_font = gui_app.font(FontWeight.NORMAL)
|
||||
col_w = (content_width - self.COLUMN_GAP) / 2 if self._uses_two_columns(content_width) else content_width
|
||||
desc_lines = wrap_text(desc_font, subtitle_text, col_w, 20, max_lines=4)
|
||||
h += len(desc_lines) * 24.0 + 12.0
|
||||
desc_lines = wrap_text(desc_font, subtitle_text, col_w, 29, max_lines=4)
|
||||
h += len(desc_lines) * PANEL_HEADER_SUBTITLE_LINE_HEIGHT + 12.0
|
||||
h += SECTION_GAP
|
||||
return h
|
||||
|
||||
@@ -3344,7 +3373,7 @@ class AetherSettingsView(PanelManagerView):
|
||||
is_last=is_last,
|
||||
action_pill=True,
|
||||
title_size=34, subtitle_size=22,
|
||||
action_pill_height=44, action_text_size=18,
|
||||
action_pill_height=AETHER_LIST_METRICS.toggle_height, action_text_size=24,
|
||||
action_text_color=action_text_color,
|
||||
action_fill=action_fill,
|
||||
action_border=action_border,
|
||||
@@ -4031,7 +4060,7 @@ class HubTile(AetherTile):
|
||||
self.desc = desc
|
||||
self.custom_icon_key = icon_key if icon_key in ("sound", "steering", "navigate", "system", "display", "vehicle", "road", "aicar") else None
|
||||
self._icon = None
|
||||
self._font_title = gui_app.font(FontWeight.BOLD)
|
||||
self._font_title = gui_app.font(FontWeight.MEDIUM)
|
||||
self._font_desc = gui_app.font(FontWeight.MEDIUM)
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
@@ -4048,7 +4077,7 @@ class HubTile(AetherTile):
|
||||
text_scale = max(0.82, min(1.12, min(rw / 360.0, rh / 205.0)))
|
||||
gap = SPACING.line_gap
|
||||
|
||||
title_size = max(58, int(round(64 * text_scale)))
|
||||
title_size = max(44, int(round(50 * text_scale)))
|
||||
desc_to_render = status_text
|
||||
desc_size = max(46, int(round(52 * text_scale))) if desc_to_render else 0
|
||||
|
||||
|
||||
@@ -353,6 +353,11 @@ class StarPilotAppearanceLayout(_SettingsPage):
|
||||
get_state=lambda: self._params.get_bool("StoppedTimer"),
|
||||
set_state=lambda s: self._params.put_bool("StoppedTimer", s),
|
||||
visible=hud_on),
|
||||
SettingRow("ShowCSCStatus", "toggle", tr_noop("CSC Status Widget"),
|
||||
subtitle=tr_noop("Show the Curve Speed Controller target speed and ambient border glow."),
|
||||
get_state=lambda: self._params.get_bool("ShowCSCStatus"),
|
||||
set_state=lambda s: self._params.put_bool("ShowCSCStatus", s),
|
||||
visible=hud_on),
|
||||
]
|
||||
|
||||
# ═══ 3. Screen Declutter & Visibility ═══
|
||||
|
||||
@@ -452,7 +452,7 @@ class ConditionalDriveModeView(PanelManagerView):
|
||||
|
||||
max_container_h = available_h
|
||||
|
||||
left_row_h = max(80.0, (max_container_h - 16.0) / max(1, len(keys)))
|
||||
left_row_h = max(95.0, (max_container_h - 16.0) / max(1, len(keys)))
|
||||
for key in keys:
|
||||
self._adjustor_rows[key].custom_row_height = left_row_h
|
||||
|
||||
@@ -502,7 +502,7 @@ class ConditionalDriveModeView(PanelManagerView):
|
||||
|
||||
def _draw_adjustors(self, y: float, x: float, width: float, keys: list[str]):
|
||||
draw_list_group_shell(rl.Rectangle(x, y, width, self._left_container_h), style=PANEL_STYLE)
|
||||
current_y = y + 8
|
||||
current_y = y + 4
|
||||
for index, key in enumerate(keys):
|
||||
adjustor = self._adjustor_rows[key]
|
||||
row_h = adjustor.measure_height(width)
|
||||
@@ -761,11 +761,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 4. Adaptive Speed Controls Rows (CES + CSC + CCM) ──
|
||||
self._curve_speed_controller_rows = [
|
||||
SettingRow("ShowCSCStatus", "toggle", tr_noop("Status Widget"),
|
||||
subtitle=tr_noop("Show the Curve Speed Controller ambient effect on the driving screen."),
|
||||
get_state=lambda: self._params.get_bool("ShowCSCStatus"),
|
||||
set_state=lambda s: self._params.put_bool("ShowCSCStatus", s),
|
||||
visible=csc_on),
|
||||
SettingRow("CalibratedLatAccel", "value", tr_noop("Calibrated Lateral Accel"),
|
||||
subtitle=tr_noop("The learned lateral acceleration from collected driving data. Higher values allow faster cornering."),
|
||||
get_value=lambda: f"{self._params_memory.get_float('CalibratedLateralAcceleration'):.2f} m/s",
|
||||
@@ -920,13 +915,9 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
self._sub_panels["ce"] = ConditionalDriveModeView(self)
|
||||
|
||||
|
||||
csc_rows = self._curve_speed_controller_rows
|
||||
self._sub_panels["csc"] = AetherSettingsView(
|
||||
self,
|
||||
[
|
||||
SettingSection(tr("Curve Speed Controller"), [x for x in csc_rows if x.type != "toggle"], column_pair="1"),
|
||||
SettingSection(tr("Curve Speed Controller"), [x for x in csc_rows if x.type == "toggle"], column_pair="1"),
|
||||
],
|
||||
[SettingSection(tr("Curve Speed Controller"), self._curve_speed_controller_rows)],
|
||||
header_title=tr("Curve Speed Controller"),
|
||||
header_subtitle=tr("Configure speed control on curves and reset collected calibration data."),
|
||||
parent_toggle=pt_csc,
|
||||
|
||||
@@ -248,14 +248,14 @@ class SoundsManagerView(PanelManagerView):
|
||||
else:
|
||||
available_container_h = 0.0
|
||||
|
||||
left_available_for_rows = available_container_h - 20.0 - 16.0 - hdr_h
|
||||
left_available_for_rows = available_container_h - 12.0 - 4.0 - hdr_h
|
||||
left_row_h = max(80.0, min(107.0, left_available_for_rows / (len(self._controller.VOLUME_KEYS) + 1)))
|
||||
for key in self._controller.VOLUME_KEYS:
|
||||
self._adjustor_rows[key].custom_row_height = left_row_h
|
||||
self._adjustor_rows[self._controller.COOLDOWN_KEY].custom_row_height = left_row_h
|
||||
|
||||
left_content_h = (len(self._controller.VOLUME_KEYS) + 1) * left_row_h + 20 + 16 + hdr_h
|
||||
tiles_needed_h = self.measure_page_grid_height(self._toggle_grid, col_width - 24) + 24 + 8 + hdr_h
|
||||
left_content_h = (len(self._controller.VOLUME_KEYS) + 1) * left_row_h + 12 + 4 + hdr_h
|
||||
tiles_needed_h = self.measure_page_grid_height(self._toggle_grid, col_width - 24) + 24 + 4 + hdr_h
|
||||
max_content_h = max(left_content_h, tiles_needed_h)
|
||||
|
||||
self._left_container_h = max_content_h
|
||||
@@ -289,23 +289,23 @@ class SoundsManagerView(PanelManagerView):
|
||||
style=PANEL_STYLE
|
||||
)
|
||||
|
||||
current_y = y + 8
|
||||
current_y = y + 4
|
||||
current_y = draw_group_header(x + 24, current_y, width - 48, tr("VOLUME"))
|
||||
|
||||
label_rect = rl.Rectangle(x + 24, current_y - GROUP_HEADER_HEIGHT - GROUP_HEADER_LINE_GAP - GROUP_HEADER_GAP, width - 48, GROUP_HEADER_HEIGHT)
|
||||
gui_label(label_rect, tr("Reset All"), 18, AetherListColors.MUTED, FontWeight.NORMAL,
|
||||
gui_label(label_rect, tr("Reset All"), 20, AetherListColors.MUTED, FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT)
|
||||
self._reset_rect = rl.Rectangle(label_rect.x + label_rect.width - 80, label_rect.y, 80, 45)
|
||||
self._interactive_rects["action:restore_defaults"] = self._reset_rect
|
||||
for i, (label, keys) in enumerate(groups):
|
||||
if label is not None:
|
||||
divider_h = 4
|
||||
divider_h = 3
|
||||
divider_color = rl.Color(173, 78, 90, 30) if i == 1 else rl.Color(139, 92, 246, 25)
|
||||
rl.draw_rectangle_rec(
|
||||
rl.Rectangle(x + 24, current_y, width - 48, divider_h),
|
||||
divider_color
|
||||
)
|
||||
current_y += divider_h + 6
|
||||
current_y += divider_h + 3
|
||||
for index, key in enumerate(keys):
|
||||
adjustor = self._adjustor_rows[key]
|
||||
row_h = adjustor.measure_height(width)
|
||||
@@ -317,7 +317,7 @@ class SoundsManagerView(PanelManagerView):
|
||||
|
||||
def _draw_utility_column(self, y: float, x: float, width: float):
|
||||
draw_list_group_shell(rl.Rectangle(x, y, width, self._tiles_container_h), style=PANEL_STYLE)
|
||||
header_y = draw_group_header(x + 24, y + 8, width - 48, tr("ALERTS"))
|
||||
header_y = draw_group_header(x + 24, y + 4, width - 48, tr("ALERTS"))
|
||||
avail_h = self._tiles_container_h - (header_y - y)
|
||||
self._render_page_grid(self._toggle_grid, rl.Rectangle(x + 12, header_y, width - 24, max(0.0, avail_h - 12)))
|
||||
|
||||
|
||||
@@ -482,8 +482,8 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
def _measure_content_height(self, width: float) -> float:
|
||||
hdr_h = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
display_h = self._slider_section_height(self._display_slider_keys, width) + 8 + hdr_h
|
||||
power_h = self._slider_section_height(self._power_slider_keys, width) + 8 + hdr_h
|
||||
display_h = self._slider_section_height(self._display_slider_keys, width) + 4 + hdr_h
|
||||
power_h = self._slider_section_height(self._power_slider_keys, width) + 4 + hdr_h
|
||||
|
||||
if self._uses_two_columns(width):
|
||||
column_w = self._column_width(width)
|
||||
@@ -496,7 +496,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
display_container_h = self._slider_section_height(self._display_slider_keys, column_w)
|
||||
power_container_h = self._slider_section_height(self._power_slider_keys, column_w)
|
||||
|
||||
left_overhead = 8.0 + 2 * (GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP) + SECTION_GAP
|
||||
left_overhead = 4.0 + 2 * (GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP) + SECTION_GAP
|
||||
left_natural_content_h = left_overhead + display_container_h + power_container_h
|
||||
|
||||
tiles_content_h = self.measure_page_grid_height(self._connectivity_tile_grid, column_w - 24)
|
||||
@@ -548,7 +548,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
draw_list_group_shell(rl.Rectangle(x, y, column_w, adj_container_h), style=PANEL_STYLE)
|
||||
|
||||
current_y = y + 8
|
||||
current_y = y + 4
|
||||
current_y = draw_group_header(x + 24, current_y, column_w - 48, tr("DISPLAY"))
|
||||
for index, key in enumerate(self._display_slider_keys):
|
||||
current_y = self._draw_slider_row(rl.Rectangle(x, current_y, column_w, 0), key, is_last=index == len(self._display_slider_keys) - 1)
|
||||
@@ -575,10 +575,10 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
self._render_page_grid(self._connectivity_tile_grid, rl.Rectangle(x + 12, y + 12, width - 24, tiles_content_h))
|
||||
|
||||
def _draw_slider_section(self, y: float, x: float, width: float, title: str, keys: list[str]) -> float:
|
||||
group_h = self._slider_section_height(keys, width) + 8 + GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
group_h = self._slider_section_height(keys, width) + 4 + GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
group_rect = rl.Rectangle(x, y, width, group_h)
|
||||
draw_list_group_shell(group_rect, style=PANEL_STYLE)
|
||||
current_y = group_rect.y + 8
|
||||
current_y = group_rect.y + 4
|
||||
current_y = draw_group_header(x + 24, current_y, width - 48, title)
|
||||
for index, key in enumerate(keys):
|
||||
current_y = self._draw_slider_row(rl.Rectangle(group_rect.x, current_y, group_rect.width, 0), key, is_last=index == len(keys) - 1)
|
||||
|
||||
@@ -177,9 +177,9 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
|
||||
def _draw_section(self, y: float, x: float, width: float, title: str, rows: list[SettingRow], row_height: float = ROW_HEIGHT) -> float:
|
||||
hdr_oh = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
group_h = len(rows) * row_height + hdr_oh + 8
|
||||
group_h = len(rows) * row_height + hdr_oh + 4
|
||||
draw_list_group_shell(rl.Rectangle(x, y, width, group_h), style=PANEL_STYLE)
|
||||
current_y = y + 8
|
||||
current_y = y + 4
|
||||
current_y = draw_group_header(x + 24, current_y, width - 48, tr(title))
|
||||
for i, row in enumerate(rows):
|
||||
self._draw_row(rl.Rectangle(x, current_y, width, row_height), row, i == len(rows) - 1)
|
||||
@@ -196,7 +196,7 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
rx = rect.x + col_w + self.COLUMN_GAP
|
||||
|
||||
draw_list_group_shell(rl.Rectangle(rect.x, y, col_w, self._container_h), style=PANEL_STYLE)
|
||||
row_y = y + 8
|
||||
row_y = y + 4
|
||||
row_y = draw_group_header(rect.x + 24, row_y, col_w - 48, tr("Vehicle Identity"))
|
||||
for i, row in enumerate(identity_rows):
|
||||
self._draw_row(rl.Rectangle(rect.x, row_y, col_w, self._left_row_height),
|
||||
@@ -212,7 +212,7 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
|
||||
if self._toggle_grid.tiles:
|
||||
draw_list_group_shell(rl.Rectangle(rx, y, col_w, self._container_h), style=PANEL_STYLE)
|
||||
tile_y = y + 8
|
||||
tile_y = y + 4
|
||||
tile_y = draw_group_header(rx + 24, tile_y, col_w - 48, tr("Features"))
|
||||
avail_h = self._container_h - (tile_y - y)
|
||||
self._render_page_grid(self._toggle_grid, rl.Rectangle(rx + 12, tile_y, col_w - 24, max(0.0, avail_h - 12)))
|
||||
@@ -227,9 +227,9 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
avail = width - 24
|
||||
th = self.measure_page_grid_height(self._toggle_grid, avail)
|
||||
hdr_oh = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
group_h = th + 24 + 8 + hdr_oh
|
||||
group_h = th + 24 + 4 + hdr_oh
|
||||
draw_list_group_shell(rl.Rectangle(rect.x, y, width, group_h), style=PANEL_STYLE)
|
||||
features_y = y + 8
|
||||
features_y = y + 4
|
||||
features_y = draw_group_header(rect.x + 24, features_y, width - 48, tr("Features"))
|
||||
self._render_page_grid(self._toggle_grid, rl.Rectangle(rect.x + 12, features_y, avail, max(0.0, group_h - (features_y - y) - 12)))
|
||||
|
||||
@@ -251,7 +251,7 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
|
||||
if self._uses_two_columns(width):
|
||||
hdr_oh = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
subsection_overhead = hdr_oh + 8
|
||||
subsection_overhead = hdr_oh + 4
|
||||
if steering_rows:
|
||||
subsection_overhead += hdr_oh
|
||||
|
||||
@@ -273,10 +273,10 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
|
||||
self._left_row_height = ROW_HEIGHT
|
||||
hdr_oh = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP
|
||||
identity_natural_h = hdr_oh + 8 + len(identity_rows) * ROW_HEIGHT
|
||||
steering_natural_h = hdr_oh + 8 + len(steering_rows) * ROW_HEIGHT
|
||||
identity_natural_h = hdr_oh + 4 + len(identity_rows) * ROW_HEIGHT
|
||||
steering_natural_h = hdr_oh + 4 + len(steering_rows) * ROW_HEIGHT
|
||||
left_natural_h = identity_natural_h + SECTION_GAP + steering_natural_h
|
||||
tiles_overhead = 8 + hdr_oh + 24 if tiles_h else 0
|
||||
tiles_overhead = 4 + hdr_oh + 24 if tiles_h else 0
|
||||
return left_natural_h + tiles_h + tiles_overhead
|
||||
|
||||
def _build_driving_toggles(self) -> list[dict]:
|
||||
|
||||
Reference in New Issue
Block a user