urwid 2.6.0.post0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of urwid might be problematic. Click here for more details.

Files changed (75) hide show
  1. urwid/__init__.py +333 -0
  2. urwid/canvas.py +1413 -0
  3. urwid/command_map.py +137 -0
  4. urwid/container.py +59 -0
  5. urwid/decoration.py +65 -0
  6. urwid/display/__init__.py +97 -0
  7. urwid/display/_posix_raw_display.py +413 -0
  8. urwid/display/_raw_display_base.py +914 -0
  9. urwid/display/_web.css +12 -0
  10. urwid/display/_web.js +462 -0
  11. urwid/display/_win32.py +171 -0
  12. urwid/display/_win32_raw_display.py +269 -0
  13. urwid/display/common.py +1219 -0
  14. urwid/display/curses.py +690 -0
  15. urwid/display/escape.py +624 -0
  16. urwid/display/html_fragment.py +251 -0
  17. urwid/display/lcd.py +518 -0
  18. urwid/display/raw.py +37 -0
  19. urwid/display/web.py +636 -0
  20. urwid/event_loop/__init__.py +55 -0
  21. urwid/event_loop/abstract_loop.py +175 -0
  22. urwid/event_loop/asyncio_loop.py +231 -0
  23. urwid/event_loop/glib_loop.py +294 -0
  24. urwid/event_loop/main_loop.py +721 -0
  25. urwid/event_loop/select_loop.py +230 -0
  26. urwid/event_loop/tornado_loop.py +206 -0
  27. urwid/event_loop/trio_loop.py +302 -0
  28. urwid/event_loop/twisted_loop.py +269 -0
  29. urwid/event_loop/zmq_loop.py +275 -0
  30. urwid/font.py +695 -0
  31. urwid/graphics.py +96 -0
  32. urwid/highlight.css +19 -0
  33. urwid/listbox.py +1899 -0
  34. urwid/monitored_list.py +522 -0
  35. urwid/numedit.py +376 -0
  36. urwid/signals.py +330 -0
  37. urwid/split_repr.py +130 -0
  38. urwid/str_util.py +358 -0
  39. urwid/text_layout.py +632 -0
  40. urwid/treetools.py +515 -0
  41. urwid/util.py +557 -0
  42. urwid/version.py +16 -0
  43. urwid/vterm.py +1806 -0
  44. urwid/widget/__init__.py +181 -0
  45. urwid/widget/attr_map.py +161 -0
  46. urwid/widget/attr_wrap.py +140 -0
  47. urwid/widget/bar_graph.py +649 -0
  48. urwid/widget/big_text.py +77 -0
  49. urwid/widget/box_adapter.py +126 -0
  50. urwid/widget/columns.py +1145 -0
  51. urwid/widget/constants.py +574 -0
  52. urwid/widget/container.py +227 -0
  53. urwid/widget/divider.py +110 -0
  54. urwid/widget/edit.py +718 -0
  55. urwid/widget/filler.py +403 -0
  56. urwid/widget/frame.py +539 -0
  57. urwid/widget/grid_flow.py +539 -0
  58. urwid/widget/line_box.py +194 -0
  59. urwid/widget/overlay.py +829 -0
  60. urwid/widget/padding.py +597 -0
  61. urwid/widget/pile.py +971 -0
  62. urwid/widget/popup.py +170 -0
  63. urwid/widget/progress_bar.py +141 -0
  64. urwid/widget/scrollable.py +597 -0
  65. urwid/widget/solid_fill.py +44 -0
  66. urwid/widget/text.py +354 -0
  67. urwid/widget/widget.py +852 -0
  68. urwid/widget/widget_decoration.py +166 -0
  69. urwid/widget/wimp.py +792 -0
  70. urwid/wimp.py +23 -0
  71. urwid-2.6.0.post0.dist-info/COPYING +504 -0
  72. urwid-2.6.0.post0.dist-info/METADATA +332 -0
  73. urwid-2.6.0.post0.dist-info/RECORD +75 -0
  74. urwid-2.6.0.post0.dist-info/WHEEL +5 -0
  75. urwid-2.6.0.post0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,227 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import enum
5
+ import typing
6
+ import warnings
7
+
8
+ from .constants import Sizing, WHSettings
9
+
10
+ if typing.TYPE_CHECKING:
11
+ from collections.abc import Iterable, Iterator
12
+
13
+ from .widget import Widget
14
+
15
+
16
+ class _ContainerElementSizingFlag(enum.IntFlag):
17
+ NONE = 0
18
+ BOX = enum.auto()
19
+ FLOW = enum.auto()
20
+ FIXED = enum.auto()
21
+ WH_WEIGHT = enum.auto()
22
+ WH_PACK = enum.auto()
23
+ WH_GIVEN = enum.auto()
24
+
25
+ @property
26
+ def reverse_flag(self) -> tuple[frozenset(Sizing), WHSettings | None]:
27
+ """Get flag in public API format."""
28
+ sizing: set[Sizing] = set()
29
+
30
+ if self & self.BOX:
31
+ sizing.add(Sizing.BOX)
32
+ if self & self.FLOW:
33
+ sizing.add(Sizing.FLOW)
34
+ if self & self.FIXED:
35
+ sizing.add(Sizing.FIXED)
36
+
37
+ if self & self.WH_WEIGHT:
38
+ return frozenset(sizing), WHSettings.WEIGHT
39
+ if self & self.WH_PACK:
40
+ return frozenset(sizing), WHSettings.PACK
41
+ if self & self.WH_GIVEN:
42
+ return frozenset(sizing), WHSettings.GIVEN
43
+ return frozenset(sizing), None
44
+
45
+ @property
46
+ def log_string(self) -> str:
47
+ """Get desctiprion in public API format."""
48
+ sizing, render = self.reverse_flag
49
+ render_string = f" {render.upper()}" if render else ""
50
+ return "|".join(sorted(mode.upper() for mode in sizing)) + render_string
51
+
52
+
53
+ class WidgetContainerMixin:
54
+ """
55
+ Mixin class for widget containers implementing common container methods
56
+ """
57
+
58
+ def __getitem__(self, position) -> Widget:
59
+ """
60
+ Container short-cut for self.contents[position][0].base_widget
61
+ which means "give me the child widget at position without any
62
+ widget decorations".
63
+
64
+ This allows for concise traversal of nested container widgets
65
+ such as:
66
+
67
+ my_widget[position0][position1][position2] ...
68
+ """
69
+ return self.contents[position][0].base_widget
70
+
71
+ def get_focus_path(self) -> list[int | str]:
72
+ """
73
+ Return the .focus_position values starting from this container
74
+ and proceeding along each child widget until reaching a leaf
75
+ (non-container) widget.
76
+ """
77
+ out = []
78
+ w = self
79
+ while True:
80
+ try:
81
+ p = w.focus_position
82
+ except IndexError:
83
+ return out
84
+ out.append(p)
85
+ w = w.focus.base_widget
86
+
87
+ def set_focus_path(self, positions: Iterable[int | str]) -> None:
88
+ """
89
+ Set the .focus_position property starting from this container
90
+ widget and proceeding along newly focused child widgets. Any
91
+ failed assignment due do incompatible position types or invalid
92
+ positions will raise an IndexError.
93
+
94
+ This method may be used to restore a particular widget to the
95
+ focus by passing in the value returned from an earlier call to
96
+ get_focus_path().
97
+
98
+ positions -- sequence of positions
99
+ """
100
+ w = self
101
+ for p in positions:
102
+ if p != w.focus_position:
103
+ w.focus_position = p # modifies w.focus
104
+ w = w.focus.base_widget
105
+
106
+ def get_focus_widgets(self) -> list[Widget]:
107
+ """
108
+ Return the .focus values starting from this container
109
+ and proceeding along each child widget until reaching a leaf
110
+ (non-container) widget.
111
+
112
+ Note that the list does not contain the topmost container widget
113
+ (i.e., on which this method is called), but does include the
114
+ lowest leaf widget.
115
+ """
116
+ out = []
117
+ w = self
118
+ while True:
119
+ w = w.base_widget.focus
120
+ if w is None:
121
+ return out
122
+ out.append(w)
123
+
124
+ @property
125
+ @abc.abstractmethod
126
+ def focus(self) -> Widget:
127
+ """
128
+ Read-only property returning the child widget in focus for
129
+ container widgets. This default implementation
130
+ always returns ``None``, indicating that this widget has no children.
131
+ """
132
+
133
+ def _get_focus(self) -> Widget:
134
+ warnings.warn(
135
+ f"method `{self.__class__.__name__}._get_focus` is deprecated, "
136
+ f"please use `{self.__class__.__name__}.focus` property",
137
+ DeprecationWarning,
138
+ stacklevel=3,
139
+ )
140
+ return self.focus
141
+
142
+
143
+ class WidgetContainerListContentsMixin:
144
+ """
145
+ Mixin class for widget containers whose positions are indexes into
146
+ a list available as self.contents.
147
+ """
148
+
149
+ def __iter__(self) -> Iterator[int]:
150
+ """
151
+ Return an iterable of positions for this container from first
152
+ to last.
153
+ """
154
+ return iter(range(len(self.contents)))
155
+
156
+ def __reversed__(self) -> Iterator[int]:
157
+ """
158
+ Return an iterable of positions for this container from last
159
+ to first.
160
+ """
161
+ return iter(range(len(self.contents) - 1, -1, -1))
162
+
163
+ def __len__(self) -> int:
164
+ return len(self.contents)
165
+
166
+ @property
167
+ @abc.abstractmethod
168
+ def contents(self) -> list[tuple[Widget, typing.Any]]:
169
+ """The contents of container as a list of (widget, options)"""
170
+
171
+ @contents.setter
172
+ def contents(self, new_contents: list[tuple[Widget, typing.Any]]) -> None:
173
+ """The contents of container as a list of (widget, options)"""
174
+
175
+ def _get_contents(self) -> list[tuple[Widget, typing.Any]]:
176
+ warnings.warn(
177
+ f"method `{self.__class__.__name__}._get_contents` is deprecated, "
178
+ f"please use `{self.__class__.__name__}.contents` property",
179
+ DeprecationWarning,
180
+ stacklevel=2,
181
+ )
182
+ return self.contents
183
+
184
+ def _set_contents(self, c: list[tuple[Widget, typing.Any]]) -> None:
185
+ warnings.warn(
186
+ f"method `{self.__class__.__name__}._set_contents` is deprecated, "
187
+ f"please use `{self.__class__.__name__}.contents` property",
188
+ DeprecationWarning,
189
+ stacklevel=2,
190
+ )
191
+ self.contents = c
192
+
193
+ @property
194
+ @abc.abstractmethod
195
+ def focus_position(self) -> int | None:
196
+ """
197
+ index of child widget in focus.
198
+ """
199
+
200
+ @focus_position.setter
201
+ def focus_position(self, position: int) -> None:
202
+ """
203
+ index of child widget in focus.
204
+ """
205
+
206
+ def _get_focus_position(self) -> int | None:
207
+ warnings.warn(
208
+ f"method `{self.__class__.__name__}._get_focus_position` is deprecated, "
209
+ f"please use `{self.__class__.__name__}.focus_position` property",
210
+ DeprecationWarning,
211
+ stacklevel=3,
212
+ )
213
+ return self.focus_position
214
+
215
+ def _set_focus_position(self, position: int) -> None:
216
+ """
217
+ Set the widget in focus.
218
+
219
+ position -- index of child widget to be made focus
220
+ """
221
+ warnings.warn(
222
+ f"method `{self.__class__.__name__}._set_focus_position` is deprecated, "
223
+ f"please use `{self.__class__.__name__}.focus_position` property",
224
+ DeprecationWarning,
225
+ stacklevel=3,
226
+ )
227
+ self.focus_position = position
@@ -0,0 +1,110 @@
1
+ from __future__ import annotations
2
+
3
+ import enum
4
+ import typing
5
+
6
+ from urwid.canvas import CompositeCanvas, SolidCanvas
7
+
8
+ from .constants import BOX_SYMBOLS, SHADE_SYMBOLS, Sizing
9
+ from .widget import Widget
10
+
11
+
12
+ class DividerSymbols(str, enum.Enum):
13
+ """Common symbols for divider widgets."""
14
+
15
+ # Lines
16
+ LIGHT_HL = BOX_SYMBOLS.LIGHT.HORIZONTAL
17
+ LIGHT_4_DASHES = BOX_SYMBOLS.LIGHT.HORIZONTAL_4_DASHES
18
+ LIGHT_3_DASHES = BOX_SYMBOLS.LIGHT.HORIZONTAL_3_DASHES
19
+ LIGHT_2_DASHES = BOX_SYMBOLS.LIGHT.HORIZONTAL_2_DASHES
20
+ HEAVY_HL = BOX_SYMBOLS.HEAVY.HORIZONTAL
21
+ HEAVY_4_DASHES = BOX_SYMBOLS.HEAVY.HORIZONTAL_4_DASHES
22
+ HEAVY_3_DASHES = BOX_SYMBOLS.HEAVY.HORIZONTAL_3_DASHES
23
+ HEAVY_2_DASHES = BOX_SYMBOLS.HEAVY.HORIZONTAL_2_DASHES
24
+ DOUBLE_HL = BOX_SYMBOLS.DOUBLE.HORIZONTAL
25
+
26
+ # Full block
27
+ FULL_BLOCK = SHADE_SYMBOLS.FULL_BLOCK
28
+ DARK_SHADE = SHADE_SYMBOLS.DARK_SHADE
29
+ MEDIUM_SHADE = SHADE_SYMBOLS.MEDIUM_SHADE
30
+ LITE_SHADE = SHADE_SYMBOLS.LITE_SHADE
31
+
32
+
33
+ class Divider(Widget):
34
+ """
35
+ Horizontal divider widget
36
+ """
37
+
38
+ Symbols = DividerSymbols
39
+
40
+ _sizing = frozenset([Sizing.FLOW])
41
+
42
+ ignore_focus = True
43
+
44
+ def __init__(
45
+ self,
46
+ div_char: str | bytes = " ",
47
+ top: int = 0,
48
+ bottom: int = 0,
49
+ ) -> None:
50
+ """
51
+ :param div_char: character to repeat across line
52
+ :type div_char: bytes or unicode
53
+
54
+ :param top: number of blank lines above
55
+ :type top: int
56
+
57
+ :param bottom: number of blank lines below
58
+ :type bottom: int
59
+
60
+ >>> Divider()
61
+ <Divider flow widget>
62
+ >>> Divider(u'-')
63
+ <Divider flow widget '-'>
64
+ >>> Divider(u'x', 1, 2)
65
+ <Divider flow widget 'x' bottom=2 top=1>
66
+ """
67
+ super().__init__()
68
+ self.div_char = div_char
69
+ self.top = top
70
+ self.bottom = bottom
71
+
72
+ def _repr_words(self) -> list[str]:
73
+ return super()._repr_words() + [repr(self.div_char)] * (self.div_char != " ")
74
+
75
+ def _repr_attrs(self) -> dict[str, typing.Any]:
76
+ attrs = dict(super()._repr_attrs())
77
+ if self.top:
78
+ attrs["top"] = self.top
79
+ if self.bottom:
80
+ attrs["bottom"] = self.bottom
81
+ return attrs
82
+
83
+ def rows(self, size: tuple[int], focus: bool = False) -> int:
84
+ """
85
+ Return the number of lines that will be rendered.
86
+
87
+ >>> Divider().rows((10,))
88
+ 1
89
+ >>> Divider(u'x', 1, 2).rows((10,))
90
+ 4
91
+ """
92
+ (_maxcol,) = size
93
+ return self.top + 1 + self.bottom
94
+
95
+ def render(self, size: tuple[int], focus: bool = False) -> CompositeCanvas:
96
+ """
97
+ Render the divider as a canvas and return it.
98
+
99
+ >>> Divider().render((10,)).text # ... = b in Python 3
100
+ [...' ']
101
+ >>> Divider(u'-', top=1).render((10,)).text
102
+ [...' ', ...'----------']
103
+ >>> Divider(u'x', bottom=2).render((5,)).text
104
+ [...'xxxxx', ...' ', ...' ']
105
+ """
106
+ (maxcol,) = size
107
+ canv = CompositeCanvas(SolidCanvas(self.div_char, maxcol, 1))
108
+ if self.top or self.bottom:
109
+ canv.pad_trim_top_bottom(self.top, self.bottom)
110
+ return canv