Copy/paste on canvas

This commit is contained in:
Joppe Blondel
2026-08-17 12:12:57 +02:00
parent fcee2ac8b6
commit 0bb2141673
8 changed files with 182 additions and 49 deletions
+21 -2
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from math import hypot
from PySide6.QtCore import QEvent, QObject, QPointF, QRectF, QSize, QTimer, Qt, Signal
from PySide6.QtGui import QColor, QPainter, QPainterPath, QPen, QWheelEvent
from PySide6.QtGui import QColor, QCursor, QPainter, QPainterPath, QPen, QWheelEvent
from PySide6.QtWidgets import QGraphicsItem, QGraphicsPathItem, QGraphicsPixmapItem, QGraphicsScene, QGraphicsSceneMouseEvent, QGraphicsView, QWidget
from bedit_core.models import BondCausality, BondConnection, Component, ComponentID, ConnectionID, GraphImplementation, SignalConnection
@@ -55,7 +55,6 @@ class GraphConnectionItem(QGraphicsPathItem):
super().__init__()
self.setPath(self._connection_path(points, half_arrow, tick_at_source))
pen = QPen(QColor("#202020"), CONNECTION_WIDTH)
pen.setCosmetic(True)
self.setPen(pen)
self.setZValue(-1)
@@ -137,9 +136,17 @@ class GraphComponentItem(QGraphicsPixmapItem):
if self.pos() != self._drag_start:
self.editor.finish_component_move(self.component_id, position)
def contextMenuEvent(self, event) -> None:
if not self.isSelected():
self.scene().clearSelection()
self.setSelected(True)
self.editor.component_context_menu_requested.emit(self.component_id, event.screenPos())
event.accept()
class GraphEditorWidget(QWidget):
component_move_requested = Signal(object, object, object)
component_context_menu_requested = Signal(object, object)
def __init__(self, parent: QWidget | None = None, snap_to_grid_size: int = 4) -> None:
super().__init__(parent)
@@ -298,6 +305,18 @@ class GraphEditorWidget(QWidget):
def component(self) -> Component | None:
return self._component
def selected_component_ids(self) -> list[ComponentID]:
return [item.component_id for item in self.scene.selectedItems() if isinstance(item, GraphComponentItem)]
def paste_position(self) -> tuple[int, int]:
viewport = self.ui.graphicsView.viewport()
viewport_position = viewport.mapFromGlobal(QCursor.pos())
if not viewport.rect().contains(viewport_position):
viewport_position = viewport.rect().center()
scene_position = self.ui.graphicsView.mapToScene(viewport_position)
size = self.snap_to_grid_size
return round(scene_position.x() / size) * size, round(scene_position.y() / size) * size
def zoom_to_fit(self) -> None:
bounds = self.scene.itemsBoundingRect()
if bounds.isEmpty():