Skip to content

Commit

Permalink
Do not use deprecated positioning in the code and examples (urwid#869)
Browse files Browse the repository at this point in the history
* Do not use deprecated positioning in the code and examples

Deprecated, but still supported:
* "fixed left"
* "fixed right"
* "fixed top"
* "fixed bottom"

* Address comments: use keyword-based arguments

* Fix doctests: rework `MonitoredList` overrides from `list`

---------

Co-authored-by: Aleksei Stepanov <alekseis@nvidia.com>
  • Loading branch information
penguinolog and Aleksei Stepanov committed Apr 15, 2024
1 parent 6a8698b commit 74a8bc5
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 40 deletions.
4 changes: 2 additions & 2 deletions examples/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def __init__(self, text, height: int | str, width: int | str, body=None) -> None
w = self.frame

# pad area around listbox
w = urwid.Padding(w, ("fixed left", 2), ("fixed right", 2))
w = urwid.Filler(w, ("fixed top", 1), ("fixed bottom", 1))
w = urwid.Padding(w, urwid.LEFT, left=2, right=2)
w = urwid.Filler(w, urwid.TOP, urwid.RELATIVE_100, top=1, bottom=1)
w = urwid.AttrMap(w, "body")

# "shadow" effect
Expand Down
30 changes: 26 additions & 4 deletions examples/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,30 @@ def main_shadow(self, w):
bg = urwid.AttrMap(urwid.SolidFill("▒"), "screen edge")
shadow = urwid.AttrMap(urwid.SolidFill(" "), "main shadow")

bg = urwid.Overlay(shadow, bg, ("fixed left", 3), ("fixed right", 1), ("fixed top", 2), ("fixed bottom", 1))
w = urwid.Overlay(w, bg, ("fixed left", 2), ("fixed right", 3), ("fixed top", 1), ("fixed bottom", 2))
bg = urwid.Overlay(
shadow,
bg,
align=urwid.LEFT,
width=urwid.RELATIVE_100,
valign=urwid.TOP,
height=urwid.RELATIVE_100,
left=3,
right=1,
top=2,
bottom=1,
)
w = urwid.Overlay(
w,
bg,
align=urwid.LEFT,
width=urwid.RELATIVE_100,
valign=urwid.TOP,
height=urwid.RELATIVE_100,
left=2,
right=3,
top=1,
bottom=2,
)
return w

def bar_graph(self, smooth=False):
Expand Down Expand Up @@ -288,10 +310,10 @@ def graph_controls(self):
def main_window(self):
self.graph = self.bar_graph()
self.graph_wrap = urwid.WidgetWrap(self.graph)
vline = urwid.AttrMap(urwid.SolidFill("\u2502"), "line")
vline = urwid.AttrMap(urwid.SolidFill(""), "line")
c = self.graph_controls()
w = urwid.Columns([(urwid.WEIGHT, 2, self.graph_wrap), (1, vline), c], dividechars=1, focus_column=2)
w = urwid.Padding(w, ("fixed left", 1), ("fixed right", 0))
w = urwid.Padding(w, urwid.LEFT, left=1)
w = urwid.AttrMap(w, "body")
w = urwid.LineBox(w)
w = urwid.AttrMap(w, "line")
Expand Down
84 changes: 65 additions & 19 deletions urwid/widget/monitored_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
import warnings

if typing.TYPE_CHECKING:
from collections.abc import Callable, Collection, Iterator
from collections.abc import Callable, Collection, Iterable, Iterator

from typing_extensions import Concatenate, ParamSpec
from typing_extensions import Concatenate, ParamSpec, Self

ArgSpec = ParamSpec("ArgSpec")
Ret = typing.TypeVar("Ret")
Expand Down Expand Up @@ -88,23 +88,69 @@ def __rich_repr__(self) -> Iterator[tuple[str | None, typing.Any] | typing.Any]:
for item in self:
yield None, item

__add__ = _call_modified(list.__add__) # type: ignore[assignment] # magic like old __super__
__delitem__ = _call_modified(list.__delitem__) # type: ignore[assignment] # magic like old __super__

__iadd__ = _call_modified(list.__iadd__) # type: ignore[assignment] # magic like old __super__
__imul__ = _call_modified(list.__imul__) # type: ignore[assignment] # magic like old __super__
__rmul__ = _call_modified(list.__rmul__) # type: ignore[assignment] # magic like old __super__
__setitem__ = _call_modified(list.__setitem__) # type: ignore[assignment] # magic like old __super__

append = _call_modified(list.append) # type: ignore[assignment] # magic like old __super__
extend = _call_modified(list.extend) # type: ignore[assignment] # magic like old __super__
insert = _call_modified(list.insert) # type: ignore[assignment] # magic like old __super__
pop = _call_modified(list.pop) # type: ignore[assignment] # magic like old __super__
remove = _call_modified(list.remove) # type: ignore[assignment] # magic like old __super__
reverse = _call_modified(list.reverse) # type: ignore[assignment] # magic like old __super__
sort = _call_modified(list.sort) # type: ignore[assignment] # magic like old __super__
if hasattr(list, "clear"):
clear = _call_modified(list.clear) # type: ignore[assignment] # magic like old __super__
@_call_modified
def __add__(self, __value: list[_T]) -> Self:
return super().__add__(__value)

@_call_modified
def __delitem__(self, __key: typing.SupportsIndex | slice) -> None:
super().__delitem__(__key)

@_call_modified
def __iadd__(self, __value: Iterable[_T]) -> Self:
return super().__iadd__(__value)

@_call_modified
def __rmul__(self, __value: typing.SupportsIndex) -> Self:
return super().__rmul__(__value)

@_call_modified
def __imul__(self, __value: typing.SupportsIndex) -> Self:
return super().__imul__(__value)

@typing.overload
@_call_modified
def __setitem__(self, __key: typing.SupportsIndex, __value: _T) -> None: ...

@typing.overload
@_call_modified
def __setitem__(self, __key: slice, __value: Iterable[_T]) -> None: ...

@_call_modified
def __setitem__(self, __key: typing.SupportsIndex | slice, __value: _T | Iterable[_T]) -> None:
super().__setitem__(__key, __value)

@_call_modified
def append(self, __object: _T) -> None:
super().append(__object)

@_call_modified
def extend(self, __iterable: Iterable[_T]) -> None:
super().extend(__iterable)

@_call_modified
def pop(self, __index: typing.SupportsIndex = -1) -> _T:
return super().pop(__index)

@_call_modified
def insert(self, __index: typing.SupportsIndex, __object: _T) -> None:
super().insert(__index, __object)

@_call_modified
def remove(self, __value: _T) -> None:
super().remove(__value)

@_call_modified
def reverse(self) -> None:
super().reverse()

@_call_modified
def sort(self, *, key: Callable[[_T], typing.Any] | None = None, reverse: bool = False) -> None:
super().sort(key=key, reverse=reverse)

@_call_modified
def clear(self) -> None:
super().clear()


class MonitoredFocusList(MonitoredList[_T], typing.Generic[_T]):
Expand Down
6 changes: 4 additions & 2 deletions urwid/widget/padding.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ def __init__(
self,
w: WrappedWidget,
align: (
Literal["left", "center", "right"] | Align | tuple[Literal["relative", WHSettings.RELATIVE], int]
Literal["left", "center", "right"]
| Align
| tuple[Literal["relative", WHSettings.RELATIVE, "fixed left", "fixed right"], int]
) = Align.LEFT,
width: (
int
| Literal["pack", "clip", WHSettings.PACK, WHSettings.CLIP]
| tuple[Literal["relative", WHSettings.RELATIVE], int]
| tuple[Literal["relative", WHSettings.RELATIVE, "fixed left", "fixed right"], int]
) = RELATIVE_100,
min_width: int | None = None,
left: int = 0,
Expand Down
29 changes: 16 additions & 13 deletions urwid/widget/popup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from urwid.canvas import CompositeCanvas

from .constants import Sizing
from .constants import Align, Sizing, VAlign
from .overlay import Overlay
from .widget import delegate_to_widget_mixin
from .widget_decoration import WidgetDecoration
Expand Down Expand Up @@ -86,8 +86,7 @@ def render(self, size, focus: bool = False) -> CompositeCanvas | Canvas:


class PopUpTarget(WidgetDecoration[WrappedWidget]):
# FIXME: this whole class is a terrible hack and must be fixed
# when layout and rendering are separated
# FIXME: this whole class is a terrible hack and must be fixed when layout and rendering are separated
_sizing = frozenset((Sizing.BOX,))
_selectable = True

Expand All @@ -105,19 +104,23 @@ def _update_overlay(self, size: tuple[int, int], focus: bool) -> None:
if self._pop_up != w:
self._pop_up = w
self._current_widget = Overlay(
w,
self._original_widget,
("fixed left", left),
overlay_width,
("fixed top", top),
overlay_height,
top_w=w,
bottom_w=self._original_widget,
align=Align.LEFT,
width=overlay_width,
valign=VAlign.TOP,
height=overlay_height,
left=left,
top=top,
)
else:
self._current_widget.set_overlay_parameters(
("fixed left", left),
overlay_width,
("fixed top", top),
overlay_height,
align=Align.LEFT,
width=overlay_width,
valign=VAlign.TOP,
height=overlay_height,
left=left,
top=top,
)
else:
self._pop_up = None
Expand Down

0 comments on commit 74a8bc5

Please sign in to comment.