mirror of
https://github.com/markqvist/NomadNet.git
synced 2026-10-05 21:17:22 +00:00
Add native resolution width/height specifier
This commit is contained in:
@@ -255,7 +255,7 @@ def test_webp_conversion():
|
||||
with os.fdopen(fd, "wb") as f:
|
||||
f.write(fixture)
|
||||
d = ImageData(webp_path)
|
||||
check(not d.ok and "converted image too large" in d.error,
|
||||
check(not d.ok and "Converted image too large" in d.error,
|
||||
"converted payload capped at %d MiB"
|
||||
% (MAX_CONVERTED_PAYLOAD_BYTES // (1024 * 1024)))
|
||||
os.unlink(webp_path)
|
||||
@@ -414,6 +414,43 @@ def test_widget_layout(image_path):
|
||||
check((c, r) == (27, 10), "height-only after reset -> (27, 10), got (%d, %d)" % (c, r))
|
||||
w.close()
|
||||
|
||||
# native resolution specification ("n"): display at the image's own
|
||||
# pixel size, quantized to the terminal cell grid. Cell = (1, 2),
|
||||
# small fixture 64x32 -> native 64 cols, 16 rows.
|
||||
from nomadnet.ui.textui.images import _webp
|
||||
small_png = _webp._encode_png_rgba(bytes(64 * 32 * 4), 64, 32)
|
||||
fd, small_path = tempfile.mkstemp(suffix=".png")
|
||||
with os.fdopen(fd, "wb") as f:
|
||||
f.write(small_png)
|
||||
try:
|
||||
wn = ImageWidget(small_path, width="n")
|
||||
wn.render((80,)) # sets _ti_cols/_ti_rows
|
||||
check((wn._ti_cols, wn._ti_rows) == (64, 16),
|
||||
"width='n' displays native size (64, 16), got (%d, %d)"
|
||||
% (wn._ti_cols, wn._ti_rows))
|
||||
wn.close()
|
||||
hn = ImageWidget(small_path, height="n")
|
||||
hn.render((80,))
|
||||
check((hn._ti_cols, hn._ti_rows) == (64, 16),
|
||||
"height='n' displays native size (64, 16), got (%d, %d)"
|
||||
% (hn._ti_cols, hn._ti_rows))
|
||||
hn.close()
|
||||
bn = ImageWidget(small_path, width="n", height="n")
|
||||
bn.render((80,))
|
||||
check((bn._ti_cols, bn._ti_rows) == (64, 16),
|
||||
"width='n' height='n' displays native size (64, 16), got (%d, %d)"
|
||||
% (bn._ti_cols, bn._ti_rows))
|
||||
bn.close()
|
||||
big = ImageWidget(image_path, width="n") # 1280x960, overflows
|
||||
c, r = big._display_size(80)
|
||||
check((c, r) == (80, 30),
|
||||
"native of a large image clamps to available width (80, 30), got (%d, %d)" % (c, r))
|
||||
big.close()
|
||||
check(raises(lambda: ImageWidget(image_path, width="x"), ValueError),
|
||||
"width='x' raises ValueError")
|
||||
finally:
|
||||
os.unlink(small_path)
|
||||
|
||||
# alignment: placement column of a narrowed image inside its canvas
|
||||
w = ImageWidget(image_path, width=40) # default center
|
||||
w.render((80,)) # sets _ti_cols/_ti_rows
|
||||
|
||||
@@ -33,6 +33,7 @@ def _check_align(value):
|
||||
|
||||
|
||||
def _check_size_spec(value, name):
|
||||
# None = auto, int = absolute cells/rows, "NN%" = percent, "n" = native resolution
|
||||
if value is None: return None
|
||||
|
||||
if isinstance(value, int):
|
||||
@@ -40,9 +41,10 @@ def _check_size_spec(value, name):
|
||||
return value
|
||||
|
||||
if isinstance(value, str):
|
||||
if value.lower() == "n": return "n"
|
||||
match = _SIZE_SPEC_RE.fullmatch(value)
|
||||
if not match or float(match.group(1)) <= 0:
|
||||
raise ValueError("invalid %s specification %r (expected a positive integer or a percent string like '50%%')" % (name, value))
|
||||
raise ValueError("invalid %s specification %r (expected a positive integer, a percent string like '50%%' or 'n' for native resolution)" % (name, value))
|
||||
return value
|
||||
|
||||
raise TypeError("invalid type for %s (got %s)" % (name, type(value).__name__))
|
||||
@@ -140,8 +142,8 @@ class ImageWidget(urwid.Widget):
|
||||
width = property(
|
||||
lambda self: self._ti_width,
|
||||
doc="""Display width specification: None (full width), a positive
|
||||
int (columns) or a percent string ("NN%") of the available layout
|
||||
width.""",
|
||||
int (columns), a percent string ("NN%") of the available layout
|
||||
width, or "n" for native resolution.""",
|
||||
)
|
||||
|
||||
@width.setter
|
||||
@@ -152,8 +154,8 @@ class ImageWidget(urwid.Widget):
|
||||
height = property(
|
||||
lambda self: self._ti_height,
|
||||
doc="""Display height specification: None (derived, aspect
|
||||
preserving), a positive int (rows) or a percent string ("NN%") of
|
||||
the visible page height.""",
|
||||
preserving), a positive int (rows), a percent string ("NN%") of
|
||||
the visible page height, or "n" for native resolution.""",
|
||||
)
|
||||
|
||||
@height.setter
|
||||
@@ -185,11 +187,13 @@ class ImageWidget(urwid.Widget):
|
||||
def _raw_width():
|
||||
if w_spec is None: return float(maxcol)
|
||||
if isinstance(w_spec, int): return float(w_spec)
|
||||
if w_spec == "n": return iw / cell_w
|
||||
return maxcol * _pct(w_spec)
|
||||
|
||||
def _raw_height():
|
||||
if h_spec is None: return None
|
||||
if isinstance(h_spec, int): return float(h_spec)
|
||||
if h_spec == "n": return ih / cell_h
|
||||
columns, lines = _termlib.get_terminal_size()
|
||||
page = max(1, lines - UI_MARGIN)
|
||||
return page * _pct(h_spec)
|
||||
|
||||
Reference in New Issue
Block a user