#!/usr/bin/env python3 """ Data Node: - Input: Accepts a value (string, integer, or float) from an input port. - Output: Outputs the current value, either from the input port or set manually via a text box. Behavior: - If both input and output are connected: - Acts as a passthrough, displaying the input value and transmitting it to the output. - Manual input is disabled. - If only the output is connected: - Allows manual value entry, which is sent to the output. - If only the input is connected: - Displays the input value but does not transmit it further. """ from OdenGraphQt import BaseNode class DataNode(BaseNode): __identifier__ = 'bunny-lab.io.data_node' NODE_NAME = 'Data Node' def __init__(self): super(DataNode, self).__init__() # Add input and output ports. self.add_input('Input') self.add_output('Output') # Add a text input widget for manual entry. self.add_text_input('value', 'Value', text='') # Initialize the value from the widget property. self.process_widget_event() self.set_name(f"Data Node") def post_create(self): """ Called after the node's widget is fully created. Connect the text input widget's textChanged signal to process_widget_event. """ text_widget = self.get_widget('value') if text_widget is not None: try: text_widget.textChanged.connect(self.process_widget_event) except Exception as e: print("Error connecting textChanged signal:", e) def process_widget_event(self, event=None): """ Reads the current text from the node's property and updates the node's internal value. """ current_text = self.get_property('value') self.value = current_text def property_changed(self, property_name): """ Called when a node property changes. If the 'value' property changes, update the internal value. """ if property_name == 'value': self.process_widget_event() def update_stream(self): """ Updates the node's behavior based on the connection states. """ input_port = self.input(0) output_port = self.output(0) if input_port.connected_ports() and output_port.connected_ports(): # Both input and output are connected; act as passthrough. self.set_property('value', '') self.get_widget('value').setEnabled(False) input_value = input_port.connected_ports()[0].node().get_property('value') self.set_property('value', input_value) elif output_port.connected_ports(): # Only output is connected; allow manual input. self.get_widget('value').setEnabled(True) elif input_port.connected_ports(): # Only input is connected; display input value. self.get_widget('value').setEnabled(False) input_value = input_port.connected_ports()[0].node().get_property('value') self.set_property('value', input_value) else: # Neither input nor output is connected; allow manual input. self.get_widget('value').setEnabled(True) def on_input_connected(self, input_port, output_port): """ Called when an input port is connected. """ self.update_stream() def on_input_disconnected(self, input_port, output_port): """ Called when an input port is disconnected. """ self.update_stream() def on_output_connected(self, output_port, input_port): """ Called when an output port is connected. """ self.update_stream() def on_output_disconnected(self, output_port, input_port): """ Called when an output port is disconnected. """ self.update_stream() def receive_data(self, data, source_port_name=None): """ Receives data from connected nodes and updates the internal value. """ self.set_property('value', str(data)) # Ensure it's always stored as a string # Transmit data further if there's an output connection output_port = self.output(0) if output_port and output_port.connected_ports(): for connected_port in output_port.connected_ports(): connected_node = connected_port.node() if hasattr(connected_node, 'receive_data'): connected_node.receive_data(data, source_port_name)