fix: Registration of keymaps and associated errors.
parent
55235c7032
commit
383f7d9bfd
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
# from . import node_trees, operators, preferences, registration
|
# from . import node_trees
|
||||||
from . import assets, preferences, registration
|
from . import assets, operators, preferences, registration
|
||||||
from . import contracts as ct
|
from . import contracts as ct
|
||||||
from .utils import logger
|
from .utils import logger
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ log = logger.get(__name__)
|
||||||
# - Load and Register Addon
|
# - Load and Register Addon
|
||||||
####################
|
####################
|
||||||
BL_REGISTER: list[ct.BLClass] = [
|
BL_REGISTER: list[ct.BLClass] = [
|
||||||
# *operators.BL_REGISTER,
|
*operators.BL_REGISTER,
|
||||||
# *assets.BL_REGISTER,
|
*assets.BL_REGISTER,
|
||||||
# *node_trees.BL_REGISTER,
|
# *node_trees.BL_REGISTER,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -39,20 +39,18 @@ BL_HANDLERS: ct.BLHandlers = reduce(
|
||||||
lambda a, b: a + b,
|
lambda a, b: a + b,
|
||||||
[
|
[
|
||||||
assets.BL_HANDLERS,
|
assets.BL_HANDLERS,
|
||||||
# *operators.BL_HANDLERS,
|
operators.BL_HANDLERS,
|
||||||
# *assets.BL_HANDLERS,
|
assets.BL_HANDLERS,
|
||||||
# *node_trees.BL_HANDLERS,
|
# node_trees.BL_HANDLERS,
|
||||||
],
|
],
|
||||||
ct.BLHandlers(),
|
ct.BLHandlers(),
|
||||||
)
|
)
|
||||||
|
|
||||||
BL_HOTKEYS: list[ct.KeymapItemDef] = [
|
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
|
||||||
# *operators.BL_HOTKEYS,
|
*assets.BL_KEYMAP_ITEMS,
|
||||||
# *assets.BL_HOTKEYS,
|
*operators.BL_KEYMAP_ITEMS,
|
||||||
]
|
]
|
||||||
|
|
||||||
## TODO: BL_HANDLERS and BL_SOCKET_DEFS
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Registration
|
# - Registration
|
||||||
|
@ -79,7 +77,7 @@ def register() -> None:
|
||||||
|
|
||||||
registration.register_classes(BL_REGISTER)
|
registration.register_classes(BL_REGISTER)
|
||||||
registration.register_handlers(BL_HANDLERS)
|
registration.register_handlers(BL_HANDLERS)
|
||||||
registration.register_hotkeys(BL_HOTKEYS)
|
registration.register_keymaps(BL_KEYMAP_ITEMS)
|
||||||
|
|
||||||
log.info('Finished Registration of Addon: %s', ct.addon.NAME)
|
log.info('Finished Registration of Addon: %s', ct.addon.NAME)
|
||||||
else:
|
else:
|
||||||
|
@ -98,7 +96,7 @@ def unregister() -> None:
|
||||||
"""
|
"""
|
||||||
log.info('Starting %s Unregister', ct.addon.NAME)
|
log.info('Starting %s Unregister', ct.addon.NAME)
|
||||||
|
|
||||||
registration.unregister_hotkeys()
|
registration.unregister_keymaps()
|
||||||
registration.unregister_handlers()
|
registration.unregister_handlers()
|
||||||
registration.unregister_classes()
|
registration.unregister_classes()
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Internal assets for use via the Python API and/or directly by the user as an asset library."""
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
import oscillode.contracts as ct
|
import oscillode.contracts as ct
|
||||||
|
@ -32,8 +34,8 @@ BL_HANDLERS: ct.BLHandlers = reduce(
|
||||||
ct.BLHandlers(),
|
ct.BLHandlers(),
|
||||||
)
|
)
|
||||||
|
|
||||||
BL_HOTKEYS: list[ct.KeymapItemDef] = [
|
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
|
||||||
*geonodes.BL_HOTKEYS,
|
*geonodes.BL_KEYMAP_ITEMS,
|
||||||
]
|
]
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
@ -31,17 +31,17 @@ log = logger.get(__name__)
|
||||||
####################
|
####################
|
||||||
# GeoNodes Paths
|
# GeoNodes Paths
|
||||||
## Internal
|
## Internal
|
||||||
GN_INTERNAL_PATH = ct.addon.PATH_ASSETS / 'internal'
|
GN_INTERNAL_PATH: Path = ct.addon.PATH_ASSETS / 'internal'
|
||||||
GN_INTERNAL_INPUTS_PATH = GN_INTERNAL_PATH / 'input'
|
GN_INTERNAL_INPUTS_PATH: Path = GN_INTERNAL_PATH / 'input'
|
||||||
GN_INTERNAL_SOURCES_PATH = GN_INTERNAL_PATH / 'source'
|
GN_INTERNAL_SOURCES_PATH: Path = GN_INTERNAL_PATH / 'source'
|
||||||
GN_INTERNAL_STRUCTURES_PATH = GN_INTERNAL_PATH / 'structure'
|
GN_INTERNAL_STRUCTURES_PATH: Path = GN_INTERNAL_PATH / 'structure'
|
||||||
GN_INTERNAL_MONITORS_PATH = GN_INTERNAL_PATH / 'monitor'
|
GN_INTERNAL_MONITORS_PATH: Path = GN_INTERNAL_PATH / 'monitor'
|
||||||
GN_INTERNAL_SIMULATIONS_PATH = GN_INTERNAL_PATH / 'simulation'
|
GN_INTERNAL_SIMULATIONS_PATH: Path = GN_INTERNAL_PATH / 'simulation'
|
||||||
|
|
||||||
## Structures
|
## Structures
|
||||||
GN_STRUCTURES_PATH = ct.addon.PATH_ASSETS / 'structures'
|
GN_STRUCTURES_PATH: Path = ct.addon.PATH_ASSETS / 'structures'
|
||||||
GN_STRUCTURES_PRIMITIVES_PATH = GN_STRUCTURES_PATH / 'primitives'
|
GN_STRUCTURES_PRIMITIVES_PATH: Path = GN_STRUCTURES_PATH / 'primitives'
|
||||||
GN_STRUCTURES_ARRAYS_PATH = GN_STRUCTURES_PATH / 'arrays'
|
GN_STRUCTURES_ARRAYS_PATH: Path = GN_STRUCTURES_PATH / 'arrays'
|
||||||
|
|
||||||
|
|
||||||
class GeoNodes(enum.StrEnum):
|
class GeoNodes(enum.StrEnum):
|
||||||
|
@ -473,10 +473,10 @@ class GeoNodesToStructureNode(bpy.types.Operator):
|
||||||
## 3. We compute it manually, to avoid the jank.
|
## 3. We compute it manually, to avoid the jank.
|
||||||
node_location = get_view_location(
|
node_location = get_view_location(
|
||||||
editor_region,
|
editor_region,
|
||||||
[
|
(
|
||||||
event.mouse_x - editor_region.x,
|
event.mouse_x - editor_region.x,
|
||||||
event.mouse_y - editor_region.y,
|
event.mouse_y - editor_region.y,
|
||||||
],
|
),
|
||||||
context.preferences.system.ui_scale,
|
context.preferences.system.ui_scale,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -525,8 +525,8 @@ ASSET_LIB_SPECS: dict[str, Path] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@bpy.app.handlers.persistent
|
@bpy.app.handlers.persistent # type: ignore[misc]
|
||||||
def initialize_asset_libraries(_: bpy.types.Scene):
|
def initialize_asset_libraries(_: bpy.types.Scene) -> None:
|
||||||
"""Before loading a `.blend` file, ensure that the WindowManager properties relied on by NodeAssetPanel are available.
|
"""Before loading a `.blend` file, ensure that the WindowManager properties relied on by NodeAssetPanel are available.
|
||||||
|
|
||||||
- Several asset libraries, defined under the global `ASSET_LIB_SPECS`, are added/replaced such that the name:path map is respected.
|
- Several asset libraries, defined under the global `ASSET_LIB_SPECS`, are added/replaced such that the name:path map is respected.
|
||||||
|
@ -586,4 +586,4 @@ BL_REGISTER = [
|
||||||
|
|
||||||
BL_HANDLERS: ct.BLHandlers = ct.BLHandlers(load_pre=(initialize_asset_libraries,))
|
BL_HANDLERS: ct.BLHandlers = ct.BLHandlers(load_pre=(initialize_asset_libraries,))
|
||||||
|
|
||||||
BL_HOTKEYS: list[ct.KeymapItemDef] = []
|
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = []
|
||||||
|
|
|
@ -22,24 +22,25 @@ from .bl import (
|
||||||
BLColorRGBA,
|
BLColorRGBA,
|
||||||
BLEnumElement,
|
BLEnumElement,
|
||||||
BLEnumID,
|
BLEnumID,
|
||||||
|
BLEventType,
|
||||||
|
BLEventValue,
|
||||||
BLIcon,
|
BLIcon,
|
||||||
BLIconSet,
|
BLIconSet,
|
||||||
BLIDStruct,
|
BLIDStruct,
|
||||||
BLImportMethod,
|
BLImportMethod,
|
||||||
BLKeymapItem,
|
|
||||||
BLModifierType,
|
BLModifierType,
|
||||||
BLNodeTreeInterfaceID,
|
BLNodeTreeInterfaceID,
|
||||||
BLOperatorStatus,
|
BLOperatorStatus,
|
||||||
BLPropFlag,
|
BLPropFlag,
|
||||||
BLRegionType,
|
BLRegionType,
|
||||||
BLSpaceType,
|
BLSpaceType,
|
||||||
KeymapItemDef,
|
|
||||||
ManagedObjName,
|
ManagedObjName,
|
||||||
PresetName,
|
PresetName,
|
||||||
PropName,
|
PropName,
|
||||||
SocketName,
|
SocketName,
|
||||||
)
|
)
|
||||||
from .bl_handlers import BLHandlers
|
from .bl_handlers import BLHandlers
|
||||||
|
from .bl_keymap import BLKeymapItem
|
||||||
from .icons import Icon
|
from .icons import Icon
|
||||||
from .mobj_types import ManagedObjType
|
from .mobj_types import ManagedObjType
|
||||||
from .node_tree_types import (
|
from .node_tree_types import (
|
||||||
|
@ -58,6 +59,8 @@ __all__ = [
|
||||||
'BLColorRGBA',
|
'BLColorRGBA',
|
||||||
'BLEnumElement',
|
'BLEnumElement',
|
||||||
'BLEnumID',
|
'BLEnumID',
|
||||||
|
'BLEventType',
|
||||||
|
'BLEventValue',
|
||||||
'BLIcon',
|
'BLIcon',
|
||||||
'BLIconSet',
|
'BLIconSet',
|
||||||
'BLIDStruct',
|
'BLIDStruct',
|
||||||
|
|
|
@ -45,7 +45,7 @@ if 'RUNNING_BLEXT_TESTS' in os.environ:
|
||||||
PATH_ADDON_ROOT.parent / 'dev' / 'local'
|
PATH_ADDON_ROOT.parent / 'dev' / 'local'
|
||||||
) ## TODO: Consult init_settings
|
) ## TODO: Consult init_settings
|
||||||
else:
|
else:
|
||||||
PATH_CACHE: Path = Path(bpy.utils.extension_path_user(__package__, create=True))
|
PATH_CACHE: Path = Path(bpy.utils.extension_path_user(__package__, create=True)) # type: ignore[no-redef]
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -95,7 +95,6 @@ BLIDStruct: typ.TypeAlias = (
|
||||||
| bpy.types.WorkSpace
|
| bpy.types.WorkSpace
|
||||||
| bpy.types.World
|
| bpy.types.World
|
||||||
)
|
)
|
||||||
BLKeymapItem: typ.TypeAlias = typ.Any ## TODO: Better Type
|
|
||||||
BLPropFlag: typ.TypeAlias = typ.Literal[
|
BLPropFlag: typ.TypeAlias = typ.Literal[
|
||||||
'HIDDEN',
|
'HIDDEN',
|
||||||
'SKIP_SAVE',
|
'SKIP_SAVE',
|
||||||
|
@ -112,6 +111,24 @@ BLColorRGBA = tuple[float, float, float, float]
|
||||||
####################
|
####################
|
||||||
# - Operators
|
# - Operators
|
||||||
####################
|
####################
|
||||||
|
BLRegionType: typ.TypeAlias = typ.Literal[
|
||||||
|
'WINDOW',
|
||||||
|
'HEADER',
|
||||||
|
'CHANNELS',
|
||||||
|
'TEMPORARY',
|
||||||
|
'UI',
|
||||||
|
'TOOLS',
|
||||||
|
'TOOL_PROPS',
|
||||||
|
'ASSET_SHELF',
|
||||||
|
'ASSET_SHELF_HEADER',
|
||||||
|
'PREVIEW',
|
||||||
|
'HUD',
|
||||||
|
'NAVIGATION_BAR',
|
||||||
|
'EXECUTE',
|
||||||
|
'FOOTER',
|
||||||
|
'TOOL_HEADER',
|
||||||
|
'XR',
|
||||||
|
]
|
||||||
BLSpaceType: typ.TypeAlias = typ.Literal[
|
BLSpaceType: typ.TypeAlias = typ.Literal[
|
||||||
'EMPTY',
|
'EMPTY',
|
||||||
'VIEW_3D',
|
'VIEW_3D',
|
||||||
|
@ -133,32 +150,151 @@ BLSpaceType: typ.TypeAlias = typ.Literal[
|
||||||
'SPREADSHEET',
|
'SPREADSHEET',
|
||||||
'PREFERENCES',
|
'PREFERENCES',
|
||||||
]
|
]
|
||||||
BLRegionType: typ.TypeAlias = typ.Literal[
|
|
||||||
'WINDOW',
|
|
||||||
'HEADER',
|
|
||||||
'CHANNELS',
|
|
||||||
'TEMPORARY',
|
|
||||||
'UI',
|
|
||||||
'TOOLS',
|
|
||||||
'TOOL_PROPS',
|
|
||||||
'ASSET_SHELF',
|
|
||||||
'ASSET_SHELF_HEADER',
|
|
||||||
'PREVIEW',
|
|
||||||
'HUD',
|
|
||||||
'NAVIGATION_BAR',
|
|
||||||
'EXECUTE',
|
|
||||||
'FOOTER',
|
|
||||||
'TOOL_HEADER',
|
|
||||||
'XR',
|
|
||||||
]
|
|
||||||
BLOperatorStatus: typ.TypeAlias = set[
|
BLOperatorStatus: typ.TypeAlias = set[
|
||||||
typ.Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']
|
typ.Literal['RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH', 'INTERFACE']
|
||||||
]
|
]
|
||||||
|
|
||||||
|
####################
|
||||||
|
# - Operators
|
||||||
|
####################
|
||||||
|
## TODO: Write the rest in.
|
||||||
|
BLEventType: typ.TypeAlias = typ.Literal[
|
||||||
|
'NONE',
|
||||||
|
'LEFTMOUSE',
|
||||||
|
'MIDDLEMOUSE',
|
||||||
|
'RIGHTMOUSE',
|
||||||
|
'BUTTON4MOUSE',
|
||||||
|
'BUTTON5MOUSE',
|
||||||
|
'BUTTON6MOUSE',
|
||||||
|
'BUTTON7MOUSE',
|
||||||
|
'PEN',
|
||||||
|
'ERASOR',
|
||||||
|
'MOUSEMOVE',
|
||||||
|
'INBETWEEN_MOUSEMOVE',
|
||||||
|
'TRACKPADPAN',
|
||||||
|
'TRACKPADZOOM',
|
||||||
|
'MOUSEROTATE',
|
||||||
|
'MOUSESMARTZOOM',
|
||||||
|
'WHEELUPMOUSE',
|
||||||
|
'WHEELDOWNMOUSE',
|
||||||
|
'WHEELINMOUSE',
|
||||||
|
'WHEELOUTMOUSE',
|
||||||
|
'A',
|
||||||
|
'B',
|
||||||
|
'C',
|
||||||
|
'D',
|
||||||
|
'E',
|
||||||
|
'F',
|
||||||
|
'G',
|
||||||
|
'H',
|
||||||
|
'I',
|
||||||
|
'J',
|
||||||
|
'K',
|
||||||
|
'L',
|
||||||
|
'M',
|
||||||
|
'N',
|
||||||
|
'O',
|
||||||
|
'P',
|
||||||
|
'Q',
|
||||||
|
'R',
|
||||||
|
'S',
|
||||||
|
'T',
|
||||||
|
'U',
|
||||||
|
'V',
|
||||||
|
'W',
|
||||||
|
'X',
|
||||||
|
'Y',
|
||||||
|
'Z',
|
||||||
|
'ZERO',
|
||||||
|
'ONE',
|
||||||
|
'TWO',
|
||||||
|
'THREE',
|
||||||
|
'FOUR',
|
||||||
|
'FIVE',
|
||||||
|
'SIX',
|
||||||
|
'SEVEN',
|
||||||
|
'EIGHT',
|
||||||
|
'NINE',
|
||||||
|
'LEFT_CTRL',
|
||||||
|
'LEFT_ALT',
|
||||||
|
'LEFT_SHIFT',
|
||||||
|
'RIGHT_ALT',
|
||||||
|
'RIGHT_CTRL',
|
||||||
|
'RIGHT_SHIFT',
|
||||||
|
'ESC',
|
||||||
|
'TAB',
|
||||||
|
'RET', ## Enter
|
||||||
|
'SPACE',
|
||||||
|
'LINE_FEED',
|
||||||
|
'BACK_SPACE',
|
||||||
|
'DEL',
|
||||||
|
'SEMI_COLON',
|
||||||
|
'PERIOD',
|
||||||
|
'COMMA',
|
||||||
|
'QUOTE',
|
||||||
|
'ACCENT_GRAVE',
|
||||||
|
'MINUS',
|
||||||
|
'PLUS',
|
||||||
|
'SLASH',
|
||||||
|
'BACK_SLASH',
|
||||||
|
'EQUAL',
|
||||||
|
'LEFT_BRACKET',
|
||||||
|
'RIGHT_BRACKET',
|
||||||
|
'LEFT_ARROW',
|
||||||
|
'DOWN_ARROW',
|
||||||
|
'RIGHT_ARROW',
|
||||||
|
'UP_ARROW',
|
||||||
|
'NUMPAD_0',
|
||||||
|
'NUMPAD_1',
|
||||||
|
'NUMPAD_2',
|
||||||
|
'NUMPAD_3',
|
||||||
|
'NUMPAD_4',
|
||||||
|
'NUMPAD_5',
|
||||||
|
'NUMPAD_6',
|
||||||
|
'NUMPAD_7',
|
||||||
|
'NUMPAD_8',
|
||||||
|
'NUMPAD_9',
|
||||||
|
'NUMPAD_PERIOD',
|
||||||
|
'NUMPAD_SLASH',
|
||||||
|
'NUMPAD_ASTERIX',
|
||||||
|
'NUMPAD_MINUS',
|
||||||
|
'NUMPAD_PLUS',
|
||||||
|
'NUMPAD_ENTER',
|
||||||
|
'F1',
|
||||||
|
'F2',
|
||||||
|
'F3',
|
||||||
|
'F4',
|
||||||
|
'F5',
|
||||||
|
'F6',
|
||||||
|
'F7',
|
||||||
|
'F8',
|
||||||
|
'F9',
|
||||||
|
'F10',
|
||||||
|
'F11',
|
||||||
|
'F12',
|
||||||
|
'PAUSE',
|
||||||
|
'INSERT',
|
||||||
|
'HOME',
|
||||||
|
'PAGE_UP',
|
||||||
|
'PAGE_DOWN',
|
||||||
|
'END',
|
||||||
|
'MEDIA_PLAY',
|
||||||
|
'MEDIA_STOP',
|
||||||
|
'MEDIA_FIRST',
|
||||||
|
'MEDIA_LAST',
|
||||||
|
]
|
||||||
|
BLEventValue: typ.TypeAlias = typ.Literal[
|
||||||
|
'ANY',
|
||||||
|
'PRESS',
|
||||||
|
'RELEASE',
|
||||||
|
'CLICK',
|
||||||
|
'DOUBLE_CLICK',
|
||||||
|
'CLICK_DRAG',
|
||||||
|
'NOTHING',
|
||||||
|
]
|
||||||
####################
|
####################
|
||||||
# - Addon Types
|
# - Addon Types
|
||||||
####################
|
####################
|
||||||
KeymapItemDef: typ.TypeAlias = typ.Any
|
|
||||||
ManagedObjName = str
|
ManagedObjName = str
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -58,6 +58,9 @@ class BLHandlers(pyd.BaseModel):
|
||||||
render_post: tuple[BLHandler, ...] = ()
|
render_post: tuple[BLHandler, ...] = ()
|
||||||
render_pre: tuple[BLHandler, ...] = ()
|
render_pre: tuple[BLHandler, ...] = ()
|
||||||
render_stats: tuple[BLHandler, ...] = ()
|
render_stats: tuple[BLHandler, ...] = ()
|
||||||
|
## TODO: Verify these type signatures.
|
||||||
|
|
||||||
|
## TODO: A validator to check that all handlers are decorated with bpy.app.handlers.persistent
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
"""Declares types for working with `bpy.types.KeyMap`s."""
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import pydantic as pyd
|
||||||
|
|
||||||
|
from .bl import BLEventType, BLEventValue, BLSpaceType
|
||||||
|
from .operator_types import OperatorType
|
||||||
|
|
||||||
|
|
||||||
|
class BLKeymapItem(pyd.BaseModel):
|
||||||
|
"""Contains lists of handlers associated with this addon."""
|
||||||
|
|
||||||
|
operator: OperatorType
|
||||||
|
|
||||||
|
event_type: BLEventType
|
||||||
|
event_value: BLEventValue
|
||||||
|
|
||||||
|
shift: bool = False
|
||||||
|
ctrl: bool = False
|
||||||
|
alt: bool = False
|
||||||
|
key_modifier: BLEventType = 'NONE'
|
||||||
|
|
||||||
|
space_type: BLSpaceType = 'EMPTY'
|
||||||
|
|
||||||
|
def register(self, addon_keymap: bpy.types.KeyMap) -> bpy.types.KeymapItem:
|
||||||
|
"""Registers this hotkey with an addon keymap.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the `space_type` constraint of the addon keymap does not match the `space_type` constraint of this `BLKeymapItem`.
|
||||||
|
"""
|
||||||
|
if self.space_type == addon_keymap.space_type:
|
||||||
|
addon_keymap.keymap_items.new(
|
||||||
|
self.operator,
|
||||||
|
self.event_type,
|
||||||
|
self.event_value,
|
||||||
|
shift=self.shift,
|
||||||
|
ctrl=self.ctrl,
|
||||||
|
alt=self.alt,
|
||||||
|
key_modifier=self.key_modifier,
|
||||||
|
)
|
||||||
|
|
||||||
|
msg = f'Addon keymap space type {addon_keymap.space_type} does not match space_type of BLKeymapItem to register: {self}'
|
||||||
|
raise ValueError(msg)
|
||||||
|
## TODO: Check if space_type matches?
|
|
@ -312,6 +312,8 @@ class MaxwellSimTree(bpy.types.NodeTree):
|
||||||
default=True,
|
default=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
viewer_node_type: ct.NodeType = ct.NodeType.Viewer
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Init Methods
|
# - Init Methods
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -16,11 +16,22 @@
|
||||||
|
|
||||||
"""Blender operators that ship with Oscillode."""
|
"""Blender operators that ship with Oscillode."""
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
|
from oscillode import contracts as ct
|
||||||
|
|
||||||
from . import connect_viewer
|
from . import connect_viewer
|
||||||
|
|
||||||
BL_REGISTER = [
|
BL_REGISTER: list[ct.BLClass] = [
|
||||||
*connect_viewer.BL_REGISTER,
|
*connect_viewer.BL_REGISTER,
|
||||||
]
|
]
|
||||||
BL_HOTKEYS = [
|
BL_HANDLERS: ct.BLHandlers = reduce(
|
||||||
*connect_viewer.BL_HOTKEYS,
|
lambda a, b: a + b,
|
||||||
|
[
|
||||||
|
*connect_viewer.BL_HANDLERS,
|
||||||
|
],
|
||||||
|
ct.BLHandlers(),
|
||||||
|
)
|
||||||
|
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
|
||||||
|
*connect_viewer.BL_KEYMAP_ITEMS,
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
from oscillode import contracts as ct
|
from oscillode import contracts as ct
|
||||||
from oscillode.node_trees.maxwell_sim_nodes.contracts import node_types
|
|
||||||
from oscillode.utils import logger
|
from oscillode.utils import logger
|
||||||
|
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
@ -79,16 +78,17 @@ class ConnectViewerNode(bpy.types.Operator):
|
||||||
selected_node = context.selected_nodes[0]
|
selected_node = context.selected_nodes[0]
|
||||||
|
|
||||||
# Find Viewer Node...
|
# Find Viewer Node...
|
||||||
|
viewer_node_type = node_tree.viewer_node_type
|
||||||
for node in node_tree.nodes:
|
for node in node_tree.nodes:
|
||||||
# TODO: Support multiple viewer nodes.
|
# TODO: Support multiple viewer nodes.
|
||||||
if hasattr(node, 'node_type') and node.node_type is node_types.Viewer:
|
if hasattr(node, 'node_type') and node.node_type is viewer_node_type:
|
||||||
viewer_node = node
|
viewer_node = node
|
||||||
break
|
break
|
||||||
|
|
||||||
# ...OR: Create Viewer Node
|
# ...OR: Create Viewer Node
|
||||||
else:
|
else:
|
||||||
# TODO: Place viewer where it doesn't overlap other nodes.
|
# TODO: Place viewer where it doesn't overlap other nodes.
|
||||||
viewer_node = node_tree.nodes.new(node_types.Viewer.value)
|
viewer_node = node_tree.nodes.new(viewer_node_type)
|
||||||
viewer_node.location.x = selected_node.location.x + 250
|
viewer_node.location.x = selected_node.location.x + 250
|
||||||
viewer_node.location.y = selected_node.location.y
|
viewer_node.location.y = selected_node.location.y
|
||||||
selected_node.select = False
|
selected_node.select = False
|
||||||
|
@ -112,19 +112,19 @@ class ConnectViewerNode(bpy.types.Operator):
|
||||||
####################
|
####################
|
||||||
# - Blender Registration
|
# - Blender Registration
|
||||||
####################
|
####################
|
||||||
BL_REGISTER = [
|
BL_REGISTER: list[ct.BLClass] = [
|
||||||
ConnectViewerNode,
|
ConnectViewerNode,
|
||||||
]
|
]
|
||||||
|
|
||||||
BL_HOTKEYS = [
|
BL_HANDLERS: ct.BLHandlers = ct.BLHandlers()
|
||||||
{
|
|
||||||
'_': (
|
BL_KEYMAP_ITEMS: list[ct.BLKeymapItem] = [
|
||||||
ct.OperatorType.ConnectViewerNode,
|
ct.BLKeymapItem(
|
||||||
'LEFTMOUSE',
|
ct.OperatorType.ConnectViewerNode,
|
||||||
'PRESS',
|
event_type='LEFTMOUSE',
|
||||||
),
|
event_value='PRESS',
|
||||||
'ctrl': True,
|
ctrl=True,
|
||||||
'shift': True,
|
shift=True,
|
||||||
'alt': False,
|
space_type='NODE_EDITOR',
|
||||||
},
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
"""Manages the registration of Blender classes, including delayed registrations that require access to Python dependencies.
|
"""Manages the registration of Blender classes, including delayed registrations that require access to Python dependencies.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_ADDON_KEYMAP: Addon-specific keymap used to register operator hotkeys.
|
_REGISTERED_CLASSES: Blender classes currently registered by this addon.
|
||||||
REG__CLASSES: Currently registered Blender classes.
|
_REGISTERED_KEYMAPS: Addon keymaps currently registered by this addon.
|
||||||
_REGISTERED_HOTKEYS: Currently registered Blender keymap items.
|
Each addon keymap is constrained to a single `space_type`, which is the key.
|
||||||
|
_REGISTERED_KEYMAP_ITEMS: Addon keymap items currently registered by this addon.
|
||||||
|
Each keymap item is paired to the keymap within which it is registered.
|
||||||
|
_Each keymap is guaranteed to also be found in `_REGISTERED_KEYMAPS`._
|
||||||
|
_REGISTERED_HANDLERS: Addon handlers currently registered by this addon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
@ -34,8 +38,8 @@ log = logger.get(__name__)
|
||||||
####################
|
####################
|
||||||
_REGISTERED_CLASSES: list[ct.BLClass] = []
|
_REGISTERED_CLASSES: list[ct.BLClass] = []
|
||||||
|
|
||||||
_ADDON_KEYMAP: bpy.types.KeyMap | None = None
|
_REGISTERED_KEYMAPS: dict[ct.BLSpaceType, bpy.types.KeyMap] = {}
|
||||||
_REGISTERED_HOTKEYS: list[ct.BLKeymapItem] = []
|
_REGISTERED_KEYMAP_ITEMS: list[tuple[bpy.types.KeyMap, bpy.types.KeymapItem]] = []
|
||||||
|
|
||||||
_REGISTERED_HANDLERS: ct.BLHandlers | None = None
|
_REGISTERED_HANDLERS: ct.BLHandlers | None = None
|
||||||
|
|
||||||
|
@ -109,59 +113,47 @@ def unregister_handlers() -> None:
|
||||||
####################
|
####################
|
||||||
# - Keymap Registration
|
# - Keymap Registration
|
||||||
####################
|
####################
|
||||||
def register_hotkeys(hotkey_defs: list[dict]) -> None:
|
def register_keymaps(keymap_items: list[ct.BLKeymapItem]) -> None:
|
||||||
"""Registers a list of Blender hotkey definitions.
|
"""Registers a list of Blender hotkey definitions.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
hotkey_defs: List of Blender hotkey definitions to register.
|
bl_keymap_items: List of Blender hotkey definitions to register.
|
||||||
"""
|
"""
|
||||||
# Lazy-Load BL_NODE_KEYMAP
|
# Aggregate Requested Spaces of All Keymap Items
|
||||||
global _ADDON_KEYMAP # noqa: PLW0603
|
keymap_space_types: set[ct.BLSpaceType] = {
|
||||||
if _ADDON_KEYMAP is None:
|
keymap_item.space_type for keymap_item in keymap_items
|
||||||
_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
|
# Create Addon Keymap per Requested Space
|
||||||
log.info('Registering %s Keymap Items', len(hotkey_defs))
|
for keymap_space_type in keymap_space_types:
|
||||||
for keymap_item_def in hotkey_defs:
|
log.info('Registering %s Keymap', keymap_space_type)
|
||||||
keymap_item = _ADDON_KEYMAP.keymap_items.new(
|
bl_keymap = bpy.context.window_manager.keyconfigs.addon.keymaps.new(
|
||||||
*keymap_item_def['_'],
|
name=f'{ct.addon.NAME} - {keymap_space_type}',
|
||||||
ctrl=keymap_item_def['ctrl'],
|
space_type=keymap_space_type,
|
||||||
shift=keymap_item_def['shift'],
|
|
||||||
alt=keymap_item_def['alt'],
|
|
||||||
)
|
)
|
||||||
log.debug(
|
_REGISTERED_KEYMAPS[keymap_space_type] = bl_keymap
|
||||||
'Registered Keymap Item %s with spec %s',
|
|
||||||
repr(keymap_item),
|
# Register Keymap Items in Correct Addon Keymap
|
||||||
keymap_item_def,
|
for keymap_item in keymap_items:
|
||||||
)
|
log.info('Registering %s Keymap Item', keymap_item)
|
||||||
_REGISTERED_HOTKEYS.append(keymap_item)
|
bl_keymap = _REGISTERED_KEYMAPS[keymap_item.space_type]
|
||||||
|
bl_keymap_item = keymap_item.register(bl_keymap)
|
||||||
|
|
||||||
|
_REGISTERED_KEYMAP_ITEMS.append((bl_keymap, bl_keymap_item))
|
||||||
|
|
||||||
|
|
||||||
def unregister_hotkeys() -> None:
|
def unregister_keymaps() -> None:
|
||||||
"""Unregisters all Blender hotkeys associated with the addon."""
|
"""Unregisters all Blender keymaps associated with the addon."""
|
||||||
global _ADDON_KEYMAP # noqa: PLW0603
|
# Unregister Keymap Items from Correct Addon Keymap
|
||||||
|
for bl_keymap, bl_keymap_item in reversed(_REGISTERED_KEYMAP_ITEMS):
|
||||||
|
log.info('Unregistering %s BL Keymap Item', bl_keymap_item)
|
||||||
|
bl_keymap.keymap_items.remove(bl_keymap_item)
|
||||||
|
|
||||||
# Unregister Keymaps
|
_REGISTERED_KEYMAP_ITEMS.clear()
|
||||||
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
|
# Delete Addon Keymaps
|
||||||
if _ADDON_KEYMAP is not None:
|
for bl_keymap in reversed(_REGISTERED_KEYMAPS.values()):
|
||||||
log.info(
|
log.info('Unregistering %s Keymap', bl_keymap)
|
||||||
'Unregistered Keymap %s',
|
bpy.context.window_manager.keyconfigs.addon.keymaps.remove(bl_keymap)
|
||||||
repr(_ADDON_KEYMAP),
|
|
||||||
)
|
_REGISTERED_KEYMAPS.clear()
|
||||||
_REGISTERED_HOTKEYS.clear()
|
|
||||||
_ADDON_KEYMAP = None
|
|
||||||
|
|
Loading…
Reference in New Issue