Source code for mini_arcade_core.runtime.window.window_adapter

"""
Module providing runtime adapters for window and scene management.
"""

from __future__ import annotations

from mini_arcade_core.backend import Backend
from mini_arcade_core.engine.render.viewport import (
    Viewport,
    ViewportMode,
    ViewportState,
)
from mini_arcade_core.runtime.window.window_port import WindowPort
from mini_arcade_core.utils import logger


[docs] class WindowAdapter(WindowPort): """ Manages multiple game windows (not implemented). """ _drawable_size: tuple[int, int] def __init__(self, backend: Backend): self.backend = backend self.backend.init() w, h = self.backend.window.size() dw, dh = self.backend.window.drawable_size() self.size = (w, h) self._drawable_size = (dw, dh) self._initialized = True self._viewport = Viewport(w, h, mode=ViewportMode.FIT) self._viewport.resize(dw, dh) self._apply_viewport_transform() def _apply_viewport_transform(self): s = self._viewport.state # This is the missing link in the new backend design: if not hasattr(self.backend, "set_viewport_transform"): logger.warning( "Backend does not support viewport transforms. " "Viewport scaling and offset will not be applied." ) return self.backend.set_viewport_transform(s.offset_x, s.offset_y, s.scale)
[docs] def set_virtual_resolution(self, width: int, height: int): self._viewport.set_virtual_resolution(int(width), int(height)) w, h = self.backend.window.size() dw, dh = self.backend.window.drawable_size() self.size = (w, h) self._drawable_size = (dw, dh) self._viewport.resize(dw, dh) self._apply_viewport_transform()
[docs] def set_viewport_mode(self, mode: ViewportMode): self._viewport.set_mode(mode) # mode change affects scale/offset if self._viewport.state is not None: self._apply_viewport_transform()
[docs] def get_viewport(self) -> ViewportState: return self._viewport.state
[docs] def screen_to_virtual(self, x: float, y: float) -> tuple[float, float]: logical_w, logical_h = self.size drawable_w, drawable_h = self._drawable_size sx = drawable_w / logical_w if logical_w else 1.0 sy = drawable_h / logical_h if logical_h else 1.0 return self._viewport.screen_to_virtual(x * sx, y * sy)
[docs] def set_title(self, title): self.backend.window.set_title(title)
[docs] def set_clear_color(self, r, g, b): self.backend.render.set_clear_color(r, g, b)
[docs] def on_window_resized(self, width: int, height: int): logger.debug(f"Window resized event: {width}x{height}") # logical logical_w, logical_h = int(width), int(height) # drawable (pixel) drawable_w, drawable_h = self.backend.window.drawable_size() # store both if useful self.size = (logical_w, logical_h) self._drawable_size = (drawable_w, drawable_h) # viewport should match what renderer draws to: self._viewport.resize(drawable_w, drawable_h) self._apply_viewport_transform()
[docs] def get_virtual_size(self) -> tuple[int, int]: s = self.get_viewport() return (s.virtual_w, s.virtual_h)