mirror of
https://github.com/rr-/pq-cli.git
synced 2026-11-12 22:40:36 -07:00
Python 3.10 is the minimum, so annotations use `X | None`, `list[X]` and friends, enforced by ruff's pyupgrade rules. The remaining typing names are imported directly, with abstract types coming from collections.abc. first() is now generic over the item and default.
51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
import curses
|
|
from typing import Any
|
|
|
|
from pqcli.ui.curses.colors import COLOR_HIGHLIGHT, has_colors
|
|
|
|
from .scrollable import Scrollable
|
|
|
|
|
|
class ListBox(Scrollable):
|
|
_items: list[str]
|
|
|
|
def __init__(self, parent: Any, h: int, w: int, y: int, x: int) -> None:
|
|
super().__init__(parent, h, w, y, x)
|
|
self._selected: int | None = None
|
|
|
|
def add(self, text: str) -> None:
|
|
self._items.append(text)
|
|
self.scroll_to_item(-1)
|
|
|
|
def set(self, idx: int, value: str) -> None:
|
|
if idx < 0:
|
|
idx %= len(self._items)
|
|
self._items[idx] = value
|
|
|
|
def get(self, idx: int) -> str | None:
|
|
if not self._items:
|
|
return None
|
|
if idx < 0:
|
|
idx %= len(self._items)
|
|
try:
|
|
return self._items[idx]
|
|
except ValueError:
|
|
return None
|
|
|
|
def delete(self, idx: int, count: int = 1) -> None:
|
|
del self._items[idx : idx + count]
|
|
|
|
def select(self, idx: int | None) -> None:
|
|
if idx < 0 and len(self._items):
|
|
idx %= len(self._items)
|
|
self._selected = idx
|
|
|
|
def _render_impl(self, h: int, w: int) -> None:
|
|
assert self._pad
|
|
for y, item in enumerate(self._items):
|
|
if y == self._selected and has_colors():
|
|
self._pad.attron(curses.color_pair(COLOR_HIGHLIGHT))
|
|
self._pad.addnstr(y, 0, item, min(len(item), w))
|
|
if y == self._selected and has_colors():
|
|
self._pad.attroff(curses.color_pair(COLOR_HIGHLIGHT))
|