Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,22 @@ jobs:

- name: Build app with Nuitka
run: |
cd src
python -m nuitka `
--standalone `
--enable-plugin=pyside6 `
--include-qt-plugins=platforms `
--output-dir=NodeEditor_Build `
--include-package=src `
--output-dir=../NodeEditor_Build `
--nofollow-import-to=tkinter,unittest,setuptools,pip,wheel `
--windows-disable-console `
--remove-output `
--lto=yes `
--include-data-dir=examples=examples `
--include-data-dir=../examples=examples `
--include-data-dir=resources=resources `
--include-data-file=dark_theme.qss=dark_theme.qss `
--include-data-file=../dark_theme.qss=dark_theme.qss `
--assume-yes-for-downloads `
src/main.py
main.py
cd ..

- name: Copy Python runtime after Nuitka build
shell: pwsh
Expand Down
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

PyFlowGraph is a universal node-based visual scripting editor built with Python and PySide6. It allows users to create, connect, and execute Python code as nodes in a data-driven graph. The project follows a "Code as Nodes" philosophy where pins are automatically generated by parsing Python function signatures.

# git and Github

- Don't ever add that it was generated with claude at the end of comments. This is bloat! Stop that!

## Common Commands

### Running the Application
Expand Down Expand Up @@ -144,4 +148,4 @@ PyFlowGraph/
- All nodes execute in isolated environments for security
- Dependencies are managed via `requirements.txt` (PySide6, Nuitka for compilation)

- Don't add claude attribution to git commits
- Don't add claude attribution to git commits
Binary file added pre-release/PyFlowGraph-Windows-v0.7.1.zip
Binary file not shown.
10 changes: 8 additions & 2 deletions run.bat
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ if not exist "%PYTHON_SCRIPT%" (
exit /b 1
)

rem Change to src directory so Python can find modules
cd src

rem Execute the python script.
rem Any arguments passed to run.bat will be passed to main.py
rem For example: run.bat arg1 arg2
echo Running %PYTHON_SCRIPT%...
python "%PYTHON_SCRIPT%" %*
echo Running main.py from src directory...
python main.py %*

rem Return to original directory
cd ..

rem Deactivate the virtual environment after the script finishes.
call deactivate
Expand Down
10 changes: 8 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ if [ ! -f "$PYTHON_SCRIPT" ]; then
exit 1
fi

# Change to src directory so Python can find modules
cd src

# Execute the python script.
# Any arguments passed to run.sh will be passed to main.py
# For example: ./run.sh arg1 arg2
echo "Running $PYTHON_SCRIPT..."
python "$PYTHON_SCRIPT" "$@"
echo "Running main.py from src directory..."
python main.py "$@"

# Return to original directory
cd ..

# The script will automatically deactivate the venv when it exits.
# You can also add 'deactivate' here if you have cleanup commands to run after.
Expand Down
2 changes: 1 addition & 1 deletion src/code_editor_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from PySide6.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox, QTabWidget
from PySide6.QtGui import QFont
from .python_code_editor import PythonCodeEditor
from python_code_editor import PythonCodeEditor


class CodeEditorDialog(QDialog):
Expand Down
6 changes: 3 additions & 3 deletions src/execution_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# Execution controller for managing batch and live mode execution

from PySide6.QtWidgets import QPushButton, QLabel
from .graph_executor import GraphExecutor
from .event_system import LiveGraphExecutor
from .ui_utils import ButtonStyleManager
from graph_executor import GraphExecutor
from event_system import LiveGraphExecutor
from ui_utils import ButtonStyleManager


class ExecutionController:
Expand Down
2 changes: 1 addition & 1 deletion src/file_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
from PySide6.QtWidgets import QFileDialog
from PySide6.QtCore import QSettings
from .flow_format import FlowFormatHandler, extract_title_from_filename
from flow_format import FlowFormatHandler, extract_title_from_filename


class FileOperationsManager:
Expand Down
4 changes: 2 additions & 2 deletions src/graph_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import os
import sys
from collections import deque
from .node import Node
from .reroute_node import RerouteNode
from node import Node
from reroute_node import RerouteNode


class GraphExecutor:
Expand Down
14 changes: 4 additions & 10 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@

import sys
import os

# Add project root to Python path so we can import from src
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if project_root not in sys.path:
sys.path.insert(0, project_root)

from PySide6.QtWidgets import QApplication
from PySide6.QtCore import qInstallMessageHandler, QtMsgType
from PySide6.QtGui import QFontDatabase
from src.node_editor_window import NodeEditorWindow
from node_editor_window import NodeEditorWindow


def custom_message_handler(mode, context, message):
Expand All @@ -33,7 +27,7 @@ def custom_message_handler(mode, context, message):
app = QApplication(sys.argv)

# --- Load Font Awesome Regular ---
font_path_regular = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "Font Awesome 7 Free-Regular-400.otf")
font_path_regular = os.path.join(os.path.dirname(__file__), "resources", "Font Awesome 7 Free-Regular-400.otf")
if os.path.exists(font_path_regular):
font_id = QFontDatabase.addApplicationFont(font_path_regular)
if font_id == -1:
Expand All @@ -44,7 +38,7 @@ def custom_message_handler(mode, context, message):
print("Warning: Font Awesome Regular font file not found at 'resources/Font Awesome 7 Free-Regular-400.otf'", file=sys.stderr)

# --- Load Font Awesome Solid ---
font_path_solid = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "Font Awesome 6 Free-Solid-900.otf")
font_path_solid = os.path.join(os.path.dirname(__file__), "resources", "Font Awesome 6 Free-Solid-900.otf")
if os.path.exists(font_path_solid):
font_id = QFontDatabase.addApplicationFont(font_path_solid)
if font_id == -1:
Expand All @@ -56,7 +50,7 @@ def custom_message_handler(mode, context, message):

# Load the dark theme stylesheet
try:
with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "dark_theme.qss"), "r") as f:
with open("dark_theme.qss", "r") as f:
style = f.read()
app.setStyleSheet(style)
except FileNotFoundError:
Expand Down
6 changes: 3 additions & 3 deletions src/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from PySide6.QtWidgets import QGraphicsItem, QGraphicsTextItem, QGraphicsProxyWidget, QPushButton, QVBoxLayout, QWidget, QStyle, QApplication
from PySide6.QtCore import QRectF, Qt, QPointF, Signal
from PySide6.QtGui import QPainter, QColor, QBrush, QPen, QFont, QLinearGradient, QPainterPath, QContextMenuEvent, QMouseEvent
from .pin import Pin
from .code_editor_dialog import CodeEditorDialog
from .node_properties_dialog import NodePropertiesDialog
from pin import Pin
from code_editor_dialog import CodeEditorDialog
from node_properties_dialog import NodePropertiesDialog


class ResizableWidgetContainer(QWidget):
Expand Down
16 changes: 8 additions & 8 deletions src/node_editor_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
from PySide6.QtGui import QAction
from PySide6.QtCore import Qt, QPointF, QSettings

from .node_graph import NodeGraph
from .node_editor_view import NodeEditorView
from .environment_manager import EnvironmentManagerDialog
from .settings_dialog import SettingsDialog
from node_graph import NodeGraph
from node_editor_view import NodeEditorView
from environment_manager import EnvironmentManagerDialog
from settings_dialog import SettingsDialog

# Import our new modular components
from .ui_utils import create_fa_icon, create_execution_control_widget
from .file_operations import FileOperationsManager
from .execution_controller import ExecutionController
from .view_state_manager import ViewStateManager
from ui_utils import create_fa_icon, create_execution_control_widget
from file_operations import FileOperationsManager
from execution_controller import ExecutionController
from view_state_manager import ViewStateManager


class NodeEditorWindow(QMainWindow):
Expand Down
8 changes: 4 additions & 4 deletions src/node_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from PySide6.QtWidgets import QGraphicsScene, QApplication
from PySide6.QtCore import Qt, QPointF, QTimer
from PySide6.QtGui import QKeyEvent, QColor
from .node import Node
from .reroute_node import RerouteNode
from .connection import Connection
from .pin import Pin
from node import Node
from reroute_node import RerouteNode
from connection import Connection
from pin import Pin


class NodeGraph(QGraphicsScene):
Expand Down
2 changes: 1 addition & 1 deletion src/pin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from PySide6.QtWidgets import QGraphicsItem, QGraphicsTextItem
from PySide6.QtCore import QRectF, Qt
from PySide6.QtGui import QPainter, QColor, QBrush, QPen, QFont
from .color_utils import generate_color_from_string
from color_utils import generate_color_from_string


class Pin(QGraphicsItem):
Expand Down
2 changes: 1 addition & 1 deletion src/python_code_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from PySide6.QtCore import Qt, QRect, QSize
from PySide6.QtWidgets import QPlainTextEdit, QWidget, QTextEdit
from PySide6.QtGui import QColor, QPainter, QFont, QKeyEvent, QTextFormat
from .python_syntax_highlighter import PythonSyntaxHighlighter
from python_syntax_highlighter import PythonSyntaxHighlighter

class LineNumberArea(QWidget):
"""A widget that displays line numbers for a QPlainTextEdit."""
Expand Down
4 changes: 2 additions & 2 deletions src/reroute_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from PySide6.QtWidgets import QGraphicsItem, QStyle
from PySide6.QtCore import QRectF, QPointF
from PySide6.QtGui import QPainter, QColor, QBrush, QPen, QRadialGradient, QKeyEvent, QPainterPath
from .pin import Pin
from .color_utils import generate_color_from_string
from pin import Pin
from color_utils import generate_color_from_string


class RerouteNode(QGraphicsItem):
Expand Down
Loading