Library drag-in
This commit is contained in:
@@ -182,6 +182,7 @@ class GraphEditorClipboardHandler(ClipboardHandler):
|
||||
self.editor = editor
|
||||
self.clipboard = clipboard
|
||||
editor.scene.selectionChanged.connect(self.availability_changed)
|
||||
editor.component_drop_requested.connect(self.drop_components)
|
||||
|
||||
def owns_focus(self, widget: QWidget) -> bool:
|
||||
return widget is self.editor or self.editor.isAncestorOf(widget)
|
||||
@@ -214,12 +215,19 @@ class GraphEditorClipboardHandler(ClipboardHandler):
|
||||
payload = self.clipboard.get_json(ClipboardService.COMPONENTS_MIME)
|
||||
if graph_component is None or not isinstance(graph_component.implementation, GraphImplementation) or payload is None:
|
||||
return
|
||||
x, y = self.editor.paste_position()
|
||||
self._paste_payload(graph_component, payload, (x, y))
|
||||
|
||||
def drop_components(self, graph_component: Component, payload: dict, position: tuple[int, int]) -> None:
|
||||
self._paste_payload(graph_component, payload, position)
|
||||
|
||||
def _paste_payload(self, graph_component: Component, payload: dict, position: tuple[int, int]) -> None:
|
||||
try:
|
||||
components, icons = import_components(payload)
|
||||
except (TypeError, ValueError) as exc:
|
||||
QMessageBox.critical(self.editor, "Could not paste components", str(exc))
|
||||
return
|
||||
x, y = self.editor.paste_position()
|
||||
x, y = position
|
||||
spacing = self.editor.snap_to_grid_size * 4
|
||||
positions = {component_id: (x + index * spacing, y + index * spacing) for index, component_id in enumerate(components)}
|
||||
self.document.paste_graph_components(graph_component, components, icons, positions)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
from PySide6.QtCore import QObject, QSize
|
||||
from PySide6.QtCore import QObject, QSize, Qt
|
||||
from PySide6.QtWidgets import QAbstractItemView, QHeaderView
|
||||
|
||||
from bedit_core.models import Component, ComponentID, GraphImplementation
|
||||
from bedit_gui.models import Icon, IconDatabase
|
||||
from bedit_gui.services.application_settings import ApplicationSettings
|
||||
from bedit_gui.services.component_clipboard import export_component_data
|
||||
from bedit_gui.services.libraries import load_library_documents
|
||||
from bedit_gui.utils.icon import render_fitted_icon
|
||||
from bedit_gui.views.main_window import MainWindow
|
||||
from bedit_gui.views.models.document_tree_model import DocumentTreeModel
|
||||
from bedit_gui.views.models.library_tree_model import LibraryTreeModel
|
||||
|
||||
ICON_SIZE = QSize(32, 32)
|
||||
|
||||
@@ -17,13 +18,17 @@ class LibraryController(QObject):
|
||||
super().__init__(window)
|
||||
self.window = window
|
||||
self.settings = settings
|
||||
self.model = DocumentTreeModel(editable=False)
|
||||
self._component_sources: dict[int, tuple[ComponentID, dict[ComponentID, Icon]]] = {}
|
||||
self.model = LibraryTreeModel(self._component_payload)
|
||||
|
||||
tree = window.ui.libraryTree
|
||||
tree.setModel(self.model)
|
||||
tree.setHeaderHidden(True)
|
||||
tree.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||
tree.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||
tree.setDragEnabled(True)
|
||||
tree.setDragDropMode(QAbstractItemView.DragDropMode.DragOnly)
|
||||
tree.setDefaultDropAction(Qt.DropAction.CopyAction)
|
||||
tree.setIconSize(QSize(48, 48))
|
||||
tree.header().setStretchLastSection(False)
|
||||
tree.header().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
|
||||
@@ -34,6 +39,11 @@ class LibraryController(QObject):
|
||||
|
||||
def reload(self) -> None:
|
||||
libraries = load_library_documents(self.settings.library_paths)
|
||||
self._component_sources = {}
|
||||
for library in libraries:
|
||||
database = library.document.metadata.get("icon_database") if library.document.metadata is not None else None
|
||||
icons = database.icons if isinstance(database, IconDatabase) else {}
|
||||
self._collect_component_sources(library.document.root, icons)
|
||||
self.model.set_documents([library.document for library in libraries])
|
||||
for library in libraries:
|
||||
database = library.document.metadata.get("icon_database") if library.document.metadata is not None else None
|
||||
@@ -41,6 +51,24 @@ class LibraryController(QObject):
|
||||
self._set_component_icons(library.document.root, icons)
|
||||
self.window.ui.libraryTree.expandAll()
|
||||
|
||||
def _component_payload(self, components: list[Component]) -> dict:
|
||||
roots = {}
|
||||
icons = {}
|
||||
for component in components:
|
||||
source = self._component_sources.get(id(component))
|
||||
if source is None:
|
||||
continue
|
||||
component_id, source_icons = source
|
||||
roots[component_id] = component
|
||||
icons.update(source_icons)
|
||||
return export_component_data(roots, icons)
|
||||
|
||||
def _collect_component_sources(self, components: dict[ComponentID, Component], icons: dict[ComponentID, Icon]) -> None:
|
||||
for component_id, component in components.items():
|
||||
self._component_sources[id(component)] = (component_id, icons)
|
||||
if isinstance(component.implementation, GraphImplementation):
|
||||
self._collect_component_sources(component.implementation.graph.components, icons)
|
||||
|
||||
def _set_component_icons(self, components: dict[ComponentID, Component], icons: dict[ComponentID, Icon]) -> None:
|
||||
for component_id, component in components.items():
|
||||
self.model.set_component_icon(component_id, render_fitted_icon(icons.get(component_id, Icon()), component.interface.ports, ICON_SIZE))
|
||||
|
||||
Reference in New Issue
Block a user