Source code for jdxi_editor.ui.widgets.controls.registry

"""
Control Registry

Dict-like registry of parameter -> widget, owned by SynthBase (or one per partial).
Supports get(param) with optional name fallback so param identity matches across
partials. Use register(param, widget) or registry[param] = widget; lookup via
registry.get(param) or registry[param].
"""

from typing import Any, Iterator, Protocol, runtime_checkable

from PySide6.QtWidgets import QWidget


@runtime_checkable
[docs] class ControlResolver(Protocol):
[docs] def get(self, param, default: QWidget | None = None) -> QWidget | None: ...
[docs] class ControlRegistry: """Registry of parameter -> control widget. Dict-like; singleton instance shared across all partials."""
[docs] _instance: "ControlRegistry | None" = None
[docs] _initialized: bool = False
def __new__(cls) -> "ControlRegistry": """Singleton pattern: return the same instance on every instantiation.""" if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self) -> None: """Initialize the registry only once.""" if not ControlRegistry._initialized: self._controls: dict[Any, QWidget] = {} ControlRegistry._initialized = True
[docs] def register(self, param: Any, widget: QWidget) -> None: self._controls[param] = widget
[docs] def get(self, param: Any, default: QWidget | None = None) -> QWidget | None: if param in self._controls: return self._controls[param] name = getattr(param, "name", None) if name: for k, w in self._controls.items(): if getattr(k, "name", None) == name: return w return default
[docs] def __setitem__(self, param: Any, widget: QWidget) -> None: self.register(param, widget)
[docs] def __getitem__(self, param: Any) -> QWidget: w = self.get(param) if w is None: raise KeyError(param) return w
[docs] def __contains__(self, param: Any) -> bool: if param in self._controls: return True name = getattr(param, "name", None) if name: for k in self._controls: if getattr(k, "name", None) == name: return True return False
[docs] def __len__(self) -> int: return len(self._controls)
[docs] def __iter__(self) -> Iterator[Any]: return iter(self._controls)
[docs] def items(self) -> Iterator[tuple[Any, QWidget]]: return iter(self._controls.items())
[docs] def keys(self) -> Iterator[Any]: return iter(self._controls.keys())
[docs] def values(self) -> Iterator[QWidget]: return iter(self._controls.values())
[docs] def pop(self, param: Any, default: QWidget | None = None) -> QWidget | None: return self._controls.pop(param, default)
[docs] def update(self, other: Any = (), /, **kwargs: Any) -> None: """Update registry from another mapping (e.g. dict or ControlRegistry) or iterable of (param, widget).""" if hasattr(other, "items"): for k, v in other.items(): self._controls[k] = v else: for k, v in other: self._controls[k] = v for k, v in kwargs.items(): self._controls[k] = v