Source code for simvx.core.clipboard

"""Clipboard support for the SimVX editor.

Provides node copy/paste (serialized via scene helpers) and text clipboard
with optional platform integration (e.g., GLFW ``glfwGetClipboardString``).
"""


from __future__ import annotations

import logging
from collections.abc import Callable
from typing import Any, ClassVar

log = logging.getLogger(__name__)


[docs] class Clipboard: """Singleton-style clipboard accessed entirely through class methods.""" _node_data: ClassVar[dict | None] = None _text: ClassVar[str] = "" _platform_get: ClassVar[Callable[[], str] | None] = None _platform_set: ClassVar[Callable[[str], None] | None] = None # -- node operations ---------------------------------------------------
[docs] @classmethod def copy_node(cls, node: Any) -> None: """Serialize *node* (and its subtree) onto the clipboard.""" from .scene import _serialize_node cls._node_data = _serialize_node(node)
[docs] @classmethod def paste_node(cls, parent: Any | None = None) -> Any | None: """Deserialize the stored node tree. If *parent* is given the new node is added as a child. Returns the new node, or ``None`` when the clipboard is empty. """ if cls._node_data is None: return None from .scene import _deserialize_node node = _deserialize_node(cls._node_data) if parent is not None: parent.add_child(node) return node
[docs] @classmethod def has_node(cls) -> bool: """Return whether serialized node data is available.""" return cls._node_data is not None
# -- text operations ---------------------------------------------------
[docs] @classmethod def copy_text(cls, text: str) -> None: """Store *text* and push to the platform clipboard if available.""" cls._text = text if cls._platform_set is not None: cls._platform_set(text)
[docs] @classmethod def paste_text(cls) -> str: """Return text from the platform clipboard, falling back to internal storage.""" if cls._platform_get is not None: return cls._platform_get() return cls._text
# -- platform integration ----------------------------------------------
[docs] @classmethod def set_platform_clipboard( cls, get_fn: Callable[[], str], set_fn: Callable[[str], None], ) -> None: """Register platform clipboard accessors (called by graphics backend at init).""" cls._platform_get = get_fn cls._platform_set = set_fn
# -- housekeeping ------------------------------------------------------
[docs] @classmethod def clear(cls) -> None: """Clear both node and text clipboard data.""" cls._node_data = None cls._text = ""