SDL2/GStreamer DLNA browser for R36S by Matteo Benedetto
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

160 lines
4.7 KiB

from __future__ import annotations
import ctypes
from queue import Queue
from r36s_dlna_browser.dlna.browser_state import BrowserState
from r36s_dlna_browser.platform.controls import Action
from r36s_dlna_browser.ui import theme
from r36s_dlna_browser.ui import sdl_app as sdl_app_module
from r36s_dlna_browser.ui.sdl_app import SDLApp, Screen
class DummyPlayer:
def __init__(self) -> None:
self._new_frame = False
self.viewport = None
def attach_window(self, _window) -> None:
pass
def set_viewport(self, *args) -> None:
self.viewport = args
def has_new_frame(self) -> bool:
return self._new_frame
def render(self, _renderer) -> bool:
self._new_frame = False
return True
def _make_app() -> SDLApp:
return SDLApp(Queue(), Queue(), BrowserState(), DummyPlayer())
def test_non_playback_draws_only_when_dirty() -> None:
app = _make_app()
app._screen = Screen.SERVERS
app._needs_redraw = False
assert app._should_draw() is False
app._mark_dirty()
assert app._should_draw() is True
def test_playback_snapshot_change_waits_for_refresh_interval(monkeypatch) -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
app._needs_redraw = False
app._last_playback_snapshot = app._playback_snapshot()
app._last_playback_draw_at = 10.0
app._state.playback_position = 1.0
monkeypatch.setattr(sdl_app_module.time, "monotonic", lambda: 10.1)
assert app._should_draw() is False
def test_playback_snapshot_change_redraws_after_refresh_interval(monkeypatch) -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
app._needs_redraw = False
app._last_playback_snapshot = app._playback_snapshot()
app._last_playback_draw_at = 10.0
app._state.playback_position = 1.0
monkeypatch.setattr(sdl_app_module.time, "monotonic", lambda: 10.3)
assert app._should_draw() is True
def test_playback_snapshot_without_changes_does_not_redraw(monkeypatch) -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
app._needs_redraw = False
app._last_playback_snapshot = app._playback_snapshot()
app._last_playback_draw_at = 10.0
monkeypatch.setattr(sdl_app_module.time, "monotonic", lambda: 10.5)
assert app._should_draw() is False
def test_playback_draws_immediately_for_new_video_frame() -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
app._needs_redraw = False
app._player._new_frame = True
assert app._should_draw() is True
def test_hud_mode_cycles_auto_fixed_hidden(monkeypatch) -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
monkeypatch.setattr(sdl_app_module.time, "monotonic", lambda: 12.0)
app._handle_action(Action.HUD_MODE)
assert app._state.playback_hud_mode == theme.PLAYBACK_HUD_PINNED
assert app._state.playback_hud_visible is True
app._handle_action(Action.HUD_MODE)
assert app._state.playback_hud_mode == theme.PLAYBACK_HUD_HIDDEN
assert app._state.playback_hud_visible is False
app._handle_action(Action.HUD_MODE)
assert app._state.playback_hud_mode == theme.PLAYBACK_HUD_AUTO
assert app._state.playback_hud_visible is True
def test_paused_playback_keeps_hud_visible_in_auto_mode(monkeypatch) -> None:
app = _make_app()
app._screen = Screen.PLAYBACK
app._state.playback_hud_mode = theme.PLAYBACK_HUD_AUTO
app._state.playback_hud_visible = False
app._state.playback_paused = True
monkeypatch.setattr(sdl_app_module.time, "monotonic", lambda: 99.0)
app._refresh_playback_hud_visibility()
assert app._state.playback_hud_visible is True
def test_layout_scales_for_square_display() -> None:
compact = theme.get_layout(640, 480)
square = theme.get_layout(720, 720)
assert square.visible_items > compact.visible_items
assert square.list_item_h > compact.list_item_h
assert square.playback_hud_top > compact.playback_hud_top
def test_sync_player_viewport_uses_runtime_layout(monkeypatch) -> None:
app = _make_app()
app._window = object()
def fake_get_window_size(_window, width_ptr, height_ptr):
width = ctypes.cast(width_ptr, ctypes.POINTER(ctypes.c_int))
height = ctypes.cast(height_ptr, ctypes.POINTER(ctypes.c_int))
width.contents.value = 720
height.contents.value = 720
monkeypatch.setattr(sdl_app_module.sdl2, "SDL_GetWindowSize", fake_get_window_size)
app._sync_player_viewport()
layout = app._layout
assert layout.width == 720
assert layout.height == 720
assert app._player.viewport == (
720,
720,
layout.playback_hud_top,
720 - layout.playback_video_bottom,
layout.playback_video_left,
720 - layout.playback_video_right,
)