urwid 2.5.0__cp312-cp312-win32.whl → 2.5.1__cp312-cp312-win32.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/canvas.py +19 -12
- urwid/command_map.py +6 -4
- urwid/display/_posix_raw_display.py +15 -4
- urwid/display/_raw_display_base.py +32 -26
- urwid/display/_win32_raw_display.py +15 -4
- urwid/str_util.pyd +0 -0
- urwid/version.py +2 -2
- urwid/vterm.py +3 -3
- urwid/widget/attr_map.py +5 -3
- urwid/widget/bar_graph.py +7 -7
- urwid/widget/box_adapter.py +6 -7
- urwid/widget/columns.py +14 -7
- urwid/widget/divider.py +2 -2
- urwid/widget/edit.py +1 -1
- urwid/widget/filler.py +8 -7
- urwid/widget/frame.py +9 -1
- urwid/widget/grid_flow.py +4 -6
- urwid/widget/line_box.py +15 -10
- urwid/widget/overlay.py +1 -1
- urwid/widget/padding.py +6 -5
- urwid/widget/pile.py +10 -7
- urwid/widget/popup.py +16 -6
- urwid/widget/progress_bar.py +1 -1
- urwid/widget/scrollable.py +7 -4
- urwid/widget/solid_fill.py +3 -1
- urwid/widget/text.py +1 -1
- urwid/widget/widget.py +8 -8
- urwid/widget/widget_decoration.py +21 -12
- urwid/widget/wimp.py +4 -4
- {urwid-2.5.0.dist-info → urwid-2.5.1.dist-info}/METADATA +6 -2
- {urwid-2.5.0.dist-info → urwid-2.5.1.dist-info}/RECORD +34 -34
- {urwid-2.5.0.dist-info → urwid-2.5.1.dist-info}/COPYING +0 -0
- {urwid-2.5.0.dist-info → urwid-2.5.1.dist-info}/WHEEL +0 -0
- {urwid-2.5.0.dist-info → urwid-2.5.1.dist-info}/top_level.txt +0 -0
urwid/canvas.py
CHANGED
|
@@ -294,7 +294,7 @@ class Canvas:
|
|
|
294
294
|
cols: int | None = None,
|
|
295
295
|
rows: int | None = None,
|
|
296
296
|
attr=None,
|
|
297
|
-
):
|
|
297
|
+
) -> Iterable[list[tuple[object, object, bytes]]]:
|
|
298
298
|
raise NotImplementedError()
|
|
299
299
|
|
|
300
300
|
def cols(self):
|
|
@@ -489,10 +489,10 @@ class TextCanvas(Canvas):
|
|
|
489
489
|
self,
|
|
490
490
|
trim_left: int = 0,
|
|
491
491
|
trim_top: int = 0,
|
|
492
|
-
cols: int = 0,
|
|
493
|
-
rows: int = 0,
|
|
494
|
-
|
|
495
|
-
):
|
|
492
|
+
cols: int | None = 0,
|
|
493
|
+
rows: int | None = 0,
|
|
494
|
+
attr=None,
|
|
495
|
+
) -> Iterable[tuple[object, object, bytes]]:
|
|
496
496
|
"""
|
|
497
497
|
Return the canvas content as a list of rows where each row
|
|
498
498
|
is a list of (attr, cs, text) tuples.
|
|
@@ -534,8 +534,8 @@ class TextCanvas(Canvas):
|
|
|
534
534
|
i = 0
|
|
535
535
|
row = []
|
|
536
536
|
for (a, cs), run in attr_cs:
|
|
537
|
-
if
|
|
538
|
-
a =
|
|
537
|
+
if attr and a in attr:
|
|
538
|
+
a = attr[a] # noqa: PLW2901
|
|
539
539
|
row.append((a, cs, text[i : i + run]))
|
|
540
540
|
i += run
|
|
541
541
|
yield row
|
|
@@ -566,10 +566,10 @@ class BlankCanvas(Canvas):
|
|
|
566
566
|
self,
|
|
567
567
|
trim_left: int = 0,
|
|
568
568
|
trim_top: int = 0,
|
|
569
|
-
cols: int = 0,
|
|
570
|
-
rows: int = 0,
|
|
569
|
+
cols: int | None = 0,
|
|
570
|
+
rows: int | None = 0,
|
|
571
571
|
attr=None,
|
|
572
|
-
):
|
|
572
|
+
) -> Iterable[list[tuple[object, object, bytes]]]:
|
|
573
573
|
"""
|
|
574
574
|
return (cols, rows) of spaces with default attributes.
|
|
575
575
|
"""
|
|
@@ -621,7 +621,7 @@ class SolidCanvas(Canvas):
|
|
|
621
621
|
cols: int | None = None,
|
|
622
622
|
rows: int | None = None,
|
|
623
623
|
attr=None,
|
|
624
|
-
):
|
|
624
|
+
) -> Iterable[list[tuple[object, object, bytes]]]:
|
|
625
625
|
if cols is None:
|
|
626
626
|
cols = self.size[0]
|
|
627
627
|
if rows is None:
|
|
@@ -717,7 +717,14 @@ class CompositeCanvas(Canvas):
|
|
|
717
717
|
raise TypeError(cols)
|
|
718
718
|
return cols
|
|
719
719
|
|
|
720
|
-
def content(
|
|
720
|
+
def content(
|
|
721
|
+
self,
|
|
722
|
+
trim_left: int = 0,
|
|
723
|
+
trim_top: int = 0,
|
|
724
|
+
cols: int | None = None,
|
|
725
|
+
rows: int | None = None,
|
|
726
|
+
attr=None,
|
|
727
|
+
) -> Iterable[list[tuple[object, object, bytes]]]:
|
|
721
728
|
"""
|
|
722
729
|
Return the canvas content as a list of rows where each row
|
|
723
730
|
is a list of (attr, cs, text) tuples.
|
urwid/command_map.py
CHANGED
|
@@ -39,6 +39,8 @@ class Command(str, enum.Enum):
|
|
|
39
39
|
MAX_RIGHT = "cursor max right"
|
|
40
40
|
ACTIVATE = "activate"
|
|
41
41
|
MENU = "menu"
|
|
42
|
+
SELECT_NEXT = "next selectable"
|
|
43
|
+
SELECT_PREVIOUS = "prev selectable"
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
REDRAW_SCREEN = Command.REDRAW_SCREEN
|
|
@@ -84,10 +86,10 @@ class CommandMap(typing.Mapping[str, typing.Union[str, Command, None]]):
|
|
|
84
86
|
return len(self._command)
|
|
85
87
|
|
|
86
88
|
_command_defaults: typing.ClassVar[dict[str, str | Command]] = {
|
|
87
|
-
"tab":
|
|
88
|
-
"ctrl n":
|
|
89
|
-
"shift tab":
|
|
90
|
-
"ctrl p":
|
|
89
|
+
"tab": Command.SELECT_NEXT,
|
|
90
|
+
"ctrl n": Command.SELECT_NEXT,
|
|
91
|
+
"shift tab": Command.SELECT_PREVIOUS,
|
|
92
|
+
"ctrl p": Command.SELECT_PREVIOUS,
|
|
91
93
|
"ctrl l": Command.REDRAW_SCREEN,
|
|
92
94
|
"esc": Command.MENU,
|
|
93
95
|
"up": Command.UP,
|
|
@@ -28,6 +28,7 @@ import contextlib
|
|
|
28
28
|
import fcntl
|
|
29
29
|
import functools
|
|
30
30
|
import os
|
|
31
|
+
import selectors
|
|
31
32
|
import signal
|
|
32
33
|
import struct
|
|
33
34
|
import sys
|
|
@@ -289,14 +290,24 @@ class Screen(_raw_display_base.Screen):
|
|
|
289
290
|
raise
|
|
290
291
|
return codes
|
|
291
292
|
|
|
292
|
-
def
|
|
293
|
+
def _read_raw_input(self, timeout: int) -> bytearray:
|
|
293
294
|
ready = self._wait_for_input_ready(timeout)
|
|
294
295
|
if self.gpm_mev is not None and self.gpm_mev.stdout.fileno() in ready:
|
|
295
296
|
self.gpm_event_pending = True
|
|
296
297
|
fd = self._input_fileno()
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
chars = bytearray()
|
|
299
|
+
|
|
300
|
+
if fd is None or fd not in ready:
|
|
301
|
+
return chars
|
|
302
|
+
|
|
303
|
+
with selectors.DefaultSelector() as selector:
|
|
304
|
+
selector.register(fd, selectors.EVENT_READ)
|
|
305
|
+
input_ready = selector.select(0)
|
|
306
|
+
while input_ready:
|
|
307
|
+
chars.extend(os.read(fd, 1024))
|
|
308
|
+
input_ready = selector.select(0)
|
|
309
|
+
|
|
310
|
+
return chars
|
|
300
311
|
|
|
301
312
|
def _encode_gpm_event(self) -> list[int]:
|
|
302
313
|
self.gpm_event_pending = False
|
|
@@ -28,6 +28,7 @@ import abc
|
|
|
28
28
|
import contextlib
|
|
29
29
|
import functools
|
|
30
30
|
import os
|
|
31
|
+
import platform
|
|
31
32
|
import selectors
|
|
32
33
|
import signal
|
|
33
34
|
import socket
|
|
@@ -41,7 +42,7 @@ from .common import UNPRINTABLE_TRANS_TABLE, UPDATE_PALETTE_ENTRY, AttrSpec, Bas
|
|
|
41
42
|
|
|
42
43
|
if typing.TYPE_CHECKING:
|
|
43
44
|
import io
|
|
44
|
-
from collections.abc import Callable
|
|
45
|
+
from collections.abc import Callable, Iterable
|
|
45
46
|
from types import FrameType
|
|
46
47
|
|
|
47
48
|
from typing_extensions import Literal
|
|
@@ -49,6 +50,7 @@ if typing.TYPE_CHECKING:
|
|
|
49
50
|
from urwid import Canvas, EventLoop
|
|
50
51
|
|
|
51
52
|
IS_WINDOWS = sys.platform == "win32"
|
|
53
|
+
IS_WSL = (sys.platform == "linux") and ("wsl" in platform.platform().lower())
|
|
52
54
|
|
|
53
55
|
|
|
54
56
|
class Screen(BaseScreen, RealTerminal):
|
|
@@ -371,7 +373,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
371
373
|
return wrapper
|
|
372
374
|
|
|
373
375
|
def _get_input_codes(self) -> list[int]:
|
|
374
|
-
return self._get_keyboard_codes()
|
|
376
|
+
return list(self._get_keyboard_codes())
|
|
375
377
|
|
|
376
378
|
def get_available_raw_input(self) -> list[int]:
|
|
377
379
|
"""
|
|
@@ -491,15 +493,6 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
491
493
|
# For get_input
|
|
492
494
|
return decoded_codes, raw_codes
|
|
493
495
|
|
|
494
|
-
def _get_keyboard_codes(self) -> list[int]:
|
|
495
|
-
codes = []
|
|
496
|
-
while True:
|
|
497
|
-
code = self._getch_nodelay()
|
|
498
|
-
if code < 0:
|
|
499
|
-
break
|
|
500
|
-
codes.append(code)
|
|
501
|
-
return codes
|
|
502
|
-
|
|
503
496
|
def _wait_for_input_ready(self, timeout: float | None) -> list[int]:
|
|
504
497
|
logger = self.logger.getChild("wait_for_input_ready")
|
|
505
498
|
fd_list = self.get_input_descriptors()
|
|
@@ -516,10 +509,10 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
516
509
|
return [event.fd for event, _ in ready]
|
|
517
510
|
|
|
518
511
|
@abc.abstractmethod
|
|
519
|
-
def
|
|
512
|
+
def _read_raw_input(self, timeout: int) -> Iterable[int]: ...
|
|
520
513
|
|
|
521
|
-
def
|
|
522
|
-
return self.
|
|
514
|
+
def _get_keyboard_codes(self) -> Iterable[int]:
|
|
515
|
+
return self._read_raw_input(0)
|
|
523
516
|
|
|
524
517
|
def _setup_G1(self) -> None:
|
|
525
518
|
"""
|
|
@@ -603,10 +596,10 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
603
596
|
if isinstance(a, AttrSpec):
|
|
604
597
|
return self._attrspec_to_escape(a)
|
|
605
598
|
# undefined attributes use default/default
|
|
606
|
-
|
|
599
|
+
self.logger.debug(f"Undefined attribute: {a!r}")
|
|
607
600
|
return self._attrspec_to_escape(AttrSpec("default", "default"))
|
|
608
601
|
|
|
609
|
-
def using_standout_or_underline(a):
|
|
602
|
+
def using_standout_or_underline(a: AttrSpec | str) -> bool:
|
|
610
603
|
a = self._pal_attrspec.get(a, a)
|
|
611
604
|
return isinstance(a, AttrSpec) and (a.standout or a.underline)
|
|
612
605
|
|
|
@@ -649,14 +642,17 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
649
642
|
first = True
|
|
650
643
|
lasta = lastcs = None
|
|
651
644
|
for a, cs, run in row:
|
|
652
|
-
if not isinstance(run, bytes): # canvases
|
|
645
|
+
if not isinstance(run, bytes): # canvases render with bytes
|
|
653
646
|
raise TypeError(run)
|
|
647
|
+
|
|
654
648
|
if cs != "U":
|
|
655
649
|
run = run.translate(UNPRINTABLE_TRANS_TABLE) # noqa: PLW2901
|
|
650
|
+
|
|
656
651
|
if first or lasta != a:
|
|
657
652
|
o.append(attr_to_escape(a))
|
|
658
653
|
lasta = a
|
|
659
|
-
|
|
654
|
+
|
|
655
|
+
if not (IS_WINDOWS or IS_WSL) and (first or lastcs != cs):
|
|
660
656
|
if cs not in {None, "0", "U"}:
|
|
661
657
|
raise ValueError(cs)
|
|
662
658
|
if lastcs == "U":
|
|
@@ -669,23 +665,33 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
669
665
|
else:
|
|
670
666
|
o.append(escape.SO)
|
|
671
667
|
lastcs = cs
|
|
668
|
+
|
|
672
669
|
o.append(run)
|
|
673
670
|
first = False
|
|
671
|
+
|
|
674
672
|
if ins:
|
|
675
673
|
(inserta, insertcs, inserttext) = ins
|
|
676
674
|
ias = attr_to_escape(inserta)
|
|
677
675
|
if insertcs not in {None, "0", "U"}:
|
|
678
676
|
raise ValueError(insertcs)
|
|
679
|
-
if cs is None:
|
|
680
|
-
icss = escape.SI
|
|
681
|
-
elif cs == "U":
|
|
682
|
-
icss = escape.IBMPC_ON
|
|
683
|
-
else:
|
|
684
|
-
icss = escape.SO
|
|
685
|
-
o += ["\x08" * back, ias, icss, escape.INSERT_ON, inserttext, escape.INSERT_OFF]
|
|
686
677
|
|
|
687
|
-
|
|
678
|
+
o.extend(("\x08" * back, ias))
|
|
679
|
+
|
|
680
|
+
if not (IS_WINDOWS or IS_WSL):
|
|
681
|
+
if cs is None:
|
|
682
|
+
icss = escape.SI
|
|
683
|
+
elif cs == "U":
|
|
684
|
+
icss = escape.IBMPC_ON
|
|
685
|
+
else:
|
|
686
|
+
icss = escape.SO
|
|
687
|
+
|
|
688
|
+
o.append(icss)
|
|
689
|
+
|
|
690
|
+
o += [escape.INSERT_ON, inserttext, escape.INSERT_OFF]
|
|
691
|
+
|
|
692
|
+
if not (IS_WINDOWS or IS_WSL) and cs == "U":
|
|
688
693
|
o.append(escape.IBMPC_OFF)
|
|
694
|
+
|
|
689
695
|
if whitespace_at_end:
|
|
690
696
|
o.append(escape.ERASE_IN_LINE_RIGHT)
|
|
691
697
|
|
|
@@ -27,6 +27,7 @@ from __future__ import annotations
|
|
|
27
27
|
import contextlib
|
|
28
28
|
import functools
|
|
29
29
|
import logging
|
|
30
|
+
import selectors
|
|
30
31
|
import socket
|
|
31
32
|
import sys
|
|
32
33
|
import threading
|
|
@@ -177,13 +178,23 @@ class Screen(_raw_display_base.Screen):
|
|
|
177
178
|
|
|
178
179
|
_input_thread: ReadInputThread | None = None
|
|
179
180
|
|
|
180
|
-
def
|
|
181
|
+
def _read_raw_input(self, timeout: int) -> bytearray:
|
|
181
182
|
ready = self._wait_for_input_ready(timeout)
|
|
182
183
|
|
|
183
184
|
fd = self._input_fileno()
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
chars = bytearray()
|
|
186
|
+
|
|
187
|
+
if fd is None or fd not in ready:
|
|
188
|
+
return chars
|
|
189
|
+
|
|
190
|
+
with selectors.DefaultSelector() as selector:
|
|
191
|
+
selector.register(fd, selectors.EVENT_READ)
|
|
192
|
+
input_ready = selector.select(0)
|
|
193
|
+
while input_ready:
|
|
194
|
+
chars.extend(self._term_input_file.recv(1024))
|
|
195
|
+
input_ready = selector.select(0)
|
|
196
|
+
|
|
197
|
+
return chars
|
|
187
198
|
|
|
188
199
|
def get_cols_rows(self) -> tuple[int, int]:
|
|
189
200
|
"""Return the terminal dimensions (num columns, num rows)."""
|
urwid/str_util.pyd
CHANGED
|
Binary file
|
urwid/version.py
CHANGED
urwid/vterm.py
CHANGED
|
@@ -1437,11 +1437,11 @@ class TermCanvas(Canvas):
|
|
|
1437
1437
|
def content(
|
|
1438
1438
|
self,
|
|
1439
1439
|
trim_left: int = 0,
|
|
1440
|
-
|
|
1440
|
+
trim_top: int = 0,
|
|
1441
1441
|
cols: int | None = None,
|
|
1442
1442
|
rows: int | None = None,
|
|
1443
1443
|
attr=None,
|
|
1444
|
-
):
|
|
1444
|
+
) -> Iterable[list[tuple[object, object, bytes]]]:
|
|
1445
1445
|
if self.scrolling_up == 0:
|
|
1446
1446
|
yield from self.term
|
|
1447
1447
|
else:
|
|
@@ -1669,7 +1669,7 @@ class Terminal(Widget):
|
|
|
1669
1669
|
elif hasattr(self, "old_tios"):
|
|
1670
1670
|
RealTerminal().tty_signal_keys(*self.old_tios)
|
|
1671
1671
|
|
|
1672
|
-
def render(self, size: tuple[int, int], focus: bool = False):
|
|
1672
|
+
def render(self, size: tuple[int, int], focus: bool = False) -> TermCanvas:
|
|
1673
1673
|
if not self.terminated:
|
|
1674
1674
|
self.change_focus(focus)
|
|
1675
1675
|
|
urwid/widget/attr_map.py
CHANGED
|
@@ -5,22 +5,24 @@ from collections.abc import Hashable, Mapping
|
|
|
5
5
|
|
|
6
6
|
from urwid.canvas import CompositeCanvas
|
|
7
7
|
|
|
8
|
-
from .widget import
|
|
8
|
+
from .widget import WidgetError, delegate_to_widget_mixin
|
|
9
9
|
from .widget_decoration import WidgetDecoration
|
|
10
10
|
|
|
11
|
+
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
class AttrMapError(WidgetError):
|
|
13
15
|
pass
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
class AttrMap(delegate_to_widget_mixin("_original_widget"), WidgetDecoration):
|
|
18
|
+
class AttrMap(delegate_to_widget_mixin("_original_widget"), WidgetDecoration[WrappedWidget]):
|
|
17
19
|
"""
|
|
18
20
|
AttrMap is a decoration that maps one set of attributes to another.
|
|
19
21
|
This object will pass all function calls and variable references to the
|
|
20
22
|
wrapped widget.
|
|
21
23
|
"""
|
|
22
24
|
|
|
23
|
-
def __init__(self, w:
|
|
25
|
+
def __init__(self, w: WrappedWidget, attr_map, focus_map=None) -> None:
|
|
24
26
|
"""
|
|
25
27
|
:param w: widget to wrap (stored as self.original_widget)
|
|
26
28
|
:type w: widget
|
urwid/widget/bar_graph.py
CHANGED
|
@@ -52,7 +52,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
|
|
|
52
52
|
eighths = BAR_SYMBOLS.VERTICAL[:8] # Full height is done by style
|
|
53
53
|
hlines = "_⎺⎻─⎼⎽"
|
|
54
54
|
|
|
55
|
-
def __init__(self, attlist, hatt=None, satt=None):
|
|
55
|
+
def __init__(self, attlist, hatt=None, satt=None) -> None:
|
|
56
56
|
"""
|
|
57
57
|
Create a bar graph with the passed display characteristics.
|
|
58
58
|
see set_segment_attributes for a description of the parameters.
|
|
@@ -134,7 +134,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
|
|
|
134
134
|
raise BarGraphError(f"fg ({fg}) not > bg ({bg})")
|
|
135
135
|
self.satt = satt
|
|
136
136
|
|
|
137
|
-
def set_data(self, bardata, top, hlines=None):
|
|
137
|
+
def set_data(self, bardata, top: float, hlines=None) -> None:
|
|
138
138
|
"""
|
|
139
139
|
Store bar data, bargraph top and horizontal line positions.
|
|
140
140
|
|
|
@@ -428,7 +428,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
|
|
|
428
428
|
return canv
|
|
429
429
|
|
|
430
430
|
|
|
431
|
-
def calculate_bargraph_display(bardata, top, bar_widths, maxrow: int):
|
|
431
|
+
def calculate_bargraph_display(bardata, top: float, bar_widths: list[int], maxrow: int):
|
|
432
432
|
"""
|
|
433
433
|
Calculate a rendering of the bar graph described by data, bar_widths
|
|
434
434
|
and height.
|
|
@@ -574,7 +574,7 @@ def calculate_bargraph_display(bardata, top, bar_widths, maxrow: int):
|
|
|
574
574
|
class GraphVScale(Widget):
|
|
575
575
|
_sizing = frozenset([Sizing.BOX])
|
|
576
576
|
|
|
577
|
-
def __init__(self, labels, top):
|
|
577
|
+
def __init__(self, labels, top: float) -> None:
|
|
578
578
|
"""
|
|
579
579
|
GraphVScale( [(label1 position, label1 markup),...], top )
|
|
580
580
|
label position -- 0 < position < top for the y position
|
|
@@ -587,7 +587,7 @@ class GraphVScale(Widget):
|
|
|
587
587
|
super().__init__()
|
|
588
588
|
self.set_scale(labels, top)
|
|
589
589
|
|
|
590
|
-
def set_scale(self, labels, top):
|
|
590
|
+
def set_scale(self, labels, top: float) -> None:
|
|
591
591
|
"""
|
|
592
592
|
set_scale( [(label1 position, label1 markup),...], top )
|
|
593
593
|
label position -- 0 < position < top for the y position
|
|
@@ -610,7 +610,7 @@ class GraphVScale(Widget):
|
|
|
610
610
|
"""
|
|
611
611
|
return False
|
|
612
612
|
|
|
613
|
-
def render(self, size: tuple[int, int], focus: bool = False):
|
|
613
|
+
def render(self, size: tuple[int, int], focus: bool = False) -> SolidCanvas | CompositeCanvas:
|
|
614
614
|
"""
|
|
615
615
|
Render GraphVScale.
|
|
616
616
|
"""
|
|
@@ -641,7 +641,7 @@ class GraphVScale(Widget):
|
|
|
641
641
|
return c
|
|
642
642
|
|
|
643
643
|
|
|
644
|
-
def scale_bar_values(bar, top, maxrow: int):
|
|
644
|
+
def scale_bar_values(bar, top: float, maxrow: int) -> list[int]:
|
|
645
645
|
"""
|
|
646
646
|
Return a list of bar values aliased to integer values of maxrow.
|
|
647
647
|
"""
|
urwid/widget/box_adapter.py
CHANGED
|
@@ -8,22 +8,21 @@ from urwid.canvas import CompositeCanvas
|
|
|
8
8
|
from .constants import Sizing
|
|
9
9
|
from .widget_decoration import WidgetDecoration, WidgetError
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
from .widget import Widget
|
|
11
|
+
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class BoxAdapterError(WidgetError):
|
|
16
15
|
pass
|
|
17
16
|
|
|
18
17
|
|
|
19
|
-
class BoxAdapter(WidgetDecoration):
|
|
18
|
+
class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
20
19
|
"""
|
|
21
20
|
Adapter for using a box widget where a flow widget would usually go
|
|
22
21
|
"""
|
|
23
22
|
|
|
24
23
|
no_cache: typing.ClassVar[list[str]] = ["rows"]
|
|
25
24
|
|
|
26
|
-
def __init__(self, box_widget, height):
|
|
25
|
+
def __init__(self, box_widget: WrappedWidget, height: int) -> None:
|
|
27
26
|
"""
|
|
28
27
|
Create a flow widget that contains a box widget
|
|
29
28
|
|
|
@@ -47,7 +46,7 @@ class BoxAdapter(WidgetDecoration):
|
|
|
47
46
|
|
|
48
47
|
# originally stored as box_widget, keep for compatibility
|
|
49
48
|
@property
|
|
50
|
-
def box_widget(self) ->
|
|
49
|
+
def box_widget(self) -> WrappedWidget:
|
|
51
50
|
warnings.warn(
|
|
52
51
|
"original stored as original_widget, keep for compatibility",
|
|
53
52
|
PendingDeprecationWarning,
|
|
@@ -56,7 +55,7 @@ class BoxAdapter(WidgetDecoration):
|
|
|
56
55
|
return self.original_widget
|
|
57
56
|
|
|
58
57
|
@box_widget.setter
|
|
59
|
-
def box_widget(self, widget:
|
|
58
|
+
def box_widget(self, widget: WrappedWidget) -> None:
|
|
60
59
|
warnings.warn(
|
|
61
60
|
"original stored as original_widget, keep for compatibility",
|
|
62
61
|
PendingDeprecationWarning,
|
|
@@ -104,7 +103,7 @@ class BoxAdapter(WidgetDecoration):
|
|
|
104
103
|
def mouse_event(
|
|
105
104
|
self,
|
|
106
105
|
size: tuple[int],
|
|
107
|
-
event,
|
|
106
|
+
event: str,
|
|
108
107
|
button: int,
|
|
109
108
|
col: int,
|
|
110
109
|
row: int,
|
urwid/widget/columns.py
CHANGED
|
@@ -6,6 +6,7 @@ from itertools import chain, repeat
|
|
|
6
6
|
|
|
7
7
|
import urwid
|
|
8
8
|
from urwid.canvas import Canvas, CanvasJoin, CompositeCanvas, SolidCanvas
|
|
9
|
+
from urwid.command_map import Command
|
|
9
10
|
from urwid.monitored_list import MonitoredFocusList, MonitoredList
|
|
10
11
|
from urwid.util import is_mouse_press
|
|
11
12
|
|
|
@@ -795,13 +796,16 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
795
796
|
else:
|
|
796
797
|
w_h_args[i] = (0,)
|
|
797
798
|
|
|
798
|
-
elif Sizing.
|
|
799
|
-
|
|
799
|
+
elif Sizing.FLOW in w_sizing or is_box:
|
|
800
|
+
if Sizing.FIXED in w_sizing:
|
|
801
|
+
width, height = widget.pack((), focused)
|
|
802
|
+
else:
|
|
803
|
+
width = self.min_width
|
|
804
|
+
|
|
800
805
|
weighted.setdefault(size_weight, []).append((widget, i, is_box, focused))
|
|
801
806
|
weights.append(size_weight)
|
|
802
807
|
weight_max_sizes.setdefault(size_weight, width)
|
|
803
808
|
weight_max_sizes[size_weight] = max(weight_max_sizes[size_weight], width)
|
|
804
|
-
|
|
805
809
|
else:
|
|
806
810
|
raise ColumnsError(f"Unsupported combination of {size_kind} box={is_box!r} for {widget}")
|
|
807
811
|
|
|
@@ -819,6 +823,9 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
819
823
|
else:
|
|
820
824
|
box.append(i)
|
|
821
825
|
|
|
826
|
+
if not heights:
|
|
827
|
+
raise ColumnsError(f"No height information for pack {self!r} as FIXED")
|
|
828
|
+
|
|
822
829
|
max_height = max(heights.values())
|
|
823
830
|
for idx in box:
|
|
824
831
|
heights[idx] = max_height
|
|
@@ -1019,7 +1026,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
1019
1026
|
def mouse_event(
|
|
1020
1027
|
self,
|
|
1021
1028
|
size: tuple[()] | tuple[int] | tuple[int, int],
|
|
1022
|
-
event,
|
|
1029
|
+
event: str,
|
|
1023
1030
|
button: int,
|
|
1024
1031
|
col: int,
|
|
1025
1032
|
row: int,
|
|
@@ -1115,15 +1122,15 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
|
|
|
1115
1122
|
|
|
1116
1123
|
i = self.focus_position
|
|
1117
1124
|
w, _ = self.contents[i]
|
|
1118
|
-
if self._command_map[key] not in {
|
|
1125
|
+
if self._command_map[key] not in {Command.UP, Command.DOWN, Command.PAGE_UP, Command.PAGE_DOWN}:
|
|
1119
1126
|
self.pref_col = None
|
|
1120
1127
|
if w.selectable():
|
|
1121
1128
|
key = w.keypress(size_args[i], key)
|
|
1122
1129
|
|
|
1123
|
-
if self._command_map[key] not in {
|
|
1130
|
+
if self._command_map[key] not in {Command.LEFT, Command.RIGHT}:
|
|
1124
1131
|
return key
|
|
1125
1132
|
|
|
1126
|
-
if self._command_map[key] ==
|
|
1133
|
+
if self._command_map[key] == Command.LEFT:
|
|
1127
1134
|
candidates = list(range(i - 1, -1, -1)) # count backwards to 0
|
|
1128
1135
|
else: # key == 'right'
|
|
1129
1136
|
candidates = list(range(i + 1, len(self.contents)))
|
urwid/widget/divider.py
CHANGED
|
@@ -69,7 +69,7 @@ class Divider(Widget):
|
|
|
69
69
|
self.top = top
|
|
70
70
|
self.bottom = bottom
|
|
71
71
|
|
|
72
|
-
def _repr_words(self):
|
|
72
|
+
def _repr_words(self) -> list[str]:
|
|
73
73
|
return super()._repr_words() + [repr(self.div_char)] * (self.div_char != " ")
|
|
74
74
|
|
|
75
75
|
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
@@ -92,7 +92,7 @@ class Divider(Widget):
|
|
|
92
92
|
(_maxcol,) = size
|
|
93
93
|
return self.top + 1 + self.bottom
|
|
94
94
|
|
|
95
|
-
def render(self, size: tuple[int], focus: bool = False):
|
|
95
|
+
def render(self, size: tuple[int], focus: bool = False) -> CompositeCanvas:
|
|
96
96
|
"""
|
|
97
97
|
Render the divider as a canvas and return it.
|
|
98
98
|
|
urwid/widget/edit.py
CHANGED
|
@@ -550,7 +550,7 @@ class Edit(Text):
|
|
|
550
550
|
self._invalidate()
|
|
551
551
|
return True
|
|
552
552
|
|
|
553
|
-
def mouse_event(self, size: tuple[int], event, button: int, x: int, y: int, focus: bool) -> bool | None:
|
|
553
|
+
def mouse_event(self, size: tuple[int], event: str, button: int, x: int, y: int, focus: bool) -> bool | None:
|
|
554
554
|
"""
|
|
555
555
|
Move the cursor to the location clicked for button 1.
|
|
556
556
|
|
urwid/widget/filler.py
CHANGED
|
@@ -22,17 +22,18 @@ from .widget_decoration import WidgetDecoration, WidgetError
|
|
|
22
22
|
if typing.TYPE_CHECKING:
|
|
23
23
|
from typing_extensions import Literal
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class FillerError(WidgetError):
|
|
29
30
|
pass
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
class Filler(WidgetDecoration):
|
|
33
|
+
class Filler(WidgetDecoration[WrappedWidget]):
|
|
33
34
|
def __init__(
|
|
34
35
|
self,
|
|
35
|
-
body:
|
|
36
|
+
body: WrappedWidget,
|
|
36
37
|
valign: (
|
|
37
38
|
Literal["top", "middle", "bottom"] | VAlign | tuple[Literal["relative", WHSettings.RELATIVE], int]
|
|
38
39
|
) = VAlign.MIDDLE,
|
|
@@ -159,7 +160,7 @@ class Filler(WidgetDecoration):
|
|
|
159
160
|
return remove_defaults(attrs, Filler.__init__)
|
|
160
161
|
|
|
161
162
|
@property
|
|
162
|
-
def body(self):
|
|
163
|
+
def body(self) -> WrappedWidget:
|
|
163
164
|
"""backwards compatibility, widget used to be stored as body"""
|
|
164
165
|
warnings.warn(
|
|
165
166
|
"backwards compatibility, widget used to be stored as body",
|
|
@@ -169,7 +170,7 @@ class Filler(WidgetDecoration):
|
|
|
169
170
|
return self.original_widget
|
|
170
171
|
|
|
171
172
|
@body.setter
|
|
172
|
-
def body(self, new_body):
|
|
173
|
+
def body(self, new_body: WrappedWidget) -> None:
|
|
173
174
|
warnings.warn(
|
|
174
175
|
"backwards compatibility, widget used to be stored as body",
|
|
175
176
|
PendingDeprecationWarning,
|
|
@@ -177,7 +178,7 @@ class Filler(WidgetDecoration):
|
|
|
177
178
|
)
|
|
178
179
|
self.original_widget = new_body
|
|
179
180
|
|
|
180
|
-
def get_body(self):
|
|
181
|
+
def get_body(self) -> WrappedWidget:
|
|
181
182
|
"""backwards compatibility, widget used to be stored as body"""
|
|
182
183
|
warnings.warn(
|
|
183
184
|
"backwards compatibility, widget used to be stored as body",
|
|
@@ -186,7 +187,7 @@ class Filler(WidgetDecoration):
|
|
|
186
187
|
)
|
|
187
188
|
return self.original_widget
|
|
188
189
|
|
|
189
|
-
def set_body(self, new_body):
|
|
190
|
+
def set_body(self, new_body: WrappedWidget) -> None:
|
|
190
191
|
warnings.warn(
|
|
191
192
|
"backwards compatibility, widget used to be stored as body",
|
|
192
193
|
DeprecationWarning,
|
urwid/widget/frame.py
CHANGED
|
@@ -448,7 +448,15 @@ class Frame(Widget, WidgetContainerMixin):
|
|
|
448
448
|
return key
|
|
449
449
|
return self.body.keypress((maxcol, remaining), key)
|
|
450
450
|
|
|
451
|
-
def mouse_event(
|
|
451
|
+
def mouse_event(
|
|
452
|
+
self,
|
|
453
|
+
size: tuple[int, int],
|
|
454
|
+
event: str,
|
|
455
|
+
button: int,
|
|
456
|
+
col: int,
|
|
457
|
+
row: int,
|
|
458
|
+
focus: bool,
|
|
459
|
+
) -> bool | None:
|
|
452
460
|
"""
|
|
453
461
|
Pass mouse event to appropriate part of frame.
|
|
454
462
|
Focus may be changed on button 1 press.
|