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/__init__.py
CHANGED
|
@@ -53,32 +53,6 @@ from urwid.command_map import (
|
|
|
53
53
|
CommandMap,
|
|
54
54
|
command_map,
|
|
55
55
|
)
|
|
56
|
-
from urwid.display import (
|
|
57
|
-
BLACK,
|
|
58
|
-
BROWN,
|
|
59
|
-
DARK_BLUE,
|
|
60
|
-
DARK_CYAN,
|
|
61
|
-
DARK_GRAY,
|
|
62
|
-
DARK_GREEN,
|
|
63
|
-
DARK_MAGENTA,
|
|
64
|
-
DARK_RED,
|
|
65
|
-
DEFAULT,
|
|
66
|
-
LIGHT_BLUE,
|
|
67
|
-
LIGHT_CYAN,
|
|
68
|
-
LIGHT_GRAY,
|
|
69
|
-
LIGHT_GREEN,
|
|
70
|
-
LIGHT_MAGENTA,
|
|
71
|
-
LIGHT_RED,
|
|
72
|
-
UPDATE_PALETTE_ENTRY,
|
|
73
|
-
WHITE,
|
|
74
|
-
YELLOW,
|
|
75
|
-
AttrSpec,
|
|
76
|
-
AttrSpecError,
|
|
77
|
-
BaseScreen,
|
|
78
|
-
RealTerminal,
|
|
79
|
-
ScreenError,
|
|
80
|
-
)
|
|
81
|
-
from urwid.event_loop import AsyncioEventLoop, EventLoop, ExitMainLoop, MainLoop, SelectEventLoop
|
|
82
56
|
from urwid.font import (
|
|
83
57
|
Font,
|
|
84
58
|
FontRegistry,
|
|
@@ -93,8 +67,6 @@ from urwid.font import (
|
|
|
93
67
|
Thin6x6Font,
|
|
94
68
|
get_all_fonts,
|
|
95
69
|
)
|
|
96
|
-
from urwid.listbox import ListBox, ListBoxError, ListWalker, ListWalkerError, SimpleFocusListWalker, SimpleListWalker
|
|
97
|
-
from urwid.monitored_list import MonitoredFocusList, MonitoredList
|
|
98
70
|
from urwid.signals import (
|
|
99
71
|
MetaSignals,
|
|
100
72
|
Signals,
|
|
@@ -121,7 +93,35 @@ from urwid.util import (
|
|
|
121
93
|
)
|
|
122
94
|
from urwid.version import version as __version__
|
|
123
95
|
from urwid.version import version_tuple as __version_tuple__
|
|
124
|
-
|
|
96
|
+
|
|
97
|
+
from . import display, event_loop, widget
|
|
98
|
+
from .display import (
|
|
99
|
+
BLACK,
|
|
100
|
+
BROWN,
|
|
101
|
+
DARK_BLUE,
|
|
102
|
+
DARK_CYAN,
|
|
103
|
+
DARK_GRAY,
|
|
104
|
+
DARK_GREEN,
|
|
105
|
+
DARK_MAGENTA,
|
|
106
|
+
DARK_RED,
|
|
107
|
+
DEFAULT,
|
|
108
|
+
LIGHT_BLUE,
|
|
109
|
+
LIGHT_CYAN,
|
|
110
|
+
LIGHT_GRAY,
|
|
111
|
+
LIGHT_GREEN,
|
|
112
|
+
LIGHT_MAGENTA,
|
|
113
|
+
LIGHT_RED,
|
|
114
|
+
UPDATE_PALETTE_ENTRY,
|
|
115
|
+
WHITE,
|
|
116
|
+
YELLOW,
|
|
117
|
+
AttrSpec,
|
|
118
|
+
AttrSpecError,
|
|
119
|
+
BaseScreen,
|
|
120
|
+
RealTerminal,
|
|
121
|
+
ScreenError,
|
|
122
|
+
)
|
|
123
|
+
from .event_loop import AsyncioEventLoop, EventLoop, ExitMainLoop, MainLoop, SelectEventLoop
|
|
124
|
+
from .widget import (
|
|
125
125
|
ANY,
|
|
126
126
|
BOTTOM,
|
|
127
127
|
BOX,
|
|
@@ -170,10 +170,17 @@ from urwid.widget import (
|
|
|
170
170
|
GridFlowError,
|
|
171
171
|
IntEdit,
|
|
172
172
|
LineBox,
|
|
173
|
+
ListBox,
|
|
174
|
+
ListBoxError,
|
|
175
|
+
ListWalker,
|
|
176
|
+
ListWalkerError,
|
|
177
|
+
MonitoredFocusList,
|
|
178
|
+
MonitoredList,
|
|
173
179
|
Overlay,
|
|
174
180
|
OverlayError,
|
|
175
181
|
Padding,
|
|
176
182
|
PaddingError,
|
|
183
|
+
ParentNode,
|
|
177
184
|
Pile,
|
|
178
185
|
PileError,
|
|
179
186
|
PopUpLauncher,
|
|
@@ -183,10 +190,17 @@ from urwid.widget import (
|
|
|
183
190
|
Scrollable,
|
|
184
191
|
ScrollBar,
|
|
185
192
|
SelectableIcon,
|
|
193
|
+
SimpleFocusListWalker,
|
|
194
|
+
SimpleListWalker,
|
|
186
195
|
Sizing,
|
|
187
196
|
SolidFill,
|
|
188
197
|
Text,
|
|
189
198
|
TextError,
|
|
199
|
+
TreeListBox,
|
|
200
|
+
TreeNode,
|
|
201
|
+
TreeWalker,
|
|
202
|
+
TreeWidget,
|
|
203
|
+
TreeWidgetError,
|
|
190
204
|
VAlign,
|
|
191
205
|
WHSettings,
|
|
192
206
|
Widget,
|
|
@@ -204,10 +218,6 @@ from urwid.widget import (
|
|
|
204
218
|
scale_bar_values,
|
|
205
219
|
)
|
|
206
220
|
|
|
207
|
-
from . import display, event_loop, widget
|
|
208
|
-
|
|
209
|
-
from .treetools import ParentNode, TreeListBox, TreeNode, TreeWalker, TreeWidget, TreeWidgetError # isort: skip
|
|
210
|
-
|
|
211
221
|
# Optional event loops with external dependencies
|
|
212
222
|
|
|
213
223
|
try:
|
|
@@ -252,6 +262,9 @@ _moved_warn: dict[str, str] = {
|
|
|
252
262
|
"lcd_display": "urwid.display.lcd",
|
|
253
263
|
"html_fragment": "urwid.display.html_fragment",
|
|
254
264
|
"web_display": "urwid.display.web",
|
|
265
|
+
"monitored_list": "urwid.widget.monitored_list",
|
|
266
|
+
"listbox": "urwid.widget.listbox",
|
|
267
|
+
"treetools": "urwid.widget.treetools",
|
|
255
268
|
}
|
|
256
269
|
# Backward compatible lazy load without any warnings
|
|
257
270
|
# Before DeprecationWarning need to start PendingDeprecationWarning process.
|
urwid/canvas.py
CHANGED
|
@@ -216,7 +216,7 @@ class Canvas:
|
|
|
216
216
|
def __init__(self) -> None:
|
|
217
217
|
"""Base Canvas class"""
|
|
218
218
|
self._widget_info = None
|
|
219
|
-
self.coords: dict[str, tuple[int, int, tuple[Widget, int, int]]] = {}
|
|
219
|
+
self.coords: dict[str, tuple[int, int, tuple[Widget, int, int]] | tuple[int, int, None]] = {}
|
|
220
220
|
self.shortcuts: dict[str, str] = {}
|
|
221
221
|
|
|
222
222
|
def finalize(
|
|
@@ -580,7 +580,7 @@ class SolidCanvas(Canvas):
|
|
|
580
580
|
A canvas filled completely with a single character.
|
|
581
581
|
"""
|
|
582
582
|
|
|
583
|
-
def __init__(self, fill_char: str, cols: int, rows: int) -> None:
|
|
583
|
+
def __init__(self, fill_char: str | bytes, cols: int, rows: int) -> None:
|
|
584
584
|
super().__init__()
|
|
585
585
|
end, col = calc_text_pos(fill_char, 0, len(fill_char), 1)
|
|
586
586
|
if col != 1:
|
|
@@ -726,8 +726,7 @@ class CompositeCanvas(Canvas):
|
|
|
726
726
|
Return the differences between other and this canvas.
|
|
727
727
|
"""
|
|
728
728
|
if not hasattr(other, "shards"):
|
|
729
|
-
|
|
730
|
-
yield row
|
|
729
|
+
yield from self.content()
|
|
731
730
|
return
|
|
732
731
|
|
|
733
732
|
shard_tail = []
|
|
@@ -1275,8 +1274,7 @@ def CanvasJoin(canvas_info: Iterable[tuple[Canvas, typing.Any, bool, int]]) -> C
|
|
|
1275
1274
|
pad_right = cols - canv.cols()
|
|
1276
1275
|
if focus:
|
|
1277
1276
|
focus_item = n
|
|
1278
|
-
|
|
1279
|
-
maxrow = rows
|
|
1277
|
+
maxrow = max(maxrow, rows)
|
|
1280
1278
|
l2.append((canv, pos, pad_right, rows))
|
|
1281
1279
|
|
|
1282
1280
|
shard_lists = []
|
|
@@ -43,7 +43,6 @@ from . import _raw_display_base, escape
|
|
|
43
43
|
from .common import INPUT_DESCRIPTORS_CHANGED
|
|
44
44
|
|
|
45
45
|
if typing.TYPE_CHECKING:
|
|
46
|
-
import io
|
|
47
46
|
import socket
|
|
48
47
|
from collections.abc import Callable
|
|
49
48
|
from types import FrameType
|
|
@@ -54,8 +53,8 @@ if typing.TYPE_CHECKING:
|
|
|
54
53
|
class Screen(_raw_display_base.Screen):
|
|
55
54
|
def __init__(
|
|
56
55
|
self,
|
|
57
|
-
input:
|
|
58
|
-
output:
|
|
56
|
+
input: typing.TextIO = sys.stdin, # noqa: A002 # pylint: disable=redefined-builtin
|
|
57
|
+
output: typing.TextIO = sys.stdout,
|
|
59
58
|
bracketed_paste_mode=False,
|
|
60
59
|
) -> None:
|
|
61
60
|
"""Initialize a screen that directly prints escape codes to an output
|
|
@@ -223,7 +222,7 @@ class Screen(_raw_display_base.Screen):
|
|
|
223
222
|
|
|
224
223
|
super()._stop()
|
|
225
224
|
|
|
226
|
-
def get_input_descriptors(self) -> list[socket.socket |
|
|
225
|
+
def get_input_descriptors(self) -> list[socket.socket | typing.IO | int]:
|
|
227
226
|
"""
|
|
228
227
|
Return a list of integer file descriptors that should be
|
|
229
228
|
polled in external event loops to check for user input.
|
|
@@ -41,7 +41,6 @@ from . import escape
|
|
|
41
41
|
from .common import UNPRINTABLE_TRANS_TABLE, UPDATE_PALETTE_ENTRY, AttrSpec, BaseScreen, RealTerminal
|
|
42
42
|
|
|
43
43
|
if typing.TYPE_CHECKING:
|
|
44
|
-
import io
|
|
45
44
|
from collections.abc import Callable, Iterable
|
|
46
45
|
from types import FrameType
|
|
47
46
|
|
|
@@ -54,7 +53,7 @@ IS_WSL = (sys.platform == "linux") and ("wsl" in platform.platform().lower())
|
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
class Screen(BaseScreen, RealTerminal):
|
|
57
|
-
def __init__(self, input:
|
|
56
|
+
def __init__(self, input: typing.IO, output: typing.IO) -> None: # noqa: A002 # pylint: disable=redefined-builtin
|
|
58
57
|
"""Initialize a screen that directly prints escape codes to an output
|
|
59
58
|
terminal.
|
|
60
59
|
"""
|
|
@@ -116,7 +115,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
116
115
|
self.screen_buf = None
|
|
117
116
|
|
|
118
117
|
@property
|
|
119
|
-
def _term_input_io(self) ->
|
|
118
|
+
def _term_input_io(self) -> typing.IO | None:
|
|
120
119
|
if hasattr(self._term_input_file, "fileno"):
|
|
121
120
|
return self._term_input_file
|
|
122
121
|
return None
|
|
@@ -310,7 +309,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
310
309
|
return keys, raw
|
|
311
310
|
return keys
|
|
312
311
|
|
|
313
|
-
def get_input_descriptors(self) -> list[socket.socket |
|
|
312
|
+
def get_input_descriptors(self) -> list[socket.socket | typing.IO | int]:
|
|
314
313
|
"""
|
|
315
314
|
Return a list of integer file descriptors that should be
|
|
316
315
|
polled in external event loops to check for user input.
|
|
@@ -323,7 +322,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
323
322
|
if not self._started:
|
|
324
323
|
return []
|
|
325
324
|
|
|
326
|
-
fd_list = [self._resize_pipe_rd]
|
|
325
|
+
fd_list: list[socket.socket | typing.IO | int] = [self._resize_pipe_rd]
|
|
327
326
|
input_io = self._term_input_io
|
|
328
327
|
if input_io is not None:
|
|
329
328
|
fd_list.append(input_io)
|
|
@@ -41,7 +41,6 @@ from . import _raw_display_base, _win32, escape
|
|
|
41
41
|
from .common import INPUT_DESCRIPTORS_CHANGED
|
|
42
42
|
|
|
43
43
|
if typing.TYPE_CHECKING:
|
|
44
|
-
import io
|
|
45
44
|
from collections.abc import Callable
|
|
46
45
|
|
|
47
46
|
from urwid.event_loop import EventLoop
|
|
@@ -53,7 +52,7 @@ class Screen(_raw_display_base.Screen):
|
|
|
53
52
|
def __init__(
|
|
54
53
|
self,
|
|
55
54
|
input: socket.socket | None = None, # noqa: A002 # pylint: disable=redefined-builtin
|
|
56
|
-
output:
|
|
55
|
+
output: typing.TextIO = sys.stdout,
|
|
57
56
|
) -> None:
|
|
58
57
|
"""Initialize a screen that directly prints escape codes to an output
|
|
59
58
|
terminal.
|
urwid/display/curses.py
CHANGED
|
@@ -103,7 +103,7 @@ _curses_colours = { # pylint: disable=consider-using-namedtuple-or-dataclass #
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
class Screen(BaseScreen, RealTerminal):
|
|
106
|
-
def __init__(self):
|
|
106
|
+
def __init__(self) -> None:
|
|
107
107
|
super().__init__()
|
|
108
108
|
self.curses_pairs = [(None, None)] # Can't be sure what pair 0 will default to
|
|
109
109
|
self.palette = {}
|
urwid/display/html_fragment.py
CHANGED
|
@@ -53,7 +53,7 @@ class HtmlGenerator(BaseScreen):
|
|
|
53
53
|
# class variables
|
|
54
54
|
fragments: typing.ClassVar[list[str]] = []
|
|
55
55
|
sizes: typing.ClassVar[list[tuple[int, int]]] = []
|
|
56
|
-
keys: typing.ClassVar[list[list[str]
|
|
56
|
+
keys: typing.ClassVar[list[list[str]]] = []
|
|
57
57
|
started = True
|
|
58
58
|
|
|
59
59
|
def __init__(self) -> None:
|
urwid/event_loop/__init__.py
CHANGED
|
@@ -20,28 +20,28 @@ __all__ = (
|
|
|
20
20
|
try:
|
|
21
21
|
from .twisted_loop import TwistedEventLoop
|
|
22
22
|
|
|
23
|
-
__all__ += ("TwistedEventLoop",)
|
|
23
|
+
__all__ += ("TwistedEventLoop",) # type: ignore[assignment]
|
|
24
24
|
except ImportError:
|
|
25
25
|
pass
|
|
26
26
|
|
|
27
27
|
try:
|
|
28
28
|
from .tornado_loop import TornadoEventLoop
|
|
29
29
|
|
|
30
|
-
__all__ += ("TornadoEventLoop",)
|
|
30
|
+
__all__ += ("TornadoEventLoop",) # type: ignore[assignment]
|
|
31
31
|
except ImportError:
|
|
32
32
|
pass
|
|
33
33
|
|
|
34
34
|
try:
|
|
35
35
|
from .glib_loop import GLibEventLoop
|
|
36
36
|
|
|
37
|
-
__all__ += ("GLibEventLoop",)
|
|
37
|
+
__all__ += ("GLibEventLoop",) # type: ignore[assignment]
|
|
38
38
|
except ImportError:
|
|
39
39
|
pass
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
42
|
from .trio_loop import TrioEventLoop
|
|
43
43
|
|
|
44
|
-
__all__ += ("TrioEventLoop",)
|
|
44
|
+
__all__ += ("TrioEventLoop",) # type: ignore[assignment]
|
|
45
45
|
except ImportError:
|
|
46
46
|
pass
|
|
47
47
|
|
|
@@ -50,6 +50,6 @@ if sys.platform != "win32":
|
|
|
50
50
|
try:
|
|
51
51
|
from .zmq_loop import ZMQEventLoop
|
|
52
52
|
|
|
53
|
-
__all__ += ("ZMQEventLoop",)
|
|
53
|
+
__all__ += ("ZMQEventLoop",) # type: ignore[assignment]
|
|
54
54
|
except ImportError:
|
|
55
55
|
pass
|
urwid/event_loop/main_loop.py
CHANGED
|
@@ -562,36 +562,41 @@ class MainLoop:
|
|
|
562
562
|
|
|
563
563
|
something_handled = False
|
|
564
564
|
|
|
565
|
-
for
|
|
566
|
-
if
|
|
565
|
+
for key in keys:
|
|
566
|
+
if key == "window resize":
|
|
567
567
|
continue
|
|
568
568
|
|
|
569
|
-
if isinstance(
|
|
569
|
+
if isinstance(key, str):
|
|
570
570
|
if self._topmost_widget.selectable():
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
571
|
+
handled_key = self._topmost_widget.keypress(self.screen_size, key)
|
|
572
|
+
if not handled_key:
|
|
573
|
+
something_handled = True
|
|
574
|
+
continue
|
|
575
|
+
|
|
576
|
+
key = handled_key # noqa: PLW2901
|
|
577
|
+
|
|
578
|
+
elif is_mouse_event(key):
|
|
579
|
+
event, button, col, row = key
|
|
580
|
+
if hasattr(self._topmost_widget, "mouse_event") and self._topmost_widget.mouse_event(
|
|
581
|
+
self.screen_size,
|
|
582
|
+
event,
|
|
583
|
+
button,
|
|
584
|
+
col,
|
|
585
|
+
row,
|
|
586
|
+
focus=True,
|
|
587
|
+
):
|
|
588
|
+
something_handled = True
|
|
589
|
+
continue
|
|
585
590
|
|
|
586
591
|
else:
|
|
587
|
-
raise TypeError(f"{
|
|
592
|
+
raise TypeError(f"{key!r} is not str | tuple[str, int, int, int]")
|
|
588
593
|
|
|
589
|
-
if
|
|
590
|
-
if command_map[
|
|
594
|
+
if key:
|
|
595
|
+
if command_map[key] == Command.REDRAW_SCREEN:
|
|
591
596
|
self.screen.clear()
|
|
592
597
|
something_handled = True
|
|
593
598
|
else:
|
|
594
|
-
something_handled |= bool(self.unhandled_input(
|
|
599
|
+
something_handled |= bool(self.unhandled_input(key))
|
|
595
600
|
else:
|
|
596
601
|
something_handled = True
|
|
597
602
|
|
urwid/event_loop/zmq_loop.py
CHANGED
|
@@ -62,11 +62,11 @@ class ZMQEventLoop(EventLoop):
|
|
|
62
62
|
|
|
63
63
|
_alarm_break = count()
|
|
64
64
|
|
|
65
|
-
def __init__(self):
|
|
65
|
+
def __init__(self) -> None:
|
|
66
66
|
super().__init__()
|
|
67
67
|
self.logger = logging.getLogger(__name__).getChild(self.__class__.__name__)
|
|
68
68
|
self._did_something = True
|
|
69
|
-
self._alarms = []
|
|
69
|
+
self._alarms: list[tuple[float, int, Callable[[], typing.Any]]] = []
|
|
70
70
|
self._poller = zmq.Poller()
|
|
71
71
|
self._queue_callbacks: dict[int, Callable[[], typing.Any]] = {}
|
|
72
72
|
self._idle_handle = 0
|
urwid/numedit.py
CHANGED
|
@@ -79,7 +79,11 @@ class NumEdit(Edit):
|
|
|
79
79
|
return self._allow_negative and ch == "-" and self.edit_pos == 0 and "-" not in self.edit_text
|
|
80
80
|
return False
|
|
81
81
|
|
|
82
|
-
def keypress(
|
|
82
|
+
def keypress(
|
|
83
|
+
self,
|
|
84
|
+
size: tuple[int], # type: ignore[override]
|
|
85
|
+
key: str,
|
|
86
|
+
) -> str | None:
|
|
83
87
|
"""
|
|
84
88
|
Handle editing keystrokes. Remove leading zeros.
|
|
85
89
|
|
urwid/signals.py
CHANGED
urwid/str_util.py
CHANGED
|
@@ -29,7 +29,6 @@ import wcwidth
|
|
|
29
29
|
if typing.TYPE_CHECKING:
|
|
30
30
|
from typing_extensions import Literal
|
|
31
31
|
|
|
32
|
-
UNICODE_VERSION = "15.1.0" # Use explicit version
|
|
33
32
|
SAFE_ASCII_RE = re.compile("^[ -~]*$")
|
|
34
33
|
SAFE_ASCII_BYTES_RE = re.compile(b"^[ -~]*$")
|
|
35
34
|
|
|
@@ -37,7 +36,7 @@ _byte_encoding: Literal["utf8", "narrow", "wide"] = "narrow"
|
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
def get_char_width(char: str) -> Literal[0, 1, 2]:
|
|
40
|
-
width = wcwidth.wcwidth(char
|
|
39
|
+
width = wcwidth.wcwidth(char)
|
|
41
40
|
if width < 0:
|
|
42
41
|
return 0
|
|
43
42
|
return width
|
urwid/text_layout.py
CHANGED
|
@@ -94,7 +94,7 @@ class CanNotDisplayText(Exception):
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
class StandardTextLayout(TextLayout):
|
|
97
|
-
def __init__(self): # , tab_stops=(), tab_stop_every=8):
|
|
97
|
+
def __init__(self) -> None: # , tab_stops=(), tab_stop_every=8):
|
|
98
98
|
pass
|
|
99
99
|
# """
|
|
100
100
|
# tab_stops -- list of screen column indexes for tab stops
|
|
@@ -181,7 +181,7 @@ class StandardTextLayout(TextLayout):
|
|
|
181
181
|
"""Calculate text segments for cases of a text trimmed (wrap is clip or ellipsis)."""
|
|
182
182
|
segments = []
|
|
183
183
|
|
|
184
|
-
nl = "\n" if isinstance(text, str) else b"\n"
|
|
184
|
+
nl: str | bytes = "\n" if isinstance(text, str) else b"\n"
|
|
185
185
|
encoding = get_encoding()
|
|
186
186
|
ellipsis_string = get_ellipsis_string(encoding)
|
|
187
187
|
ellipsis_width = _get_width(ellipsis_string)
|
|
@@ -508,7 +508,11 @@ def trim_line(
|
|
|
508
508
|
return result
|
|
509
509
|
|
|
510
510
|
|
|
511
|
-
def calc_line_pos(
|
|
511
|
+
def calc_line_pos(
|
|
512
|
+
text: str | bytes,
|
|
513
|
+
line_layout,
|
|
514
|
+
pref_col: Literal["left", "right", Align.LEFT, Align.RIGHT] | int,
|
|
515
|
+
):
|
|
512
516
|
"""
|
|
513
517
|
Calculate the closest linear position to pref_col given a
|
|
514
518
|
line layout structure. Returns None if no position found.
|
|
@@ -566,7 +570,7 @@ def calc_line_pos(text: str | bytes, line_layout, pref_col: Literal["left", "rig
|
|
|
566
570
|
def calc_pos(
|
|
567
571
|
text: str | bytes,
|
|
568
572
|
layout: list[list[tuple[int, int, int | bytes] | tuple[int, int | None]]],
|
|
569
|
-
pref_col: Literal["left", "right"] | int,
|
|
573
|
+
pref_col: Literal["left", "right", Align.LEFT, Align.RIGHT] | int,
|
|
570
574
|
row: int,
|
|
571
575
|
) -> int:
|
|
572
576
|
"""
|
urwid/version.py
CHANGED
urwid/vterm.py
CHANGED
|
@@ -721,7 +721,7 @@ class TermCanvas(Canvas):
|
|
|
721
721
|
x, y = self.term_cursor
|
|
722
722
|
|
|
723
723
|
if isinstance(char, int):
|
|
724
|
-
char =
|
|
724
|
+
char = char.to_bytes(1, "little")
|
|
725
725
|
|
|
726
726
|
dc = self.modes.display_ctrl
|
|
727
727
|
|
|
@@ -986,14 +986,14 @@ class TermCanvas(Canvas):
|
|
|
986
986
|
chars = 1
|
|
987
987
|
|
|
988
988
|
if char is None:
|
|
989
|
-
|
|
989
|
+
char_spec = self.empty_char()
|
|
990
990
|
else:
|
|
991
|
-
|
|
991
|
+
char_spec = (self.attrspec, self.charset.current, char)
|
|
992
992
|
|
|
993
993
|
x, y = position
|
|
994
994
|
|
|
995
995
|
while chars > 0:
|
|
996
|
-
self.term[y].insert(x,
|
|
996
|
+
self.term[y].insert(x, char_spec)
|
|
997
997
|
self.term[y].pop()
|
|
998
998
|
chars -= 1
|
|
999
999
|
|
|
@@ -1187,19 +1187,19 @@ class TermCanvas(Canvas):
|
|
|
1187
1187
|
return _color_desc_256(color)
|
|
1188
1188
|
return _BASIC_COLORS[color]
|
|
1189
1189
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1190
|
+
decoded_fg = _defaulter(fg, colors)
|
|
1191
|
+
decoded_bg = _defaulter(bg, colors)
|
|
1192
1192
|
|
|
1193
1193
|
if attributes:
|
|
1194
|
-
|
|
1194
|
+
decoded_fg = ",".join((decoded_fg, *list(attributes)))
|
|
1195
1195
|
|
|
1196
|
-
if
|
|
1196
|
+
if decoded_fg == decoded_bg == "default":
|
|
1197
1197
|
return None
|
|
1198
1198
|
|
|
1199
1199
|
if colors:
|
|
1200
|
-
return AttrSpec(
|
|
1200
|
+
return AttrSpec(decoded_fg, decoded_bg, colors=colors)
|
|
1201
1201
|
|
|
1202
|
-
return AttrSpec(
|
|
1202
|
+
return AttrSpec(decoded_fg, decoded_bg)
|
|
1203
1203
|
|
|
1204
1204
|
def csi_set_attr(self, attrs: Sequence[int]) -> None:
|
|
1205
1205
|
"""
|
urwid/widget/__init__.py
CHANGED
|
@@ -27,8 +27,10 @@ from .divider import Divider
|
|
|
27
27
|
from .edit import Edit, EditError, IntEdit
|
|
28
28
|
from .filler import Filler, FillerError, calculate_top_bottom_filler
|
|
29
29
|
from .frame import Frame, FrameError
|
|
30
|
-
from .grid_flow import GridFlow, GridFlowError
|
|
30
|
+
from .grid_flow import GridFlow, GridFlowError, GridFlowWarning
|
|
31
31
|
from .line_box import LineBox
|
|
32
|
+
from .listbox import ListBox, ListBoxError, ListWalker, ListWalkerError, SimpleFocusListWalker, SimpleListWalker
|
|
33
|
+
from .monitored_list import MonitoredFocusList, MonitoredList
|
|
32
34
|
from .overlay import Overlay, OverlayError, OverlayWarning
|
|
33
35
|
from .padding import Padding, PaddingError, PaddingWarning, calculate_left_right_padding
|
|
34
36
|
from .pile import Pile, PileError, PileWarning
|
|
@@ -37,6 +39,7 @@ from .progress_bar import ProgressBar
|
|
|
37
39
|
from .scrollable import Scrollable, ScrollableError, ScrollBar
|
|
38
40
|
from .solid_fill import SolidFill
|
|
39
41
|
from .text import Text, TextError
|
|
42
|
+
from .treetools import ParentNode, TreeListBox, TreeNode, TreeWalker, TreeWidget, TreeWidgetError
|
|
40
43
|
from .widget import (
|
|
41
44
|
BoxWidget,
|
|
42
45
|
FixedWidget,
|
|
@@ -58,6 +61,8 @@ from .wimp import Button, CheckBox, CheckBoxError, RadioButton, SelectableIcon
|
|
|
58
61
|
__all__ = (
|
|
59
62
|
"ANY",
|
|
60
63
|
"BOTTOM",
|
|
64
|
+
"MonitoredList",
|
|
65
|
+
"MonitoredFocusList",
|
|
61
66
|
"BOX",
|
|
62
67
|
"CENTER",
|
|
63
68
|
"CLIP",
|
|
@@ -67,6 +72,7 @@ __all__ = (
|
|
|
67
72
|
"GIVEN",
|
|
68
73
|
"LEFT",
|
|
69
74
|
"MIDDLE",
|
|
75
|
+
"GridFlowWarning",
|
|
70
76
|
"PACK",
|
|
71
77
|
"RELATIVE",
|
|
72
78
|
"RELATIVE_100",
|
|
@@ -85,8 +91,20 @@ __all__ = (
|
|
|
85
91
|
"BoxAdapter",
|
|
86
92
|
"BoxAdapterError",
|
|
87
93
|
"BoxWidget",
|
|
94
|
+
"ListWalkerError",
|
|
95
|
+
"ListWalker",
|
|
96
|
+
"SimpleListWalker",
|
|
97
|
+
"SimpleFocusListWalker",
|
|
98
|
+
"ListBoxError",
|
|
99
|
+
"ListBox",
|
|
88
100
|
"Button",
|
|
89
101
|
"CheckBox",
|
|
102
|
+
"TreeWidgetError",
|
|
103
|
+
"TreeWidget",
|
|
104
|
+
"TreeNode",
|
|
105
|
+
"ParentNode",
|
|
106
|
+
"TreeWalker",
|
|
107
|
+
"TreeListBox",
|
|
90
108
|
"CheckBoxError",
|
|
91
109
|
"Columns",
|
|
92
110
|
"ColumnsError",
|
urwid/widget/bar_graph.py
CHANGED
|
@@ -611,7 +611,11 @@ class GraphVScale(Widget):
|
|
|
611
611
|
"""
|
|
612
612
|
return False
|
|
613
613
|
|
|
614
|
-
def render(
|
|
614
|
+
def render(
|
|
615
|
+
self,
|
|
616
|
+
size: tuple[int, int],
|
|
617
|
+
focus: bool = False,
|
|
618
|
+
) -> SolidCanvas | CompositeCanvas:
|
|
615
619
|
"""
|
|
616
620
|
Render GraphVScale.
|
|
617
621
|
"""
|
|
@@ -636,10 +640,10 @@ class GraphVScale(Widget):
|
|
|
636
640
|
if not combinelist:
|
|
637
641
|
return SolidCanvas(" ", size[0], size[1])
|
|
638
642
|
|
|
639
|
-
|
|
643
|
+
canvas = CanvasCombine(combinelist)
|
|
640
644
|
if maxrow - rows:
|
|
641
|
-
|
|
642
|
-
return
|
|
645
|
+
canvas.pad_trim_top_bottom(0, maxrow - rows)
|
|
646
|
+
return canvas
|
|
643
647
|
|
|
644
648
|
|
|
645
649
|
def scale_bar_values(bar, top: float, maxrow: int) -> list[int]:
|
urwid/widget/big_text.py
CHANGED
|
@@ -9,6 +9,8 @@ from .constants import Sizing
|
|
|
9
9
|
from .widget import Widget, fixed_size
|
|
10
10
|
|
|
11
11
|
if typing.TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Hashable
|
|
13
|
+
|
|
12
14
|
from urwid import Font
|
|
13
15
|
|
|
14
16
|
|
|
@@ -41,16 +43,24 @@ class BigText(Widget):
|
|
|
41
43
|
self.font = font
|
|
42
44
|
self._invalidate()
|
|
43
45
|
|
|
44
|
-
def pack(
|
|
46
|
+
def pack(
|
|
47
|
+
self,
|
|
48
|
+
size: tuple[()] | None = (), # type: ignore[override]
|
|
49
|
+
focus: bool = False,
|
|
50
|
+
) -> tuple[int, int]:
|
|
45
51
|
rows = self.font.height
|
|
46
52
|
cols = 0
|
|
47
53
|
for c in self.text:
|
|
48
54
|
cols += self.font.char_width(c)
|
|
49
55
|
return cols, rows
|
|
50
56
|
|
|
51
|
-
def render(
|
|
57
|
+
def render(
|
|
58
|
+
self,
|
|
59
|
+
size: tuple[()], # type: ignore[override]
|
|
60
|
+
focus: bool = False,
|
|
61
|
+
) -> CompositeCanvas:
|
|
52
62
|
fixed_size(size) # complain if parameter is wrong
|
|
53
|
-
a = None
|
|
63
|
+
a: Hashable | None = None
|
|
54
64
|
ai = ak = 0
|
|
55
65
|
o = []
|
|
56
66
|
rows = self.font.height
|
|
@@ -64,7 +74,7 @@ class BigText(Widget):
|
|
|
64
74
|
if not width:
|
|
65
75
|
# ignore invalid characters
|
|
66
76
|
continue
|
|
67
|
-
c = self.font.render(ch)
|
|
77
|
+
c: TextCanvas | CompositeCanvas = self.font.render(ch)
|
|
68
78
|
if a is not None:
|
|
69
79
|
c = CompositeCanvas(c)
|
|
70
80
|
c.fill_attr(a)
|