Right-click blocks in the graph, Document tree, or Libraries tree and choose “Port Options…”. Unified port list with:Add/remove port Name Type (Signal currently) Input/output orientation New ports start at (0, 0) in the icon editor. Connected ports cannot be removed, reoriented, or changed incompatibly. Added a PortType registry; connections require matching port types. Removed/hid the separate Add Input and Add Output workspace tools. Library port changes are written back to the library JSON. Added independent graph and icon grid-size settings. Components, interface terminals, icon shapes, resize handles, and icon ports snap to their corresponding grid. Icon canvases and component hitboxes are now fixed at 128×128. Selected icon shapes show a bottom-right resize handle. Circles preserve equal width and height while resizing. Shapes and ports are constrained to the icon hitbox. Fixed the icon-editor crash and grid behavior. Renamed the resize handle’s shape attribute, which was overriding Qt’s required shape() method. Icon shapes, resize handles, and port anchors now snap while dragging. Graph blocks and interface terminals also snap while dragging. Replaced the nearly invisible dotted graph grid with higher-contrast grid lines. Retained final release-time snapping as a safety check. Python compilation and diff validation pass.
112 lines
4.5 KiB
Python
112 lines
4.5 KiB
Python
from pathlib import Path
|
|
|
|
from PySide6.QtCore import QSettings, Signal
|
|
from PySide6.QtWidgets import QDialog, QFileDialog, QFormLayout, QGroupBox, QSpinBox
|
|
|
|
from bedit.library.repository import default_library_paths
|
|
from bedit.ui_settings_dialog import Ui_SettingsDialog
|
|
|
|
|
|
class SettingsDialog(QDialog):
|
|
"""Edit application preferences defined in the Designer form."""
|
|
|
|
settingsChanged = Signal()
|
|
|
|
def __init__(self, parent=None) -> None:
|
|
super().__init__(parent)
|
|
self.ui = Ui_SettingsDialog()
|
|
self.ui.setupUi(self)
|
|
self.grid_group = QGroupBox("Editor grids", self.ui.generalTab)
|
|
grid_form = QFormLayout(self.grid_group)
|
|
self.graph_grid_spin = QSpinBox()
|
|
self.graph_grid_spin.setRange(2, 256)
|
|
self.graph_grid_spin.setSuffix(" units")
|
|
self.icon_grid_spin = QSpinBox()
|
|
self.icon_grid_spin.setRange(1, 64)
|
|
self.icon_grid_spin.setSuffix(" units")
|
|
grid_form.addRow("Graph grid size:", self.graph_grid_spin)
|
|
grid_form.addRow("Icon grid size:", self.icon_grid_spin)
|
|
self.ui.generalLayout.insertWidget(1, self.grid_group)
|
|
self.settings = QSettings()
|
|
self.ui.addLibraryFileButton.clicked.connect(self._add_library_file)
|
|
self.ui.addLibraryFolderButton.clicked.connect(self._add_library_folder)
|
|
self.ui.removeLibraryPathButton.clicked.connect(self._remove_library_path)
|
|
self.ui.libraryPathsList.itemSelectionChanged.connect(self._update_remove_button)
|
|
self._load_settings()
|
|
|
|
def _load_settings(self) -> None:
|
|
self.ui.autosaveGroupBox.setChecked(
|
|
self.settings.value("general/autosaveEnabled", False, type=bool)
|
|
)
|
|
self.ui.autosaveIntervalSpinBox.setValue(
|
|
self.settings.value("general/autosaveInterval", 5, type=int)
|
|
)
|
|
self.ui.libraryPathsList.clear()
|
|
self.ui.libraryPathsList.addItems(self.library_paths(self.settings))
|
|
self.graph_grid_spin.setValue(self.graph_grid_size(self.settings))
|
|
self.icon_grid_spin.setValue(self.icon_grid_size(self.settings))
|
|
self._update_remove_button()
|
|
|
|
@staticmethod
|
|
def library_paths(settings: QSettings | None = None) -> list[str]:
|
|
settings = settings or QSettings()
|
|
value = settings.value("libraries/paths", default_library_paths())
|
|
if isinstance(value, str):
|
|
return [value]
|
|
return [str(path) for path in value]
|
|
|
|
@staticmethod
|
|
def graph_grid_size(settings: QSettings | None = None) -> int:
|
|
return (settings or QSettings()).value("grid/graphSize", 32, type=int)
|
|
|
|
@staticmethod
|
|
def icon_grid_size(settings: QSettings | None = None) -> int:
|
|
return (settings or QSettings()).value("grid/iconSize", 8, type=int)
|
|
|
|
def _add_library_file(self) -> None:
|
|
path, _ = QFileDialog.getOpenFileName(
|
|
self,
|
|
"Add library",
|
|
"",
|
|
"BEdit libraries (*.json);;All files (*)",
|
|
)
|
|
if path:
|
|
self._append_unique_path(path)
|
|
|
|
def _add_library_folder(self) -> None:
|
|
path = QFileDialog.getExistingDirectory(self, "Add library folder")
|
|
if path:
|
|
self._append_unique_path(path)
|
|
|
|
def _append_unique_path(self, path: str) -> None:
|
|
normalized = str(Path(path).expanduser().resolve())
|
|
existing = {
|
|
self.ui.libraryPathsList.item(row).text()
|
|
for row in range(self.ui.libraryPathsList.count())
|
|
}
|
|
if normalized not in existing:
|
|
self.ui.libraryPathsList.addItem(normalized)
|
|
|
|
def _remove_library_path(self) -> None:
|
|
for item in self.ui.libraryPathsList.selectedItems():
|
|
self.ui.libraryPathsList.takeItem(self.ui.libraryPathsList.row(item))
|
|
|
|
def _update_remove_button(self) -> None:
|
|
self.ui.removeLibraryPathButton.setEnabled(bool(self.ui.libraryPathsList.selectedItems()))
|
|
|
|
def accept(self) -> None:
|
|
self.settings.setValue("general/autosaveEnabled", self.ui.autosaveGroupBox.isChecked())
|
|
self.settings.setValue(
|
|
"general/autosaveInterval", self.ui.autosaveIntervalSpinBox.value()
|
|
)
|
|
paths = [
|
|
self.ui.libraryPathsList.item(row).text()
|
|
for row in range(self.ui.libraryPathsList.count())
|
|
]
|
|
self.settings.setValue("libraries/paths", paths)
|
|
self.settings.setValue("grid/graphSize", self.graph_grid_spin.value())
|
|
self.settings.setValue("grid/iconSize", self.icon_grid_spin.value())
|
|
self.settings.sync()
|
|
self.settingsChanged.emit()
|
|
super().accept()
|