Source code for arcade.gui.style

from abc import abstractmethod
from dataclasses import dataclass
from typing import Any, Generic, TypeVar, overload

from arcade.gui.property import DictProperty
from arcade.gui.widgets import UIWidget


[docs] @dataclass class UIStyleBase: """Base class for styles to ensure a general interface and implement additional magic. Support dict like access syntax. A styled widget should own a dataclass, which subclasses this class """ @overload def get(self, key, default: str) -> str: ... @overload def get(self, key, default: Any) -> Any: ...
[docs] def get(self, key, default=None): """Get a value from the style, if not available return default.""" return self[key] if key in self else default
def __contains__(self, item): return hasattr(self, item) def __getitem__(self, item): return getattr(self, item) def __setitem__(self, key, value): setattr(self, key, value)
StyleRef = TypeVar("StyleRef", bound=UIStyleBase)
[docs] class UIStyledWidget(UIWidget, Generic[StyleRef]): """Baseclass for widgets to be styled. A styled widget should own a dataclass, which subclasses UIStyleBase. The style dict should contain the different states of the widget. The widget should implement py:method::`get_current_state()`, which should return the current state of the widget. Args: style: A mapping of states to styles **kwargs: passed to UIWidget """ # TODO detect StyleBase changes, so that style changes can trigger rendering. style = DictProperty[str, StyleRef]() def __init__(self, *, style: dict[str, StyleRef], **kwargs): self.style = style super().__init__(**kwargs)
[docs] @abstractmethod def get_current_state(self) -> str: """ Return the current state of the widget. These should be contained in the style dict. Well known states: - normal - hover - press - disabled """ pass
[docs] def get_current_style(self) -> StyleRef | None: """Return style based on any state of the widget""" return self.style.get(self.get_current_state(), None)