@@ -95,6 +95,7 @@ def onKeyboardShortcut(self):
95
95
SEQUENCE_PATTERN : str = r'(\w+?)(\d+)(.+)'
96
96
IS_EXPOSE_PUBLIC : bool = False
97
97
EXT_SELF = None
98
+ EXT_OWNERCOMP = None
98
99
STUBS_ENABLED : bool = False
99
100
100
101
@classmethod
@@ -104,6 +105,7 @@ def Init(cls, extension_self, ownerComp: COMP, enable_properties: bool = True, e
104
105
enable_stubs : bool = False ) -> None :
105
106
"""Initialize the CustomParHelper."""
106
107
cls .EXT_SELF = extension_self
108
+ cls .EXT_OWNERCOMP = ownerComp
107
109
cls .IS_EXPOSE_PUBLIC = expose_public
108
110
cls .PAR_PROPS = par_properties
109
111
cls .PAR_CALLBACKS = par_callbacks
@@ -360,190 +362,3 @@ def UpdateStubs(cls) -> None:
360
362
class_name = cls .EXT_SELF .__class__ .__name__
361
363
op_ext = op (class_name )
362
364
_docked .StubifyDat (op_ext )
363
-
364
-
365
-
366
- class NoNode :
367
- """
368
- NoNode is a utility class that provides functionality for handling keyboard shortcuts
369
- and CHOP executions without the need for a specific node in TouchDesigner.
370
- """
371
-
372
- CHOPEXEC_CALLBACKS : TDStoreTools .DependDict [str , dict [CHOP , dict [str , Callable ]]] = TDStoreTools .DependDict ()
373
- KEYBOARD_SHORTCUTS : dict = {}
374
-
375
- KEYBOARD_IS_ENABLED : bool = False
376
- CHOPEXEC_IS_ENABLED : bool = False
377
-
378
- @classmethod
379
- def Init (cls , enable_chopexec : bool = True , enable_keyboard_shortcuts : bool = True ) -> None :
380
- """Initialize the NoNode functionality."""
381
- cls .CHOPEXEC_IS_ENABLED = enable_chopexec
382
- cls .KEYBOARD_IS_ENABLED = enable_keyboard_shortcuts
383
- cls .CHOPEXEC_CALLBACKS = TDStoreTools .DependDict ()
384
- cls .KEYBOARD_SHORTCUTS = {}
385
-
386
- # Disable all CHOP execute operators by default
387
- for _docked in me .docked :
388
- if any (tag in _docked .tags for tag in ['extChopValueExec' , 'extChopOffToOnExec' , 'extChopWhileOnExec' , 'extChopWhileOffExec' ]):
389
- _docked .par .active = False
390
-
391
- if enable_chopexec :
392
- cls .EnableChopExec ()
393
- else :
394
- cls .DisableChopExec ()
395
-
396
- if enable_keyboard_shortcuts :
397
- cls .EnableKeyboardShortcuts ()
398
- else :
399
- cls .DisableKeyboardShortcuts ()
400
-
401
- @classmethod
402
- def EnableChopExec (cls ) -> None :
403
- """Enable chopExec handling."""
404
- cls .CHOPEXEC_IS_ENABLED = True
405
- # Note: We don't enable any specific operators here anymore
406
-
407
- @classmethod
408
- def DisableChopExec (cls ) -> None :
409
- """Disable chopExec handling."""
410
- cls .CHOPEXEC_IS_ENABLED = False
411
- for _docked in me .docked :
412
- if any (tag in _docked .tags for tag in ['extChopValueExec' , 'extChopOffToOnExec' , 'extChopWhileOnExec' , 'extChopWhileOffExec' ]):
413
- _docked .par .active = False
414
-
415
- @classmethod
416
- def RegisterChopExec (cls , event_type : str , chop : COMP , channels : str , callback : Callable ) -> None :
417
- """
418
- Register a CHOP execute callback.
419
-
420
- Args:
421
- event_type (str): The type of event to listen for ('OffToOn', 'WhileOn', 'WhileOff', 'ValueChange').
422
- chop (CHOP): The CHOP operator to register the callback for.
423
- channels (str): The channel(s) to listen to. Use '*' for all channels.
424
- callback (Callable): The callback function to be called on CHOP execution.
425
-
426
- Example:
427
- def my_callback(event_type, channel, index, value, prev):
428
- print(f"Event: {event_type}, Channel {channel} at index {index} changed from {prev} to {value}")
429
-
430
- NoNode.RegisterChopExec('ValueChange', op('constant1'), '*', my_callback)
431
- """
432
- if event_type not in cls .CHOPEXEC_CALLBACKS .getRaw ():
433
- cls .CHOPEXEC_CALLBACKS .setItem (event_type , {}, raw = True )
434
-
435
- current_callbacks = cls .CHOPEXEC_CALLBACKS .getDependency (event_type )
436
- if chop not in current_callbacks .val :
437
- current_callbacks .val [chop ] = {}
438
- current_callbacks .val [chop ][channels ] = callback
439
- cls .CHOPEXEC_CALLBACKS .setItem (event_type , current_callbacks )
440
-
441
- # Enable the appropriate docked operator based on the event type
442
- for _docked in me .docked :
443
- if 'extChopValueExec' in _docked .tags :
444
- if event_type == 'ValueChange' :
445
- _docked .par .active = True
446
- elif 'extChopOffToOnExec' in _docked .tags :
447
- if event_type == 'OffToOn' :
448
- _docked .par .active = True
449
- elif 'extChopWhileOnExec' in _docked .tags :
450
- if event_type == 'WhileOn' :
451
- _docked .par .active = True
452
- elif 'extChopWhileOffExec' in _docked .tags :
453
- if event_type == 'WhileOff' :
454
- _docked .par .active = True
455
-
456
- @classmethod
457
- def DeregisterChopExec (cls , event_type : str , chop : CHOP = None , channels : str = None ) -> None :
458
- """
459
- Deregister a chopExec callback
460
-
461
- Args:
462
- event_type (str): The event type to deregister ('OffToOn', 'WhileOn', 'WhileOff', 'ValueChange').
463
- chop (CHOP, optional): The CHOP operator to deregister the callback for. If None, deregisters all CHOPs for the event type.
464
- channels (str, optional): The channel(s) to deregister. If None, deregisters all channels for the specified CHOP.
465
- """
466
- if event_type in cls .CHOPEXEC_CALLBACKS :
467
- if chop is None :
468
- del cls .CHOPEXEC_CALLBACKS [event_type ]
469
- elif chop in cls .CHOPEXEC_CALLBACKS [event_type ]:
470
- if channels is None :
471
- del cls .CHOPEXEC_CALLBACKS [event_type ][chop ]
472
- else :
473
- cls .CHOPEXEC_CALLBACKS [event_type ][chop ].pop (channels , None )
474
-
475
- if not cls .CHOPEXEC_CALLBACKS [event_type ][chop ]:
476
- del cls .CHOPEXEC_CALLBACKS [event_type ][chop ]
477
-
478
- if not cls .CHOPEXEC_CALLBACKS [event_type ]:
479
- del cls .CHOPEXEC_CALLBACKS [event_type ]
480
-
481
- @classmethod
482
- def OnChopExec (cls , event_type : str , channel : Channel , sampleIndex : int , val : float , prev : float ) -> None :
483
- """Handle chopExec events."""
484
- if not cls .CHOPEXEC_IS_ENABLED :
485
- return
486
-
487
- def execute_callback (callback ):
488
- arg_count = callback .__code__ .co_argcount
489
- if arg_count == 1 :
490
- callback ()
491
- elif arg_count == 2 :
492
- callback (val )
493
- elif arg_count == 3 :
494
- callback (channel , val )
495
- elif arg_count == 4 :
496
- callback (channel , sampleIndex , val )
497
- elif arg_count == 5 :
498
- callback (channel , sampleIndex , val , prev )
499
-
500
- chop = channel .owner
501
- if event_type in cls .CHOPEXEC_CALLBACKS :
502
- callbacks = cls .CHOPEXEC_CALLBACKS [event_type ].get (chop , {})
503
- for ch , callback in callbacks .items ():
504
- if ch == '*' or channel .name == ch :
505
- execute_callback (callback )
506
-
507
- @classmethod
508
- def EnableKeyboardShortcuts (cls ) -> None :
509
- """Enable keyboard shortcut handling."""
510
- cls .KEYBOARD_IS_ENABLED = True
511
- for _docked in me .docked :
512
- if 'extKeyboardin' in _docked .tags :
513
- _docked .par .active = True
514
- cls ._UpdateKeyboardShortcuts ()
515
-
516
- @classmethod
517
- def DisableKeyboardShortcuts (cls ) -> None :
518
- """Disable keyboard shortcut handling."""
519
- cls .KEYBOARD_IS_ENABLED = False
520
- for _docked in me .docked :
521
- if 'extKeyboardin' in _docked .tags :
522
- _docked .par .active = False
523
-
524
- @classmethod
525
- def RegisterKeyboardShortcut (cls , shortcut : str , callback : callable ) -> None :
526
- """Register a keyboard shortcut and its callback."""
527
- cls .KEYBOARD_SHORTCUTS [shortcut ] = callback
528
- if cls .KEYBOARD_IS_ENABLED :
529
- cls ._UpdateKeyboardShortcuts ()
530
-
531
- @classmethod
532
- def UnregisterKeyboardShortcut (cls , shortcut : str ) -> None :
533
- """Unregister a keyboard shortcut."""
534
- cls .KEYBOARD_SHORTCUTS .pop (shortcut , None )
535
- if cls .KEYBOARD_IS_ENABLED :
536
- cls ._UpdateKeyboardShortcuts ()
537
-
538
- @classmethod
539
- def _UpdateKeyboardShortcuts (cls ) -> None :
540
- """Update the extKeyboardIn operator's shortcuts parameter."""
541
- for _docked in me .docked :
542
- if 'extKeyboardin' in _docked .tags :
543
- _docked .par .shortcuts = ' ' .join (cls .KEYBOARD_SHORTCUTS .keys ())
544
-
545
- @classmethod
546
- def OnKeyboardShortcut (cls , shortcut : str ) -> None :
547
- """Handle keyboard shortcut events."""
548
- if cls .KEYBOARD_IS_ENABLED and shortcut in cls .KEYBOARD_SHORTCUTS :
549
- cls .KEYBOARD_SHORTCUTS [shortcut ]()
0 commit comments