urwid 2.6.8__py3-none-any.whl → 2.6.10__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.
- urwid/display/escape.py +7 -9
- urwid/event_loop/asyncio_loop.py +4 -3
- urwid/event_loop/trio_loop.py +4 -3
- urwid/version.py +2 -2
- urwid/widget/__init__.py +15 -15
- urwid/widget/listbox.py +178 -63
- urwid/widget/monitored_list.py +1 -1
- urwid/widget/scrollable.py +70 -25
- urwid/widget/treetools.py +4 -4
- {urwid-2.6.8.dist-info → urwid-2.6.10.dist-info}/METADATA +1 -1
- {urwid-2.6.8.dist-info → urwid-2.6.10.dist-info}/RECORD +14 -14
- {urwid-2.6.8.dist-info → urwid-2.6.10.dist-info}/WHEEL +1 -1
- {urwid-2.6.8.dist-info → urwid-2.6.10.dist-info}/COPYING +0 -0
- {urwid-2.6.8.dist-info → urwid-2.6.10.dist-info}/top_level.txt +0 -0
urwid/display/escape.py
CHANGED
|
@@ -310,17 +310,15 @@ class KeyqueueTrie:
|
|
|
310
310
|
|
|
311
311
|
(b, x, y) = (int(val) for val in value[:-1].split(";"))
|
|
312
312
|
action = value[-1]
|
|
313
|
-
|
|
314
|
-
#
|
|
315
|
-
# can
|
|
316
|
-
#
|
|
317
|
-
#
|
|
318
|
-
# registered click is below a certain threshold. This threshold
|
|
319
|
-
# is normally set in the operating system itself, so setting one
|
|
320
|
-
# here will cause an inconsistent behaviour. I do not plan to use
|
|
321
|
-
# that feature, so I won't implement it.
|
|
313
|
+
# Double and triple clicks are not supported.
|
|
314
|
+
# They can be implemented by using a timer.
|
|
315
|
+
# This timer can check if the last registered click is below a certain threshold.
|
|
316
|
+
# This threshold is normally set in the operating system itself,
|
|
317
|
+
# so setting one here will cause an inconsistent behaviour.
|
|
322
318
|
|
|
323
319
|
prefixes = []
|
|
320
|
+
if b & 4:
|
|
321
|
+
prefixes.append("shift ")
|
|
324
322
|
if b & 8:
|
|
325
323
|
prefixes.append("meta ")
|
|
326
324
|
if b & 16:
|
urwid/event_loop/asyncio_loop.py
CHANGED
|
@@ -222,9 +222,10 @@ class AsyncioEventLoop(EventLoop):
|
|
|
222
222
|
loop.default_exception_handler(context)
|
|
223
223
|
|
|
224
224
|
def run(self) -> None:
|
|
225
|
-
"""
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
"""Start the event loop.
|
|
226
|
+
|
|
227
|
+
Exit the loop when any callback raises an exception.
|
|
228
|
+
If ExitMainLoop is raised, exit cleanly.
|
|
228
229
|
"""
|
|
229
230
|
self._loop.set_exception_handler(self._exception_handler)
|
|
230
231
|
self._loop.run_forever()
|
urwid/event_loop/trio_loop.py
CHANGED
|
@@ -160,9 +160,10 @@ class TrioEventLoop(EventLoop):
|
|
|
160
160
|
trio.run(self._main_task, instruments=[emulate_idle_callbacks])
|
|
161
161
|
|
|
162
162
|
async def run_async(self) -> None:
|
|
163
|
-
"""Starts the main loop and blocks asynchronously until the main loop
|
|
164
|
-
|
|
165
|
-
Trio event loop is already running.
|
|
163
|
+
"""Starts the main loop and blocks asynchronously until the main loop exits.
|
|
164
|
+
|
|
165
|
+
This allows one to embed an urwid app in a Trio app even if the Trio event loop is already running.
|
|
166
|
+
Example::
|
|
166
167
|
|
|
167
168
|
with trio.open_nursery() as nursery:
|
|
168
169
|
event_loop = urwid.TrioEventLoop()
|
urwid/version.py
CHANGED
urwid/widget/__init__.py
CHANGED
|
@@ -61,8 +61,6 @@ from .wimp import Button, CheckBox, CheckBoxError, RadioButton, SelectableIcon
|
|
|
61
61
|
__all__ = (
|
|
62
62
|
"ANY",
|
|
63
63
|
"BOTTOM",
|
|
64
|
-
"MonitoredList",
|
|
65
|
-
"MonitoredFocusList",
|
|
66
64
|
"BOX",
|
|
67
65
|
"CENTER",
|
|
68
66
|
"CLIP",
|
|
@@ -72,7 +70,6 @@ __all__ = (
|
|
|
72
70
|
"GIVEN",
|
|
73
71
|
"LEFT",
|
|
74
72
|
"MIDDLE",
|
|
75
|
-
"GridFlowWarning",
|
|
76
73
|
"PACK",
|
|
77
74
|
"RELATIVE",
|
|
78
75
|
"RELATIVE_100",
|
|
@@ -91,20 +88,8 @@ __all__ = (
|
|
|
91
88
|
"BoxAdapter",
|
|
92
89
|
"BoxAdapterError",
|
|
93
90
|
"BoxWidget",
|
|
94
|
-
"ListWalkerError",
|
|
95
|
-
"ListWalker",
|
|
96
|
-
"SimpleListWalker",
|
|
97
|
-
"SimpleFocusListWalker",
|
|
98
|
-
"ListBoxError",
|
|
99
|
-
"ListBox",
|
|
100
91
|
"Button",
|
|
101
92
|
"CheckBox",
|
|
102
|
-
"TreeWidgetError",
|
|
103
|
-
"TreeWidget",
|
|
104
|
-
"TreeNode",
|
|
105
|
-
"ParentNode",
|
|
106
|
-
"TreeWalker",
|
|
107
|
-
"TreeListBox",
|
|
108
93
|
"CheckBoxError",
|
|
109
94
|
"Columns",
|
|
110
95
|
"ColumnsError",
|
|
@@ -121,14 +106,22 @@ __all__ = (
|
|
|
121
106
|
"GraphVScale",
|
|
122
107
|
"GridFlow",
|
|
123
108
|
"GridFlowError",
|
|
109
|
+
"GridFlowWarning",
|
|
124
110
|
"IntEdit",
|
|
125
111
|
"LineBox",
|
|
112
|
+
"ListBox",
|
|
113
|
+
"ListBoxError",
|
|
114
|
+
"ListWalker",
|
|
115
|
+
"ListWalkerError",
|
|
116
|
+
"MonitoredFocusList",
|
|
117
|
+
"MonitoredList",
|
|
126
118
|
"Overlay",
|
|
127
119
|
"OverlayError",
|
|
128
120
|
"OverlayWarning",
|
|
129
121
|
"Padding",
|
|
130
122
|
"PaddingError",
|
|
131
123
|
"PaddingWarning",
|
|
124
|
+
"ParentNode",
|
|
132
125
|
"Pile",
|
|
133
126
|
"PileError",
|
|
134
127
|
"PileWarning",
|
|
@@ -140,10 +133,17 @@ __all__ = (
|
|
|
140
133
|
"Scrollable",
|
|
141
134
|
"ScrollableError",
|
|
142
135
|
"SelectableIcon",
|
|
136
|
+
"SimpleFocusListWalker",
|
|
137
|
+
"SimpleListWalker",
|
|
143
138
|
"Sizing",
|
|
144
139
|
"SolidFill",
|
|
145
140
|
"Text",
|
|
146
141
|
"TextError",
|
|
142
|
+
"TreeListBox",
|
|
143
|
+
"TreeNode",
|
|
144
|
+
"TreeWalker",
|
|
145
|
+
"TreeWidget",
|
|
146
|
+
"TreeWidgetError",
|
|
147
147
|
"VAlign",
|
|
148
148
|
"WHSettings",
|
|
149
149
|
"Widget",
|
urwid/widget/listbox.py
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
+
import operator
|
|
23
24
|
import typing
|
|
24
25
|
import warnings
|
|
25
26
|
from collections.abc import Iterable, Sized
|
|
@@ -43,7 +44,18 @@ if typing.TYPE_CHECKING:
|
|
|
43
44
|
|
|
44
45
|
from urwid.canvas import Canvas, CompositeCanvas
|
|
45
46
|
|
|
46
|
-
__all__ = (
|
|
47
|
+
__all__ = (
|
|
48
|
+
"ListBox",
|
|
49
|
+
"ListBoxError",
|
|
50
|
+
"ListWalker",
|
|
51
|
+
"ListWalkerError",
|
|
52
|
+
"SimpleFocusListWalker",
|
|
53
|
+
"SimpleListWalker",
|
|
54
|
+
"VisibleInfo",
|
|
55
|
+
"VisibleInfoFillItem",
|
|
56
|
+
"VisibleInfoMiddle",
|
|
57
|
+
"VisibleInfoTopBottom",
|
|
58
|
+
)
|
|
47
59
|
|
|
48
60
|
_T = typing.TypeVar("_T")
|
|
49
61
|
_K = typing.TypeVar("_K")
|
|
@@ -54,22 +66,30 @@ class ListWalkerError(Exception):
|
|
|
54
66
|
|
|
55
67
|
|
|
56
68
|
@runtime_checkable
|
|
57
|
-
class ScrollSupportingBody(
|
|
58
|
-
"""Protocol for ListWalkers
|
|
69
|
+
class ScrollSupportingBody(Protocol):
|
|
70
|
+
"""Protocol for ListWalkers."""
|
|
59
71
|
|
|
60
72
|
def get_focus(self) -> tuple[Widget, _K]: ...
|
|
61
73
|
|
|
62
74
|
def set_focus(self, position: _K) -> None: ...
|
|
63
75
|
|
|
64
|
-
def __getitem__(self, index: _K) -> _T: ...
|
|
65
|
-
|
|
66
|
-
def positions(self, reverse: bool = False) -> Iterable[_K]: ...
|
|
67
|
-
|
|
68
76
|
def get_next(self, position: _K) -> tuple[Widget, _K] | tuple[None, None]: ...
|
|
69
77
|
|
|
70
78
|
def get_prev(self, position: _K) -> tuple[Widget, _K] | tuple[None, None]: ...
|
|
71
79
|
|
|
72
80
|
|
|
81
|
+
@runtime_checkable
|
|
82
|
+
class EstimatedSized(Protocol):
|
|
83
|
+
"""Widget can estimate it's size.
|
|
84
|
+
|
|
85
|
+
PEP 424 defines API for memory-efficiency.
|
|
86
|
+
For the ListBox it's a sign of the limited body length.
|
|
87
|
+
The main use-case is lazy-load, where real length calculation is expensive.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __length_hint__(self) -> int: ...
|
|
91
|
+
|
|
92
|
+
|
|
73
93
|
class ListWalker(metaclass=signals.MetaSignals): # pylint: disable=no-member, unsubscriptable-object
|
|
74
94
|
# mixin not named as mixin
|
|
75
95
|
signals: typing.ClassVar[list[str]] = ["modified"]
|
|
@@ -276,7 +296,7 @@ class ListBoxError(Exception):
|
|
|
276
296
|
pass
|
|
277
297
|
|
|
278
298
|
|
|
279
|
-
class
|
|
299
|
+
class VisibleInfoMiddle(typing.NamedTuple):
|
|
280
300
|
"""Named tuple for ListBox internals."""
|
|
281
301
|
|
|
282
302
|
offset: int
|
|
@@ -286,7 +306,7 @@ class _Middle(typing.NamedTuple):
|
|
|
286
306
|
cursor: tuple[int, int] | tuple[int] | None
|
|
287
307
|
|
|
288
308
|
|
|
289
|
-
class
|
|
309
|
+
class VisibleInfoFillItem(typing.NamedTuple):
|
|
290
310
|
"""Named tuple for ListBox internals."""
|
|
291
311
|
|
|
292
312
|
widget: Widget
|
|
@@ -294,11 +314,45 @@ class _FillItem(typing.NamedTuple):
|
|
|
294
314
|
rows: int
|
|
295
315
|
|
|
296
316
|
|
|
297
|
-
class
|
|
317
|
+
class VisibleInfoTopBottom(typing.NamedTuple):
|
|
298
318
|
"""Named tuple for ListBox internals."""
|
|
299
319
|
|
|
300
320
|
trim: int
|
|
301
|
-
fill: list[
|
|
321
|
+
fill: list[VisibleInfoFillItem]
|
|
322
|
+
|
|
323
|
+
@classmethod
|
|
324
|
+
def from_raw_data(
|
|
325
|
+
cls,
|
|
326
|
+
trim: int,
|
|
327
|
+
fill: Iterable[tuple[Widget, Hashable, int]],
|
|
328
|
+
) -> Self:
|
|
329
|
+
"""Construct from not typed data.
|
|
330
|
+
|
|
331
|
+
Useful for overridden cases."""
|
|
332
|
+
return cls(trim=trim, fill=[VisibleInfoFillItem(*item) for item in fill]) # pragma: no cover
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class VisibleInfo(typing.NamedTuple):
|
|
336
|
+
middle: VisibleInfoMiddle
|
|
337
|
+
top: VisibleInfoTopBottom
|
|
338
|
+
bottom: VisibleInfoTopBottom
|
|
339
|
+
|
|
340
|
+
@classmethod
|
|
341
|
+
def from_raw_data(
|
|
342
|
+
cls,
|
|
343
|
+
middle: tuple[int, Widget, Hashable, int, tuple[int, int] | tuple[int] | None],
|
|
344
|
+
top: tuple[int, Iterable[tuple[Widget, Hashable, int]]],
|
|
345
|
+
bottom: tuple[int, Iterable[tuple[Widget, Hashable, int]]],
|
|
346
|
+
) -> Self:
|
|
347
|
+
"""Construct from not typed data.
|
|
348
|
+
|
|
349
|
+
Useful for overridden cases.
|
|
350
|
+
"""
|
|
351
|
+
return cls( # pragma: no cover
|
|
352
|
+
middle=VisibleInfoMiddle(*middle),
|
|
353
|
+
top=VisibleInfoTopBottom.from_raw_data(*top),
|
|
354
|
+
bottom=VisibleInfoTopBottom.from_raw_data(*bottom),
|
|
355
|
+
)
|
|
302
356
|
|
|
303
357
|
|
|
304
358
|
class ListBox(Widget, WidgetContainerMixin):
|
|
@@ -390,16 +444,23 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
390
444
|
)
|
|
391
445
|
self.body = body
|
|
392
446
|
|
|
393
|
-
|
|
447
|
+
@property
|
|
448
|
+
def __len__(self) -> Callable[[], int]:
|
|
394
449
|
if isinstance(self._body, Sized):
|
|
395
|
-
return
|
|
450
|
+
return self._body.__len__
|
|
396
451
|
raise AttributeError(f"{self._body.__class__.__name__} is not Sized")
|
|
397
452
|
|
|
453
|
+
@property
|
|
454
|
+
def __length_hint__(self) -> Callable[[], int]: # pylint: disable=invalid-length-hint-returned
|
|
455
|
+
if isinstance(self._body, (Sized, EstimatedSized)):
|
|
456
|
+
return lambda: operator.length_hint(self._body)
|
|
457
|
+
raise AttributeError(f'{self._body.__class__.__name__} is not Sized and do not implement "__length_hint__"')
|
|
458
|
+
|
|
398
459
|
def calculate_visible(
|
|
399
460
|
self,
|
|
400
461
|
size: tuple[int, int],
|
|
401
462
|
focus: bool = False,
|
|
402
|
-
) ->
|
|
463
|
+
) -> VisibleInfo | tuple[None, None, None]:
|
|
403
464
|
"""
|
|
404
465
|
Returns the widgets that would be displayed in
|
|
405
466
|
the ListBox given the current *size* and *focus*.
|
|
@@ -470,7 +531,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
470
531
|
|
|
471
532
|
p_rows = prev.rows((maxcol,))
|
|
472
533
|
if p_rows: # filter out 0-height widgets
|
|
473
|
-
fill_above.append(
|
|
534
|
+
fill_above.append(VisibleInfoFillItem(prev, pos, p_rows))
|
|
474
535
|
if p_rows > fill_lines: # crosses top edge?
|
|
475
536
|
trim_top = p_rows - fill_lines
|
|
476
537
|
break
|
|
@@ -489,7 +550,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
489
550
|
|
|
490
551
|
n_rows = next_pos.rows((maxcol,))
|
|
491
552
|
if n_rows: # filter out 0-height widgets
|
|
492
|
-
fill_below.append(
|
|
553
|
+
fill_below.append(VisibleInfoFillItem(next_pos, pos, n_rows))
|
|
493
554
|
if n_rows > fill_lines: # crosses bottom edge?
|
|
494
555
|
trim_bottom = n_rows - fill_lines
|
|
495
556
|
fill_lines -= n_rows
|
|
@@ -515,7 +576,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
515
576
|
break
|
|
516
577
|
|
|
517
578
|
p_rows = prev.rows((maxcol,))
|
|
518
|
-
fill_above.append(
|
|
579
|
+
fill_above.append(VisibleInfoFillItem(prev, pos, p_rows))
|
|
519
580
|
if p_rows > fill_lines: # more than required
|
|
520
581
|
trim_top = p_rows - fill_lines
|
|
521
582
|
offset_rows += fill_lines
|
|
@@ -524,17 +585,31 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
524
585
|
offset_rows += p_rows
|
|
525
586
|
|
|
526
587
|
# 5. return the interesting bits
|
|
527
|
-
return (
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
588
|
+
return VisibleInfo(
|
|
589
|
+
VisibleInfoMiddle(offset_rows - inset_rows, focus_widget, focus_pos, focus_rows, cursor),
|
|
590
|
+
VisibleInfoTopBottom(trim_top, fill_above),
|
|
591
|
+
VisibleInfoTopBottom(trim_bottom, fill_below),
|
|
531
592
|
)
|
|
532
593
|
|
|
533
|
-
def
|
|
534
|
-
|
|
594
|
+
def _check_support_scrolling(self) -> None:
|
|
595
|
+
from .treetools import TreeWalker
|
|
596
|
+
|
|
535
597
|
if not isinstance(self._body, ScrollSupportingBody):
|
|
536
598
|
raise ListBoxError(f"{self} body do not implement methods required for scrolling protocol")
|
|
537
599
|
|
|
600
|
+
if not isinstance(self._body, (Sized, EstimatedSized, TreeWalker)):
|
|
601
|
+
raise ListBoxError(
|
|
602
|
+
f"{self} body is not a Sized, can not estimate it's size and not a TreeWalker."
|
|
603
|
+
f"Scroll is not allowed due to risk of infinite cycle of widgets load."
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
if getattr(self._body, "wrap_around", False):
|
|
607
|
+
raise ListBoxError("Body is wrapped around. Scroll position calculation is undefined.")
|
|
608
|
+
|
|
609
|
+
def get_scrollpos(self, size: tuple[int, int] | None = None, focus: bool = False) -> int:
|
|
610
|
+
"""Current scrolling position."""
|
|
611
|
+
self._check_support_scrolling()
|
|
612
|
+
|
|
538
613
|
if not self._body:
|
|
539
614
|
return 0
|
|
540
615
|
|
|
@@ -560,22 +635,65 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
560
635
|
|
|
561
636
|
def rows_max(self, size: tuple[int, int] | None = None, focus: bool = False) -> int:
|
|
562
637
|
"""Scrollable protocol for sized iterable and not wrapped around contents."""
|
|
563
|
-
|
|
564
|
-
raise ListBoxError(f"{self} body do not implement methods required for scrolling protocol")
|
|
565
|
-
|
|
566
|
-
if getattr(self._body, "wrap_around", False):
|
|
567
|
-
raise ListBoxError("Body is wrapped around")
|
|
638
|
+
self._check_support_scrolling()
|
|
568
639
|
|
|
569
640
|
if size is not None:
|
|
570
641
|
self._rendered_size = size
|
|
571
642
|
|
|
572
643
|
if size or not self._rows_max_cached:
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
644
|
+
cols = self._rendered_size[0]
|
|
645
|
+
rows = 0
|
|
646
|
+
|
|
647
|
+
focused_w, idx = self.body.get_focus()
|
|
648
|
+
rows += focused_w.rows((cols,), focus)
|
|
649
|
+
|
|
650
|
+
prev, pos = self._body.get_prev(idx)
|
|
651
|
+
while prev is not None:
|
|
652
|
+
rows += prev.rows((cols,), False)
|
|
653
|
+
prev, pos = self._body.get_prev(pos)
|
|
654
|
+
|
|
655
|
+
next_, pos = self.body.get_next(idx)
|
|
656
|
+
while next_ is not None:
|
|
657
|
+
rows += next_.rows((cols,), True)
|
|
658
|
+
next_, pos = self._body.get_next(pos)
|
|
659
|
+
|
|
660
|
+
self._rows_max_cached = rows
|
|
576
661
|
|
|
577
662
|
return self._rows_max_cached
|
|
578
663
|
|
|
664
|
+
def require_relative_scroll(self, size: tuple[int, int], focus: bool = False) -> bool:
|
|
665
|
+
"""Widget require relative scroll due to performance limitations of real lines count calculation."""
|
|
666
|
+
return isinstance(self._body, (Sized, EstimatedSized)) and (size[1] * 3 < operator.length_hint(self.body))
|
|
667
|
+
|
|
668
|
+
def get_first_visible_pos(self, size: tuple[int, int], focus: bool = False) -> int:
|
|
669
|
+
self._check_support_scrolling()
|
|
670
|
+
|
|
671
|
+
if not self._body:
|
|
672
|
+
return 0
|
|
673
|
+
|
|
674
|
+
_mid, top, _bottom = self.calculate_visible(size, focus)
|
|
675
|
+
if top.fill:
|
|
676
|
+
first_pos = top.fill[-1].position
|
|
677
|
+
else:
|
|
678
|
+
first_pos = self.focus_position
|
|
679
|
+
|
|
680
|
+
over = 0
|
|
681
|
+
_widget, first_pos = self.body.get_prev(first_pos)
|
|
682
|
+
while first_pos is not None:
|
|
683
|
+
over += 1
|
|
684
|
+
_widget, first_pos = self.body.get_prev(first_pos)
|
|
685
|
+
|
|
686
|
+
return over
|
|
687
|
+
|
|
688
|
+
def get_visible_amount(self, size: tuple[int, int], focus: bool = False) -> int:
|
|
689
|
+
self._check_support_scrolling()
|
|
690
|
+
|
|
691
|
+
if not self._body:
|
|
692
|
+
return 1
|
|
693
|
+
|
|
694
|
+
_mid, top, bottom = self.calculate_visible(size, focus)
|
|
695
|
+
return 1 + len(top.fill) + len(bottom.fill)
|
|
696
|
+
|
|
579
697
|
def render(
|
|
580
698
|
self,
|
|
581
699
|
size: tuple[int, int], # type: ignore[override]
|
|
@@ -594,9 +712,9 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
594
712
|
if middle is None:
|
|
595
713
|
return SolidCanvas(" ", maxcol, maxrow)
|
|
596
714
|
|
|
597
|
-
_ignore, focus_widget, focus_pos, focus_rows, cursor = middle
|
|
598
|
-
trim_top, fill_above = top
|
|
599
|
-
trim_bottom, fill_below = bottom
|
|
715
|
+
_ignore, focus_widget, focus_pos, focus_rows, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
716
|
+
trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
717
|
+
trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
600
718
|
|
|
601
719
|
combinelist: list[tuple[Canvas, int, bool]] = []
|
|
602
720
|
rows = 0
|
|
@@ -706,7 +824,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
706
824
|
if middle is None:
|
|
707
825
|
return None
|
|
708
826
|
|
|
709
|
-
offset_inset, _ignore1, _ignore2, _ignore3, cursor = middle
|
|
827
|
+
offset_inset, _ignore1, _ignore2, _ignore3, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
710
828
|
if not cursor:
|
|
711
829
|
return None
|
|
712
830
|
|
|
@@ -897,9 +1015,9 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
897
1015
|
if middle is None:
|
|
898
1016
|
return
|
|
899
1017
|
|
|
900
|
-
row_offset, focus_widget, _focus_pos, focus_rows, _cursor = middle
|
|
901
|
-
_trim_top, _fill_above = top
|
|
902
|
-
trim_bottom, fill_below = bottom
|
|
1018
|
+
row_offset, focus_widget, _focus_pos, focus_rows, _cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1019
|
+
_trim_top, _fill_above = top # pylint: disable=unpacking-non-sequence
|
|
1020
|
+
trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
903
1021
|
|
|
904
1022
|
if focus_widget.selectable():
|
|
905
1023
|
return
|
|
@@ -935,9 +1053,9 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
935
1053
|
self._body.set_focus(focus_pos)
|
|
936
1054
|
|
|
937
1055
|
middle, top, bottom = self.calculate_visible((maxcol, maxrow), focus)
|
|
938
|
-
focus_offset, _focus_widget, focus_pos, focus_rows, _cursor = middle
|
|
939
|
-
_trim_top, fill_above = top
|
|
940
|
-
_trim_bottom, fill_below = bottom
|
|
1056
|
+
focus_offset, _focus_widget, focus_pos, focus_rows, _cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1057
|
+
_trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
1058
|
+
_trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
941
1059
|
|
|
942
1060
|
offset = focus_offset
|
|
943
1061
|
for _widget, pos, rows in fill_above:
|
|
@@ -1251,8 +1369,8 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1251
1369
|
if middle is None:
|
|
1252
1370
|
return True
|
|
1253
1371
|
|
|
1254
|
-
focus_row_offset, focus_widget, focus_pos, _ignore, cursor = middle
|
|
1255
|
-
_trim_top, fill_above = top
|
|
1372
|
+
focus_row_offset, focus_widget, focus_pos, _ignore, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1373
|
+
_trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
1256
1374
|
|
|
1257
1375
|
row_offset = focus_row_offset
|
|
1258
1376
|
|
|
@@ -1324,8 +1442,8 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1324
1442
|
if middle is None:
|
|
1325
1443
|
return True
|
|
1326
1444
|
|
|
1327
|
-
focus_row_offset, focus_widget, focus_pos, focus_rows, cursor = middle
|
|
1328
|
-
_trim_bottom, fill_below = bottom
|
|
1445
|
+
focus_row_offset, focus_widget, focus_pos, focus_rows, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1446
|
+
_trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
1329
1447
|
|
|
1330
1448
|
row_offset = focus_row_offset + focus_rows
|
|
1331
1449
|
rows = focus_rows
|
|
@@ -1363,9 +1481,6 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1363
1481
|
if widget is None:
|
|
1364
1482
|
self.shift_focus((maxcol, maxrow), row_offset - rows)
|
|
1365
1483
|
return None
|
|
1366
|
-
# FIXME: catch this bug in testcase
|
|
1367
|
-
# self.change_focus((maxcol,maxrow), pos,
|
|
1368
|
-
# row_offset+rows, 'above')
|
|
1369
1484
|
self.change_focus((maxcol, maxrow), pos, row_offset - rows, "above")
|
|
1370
1485
|
return None
|
|
1371
1486
|
|
|
@@ -1406,8 +1521,8 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1406
1521
|
if middle is None:
|
|
1407
1522
|
return True
|
|
1408
1523
|
|
|
1409
|
-
row_offset, focus_widget, focus_pos, focus_rows, cursor = middle
|
|
1410
|
-
_trim_top, fill_above = top
|
|
1524
|
+
row_offset, focus_widget, focus_pos, focus_rows, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1525
|
+
_trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
1411
1526
|
|
|
1412
1527
|
# topmost_visible is row_offset rows above top row of
|
|
1413
1528
|
# focus (+ve) or -row_offset rows below top row of focus (-ve)
|
|
@@ -1516,7 +1631,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1516
1631
|
|
|
1517
1632
|
# find out where that actually puts us
|
|
1518
1633
|
middle, top, _bottom = self.calculate_visible((maxcol, maxrow), True)
|
|
1519
|
-
act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle
|
|
1634
|
+
act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle # pylint: disable=unpacking-non-sequence
|
|
1520
1635
|
|
|
1521
1636
|
# discard chosen widget if it will reduce scroll amount
|
|
1522
1637
|
# because of a fixed cursor (absolute last resort)
|
|
@@ -1566,7 +1681,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1566
1681
|
|
|
1567
1682
|
# final check for pathological case where we may fall short
|
|
1568
1683
|
middle, top, _bottom = self.calculate_visible((maxcol, maxrow), True)
|
|
1569
|
-
act_row_offset, _ign1, pos, _ign2, _ign3 = middle
|
|
1684
|
+
act_row_offset, _ign1, pos, _ign2, _ign3 = middle # pylint: disable=unpacking-non-sequence
|
|
1570
1685
|
if act_row_offset >= row_offset:
|
|
1571
1686
|
# no problem
|
|
1572
1687
|
return None
|
|
@@ -1598,8 +1713,8 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1598
1713
|
if middle is None:
|
|
1599
1714
|
return True
|
|
1600
1715
|
|
|
1601
|
-
row_offset, focus_widget, focus_pos, focus_rows, cursor = middle
|
|
1602
|
-
_trim_bottom, fill_below = bottom
|
|
1716
|
+
row_offset, focus_widget, focus_pos, focus_rows, cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1717
|
+
_trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
1603
1718
|
|
|
1604
1719
|
# bottom_edge is maxrow-focus_pos rows below top row of focus
|
|
1605
1720
|
bottom_edge = maxrow - row_offset
|
|
@@ -1704,7 +1819,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1704
1819
|
|
|
1705
1820
|
# find out where that actually puts us
|
|
1706
1821
|
middle, _top, bottom = self.calculate_visible((maxcol, maxrow), True)
|
|
1707
|
-
act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle
|
|
1822
|
+
act_row_offset, _ign1, _ign2, _ign3, _ign4 = middle # pylint: disable=unpacking-non-sequence
|
|
1708
1823
|
|
|
1709
1824
|
# discard chosen widget if it will reduce scroll amount
|
|
1710
1825
|
# because of a fixed cursor (absolute last resort)
|
|
@@ -1750,7 +1865,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1750
1865
|
|
|
1751
1866
|
# final check for pathological case where we may fall short
|
|
1752
1867
|
middle, _top, bottom = self.calculate_visible((maxcol, maxrow), True)
|
|
1753
|
-
act_row_offset, _ign1, pos, _ign2, _ign3 = middle
|
|
1868
|
+
act_row_offset, _ign1, pos, _ign2, _ign3 = middle # pylint: disable=unpacking-non-sequence
|
|
1754
1869
|
if act_row_offset <= row_offset:
|
|
1755
1870
|
# no problem
|
|
1756
1871
|
return None
|
|
@@ -1795,9 +1910,9 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1795
1910
|
if middle is None:
|
|
1796
1911
|
return False
|
|
1797
1912
|
|
|
1798
|
-
_ignore, focus_widget, focus_pos, focus_rows, _cursor = middle
|
|
1799
|
-
trim_top, fill_above = top
|
|
1800
|
-
_ignore, fill_below = bottom
|
|
1913
|
+
_ignore, focus_widget, focus_pos, focus_rows, _cursor = middle # pylint: disable=unpacking-non-sequence
|
|
1914
|
+
trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
1915
|
+
_ignore, fill_below = bottom # pylint: disable=unpacking-non-sequence
|
|
1801
1916
|
|
|
1802
1917
|
fill_above.reverse() # fill_above is in bottom-up order
|
|
1803
1918
|
w_list = [*fill_above, (focus_widget, focus_pos, focus_rows), *fill_below]
|
|
@@ -1850,11 +1965,11 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1850
1965
|
middle, top, bottom = self.calculate_visible((maxcol, maxrow), focus=focus)
|
|
1851
1966
|
if middle is None: # empty listbox
|
|
1852
1967
|
return ["top", "bottom"]
|
|
1853
|
-
trim_top, above = top
|
|
1854
|
-
trim_bottom, below = bottom
|
|
1968
|
+
trim_top, above = top # pylint: disable=unpacking-non-sequence
|
|
1969
|
+
trim_bottom, below = bottom # pylint: disable=unpacking-non-sequence
|
|
1855
1970
|
|
|
1856
1971
|
if trim_bottom == 0:
|
|
1857
|
-
row_offset, _w, pos, rows, _c = middle
|
|
1972
|
+
row_offset, _w, pos, rows, _c = middle # pylint: disable=unpacking-non-sequence
|
|
1858
1973
|
row_offset += rows
|
|
1859
1974
|
for _w, pos, rows in below: # noqa: B007 # magic with scope
|
|
1860
1975
|
row_offset += rows
|
|
@@ -1862,7 +1977,7 @@ class ListBox(Widget, WidgetContainerMixin):
|
|
|
1862
1977
|
result.append("bottom")
|
|
1863
1978
|
|
|
1864
1979
|
if trim_top == 0:
|
|
1865
|
-
row_offset, _w, pos, _rows, _c = middle
|
|
1980
|
+
row_offset, _w, pos, _rows, _c = middle # pylint: disable=unpacking-non-sequence
|
|
1866
1981
|
for _w, pos, rows in above: # noqa: B007 # magic with scope
|
|
1867
1982
|
row_offset -= rows
|
|
1868
1983
|
if self._body.get_prev(pos) == (None, None):
|
urwid/widget/monitored_list.py
CHANGED
urwid/widget/scrollable.py
CHANGED
|
@@ -85,10 +85,10 @@ class ScrollbarSymbols(str, enum.Enum):
|
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
@runtime_checkable
|
|
88
|
-
class
|
|
89
|
-
"""Protocol for
|
|
88
|
+
class WidgetProto(Protocol):
|
|
89
|
+
"""Protocol for widget.
|
|
90
90
|
|
|
91
|
-
Due to protocol
|
|
91
|
+
Due to protocol cannot inherit non-protocol bases, define several obligatory Widget methods.
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
94
|
# Base widget methods (from Widget)
|
|
@@ -116,12 +116,27 @@ class SupportsScroll(Protocol):
|
|
|
116
116
|
|
|
117
117
|
def render(self, size: tuple[int, int], focus: bool = False) -> Canvas: ...
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
|
|
120
|
+
@runtime_checkable
|
|
121
|
+
class SupportsScroll(WidgetProto, Protocol):
|
|
122
|
+
"""Scroll specific methods."""
|
|
123
|
+
|
|
120
124
|
def get_scrollpos(self, size: tuple[int, int], focus: bool = False) -> int: ...
|
|
121
125
|
|
|
122
126
|
def rows_max(self, size: tuple[int, int] | None = None, focus: bool = False) -> int: ...
|
|
123
127
|
|
|
124
128
|
|
|
129
|
+
@runtime_checkable
|
|
130
|
+
class SupportsRelativeScroll(WidgetProto, Protocol):
|
|
131
|
+
"""Relative scroll-specific methods."""
|
|
132
|
+
|
|
133
|
+
def require_relative_scroll(self, size: tuple[int, int], focus: bool = False) -> bool: ...
|
|
134
|
+
|
|
135
|
+
def get_first_visible_pos(self, size: tuple[int, int], focus: bool = False) -> int: ...
|
|
136
|
+
|
|
137
|
+
def get_visible_amount(self, size: tuple[int, int], focus: bool = False) -> int: ...
|
|
138
|
+
|
|
139
|
+
|
|
125
140
|
class Scrollable(WidgetDecoration[WrappedWidget]):
|
|
126
141
|
def sizing(self) -> frozenset[Sizing]:
|
|
127
142
|
return frozenset((Sizing.BOX,))
|
|
@@ -286,7 +301,7 @@ class Scrollable(WidgetDecoration[WrappedWidget]):
|
|
|
286
301
|
ow = self._original_widget
|
|
287
302
|
ow_size = self._get_original_widget_size(size)
|
|
288
303
|
|
|
289
|
-
# Remember previous cursor position if possible
|
|
304
|
+
# Remember the previous cursor position if possible
|
|
290
305
|
if hasattr(ow, "get_cursor_coords"):
|
|
291
306
|
self._old_cursor_coords = ow.get_cursor_coords(ow_size)
|
|
292
307
|
|
|
@@ -294,7 +309,7 @@ class Scrollable(WidgetDecoration[WrappedWidget]):
|
|
|
294
309
|
if key is None:
|
|
295
310
|
return None
|
|
296
311
|
|
|
297
|
-
# Handle up/down, page up/down, etc
|
|
312
|
+
# Handle up/down, page up/down, etc.
|
|
298
313
|
command_map = self._command_map
|
|
299
314
|
if command_map[key] == Command.UP:
|
|
300
315
|
self._scroll_action = SCROLL_LINE_UP
|
|
@@ -438,10 +453,10 @@ class Scrollable(WidgetDecoration[WrappedWidget]):
|
|
|
438
453
|
class ScrollBar(WidgetDecoration[WrappedWidget]):
|
|
439
454
|
Symbols = ScrollbarSymbols
|
|
440
455
|
|
|
441
|
-
def sizing(self):
|
|
456
|
+
def sizing(self) -> frozenset[Sizing]:
|
|
442
457
|
return frozenset((Sizing.BOX,))
|
|
443
458
|
|
|
444
|
-
def selectable(self):
|
|
459
|
+
def selectable(self) -> bool:
|
|
445
460
|
return True
|
|
446
461
|
|
|
447
462
|
def __init__(
|
|
@@ -483,30 +498,60 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
|
|
|
483
498
|
) -> Canvas:
|
|
484
499
|
from urwid import canvas
|
|
485
500
|
|
|
501
|
+
def render_no_scrollbar() -> Canvas:
|
|
502
|
+
self._original_widget_size = size
|
|
503
|
+
return ow.render(size, focus)
|
|
504
|
+
|
|
505
|
+
def render_for_scrollbar() -> Canvas:
|
|
506
|
+
self._original_widget_size = ow_size
|
|
507
|
+
return ow.render(ow_size, focus)
|
|
508
|
+
|
|
486
509
|
maxcol, maxrow = size
|
|
487
510
|
|
|
488
|
-
|
|
489
|
-
ow_size = (max(0, maxcol - sb_width), maxrow)
|
|
511
|
+
ow_size = (max(0, maxcol - self._scrollbar_width), maxrow)
|
|
490
512
|
sb_width = maxcol - ow_size[0]
|
|
491
513
|
|
|
492
514
|
ow = self._original_widget
|
|
493
515
|
ow_base = self.scrolling_base_widget
|
|
494
|
-
ow_rows_max = ow_base.rows_max(size, focus)
|
|
495
|
-
if ow_rows_max <= maxrow:
|
|
496
|
-
# Canvas fits without scrolling - no scrollbar needed
|
|
497
|
-
self._original_widget_size = size
|
|
498
|
-
return ow.render(size, focus)
|
|
499
|
-
ow_rows_max = ow_base.rows_max(ow_size, focus)
|
|
500
516
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
517
|
+
# Use hasattr instead of protocol: hasattr will return False in case of getattr raise AttributeError
|
|
518
|
+
# Use __length_hint__ first since it's less resource intensive
|
|
519
|
+
use_relative = (
|
|
520
|
+
isinstance(ow_base, SupportsRelativeScroll)
|
|
521
|
+
and any(hasattr(ow_base, attrib) for attrib in ("__length_hint__", "__len__"))
|
|
522
|
+
and ow_base.require_relative_scroll(size, focus)
|
|
523
|
+
)
|
|
506
524
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
525
|
+
if use_relative:
|
|
526
|
+
# `operator.length_hint` is Protocol (Spec) over class based and can end false-negative on the instance
|
|
527
|
+
# use length_hint-like approach with safe `AttributeError` handling
|
|
528
|
+
ow_len = getattr(ow_base, "__len__", getattr(ow_base, "__length_hint__", lambda: 0))()
|
|
529
|
+
ow_canv = render_for_scrollbar()
|
|
530
|
+
visible_amount = ow_base.get_visible_amount(ow_size, focus)
|
|
531
|
+
pos = ow_base.get_first_visible_pos(ow_size, focus)
|
|
532
|
+
|
|
533
|
+
# in the case of estimated length, it can be smaller than real widget length
|
|
534
|
+
ow_len = max(ow_len, visible_amount, pos)
|
|
535
|
+
posmax = ow_len - visible_amount
|
|
536
|
+
thumb_weight = min(1.0, visible_amount / max(1, ow_len))
|
|
537
|
+
|
|
538
|
+
if ow_len == visible_amount:
|
|
539
|
+
# Corner case: formally all contents indexes should be visible, but this does not mean all rows
|
|
540
|
+
use_relative = False
|
|
541
|
+
|
|
542
|
+
if not use_relative:
|
|
543
|
+
ow_rows_max = ow_base.rows_max(size, focus)
|
|
544
|
+
if ow_rows_max <= maxrow:
|
|
545
|
+
# Canvas fits without scrolling - no scrollbar needed
|
|
546
|
+
return render_no_scrollbar()
|
|
547
|
+
|
|
548
|
+
ow_canv = render_for_scrollbar()
|
|
549
|
+
ow_rows_max = ow_base.rows_max(ow_size, focus)
|
|
550
|
+
pos = ow_base.get_scrollpos(ow_size, focus)
|
|
551
|
+
posmax = ow_rows_max - maxrow
|
|
552
|
+
thumb_weight = min(1.0, maxrow / max(1, ow_rows_max))
|
|
553
|
+
|
|
554
|
+
# Thumb shrinks/grows according to the ratio of <number of visible lines> / <number of total lines>
|
|
510
555
|
thumb_height = max(1, round(thumb_weight * maxrow))
|
|
511
556
|
|
|
512
557
|
# Thumb may only touch top/bottom if the first/last row is visible
|
|
@@ -564,7 +609,7 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
|
|
|
564
609
|
self._invalidate()
|
|
565
610
|
|
|
566
611
|
@property
|
|
567
|
-
def scrolling_base_widget(self) -> SupportsScroll:
|
|
612
|
+
def scrolling_base_widget(self) -> SupportsScroll | SupportsRelativeScroll:
|
|
568
613
|
"""Nearest `original_widget` that is compatible with the scrolling API"""
|
|
569
614
|
|
|
570
615
|
def orig_iter(w: Widget) -> Iterator[Widget]:
|
urwid/widget/treetools.py
CHANGED
|
@@ -43,7 +43,7 @@ from .wimp import SelectableIcon
|
|
|
43
43
|
if typing.TYPE_CHECKING:
|
|
44
44
|
from collections.abc import Hashable, Sequence
|
|
45
45
|
|
|
46
|
-
__all__ = ("
|
|
46
|
+
__all__ = ("ParentNode", "TreeListBox", "TreeNode", "TreeWalker", "TreeWidget", "TreeWidgetError")
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class TreeWidgetError(RuntimeError):
|
|
@@ -85,7 +85,7 @@ class TreeWidget(WidgetWrap[Padding[typing.Union[Text, Columns]]]):
|
|
|
85
85
|
"""Update display widget text for parent widgets"""
|
|
86
86
|
# icon is first element in columns indented widget
|
|
87
87
|
icon = [self.unexpanded_icon, self.expanded_icon][self.expanded]
|
|
88
|
-
self._w.
|
|
88
|
+
self._w.base_widget.contents[0] = (icon, (WHSettings.GIVEN, 1, False))
|
|
89
89
|
|
|
90
90
|
def get_indent_cols(self) -> int:
|
|
91
91
|
return self.indent_cols * self.get_node().get_depth()
|
|
@@ -496,8 +496,8 @@ class TreeListBox(ListBox):
|
|
|
496
496
|
|
|
497
497
|
middle, top, _bottom = self.calculate_visible(size)
|
|
498
498
|
|
|
499
|
-
row_offset, _focus_widget, _focus_pos, _focus_rows, _cursor = middle
|
|
500
|
-
_trim_top, fill_above = top
|
|
499
|
+
row_offset, _focus_widget, _focus_pos, _focus_rows, _cursor = middle # pylint: disable=unpacking-non-sequence
|
|
500
|
+
_trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
|
|
501
501
|
|
|
502
502
|
for _widget, pos, rows in fill_above:
|
|
503
503
|
row_offset -= rows
|
|
@@ -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=Q6B6SJpzx7ArqUrw_2w87t72hs-NzqHnm-ERmJDUGVM,413
|
|
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
|
|
@@ -23,22 +23,22 @@ urwid/display/_win32.py,sha256=hD4hytElpfIv5qxGNTMSa2QeBNByqJDNVpmiiQSj6CM,5401
|
|
|
23
23
|
urwid/display/_win32_raw_display.py,sha256=0PuHEhqJRl8uQmaWSOWceM1aEuolPZ-1MbHYN7s9yRY,9248
|
|
24
24
|
urwid/display/common.py,sha256=_WiwXtt6KULEVLGeZvRIwmNcSfL92BPFv-uhb0_w2d0,39528
|
|
25
25
|
urwid/display/curses.py,sha256=poYvs4iGPzl1jXpi8UUNyrTX2Ap9qxXPVhSu_zE4IuY,22800
|
|
26
|
-
urwid/display/escape.py,sha256=
|
|
26
|
+
urwid/display/escape.py,sha256=rG7x82_S91SRdfKXOEzkawDFtmVk5_KiKIY4Bh2mf7s,17826
|
|
27
27
|
urwid/display/html_fragment.py,sha256=lQRqr-hTrknQyZTtzPDp9zr-TWOT4NcuSsusS-LXIOU,8547
|
|
28
28
|
urwid/display/lcd.py,sha256=qXfuyZcicarrZM-O-ccPFBPjflD3_bLMv3IQzmYI43E,17607
|
|
29
29
|
urwid/display/raw.py,sha256=TSkIEM6KnQHPmmpBkWKdirZOwVXhSV67k7hWmuuR2OY,1125
|
|
30
30
|
urwid/display/web.py,sha256=39o12Cl79Ft669-mIbq_ZGGVzzkSfHb3Ny54mASegec,19250
|
|
31
31
|
urwid/event_loop/__init__.py,sha256=6di4AYD6HbCf6v5p0rZOoteKnM9U5tfk4NKcWMH4FV4,1199
|
|
32
32
|
urwid/event_loop/abstract_loop.py,sha256=6Kkw3KCJ4ndiI2I1P8fPdtHzjuekRxUuvzFOiR0Myok,5494
|
|
33
|
-
urwid/event_loop/asyncio_loop.py,sha256=
|
|
33
|
+
urwid/event_loop/asyncio_loop.py,sha256=9B3redIwvfYzqKSbnxiocb6wx9VXLi5XB08cUJkserE,8471
|
|
34
34
|
urwid/event_loop/glib_loop.py,sha256=GFoLAenoWKm-13rTBKzCF2JdCEryJKpMo25aidZ7BWs,9351
|
|
35
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
|
-
urwid/event_loop/trio_loop.py,sha256=
|
|
38
|
+
urwid/event_loop/trio_loop.py,sha256=46uFQ1O-AM8EaJETCsXzECDNviYMyzOsDKQoJgMHQSk,10468
|
|
39
39
|
urwid/event_loop/twisted_loop.py,sha256=CtpWBzxNp_y7LHejnXIS67B-iboM3irb_MuI_FtXzc0,9219
|
|
40
40
|
urwid/event_loop/zmq_loop.py,sha256=wt4lE0hnDODTVaAMuB5wCSAD5yQ6D9pj8_G_7iNGBUI,9074
|
|
41
|
-
urwid/widget/__init__.py,sha256=
|
|
41
|
+
urwid/widget/__init__.py,sha256=lEFAuQKYnGKS9-dhUggItnnm9Bvbbuk7RAKvzrs8xkI,4683
|
|
42
42
|
urwid/widget/attr_map.py,sha256=L6svBcabtXeSaU2cNrgDv4Nne6QYk-nvVbr88sA4WnY,6205
|
|
43
43
|
urwid/widget/attr_wrap.py,sha256=pJQHVNlwcX5IgpdSmTqYOt63EX-p5hA0mJfXtWXJ6wg,4830
|
|
44
44
|
urwid/widget/bar_graph.py,sha256=Ui2Z-DJ7Try9rkAQ14rK__-oSGfsWncpJH-AxSF00bk,21615
|
|
@@ -53,22 +53,22 @@ urwid/widget/filler.py,sha256=EEnyAawdKXuwf79pErfNuvqsU1SVTutcMUrwWkU4wfo,14665
|
|
|
53
53
|
urwid/widget/frame.py,sha256=AOe4FwjvwcIwrpXqyZkCwSZWwAALNl1XRMAKx6ZXYWs,21834
|
|
54
54
|
urwid/widget/grid_flow.py,sha256=otujeOTWYDr4gwuDikBm9zZd8SUgma9yvQ1hDWI-dGk,21514
|
|
55
55
|
urwid/widget/line_box.py,sha256=V750xiZtkw6_uRXLhNY91ER3pXwwrZstVv_IJUZd_YY,6884
|
|
56
|
-
urwid/widget/listbox.py,sha256=
|
|
57
|
-
urwid/widget/monitored_list.py,sha256=
|
|
56
|
+
urwid/widget/listbox.py,sha256=EaGo13fpt4Oy9V00n27U-2PhOWa7-nmsTgnddKv9GII,74392
|
|
57
|
+
urwid/widget/monitored_list.py,sha256=8lBb8kowLAqKMKByiBZp4jt9PSnXjYAoAjXFXm-7xcg,18773
|
|
58
58
|
urwid/widget/overlay.py,sha256=7EtTHOomIF4xzwYiY7SiMCQZF2IHrmO88YeosFOMFo0,34505
|
|
59
59
|
urwid/widget/padding.py,sha256=tdBJybrKJqR8OLo5DHixn6KZA3tefYlfo9kkqvxYLEc,21252
|
|
60
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
|
-
urwid/widget/scrollable.py,sha256=
|
|
63
|
+
urwid/widget/scrollable.py,sha256=yB3S3k5dOdZ-wrQMlgxQH-1AZONSf5X6Y2accIa9tpk,24279
|
|
64
64
|
urwid/widget/solid_fill.py,sha256=NZRDSRK0lP4r7gXcKDgVaKEoeOcWvtrY5k2aueQEEL4,1260
|
|
65
65
|
urwid/widget/text.py,sha256=jy15hL6rCBoJdZviq2jJ-i9eO6vEcxvzCIVAZs12AUw,12187
|
|
66
|
-
urwid/widget/treetools.py,sha256=
|
|
66
|
+
urwid/widget/treetools.py,sha256=5s3Dnp2PCz4wQccutmdvsTTbAROJMLehXe4moB5POY0,17387
|
|
67
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.10.dist-info/COPYING,sha256=NrbT-keRaUP9X-wxPFhHhJRgR-wTN6eLRA5ZkstZX4k,26434
|
|
71
|
+
urwid-2.6.10.dist-info/METADATA,sha256=o9GKYe-Nt5Hkz7EF_S6E3DXp8CblUs66umXNmAj5-jI,11043
|
|
72
|
+
urwid-2.6.10.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
73
|
+
urwid-2.6.10.dist-info/top_level.txt,sha256=AwxQA43kNkjHbhYELXHBKrQ01X5CR2KnDzU07cVqilY,6
|
|
74
|
+
urwid-2.6.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|