urwid 2.6.4__py3-none-any.whl → 2.6.6__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/__init__.py +46 -33
- urwid/canvas.py +4 -6
- urwid/display/_posix_raw_display.py +3 -4
- urwid/display/_raw_display_base.py +4 -5
- urwid/display/_win32_raw_display.py +1 -2
- urwid/display/curses.py +1 -1
- urwid/display/html_fragment.py +1 -1
- urwid/event_loop/__init__.py +5 -5
- urwid/event_loop/main_loop.py +26 -21
- urwid/event_loop/zmq_loop.py +2 -2
- urwid/numedit.py +5 -1
- urwid/signals.py +1 -1
- urwid/str_util.py +1 -2
- urwid/text_layout.py +8 -4
- urwid/version.py +2 -2
- urwid/vterm.py +10 -10
- urwid/widget/__init__.py +19 -1
- urwid/widget/bar_graph.py +8 -4
- urwid/widget/big_text.py +14 -4
- urwid/widget/box_adapter.py +11 -3
- urwid/widget/columns.py +104 -34
- urwid/widget/constants.py +43 -76
- urwid/widget/container.py +2 -2
- urwid/widget/divider.py +5 -1
- urwid/widget/edit.py +20 -14
- urwid/widget/filler.py +11 -4
- urwid/widget/frame.py +91 -28
- urwid/widget/grid_flow.py +66 -15
- urwid/{listbox.py → widget/listbox.py} +27 -23
- urwid/{monitored_list.py → widget/monitored_list.py} +2 -0
- urwid/widget/overlay.py +99 -14
- urwid/widget/padding.py +16 -3
- urwid/widget/pile.py +57 -13
- urwid/widget/progress_bar.py +5 -1
- urwid/widget/scrollable.py +28 -9
- urwid/widget/solid_fill.py +5 -1
- urwid/widget/text.py +11 -3
- urwid/{treetools.py → widget/treetools.py} +35 -18
- urwid/widget/widget.py +17 -9
- urwid/widget/wimp.py +8 -4
- {urwid-2.6.4.dist-info → urwid-2.6.6.dist-info}/METADATA +1 -1
- urwid-2.6.6.dist-info/RECORD +74 -0
- urwid-2.6.4.dist-info/RECORD +0 -74
- {urwid-2.6.4.dist-info → urwid-2.6.6.dist-info}/COPYING +0 -0
- {urwid-2.6.4.dist-info → urwid-2.6.6.dist-info}/WHEEL +0 -0
- {urwid-2.6.4.dist-info → urwid-2.6.6.dist-info}/top_level.txt +0 -0
urwid/widget/box_adapter.py
CHANGED
|
@@ -90,7 +90,11 @@ class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
|
90
90
|
return None
|
|
91
91
|
return self._original_widget.get_pref_col((maxcol, self.height))
|
|
92
92
|
|
|
93
|
-
def keypress(
|
|
93
|
+
def keypress(
|
|
94
|
+
self,
|
|
95
|
+
size: tuple[int], # type: ignore[override]
|
|
96
|
+
key: str,
|
|
97
|
+
) -> str | None:
|
|
94
98
|
(maxcol,) = size
|
|
95
99
|
return self._original_widget.keypress((maxcol, self.height), key)
|
|
96
100
|
|
|
@@ -102,7 +106,7 @@ class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
|
102
106
|
|
|
103
107
|
def mouse_event(
|
|
104
108
|
self,
|
|
105
|
-
size: tuple[int],
|
|
109
|
+
size: tuple[int], # type: ignore[override]
|
|
106
110
|
event: str,
|
|
107
111
|
button: int,
|
|
108
112
|
col: int,
|
|
@@ -114,7 +118,11 @@ class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
|
114
118
|
return False
|
|
115
119
|
return self._original_widget.mouse_event((maxcol, self.height), event, button, col, row, focus)
|
|
116
120
|
|
|
117
|
-
def render(
|
|
121
|
+
def render(
|
|
122
|
+
self,
|
|
123
|
+
size: tuple[int], # type: ignore[override]
|
|
124
|
+
focus: bool = False,
|
|
125
|
+
) -> CompositeCanvas:
|
|
118
126
|
(maxcol,) = size
|
|
119
127
|
canv = CompositeCanvas(self._original_widget.render((maxcol, self.height), focus))
|
|
120
128
|
return canv
|
urwid/widget/columns.py
CHANGED
|
@@ -7,15 +7,16 @@ 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.
|
|
10
|
+
from urwid.split_repr import remove_defaults
|
|
11
11
|
from urwid.util import is_mouse_press
|
|
12
12
|
|
|
13
13
|
from .constants import Align, Sizing, WHSettings
|
|
14
14
|
from .container import WidgetContainerListContentsMixin, WidgetContainerMixin, _ContainerElementSizingFlag
|
|
15
|
+
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,40 +67,47 @@ 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)>
|
|
103
|
+
|
|
104
|
+
# Special case: empty columns widget sizing is impossible to calculate
|
|
105
|
+
>>> Columns(())
|
|
106
|
+
<Columns box/flow widget ()>
|
|
102
107
|
"""
|
|
108
|
+
if not self.contents:
|
|
109
|
+
return frozenset((urwid.BOX, urwid.FLOW))
|
|
110
|
+
|
|
103
111
|
strict_box = False
|
|
104
112
|
has_flow = False
|
|
105
113
|
|
|
@@ -176,6 +184,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
176
184
|
supported.add(Sizing.FLOW)
|
|
177
185
|
|
|
178
186
|
if has_fixed and not block_fixed:
|
|
187
|
+
supported.add(Sizing.FLOW)
|
|
179
188
|
supported.add(Sizing.FIXED)
|
|
180
189
|
|
|
181
190
|
if not supported:
|
|
@@ -238,10 +247,12 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
238
247
|
self._cache_column_widths: list[int] = []
|
|
239
248
|
super().__init__()
|
|
240
249
|
self._contents: MonitoredFocusList[
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
250
|
+
tuple[
|
|
251
|
+
Widget,
|
|
252
|
+
tuple[Literal[WHSettings.PACK], None, bool]
|
|
253
|
+
| tuple[Literal[WHSettings.GIVEN], int, bool]
|
|
254
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float, bool],
|
|
255
|
+
],
|
|
245
256
|
] = MonitoredFocusList()
|
|
246
257
|
self._contents.set_modified_callback(self._contents_modified)
|
|
247
258
|
self._contents.set_focus_changed_callback(lambda f: self._invalidate())
|
|
@@ -278,6 +289,53 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
278
289
|
self.min_width = min_width
|
|
279
290
|
self._cache_maxcol = None
|
|
280
291
|
|
|
292
|
+
def _repr_words(self) -> list[str]:
|
|
293
|
+
if len(self.contents) > 1:
|
|
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)
|
|
338
|
+
|
|
281
339
|
def _contents_modified(self) -> None:
|
|
282
340
|
"""
|
|
283
341
|
Recalculate whether this widget should be selectable whenever the
|
|
@@ -342,7 +400,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
342
400
|
chain(self.contents, repeat((None, (WHSettings.WEIGHT, 1, False)))),
|
|
343
401
|
)
|
|
344
402
|
]
|
|
345
|
-
if focus_position < len(widgets):
|
|
403
|
+
if focus_position < len(widgets): # pylint: disable=consider-using-max-builtin # pylint bug
|
|
346
404
|
self.focus_position = focus_position
|
|
347
405
|
|
|
348
406
|
@property
|
|
@@ -383,7 +441,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
383
441
|
(w, ({Sizing.FIXED: WHSettings.GIVEN, Sizing.FLOW: WHSettings.PACK}.get(new_t, new_t), new_n, b))
|
|
384
442
|
for ((new_t, new_n), (w, (t, n, b))) in zip(column_types, self.contents)
|
|
385
443
|
]
|
|
386
|
-
if focus_position < len(column_types):
|
|
444
|
+
if focus_position < len(column_types): # pylint: disable=consider-using-max-builtin # pylint bug
|
|
387
445
|
self.focus_position = focus_position
|
|
388
446
|
|
|
389
447
|
@property
|
|
@@ -442,10 +500,12 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
442
500
|
def contents(
|
|
443
501
|
self,
|
|
444
502
|
) -> MonitoredFocusList[
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
503
|
+
tuple[
|
|
504
|
+
Widget,
|
|
505
|
+
tuple[Literal[WHSettings.PACK], None, bool]
|
|
506
|
+
| tuple[Literal[WHSettings.GIVEN], int, bool]
|
|
507
|
+
| tuple[Literal[WHSettings.WEIGHT], int | float, bool],
|
|
508
|
+
],
|
|
449
509
|
]:
|
|
450
510
|
"""
|
|
451
511
|
The contents of this Columns as a list of `(widget, options)` tuples.
|
|
@@ -886,11 +946,17 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
886
946
|
box.append(i)
|
|
887
947
|
|
|
888
948
|
elif Sizing.FLOW in w_sizing:
|
|
889
|
-
|
|
949
|
+
if width > 0:
|
|
950
|
+
heights[i] = widget.rows((width,), focus and i == self.focus_position)
|
|
951
|
+
else:
|
|
952
|
+
heights[i] = 0
|
|
890
953
|
w_h_args[i] = (width,)
|
|
891
954
|
|
|
892
955
|
elif size_kind == WHSettings.PACK:
|
|
893
|
-
|
|
956
|
+
if width > 0:
|
|
957
|
+
heights[i] = widget.pack((), focus and i == self.focus_position)[1]
|
|
958
|
+
else:
|
|
959
|
+
heights[i] = 0
|
|
894
960
|
w_h_args[i] = ()
|
|
895
961
|
|
|
896
962
|
else:
|
|
@@ -922,7 +988,11 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
922
988
|
tuple(w_h_args[idx] for idx in range(len(w_h_args))),
|
|
923
989
|
)
|
|
924
990
|
|
|
925
|
-
def pack(
|
|
991
|
+
def pack(
|
|
992
|
+
self,
|
|
993
|
+
size: tuple[()] | tuple[int] | tuple[int, int] = (),
|
|
994
|
+
focus: bool = False,
|
|
995
|
+
) -> tuple[int, int]:
|
|
926
996
|
"""Get packed sized for widget."""
|
|
927
997
|
if size:
|
|
928
998
|
return super().pack(size, focus)
|
|
@@ -1113,16 +1183,16 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
1113
1183
|
|
|
1114
1184
|
see :meth:`Widget.rows` for details
|
|
1115
1185
|
"""
|
|
1116
|
-
|
|
1186
|
+
_, heights, _ = self.get_column_sizes(size, focus)
|
|
1187
|
+
if heights:
|
|
1188
|
+
return max(1, *heights)
|
|
1189
|
+
return 1
|
|
1117
1190
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
return rows
|
|
1124
|
-
|
|
1125
|
-
def keypress(self, size: tuple[()] | tuple[int] | tuple[int, int], key: str) -> str | None:
|
|
1191
|
+
def keypress(
|
|
1192
|
+
self,
|
|
1193
|
+
size: tuple[()] | tuple[int] | tuple[int, int],
|
|
1194
|
+
key: str,
|
|
1195
|
+
) -> str | None:
|
|
1126
1196
|
"""
|
|
1127
1197
|
Pass keypress to the focus column.
|
|
1128
1198
|
|
urwid/widget/constants.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import dataclasses
|
|
3
4
|
import enum
|
|
4
5
|
import typing
|
|
5
6
|
|
|
@@ -454,91 +455,51 @@ def simplify_height(
|
|
|
454
455
|
return (WHSettings(height_type), height_amount)
|
|
455
456
|
|
|
456
457
|
|
|
457
|
-
|
|
458
|
-
|
|
458
|
+
@dataclasses.dataclass(frozen=True)
|
|
459
|
+
class _BoxSymbols:
|
|
460
|
+
"""Box symbols for drawing."""
|
|
459
461
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
462
|
+
HORIZONTAL: str
|
|
463
|
+
VERTICAL: str
|
|
464
|
+
TOP_LEFT: str
|
|
465
|
+
TOP_RIGHT: str
|
|
466
|
+
BOTTOM_LEFT: str
|
|
467
|
+
BOTTOM_RIGHT: str
|
|
468
|
+
# Joints for tables making
|
|
469
|
+
LEFT_T: str
|
|
470
|
+
RIGHT_T: str
|
|
471
|
+
TOP_T: str
|
|
472
|
+
BOTTOM_T: str
|
|
473
|
+
CROSS: str
|
|
463
474
|
|
|
464
|
-
# fmt: off
|
|
465
475
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
TOP_LEFT: str = "┌"
|
|
469
|
-
TOP_RIGHT: str = "┐"
|
|
470
|
-
BOTTOM_LEFT: str = "└"
|
|
471
|
-
BOTTOM_RIGHT: str = "┘"
|
|
472
|
-
# Joints for tables making
|
|
473
|
-
LEFT_T: str = "├"
|
|
474
|
-
RIGHT_T: str = "┤"
|
|
475
|
-
TOP_T: str = "┬"
|
|
476
|
-
BOTTOM_T: str = "┴"
|
|
477
|
-
CROSS: str = "┼"
|
|
478
|
-
# Dashes
|
|
479
|
-
HORIZONTAL_4_DASHES: str = "┈"
|
|
480
|
-
HORIZONTAL_3_DASHES: str = "┄"
|
|
481
|
-
HORIZONTAL_2_DASHES: str = "╌"
|
|
482
|
-
VERTICAL_2_DASH: str = "╎"
|
|
483
|
-
VERTICAL_3_DASH: str = "┆"
|
|
484
|
-
VERTICAL_4_DASH: str = "┊"
|
|
485
|
-
# Unique for light only
|
|
486
|
-
TOP_LEFT_ROUNDED: str = "╭"
|
|
487
|
-
TOP_RIGHT_ROUNDED: str = "╮"
|
|
488
|
-
BOTTOM_RIGHT_ROUNDED: str = "╯"
|
|
489
|
-
BOTTOM_LEFT_ROUNDED: str = "╰"
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
class _HeavyBoxSymbols(typing.NamedTuple):
|
|
476
|
+
@dataclasses.dataclass(frozen=True)
|
|
477
|
+
class _BoxSymbolsWithDashes(_BoxSymbols):
|
|
493
478
|
"""Box symbols for drawing.
|
|
494
479
|
|
|
495
|
-
|
|
496
|
-
Symbols are ordered as in Unicode except dashes.
|
|
480
|
+
Extra dashes symbols.
|
|
497
481
|
"""
|
|
498
482
|
|
|
499
|
-
|
|
483
|
+
HORIZONTAL_4_DASHES: str
|
|
484
|
+
HORIZONTAL_3_DASHES: str
|
|
485
|
+
HORIZONTAL_2_DASHES: str
|
|
486
|
+
VERTICAL_2_DASH: str
|
|
487
|
+
VERTICAL_3_DASH: str
|
|
488
|
+
VERTICAL_4_DASH: str
|
|
500
489
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
TOP_RIGHT: str = "┓"
|
|
505
|
-
BOTTOM_LEFT: str = "┗"
|
|
506
|
-
BOTTOM_RIGHT: str = "┛"
|
|
507
|
-
# Joints for tables making
|
|
508
|
-
LEFT_T: str = "┣"
|
|
509
|
-
RIGHT_T: str = "┫"
|
|
510
|
-
TOP_T: str = "┳"
|
|
511
|
-
BOTTOM_T: str = "┻"
|
|
512
|
-
CROSS: str = "╋"
|
|
513
|
-
# Dashes
|
|
514
|
-
HORIZONTAL_4_DASHES: str = "┉"
|
|
515
|
-
HORIZONTAL_3_DASHES: str = "┅"
|
|
516
|
-
HORIZONTAL_2_DASHES: str = "╍"
|
|
517
|
-
VERTICAL_2_DASH: str = "╏"
|
|
518
|
-
VERTICAL_3_DASH: str = "┇"
|
|
519
|
-
VERTICAL_4_DASH: str = "┋"
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
class _DoubleBoxSymbols(typing.NamedTuple):
|
|
490
|
+
|
|
491
|
+
@dataclasses.dataclass(frozen=True)
|
|
492
|
+
class _LightBoxSymbols(_BoxSymbolsWithDashes):
|
|
523
493
|
"""Box symbols for drawing.
|
|
524
494
|
|
|
525
|
-
|
|
495
|
+
The Thin version includes extra symbols.
|
|
496
|
+
Symbols are ordered as in Unicode except dashes.
|
|
526
497
|
"""
|
|
527
498
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
TOP_LEFT: str = "╔"
|
|
533
|
-
TOP_RIGHT: str = "╗"
|
|
534
|
-
BOTTOM_LEFT: str = "╚"
|
|
535
|
-
BOTTOM_RIGHT: str = "╝"
|
|
536
|
-
# Joints for tables making
|
|
537
|
-
LEFT_T: str = "╠"
|
|
538
|
-
RIGHT_T: str = "╣"
|
|
539
|
-
TOP_T: str = "╦"
|
|
540
|
-
BOTTOM_T: str = "╩"
|
|
541
|
-
CROSS: str = "╬"
|
|
499
|
+
TOP_LEFT_ROUNDED: str
|
|
500
|
+
TOP_RIGHT_ROUNDED: str
|
|
501
|
+
BOTTOM_LEFT_ROUNDED: str
|
|
502
|
+
BOTTOM_RIGHT_ROUNDED: str
|
|
542
503
|
|
|
543
504
|
|
|
544
505
|
class _BoxSymbolsCollection(typing.NamedTuple):
|
|
@@ -551,9 +512,15 @@ class _BoxSymbolsCollection(typing.NamedTuple):
|
|
|
551
512
|
|
|
552
513
|
# fmt: off
|
|
553
514
|
|
|
554
|
-
LIGHT: _LightBoxSymbols = _LightBoxSymbols(
|
|
555
|
-
|
|
556
|
-
|
|
515
|
+
LIGHT: _LightBoxSymbols = _LightBoxSymbols(
|
|
516
|
+
"─", "│", "┌", "┐", "└", "┘", "├", "┤", "┬", "┴", "┼", "┈", "┄", "╌", "╎", "┆", "┊", "╭", "╮", "╰", "╯"
|
|
517
|
+
)
|
|
518
|
+
HEAVY: _BoxSymbolsWithDashes = _BoxSymbolsWithDashes(
|
|
519
|
+
"━", "┃", "┏", "┓", "┗", "┛", "┣", "┫", "┳", "┻", "╋", "┉", "┅", "╍", "╏", "┇", "┋"
|
|
520
|
+
)
|
|
521
|
+
DOUBLE: _BoxSymbols = _BoxSymbols(
|
|
522
|
+
"═", "║", "╔", "╗", "╚", "╝", "╠", "╣", "╦", "╩", "╬"
|
|
523
|
+
)
|
|
557
524
|
|
|
558
525
|
|
|
559
526
|
BOX_SYMBOLS = _BoxSymbolsCollection()
|
urwid/widget/container.py
CHANGED
|
@@ -97,11 +97,11 @@ class WidgetContainerMixin:
|
|
|
97
97
|
|
|
98
98
|
positions -- sequence of positions
|
|
99
99
|
"""
|
|
100
|
-
w = self
|
|
100
|
+
w: Widget = self
|
|
101
101
|
for p in positions:
|
|
102
102
|
if p != w.focus_position:
|
|
103
103
|
w.focus_position = p # modifies w.focus
|
|
104
|
-
w = w.focus.base_widget
|
|
104
|
+
w = w.focus.base_widget # type: ignore[assignment]
|
|
105
105
|
|
|
106
106
|
def get_focus_widgets(self) -> list[Widget]:
|
|
107
107
|
"""
|
urwid/widget/divider.py
CHANGED
|
@@ -92,7 +92,11 @@ class Divider(Widget):
|
|
|
92
92
|
(_maxcol,) = size
|
|
93
93
|
return self.top + 1 + self.bottom
|
|
94
94
|
|
|
95
|
-
def render(
|
|
95
|
+
def render(
|
|
96
|
+
self,
|
|
97
|
+
size: tuple[int], # type: ignore[override]
|
|
98
|
+
focus: bool = False,
|
|
99
|
+
) -> CompositeCanvas:
|
|
96
100
|
"""
|
|
97
101
|
Render the divider as a canvas and return it.
|
|
98
102
|
|
urwid/widget/edit.py
CHANGED
|
@@ -153,7 +153,7 @@ class Edit(Text):
|
|
|
153
153
|
|
|
154
154
|
return self._caption + (self._mask * len(self._edit_text)), self._attrib
|
|
155
155
|
|
|
156
|
-
def set_text(self, markup: tuple[
|
|
156
|
+
def set_text(self, markup: str | tuple[Hashable, str] | list[str | tuple[Hashable, str]]) -> None:
|
|
157
157
|
"""
|
|
158
158
|
Not supported by Edit widget.
|
|
159
159
|
|
|
@@ -308,8 +308,8 @@ class Edit(Text):
|
|
|
308
308
|
self._emit("change", text)
|
|
309
309
|
old_text = self._edit_text
|
|
310
310
|
self._edit_text = text
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
self.edit_pos = min(self.edit_pos, len(text))
|
|
312
|
+
|
|
313
313
|
self._emit("postchange", old_text)
|
|
314
314
|
self._invalidate()
|
|
315
315
|
|
|
@@ -359,10 +359,7 @@ class Edit(Text):
|
|
|
359
359
|
self.highlight = None
|
|
360
360
|
|
|
361
361
|
def _normalize_to_caption(self, text: str | bytes) -> str | bytes:
|
|
362
|
-
"""
|
|
363
|
-
Return text converted to the same type as self.caption
|
|
364
|
-
(bytes or unicode)
|
|
365
|
-
"""
|
|
362
|
+
"""Return text converted to the same type as self.caption (bytes or unicode)"""
|
|
366
363
|
tu = isinstance(text, str)
|
|
367
364
|
cu = isinstance(self._caption, str)
|
|
368
365
|
if tu == cu:
|
|
@@ -400,7 +397,11 @@ class Edit(Text):
|
|
|
400
397
|
result_pos += len(text)
|
|
401
398
|
return (result_text, result_pos)
|
|
402
399
|
|
|
403
|
-
def keypress(
|
|
400
|
+
def keypress(
|
|
401
|
+
self,
|
|
402
|
+
size: tuple[int], # type: ignore[override]
|
|
403
|
+
key: str,
|
|
404
|
+
) -> str | None:
|
|
404
405
|
"""
|
|
405
406
|
Handle editing keystrokes, return others.
|
|
406
407
|
|
|
@@ -421,9 +422,6 @@ class Edit(Text):
|
|
|
421
422
|
pos = self.edit_pos
|
|
422
423
|
if self.valid_char(key):
|
|
423
424
|
if isinstance(key, str) and not isinstance(self._caption, str):
|
|
424
|
-
# screen is sending us unicode input, must be using utf-8
|
|
425
|
-
# encoding because that's all we support, so convert it
|
|
426
|
-
# to bytes to match our caption's type
|
|
427
425
|
key = key.encode("utf-8")
|
|
428
426
|
self.insert_text(key)
|
|
429
427
|
return None
|
|
@@ -546,7 +544,7 @@ class Edit(Text):
|
|
|
546
544
|
|
|
547
545
|
def mouse_event(
|
|
548
546
|
self,
|
|
549
|
-
size: tuple[int],
|
|
547
|
+
size: tuple[int], # type: ignore[override]
|
|
550
548
|
event: str,
|
|
551
549
|
button: int,
|
|
552
550
|
col: int,
|
|
@@ -581,7 +579,11 @@ class Edit(Text):
|
|
|
581
579
|
self.highlight = None
|
|
582
580
|
return True
|
|
583
581
|
|
|
584
|
-
def render(
|
|
582
|
+
def render(
|
|
583
|
+
self,
|
|
584
|
+
size: tuple[int], # type: ignore[override]
|
|
585
|
+
focus: bool = False,
|
|
586
|
+
) -> TextCanvas | CompositeCanvas:
|
|
585
587
|
"""
|
|
586
588
|
Render edit widget and return canvas. Include cursor when in
|
|
587
589
|
focus.
|
|
@@ -679,7 +681,11 @@ class IntEdit(Edit):
|
|
|
679
681
|
val = ""
|
|
680
682
|
super().__init__(caption, val)
|
|
681
683
|
|
|
682
|
-
def keypress(
|
|
684
|
+
def keypress(
|
|
685
|
+
self,
|
|
686
|
+
size: tuple[int], # type: ignore[override]
|
|
687
|
+
key: str,
|
|
688
|
+
) -> str | None:
|
|
683
689
|
"""
|
|
684
690
|
Handle editing keystrokes. Remove leading zeros.
|
|
685
691
|
|
urwid/widget/filler.py
CHANGED
|
@@ -22,7 +22,6 @@ from .widget_decoration import WidgetDecoration, WidgetError
|
|
|
22
22
|
if typing.TYPE_CHECKING:
|
|
23
23
|
from typing_extensions import Literal
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
27
26
|
|
|
28
27
|
|
|
@@ -231,7 +230,11 @@ class Filler(WidgetDecoration[WrappedWidget]):
|
|
|
231
230
|
self.bottom,
|
|
232
231
|
)
|
|
233
232
|
|
|
234
|
-
def render(
|
|
233
|
+
def render(
|
|
234
|
+
self,
|
|
235
|
+
size: tuple[int, int] | tuple[int], # type: ignore[override]
|
|
236
|
+
focus: bool = False,
|
|
237
|
+
) -> CompositeCanvas:
|
|
235
238
|
"""Render self.original_widget with space above and/or below."""
|
|
236
239
|
maxcol, maxrow = self.pack(size, focus)
|
|
237
240
|
top, bottom = self.filler_values(size, focus)
|
|
@@ -252,7 +255,11 @@ class Filler(WidgetDecoration[WrappedWidget]):
|
|
|
252
255
|
canv.pad_trim_top_bottom(top, bottom)
|
|
253
256
|
return canv
|
|
254
257
|
|
|
255
|
-
def keypress(
|
|
258
|
+
def keypress(
|
|
259
|
+
self,
|
|
260
|
+
size: tuple[int, int] | tuple[()], # type: ignore[override]
|
|
261
|
+
key: str,
|
|
262
|
+
) -> str | None:
|
|
256
263
|
"""Pass keypress to self.original_widget."""
|
|
257
264
|
maxcol, maxrow = self.pack(size, True)
|
|
258
265
|
if self.height_type == WHSettings.PACK:
|
|
@@ -309,7 +316,7 @@ class Filler(WidgetDecoration[WrappedWidget]):
|
|
|
309
316
|
|
|
310
317
|
def mouse_event(
|
|
311
318
|
self,
|
|
312
|
-
size: tuple[int, int] | tuple[int],
|
|
319
|
+
size: tuple[int, int] | tuple[int], # type: ignore[override]
|
|
313
320
|
event,
|
|
314
321
|
button: int,
|
|
315
322
|
col: int,
|