urwid 2.6.0.post0__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 +333 -0
- urwid/canvas.py +1413 -0
- urwid/command_map.py +137 -0
- urwid/container.py +59 -0
- urwid/decoration.py +65 -0
- urwid/display/__init__.py +97 -0
- urwid/display/_posix_raw_display.py +413 -0
- urwid/display/_raw_display_base.py +914 -0
- urwid/display/_web.css +12 -0
- urwid/display/_web.js +462 -0
- urwid/display/_win32.py +171 -0
- urwid/display/_win32_raw_display.py +269 -0
- urwid/display/common.py +1219 -0
- urwid/display/curses.py +690 -0
- urwid/display/escape.py +624 -0
- urwid/display/html_fragment.py +251 -0
- urwid/display/lcd.py +518 -0
- urwid/display/raw.py +37 -0
- urwid/display/web.py +636 -0
- urwid/event_loop/__init__.py +55 -0
- urwid/event_loop/abstract_loop.py +175 -0
- urwid/event_loop/asyncio_loop.py +231 -0
- urwid/event_loop/glib_loop.py +294 -0
- urwid/event_loop/main_loop.py +721 -0
- urwid/event_loop/select_loop.py +230 -0
- urwid/event_loop/tornado_loop.py +206 -0
- urwid/event_loop/trio_loop.py +302 -0
- urwid/event_loop/twisted_loop.py +269 -0
- urwid/event_loop/zmq_loop.py +275 -0
- urwid/font.py +695 -0
- urwid/graphics.py +96 -0
- urwid/highlight.css +19 -0
- urwid/listbox.py +1899 -0
- urwid/monitored_list.py +522 -0
- urwid/numedit.py +376 -0
- urwid/signals.py +330 -0
- urwid/split_repr.py +130 -0
- urwid/str_util.py +358 -0
- urwid/text_layout.py +632 -0
- urwid/treetools.py +515 -0
- urwid/util.py +557 -0
- urwid/version.py +16 -0
- urwid/vterm.py +1806 -0
- urwid/widget/__init__.py +181 -0
- urwid/widget/attr_map.py +161 -0
- urwid/widget/attr_wrap.py +140 -0
- urwid/widget/bar_graph.py +649 -0
- urwid/widget/big_text.py +77 -0
- urwid/widget/box_adapter.py +126 -0
- urwid/widget/columns.py +1145 -0
- urwid/widget/constants.py +574 -0
- urwid/widget/container.py +227 -0
- urwid/widget/divider.py +110 -0
- urwid/widget/edit.py +718 -0
- urwid/widget/filler.py +403 -0
- urwid/widget/frame.py +539 -0
- urwid/widget/grid_flow.py +539 -0
- urwid/widget/line_box.py +194 -0
- urwid/widget/overlay.py +829 -0
- urwid/widget/padding.py +597 -0
- urwid/widget/pile.py +971 -0
- urwid/widget/popup.py +170 -0
- urwid/widget/progress_bar.py +141 -0
- urwid/widget/scrollable.py +597 -0
- urwid/widget/solid_fill.py +44 -0
- urwid/widget/text.py +354 -0
- urwid/widget/widget.py +852 -0
- urwid/widget/widget_decoration.py +166 -0
- urwid/widget/wimp.py +792 -0
- urwid/wimp.py +23 -0
- urwid-2.6.0.post0.dist-info/COPYING +504 -0
- urwid-2.6.0.post0.dist-info/METADATA +332 -0
- urwid-2.6.0.post0.dist-info/RECORD +75 -0
- urwid-2.6.0.post0.dist-info/WHEEL +5 -0
- urwid-2.6.0.post0.dist-info/top_level.txt +1 -0
urwid/widget/__init__.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .attr_map import AttrMap, AttrMapError
|
|
4
|
+
from .attr_wrap import AttrWrap
|
|
5
|
+
from .bar_graph import BarGraph, BarGraphError, BarGraphMeta, GraphVScale, scale_bar_values
|
|
6
|
+
from .big_text import BigText
|
|
7
|
+
from .box_adapter import BoxAdapter, BoxAdapterError
|
|
8
|
+
from .columns import Columns, ColumnsError, ColumnsWarning
|
|
9
|
+
from .constants import (
|
|
10
|
+
RELATIVE_100,
|
|
11
|
+
Align,
|
|
12
|
+
Sizing,
|
|
13
|
+
VAlign,
|
|
14
|
+
WHSettings,
|
|
15
|
+
WrapMode,
|
|
16
|
+
normalize_align,
|
|
17
|
+
normalize_height,
|
|
18
|
+
normalize_valign,
|
|
19
|
+
normalize_width,
|
|
20
|
+
simplify_align,
|
|
21
|
+
simplify_height,
|
|
22
|
+
simplify_valign,
|
|
23
|
+
simplify_width,
|
|
24
|
+
)
|
|
25
|
+
from .container import WidgetContainerListContentsMixin, WidgetContainerMixin
|
|
26
|
+
from .divider import Divider
|
|
27
|
+
from .edit import Edit, EditError, IntEdit
|
|
28
|
+
from .filler import Filler, FillerError, calculate_top_bottom_filler
|
|
29
|
+
from .frame import Frame, FrameError
|
|
30
|
+
from .grid_flow import GridFlow, GridFlowError
|
|
31
|
+
from .line_box import LineBox
|
|
32
|
+
from .overlay import Overlay, OverlayError, OverlayWarning
|
|
33
|
+
from .padding import Padding, PaddingError, PaddingWarning, calculate_left_right_padding
|
|
34
|
+
from .pile import Pile, PileError, PileWarning
|
|
35
|
+
from .popup import PopUpLauncher, PopUpTarget
|
|
36
|
+
from .progress_bar import ProgressBar
|
|
37
|
+
from .scrollable import Scrollable, ScrollableError, ScrollBar
|
|
38
|
+
from .solid_fill import SolidFill
|
|
39
|
+
from .text import Text, TextError
|
|
40
|
+
from .widget import (
|
|
41
|
+
BoxWidget,
|
|
42
|
+
FixedWidget,
|
|
43
|
+
FlowWidget,
|
|
44
|
+
Widget,
|
|
45
|
+
WidgetError,
|
|
46
|
+
WidgetMeta,
|
|
47
|
+
WidgetWarning,
|
|
48
|
+
WidgetWrap,
|
|
49
|
+
WidgetWrapError,
|
|
50
|
+
delegate_to_widget_mixin,
|
|
51
|
+
fixed_size,
|
|
52
|
+
nocache_widget_render,
|
|
53
|
+
nocache_widget_render_instance,
|
|
54
|
+
)
|
|
55
|
+
from .widget_decoration import WidgetDecoration, WidgetDisable, WidgetPlaceholder
|
|
56
|
+
from .wimp import Button, CheckBox, CheckBoxError, RadioButton, SelectableIcon
|
|
57
|
+
|
|
58
|
+
__all__ = (
|
|
59
|
+
"ANY",
|
|
60
|
+
"BOTTOM",
|
|
61
|
+
"BOX",
|
|
62
|
+
"CENTER",
|
|
63
|
+
"CLIP",
|
|
64
|
+
"ELLIPSIS",
|
|
65
|
+
"FIXED",
|
|
66
|
+
"FLOW",
|
|
67
|
+
"GIVEN",
|
|
68
|
+
"LEFT",
|
|
69
|
+
"MIDDLE",
|
|
70
|
+
"PACK",
|
|
71
|
+
"RELATIVE",
|
|
72
|
+
"RELATIVE_100",
|
|
73
|
+
"RIGHT",
|
|
74
|
+
"SPACE",
|
|
75
|
+
"TOP",
|
|
76
|
+
"WEIGHT",
|
|
77
|
+
"Align",
|
|
78
|
+
"AttrMap",
|
|
79
|
+
"AttrMapError",
|
|
80
|
+
"AttrWrap",
|
|
81
|
+
"BarGraph",
|
|
82
|
+
"BarGraphError",
|
|
83
|
+
"BarGraphMeta",
|
|
84
|
+
"BigText",
|
|
85
|
+
"BoxAdapter",
|
|
86
|
+
"BoxAdapterError",
|
|
87
|
+
"BoxWidget",
|
|
88
|
+
"Button",
|
|
89
|
+
"CheckBox",
|
|
90
|
+
"CheckBoxError",
|
|
91
|
+
"Columns",
|
|
92
|
+
"ColumnsError",
|
|
93
|
+
"ColumnsWarning",
|
|
94
|
+
"Divider",
|
|
95
|
+
"Edit",
|
|
96
|
+
"EditError",
|
|
97
|
+
"Filler",
|
|
98
|
+
"FillerError",
|
|
99
|
+
"FixedWidget",
|
|
100
|
+
"FlowWidget",
|
|
101
|
+
"Frame",
|
|
102
|
+
"FrameError",
|
|
103
|
+
"GraphVScale",
|
|
104
|
+
"GridFlow",
|
|
105
|
+
"GridFlowError",
|
|
106
|
+
"IntEdit",
|
|
107
|
+
"LineBox",
|
|
108
|
+
"Overlay",
|
|
109
|
+
"OverlayError",
|
|
110
|
+
"OverlayWarning",
|
|
111
|
+
"Padding",
|
|
112
|
+
"PaddingError",
|
|
113
|
+
"PaddingWarning",
|
|
114
|
+
"Pile",
|
|
115
|
+
"PileError",
|
|
116
|
+
"PileWarning",
|
|
117
|
+
"PopUpLauncher",
|
|
118
|
+
"PopUpTarget",
|
|
119
|
+
"ProgressBar",
|
|
120
|
+
"RadioButton",
|
|
121
|
+
"ScrollBar",
|
|
122
|
+
"Scrollable",
|
|
123
|
+
"ScrollableError",
|
|
124
|
+
"SelectableIcon",
|
|
125
|
+
"Sizing",
|
|
126
|
+
"SolidFill",
|
|
127
|
+
"Text",
|
|
128
|
+
"TextError",
|
|
129
|
+
"VAlign",
|
|
130
|
+
"WHSettings",
|
|
131
|
+
"Widget",
|
|
132
|
+
"WidgetContainerListContentsMixin",
|
|
133
|
+
"WidgetContainerMixin",
|
|
134
|
+
"WidgetDecoration",
|
|
135
|
+
"WidgetDisable",
|
|
136
|
+
"WidgetError",
|
|
137
|
+
"WidgetMeta",
|
|
138
|
+
"WidgetPlaceholder",
|
|
139
|
+
"WidgetWarning",
|
|
140
|
+
"WidgetWrap",
|
|
141
|
+
"WidgetWrapError",
|
|
142
|
+
"WrapMode",
|
|
143
|
+
"calculate_left_right_padding",
|
|
144
|
+
"calculate_top_bottom_filler",
|
|
145
|
+
"delegate_to_widget_mixin",
|
|
146
|
+
"fixed_size",
|
|
147
|
+
"nocache_widget_render",
|
|
148
|
+
"nocache_widget_render_instance",
|
|
149
|
+
"normalize_align",
|
|
150
|
+
"normalize_height",
|
|
151
|
+
"normalize_valign",
|
|
152
|
+
"normalize_width",
|
|
153
|
+
"scale_bar_values",
|
|
154
|
+
"simplify_align",
|
|
155
|
+
"simplify_height",
|
|
156
|
+
"simplify_valign",
|
|
157
|
+
"simplify_width",
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Backward compatibility
|
|
161
|
+
FLOW = Sizing.FLOW
|
|
162
|
+
BOX = Sizing.BOX
|
|
163
|
+
FIXED = Sizing.FIXED
|
|
164
|
+
|
|
165
|
+
LEFT = Align.LEFT
|
|
166
|
+
RIGHT = Align.RIGHT
|
|
167
|
+
CENTER = Align.CENTER
|
|
168
|
+
|
|
169
|
+
TOP = VAlign.TOP
|
|
170
|
+
MIDDLE = VAlign.MIDDLE
|
|
171
|
+
BOTTOM = VAlign.BOTTOM
|
|
172
|
+
|
|
173
|
+
SPACE = WrapMode.SPACE
|
|
174
|
+
ANY = WrapMode.ANY
|
|
175
|
+
CLIP = WrapMode.CLIP
|
|
176
|
+
ELLIPSIS = WrapMode.ELLIPSIS
|
|
177
|
+
|
|
178
|
+
PACK = WHSettings.PACK
|
|
179
|
+
GIVEN = WHSettings.GIVEN
|
|
180
|
+
RELATIVE = WHSettings.RELATIVE
|
|
181
|
+
WEIGHT = WHSettings.WEIGHT
|
urwid/widget/attr_map.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from collections.abc import Hashable, Mapping
|
|
5
|
+
|
|
6
|
+
from urwid.canvas import CompositeCanvas
|
|
7
|
+
|
|
8
|
+
from .widget import WidgetError, delegate_to_widget_mixin
|
|
9
|
+
from .widget_decoration import WidgetDecoration
|
|
10
|
+
|
|
11
|
+
WrappedWidget = typing.TypeVar("WrappedWidget")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AttrMapError(WidgetError):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AttrMap(delegate_to_widget_mixin("_original_widget"), WidgetDecoration[WrappedWidget]):
|
|
19
|
+
"""
|
|
20
|
+
AttrMap is a decoration that maps one set of attributes to another.
|
|
21
|
+
This object will pass all function calls and variable references to the
|
|
22
|
+
wrapped widget.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
w: WrappedWidget,
|
|
28
|
+
attr_map: Hashable | Mapping[Hashable | None, Hashable] | None,
|
|
29
|
+
focus_map: Hashable | Mapping[Hashable | None, Hashable] | None = None,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""
|
|
32
|
+
:param w: widget to wrap (stored as self.original_widget)
|
|
33
|
+
:type w: widget
|
|
34
|
+
|
|
35
|
+
:param attr_map: attribute to apply to *w*, or dict of old display
|
|
36
|
+
attribute: new display attribute mappings
|
|
37
|
+
:type attr_map: display attribute or dict
|
|
38
|
+
|
|
39
|
+
:param focus_map: attribute to apply when in focus or dict of
|
|
40
|
+
old display attribute: new display attribute mappings;
|
|
41
|
+
if ``None`` use *attr*
|
|
42
|
+
:type focus_map: display attribute or dict
|
|
43
|
+
|
|
44
|
+
>>> from urwid import Divider, Edit, Text
|
|
45
|
+
>>> AttrMap(Divider(u"!"), 'bright')
|
|
46
|
+
<AttrMap flow widget <Divider flow widget '!'> attr_map={None: 'bright'}>
|
|
47
|
+
>>> AttrMap(Edit(), 'notfocus', 'focus').attr_map
|
|
48
|
+
{None: 'notfocus'}
|
|
49
|
+
>>> AttrMap(Edit(), 'notfocus', 'focus').focus_map
|
|
50
|
+
{None: 'focus'}
|
|
51
|
+
>>> size = (5,)
|
|
52
|
+
>>> am = AttrMap(Text(u"hi"), 'greeting', 'fgreet')
|
|
53
|
+
>>> next(am.render(size, focus=False).content()) # ... = b in Python 3
|
|
54
|
+
[('greeting', None, ...'hi ')]
|
|
55
|
+
>>> next(am.render(size, focus=True).content())
|
|
56
|
+
[('fgreet', None, ...'hi ')]
|
|
57
|
+
>>> am2 = AttrMap(Text(('word', u"hi")), {'word':'greeting', None:'bg'})
|
|
58
|
+
>>> am2
|
|
59
|
+
<AttrMap fixed/flow widget <Text fixed/flow widget 'hi'> attr_map={'word': 'greeting', None: 'bg'}>
|
|
60
|
+
>>> next(am2.render(size).content())
|
|
61
|
+
[('greeting', None, ...'hi'), ('bg', None, ...' ')]
|
|
62
|
+
"""
|
|
63
|
+
super().__init__(w)
|
|
64
|
+
|
|
65
|
+
if isinstance(attr_map, Mapping):
|
|
66
|
+
self.attr_map = dict(attr_map)
|
|
67
|
+
else:
|
|
68
|
+
self.attr_map = {None: attr_map}
|
|
69
|
+
|
|
70
|
+
if isinstance(focus_map, Mapping):
|
|
71
|
+
self.focus_map = dict(focus_map)
|
|
72
|
+
elif focus_map is None:
|
|
73
|
+
self.focus_map = focus_map
|
|
74
|
+
else:
|
|
75
|
+
self.focus_map = {None: focus_map}
|
|
76
|
+
|
|
77
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
78
|
+
# only include the focus_attr when it takes effect (not None)
|
|
79
|
+
d = {**super()._repr_attrs(), "attr_map": self._attr_map}
|
|
80
|
+
if self._focus_map is not None:
|
|
81
|
+
d["focus_map"] = self._focus_map
|
|
82
|
+
return d
|
|
83
|
+
|
|
84
|
+
def get_attr_map(self) -> dict[Hashable | None, Hashable]:
|
|
85
|
+
# make a copy so ours is not accidentally modified
|
|
86
|
+
# FIXME: a dictionary that detects modifications would be better
|
|
87
|
+
return dict(self._attr_map)
|
|
88
|
+
|
|
89
|
+
def set_attr_map(self, attr_map: dict[Hashable | None, Hashable] | None) -> None:
|
|
90
|
+
"""
|
|
91
|
+
Set the attribute mapping dictionary {from_attr: to_attr, ...}
|
|
92
|
+
|
|
93
|
+
Note this function does not accept a single attribute the way the
|
|
94
|
+
constructor does. You must specify {None: attribute} instead.
|
|
95
|
+
|
|
96
|
+
>>> from urwid import Text
|
|
97
|
+
>>> w = AttrMap(Text(u"hi"), None)
|
|
98
|
+
>>> w.set_attr_map({'a':'b'})
|
|
99
|
+
>>> w
|
|
100
|
+
<AttrMap fixed/flow widget <Text fixed/flow widget 'hi'> attr_map={'a': 'b'}>
|
|
101
|
+
"""
|
|
102
|
+
for from_attr, to_attr in attr_map.items():
|
|
103
|
+
if not isinstance(from_attr, Hashable) or not isinstance(to_attr, Hashable):
|
|
104
|
+
raise AttrMapError(
|
|
105
|
+
f"{from_attr!r}:{to_attr!r} attribute mapping is invalid. Attributes must be hashable"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
self._attr_map = attr_map
|
|
109
|
+
self._invalidate()
|
|
110
|
+
|
|
111
|
+
attr_map = property(get_attr_map, set_attr_map)
|
|
112
|
+
|
|
113
|
+
def get_focus_map(self) -> dict[Hashable | None, Hashable] | None:
|
|
114
|
+
# make a copy so ours is not accidentally modified
|
|
115
|
+
# FIXME: a dictionary that detects modifications would be better
|
|
116
|
+
if self._focus_map:
|
|
117
|
+
return dict(self._focus_map)
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
def set_focus_map(self, focus_map: dict[Hashable | None, Hashable] | None) -> None:
|
|
121
|
+
"""
|
|
122
|
+
Set the focus attribute mapping dictionary
|
|
123
|
+
{from_attr: to_attr, ...}
|
|
124
|
+
|
|
125
|
+
If None this widget will use the attr mapping instead (no change
|
|
126
|
+
when in focus).
|
|
127
|
+
|
|
128
|
+
Note this function does not accept a single attribute the way the
|
|
129
|
+
constructor does. You must specify {None: attribute} instead.
|
|
130
|
+
|
|
131
|
+
>>> from urwid import Text
|
|
132
|
+
>>> w = AttrMap(Text(u"hi"), {})
|
|
133
|
+
>>> w.set_focus_map({'a':'b'})
|
|
134
|
+
>>> w
|
|
135
|
+
<AttrMap fixed/flow widget <Text fixed/flow widget 'hi'> attr_map={} focus_map={'a': 'b'}>
|
|
136
|
+
>>> w.set_focus_map(None)
|
|
137
|
+
>>> w
|
|
138
|
+
<AttrMap fixed/flow widget <Text fixed/flow widget 'hi'> attr_map={}>
|
|
139
|
+
"""
|
|
140
|
+
if focus_map is not None:
|
|
141
|
+
for from_attr, to_attr in focus_map.items():
|
|
142
|
+
if not isinstance(from_attr, Hashable) or not isinstance(to_attr, Hashable):
|
|
143
|
+
raise AttrMapError(
|
|
144
|
+
f"{from_attr!r}:{to_attr!r} attribute mapping is invalid. Attributes must be hashable"
|
|
145
|
+
)
|
|
146
|
+
self._focus_map = focus_map
|
|
147
|
+
self._invalidate()
|
|
148
|
+
|
|
149
|
+
focus_map = property(get_focus_map, set_focus_map)
|
|
150
|
+
|
|
151
|
+
def render(self, size, focus: bool = False) -> CompositeCanvas:
|
|
152
|
+
"""
|
|
153
|
+
Render wrapped widget and apply attribute. Return canvas.
|
|
154
|
+
"""
|
|
155
|
+
attr_map = self._attr_map
|
|
156
|
+
if focus and self._focus_map is not None:
|
|
157
|
+
attr_map = self._focus_map
|
|
158
|
+
canv = self._original_widget.render(size, focus=focus)
|
|
159
|
+
canv = CompositeCanvas(canv)
|
|
160
|
+
canv.fill_attr_apply(attr_map)
|
|
161
|
+
return canv
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from .attr_map import AttrMap
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from .constants import Sizing
|
|
10
|
+
from .widget import Widget
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AttrWrap(AttrMap):
|
|
14
|
+
def __init__(self, w: Widget, attr, focus_attr=None):
|
|
15
|
+
"""
|
|
16
|
+
w -- widget to wrap (stored as self.original_widget)
|
|
17
|
+
attr -- attribute to apply to w
|
|
18
|
+
focus_attr -- attribute to apply when in focus, if None use attr
|
|
19
|
+
|
|
20
|
+
This widget is a special case of the new AttrMap widget, and it
|
|
21
|
+
will pass all function calls and variable references to the wrapped
|
|
22
|
+
widget. This class is maintained for backwards compatibility only,
|
|
23
|
+
new code should use AttrMap instead.
|
|
24
|
+
|
|
25
|
+
>>> from urwid import Divider, Edit, Text
|
|
26
|
+
>>> AttrWrap(Divider(u"!"), 'bright')
|
|
27
|
+
<AttrWrap flow widget <Divider flow widget '!'> attr='bright'>
|
|
28
|
+
>>> AttrWrap(Edit(), 'notfocus', 'focus')
|
|
29
|
+
<AttrWrap selectable flow widget <Edit selectable flow widget '' edit_pos=0> attr='notfocus' focus_attr='focus'>
|
|
30
|
+
>>> size = (5,)
|
|
31
|
+
>>> aw = AttrWrap(Text(u"hi"), 'greeting', 'fgreet')
|
|
32
|
+
>>> next(aw.render(size, focus=False).content())
|
|
33
|
+
[('greeting', None, ...'hi ')]
|
|
34
|
+
>>> next(aw.render(size, focus=True).content())
|
|
35
|
+
[('fgreet', None, ...'hi ')]
|
|
36
|
+
"""
|
|
37
|
+
warnings.warn(
|
|
38
|
+
"AttrWrap is maintained for backwards compatibility only, new code should use AttrMap instead.",
|
|
39
|
+
PendingDeprecationWarning,
|
|
40
|
+
stacklevel=2,
|
|
41
|
+
)
|
|
42
|
+
super().__init__(w, attr, focus_attr)
|
|
43
|
+
|
|
44
|
+
def _repr_attrs(self) -> dict[str, typing.Any]:
|
|
45
|
+
# only include the focus_attr when it takes effect (not None)
|
|
46
|
+
d = {**super()._repr_attrs(), "attr": self.attr}
|
|
47
|
+
del d["attr_map"]
|
|
48
|
+
if "focus_map" in d:
|
|
49
|
+
del d["focus_map"]
|
|
50
|
+
if self.focus_attr is not None:
|
|
51
|
+
d["focus_attr"] = self.focus_attr
|
|
52
|
+
return d
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def w(self) -> Widget:
|
|
56
|
+
"""backwards compatibility, widget used to be stored as w"""
|
|
57
|
+
warnings.warn(
|
|
58
|
+
"backwards compatibility, widget used to be stored as original_widget",
|
|
59
|
+
PendingDeprecationWarning,
|
|
60
|
+
stacklevel=2,
|
|
61
|
+
)
|
|
62
|
+
return self.original_widget
|
|
63
|
+
|
|
64
|
+
@w.setter
|
|
65
|
+
def w(self, new_widget: Widget) -> None:
|
|
66
|
+
warnings.warn(
|
|
67
|
+
"backwards compatibility, widget used to be stored as original_widget",
|
|
68
|
+
PendingDeprecationWarning,
|
|
69
|
+
stacklevel=2,
|
|
70
|
+
)
|
|
71
|
+
self.original_widget = new_widget
|
|
72
|
+
|
|
73
|
+
def get_w(self):
|
|
74
|
+
warnings.warn(
|
|
75
|
+
"backwards compatibility, widget used to be stored as original_widget",
|
|
76
|
+
DeprecationWarning,
|
|
77
|
+
stacklevel=2,
|
|
78
|
+
)
|
|
79
|
+
return self.original_widget
|
|
80
|
+
|
|
81
|
+
def set_w(self, new_widget: Widget) -> None:
|
|
82
|
+
warnings.warn(
|
|
83
|
+
"backwards compatibility, widget used to be stored as original_widget",
|
|
84
|
+
DeprecationWarning,
|
|
85
|
+
stacklevel=2,
|
|
86
|
+
)
|
|
87
|
+
self.original_widget = new_widget
|
|
88
|
+
|
|
89
|
+
def get_attr(self):
|
|
90
|
+
return self.attr_map[None]
|
|
91
|
+
|
|
92
|
+
def set_attr(self, attr):
|
|
93
|
+
"""
|
|
94
|
+
Set the attribute to apply to the wrapped widget
|
|
95
|
+
|
|
96
|
+
>> w = AttrWrap(Divider("-"), None)
|
|
97
|
+
>> w.set_attr('new_attr')
|
|
98
|
+
>> w
|
|
99
|
+
<AttrWrap flow widget <Divider flow widget '-'> attr='new_attr'>
|
|
100
|
+
"""
|
|
101
|
+
self.set_attr_map({None: attr})
|
|
102
|
+
|
|
103
|
+
attr = property(get_attr, set_attr)
|
|
104
|
+
|
|
105
|
+
def get_focus_attr(self):
|
|
106
|
+
focus_map = self.focus_map
|
|
107
|
+
if focus_map:
|
|
108
|
+
return focus_map[None]
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
def set_focus_attr(self, focus_attr):
|
|
112
|
+
"""
|
|
113
|
+
Set the attribute to apply to the wapped widget when it is in
|
|
114
|
+
focus
|
|
115
|
+
|
|
116
|
+
If None this widget will use the attr instead (no change when in
|
|
117
|
+
focus).
|
|
118
|
+
|
|
119
|
+
>> w = AttrWrap(Divider("-"), 'old')
|
|
120
|
+
>> w.set_focus_attr('new_attr')
|
|
121
|
+
>> w
|
|
122
|
+
<AttrWrap flow widget <Divider flow widget '-'> attr='old' focus_attr='new_attr'>
|
|
123
|
+
>> w.set_focus_attr(None)
|
|
124
|
+
>> w
|
|
125
|
+
<AttrWrap flow widget <Divider flow widget '-'> attr='old'>
|
|
126
|
+
"""
|
|
127
|
+
self.set_focus_map({None: focus_attr})
|
|
128
|
+
|
|
129
|
+
focus_attr = property(get_focus_attr, set_focus_attr)
|
|
130
|
+
|
|
131
|
+
def __getattr__(self, name: str):
|
|
132
|
+
"""
|
|
133
|
+
Call getattr on wrapped widget. This has been the longstanding
|
|
134
|
+
behaviour of AttrWrap, but is discouraged. New code should be
|
|
135
|
+
using AttrMap and .base_widget or .original_widget instead.
|
|
136
|
+
"""
|
|
137
|
+
return getattr(self._original_widget, name)
|
|
138
|
+
|
|
139
|
+
def sizing(self) -> frozenset[Sizing]:
|
|
140
|
+
return self._original_widget.sizing()
|