bowl/cheuph/attributed_text_widget.py

69 lines
1.9 KiB
Python

from typing import Any, List, Tuple, Union
import urwid
from .markup import AttributedText
__all__ = ["AttributedTextWidget", "ATWidget"]
class AttributedTextWidget(urwid.Text):
"""
A widget that works like urwid.Text, but displays AttributedText.
The AttributedText's "style" attribute is used as the style for urwid.Text,
where present.
"""
def __init__(self,
text: AttributedText,
*args: Any,
**kwargs: Any
) -> None:
"""
text - an AttributedText object
All other arguments are passed onto a urwid.Text constructor and thus
work the same way.
"""
self._attributed_text = text
super().__init__(self._convert_to_markup(text), *args, **kwargs)
@staticmethod
def _convert_to_markup(text: AttributedText
) -> List[Union[str, Tuple[str, str]]]:
# Wonder why mypy can't figure out the type signature of markup on its
# own... :P
markup: List[Union[str, Tuple[str, str]]]
markup = [
segment.text if style is None else (style, segment.text)
for segment, style in text.split_by("style")
]
return markup or [""]
def set_attributed_text(self, text: AttributedText) -> None:
"""
Set the content of the AttributedTextWidget.
"""
self._attributed_text = text
super().set_text(self._convert_to_markup(text))
def get_attributed_text(self) -> AttributedText:
"""
Returns the currently used AttributedText.
urwid.Text's get_text() also returns a run length encoded list of
attributes. This is not necessary here because the AttributedText
already contains all its attributes.
"""
return self._attributed_text
@property
def attributed_text(self) -> AttributedText:
return self.get_attributed_text()
ATWidget = AttributedTextWidget