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,194 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from .columns import Columns
6
+ from .constants import BOX_SYMBOLS, Align, WHSettings
7
+ from .divider import Divider
8
+ from .pile import Pile
9
+ from .solid_fill import SolidFill
10
+ from .text import Text
11
+ from .widget_decoration import WidgetDecoration, delegate_to_widget_mixin
12
+
13
+ if typing.TYPE_CHECKING:
14
+ from typing_extensions import Literal
15
+
16
+ from .widget import Widget
17
+
18
+ WrappedWidget = typing.TypeVar("WrappedWidget")
19
+
20
+
21
+ class LineBox(WidgetDecoration[WrappedWidget], delegate_to_widget_mixin("_wrapped_widget")):
22
+ Symbols = BOX_SYMBOLS
23
+
24
+ def __init__(
25
+ self,
26
+ original_widget: WrappedWidget,
27
+ title: str = "",
28
+ title_align: Literal["left", "center", "right"] | Align = Align.CENTER,
29
+ title_attr=None,
30
+ tlcorner: str = BOX_SYMBOLS.LIGHT.TOP_LEFT,
31
+ tline: str = BOX_SYMBOLS.LIGHT.HORIZONTAL,
32
+ lline: str = BOX_SYMBOLS.LIGHT.VERTICAL,
33
+ trcorner: str = BOX_SYMBOLS.LIGHT.TOP_RIGHT,
34
+ blcorner: str = BOX_SYMBOLS.LIGHT.BOTTOM_LEFT,
35
+ rline: str = BOX_SYMBOLS.LIGHT.VERTICAL,
36
+ bline: str = BOX_SYMBOLS.LIGHT.HORIZONTAL,
37
+ brcorner: str = BOX_SYMBOLS.LIGHT.BOTTOM_RIGHT,
38
+ ) -> None:
39
+ """
40
+ Draw a line around original_widget.
41
+
42
+ Use 'title' to set an initial title text with will be centered
43
+ on top of the box.
44
+
45
+ Use `title_attr` to apply a specific attribute to the title text.
46
+
47
+ Use `title_align` to align the title to the 'left', 'right', or 'center'.
48
+ The default is 'center'.
49
+
50
+ You can also override the widgets used for the lines/corners:
51
+ tline: top line
52
+ bline: bottom line
53
+ lline: left line
54
+ rline: right line
55
+ tlcorner: top left corner
56
+ trcorner: top right corner
57
+ blcorner: bottom left corner
58
+ brcorner: bottom right corner
59
+
60
+ If empty string is specified for one of the lines/corners, then no character will be output there.
61
+ If no top/bottom/left/right lines - whole lines will be omitted.
62
+ This allows for seamless use of adjoining LineBoxes.
63
+
64
+ Class attribute `Symbols` can be used as source for standard lines:
65
+
66
+ >>> print(LineBox(Text("Some text")).render(()))
67
+ ┌─────────┐
68
+ │Some text│
69
+ └─────────┘
70
+ >>> print(
71
+ ... LineBox(
72
+ ... Text("Some text"),
73
+ ... tlcorner=LineBox.Symbols.LIGHT.TOP_LEFT_ROUNDED,
74
+ ... trcorner=LineBox.Symbols.LIGHT.TOP_RIGHT_ROUNDED,
75
+ ... blcorner=LineBox.Symbols.LIGHT.BOTTOM_LEFT_ROUNDED,
76
+ ... brcorner=LineBox.Symbols.LIGHT.BOTTOM_RIGHT_ROUNDED,
77
+ ... ).render(())
78
+ ... )
79
+ ╭─────────╮
80
+ │Some text│
81
+ ╰─────────╯
82
+ >>> print(
83
+ ... LineBox(
84
+ ... Text("Some text"),
85
+ ... tline=LineBox.Symbols.HEAVY.HORIZONTAL,
86
+ ... bline=LineBox.Symbols.HEAVY.HORIZONTAL,
87
+ ... lline=LineBox.Symbols.HEAVY.VERTICAL,
88
+ ... rline=LineBox.Symbols.HEAVY.VERTICAL,
89
+ ... tlcorner=LineBox.Symbols.HEAVY.TOP_LEFT,
90
+ ... trcorner=LineBox.Symbols.HEAVY.TOP_RIGHT,
91
+ ... blcorner=LineBox.Symbols.HEAVY.BOTTOM_LEFT,
92
+ ... brcorner=LineBox.Symbols.HEAVY.BOTTOM_RIGHT,
93
+ ... ).render(())
94
+ ... )
95
+ ┏━━━━━━━━━┓
96
+ ┃Some text┃
97
+ ┗━━━━━━━━━┛
98
+
99
+ To make Table constructions, some lineboxes need to be drawn without sides
100
+ and T or CROSS symbols used for corners of cells.
101
+ """
102
+
103
+ w_lline = SolidFill(lline)
104
+ w_rline = SolidFill(rline)
105
+
106
+ w_tlcorner, w_tline, w_trcorner = Text(tlcorner), Divider(tline), Text(trcorner)
107
+ w_blcorner, w_bline, w_brcorner = Text(blcorner), Divider(bline), Text(brcorner)
108
+
109
+ if not tline and title:
110
+ raise ValueError("Cannot have a title when tline is empty string")
111
+
112
+ if title_attr:
113
+ self.title_widget = Text((title_attr, self.format_title(title)))
114
+ else:
115
+ self.title_widget = Text(self.format_title(title))
116
+
117
+ if tline:
118
+ if title_align not in {Align.LEFT, Align.CENTER, Align.RIGHT}:
119
+ raise ValueError('title_align must be one of "left", "right", or "center"')
120
+ if title_align == Align.LEFT:
121
+ tline_widgets = [(WHSettings.PACK, self.title_widget), w_tline]
122
+ else:
123
+ tline_widgets = [w_tline, (WHSettings.PACK, self.title_widget)]
124
+ if title_align == Align.CENTER:
125
+ tline_widgets.append(w_tline)
126
+
127
+ self.tline_widget = Columns(tline_widgets)
128
+ top = Columns(
129
+ (
130
+ (int(bool(tlcorner and lline)), w_tlcorner),
131
+ self.tline_widget,
132
+ (int(bool(trcorner and rline)), w_trcorner),
133
+ )
134
+ )
135
+
136
+ else:
137
+ self.tline_widget = None
138
+ top = None
139
+
140
+ # Note: We need to define a fixed first widget (even if it's 0 width) so that the other
141
+ # widgets have something to anchor onto
142
+ middle = Columns(
143
+ ((int(bool(lline)), w_lline), original_widget, (int(bool(rline)), w_rline)),
144
+ box_columns=[0, 2],
145
+ focus_column=original_widget,
146
+ )
147
+
148
+ if bline:
149
+ bottom = Columns(
150
+ (
151
+ (int(bool(blcorner and lline)), w_blcorner),
152
+ w_bline,
153
+ (int(bool(brcorner and rline)), w_brcorner),
154
+ )
155
+ )
156
+ else:
157
+ bottom = None
158
+
159
+ pile_widgets = []
160
+ if top:
161
+ pile_widgets.append((WHSettings.PACK, top))
162
+ pile_widgets.append(middle)
163
+ if bottom:
164
+ pile_widgets.append((WHSettings.PACK, bottom))
165
+
166
+ self._wrapped_widget = Pile(pile_widgets, focus_item=middle)
167
+
168
+ super().__init__(original_widget)
169
+
170
+ @property
171
+ def _w(self) -> Pile:
172
+ return self._wrapped_widget
173
+
174
+ def format_title(self, text: str) -> str:
175
+ if text:
176
+ return f" {text} "
177
+
178
+ return ""
179
+
180
+ def set_title(self, text: str) -> None:
181
+ if not self.tline_widget:
182
+ raise ValueError("Cannot set title when tline is unset")
183
+ self.title_widget.set_text(self.format_title(text))
184
+ self.tline_widget._invalidate()
185
+
186
+ @property
187
+ def focus(self) -> Widget | None:
188
+ """LineBox is partially container.
189
+
190
+ While focus position is a bit hacky
191
+ (formally it's not container and only position 0 available),
192
+ focus widget is always provided by original widget.
193
+ """
194
+ return self._original_widget.focus