diff --git a/openpilot/starpilot/ui/onroad_large_widgets.py b/openpilot/starpilot/ui/onroad_large_widgets.py index e2eedb15da..d37f68cf5c 100644 --- a/openpilot/starpilot/ui/onroad_large_widgets.py +++ b/openpilot/starpilot/ui/onroad_large_widgets.py @@ -16,7 +16,7 @@ from openpilot.starpilot.ui.onroad_widget_style import draw_control_card from openpilot.starpilot.ui.presentation import BitmapFonts, FontRole, Profile from openpilot.starpilot.ui.wheel_feedback import WheelFeedbackFade from openpilot.starpilot.ui.unified_speed_presentation import resolve_unified_speed -from openpilot.starpilot.ui.speed_limit_widget import SpeedLimitWidget, draw_caption, draw_ink, draw_text +from openpilot.starpilot.ui.speed_limit_widget import MUTED, SpeedLimitWidget, draw_caption, draw_ink, draw_line, draw_text ENGAGED = rl.Color(128, 216, 166, 255) @@ -78,7 +78,11 @@ class UnifiedSpeedWidget: border = rl.Color(*rgba(state.customization, 'cardBorder', 'large', 'cruise_limits')) text = rl.Color(*rgba(state.customization, 'text', 'large', 'cruise_limits')) if shown.mode != 'limit_only': - if manual_slc_confirmation(Profile.LARGE, state): + if shown.max_text == '–': + center = rect.x + 120 + draw_caption(self.fonts, 'SET', center, rect.y + 15, unit=shown.unit, centered=True) + draw_line(Profile.LARGE, rl.Vector2(center - 28, rect.y + 101), rl.Vector2(center + 28, rect.y + 101), 8, MUTED) + elif manual_slc_confirmation(Profile.LARGE, state): x = rect.x + PADDING draw_caption(self.fonts, 'SET', x, rect.y + 19, unit=shown.unit, size=32) size = 120 @@ -92,10 +96,8 @@ class UnifiedSpeedWidget: size *= min(1, 200 / max(1, self.fonts.measure(shown.max_text, FontRole.SET_SPEED, size).width)) left, right = self.fonts.horizontal_ink(shown.max_text, FontRole.SET_SPEED, size) top, bottom = self.fonts.vertical_ink(shown.max_text, FontRole.SET_SPEED, size) - # The pinned DINish dash has 15 inked rows in its 200-pixel atlas cell. - number_height = size * self.fonts.profile.font_scale * 15 / 200 if shown.max_text == '–' else bottom - top draw_ink(self.fonts, shown.max_text, FontRole.SET_SPEED, size, center - (left + right) / 2, - rect.y + 101 - number_height / 2, text) + rect.y + 101 - (bottom - top) / 2, text) self.sign.render(state, defer_confirmation=True) if shown.mode == 'limit_only' and (bounds := speed_limit_bounds(Profile.LARGE, state)) is not None: draw_ink(self.fonts, shown.unit, FontRole.NORMAL, 24, bounds[2], bounds[3] - 32) diff --git a/openpilot/starpilot/ui/tests/test_dinish_speed.py b/openpilot/starpilot/ui/tests/test_dinish_speed.py index bb8813677f..a052115f9d 100644 --- a/openpilot/starpilot/ui/tests/test_dinish_speed.py +++ b/openpilot/starpilot/ui/tests/test_dinish_speed.py @@ -127,7 +127,7 @@ def test_large_sign_is_secondary_to_set_speed_at_the_saved_position(): current = replace(current, metric=metric, cruise_kph=value / factor * 3.6 if value else None, speed_limit=observation) calls = [] - with patch.object(fonts, 'draw', lambda *args, calls=calls: calls.append(args)): + with patch.object(fonts, 'draw', lambda *args, calls=calls: calls.append(args)), patch.object(rl, 'draw_line_ex') as lines: UnifiedSpeedWidget(fonts).render(rl.Rectangle(30, 30, 1800, 1020), current) calls = [call for call in calls if call[-1].a == 255] posted = next(call for call in calls if call[0] == '120' and call[1] == FontRole.SET_SPEED) @@ -138,7 +138,7 @@ def test_large_sign_is_secondary_to_set_speed_at_the_saved_position(): assert b - a == pytest.approx(60, abs=.1) assert abs(posted[4]+(a+b)/2-(95+67*1.25)) <= .5 set_calls = [call for call in calls if call[1] == FontRole.SET_SPEED and call[3] < 388] - assert bool(set_calls) == show_set + assert bool(set_calls) == (show_set and value is not None) if set_calls: text, role, size, x, y, _ = set_calls[0] assert fonts.measure(text, role, size).width <= 200 @@ -146,14 +146,18 @@ def test_large_sign_is_secondary_to_set_speed_at_the_saved_position(): assert x + (left + right) / 2 == pytest.approx(308) assert x + right + 20 <= 418 top, bottom = fonts.vertical_ink(text, role, size) - if value is not None: - assert bottom - top == pytest.approx(88, abs=1) - assert y + (top + bottom) / 2 == pytest.approx(196) - else: - assert y + top + size * fonts.profile.font_scale * 15 / 400 == pytest.approx(196) + assert bottom - top == pytest.approx(88, abs=1) + assert y + (top + bottom) / 2 == pytest.approx(196) unit = next(call for call in calls if call[0] == ('km/h' if metric else 'mph')) assert unit[2] == 28 assert unit[4] + fonts.vertical_ink(unit[0], unit[1], unit[2])[1] + 12 <= y + top + if show_set and value is None: + start, end, stroke, color = lines.call_args.args + assert (start.x, start.y, end.x, end.y, stroke) == (280, 196, 336, 196, 8) + assert (color.r, color.g, color.b, color.a) == (190, 208, 202, 255) + assert all(call[0] not in ('–', '?') for call in calls) + else: + lines.assert_not_called() finally: if owns_context: rl.close_window() diff --git a/openpilot/starpilot/ui/tests/test_unified_speed_native.py b/openpilot/starpilot/ui/tests/test_unified_speed_native.py index bfd93e21ea..6f29349878 100644 --- a/openpilot/starpilot/ui/tests/test_unified_speed_native.py +++ b/openpilot/starpilot/ui/tests/test_unified_speed_native.py @@ -292,6 +292,18 @@ def test_compact_max_restores_dinish_number_label_and_shadow(drawing): drawing['draw_circle_gradient'].assert_called_once() +@pytest.mark.parametrize('metric', [False, True]) +@pytest.mark.parametrize('engaged', [False, True]) +def test_compact_unset_max_stays_hidden(metric, engaged, drawing): + font = fonts(Profile.COMPACT) + hud = CompactHudRenderer(font, Mock()) + current = state(metric=metric, engaged=engaged, longitudinal_active=engaged, cruise_kph=None, drive_frame=1) + hud.render_max_speed(current) + hud.render_max_speed(replace(current, observed_ns=current.observed_ns + 20_000_000)) + font.draw.assert_not_called() + drawing['draw_circle_gradient'].assert_not_called() + + def test_large_limit_keeps_a_unit_when_set_speed_is_hidden(): profile = Profile.LARGE current = state()