oscillode/oscillode/registration.py

168 lines
4.7 KiB
Python

# oscillode
# Copyright (C) 2024 oscillode Project Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manages the registration of Blender classes, including delayed registrations that require access to Python dependencies.
Attributes:
_ADDON_KEYMAP: Addon-specific keymap used to register operator hotkeys.
REG__CLASSES: Currently registered Blender classes.
_REGISTERED_HOTKEYS: Currently registered Blender keymap items.
"""
import bpy
from . import contracts as ct
from .utils import logger
log = logger.get(__name__)
####################
# - Globals
####################
_REGISTERED_CLASSES: list[ct.BLClass] = []
_ADDON_KEYMAP: bpy.types.KeyMap | None = None
_REGISTERED_HOTKEYS: list[ct.BLKeymapItem] = []
_REGISTERED_HANDLERS: ct.BLHandlers | None = None
####################
# - Class Registration
####################
def register_classes(bl_register: list[ct.BLClass]) -> None:
"""Registers a list of Blender classes.
Parameters:
bl_register: List of Blender classes to register.
"""
log.info('Registering %s Classes', len(bl_register))
for cls in bl_register:
if cls.bl_idname in _REGISTERED_CLASSES:
msg = f'Skipping register of {cls.bl_idname}'
log.info(msg)
continue
log.debug(
'Registering Class %s',
repr(cls),
)
bpy.utils.register_class(cls)
_REGISTERED_CLASSES.append(cls)
def unregister_classes() -> None:
"""Unregisters all previously registered Blender classes."""
log.info('Unregistering %s Classes', len(_REGISTERED_CLASSES))
for cls in reversed(_REGISTERED_CLASSES):
log.debug(
'Unregistering Class %s',
repr(cls),
)
bpy.utils.unregister_class(cls)
_REGISTERED_CLASSES.clear()
####################
# - Handler Registration
####################
def register_handlers(bl_handlers: ct.BLHandlers) -> None:
"""Register the given Blender handlers."""
global _REGISTERED_HANDLERS # noqa: PLW0603
log.info('Registering BLHandlers') ## TODO: More information
if _REGISTERED_HANDLERS is None:
bl_handlers.register()
_REGISTERED_HANDLERS = bl_handlers
msg = 'There are already BLHandlers registered; they must be unregistered before a new set can be registered.'
raise ValueError(msg)
def unregister_handlers() -> None:
"""Unregister this addon's registered Blender handlers."""
global _REGISTERED_HANDLERS # noqa: PLW0603
log.info('Unregistering BLHandlers') ## TODO: More information
if _REGISTERED_HANDLERS is not None:
_REGISTERED_HANDLERS.register()
_REGISTERED_HANDLERS = None
msg = 'There are no BLHandlers registered; therefore, there is nothing to register.'
raise ValueError(msg)
####################
# - Keymap Registration
####################
def register_hotkeys(hotkey_defs: list[dict]) -> None:
"""Registers a list of Blender hotkey definitions.
Parameters:
hotkey_defs: List of Blender hotkey definitions to register.
"""
# Lazy-Load BL_NODE_KEYMAP
global _ADDON_KEYMAP # noqa: PLW0603
if _ADDON_KEYMAP is None:
_ADDON_KEYMAP = bpy.context.window_manager.keyconfigs.addon.keymaps.new(
name='Node Editor',
space_type='NODE_EDITOR',
)
log.info(
'Registered Addon Keymap (Base for Keymap Items): %s',
str(_ADDON_KEYMAP),
)
# Register Keymaps
log.info('Registering %s Keymap Items', len(hotkey_defs))
for keymap_item_def in hotkey_defs:
keymap_item = _ADDON_KEYMAP.keymap_items.new(
*keymap_item_def['_'],
ctrl=keymap_item_def['ctrl'],
shift=keymap_item_def['shift'],
alt=keymap_item_def['alt'],
)
log.debug(
'Registered Keymap Item %s with spec %s',
repr(keymap_item),
keymap_item_def,
)
_REGISTERED_HOTKEYS.append(keymap_item)
def unregister_hotkeys() -> None:
"""Unregisters all Blender hotkeys associated with the addon."""
global _ADDON_KEYMAP # noqa: PLW0603
# Unregister Keymaps
log.info('Unregistering %s Keymap Items', len(_REGISTERED_HOTKEYS))
for keymap_item in reversed(_REGISTERED_HOTKEYS):
log.debug(
'Unregistered Keymap Item %s',
repr(keymap_item),
)
_ADDON_KEYMAP.keymap_items.remove(keymap_item)
# Lazy-Unload BL_NODE_KEYMAP
if _ADDON_KEYMAP is not None:
log.info(
'Unregistered Keymap %s',
repr(_ADDON_KEYMAP),
)
_REGISTERED_HOTKEYS.clear()
_ADDON_KEYMAP = None