Skip to content

Conversation

@philippe-ynput
Copy link

feat(groups): add node groups for visual organization of related nodes

Implement comprehensive node groups feature allowing users to visually organize related nodes within colored, labeled containers.

Key additions:

  • NodeGroupModel for group data storage with serialization support
  • NodeGroupView with semi-transparent backgrounds, title bars, and resize handles
  • NodeGroupController managing group lifecycle and member interactions
  • Full API surface: create, delete, rename, add/remove members, validate
  • Keyboard shortcuts: Ctrl+G (create), Ctrl+Shift+G (remove)
  • Custom exceptions: GroupNotFoundError, GroupExistsError,
    NodeAlreadyInGroupError
  • Configuration options for styling, padding, and color palette
  • Backward-compatible graph serialization with groups metadata

Groups automatically resize to fit members, move all members together, and clean up properly when nodes are deleted.

Signed-off-by: philippe-ynput philippe@ynput.io

Signed-off-by: philippe-ynput <philippe@ynput.io>
Implement comprehensive node groups feature allowing users to visually organize related nodes within colored, labeled containers.

Key additions:
- NodeGroupModel for group data storage with serialization support
- NodeGroupView with semi-transparent backgrounds, title bars, and resize handles
- NodeGroupController managing group lifecycle and member interactions
- Full API surface: create, delete, rename, add/remove members, validate
- Keyboard shortcuts: Ctrl+G (create), Ctrl+Shift+G (remove)
- Custom exceptions: GroupNotFoundError, GroupExistsError,
  NodeAlreadyInGroupError
- Configuration options for styling, padding, and color palette
- Backward-compatible graph serialization with groups metadata

Groups automatically resize to fit members, move all members together, and clean up properly when nodes are deleted.

Signed-off-by: philippe-ynput <philippe@ynput.io>
@philippe-ynput philippe-ynput added the enhancement New feature or request label Dec 15, 2025
…o group.

Signed-off-by: philippe-ynput <philippe@ynput.io>
The `_get_all_types()` function used `isinstance(type_entry, Iterable)` which incorrectly matched generic type aliases like `typing.List[Union[...]]`. When these were iterated, Python's typing system produced `typing.Unpack` special forms that still passed the `Iterable` check, causing infinite recursion.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
Add method to clear all node groups while preserving member nodes.
Implemented across model, controller, and API layers.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
The color parameter in create_node_group methods now accepts an RGBA tuple (R, G, B, A) instead of a hex string. This provides better type safety and eliminates the need for color parsing logic. The change includes:

- Updated NodeGroupController.create_node_group signature
- Removed _parse_color method as it's no longer needed
- Updated NodzAPI.create_node_group to match new signature
- Added automatic alpha channel handling for RGB tuples
- Updated docstrings and examples to reflect new format

BREAKING CHANGE: The color parameter now expects a tuple of integers (R, G, B, A) instead of a hex string. Update any code that passes color values to create_node_group methods.

Signed-off-by: philippe-ynput <philippe@ynput.io>
…and NodzAPI

Adds a new method to set the background color of node groups using RGBA tuples.
The method includes validation for group existence and handles both RGB and RGBA color inputs by providing a default alpha value when needed.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Original implementation wasn't working.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Add a new method to retrieve currently selected node names from the scene view

Signed-off-by: philippe-ynput <philippe@ynput.io>
…view

- Add group_deleted signal emission in NodeGroupController
- Update NodzView to handle deletion of both nodes and node groups
- Add group_deleted signal to ViewSignals class

Signed-off-by: philippe-ynput <philippe@ynput.io>
Add signal blocking around create_node_group and
operations to prevent unwanted signal emissions during batch operations

Signed-off-by: philippe-ynput <philippe@ynput.io>
- Reformat long lines across multiple files to comply with 79 character limit

Signed-off-by: philippe-ynput <philippe@ynput.io>
The decorator uses a context manager to ensure signals are properly
restored to their previous state, even if exceptions occur during
method execution.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
- Remove unused HANDLE_SIZE constant and related configuration
- Replace rectangular resize handles with triangular corner indicators
- Change selection border from dashed white to solid outline using group color
- Adjust title bar and handle positioning for better visual alignment

Signed-off-by: philippe-ynput <philippe@ynput.io>
- Implement group highlighting during node drag operations
- Add _clear_group_highlights() to reset visual state
- Add _find_intersecting_groups() to detect group intersections
- Add _check_drag_over_groups() for real-time drag feedback
- Update _check_drop_on_group() to use new intersection logic
- Change drop zone highlight style to solid line for better visibility

Signed-off-by: philippe-ynput <philippe@ynput.io>
Add label functionality to nodes and node groups, allowing users to set and retrieve custom display labels. Labels are rendered in the UI and can be used as cosmetic display names while preserving the original technical names.

- Add label property to NodeModel and NodeGroupModel
- Implement set/get label methods in controllers and API
- Update views to display labels (falling back to names)
- Add label support to serialization/deserialization
- Include label examples in demo script

Signed-off-by: philippe-ynput <philippe@ynput.io>
Rename AttributeError to NodzAttributeError and AttributeNotFoundError
to NodzAttributeNotFoundError to avoid shadowing Python's built-in
AttributeError exception.

BREAKING CHANGE: AttributeError renamed to NodzAttributeError and
AttributeNotFoundError renamed to NodzAttributeNotFoundError

Signed-off-by: philippe-ynput <philippe@ynput.io>
Rename exception classes to use consistent Nodz namespace prefix:
- NodeError → NodzNodeError
- NodeNotFoundError → NodzNodeNotFoundError
- NodeExistsError → NodzNodeExistsError
- ConnectionError → NodzConnectionError
- IncompatibleTypesError → NodzIncompatibleTypesError
- SelfConnectionError → NodzSelfConnectionError
- MaxConnectionsExceededError → NodzMaxConnectionsExceededError
- DuplicateConnectionError → NodzDuplicateConnectionError

BREAKING CHANGE: public error class names changed in module exports

Signed-off-by: philippe-ynput <philippe@ynput.io>
…FIXME comment

Signed-off-by: philippe-ynput <philippe@ynput.io>
Replace silent exception handling with debug logging to provide visibility
into connection cleanup failures without disrupting normal flow.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Rename group-related exception classes for consistent naming:
- NodeGroupError → NodzGroupError
- GroupNotFoundError → NodzGroupNotFoundError
- GroupExistsError → NodzGroupExistsError
- NodeAlreadyInGroupError → NodzNodeAlreadyInGroupError

Signed-off-by: philippe-ynput <philippe@ynput.io>
Signed-off-by: philippe-ynput <philippe@ynput.io>
@rdelillo rdelillo self-assigned this Jan 7, 2026
Copy link

@rdelillo rdelillo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ! Tested alongside https://github.com/ynput/ayon-workflow/pull/56 and worked like a charm.

Add explicit emit parameter to node and group operations instead of using
block_signals decorator. This provides more granular control over signal
emission and allows internal operations to avoid triggering signals while
maintaining user-triggered behavior. Update main.py to pass emit=True for
user-initiated delete and create operations.

BREAKING CHANGE: delete_node, create_node_group, and delete_node_group
methods now require emit=True to emit signals in the public API.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Add emit parameter to add_to_node_group and remove_from_node_group methods
to control whether group_membership_changed signal is emitted. This allows
batch operations to avoid redundant signal emissions.

Signed-off-by: philippe-ynput <philippe@ynput.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants