mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-01 03:24:05 +08:00
Pagination Edge Gradient Cleanup
This commit is contained in:
@@ -114,21 +114,22 @@ class FeatureSettingsView:
|
||||
self._value_row(state, state.rows[0], rl.Rectangle(*value_editor_rect(state)), buttons)
|
||||
self._value_done(state)
|
||||
return
|
||||
can_page = drag_x != 0 and feature_scroll(state.scroll, 1 if drag_x < 0 else -1, len(state.rows)) != state.scroll
|
||||
rows_state, pull_x, cover = self._page_frame(state, feature_pull(drag_x, can_page), drag_x != 0)
|
||||
if pull_x and can_page:
|
||||
edge_x = 2125 - FEATURE_FLICK_DISTANCE if pull_x < 0 else left + 25
|
||||
gap_x = 2125 + pull_x if pull_x < 0 else left - 20
|
||||
gap_right = 2160 if pull_x < 0 else left + 25 + pull_x
|
||||
color_left, color_right = (PANEL_BG, EDGE_ACCENT) if pull_x < 0 else (EDGE_ACCENT, PANEL_BG)
|
||||
rl.draw_rectangle_gradient_ex(rl.Rectangle(gap_x, row_top, gap_right - gap_x, FEATURE_VISIBLE_ROWS * FEATURE_ROW_HEIGHT),
|
||||
color_left, color_left, color_right, color_right)
|
||||
cx, cy = edge_x + FEATURE_FLICK_DISTANCE / 2, row_top + FEATURE_VISIBLE_ROWS * FEATURE_ROW_HEIGHT / 2
|
||||
direction = 1 if pull_x < 0 else -1
|
||||
tip = rl.Vector2(cx + direction * 8, cy)
|
||||
rl.draw_line_ex(rl.Vector2(cx - direction * 8, cy - 16), tip, 4, TEXT_PRIMARY)
|
||||
rl.draw_line_ex(tip, rl.Vector2(cx - direction * 8, cy + 16), 4, TEXT_PRIMARY)
|
||||
clip.begin_scissor_mode(left + 25, row_top, 2100 - left, FEATURE_VISIBLE_ROWS * FEATURE_ROW_HEIGHT)
|
||||
try:
|
||||
can_page = drag_x != 0 and feature_scroll(state.scroll, 1 if drag_x < 0 else -1, len(state.rows)) != state.scroll
|
||||
rows_state, pull_x, cover = self._page_frame(state, feature_pull(drag_x, can_page), drag_x != 0)
|
||||
if pull_x and can_page:
|
||||
edge_x = 2125 - FEATURE_FLICK_DISTANCE if pull_x < 0 else left + 25
|
||||
gap_x = 2125 + pull_x if pull_x < 0 else left + 25
|
||||
color_left, color_right = (PANEL_BG, EDGE_ACCENT) if pull_x < 0 else (EDGE_ACCENT, PANEL_BG)
|
||||
rl.draw_rectangle_gradient_ex(rl.Rectangle(gap_x, row_top, abs(pull_x), FEATURE_VISIBLE_ROWS * FEATURE_ROW_HEIGHT),
|
||||
color_left, color_left, color_right, color_right)
|
||||
cx, cy = edge_x + FEATURE_FLICK_DISTANCE / 2, row_top + FEATURE_VISIBLE_ROWS * FEATURE_ROW_HEIGHT / 2
|
||||
direction = 1 if pull_x < 0 else -1
|
||||
tip = rl.Vector2(cx + direction * 8, cy)
|
||||
rl.draw_line_ex(rl.Vector2(cx - direction * 8, cy - 16), tip, 4, TEXT_PRIMARY)
|
||||
rl.draw_line_ex(tip, rl.Vector2(cx - direction * 8, cy + 16), 4, TEXT_PRIMARY)
|
||||
if pull_x:
|
||||
rl.rl_push_matrix()
|
||||
try:
|
||||
|
||||
@@ -1270,16 +1270,11 @@ class StarShellSession:
|
||||
pane = _FEATURE_SETTINGS_PANES.get(snapshot.selected)
|
||||
drag_x = getattr(self.input, pane[2]).drag_x if pane else 0.0
|
||||
self.view.render(replace(snapshot, selected=Destination.NETWORK) if external else snapshot, drag_x=drag_x)
|
||||
if external:
|
||||
self.view.settings.render_rail(snapshot.settings, selected=snapshot.selected)
|
||||
if mode == ShellMode.ONROAD:
|
||||
self.favorites.render(time.monotonic())
|
||||
if self.notice and time.monotonic() < self.notice_until:
|
||||
rl.draw_rectangle(0, self.profile.size[1] - 42, self.profile.size[0], 42, rl.Color(0, 0, 0, 220))
|
||||
self.fonts.draw(self.notice[:65], FontRole.MEDIUM, 23 if self.profile == Profile.COMPACT else 27,
|
||||
12, self.profile.size[1] - 37)
|
||||
if (mode == ShellMode.SETTINGS and self.profile == Profile.LARGE and snapshot.selected == Destination.NETWORK and
|
||||
snapshot.settings.destination(Destination.NETWORK).available and self.network_layer is not None):
|
||||
network = (mode == ShellMode.SETTINGS and self.profile == Profile.LARGE and snapshot.selected == Destination.NETWORK and
|
||||
snapshot.settings.destination(Destination.NETWORK).available and self.network_layer is not None)
|
||||
if network:
|
||||
rail_width = 500 if snapshot.settings.sidebar_expanded else 0
|
||||
content = rl.Rectangle(rect.x + rail_width + 50, rect.y + 25,
|
||||
rect.width - rail_width - 100, rect.height - 50)
|
||||
@@ -1291,12 +1286,20 @@ class StarShellSession:
|
||||
self._on_destination_change(Destination.STAR)
|
||||
self._unavailable("network panel is unavailable")
|
||||
|
||||
if (mode == ShellMode.SETTINGS and self.profile == Profile.LARGE and
|
||||
snapshot.selected in NATIVE_SETTINGS_PANELS and self.settings_layer is not None):
|
||||
if external:
|
||||
rail_width = 500 if snapshot.settings.sidebar_expanded else 0
|
||||
content = rl.Rectangle(rect.x + rail_width + 50, rect.y + 25, rect.width - rail_width - 100, rect.height - 50)
|
||||
self.settings_layer(snapshot.selected, content)
|
||||
|
||||
if external or network or self.notice:
|
||||
with placed_at(rect, parent_clip):
|
||||
if external or network:
|
||||
self.view.settings.render_rail(snapshot.settings, selected=snapshot.selected)
|
||||
if self.notice and time.monotonic() < self.notice_until:
|
||||
rl.draw_rectangle(0, self.profile.size[1] - 42, self.profile.size[0], 42, rl.Color(0, 0, 0, 220))
|
||||
self.fonts.draw(self.notice[:65], FontRole.MEDIUM, 23 if self.profile == Profile.COMPACT else 27,
|
||||
12, self.profile.size[1] - 37)
|
||||
|
||||
def _unavailable(self, label: str) -> None:
|
||||
self.notice = f"Unavailable: {label}"
|
||||
self.notice_until = time.monotonic() + 3.0
|
||||
|
||||
@@ -272,6 +272,9 @@ class FeatureVisualTests(unittest.TestCase):
|
||||
rl.draw_line_ex.reset_mock()
|
||||
for transform in (rl.rl_push_matrix, rl.rl_translatef, rl.rl_pop_matrix):
|
||||
transform.reset_mock()
|
||||
draws = Mock()
|
||||
for name in ("draw_rectangle_gradient_ex", "draw_line_ex", "begin_scissor_mode", "draw_rectangle_rec"):
|
||||
draws.attach_mock(getattr(rl, name), name)
|
||||
fonts = fake_fonts()
|
||||
with patch.object(view, "feature_scroll", wraps=feature_scroll) as paging, patch.object(view, "draw_settings_header"):
|
||||
view.FeatureSettingsView(fonts).render(FeatureSettingsState(rows=rows, scroll=scroll, sidebar_expanded=expanded), drag)
|
||||
@@ -300,11 +303,19 @@ class FeatureVisualTests(unittest.TestCase):
|
||||
gradient = rl.draw_rectangle_gradient_ex.call_args
|
||||
gap = abs(view.feature_pull(drag, can_page))
|
||||
bounds = gradient.args[0]
|
||||
gap_x = 2125 - gap if drag < 0 else left - 20
|
||||
gap_right = 2160 if drag < 0 else left + 25 + gap
|
||||
self.assertEqual((bounds.x, bounds.y, bounds.width, bounds.height),
|
||||
(2125 - gap if drag < 0 else left + 25, FEATURE_ROW_TOP, gap, 5 * FEATURE_ROW_HEIGHT))
|
||||
(gap_x, FEATURE_ROW_TOP, gap_right - gap_x, 5 * FEATURE_ROW_HEIGHT))
|
||||
color_left, color_right = (geometry.PANEL_BG, view.EDGE_ACCENT) if drag < 0 else (view.EDGE_ACCENT, geometry.PANEL_BG)
|
||||
self.assertEqual(gradient.args[1:], (color_left, color_left, color_right, color_right))
|
||||
self.assertEqual(rl.draw_line_ex.call_args.args[0].x, (2095 if drag < 0 else left + 55) + (8 if drag < 0 else -8))
|
||||
order = [call[0] for call in draws.mock_calls]
|
||||
self.assertLess(order.index("draw_rectangle_gradient_ex"), order.index("draw_line_ex"))
|
||||
self.assertLess(max(index for index, name in enumerate(order) if name == "draw_line_ex"),
|
||||
max(index for index, name in enumerate(order) if name == "begin_scissor_mode"))
|
||||
self.assertLess(max(index for index, name in enumerate(order) if name == "begin_scissor_mode"),
|
||||
order.index("draw_rectangle_rec"))
|
||||
footer = [call for call in fonts.draw.call_args_list if call.args[0] in ("Previous", "Next")]
|
||||
self.assertEqual(len(footer), 2)
|
||||
|
||||
|
||||
@@ -161,6 +161,47 @@ class ShellActionTests(unittest.TestCase):
|
||||
self.assertEqual(shell_render.call_args.kwargs["drag_x"], 0)
|
||||
feature_render.assert_not_called()
|
||||
|
||||
def test_adapted_panels_draw_before_placed_navigation_and_notices(self):
|
||||
import pyray as rl
|
||||
from openpilot.starpilot.ui import clip, runtime_app
|
||||
from openpilot.starpilot.ui.settings_state import DestinationAvailability
|
||||
|
||||
rect = rl.Rectangle(20, 30, 2160, 1080)
|
||||
parent = rl.Rectangle(25, 35, 2140, 1060)
|
||||
for destination in (*runtime_app.NATIVE_SETTINGS_PANELS, Destination.NETWORK):
|
||||
for expanded in (True, False):
|
||||
with self.subTest(destination=destination, expanded=expanded):
|
||||
session = runtime_app.StarShellSession.__new__(runtime_app.StarShellSession)
|
||||
session.profile, session.slc_actions = Profile.LARGE, None
|
||||
session.favorites, session.pip_warning = Mock(), Mock()
|
||||
session.input, session.view, session.fonts = Mock(), Mock(), Mock()
|
||||
session.settings_layer, session.network_layer = Mock(), Mock(return_value=True)
|
||||
session.notice, session.notice_until = "Test notice", float("inf")
|
||||
settings = SettingsState(sidebar_expanded=expanded, availability=(DestinationAvailability(Destination.NETWORK, True),))
|
||||
snapshot = ShellSnapshot(ShellMode.SETTINGS, reference_state(), settings,
|
||||
OnroadState(False, False, None, None, SpeedLimitObservation()), selected=destination)
|
||||
session.snapshot = Mock(return_value=snapshot)
|
||||
def rail(*_args, **_kwargs):
|
||||
ox, oy, viewport, parent_clip = clip._placement.get()
|
||||
self.assertEqual((ox, oy, viewport.x, viewport.y, viewport.width, viewport.height), (20, 30, 25, 35, 2140, 1060))
|
||||
self.assertIs(parent_clip, parent)
|
||||
session.view.settings.render_rail.side_effect = rail
|
||||
order = Mock()
|
||||
order.attach_mock(session.view.render, "view")
|
||||
panel = session.network_layer if destination == Destination.NETWORK else session.settings_layer
|
||||
order.attach_mock(panel, "panel")
|
||||
order.attach_mock(session.view.settings.render_rail, "rail")
|
||||
order.attach_mock(session.fonts.draw, "notice")
|
||||
with patch.object(rl, "rl_push_matrix"), patch.object(rl, "rl_pop_matrix"), patch.object(rl, "rl_translatef"), \
|
||||
patch.object(rl, "begin_scissor_mode"), patch.object(rl, "end_scissor_mode"), patch.object(rl, "draw_rectangle"):
|
||||
session.render(ShellMode.SETTINGS, rect, parent)
|
||||
self.assertEqual([call[0] for call in order.mock_calls], ["view", "panel", "rail", "notice"])
|
||||
session.view.settings.render_rail.assert_called_once_with(settings, selected=destination)
|
||||
content = panel.call_args.args[-1]
|
||||
self.assertEqual((content.x, content.y, content.width, content.height),
|
||||
(570 if expanded else 70, 55, 1560 if expanded else 2060, 1030))
|
||||
self.assertIsNone(clip._placement.get())
|
||||
|
||||
def test_toggle_request_needs_same_displayed_value_on_release(self) -> None:
|
||||
requests = []
|
||||
touch = TogglesInput(requests.append)
|
||||
|
||||
Reference in New Issue
Block a user