Skip to content

Commit

Permalink
Add annotation for Widget
Browse files Browse the repository at this point in the history
  • Loading branch information
NMertsch committed Jul 23, 2023
1 parent 3824a8f commit 8752aef
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions core/src/toga/widgets/base.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from __future__ import annotations

from builtins import id as identifier
from typing import NoReturn, Iterator, TYPE_CHECKING

from travertino.node import Node

from toga.platform import get_platform_factory
from toga.style import Pack, TogaApplicator

if TYPE_CHECKING:
from toga.app import App
from toga.window import Window


class WidgetRegistry(dict):
# WidgetRegistry is implemented as a subclass of dict, because it provides
Expand All @@ -16,26 +21,26 @@ class WidgetRegistry(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def __setitem__(self, key, value):
def __setitem__(self, key: str, value: Widget) -> NoReturn:
# We do not want to allow setting items directly but to use the "add"
# method instead.
raise RuntimeError("Widgets cannot be directly added to a registry")

def update(self, widgets: list[Widget]):
def update(self, widgets: list[Widget]) -> None:
for widget in widgets:
self.add(widget)

def add(self, widget: Widget):
def add(self, widget: Widget) -> None:
if widget.id in self:
# Prevent from adding the same widget twice
# or adding 2 widgets with the same id
raise KeyError(f"There is already a widget with the id {widget.id!r}")
super().__setitem__(widget.id, widget)

def remove(self, id: str):
def remove(self, id: str) -> None:
del self[id]

def __iter__(self):
def __iter__(self) -> Iterator[Widget]:
return iter(self.values())


Expand All @@ -47,7 +52,7 @@ def __init__(
self,
id: str | None = None,
style=None,
):
) -> None:
"""Create a base Toga widget.
This is an abstract base class; it cannot be instantiated.
Expand All @@ -68,7 +73,7 @@ def __init__(

self.factory = get_platform_factory()

def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}:0x{identifier(self):x}>"

@property
Expand All @@ -80,7 +85,7 @@ def id(self) -> str:
return self._id

@property
def tab_index(self):
def tab_index(self) -> int | None:
"""The position of the widget in the focus chain for the window.
.. note::
Expand All @@ -91,10 +96,10 @@ def tab_index(self):
return self._impl.get_tab_index()

@tab_index.setter
def tab_index(self, tab_index):
def tab_index(self, tab_index: int) -> None:
self._impl.set_tab_index(tab_index)

def add(self, *children: Widget):
def add(self, *children: Widget) -> None:
"""Add the provided widgets as children of this widget.
If a child widget already has a parent, it will be re-parented as a
Expand Down Expand Up @@ -122,7 +127,7 @@ def add(self, *children: Widget):
# Whatever layout we're a part of needs to be refreshed
self.refresh()

def insert(self, index: int, child: Widget):
def insert(self, index: int, child: Widget) -> None:
"""Insert a widget as a child of this widget.
If a child widget already has a parent, it will be re-parented as a
Expand Down Expand Up @@ -151,7 +156,7 @@ def insert(self, index: int, child: Widget):
# Whatever layout we're a part of needs to be refreshed
self.refresh()

def remove(self, *children: Widget):
def remove(self, *children: Widget) -> None:
"""Remove the provided widgets as children of this node.
Any nominated child widget that is not a child of this widget will
Expand All @@ -178,7 +183,7 @@ def remove(self, *children: Widget):
if removed:
self.refresh()

def clear(self):
def clear(self) -> None:
"""Remove all child widgets of this node.
Refreshes the widget after removal if any children were removed.
Expand All @@ -188,7 +193,7 @@ def clear(self):
self.remove(*self.children)

@property
def app(self):
def app(self) -> None:
"""The App to which this widget belongs.
When setting the app for a widget, all children of this widget will be
Expand All @@ -199,7 +204,7 @@ def app(self):
return self._app

@app.setter
def app(self, app):
def app(self, app: App | None) -> None:
# If the widget is already assigned to an app
if self._app:
if self._app == app:
Expand All @@ -219,7 +224,7 @@ def app(self, app):
app.widgets.add(self)

@property
def window(self):
def window(self) -> Window | None:
"""The window to which this widget belongs.
When setting the window for a widget, all children of this widget will be
Expand All @@ -228,7 +233,7 @@ def window(self):
return self._window

@window.setter
def window(self, window):
def window(self, window: Window | None) -> None:
# Remove the widget from the widget registry it is currently a part of
if self.window is not None:
self.window.widgets.remove(self.id)
Expand All @@ -249,15 +254,15 @@ def enabled(self) -> bool:
return self._impl.get_enabled()

@enabled.setter
def enabled(self, value):
def enabled(self, value: bool) -> None:
self._impl.set_enabled(bool(value))

def refresh(self):
def refresh(self) -> None:
self._impl.refresh()

# Refresh the layout
if self._root:
# We're not the root of the node heirarchy;
# We're not the root of the node hierarchy;
# defer the refresh call to the root node.
self._root.refresh()
else:
Expand All @@ -267,11 +272,11 @@ def refresh(self):
super().refresh(self._impl.viewport)
self._impl.viewport.refreshed()

def refresh_sublayouts(self):
def refresh_sublayouts(self) -> None:
for child in self.children:
child.refresh_sublayouts()

def focus(self):
def focus(self) -> None:
"""Give this widget the input focus.
This method is a no-op if the widget can't accept focus. The ability of a widget
Expand Down

0 comments on commit 8752aef

Please sign in to comment.