add edit step + do recipe in main view, added carousel for recipe selection

This commit is contained in:
2026-03-12 22:57:15 +01:00
parent 90257a62a0
commit d5dacb8fc4
21 changed files with 1052 additions and 279 deletions

View File

@@ -0,0 +1,54 @@
from __future__ import annotations
from typing import List, Tuple
from PIL import ImageDraw
from .base import SelectableList
from .item import ListItem
class ListView(SelectableList):
"""Compact scrolling list shows up to *max_visible* items at once.
The visible window is kept centred on the selected item and scrolls
as the selection moves.
``font_size`` is forwarded to :pymeth:`ListItem.render` so the
underlying render function can use it (e.g. for PIL ``draw.text``).
Pass ``None`` to let render functions use their own default.
"""
def __init__(self, *args, font_size: int | None = None, **kwargs):
super().__init__(*args, **kwargs)
self.font_size = font_size
def _get_visible_window(self) -> Tuple[List[ListItem], int]:
"""Return (visible_items, start_offset)."""
total = len(self._items)
if total <= self.max_visible:
return self._items, 0
start = max(0, self.selected_index - self.max_visible // 2)
start = min(start, total - self.max_visible)
end = start + self.max_visible
return self._items[start:end], start
def render(self, draw: ImageDraw.ImageDraw, y_start: int) -> None:
if not self._items:
return
visible_items, start = self._get_visible_window()
fs = self.font_size or 10
kwargs = {} if self.font_size is None else {'font_size': self.font_size}
for idx, item in enumerate(visible_items):
actual_idx = start + idx
y_pos = y_start + idx * self.item_height
if actual_idx == self.selected_index:
self._draw_highlight(draw, self.x_offset, y_pos + fs // 2, font_size=fs)
item.render(draw, (self.x_offset, y_pos), fill='white', **kwargs)
else:
item.render(draw, (self.x_offset, y_pos), fill='black', **kwargs)