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 ----------------------------------------------
# -- housekeeping ------------------------------------------------------
[docs]
@classmethod
def clear(cls) -> None:
"""Clear both node and text clipboard data."""
cls._node_data = None
cls._text = ""