Fixed a bunch of crap

This commit is contained in:
2025-02-11 23:48:09 -07:00
parent 6c757e72a4
commit 584e229c1c
22 changed files with 513 additions and 213 deletions

0
Nodes/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

49
Nodes/array_node.py Normal file
View File

@ -0,0 +1,49 @@
from NodeGraphQt import BaseNode
class ArrayNode(BaseNode):
"""
Array Node:
- Inputs: 'in' (value to store), 'ArraySize' (defines maximum length)
- Output: 'Array' (the current array as a string)
- Stores incoming values in an array with size defined by ArraySize.
When full, it removes the oldest value.
"""
__identifier__ = 'io.github.nicole.array'
NODE_NAME = 'Array'
def __init__(self):
super(ArrayNode, self).__init__()
self.values = {} # Ensure values is a dictionary.
self.add_input('in')
self.add_input('ArraySize')
self.add_output('Array')
self.array = []
self.value = "[]" # Output as a string.
self.array_size = 10 # Default array size.
self.set_name("Array: []")
def process_input(self):
# Get array size from 'ArraySize' input if available.
size_port = self.input('ArraySize')
connected_size = size_port.connected_ports() if size_port is not None else []
if connected_size:
connected_port = connected_size[0]
parent_node = connected_port.node()
try:
self.array_size = int(float(getattr(parent_node, 'value', 10)))
except (ValueError, TypeError):
self.array_size = 10
# Get new value from 'in' input if available.
in_port = self.input('in')
connected_in = in_port.connected_ports() if in_port is not None else []
if connected_in:
connected_port = connected_in[0]
parent_node = connected_port.node()
new_value = getattr(parent_node, 'value', None)
if new_value is not None:
self.array.append(new_value)
while len(self.array) > self.array_size:
self.array.pop(0)
self.value = str(self.array)
self.set_name(f"Array: {self.value}")

36
Nodes/average_node.py Normal file
View File

@ -0,0 +1,36 @@
from NodeGraphQt import BaseNode
class AverageNode(BaseNode):
"""
Average Node:
- Inputs: A, B, C (adjustable as needed)
- Output: Result (the average of the inputs)
"""
__identifier__ = 'io.github.nicole.average'
NODE_NAME = 'Average'
def __init__(self):
super(AverageNode, self).__init__()
self.values = {} # Ensure values is a dictionary.
self.add_input('A')
self.add_input('B')
self.add_input('C')
self.add_output('Result')
self.value = 0
self.set_name("Average: 0")
def process_input(self):
values = []
for port_name in ['A', 'B', 'C']:
port = self.input(port_name)
connected = port.connected_ports() if port is not None else []
if connected:
connected_port = connected[0]
parent_node = connected_port.node()
try:
values.append(float(getattr(parent_node, 'value', 0)))
except (ValueError, TypeError):
pass
avg = sum(values) / len(values) if values else 0
self.value = avg
self.set_name(f"Average: {avg}")

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""
Character Status Node
This node represents the character's status. It has no input ports and four output ports:
- HP, MP, FP, EXP.
It polls an API endpoint (http://127.0.0.1:5000/data) every 500 ms to update its values.
If the API call is successful, the node's title is set to "Character Status (API Connected)".
If the API is down or returns an error, the title is set to "Character Status (API Disconnected)".
"""
from NodeGraphQt import BaseNode
from Qt import QtCore, QtGui
import requests
def get_draw_stat_port(color, border_color=None, alpha=127):
"""
Returns a custom port painter function that draws a circular port with a
semi-transparent fill and then draws text (port label and current value)
next to it.
"""
if border_color is None:
border_color = color
def painter_func(painter, rect, info):
painter.save()
# Draw the port circle.
pen = QtGui.QPen(QtGui.QColor(*border_color))
pen.setWidth(1.8)
painter.setPen(pen)
semi_transparent_color = QtGui.QColor(color[0], color[1], color[2], alpha)
painter.setBrush(semi_transparent_color)
painter.drawEllipse(rect)
# Draw the label and current value.
port = info.get('port')
if port is not None:
node = port.node()
stat = port.name()
# Use the node's 'values' dictionary if available.
value = node.values.get(stat, "N/A") if hasattr(node, 'values') else "N/A"
text_rect = rect.adjusted(rect.width() + 4, 0, rect.width() + 70, 0)
painter.setPen(QtGui.QColor(0, 0, 0))
painter.drawText(text_rect, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft,
f"{stat}: {value}")
painter.restore()
return painter_func
class CharacterStatusNode(BaseNode):
__identifier__ = 'io.github.nicole.status'
NODE_NAME = 'Character Status'
def __init__(self):
super(CharacterStatusNode, self).__init__()
# Initialize the output values as a dictionary.
self.values = {"HP": "N/A", "MP": "N/A", "FP": "N/A", "EXP": "N/A"}
# Add output ports for each stat with custom painters.
self.add_output("HP", painter_func=get_draw_stat_port((255, 0, 0))) # Red for HP
self.add_output("MP", painter_func=get_draw_stat_port((0, 0, 255))) # Blue for MP
self.add_output("FP", painter_func=get_draw_stat_port((0, 255, 0))) # Green for FP
self.add_output("EXP", painter_func=get_draw_stat_port((127, 255, 212))) # Aquamarine for EXP
# Set an initial title.
self.set_name("Character Status (API Disconnected)")
# Create a QTimer that polls the API every 500ms.
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.poll_api)
self.timer.start(500)
def poll_api(self):
"""
Polls the API endpoint to retrieve the latest character stats and updates
the node's internal values. Expects a JSON response with keys:
- "hp", "mp", "fp", "exp"
"""
try:
response = requests.get("http://127.0.0.1:5000/data", timeout=1)
if response.status_code == 200:
data = response.json()
# Update the values dictionary.
self.values["HP"] = data.get("hp", "0/0")
self.values["MP"] = data.get("mp", "0/0")
self.values["FP"] = data.get("fp", "0/0")
self.values["EXP"] = data.get("exp", "0.0000")
self.set_name("Character Status (API Connected)")
self.update()
else:
self.set_name("Character Status (API Disconnected)")
except Exception as e:
self.set_name("Character Status (API Disconnected)")
print("Error polling API in CharacterStatusNode:", e)

View File

@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""
Convert to Percent Node
This node takes an input string formatted as "numerator/denom" (e.g., "50/50"),
splits it into two numbers, computes (numerator / denom) * 100, and outputs the result
as a float formatted to 4 decimal places. If an error occurs, an error message is stored.
The node's title is always "Convert to Percent".
"""
from NodeGraphQt import BaseNode
from Qt import QtCore
class ConvertToPercentNode(BaseNode):
__identifier__ = 'io.github.nicole.convert'
NODE_NAME = 'Convert to Percent'
def __init__(self):
super(ConvertToPercentNode, self).__init__()
# Add one input port (expects a string in "numerator/denom" format).
self.add_input("in")
# Add one output port.
self.add_output("Percent")
# Initialize internal value.
self.value = "No Input"
# Set the node title to a static string.
self.set_name(self.NODE_NAME)
# Initialize a values dictionary so that connected Display nodes can read output.
self.values = {}
def process_input(self):
input_port = self.input(0)
connected_ports = input_port.connected_ports() if input_port is not None else []
if connected_ports:
connected_output = connected_ports[0]
parent_node = connected_output.node()
port_name = connected_output.name()
# Use parent's values dictionary if available, else use its value attribute.
if hasattr(parent_node, 'values') and isinstance(parent_node.values, dict):
input_value = parent_node.values.get(port_name, "")
else:
input_value = getattr(parent_node, 'value', "")
input_str = str(input_value).strip()
try:
parts = input_str.split('/')
if len(parts) != 2:
raise ValueError("Input must be in the format 'num/denom'")
numerator = float(parts[0].strip())
denominator = float(parts[1].strip())
if denominator == 0:
raise ZeroDivisionError("Division by zero")
percent = (numerator / denominator) * 100
formatted_percent = f"{percent:.4f}"
self.value = formatted_percent
except Exception as e:
self.value = f"Error: {e}"
else:
self.value = "No Input"
# Always keep the title static.
self.set_name(self.NODE_NAME)
# Store the computed value in the values dictionary under the output port key.
self.values["Percent"] = self.value

113
Nodes/data_node.py Normal file
View File

@ -0,0 +1,113 @@
#!/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 NodeGraphQt import BaseNode
class DataNode(BaseNode):
__identifier__ = 'io.github.nicole.data'
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: {self.value}")
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:
# Connect the textChanged signal if available.
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
self.set_name(f"Data Node: {self.value}")
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)
output_port.send_data(input_value)
elif output_port.connected_ports():
# Only output is connected; allow manual input.
self.get_widget('value').setEnabled(True)
output_port.send_data(self.get_property('value'))
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()

36
Nodes/multiply_node.py Normal file
View File

@ -0,0 +1,36 @@
from NodeGraphQt import BaseNode
class MultiplyNode(BaseNode):
"""
Multiply Node:
- Inputs: A, B
- Output: Result (A * B)
"""
__identifier__ = 'io.github.nicole.multiply'
NODE_NAME = 'Multiply'
def __init__(self):
super(MultiplyNode, self).__init__()
self.values = {} # Ensure values is a dictionary.
self.add_input('A')
self.add_input('B')
self.add_output('Result')
self.value = 0
def process_input(self):
inputs = {}
for port_name in ['A', 'B']:
port = self.input(port_name)
connected = port.connected_ports() if port is not None else []
if connected:
connected_port = connected[0]
parent_node = connected_port.node()
try:
inputs[port_name] = float(getattr(parent_node, 'value', 0))
except (ValueError, TypeError):
inputs[port_name] = 0.0
else:
inputs[port_name] = 0.0
result = inputs['A'] * inputs['B']
self.value = result
self.set_name(f"Multiply: {result}")

37
Nodes/subtract_node.py Normal file
View File

@ -0,0 +1,37 @@
# Nodes/subtract_node.py
from NodeGraphQt import BaseNode
class SubtractNode(BaseNode):
"""
Subtract Node:
- Inputs: A, B
- Output: Result (A - B)
"""
__identifier__ = 'io.github.nicole.subtract'
NODE_NAME = 'Subtract'
def __init__(self):
super(SubtractNode, self).__init__()
self.add_input('A')
self.add_input('B')
self.add_output('Result')
self.value = 0
def process_input(self):
inputs = {}
for port_name in ['A', 'B']:
port = self.input(port_name)
connected = port.connected_ports() if port is not None else []
if connected:
connected_port = connected[0]
parent_node = connected_port.node()
try:
inputs[port_name] = float(getattr(parent_node, 'value', 0))
except (ValueError, TypeError):
inputs[port_name] = 0.0
else:
inputs[port_name] = 0.0
result = inputs['A'] - inputs['B']
self.value = result
self.set_name(f"Subtract: {result}")