urwid 2.6.5__py3-none-any.whl → 2.6.7__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.
- urwid/event_loop/main_loop.py +20 -25
- urwid/version.py +2 -2
- urwid/widget/columns.py +70 -26
- urwid/widget/frame.py +17 -0
- urwid/widget/grid_flow.py +39 -4
- urwid/widget/overlay.py +62 -2
- urwid/widget/padding.py +10 -0
- urwid/widget/pile.py +45 -14
- urwid/widget/widget.py +1 -1
- {urwid-2.6.5.dist-info → urwid-2.6.7.dist-info}/METADATA +1 -1
- {urwid-2.6.5.dist-info → urwid-2.6.7.dist-info}/RECORD +14 -14
- {urwid-2.6.5.dist-info → urwid-2.6.7.dist-info}/COPYING +0 -0
- {urwid-2.6.5.dist-info → urwid-2.6.7.dist-info}/WHEEL +0 -0
- {urwid-2.6.5.dist-info → urwid-2.6.7.dist-info}/top_level.txt +0 -0
urwid/event_loop/main_loop.py
CHANGED
|
@@ -190,7 +190,7 @@ class MainLoop:
|
|
|
190
190
|
else:
|
|
191
191
|
self._topmost_widget = self._widget
|
|
192
192
|
|
|
193
|
-
def _set_pop_ups(self, pop_ups) -> None:
|
|
193
|
+
def _set_pop_ups(self, pop_ups: bool) -> None:
|
|
194
194
|
warnings.warn(
|
|
195
195
|
f"method `{self.__class__.__name__}._set_pop_ups` is deprecated, "
|
|
196
196
|
f"please use `{self.__class__.__name__}.pop_ups` property",
|
|
@@ -214,7 +214,7 @@ class MainLoop:
|
|
|
214
214
|
"""
|
|
215
215
|
self.logger.debug(f"Setting alarm in {sec!r} seconds with callback {callback!r}")
|
|
216
216
|
|
|
217
|
-
def cb():
|
|
217
|
+
def cb() -> None:
|
|
218
218
|
callback(self, user_data)
|
|
219
219
|
|
|
220
220
|
return self.event_loop.alarm(sec, cb)
|
|
@@ -236,7 +236,7 @@ class MainLoop:
|
|
|
236
236
|
sec = tm - time.time()
|
|
237
237
|
self.logger.debug(f"Setting alarm in {sec!r} seconds with callback {callback!r}")
|
|
238
238
|
|
|
239
|
-
def cb():
|
|
239
|
+
def cb() -> None:
|
|
240
240
|
callback(self, user_data)
|
|
241
241
|
|
|
242
242
|
return self.event_loop.alarm(sec, cb)
|
|
@@ -250,33 +250,28 @@ class MainLoop:
|
|
|
250
250
|
|
|
251
251
|
if not IS_WINDOWS:
|
|
252
252
|
|
|
253
|
-
def watch_pipe(self, callback: Callable[[bytes], bool]) -> int:
|
|
253
|
+
def watch_pipe(self, callback: Callable[[bytes], bool | None]) -> int:
|
|
254
254
|
"""
|
|
255
255
|
Create a pipe for use by a subprocess or thread to trigger a callback
|
|
256
256
|
in the process/thread running the main loop.
|
|
257
257
|
|
|
258
|
-
:param callback: function taking one parameter to call from within
|
|
259
|
-
the process/thread running the main loop
|
|
258
|
+
:param callback: function taking one parameter to call from within the process/thread running the main loop
|
|
260
259
|
:type callback: callable
|
|
261
260
|
|
|
262
|
-
This method returns a file descriptor attached to the write end of a
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
data read from the pipe.
|
|
261
|
+
This method returns a file descriptor attached to the write end of a pipe.
|
|
262
|
+
The read end of the pipe is added to the list of files :attr:`event_loop` is watching.
|
|
263
|
+
When data is written to the pipe the callback function will be called
|
|
264
|
+
and passed a single value containing data read from the pipe.
|
|
267
265
|
|
|
268
|
-
This method may be used any time you want to update widgets from
|
|
269
|
-
another thread or subprocess.
|
|
266
|
+
This method may be used any time you want to update widgets from another thread or subprocess.
|
|
270
267
|
|
|
271
|
-
Data may be written to the returned file descriptor with
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
complete value of data passed in.
|
|
268
|
+
Data may be written to the returned file descriptor with ``os.write(fd, data)``.
|
|
269
|
+
Ensure that data is less than 512 bytes (or 4K on Linux)
|
|
270
|
+
so that the callback will be triggered just once with the complete value of data passed in.
|
|
275
271
|
|
|
276
|
-
If the callback returns ``False`` then the watch will be removed from
|
|
277
|
-
|
|
278
|
-
are responsible for closing the write end of the pipe with
|
|
279
|
-
``os.close(fd)``.
|
|
272
|
+
If the callback returns ``False`` then the watch will be removed from :attr:`event_loop`
|
|
273
|
+
and the read end of the pipe will be closed.
|
|
274
|
+
You are responsible for closing the write end of the pipe with ``os.close(fd)``.
|
|
280
275
|
"""
|
|
281
276
|
import fcntl
|
|
282
277
|
|
|
@@ -286,7 +281,7 @@ class MainLoop:
|
|
|
286
281
|
|
|
287
282
|
def cb() -> None:
|
|
288
283
|
data = os.read(pipe_rd, PIPE_BUFFER_READ_SIZE)
|
|
289
|
-
if
|
|
284
|
+
if callback(data) is False:
|
|
290
285
|
self.event_loop.remove_watch_file(watch_handle)
|
|
291
286
|
os.close(pipe_rd)
|
|
292
287
|
|
|
@@ -296,9 +291,9 @@ class MainLoop:
|
|
|
296
291
|
|
|
297
292
|
def remove_watch_pipe(self, write_fd: int) -> bool:
|
|
298
293
|
"""
|
|
299
|
-
Close the read end of the pipe and remove the watch created by
|
|
300
|
-
|
|
301
|
-
the pipe.
|
|
294
|
+
Close the read end of the pipe and remove the watch created by :meth:`watch_pipe`.
|
|
295
|
+
|
|
296
|
+
..note:: You are responsible for closing the write end of the pipe.
|
|
302
297
|
|
|
303
298
|
Returns ``True`` if the watch pipe exists, ``False`` otherwise
|
|
304
299
|
"""
|
urwid/version.py
CHANGED
urwid/widget/columns.py
CHANGED
|
@@ -7,6 +7,7 @@ from itertools import chain, repeat
|
|
|
7
7
|
import urwid
|
|
8
8
|
from urwid.canvas import Canvas, CanvasJoin, CompositeCanvas, SolidCanvas
|
|
9
9
|
from urwid.command_map import Command
|
|
10
|
+
from urwid.split_repr import remove_defaults
|
|
10
11
|
from urwid.util import is_mouse_press
|
|
11
12
|
|
|
12
13
|
from .constants import Align, Sizing, WHSettings
|
|
@@ -15,7 +16,7 @@ from .monitored_list import MonitoredFocusList, MonitoredList
|
|
|
15
16
|
from .widget import Widget, WidgetError, WidgetWarning
|
|
16
17
|
|
|
17
18
|
if typing.TYPE_CHECKING:
|
|
18
|
-
from collections.abc import Iterable, Sequence
|
|
19
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
19
20
|
|
|
20
21
|
from typing_extensions import Literal
|
|
21
22
|
|
|
@@ -66,43 +67,43 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
66
67
|
|
|
67
68
|
# BOX-only widget
|
|
68
69
|
>>> Columns((SolidFill("#"),))
|
|
69
|
-
<Columns box widget
|
|
70
|
+
<Columns box widget (1 item)>
|
|
70
71
|
|
|
71
72
|
# BOX-only widget with "get height from max"
|
|
72
73
|
>>> Columns((SolidFill("#"),), box_columns=(0,))
|
|
73
|
-
<Columns box widget
|
|
74
|
+
<Columns box widget (1 item)>
|
|
74
75
|
|
|
75
76
|
# FLOW-only
|
|
76
77
|
>>> Columns((Edit(),))
|
|
77
|
-
<Columns selectable flow widget
|
|
78
|
+
<Columns selectable flow widget (1 item)>
|
|
78
79
|
|
|
79
80
|
# FLOW allowed by "box_columns"
|
|
80
81
|
>>> Columns((Edit(), SolidFill("#")), box_columns=(1,))
|
|
81
|
-
<Columns selectable flow widget
|
|
82
|
+
<Columns selectable flow widget (2 items) focus_column=0>
|
|
82
83
|
|
|
83
84
|
# FLOW/FIXED
|
|
84
85
|
>>> Columns((Text("T"),))
|
|
85
|
-
<Columns fixed/flow widget
|
|
86
|
+
<Columns fixed/flow widget (1 item)>
|
|
86
87
|
|
|
87
88
|
# GIVEN BOX only -> BOX only
|
|
88
89
|
>>> Columns(((5, SolidFill("#")),), box_columns=(0,))
|
|
89
|
-
<Columns box widget
|
|
90
|
+
<Columns box widget (1 item)>
|
|
90
91
|
|
|
91
92
|
# No FLOW - BOX only
|
|
92
93
|
>>> Columns(((5, SolidFill("#")), SolidFill("*")), box_columns=(0, 1))
|
|
93
|
-
<Columns box widget
|
|
94
|
+
<Columns box widget (2 items) focus_column=0>
|
|
94
95
|
|
|
95
|
-
# FIXED only -> FIXED
|
|
96
|
+
# FIXED only -> FIXED (and FLOW via drop/expand)
|
|
96
97
|
>>> Columns(((WHSettings.PACK, BigText("1", font)),))
|
|
97
|
-
<Columns fixed widget
|
|
98
|
+
<Columns fixed/flow widget (1 item)>
|
|
98
99
|
|
|
99
100
|
# Invalid sizing combination -> use fallback settings (and produce warning)
|
|
100
101
|
>>> Columns(((WHSettings.PACK, SolidFill("#")),))
|
|
101
|
-
<Columns box/flow widget
|
|
102
|
+
<Columns box/flow widget (1 item)>
|
|
102
103
|
|
|
103
104
|
# Special case: empty columns widget sizing is impossible to calculate
|
|
104
105
|
>>> Columns(())
|
|
105
|
-
<Columns box/flow widget
|
|
106
|
+
<Columns box/flow widget ()>
|
|
106
107
|
"""
|
|
107
108
|
if not self.contents:
|
|
108
109
|
return frozenset((urwid.BOX, urwid.FLOW))
|
|
@@ -183,6 +184,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
183
184
|
supported.add(Sizing.FLOW)
|
|
184
185
|
|
|
185
186
|
if has_fixed and not block_fixed:
|
|
187
|
+
supported.add(Sizing.FLOW)
|
|
186
188
|
supported.add(Sizing.FIXED)
|
|
187
189
|
|
|
188
190
|
if not supported:
|
|
@@ -289,10 +291,50 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
289
291
|
|
|
290
292
|
def _repr_words(self) -> list[str]:
|
|
291
293
|
if len(self.contents) > 1:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
contents_string = f"({len(self.contents)} items)"
|
|
295
|
+
elif self.contents:
|
|
296
|
+
contents_string = "(1 item)"
|
|
297
|
+
else:
|
|
298
|
+
contents_string = "()"
|
|
299
|
+
return [*super()._repr_words(), contents_string]
|
|
300
|
+
|
|
301
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
302
|
+
attrs = {
|
|
303
|
+
**super()._repr_attrs(),
|
|
304
|
+
"dividechars": self.dividechars,
|
|
305
|
+
"focus_column": self.focus_position if len(self._contents) > 1 else None,
|
|
306
|
+
"min_width": self.min_width,
|
|
307
|
+
}
|
|
308
|
+
return remove_defaults(attrs, Columns.__init__)
|
|
309
|
+
|
|
310
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
311
|
+
widget_list: list[
|
|
312
|
+
Widget
|
|
313
|
+
| tuple[Literal[WHSettings.PACK] | int, Widget]
|
|
314
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float, Widget]
|
|
315
|
+
] = []
|
|
316
|
+
box_columns: list[int] = []
|
|
317
|
+
for idx, (w_instance, (sizing, amount, is_box)) in enumerate(self._contents):
|
|
318
|
+
if sizing == WHSettings.GIVEN:
|
|
319
|
+
widget_list.append((amount, w_instance))
|
|
320
|
+
elif sizing == WHSettings.PACK:
|
|
321
|
+
widget_list.append((WHSettings.PACK, w_instance))
|
|
322
|
+
elif amount == 1:
|
|
323
|
+
widget_list.append(w_instance)
|
|
324
|
+
else:
|
|
325
|
+
widget_list.append((WHSettings.WEIGHT, amount, w_instance))
|
|
326
|
+
|
|
327
|
+
if is_box:
|
|
328
|
+
box_columns.append(idx)
|
|
329
|
+
|
|
330
|
+
yield "widget_list", widget_list
|
|
331
|
+
yield "dividechars", self.dividechars
|
|
332
|
+
yield "focus_column", self.focus_position if self._contents else None
|
|
333
|
+
yield "min_width", self.min_width
|
|
334
|
+
yield "box_columns", box_columns
|
|
335
|
+
|
|
336
|
+
def __len__(self) -> int:
|
|
337
|
+
return len(self._contents)
|
|
296
338
|
|
|
297
339
|
def _contents_modified(self) -> None:
|
|
298
340
|
"""
|
|
@@ -904,11 +946,17 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
904
946
|
box.append(i)
|
|
905
947
|
|
|
906
948
|
elif Sizing.FLOW in w_sizing:
|
|
907
|
-
|
|
949
|
+
if width > 0:
|
|
950
|
+
heights[i] = widget.rows((width,), focus and i == self.focus_position)
|
|
951
|
+
else:
|
|
952
|
+
heights[i] = 0
|
|
908
953
|
w_h_args[i] = (width,)
|
|
909
954
|
|
|
910
955
|
elif size_kind == WHSettings.PACK:
|
|
911
|
-
|
|
956
|
+
if width > 0:
|
|
957
|
+
heights[i] = widget.pack((), focus and i == self.focus_position)[1]
|
|
958
|
+
else:
|
|
959
|
+
heights[i] = 0
|
|
912
960
|
w_h_args[i] = ()
|
|
913
961
|
|
|
914
962
|
else:
|
|
@@ -1135,14 +1183,10 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
1135
1183
|
|
|
1136
1184
|
see :meth:`Widget.rows` for details
|
|
1137
1185
|
"""
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
if b or mc <= 0:
|
|
1143
|
-
continue
|
|
1144
|
-
rows = max(rows, w.rows((mc,), focus=focus and self.focus_position == i))
|
|
1145
|
-
return rows
|
|
1186
|
+
_, heights, _ = self.get_column_sizes(size, focus)
|
|
1187
|
+
if heights:
|
|
1188
|
+
return max(1, *heights)
|
|
1189
|
+
return 1
|
|
1146
1190
|
|
|
1147
1191
|
def keypress(
|
|
1148
1192
|
self,
|
urwid/widget/frame.py
CHANGED
|
@@ -4,6 +4,7 @@ import typing
|
|
|
4
4
|
import warnings
|
|
5
5
|
|
|
6
6
|
from urwid.canvas import CanvasCombine, CompositeCanvas
|
|
7
|
+
from urwid.split_repr import remove_defaults
|
|
7
8
|
from urwid.util import is_mouse_press
|
|
8
9
|
|
|
9
10
|
from .constants import Sizing, VAlign
|
|
@@ -89,6 +90,22 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
|
|
|
89
90
|
_check_widget_subclass(body)
|
|
90
91
|
_check_widget_subclass(footer)
|
|
91
92
|
|
|
93
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
94
|
+
attrs = {
|
|
95
|
+
**super()._repr_attrs(),
|
|
96
|
+
"body": self._body,
|
|
97
|
+
"header": self._header,
|
|
98
|
+
"footer": self._footer,
|
|
99
|
+
"focus_part": self.focus_part,
|
|
100
|
+
}
|
|
101
|
+
return remove_defaults(attrs, Frame.__init__)
|
|
102
|
+
|
|
103
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
104
|
+
yield "body", self._body
|
|
105
|
+
yield "header", self._header
|
|
106
|
+
yield "footer", self._footer
|
|
107
|
+
yield "focus_part", self.focus_part
|
|
108
|
+
|
|
92
109
|
@property
|
|
93
110
|
def header(self) -> HeaderWidget:
|
|
94
111
|
return self._header
|
urwid/widget/grid_flow.py
CHANGED
|
@@ -3,6 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
import typing
|
|
4
4
|
import warnings
|
|
5
5
|
|
|
6
|
+
from urwid.split_repr import remove_defaults
|
|
7
|
+
|
|
6
8
|
from .columns import Columns
|
|
7
9
|
from .constants import Align, Sizing, WHSettings
|
|
8
10
|
from .container import WidgetContainerListContentsMixin, WidgetContainerMixin
|
|
@@ -13,7 +15,7 @@ from .pile import Pile
|
|
|
13
15
|
from .widget import Widget, WidgetError, WidgetWarning, WidgetWrap
|
|
14
16
|
|
|
15
17
|
if typing.TYPE_CHECKING:
|
|
16
|
-
from collections.abc import Iterable, Sequence
|
|
18
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
17
19
|
|
|
18
20
|
from typing_extensions import Literal
|
|
19
21
|
|
|
@@ -78,12 +80,45 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
|
|
|
78
80
|
self._cache_maxcol = self._get_maxcol(())
|
|
79
81
|
super().__init__(self.generate_display_widget((self._cache_maxcol,)))
|
|
80
82
|
|
|
83
|
+
def _repr_words(self) -> list[str]:
|
|
84
|
+
if len(self.contents) > 1:
|
|
85
|
+
contents_string = f"({len(self.contents)} items)"
|
|
86
|
+
elif self.contents:
|
|
87
|
+
contents_string = "(1 item)"
|
|
88
|
+
else:
|
|
89
|
+
contents_string = "()"
|
|
90
|
+
return [*super()._repr_words(), contents_string]
|
|
91
|
+
|
|
92
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
93
|
+
attrs = {
|
|
94
|
+
**super()._repr_attrs(),
|
|
95
|
+
"cell_width": self.cell_width,
|
|
96
|
+
"h_sep": self.h_sep,
|
|
97
|
+
"v_sep": self.v_sep,
|
|
98
|
+
"align": self.align,
|
|
99
|
+
"focus": self.focus_position if len(self._contents) > 1 else None,
|
|
100
|
+
}
|
|
101
|
+
return remove_defaults(attrs, GridFlow.__init__)
|
|
102
|
+
|
|
103
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
104
|
+
yield "cells", [widget for widget, _ in self.contents]
|
|
105
|
+
yield "cell_width", self.cell_width
|
|
106
|
+
yield "h_sep", self.h_sep
|
|
107
|
+
yield "v_sep", self.v_sep
|
|
108
|
+
yield "align", self.align
|
|
109
|
+
yield "focus", self.focus_position
|
|
110
|
+
|
|
111
|
+
def __len__(self) -> int:
|
|
112
|
+
return len(self._contents)
|
|
113
|
+
|
|
81
114
|
def _invalidate(self) -> None:
|
|
82
115
|
self._cache_maxcol = None
|
|
83
116
|
super()._invalidate()
|
|
84
117
|
|
|
85
118
|
def _contents_modified(
|
|
86
|
-
self,
|
|
119
|
+
self,
|
|
120
|
+
_slc: tuple[int, int, int],
|
|
121
|
+
new_items: Iterable[tuple[Widget, tuple[Literal["given", WHSettings.GIVEN], int]]],
|
|
87
122
|
) -> None:
|
|
88
123
|
for item in new_items:
|
|
89
124
|
try:
|
|
@@ -258,7 +293,7 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
|
|
|
258
293
|
return None
|
|
259
294
|
return self.contents[self.focus_position][0]
|
|
260
295
|
|
|
261
|
-
def _get_focus(self) -> Widget:
|
|
296
|
+
def _get_focus(self) -> Widget | None:
|
|
262
297
|
warnings.warn(
|
|
263
298
|
f"method `{self.__class__.__name__}._get_focus` is deprecated, "
|
|
264
299
|
f"please use `{self.__class__.__name__}.focus` property",
|
|
@@ -446,7 +481,7 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
|
|
|
446
481
|
|
|
447
482
|
# Use width == maxcol in case of maxcol < width amount
|
|
448
483
|
# Columns will use empty widget in case of GIVEN width > maxcol
|
|
449
|
-
c.contents.append((w, c.options(WHSettings.GIVEN, width_amount
|
|
484
|
+
c.contents.append((w, c.options(WHSettings.GIVEN, min(width_amount, maxcol))))
|
|
450
485
|
if (i == self.focus_position) or (not column_focused and w.selectable()):
|
|
451
486
|
c.focus_position = len(c.contents) - 1
|
|
452
487
|
column_focused = True
|
urwid/widget/overlay.py
CHANGED
|
@@ -4,6 +4,7 @@ import typing
|
|
|
4
4
|
import warnings
|
|
5
5
|
|
|
6
6
|
from urwid.canvas import CanvasOverlay, CompositeCanvas
|
|
7
|
+
from urwid.split_repr import remove_defaults
|
|
7
8
|
|
|
8
9
|
from .constants import (
|
|
9
10
|
RELATIVE_100,
|
|
@@ -330,8 +331,67 @@ class Overlay(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin, ty
|
|
|
330
331
|
f"min_height={self.min_height!r}"
|
|
331
332
|
)
|
|
332
333
|
|
|
333
|
-
def
|
|
334
|
-
|
|
334
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
335
|
+
attrs = {
|
|
336
|
+
**super()._repr_attrs(),
|
|
337
|
+
"top_w": self.top_w,
|
|
338
|
+
"bottom_w": self.bottom_w,
|
|
339
|
+
"align": self.align,
|
|
340
|
+
"width": self.width,
|
|
341
|
+
"valign": self.valign,
|
|
342
|
+
"height": self.height,
|
|
343
|
+
"min_width": self.min_width,
|
|
344
|
+
"min_height": self.min_height,
|
|
345
|
+
"left": self.left,
|
|
346
|
+
"right": self.right,
|
|
347
|
+
"top": self.top,
|
|
348
|
+
"bottom": self.bottom,
|
|
349
|
+
}
|
|
350
|
+
return remove_defaults(attrs, Overlay.__init__)
|
|
351
|
+
|
|
352
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
353
|
+
yield "top", self.top_w
|
|
354
|
+
yield "bottom", self.bottom_w
|
|
355
|
+
yield "align", self.align
|
|
356
|
+
yield "width", self.width
|
|
357
|
+
yield "valign", self.valign
|
|
358
|
+
yield "height", self.height
|
|
359
|
+
yield "min_width", self.min_width
|
|
360
|
+
yield "min_height", self.min_height
|
|
361
|
+
yield "left", self.left
|
|
362
|
+
yield "right", self.right
|
|
363
|
+
yield "top", self.top
|
|
364
|
+
yield "bottom", self.bottom
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def align(self) -> Align | tuple[Literal[WHSettings.RELATIVE], int]:
|
|
368
|
+
return simplify_align(self.align_type, self.align_amount)
|
|
369
|
+
|
|
370
|
+
@property
|
|
371
|
+
def width(
|
|
372
|
+
self,
|
|
373
|
+
) -> (
|
|
374
|
+
Literal[WHSettings.CLIP, WHSettings.PACK]
|
|
375
|
+
| int
|
|
376
|
+
| tuple[Literal[WHSettings.RELATIVE], int]
|
|
377
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float]
|
|
378
|
+
):
|
|
379
|
+
return simplify_width(self.width_type, self.width_amount)
|
|
380
|
+
|
|
381
|
+
@property
|
|
382
|
+
def valign(self) -> VAlign | tuple[Literal[WHSettings.RELATIVE], int]:
|
|
383
|
+
return simplify_valign(self.valign_type, self.valign_amount)
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def height(
|
|
387
|
+
self,
|
|
388
|
+
) -> (
|
|
389
|
+
int
|
|
390
|
+
| Literal[WHSettings.FLOW, WHSettings.PACK]
|
|
391
|
+
| tuple[Literal[WHSettings.RELATIVE], int]
|
|
392
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float]
|
|
393
|
+
):
|
|
394
|
+
return simplify_height(self.height_type, self.height_amount)
|
|
335
395
|
|
|
336
396
|
@staticmethod
|
|
337
397
|
def options(
|
urwid/widget/padding.py
CHANGED
|
@@ -20,6 +20,8 @@ from .constants import (
|
|
|
20
20
|
from .widget_decoration import WidgetDecoration, WidgetError, WidgetWarning
|
|
21
21
|
|
|
22
22
|
if typing.TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Iterator
|
|
24
|
+
|
|
23
25
|
from typing_extensions import Literal
|
|
24
26
|
|
|
25
27
|
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
@@ -184,6 +186,14 @@ class Padding(WidgetDecoration[WrappedWidget], typing.Generic[WrappedWidget]):
|
|
|
184
186
|
}
|
|
185
187
|
return remove_defaults(attrs, Padding.__init__)
|
|
186
188
|
|
|
189
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
190
|
+
yield "w", self.original_widget
|
|
191
|
+
yield "align", self.align
|
|
192
|
+
yield "width", self.width
|
|
193
|
+
yield "min_width", self.min_width
|
|
194
|
+
yield "left", self.left
|
|
195
|
+
yield "right", self.right
|
|
196
|
+
|
|
187
197
|
@property
|
|
188
198
|
def align(
|
|
189
199
|
self,
|
urwid/widget/pile.py
CHANGED
|
@@ -6,6 +6,7 @@ from itertools import chain, repeat
|
|
|
6
6
|
|
|
7
7
|
from urwid.canvas import CanvasCombine, CompositeCanvas, SolidCanvas
|
|
8
8
|
from urwid.command_map import Command
|
|
9
|
+
from urwid.split_repr import remove_defaults
|
|
9
10
|
from urwid.util import is_mouse_press
|
|
10
11
|
|
|
11
12
|
from .constants import Sizing, WHSettings
|
|
@@ -14,7 +15,7 @@ from .monitored_list import MonitoredFocusList, MonitoredList
|
|
|
14
15
|
from .widget import Widget, WidgetError, WidgetWarning
|
|
15
16
|
|
|
16
17
|
if typing.TYPE_CHECKING:
|
|
17
|
-
from collections.abc import Iterable, Sequence
|
|
18
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
18
19
|
|
|
19
20
|
from typing_extensions import Literal
|
|
20
21
|
|
|
@@ -58,39 +59,39 @@ class Pile(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
58
59
|
|
|
59
60
|
# BOX-only widget
|
|
60
61
|
>>> Pile((SolidFill("#"),))
|
|
61
|
-
<Pile box widget
|
|
62
|
+
<Pile box widget (1 item)>
|
|
62
63
|
|
|
63
64
|
# GIVEN BOX -> BOX/FLOW
|
|
64
65
|
>>> Pile(((10, SolidFill("#")),))
|
|
65
|
-
<Pile box/flow widget
|
|
66
|
+
<Pile box/flow widget (1 item)>
|
|
66
67
|
|
|
67
68
|
# FLOW-only
|
|
68
69
|
>>> Pile((ProgressBar(None, None),))
|
|
69
|
-
<Pile flow widget
|
|
70
|
+
<Pile flow widget (1 item)>
|
|
70
71
|
|
|
71
72
|
# FIXED -> FIXED
|
|
72
73
|
>>> Pile(((WHSettings.PACK, BigText("0", font)),))
|
|
73
|
-
<Pile fixed widget
|
|
74
|
+
<Pile fixed widget (1 item)>
|
|
74
75
|
|
|
75
76
|
# FLOW/FIXED -> FLOW/FIXED
|
|
76
77
|
>>> Pile(((WHSettings.PACK, Text("text")),))
|
|
77
|
-
<Pile fixed/flow widget
|
|
78
|
+
<Pile fixed/flow widget (1 item)>
|
|
78
79
|
|
|
79
80
|
# FLOW + FIXED widgets -> FLOW/FIXED
|
|
80
81
|
>>> Pile((ProgressBar(None, None), (WHSettings.PACK, BigText("0", font))))
|
|
81
|
-
<Pile fixed/flow widget
|
|
82
|
+
<Pile fixed/flow widget (2 items) focus_item=0>
|
|
82
83
|
|
|
83
84
|
# GIVEN BOX + FIXED widgets -> BOX/FLOW/FIXED (GIVEN BOX allows overriding its height & allows any width)
|
|
84
85
|
>>> Pile(((10, SolidFill("#")), (WHSettings.PACK, BigText("0", font))))
|
|
85
|
-
<Pile widget
|
|
86
|
+
<Pile widget (2 items) focus_item=0>
|
|
86
87
|
|
|
87
88
|
# Invalid sizing combination -> use fallback settings (and produce warning)
|
|
88
89
|
>>> Pile(((WHSettings.WEIGHT, 1, BigText("0", font)),))
|
|
89
|
-
<Pile box/flow widget
|
|
90
|
+
<Pile box/flow widget (1 item)>
|
|
90
91
|
|
|
91
92
|
# Special case: empty pile widget sizing is impossible to calculate
|
|
92
93
|
>>> Pile(())
|
|
93
|
-
<Pile box/flow widget
|
|
94
|
+
<Pile box/flow widget ()>
|
|
94
95
|
"""
|
|
95
96
|
if not self.contents:
|
|
96
97
|
return frozenset((Sizing.BOX, Sizing.FLOW))
|
|
@@ -233,10 +234,40 @@ class Pile(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
233
234
|
|
|
234
235
|
def _repr_words(self) -> list[str]:
|
|
235
236
|
if len(self.contents) > 1:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
contents_string = f"({len(self.contents)} items)"
|
|
238
|
+
elif self.contents:
|
|
239
|
+
contents_string = "(1 item)"
|
|
240
|
+
else:
|
|
241
|
+
contents_string = "()"
|
|
242
|
+
return [*super()._repr_words(), contents_string]
|
|
243
|
+
|
|
244
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
245
|
+
attrs = {**super()._repr_attrs(), "focus_item": self.focus_position if len(self._contents) > 1 else None}
|
|
246
|
+
return remove_defaults(attrs, Pile.__init__)
|
|
247
|
+
|
|
248
|
+
def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
|
|
249
|
+
widget_list: list[
|
|
250
|
+
Widget
|
|
251
|
+
| tuple[Literal[WHSettings.PACK] | int, Widget]
|
|
252
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float, Widget]
|
|
253
|
+
] = []
|
|
254
|
+
|
|
255
|
+
for w_instance, (sizing, amount) in self._contents:
|
|
256
|
+
if sizing == WHSettings.GIVEN:
|
|
257
|
+
widget_list.append((amount, w_instance))
|
|
258
|
+
elif sizing == WHSettings.PACK:
|
|
259
|
+
widget_list.append((WHSettings.PACK, w_instance))
|
|
260
|
+
elif sizing == WHSettings.WEIGHT:
|
|
261
|
+
if amount == 1:
|
|
262
|
+
widget_list.append(w_instance)
|
|
263
|
+
else:
|
|
264
|
+
widget_list.append((WHSettings.WEIGHT, amount, w_instance))
|
|
265
|
+
|
|
266
|
+
yield "widget_list", widget_list
|
|
267
|
+
yield "focus_item", self.focus_position if self._contents else None
|
|
268
|
+
|
|
269
|
+
def __len__(self) -> int:
|
|
270
|
+
return len(self._contents)
|
|
240
271
|
|
|
241
272
|
def _contents_modified(self) -> None:
|
|
242
273
|
"""Recalculate whether this widget should be selectable whenever the contents has been changed."""
|
urwid/widget/widget.py
CHANGED
|
@@ -391,7 +391,7 @@ class Widget(metaclass=WidgetMeta):
|
|
|
391
391
|
"""
|
|
392
392
|
if not size:
|
|
393
393
|
if Sizing.FIXED in self.sizing():
|
|
394
|
-
raise NotImplementedError("
|
|
394
|
+
raise NotImplementedError(f"{self!r} must override Widget.pack()")
|
|
395
395
|
raise WidgetError(f"Cannot pack () size, this is not a fixed widget: {self!r}")
|
|
396
396
|
|
|
397
397
|
if len(size) == 1:
|
|
@@ -11,7 +11,7 @@ urwid/split_repr.py,sha256=pXzuddzQ4RnfIl537Gvoe8PVaBRHCPnxgdYvKK0qm8k,3899
|
|
|
11
11
|
urwid/str_util.py,sha256=1ss-LHAhjXTynTVBcoSgYWIpBeN_RirqHYhP7fq7MrA,10844
|
|
12
12
|
urwid/text_layout.py,sha256=lHiGfo7clmwHt5dMl_AaQSs2ov9IbY9JySTATZBm7h0,22821
|
|
13
13
|
urwid/util.py,sha256=pGXnma03_IBx3v6_qN9cDWPXPj_YjkhQ9IxLjm_0TpU,15747
|
|
14
|
-
urwid/version.py,sha256=
|
|
14
|
+
urwid/version.py,sha256=tZREgQXhRCjy8CaVlbDdgPh_RAE1RKJtFgHzY2HTyfw,411
|
|
15
15
|
urwid/vterm.py,sha256=q9-8dxJpVr_7a0Bj_z_FYDiRgzos3IS17BjhYcy1RDw,58410
|
|
16
16
|
urwid/wimp.py,sha256=o1YsjL_tBLXba8ZRr1MTHH0poLSlXT_atY3-uD_Ualg,567
|
|
17
17
|
urwid/display/__init__.py,sha256=y90WbHPNRHlimPrXhzsSfFsBbBHy8QErmB1y4Xza-xo,1732
|
|
@@ -32,7 +32,7 @@ urwid/event_loop/__init__.py,sha256=6di4AYD6HbCf6v5p0rZOoteKnM9U5tfk4NKcWMH4FV4,
|
|
|
32
32
|
urwid/event_loop/abstract_loop.py,sha256=6Kkw3KCJ4ndiI2I1P8fPdtHzjuekRxUuvzFOiR0Myok,5494
|
|
33
33
|
urwid/event_loop/asyncio_loop.py,sha256=QoK1zO6YHg5dn2DPlCXSf9uXPHEe6k6P9pPJMWISB-Q,8473
|
|
34
34
|
urwid/event_loop/glib_loop.py,sha256=GFoLAenoWKm-13rTBKzCF2JdCEryJKpMo25aidZ7BWs,9351
|
|
35
|
-
urwid/event_loop/main_loop.py,sha256=
|
|
35
|
+
urwid/event_loop/main_loop.py,sha256=gR2jGmqg1-CXFdNDlt-NizdS5AA7EZfmp6sW-nXwa18,26000
|
|
36
36
|
urwid/event_loop/select_loop.py,sha256=5ZkIPqyIVJdWRTC89Ca5h8ub_-jpqXjFZaKqiWhdkDg,7534
|
|
37
37
|
urwid/event_loop/tornado_loop.py,sha256=VNgXW2gO4edcYDjyEGb86yOHrE0NNXQUPXIOfJyZnAk,7100
|
|
38
38
|
urwid/event_loop/trio_loop.py,sha256=2SBX1pbiJddAsXbe1itPPXYdoX5_U00m56A4h0x9dWI,10467
|
|
@@ -44,31 +44,31 @@ urwid/widget/attr_wrap.py,sha256=pJQHVNlwcX5IgpdSmTqYOt63EX-p5hA0mJfXtWXJ6wg,483
|
|
|
44
44
|
urwid/widget/bar_graph.py,sha256=Ui2Z-DJ7Try9rkAQ14rK__-oSGfsWncpJH-AxSF00bk,21615
|
|
45
45
|
urwid/widget/big_text.py,sha256=Zvjbkdh4H1Wv9ZTdCbX23vfNyeybO8au-kUssE58Bbs,2393
|
|
46
46
|
urwid/widget/box_adapter.py,sha256=uOFlZUaCK9A4H8Pmw6-OoS9QTYi9nn-LhlSa-JpC9Iw,4276
|
|
47
|
-
urwid/widget/columns.py,sha256=
|
|
47
|
+
urwid/widget/columns.py,sha256=Jz-0oR27uAoUV8LdhPWuCrkMgSHSYTxciNjxDCXPTbs,46508
|
|
48
48
|
urwid/widget/constants.py,sha256=bNvw1OoT6jFWzDc_NDJRcle1uIX-ENswhvy2S6mIUEk,15313
|
|
49
49
|
urwid/widget/container.py,sha256=HqafpI2Apz-oI1bcW5rTl3kbOKfPFv_xI8zEXQU7hYI,7177
|
|
50
50
|
urwid/widget/divider.py,sha256=cM0gWHAqBz7E8l52CGEWWDMSVQkPNDjwy-t3ptbmh2s,3251
|
|
51
51
|
urwid/widget/edit.py,sha256=qgVYeg_hX6tqRUiuLQkYwYKmWcfVLrLzAG1a5Au6S-w,23732
|
|
52
52
|
urwid/widget/filler.py,sha256=EEnyAawdKXuwf79pErfNuvqsU1SVTutcMUrwWkU4wfo,14665
|
|
53
|
-
urwid/widget/frame.py,sha256=
|
|
54
|
-
urwid/widget/grid_flow.py,sha256=
|
|
53
|
+
urwid/widget/frame.py,sha256=AOe4FwjvwcIwrpXqyZkCwSZWwAALNl1XRMAKx6ZXYWs,21834
|
|
54
|
+
urwid/widget/grid_flow.py,sha256=otujeOTWYDr4gwuDikBm9zZd8SUgma9yvQ1hDWI-dGk,21514
|
|
55
55
|
urwid/widget/line_box.py,sha256=V750xiZtkw6_uRXLhNY91ER3pXwwrZstVv_IJUZd_YY,6884
|
|
56
56
|
urwid/widget/listbox.py,sha256=s3hg3VoiDY3pfqEmkURIE_Fa8WcLLzuaJn-_LVfG0EM,69495
|
|
57
57
|
urwid/widget/monitored_list.py,sha256=M0PjNc_Vtuk6fnWdDelx-nbs3jLtXAo4JKB_OTk8McI,18773
|
|
58
|
-
urwid/widget/overlay.py,sha256=
|
|
59
|
-
urwid/widget/padding.py,sha256=
|
|
60
|
-
urwid/widget/pile.py,sha256=
|
|
58
|
+
urwid/widget/overlay.py,sha256=sCkrAI5qte_Ddb9VrIqknZNgYAXq1JPxNFqHxF6s9Po,32892
|
|
59
|
+
urwid/widget/padding.py,sha256=tdBJybrKJqR8OLo5DHixn6KZA3tefYlfo9kkqvxYLEc,21252
|
|
60
|
+
urwid/widget/pile.py,sha256=aIzKYNrSQtbHVk_bn2PElHUiSdsO_NKnL4mTu-sXm4I,38628
|
|
61
61
|
urwid/widget/popup.py,sha256=UQ1MTzt8RNcfIvmwIqDM4mypxxXUOMsGoiozom8HfTg,5814
|
|
62
62
|
urwid/widget/progress_bar.py,sha256=HRnIu2V2_4wgsnAdrhK-GVVToyLaXRH0gtlkWllA4Mo,4767
|
|
63
63
|
urwid/widget/scrollable.py,sha256=PZjcelZlyfl0MnxY7DHuaae_XbjuJQ1bVNPlSlmaWJI,22198
|
|
64
64
|
urwid/widget/solid_fill.py,sha256=NZRDSRK0lP4r7gXcKDgVaKEoeOcWvtrY5k2aueQEEL4,1260
|
|
65
65
|
urwid/widget/text.py,sha256=jy15hL6rCBoJdZviq2jJ-i9eO6vEcxvzCIVAZs12AUw,12187
|
|
66
66
|
urwid/widget/treetools.py,sha256=7b2US3Dj_akQ2JCf5gPo1SKGfvIhnQjbkpcLfYl0Kk4,17307
|
|
67
|
-
urwid/widget/widget.py,sha256=
|
|
67
|
+
urwid/widget/widget.py,sha256=dMGNVewj2NGFdGKAtDJYgOzhuJAtrr_BALOMwNzUyj0,29550
|
|
68
68
|
urwid/widget/widget_decoration.py,sha256=aHP9Y7JKVCI2dw2OdRrzMj9p--C1pMIbxSJskWBLIgc,5633
|
|
69
69
|
urwid/widget/wimp.py,sha256=4wfzTQBLMbhicSlL64hBPb-1W5FAFrIKfb43i10MKSY,27305
|
|
70
|
-
urwid-2.6.
|
|
71
|
-
urwid-2.6.
|
|
72
|
-
urwid-2.6.
|
|
73
|
-
urwid-2.6.
|
|
74
|
-
urwid-2.6.
|
|
70
|
+
urwid-2.6.7.dist-info/COPYING,sha256=NrbT-keRaUP9X-wxPFhHhJRgR-wTN6eLRA5ZkstZX4k,26434
|
|
71
|
+
urwid-2.6.7.dist-info/METADATA,sha256=Eb5tCnShmcVDexTEGqLILy1Du58ABPC31aGqbwmMRIc,11042
|
|
72
|
+
urwid-2.6.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
73
|
+
urwid-2.6.7.dist-info/top_level.txt,sha256=AwxQA43kNkjHbhYELXHBKrQ01X5CR2KnDzU07cVqilY,6
|
|
74
|
+
urwid-2.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|