mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #1086 from davep/drop-prenamed-mount
Drop support for anonymous vs named widget mounting
This commit is contained in:
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## [0.4.0] - Unreleased
|
## [0.4.0] - Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Dropped support for mounting "named" and "anonymous" widgets via
|
||||||
|
`App.mount` and `Widget.mount`. Both methods now simply take one or more
|
||||||
|
widgets as positional arguments.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `init` param to reactive.watch
|
- Added `init` param to reactive.watch
|
||||||
|
|||||||
@@ -822,27 +822,27 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
self._require_stylesheet_update.add(self.screen if node is None else node)
|
self._require_stylesheet_update.add(self.screen if node is None else node)
|
||||||
self.check_idle()
|
self.check_idle()
|
||||||
|
|
||||||
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount:
|
def mount(self, *widgets: Widget) -> AwaitMount:
|
||||||
"""Mount widgets. Widgets specified as positional args, or keywords args. If supplied
|
"""Mount the given widgets.
|
||||||
as keyword args they will be assigned an id of the key.
|
|
||||||
|
Args:
|
||||||
|
*widgets (Widget): The widget(s) to mount.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AwaitMount: An awaitable object that waits for widgets to be mounted.
|
AwaitMount: An awaitable object that waits for widgets to be mounted.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
mounted_widgets = self._register(self.screen, *anon_widgets, **widgets)
|
return AwaitMount(self._register(self.screen, *widgets))
|
||||||
return AwaitMount(mounted_widgets)
|
|
||||||
|
|
||||||
def mount_all(self, widgets: Iterable[Widget]) -> AwaitMount:
|
def mount_all(self, widgets: Iterable[Widget]) -> AwaitMount:
|
||||||
"""Mount widgets from an iterable.
|
"""Mount widgets from an iterable.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
widgets (Iterable[Widget]): An iterable of widgets.
|
widgets (Iterable[Widget]): An iterable of widgets.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AwaitMount: An awaitable object that waits for widgets to be mounted.
|
||||||
"""
|
"""
|
||||||
mounted_widgets = list(widgets)
|
return self.mount(*widgets)
|
||||||
for widget in mounted_widgets:
|
|
||||||
self._register(self.screen, widget)
|
|
||||||
return AwaitMount(mounted_widgets)
|
|
||||||
|
|
||||||
def is_screen_installed(self, screen: Screen | str) -> bool:
|
def is_screen_installed(self, screen: Screen | str) -> bool:
|
||||||
"""Check if a given screen has been installed.
|
"""Check if a given screen has been installed.
|
||||||
@@ -1300,37 +1300,33 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _register(
|
def _register(self, parent: DOMNode, *widgets: Widget) -> list[Widget]:
|
||||||
self, parent: DOMNode, *anon_widgets: Widget, **widgets: Widget
|
|
||||||
) -> list[Widget]:
|
|
||||||
"""Register widget(s) so they may receive events.
|
"""Register widget(s) so they may receive events.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
parent (Widget): Parent Widget.
|
parent (DOMNode): Parent node.
|
||||||
|
*widgets: The widget(s) to register.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[Widget]: List of modified widgets.
|
list[Widget]: List of modified widgets.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not anon_widgets and not widgets:
|
|
||||||
|
if not widgets:
|
||||||
return []
|
return []
|
||||||
name_widgets: list[tuple[str | None, Widget]]
|
|
||||||
name_widgets = [*((None, widget) for widget in anon_widgets), *widgets.items()]
|
|
||||||
apply_stylesheet = self.stylesheet.apply
|
apply_stylesheet = self.stylesheet.apply
|
||||||
|
|
||||||
for widget_id, widget in name_widgets:
|
for widget in widgets:
|
||||||
if not isinstance(widget, Widget):
|
if not isinstance(widget, Widget):
|
||||||
raise AppError(f"Can't register {widget!r}; expected a Widget instance")
|
raise AppError(f"Can't register {widget!r}; expected a Widget instance")
|
||||||
if widget not in self._registry:
|
if widget not in self._registry:
|
||||||
if widget_id is not None:
|
|
||||||
widget.id = widget_id
|
|
||||||
self._register_child(parent, widget)
|
self._register_child(parent, widget)
|
||||||
if widget.children:
|
if widget.children:
|
||||||
self._register(widget, *widget.children)
|
self._register(widget, *widget.children)
|
||||||
apply_stylesheet(widget)
|
apply_stylesheet(widget)
|
||||||
|
|
||||||
registered_widgets = [widget for _, widget in name_widgets]
|
return list(widgets)
|
||||||
return registered_widgets
|
|
||||||
|
|
||||||
def _unregister(self, widget: Widget) -> None:
|
def _unregister(self, widget: Widget) -> None:
|
||||||
"""Unregister a widget.
|
"""Unregister a widget.
|
||||||
|
|||||||
@@ -609,21 +609,16 @@ class DOMNode(MessagePump):
|
|||||||
self.children._append(node)
|
self.children._append(node)
|
||||||
node._attach(self)
|
node._attach(self)
|
||||||
|
|
||||||
def _add_children(self, *nodes: Widget, **named_nodes: Widget) -> None:
|
def _add_children(self, *nodes: Widget) -> None:
|
||||||
"""Add multiple children to this node.
|
"""Add multiple children to this node.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*nodes (DOMNode): Positional args should be new DOM nodes.
|
*nodes (DOMNode): Positional args should be new DOM nodes.
|
||||||
**named_nodes (DOMNode): Keyword args will be assigned the argument name as an ID.
|
|
||||||
"""
|
"""
|
||||||
_append = self.children._append
|
_append = self.children._append
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
node._attach(self)
|
node._attach(self)
|
||||||
_append(node)
|
_append(node)
|
||||||
for node_id, node in named_nodes.items():
|
|
||||||
node._attach(self)
|
|
||||||
_append(node)
|
|
||||||
node.id = node_id
|
|
||||||
|
|
||||||
WalkType = TypeVar("WalkType")
|
WalkType = TypeVar("WalkType")
|
||||||
|
|
||||||
|
|||||||
@@ -375,23 +375,16 @@ class Widget(DOMNode):
|
|||||||
if self._scrollbar_corner is not None:
|
if self._scrollbar_corner is not None:
|
||||||
yield self._scrollbar_corner
|
yield self._scrollbar_corner
|
||||||
|
|
||||||
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount:
|
def mount(self, *widgets: Widget) -> AwaitMount:
|
||||||
"""Mount child widgets (making this widget a container).
|
"""Mount child widgets (making this widget a container).
|
||||||
|
|
||||||
Widgets may be passed as positional arguments or keyword arguments. If keyword arguments,
|
Args:
|
||||||
the keys will be set as the Widget's id.
|
*widgets (Widget): The widget(s) to mount.
|
||||||
|
|
||||||
Example:
|
|
||||||
```python
|
|
||||||
self.mount(Static("hello"), header=Header())
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AwaitMount: An awaitable object that waits for widgets to be mounted.
|
AwaitMount: An awaitable object that waits for widgets to be mounted.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
mounted_widgets = self.app._register(self, *anon_widgets, **widgets)
|
return AwaitMount(self.app._register(self, *widgets))
|
||||||
return AwaitMount(mounted_widgets)
|
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""Called by Textual to create child widgets.
|
"""Called by Textual to create child widgets.
|
||||||
|
|||||||
Reference in New Issue
Block a user