Move Viewport + _DRIFT_TOLERANCE from preview.py to popout/viewport.py (no behavior change)
Step 2 of the gui/app.py + gui/preview.py structural refactor. Pure move: the popout viewport NamedTuple and the drift-tolerance constant are now in their own module under popout/. preview.py grows another re-export shim line so FullscreenPreview's method bodies (which reference Viewport and _DRIFT_TOLERANCE by bare name) keep working unchanged. Shim removed in commit 14. See docs/REFACTOR_PLAN.md.
This commit is contained in:
parent
cd7b8a3cca
commit
18a86358e2
0
booru_viewer/gui/popout/__init__.py
Normal file
0
booru_viewer/gui/popout/__init__.py
Normal file
36
booru_viewer/gui/popout/viewport.py
Normal file
36
booru_viewer/gui/popout/viewport.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
"""Popout viewport math: persistent intent + drift tolerance."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
|
class Viewport(NamedTuple):
|
||||||
|
"""Where and how large the user wants popout content to appear.
|
||||||
|
|
||||||
|
Three numbers, no aspect. Aspect is a property of the currently-
|
||||||
|
displayed post and is recomputed from actual content on every
|
||||||
|
navigation. The viewport stays put across navigations; the window
|
||||||
|
rect is a derived projection (Viewport, content_aspect) → (x,y,w,h).
|
||||||
|
|
||||||
|
`long_side` is the binding edge length: for landscape it becomes
|
||||||
|
width, for portrait it becomes height. Symmetric across the two
|
||||||
|
orientations, which is the property that breaks the
|
||||||
|
width-anchor ratchet that the previous `_fit_to_content` had.
|
||||||
|
"""
|
||||||
|
center_x: float
|
||||||
|
center_y: float
|
||||||
|
long_side: float
|
||||||
|
|
||||||
|
|
||||||
|
# Maximum drift between our last-dispatched window rect and the current
|
||||||
|
# Hyprland-reported rect that we still treat as "no user action happened."
|
||||||
|
# Anything within this tolerance is absorbed (Hyprland gap rounding,
|
||||||
|
# subpixel accumulation, decoration accounting). Anything beyond it is
|
||||||
|
# treated as "the user dragged or resized the window externally" and the
|
||||||
|
# persistent viewport gets updated from current state.
|
||||||
|
#
|
||||||
|
# 2px is small enough not to false-positive on real user drags (which
|
||||||
|
# are always tens of pixels minimum) and large enough to absorb the
|
||||||
|
# 1-2px per-nav drift that compounds across many navigations.
|
||||||
|
_DRIFT_TOLERANCE = 2
|
||||||
@ -18,37 +18,6 @@ import mpv as mpvlib
|
|||||||
_log = logging.getLogger("booru")
|
_log = logging.getLogger("booru")
|
||||||
|
|
||||||
|
|
||||||
class Viewport(NamedTuple):
|
|
||||||
"""Where and how large the user wants popout content to appear.
|
|
||||||
|
|
||||||
Three numbers, no aspect. Aspect is a property of the currently-
|
|
||||||
displayed post and is recomputed from actual content on every
|
|
||||||
navigation. The viewport stays put across navigations; the window
|
|
||||||
rect is a derived projection (Viewport, content_aspect) → (x,y,w,h).
|
|
||||||
|
|
||||||
`long_side` is the binding edge length: for landscape it becomes
|
|
||||||
width, for portrait it becomes height. Symmetric across the two
|
|
||||||
orientations, which is the property that breaks the
|
|
||||||
width-anchor ratchet that the previous `_fit_to_content` had.
|
|
||||||
"""
|
|
||||||
center_x: float
|
|
||||||
center_y: float
|
|
||||||
long_side: float
|
|
||||||
|
|
||||||
|
|
||||||
# Maximum drift between our last-dispatched window rect and the current
|
|
||||||
# Hyprland-reported rect that we still treat as "no user action happened."
|
|
||||||
# Anything within this tolerance is absorbed (Hyprland gap rounding,
|
|
||||||
# subpixel accumulation, decoration accounting). Anything beyond it is
|
|
||||||
# treated as "the user dragged or resized the window externally" and the
|
|
||||||
# persistent viewport gets updated from current state.
|
|
||||||
#
|
|
||||||
# 2px is small enough not to false-positive on real user drags (which
|
|
||||||
# are always tens of pixels minimum) and large enough to absorb the
|
|
||||||
# 1-2px per-nav drift that compounds across many navigations.
|
|
||||||
_DRIFT_TOLERANCE = 2
|
|
||||||
|
|
||||||
|
|
||||||
## Overlay styling for the popout's translucent toolbar / controls bar
|
## Overlay styling for the popout's translucent toolbar / controls bar
|
||||||
## now lives in the bundled themes (themes/*.qss). The widgets get their
|
## now lives in the bundled themes (themes/*.qss). The widgets get their
|
||||||
## object names set in code (FullscreenPreview / VideoPlayer) so theme QSS
|
## object names set in code (FullscreenPreview / VideoPlayer) so theme QSS
|
||||||
@ -2269,3 +2238,4 @@ class ImagePreview(QWidget):
|
|||||||
|
|
||||||
# -- Refactor compatibility shims (deleted in commit 14) --
|
# -- Refactor compatibility shims (deleted in commit 14) --
|
||||||
from .media.constants import VIDEO_EXTENSIONS, _is_video # re-export for refactor compat
|
from .media.constants import VIDEO_EXTENSIONS, _is_video # re-export for refactor compat
|
||||||
|
from .popout.viewport import Viewport, _DRIFT_TOLERANCE # re-export for refactor compat
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user