Source code for houdini_core_tools.nodegraph

"""Functions and tools for dealing with the node graph."""

# Future
from __future__ import annotations

# Standard Library
import enum
import functools
from typing import TYPE_CHECKING, ClassVar

# Houdini
import nodegraphtitle

if TYPE_CHECKING:
    from collections.abc import Callable

# Enums


[docs] class NodeGraphTitleLocation(enum.Enum): """Enum for selecting the title location.""" LEFT = "left" RIGHT = "right"
# Classes class _Singleton(type): """Singleton implementation as a metaclass.""" _instances: ClassVar[dict] = {} def __call__(cls, *args, **kwargs): # type: ignore if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls]
[docs] class NodeGraphTitleManager(metaclass=_Singleton): """Manager for setting node graph titles.""" def __init__(self) -> None: # Store references to the original functions. self._original_left = nodegraphtitle.networkEditorTitleLeft self._original_right = nodegraphtitle.networkEditorTitleRight # Non-Public Methods def _set_title( self, location: NodeGraphTitleLocation, value_func: Callable, *, include_default: bool = True, ) -> None: """Set a dynamic title value for the selected title field. Args: location: The title location to modify. value_func: A callable to provide the title value. include_default: Whether to include the default title information. """ original = getattr(self, f"_original_{location.value}") def title_wrapper(*args, **kwargs): # type: ignore value = value_func() title = original(*args, **kwargs) if include_default else "" return f"{value} - {title}" if title else value setattr(nodegraphtitle, f"networkEditorTitle{location.value.title()}", title_wrapper) functools.update_wrapper(title_wrapper, original) # Methods
[docs] def reset_title(self, location: NodeGraphTitleLocation) -> None: """Reset the left title to the default. Args: location: The title location to reset. """ original = getattr(self, f"_original_{location.value}") setattr(nodegraphtitle, f"networkEditorTitle{location.value.title()}", original)
[docs] def set_dynamic_title( self, location: NodeGraphTitleLocation, value_func: Callable, *, include_default: bool = True, ) -> None: """Set a dynamic title value for the selected title field. The value function will be called whenever the node graph is refreshed. Args: location: The title location to modify. value_func: A callable to provide the title value. include_default: Whether to include the default title information. """ self._set_title(location, value_func, include_default=include_default)
[docs] def set_static_title(self, location: NodeGraphTitleLocation, value: str, *, include_default: bool = True) -> None: """Set a static title value for the left title field. Args: location: The title location to modify. value: The value to set. include_default: Whether to include the default title information. """ def value_func(): # type: ignore return value self.set_dynamic_title(location, value_func, include_default=include_default)