Files
BondGraph/BEdit/README.md
Joppe Blondel 48a2b4c8d0 Reorganized the application around a clear frontend/backend boundary.
src/bedit/
├── __main__.py
├── core/                   # Pure Python, no PySide
│   ├── model.py
│   ├── port_types.py
│   ├── serializer.py
│   └── libraries.py
└── gui/                    # All Qt-dependent code
    ├── app.py
    ├── main_window.py
    ├── preferences.py
    ├── controllers/
    ├── dialogs/
    ├── graphics/
    ├── models/
    └── generated/          # Designer/resource output only
Notable improvements:
Domain models, serialization, port types, and library parsing are now Qt-free.
Qt signals and undo infrastructure are explicitly isolated under gui/controllers.
Library parsing is separated from the Qt repository and tree models.
All generated Python is contained in gui/generated.
Designer build tasks now write to the generated directory.
The application entry point and package metadata use the new paths.
README now documents the structure and dependency rules.
Removed the old mixed document, library, and workspace packages.
2026-07-20 12:09:00 +02:00

194 lines
7.9 KiB
Markdown

# BEdit Qt starter
A small desktop application scaffold using Python and PySide6 (the official Qt
bindings). Its interface is maintained in Qt Designer and it includes a main
window, menu bar, blank central workspace, common keyboard shortcuts, and
persisted window geometry. The application forces Qt's light Fusion palette, so
it remains light even when the operating-system theme is dark.
## Run it
Python 3.10 or newer is required. From this directory:
```bash
python -m venv .venv
```
Activate the environment:
- Windows PowerShell: `.venv\Scripts\Activate.ps1`
- Windows Command Prompt: `.venv\Scripts\activate.bat`
- Linux/macOS: `source .venv/bin/activate`
Then install and launch:
```bash
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m bedit
```
After installation, the `bedit` command also launches the application.
## Project layout
```text
.
├── pyproject.toml dependencies, package metadata, and `bedit` command
├── README.md
├── ui/ editable Qt Designer sources
└── src/bedit
├── __main__.py minimal `python -m bedit` entry point
├── core/ Qt-free domain model, port types, files, libraries
└── gui/ every PySide-dependent module
├── app.py Qt startup and application palette
├── main_window.py top-level UI orchestration
├── controllers/ document controller and undo commands
├── dialogs/ dialog behavior
├── graphics/ graph workspace and vector icon editor
├── models/ Qt tree models and repository adapters
└── generated/ generated UI/resources; do not hand-edit
```
## Designing the UI further
The project now uses Qt Designer. It is included with PySide6 on most
installations. Open the existing form with:
```bash
pyside6-designer ui/main_window.ui
```
In Designer, use the Widget Box to add controls, the Object Inspector to select
them, and the Property Editor to name and configure them. Always put widgets in
a layout (horizontal, vertical, grid, or form) so the window resizes correctly.
Save the form, close the running application if necessary, then regenerate its
Python wrapper:
```bash
pyside6-uic --from-imports ui/main_window.ui \
-o src/bedit/gui/generated/ui_main_window.py
```
Do not hand-edit files in `gui/generated`; change the `.ui` source and regenerate
it. Add behavior and signal connections in `gui/main_window.py`. Widget names from
Designer are available there through `self.ui`, such as `self.ui.graphView`.
In VS Code, the same commands are available through **Terminal → Run Task**:
- **Qt: Open Main Window in Designer** opens the form for visual editing.
- **Qt: Build Designer Files** compiles resources and then regenerates the UI
wrapper. It is the default build task, available with `Ctrl+Shift+B`.
- The separate resource and UI compilation tasks remain available when only one
generated file needs rebuilding.
## Architecture rules
- `bedit.core` must remain importable without PySide6.
- `bedit.gui` may depend on `core`; `core` must never import `gui`.
- Designer output and resource output belong only in `gui/generated`.
- Domain serialization and library parsing stay in `core`; Qt signals, models,
undo integration, painting, and widgets stay in `gui`.
## Graph and library prototype
Documents and libraries use the same recursive format: a library is simply a
BEdit document used as a copy source. The built-in example defines A, B, and C.
- A document can own multiple independent top-level graph or text components.
Right-click **Current Document** to create one, and double-click a current
component in the tree to activate it.
- Drag a component from Libraries onto the workspace. Placement recursively
copies it with new IDs, leaving no link to the source.
- Drag components to move them; movement participates in undo and redo.
- Components, interface terminals, and connections are selectable. Use a rubber
band or Ctrl-click for multiple selection, Delete to remove items, and the
standard Cut/Copy/Paste shortcuts to duplicate selected component groups.
- Click an output port and then an input port to create a connection.
- Double-click a graph component to open its owned subgraph; use **Up** to return.
- Graph components show **Pointer**, **Input**, and **Output** tools. Select an
interface tool and click the canvas to add a visible internal terminal and a
corresponding external block port. Interface terminals can be moved afterward.
- Right-click a component on the canvas or in Current Document to edit its name,
icon shape, icon text, fill color, and border color. The same dialog can hide
that component's contained subtree from the Libraries tree.
- Double-click a text component to edit its input list, output list, and
`implementation.source` JSON.
- Right-click any graph component under Current Document to add nested graph or
text blocks. Any current-document component can also be deleted there.
- The active document hierarchy has its own Document panel; the Libraries panel
contains only configured external libraries.
- Select one or more blocks and press `Ctrl+R`, or use the Transform toolbar, to
rotate them clockwise by 90 degrees. Rotation is saved and supports undo/redo.
**Apply JSON** updates that source and participates in undo/redo.
- File → Save writes the complete recursive document to JSON.
- File → Close Document removes the active document and returns to an empty
workspace. An open graph uses a light gray, 32-unit dotted canvas.
- Edit → Settings → Libraries accepts document files or folders of JSON files.
Every component owns its ports, declarative icon, properties, and child graph:
```json
{
"format": "bedit-document",
"version": 1,
"roots": [{
"id": "my-component",
"name": "My Component",
"position": {"x": 0, "y": 0},
"interface": {
"inputs": [{"id": "in", "name": "Input", "type": "signal", "properties": {
"iconPosition": {"x": 0, "y": 40}
}}],
"outputs": [{"id": "out", "name": "Output", "type": "signal", "properties": {
"iconPosition": {"x": 128, "y": 64}
}}]
},
"icon": {
"size": {"width": 128, "height": 128},
"elements": [{
"type": "rectangle", "x": 32, "y": 32,
"width": 64, "height": 64,
"cornerRadius": 5,
"fill": "#dbeafe", "stroke": "#245c9c",
"lineWidth": 1.5, "lineStyle": "solid"
}]
},
"properties": {},
"implementation": {
"kind": "text",
"source": {
"equations": ["out = gain * in"],
"parameters": {"gain": 1.0}
}
}
}]
}
```
Graph components use `"implementation": {"kind": "graph", "graph": ...}`;
text components use `"implementation": {"kind": "text", "source": ...}` and
never own a graph. Vector icons can contain rectangles, circles, ellipses,
lines, triangles, and text. Each element owns its geometry, fill, stroke, and
line style; ports keep their icon anchor in `properties.iconPosition`. The
port type registry controls which types may connect (currently `signal` only).
The workspace grid size, its finer snapping size, and the icon grid size are
configured independently in Settings. The recursive model and file loading are
under `src/bedit/core/`; the live Qt trees and graphics are isolated under
`src/bedit/gui/models/` and `src/bedit/gui/graphics/`.
## Optional tools
You do not need another GUI framework. Useful additions are:
- **Qt Designer** for drag-and-drop form layout.
- **Ruff** for formatting/linting (`ruff check .`).
- **pytest-qt** later for GUI interaction tests.
- **PyInstaller** or **Nuitka** later to produce a Windows `.exe`.
The light colors are defined in `apply_light_theme()` in `src/bedit/app.py`.
Adjust that palette if you want different light colors. Avoid a large stylesheet
unless the application needs highly customized controls; palettes preserve more
of Qt's standard behavior.