Adding node link color as a builtin module

This commit is contained in:
ange committed 2026-01-11 22:54:40 +01:00
1 parent d08655e6c3
commit 1d78637578
3 files changed
+728

No files matched your search

+576
View File
@@ -0,0 +1,576 @@
{
"id": "c2600a8d-8eee-4d7f-a41a-8106b9c8e62a",
"name": "New Synoptik",
"description": "",
"machines": [
{
"id": "977ef95a-42db-4b36-a3e6-45e11b3ae554",
"name": "Moniteur",
"category": "Affichage",
"manufacturer": "Générique",
"model": "Display",
"inputs": [
{
"id": "b7c8b4be-e257-4eeb-ac49-ae0d19e2783c",
"name": "HDMI IN",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "977ef95a-42db-4b36-a3e6-45e11b3ae554",
"index": 0
}
],
"outputs": [],
"position": [
482,
118
],
"size": null,
"color": "#43A047",
"description": "",
"notes": ""
},
{
"id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"name": "ATEM Mini",
"category": "Mélangeur",
"manufacturer": "Blackmagic",
"model": "ATEM Mini",
"inputs": [
{
"id": "9ba74a6e-eed7-4e9a-8ff5-3ac3a50b805a",
"name": "HDMI 1",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 0
},
{
"id": "fa75c842-6730-40ac-be5c-f0e8c0b7a207",
"name": "HDMI 2",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 1
},
{
"id": "f7952365-bef5-446b-ac16-10453fc4e9fa",
"name": "HDMI 3",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 2
},
{
"id": "2fde6463-891b-4d0f-81c3-9a5835dbd6ca",
"name": "HDMI 4",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 3
},
{
"id": "37c81250-7310-4665-b9f0-2240f7b62746",
"name": "MIC 1",
"flux_type": {
"id": "208d9829-8377-42ba-b029-f5b2dae773ab",
"name": "Mini-Jack",
"category_id": "audio",
"color": "#CDDC39",
"description": "Jack 3.5mm",
"connector_type": "Jack 3.5",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 4
},
{
"id": "5a34ebc9-7159-4059-bf5a-53bde3a9a92c",
"name": "MIC 2",
"flux_type": {
"id": "208d9829-8377-42ba-b029-f5b2dae773ab",
"name": "Mini-Jack",
"category_id": "audio",
"color": "#CDDC39",
"description": "Jack 3.5mm",
"connector_type": "Jack 3.5",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 5
}
],
"outputs": [
{
"id": "42120229-c28b-4b8a-ad07-866abadcf543",
"name": "HDMI OUT",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "output",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 0
},
{
"id": "12074e22-b46c-44c5-8f6d-9ebf22135bd6",
"name": "USB-C",
"flux_type": {
"id": "82ba792c-cd4b-4f72-8e7a-cd5e7ee40a60",
"name": "USB-C",
"category_id": "data",
"color": "#1976D2",
"description": "USB Type C",
"connector_type": "USB-C",
"signal_type": "digital",
"bidirectional": false
},
"direction": "output",
"machine_id": "92b310b6-30c2-4ce7-bacd-8b58fc7d3828",
"index": 1
}
],
"position": [
180,
130
],
"size": null,
"color": "#7B1FA2",
"description": "",
"notes": ""
},
{
"id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"name": "Computer",
"category": "Other",
"manufacturer": "",
"model": "",
"inputs": [
{
"id": "1f47595c-6d7b-432c-b1d6-23a51841a9c9",
"name": "Power 19V",
"flux_type": {
"id": "5a1458ba-39eb-45b9-9a54-b1b3bab7e5f0",
"name": "AC Power",
"category_id": "power",
"color": "#F44336",
"description": "Alimentation secteur",
"connector_type": "IEC C13/C14",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"index": 0
},
{
"id": "d511b4d2-1d4c-4136-a477-be049c754251",
"name": "Thunderbolt",
"flux_type": {
"id": "1fcaba72-4f84-4b89-bd71-ac035fb25410",
"name": "Thunderbolt",
"category_id": "data",
"color": "#0D47A1",
"description": "Thunderbolt",
"connector_type": "USB-C/TB",
"signal_type": "digital",
"bidirectional": false
},
"direction": "input",
"machine_id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"index": 1
}
],
"outputs": [
{
"id": "be40fa42-a59b-4c96-9e7a-07648e32c569",
"name": "Video Out",
"flux_type": {
"id": "6ff480b3-ac5e-4cc0-b57a-57fdff8d2074",
"name": "HDMI",
"category_id": "video",
"color": "#E91E63",
"description": "High-Definition Multimedia Interface",
"connector_type": "HDMI Type A",
"signal_type": "digital",
"bidirectional": false
},
"direction": "output",
"machine_id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"index": 0
},
{
"id": "cc1c4377-2728-4990-b88b-d05c0759bc07",
"name": "Audio Out",
"flux_type": {
"id": "208d9829-8377-42ba-b029-f5b2dae773ab",
"name": "Mini-Jack",
"category_id": "audio",
"color": "#CDDC39",
"description": "Jack 3.5mm",
"connector_type": "Jack 3.5",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"index": 1
},
{
"id": "ade49023-865a-40a5-b2e8-c3cc7dc53f13",
"name": "USB C",
"flux_type": {
"id": "82ba792c-cd4b-4f72-8e7a-cd5e7ee40a60",
"name": "USB-C",
"category_id": "data",
"color": "#1976D2",
"description": "USB Type C",
"connector_type": "USB-C",
"signal_type": "digital",
"bidirectional": false
},
"direction": "output",
"machine_id": "7c9eb69c-5ba0-40b4-8236-fc51bed5816d",
"index": 2
}
],
"position": [
106,
405
],
"size": null,
"color": "#b65c5c",
"description": "",
"notes": ""
},
{
"id": "fb546022-cc29-4de7-80f7-fb8f4132cee1",
"name": "Convertisseur mini-jack XLR F x2",
"category": "Source",
"manufacturer": "",
"model": "",
"inputs": [
{
"id": "a6ce0b54-b36f-4b74-9ad5-fa29af6cde0e",
"name": "mini-jack M",
"flux_type": {
"id": "208d9829-8377-42ba-b029-f5b2dae773ab",
"name": "Mini-Jack",
"category_id": "audio",
"color": "#CDDC39",
"description": "Jack 3.5mm",
"connector_type": "Jack 3.5",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "fb546022-cc29-4de7-80f7-fb8f4132cee1",
"index": 0
}
],
"outputs": [
{
"id": "d1eafcfa-fbc9-4d0d-a42d-f8023de2732b",
"name": "XLR M",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "fb546022-cc29-4de7-80f7-fb8f4132cee1",
"index": 0
},
{
"id": "eb343957-e039-4207-a561-0e9b35b56706",
"name": "XLR F",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "fb546022-cc29-4de7-80f7-fb8f4132cee1",
"index": 1
}
],
"position": [
295,
475
],
"size": null,
"color": "#2d2d2d",
"description": "",
"notes": ""
},
{
"id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"name": "Console Audio",
"category": "Audio",
"manufacturer": "Générique",
"model": "Mixer 8CH",
"inputs": [
{
"id": "c09a0980-5912-4f4f-9119-1438d33d4ef3",
"name": "XLR 1",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 0
},
{
"id": "d527d52a-fa9e-4636-86f8-c8d542504ad2",
"name": "XLR 2",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 1
},
{
"id": "309bd756-e11d-4e78-b422-ad0493e493af",
"name": "XLR 3",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 2
},
{
"id": "5e86f501-c332-43d5-a798-4026e86138eb",
"name": "XLR 4",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 3
},
{
"id": "db7c2b04-8218-4249-bcb8-d53d47c53874",
"name": "LINE 5",
"flux_type": {
"id": "087e6684-ced6-4988-9e75-20987e62f23e",
"name": "Jack 6.35",
"category_id": "audio",
"color": "#8BC34A",
"description": "Jack 6.35mm TRS",
"connector_type": "Jack 6.35",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 4
},
{
"id": "508d0179-1db9-4497-a322-49b19da9e4f4",
"name": "LINE 6",
"flux_type": {
"id": "087e6684-ced6-4988-9e75-20987e62f23e",
"name": "Jack 6.35",
"category_id": "audio",
"color": "#8BC34A",
"description": "Jack 6.35mm TRS",
"connector_type": "Jack 6.35",
"signal_type": "analog",
"bidirectional": false
},
"direction": "input",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 5
}
],
"outputs": [
{
"id": "c96530da-3f03-407f-a5fd-04554adec3a0",
"name": "MAIN L",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 0
},
{
"id": "1f796e4b-2b49-475f-807b-a4323807702f",
"name": "MAIN R",
"flux_type": {
"id": "c30669a9-da43-4eb0-a2d0-8be4a093a803",
"name": "XLR",
"category_id": "audio",
"color": "#4CAF50",
"description": "XLR Audio Connector",
"connector_type": "XLR 3-pin",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 1
},
{
"id": "cc122298-c1c2-4bb5-8c5b-06689260ec42",
"name": "AUX 1",
"flux_type": {
"id": "087e6684-ced6-4988-9e75-20987e62f23e",
"name": "Jack 6.35",
"category_id": "audio",
"color": "#8BC34A",
"description": "Jack 6.35mm TRS",
"connector_type": "Jack 6.35",
"signal_type": "analog",
"bidirectional": false
},
"direction": "output",
"machine_id": "708a37ab-e7a3-4914-a33c-79622125a2d9",
"index": 2
}
],
"position": [
621,
517
],
"size": null,
"color": "#00897B",
"description": "",
"notes": ""
}
],
"connections": [
{
"id": "3f724852-0c6b-4431-925a-71f55164b216",
"source_port_id": "42120229-c28b-4b8a-ad07-866abadcf543",
"target_port_id": "b7c8b4be-e257-4eeb-ac49-ae0d19e2783c",
"label": "",
"color": null
},
{
"id": "ab2a63fb-d6e6-4ce4-82f5-56c5b5f30d84",
"source_port_id": "cc1c4377-2728-4990-b88b-d05c0759bc07",
"target_port_id": "a6ce0b54-b36f-4b74-9ad5-fa29af6cde0e",
"label": "",
"color": null
},
{
"id": "bb8c9546-c159-4f8c-bd40-abe062e252bd",
"source_port_id": "d1eafcfa-fbc9-4d0d-a42d-f8023de2732b",
"target_port_id": "c09a0980-5912-4f4f-9119-1438d33d4ef3",
"label": "",
"color": null
},
{
"id": "6a6edeb5-c54e-417b-b520-028079ee0521",
"source_port_id": "eb343957-e039-4207-a561-0e9b35b56706",
"target_port_id": "d527d52a-fa9e-4636-86f8-c8d542504ad2",
"label": "",
"color": null
}
],
"custom_flux_types": [],
"created_at": "2026-01-11T22:45:46.506865",
"modified_at": "2026-01-11T22:51:58.198843"
}
+8
View File
@@ -264,6 +264,14 @@ class NodeEditorPanel:
"""Get port ID from attribute tag."""
return self._attr_to_port.get(attr_tag)
def get_link_tag(self, connection_id: str) -> Optional[str]:
"""Get DPG link tag for a connection ID."""
return self._conn_to_link.get(connection_id)
def get_attr_tag(self, port_id: str) -> Optional[str]:
"""Get DPG attribute tag for a port ID."""
return self._port_to_attr.get(port_id)
def _create_port_attribute(self, port, is_input: bool) -> str:
"""Create a node attribute for a port."""
flux_color = hex_to_rgba(port.flux_type.color)
+144
View File
@@ -0,0 +1,144 @@
"""
Colored Links Module - Colorize connections based on flux type.
This module automatically applies the flux type color to connection links
in the node editor, making it easier to visually identify signal types.
"""
import dearpygui.dearpygui as dpg
from synodetik.modules import Module, ModuleInfo
from synodetik.events import EventType
from synodetik.gui.themes import hex_to_rgba
class ColoredLinksModule(Module):
"""
Colorizes node editor links based on flux type color.
When a connection is created, this module automatically applies
the source port's flux type color to the link, providing visual
consistency between port colors and connection colors.
"""
def __init__(self):
super().__init__()
# Track created themes for cleanup
self._link_themes: dict[str, int] = {}
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
id="colored_links",
name="Colored Links",
version="1.0.0",
author="Synodetik",
description="Colorize connections based on flux type"
)
def on_load(self) -> bool:
"""Subscribe to connection events."""
self.events.on(EventType.CONNECTION_CREATED, self._on_connection_created)
self.events.on(EventType.SYNOPTIK_LOADED, self._on_synoptik_loaded)
# Colorize any existing connections
self._colorize_all_connections()
print(f"[{self.info.name}] Module loaded")
return True
def on_unload(self) -> None:
"""Unsubscribe and clean up themes."""
self.events.off(EventType.CONNECTION_CREATED, self._on_connection_created)
self.events.off(EventType.SYNOPTIK_LOADED, self._on_synoptik_loaded)
# Clean up all created themes
for theme_id in self._link_themes.values():
if dpg.does_item_exist(theme_id):
dpg.delete_item(theme_id)
self._link_themes.clear()
print(f"[{self.info.name}] Module unloaded")
def _on_connection_created(self, event) -> None:
"""Handle new connection creation."""
connection = event.data.get('connection')
if connection:
self._colorize_link(connection)
def _on_synoptik_loaded(self, event) -> None:
"""Handle synoptik load - colorize all connections."""
# Small delay to ensure UI is ready
self._colorize_all_connections()
def _colorize_all_connections(self) -> None:
"""Colorize all existing connections in the current synoptik."""
if not self.app or not self.app.synoptik:
return
for connection in self.app.synoptik.connections:
self._colorize_link(connection)
def _colorize_link(self, connection) -> None:
"""Apply flux color to a connection link."""
if not self.app or not self.app.synoptik or not self.app.node_editor:
return
# Get the source port to determine flux color
source_port = self.app.synoptik._find_port(connection.source_port_id)
if not source_port:
return
# Get flux color
flux_color = source_port.flux_type.color
# Get the DPG link tag
link_tag = self.app.node_editor.get_link_tag(connection.id)
if not link_tag or not dpg.does_item_exist(link_tag):
return
# Create and apply theme
theme = self._create_link_theme(connection.id, flux_color)
dpg.bind_item_theme(link_tag, theme)
def _create_link_theme(self, connection_id: str, color: str) -> int:
"""Create a DPG theme for a colored link."""
# Clean up existing theme for this connection if any
if connection_id in self._link_themes:
old_theme = self._link_themes[connection_id]
if dpg.does_item_exist(old_theme):
dpg.delete_item(old_theme)
# Convert hex color to RGBA
rgba = hex_to_rgba(color)
# Create theme with link colors
with dpg.theme() as link_theme:
with dpg.theme_component(dpg.mvNodeLink):
dpg.add_theme_color(
dpg.mvNodeCol_Link,
rgba,
category=dpg.mvThemeCat_Nodes
)
dpg.add_theme_color(
dpg.mvNodeCol_LinkHovered,
self._brighten_color(rgba, 1.3),
category=dpg.mvThemeCat_Nodes
)
dpg.add_theme_color(
dpg.mvNodeCol_LinkSelected,
self._brighten_color(rgba, 1.5),
category=dpg.mvThemeCat_Nodes
)
self._link_themes[connection_id] = link_theme
return link_theme
def _brighten_color(self, rgba: tuple, factor: float) -> tuple:
"""Brighten a color by a factor."""
r, g, b, a = rgba
return (
min(255, int(r * factor)),
min(255, int(g * factor)),
min(255, int(b * factor)),
a
)