codekingpro/portable-devtools
114k
1from __future__ import annotations2 3import typing4 5from urwid.canvas import CanvasJoin, CompositeCanvas, TextCanvas6from urwid.util import decompose_tagmarkup7 8from .constants import Sizing9from .widget import Widget, fixed_size10 11if typing.TYPE_CHECKING:12 from collections.abc import Hashable13 14 from urwid import Font15 16 17class BigText(Widget):18 _sizing = frozenset([Sizing.FIXED])19 20 def __init__(self, markup, font: Font) -> None:21 """22 markup -- same as Text widget markup23 font -- instance of a Font class24 """25 super().__init__()26 self.text: str = ""27 self.attrib = []28 self.font: Font = font29 self.set_font(font)30 self.set_text(markup)31 32 def set_text(self, markup):33 self.text, self.attrib = decompose_tagmarkup(markup)34 self._invalidate()35 36 def get_text(self):37 """38 Returns (text, attributes).39 """40 return self.text, self.attrib41 42 def set_font(self, font: Font) -> None:43 self.font = font44 self._invalidate()45 46 def pack(47 self,48 size: tuple[()] | None = (), # type: ignore[override]49 focus: bool = False,50 ) -> tuple[int, int]:51 rows = self.font.height52 cols = 053 for c in self.text:54 cols += self.font.char_width(c)55 return cols, rows56 57 def render(58 self,59 size: tuple[()], # type: ignore[override]60 focus: bool = False,61 ) -> CompositeCanvas:62 fixed_size(size) # complain if parameter is wrong63 a: Hashable | None = None64 ai = ak = 065 o = []66 rows = self.font.height67 attrib = [*self.attrib, (None, len(self.text))]68 for ch in self.text:69 if not ak:70 a, ak = attrib[ai]71 ai += 172 ak -= 173 74 if width := self.font.char_width(ch):75 c: TextCanvas | CompositeCanvas = self.font.render(ch)76 if a is not None:77 c = CompositeCanvas(c)78 c.fill_attr(a)79 o.append((c, None, False, width))80 81 if o:82 canv = CanvasJoin(o)83 else:84 canv = CompositeCanvas(TextCanvas([b""] * rows, maxcol=0, check_width=False))85 canv.set_depends([])86 return canv87 