Added ports to icon
This commit is contained in:
@@ -6,6 +6,7 @@ from PySide6.QtCore import QEvent, QObject, Qt, Signal
|
||||
from PySide6.QtGui import QKeySequence, QPainter, QShortcut, QUndoCommand, QUndoStack, QWheelEvent, QShowEvent
|
||||
from PySide6.QtWidgets import QDialog, QGraphicsView, QMainWindow, QWidget
|
||||
|
||||
from bedit_core.models import Port, PortID, SignalDirection
|
||||
from bedit_gui.models import Icon, Shape, ShapeID
|
||||
from bedit_gui.ui.generated.ui_icon_editor_window import Ui_iconEditor
|
||||
from bedit_gui.views.icon_graphics_scene import IconGraphicsScene, RectangleCreationTool
|
||||
@@ -69,6 +70,21 @@ class DeleteShapesCommand(QUndoCommand):
|
||||
self.editor._restore_shapes(self.shapes)
|
||||
|
||||
|
||||
class MovePortCommand(QUndoCommand):
|
||||
def __init__(self, editor: IconEditorWindow, port_id: PortID, old_position: tuple[int, int], new_position: tuple[int, int]) -> None:
|
||||
super().__init__("Move port")
|
||||
self.editor = editor
|
||||
self.port_id = port_id
|
||||
self.old_position = old_position
|
||||
self.new_position = new_position
|
||||
|
||||
def redo(self) -> None:
|
||||
self.editor._move_port(self.port_id, self.new_position)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.editor._move_port(self.port_id, self.old_position)
|
||||
|
||||
|
||||
class IconEditorWindow(QMainWindow):
|
||||
"""Independent icon editing session with its own undo stack."""
|
||||
|
||||
@@ -78,7 +94,7 @@ class IconEditorWindow(QMainWindow):
|
||||
minimum_zoom = 0.1
|
||||
maximum_zoom = 10.0
|
||||
|
||||
def __init__(self, icon: Icon, parent: QWidget | None = None) -> None:
|
||||
def __init__(self, icon: Icon, ports: dict[PortID, Port], parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self.ui = Ui_iconEditor()
|
||||
@@ -88,7 +104,10 @@ class IconEditorWindow(QMainWindow):
|
||||
self._icon = deepcopy(icon)
|
||||
|
||||
self.scene = IconGraphicsScene(self)
|
||||
self.scene.set_ports(ports)
|
||||
self._ensure_port_positions(ports)
|
||||
self.scene.set_icon(self._icon)
|
||||
self.scene.port_moved.connect(self._port_moved)
|
||||
self.scene.shape_created.connect(self._shape_created)
|
||||
self.scene.shape_changed.connect(self._shape_changed)
|
||||
self.scene.shape_options_requested.connect(self._show_shape_options)
|
||||
@@ -197,12 +216,20 @@ class IconEditorWindow(QMainWindow):
|
||||
self.scene.set_icon(self._icon)
|
||||
self.icon_changed.emit(self.icon())
|
||||
|
||||
def _move_port(self, port_id: PortID, position: tuple[int, int]) -> None:
|
||||
self._icon.port_positions[port_id] = position
|
||||
self.scene.set_icon(self._icon)
|
||||
self.icon_changed.emit(self.icon())
|
||||
|
||||
def _shape_created(self, shape: Shape) -> None:
|
||||
self.undo_stack.push(AddShapeCommand(self, ShapeID(), shape))
|
||||
|
||||
def _shape_changed(self, shape_id: ShapeID, old_shape: Shape, new_shape: Shape) -> None:
|
||||
self.undo_stack.push(ChangeShapeCommand(self, shape_id, old_shape, new_shape))
|
||||
|
||||
def _port_moved(self, port_id: PortID, old_position: tuple[int, int], new_position: tuple[int, int]) -> None:
|
||||
self.undo_stack.push(MovePortCommand(self, port_id, old_position, new_position))
|
||||
|
||||
def _delete_selected_shapes(self) -> None:
|
||||
shape_ids = self.scene.selected_shape_ids()
|
||||
shapes = {shape_id: self._icon.shapes[shape_id] for shape_id in shape_ids}
|
||||
@@ -219,6 +246,26 @@ class IconEditorWindow(QMainWindow):
|
||||
if new_shape != old_shape:
|
||||
self.undo_stack.push(ChangeShapeCommand(self, shape_id, old_shape, new_shape))
|
||||
|
||||
def _ensure_port_positions(self, ports: dict[PortID, Port]) -> None:
|
||||
bounds = self.scene.sceneRect()
|
||||
left = round(bounds.left())
|
||||
top = round(bounds.top())
|
||||
right = round(bounds.right() - 16)
|
||||
bottom = round(bounds.bottom() - 16)
|
||||
positions: dict[PortID, tuple[int, int]] = {}
|
||||
input_index = 0
|
||||
output_index = 0
|
||||
for port_id, port in ports.items():
|
||||
if port.direction is SignalDirection.INPUT:
|
||||
default = (left, top + input_index * 16)
|
||||
input_index += 1
|
||||
else:
|
||||
default = (right, top + output_index * 16)
|
||||
output_index += 1
|
||||
position = self._icon.port_positions.get(port_id, default)
|
||||
positions[port_id] = (max(left, min(right, position[0])), max(top, min(bottom, position[1])))
|
||||
self._icon.port_positions = positions
|
||||
|
||||
def _start_rectangle_tool(self) -> None:
|
||||
layer = max((shape.layer for shape in self._icon.shapes.values()), default=-1) + 1
|
||||
self.scene.set_creation_tool(RectangleCreationTool(self.scene, layer))
|
||||
|
||||
Reference in New Issue
Block a user