feat: preview

This commit is contained in:
2026-04-01 10:13:14 +02:00
parent 8776459ffb
commit 0316e50233
13 changed files with 590 additions and 538 deletions

View File

@@ -39,17 +39,19 @@ class Cell:
style: CellStyle = field(default_factory=CellStyle)
is_border: bool = False # True for box-drawing characters (for merge pass)
border_weight: BorderWeight | None = None
border_id: int = 0 # Identifies which box this border belongs to
link: str | None = None # Micron link destination
class CharGrid:
"""2D buffer of cells. Origin (0,0) is top-left."""
__slots__ = ("width", "height", "cells")
__slots__ = ("width", "height", "cells", "_border_counter")
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self._border_counter = 0
self.cells: list[list[Cell]] = [
[Cell() for _ in range(width)]
for _ in range(height)
@@ -62,6 +64,7 @@ class CharGrid:
style: CellStyle | None = None,
is_border: bool = False,
border_weight: BorderWeight | None = None,
border_id: int = 0,
link: str | None = None) -> None:
"""Write a single character to the grid."""
if not self.in_bounds(x, y):
@@ -72,6 +75,8 @@ class CharGrid:
cell.style = style
cell.is_border = is_border
cell.border_weight = border_weight
if border_id:
cell.border_id = border_id
if link is not None:
cell.link = link
@@ -114,24 +119,27 @@ class CharGrid:
if w < 2 or h < 2:
return
self._border_counter += 1
bid = self._border_counter
ch = BOX_CHARS[weight]
border_style = CellStyle()
# Corners
self.put(x, y, ch["tl"], border_style, is_border=True, border_weight=weight)
self.put(x + w - 1, y, ch["tr"], border_style, is_border=True, border_weight=weight)
self.put(x, y + h - 1, ch["bl"], border_style, is_border=True, border_weight=weight)
self.put(x + w - 1, y + h - 1, ch["br"], border_style, is_border=True, border_weight=weight)
self.put(x, y, ch["tl"], border_style, is_border=True, border_weight=weight, border_id=bid)
self.put(x + w - 1, y, ch["tr"], border_style, is_border=True, border_weight=weight, border_id=bid)
self.put(x, y + h - 1, ch["bl"], border_style, is_border=True, border_weight=weight, border_id=bid)
self.put(x + w - 1, y + h - 1, ch["br"], border_style, is_border=True, border_weight=weight, border_id=bid)
# Top and bottom edges
for col in range(x + 1, x + w - 1):
self.put(col, y, ch["h"], border_style, is_border=True, border_weight=weight)
self.put(col, y + h - 1, ch["h"], border_style, is_border=True, border_weight=weight)
self.put(col, y, ch["h"], border_style, is_border=True, border_weight=weight, border_id=bid)
self.put(col, y + h - 1, ch["h"], border_style, is_border=True, border_weight=weight, border_id=bid)
# Left and right edges
for row in range(y + 1, y + h - 1):
self.put(x, row, ch["v"], border_style, is_border=True, border_weight=weight)
self.put(x + w - 1, row, ch["v"], border_style, is_border=True, border_weight=weight)
self.put(x, row, ch["v"], border_style, is_border=True, border_weight=weight, border_id=bid)
self.put(x + w - 1, row, ch["v"], border_style, is_border=True, border_weight=weight, border_id=bid)
# Title in top border
if title and w > 4: