Text fields and saving Icons to file

This commit is contained in:
2026-07-27 14:30:25 +02:00
parent 13d3825f9b
commit c68e693359
12 changed files with 510 additions and 35 deletions

View File

@@ -5,11 +5,11 @@ from copy import deepcopy
from typing import Protocol
from PySide6.QtCore import QObject, QPointF, QRectF, Qt, Signal
from PySide6.QtGui import QBrush, QColor, QPainter, QPainterPath, QPen
from PySide6.QtGui import QBrush, QColor, QFont, QPainter, QPainterPath, QPen
from PySide6.QtWidgets import QGraphicsItem, QGraphicsPathItem, QGraphicsRectItem, QGraphicsScene, QGraphicsSceneContextMenuEvent, QGraphicsSceneMouseEvent, QMenu, QStyleOptionGraphicsItem, QWidget
from bedit_core.models import Port, PortID, SignalDirection
from bedit_gui.models import Icon, LineType, Rectangle, Shape, ShapeID
from bedit_gui.models import Icon, LineType, Rectangle, Shape, ShapeID, Text
class ShapeCreationTool(Protocol):
@@ -36,7 +36,7 @@ class RectangleCreationTool:
position = self._bounded(position)
self.preview.setRect(QRectF(self.start, position).normalized())
def finish(self, position: QPointF) -> Rectangle | None:
def finish(self, position: QPointF) -> Shape | None:
if self.start is None:
return None
position = self._bounded(position)
@@ -44,6 +44,9 @@ class RectangleCreationTool:
self.cancel()
if rect.width() < 1 or rect.height() < 1:
return None
return self.create_shape(rect)
def create_shape(self, rect: QRectF) -> Shape:
return Rectangle(layer=self.layer, pos=(round(rect.x()), round(rect.y())), width=rect.width(), height=rect.height())
def cancel(self) -> None:
@@ -59,6 +62,11 @@ class RectangleCreationTool:
return QPointF(x, y)
class TextCreationTool(RectangleCreationTool):
def create_shape(self, rect: QRectF) -> Shape:
return Text(layer=self.layer, pos=(round(rect.x()), round(rect.y())), width=rect.width(), height=rect.height(), text="Text")
class ShapeGraphicsItem(QGraphicsPathItem):
handle_size = 6.0
@@ -173,6 +181,48 @@ class RectangleGraphicsItem(ShapeGraphicsItem):
self.setPath(path)
class TextGraphicsItem(ShapeGraphicsItem):
def __init__(self, shape_id: ShapeID, shape: Text, scene: IconGraphicsScene) -> None:
super().__init__(shape_id, shape, scene)
self.text = deepcopy(shape)
self.setPos(shape.pos[0], shape.pos[1])
self._set_size(shape.width, shape.height)
self.setPen(QPen(Qt.PenStyle.NoPen))
self.setBrush(QBrush(QColor(0, 0, 0, 0)))
self.setZValue(shape.layer)
def current_shape(self) -> Text:
shape = deepcopy(self.text)
shape.pos = (round(self.pos().x()), round(self.pos().y()))
rect = self.path().boundingRect()
shape.width = rect.width()
shape.height = rect.height()
return shape
def resize_to(self, position: QPointF) -> None:
bounds = self.icon_scene.sceneRect()
width = max(1.0, min(bounds.right(), round(position.x())) - self.pos().x())
height = max(1.0, min(bounds.bottom(), round(position.y())) - self.pos().y())
self._set_size(width, height)
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget | None = None) -> None:
super().paint(painter, option, widget)
font = QFont()
font.setPixelSize(max(1, round(self.text.size)))
font.setBold(self.text.bold)
font.setItalic(self.text.italic)
painter.setFont(font)
painter.setPen(self.icon_scene._color(self.text.color))
painter.setClipRect(self.path().boundingRect())
painter.drawText(self.path().boundingRect(), Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextWordWrap, self.text.text)
def _set_size(self, width: float, height: float) -> None:
self.prepareGeometryChange()
path = QPainterPath()
path.addRect(QRectF(0, 0, width, height))
self.setPath(path)
class PortGraphicsItem(QGraphicsRectItem):
size = 16.0
@@ -304,9 +354,10 @@ class IconGraphicsScene(QGraphicsScene):
super().mouseReleaseEvent(event)
def _add_shape_item(self, shape_id: ShapeID, shape: Shape) -> None:
if not isinstance(shape, Rectangle):
return
self.addItem(RectangleGraphicsItem(shape_id, shape, self))
if isinstance(shape, Rectangle):
self.addItem(RectangleGraphicsItem(shape_id, shape, self))
elif isinstance(shape, Text):
self.addItem(TextGraphicsItem(shape_id, shape, self))
@staticmethod
def _pen(shape: Rectangle) -> QPen: