116 lines
4.0 KiB
Python
116 lines
4.0 KiB
Python
|
|
"""
|
||
|
|
Zentrales Canvas-Widget: zeigt das Logo mit Zoom, Pan und Rasterlinien an.
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
|
||
|
|
from PySide6.QtCore import Qt, Signal, QPointF
|
||
|
|
from PySide6.QtGui import (
|
||
|
|
QPainter, QPen, QColor, QPixmap, QWheelEvent, QMouseEvent,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class LogoCanvas(QGraphicsView):
|
||
|
|
zoom_changed = Signal(float)
|
||
|
|
|
||
|
|
def __init__(self, parent=None):
|
||
|
|
super().__init__(parent)
|
||
|
|
self._scene = QGraphicsScene(self)
|
||
|
|
self.setScene(self._scene)
|
||
|
|
|
||
|
|
self._pixmap_item: QGraphicsPixmapItem | None = None
|
||
|
|
self._overlay_item: QGraphicsPixmapItem | None = None
|
||
|
|
self._zoom = 1.0
|
||
|
|
self._pan_active = False
|
||
|
|
self._pan_start = QPointF()
|
||
|
|
|
||
|
|
self.setRenderHints(
|
||
|
|
QPainter.RenderHint.Antialiasing
|
||
|
|
| QPainter.RenderHint.SmoothPixmapTransform
|
||
|
|
)
|
||
|
|
self.setDragMode(QGraphicsView.DragMode.NoDrag)
|
||
|
|
self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)
|
||
|
|
self.setBackgroundBrush(QColor("#2b2b2b"))
|
||
|
|
self.setMinimumSize(400, 300)
|
||
|
|
|
||
|
|
self._draw_checkerboard()
|
||
|
|
|
||
|
|
def _draw_checkerboard(self):
|
||
|
|
"""Schachbrettmuster als Transparenz-Indikator."""
|
||
|
|
self.setStyleSheet("""
|
||
|
|
QGraphicsView {
|
||
|
|
background-color: #2b2b2b;
|
||
|
|
}
|
||
|
|
""")
|
||
|
|
|
||
|
|
def set_original_image(self, pixmap: QPixmap):
|
||
|
|
"""Zeigt das Original-PNG an."""
|
||
|
|
if self._pixmap_item:
|
||
|
|
self._scene.removeItem(self._pixmap_item)
|
||
|
|
self._pixmap_item = self._scene.addPixmap(pixmap)
|
||
|
|
self._pixmap_item.setZValue(0)
|
||
|
|
self.fitInView(self._pixmap_item, Qt.AspectRatioMode.KeepAspectRatio)
|
||
|
|
self._zoom = self.transform().m11()
|
||
|
|
self.zoom_changed.emit(self._zoom)
|
||
|
|
|
||
|
|
def set_overlay(self, pixmap: QPixmap):
|
||
|
|
"""Zeigt die gerenderten Vektorpfade als Overlay an."""
|
||
|
|
if self._overlay_item:
|
||
|
|
self._scene.removeItem(self._overlay_item)
|
||
|
|
self._overlay_item = self._scene.addPixmap(pixmap)
|
||
|
|
self._overlay_item.setZValue(1)
|
||
|
|
self._overlay_item.setOpacity(0.85)
|
||
|
|
|
||
|
|
def clear_overlay(self):
|
||
|
|
if self._overlay_item:
|
||
|
|
self._scene.removeItem(self._overlay_item)
|
||
|
|
self._overlay_item = None
|
||
|
|
|
||
|
|
# --- Zoom via Mausrad ---
|
||
|
|
def wheelEvent(self, event: QWheelEvent):
|
||
|
|
factor = 1.15 if event.angleDelta().y() > 0 else 1 / 1.15
|
||
|
|
self._zoom *= factor
|
||
|
|
self.scale(factor, factor)
|
||
|
|
self.zoom_changed.emit(self._zoom)
|
||
|
|
|
||
|
|
# --- Pan via mittlere Maustaste oder Leertaste + Links ---
|
||
|
|
def mousePressEvent(self, event: QMouseEvent):
|
||
|
|
if event.button() == Qt.MouseButton.MiddleButton:
|
||
|
|
self._pan_active = True
|
||
|
|
self._pan_start = event.position()
|
||
|
|
self.setCursor(Qt.CursorShape.ClosedHandCursor)
|
||
|
|
else:
|
||
|
|
super().mousePressEvent(event)
|
||
|
|
|
||
|
|
def mouseMoveEvent(self, event: QMouseEvent):
|
||
|
|
if self._pan_active:
|
||
|
|
delta = event.position() - self._pan_start
|
||
|
|
self._pan_start = event.position()
|
||
|
|
self.horizontalScrollBar().setValue(
|
||
|
|
self.horizontalScrollBar().value() - int(delta.x())
|
||
|
|
)
|
||
|
|
self.verticalScrollBar().setValue(
|
||
|
|
self.verticalScrollBar().value() - int(delta.y())
|
||
|
|
)
|
||
|
|
else:
|
||
|
|
super().mouseMoveEvent(event)
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, event: QMouseEvent):
|
||
|
|
if event.button() == Qt.MouseButton.MiddleButton:
|
||
|
|
self._pan_active = False
|
||
|
|
self.setCursor(Qt.CursorShape.ArrowCursor)
|
||
|
|
else:
|
||
|
|
super().mouseReleaseEvent(event)
|
||
|
|
|
||
|
|
def set_zoom(self, zoom: float):
|
||
|
|
factor = zoom / self._zoom
|
||
|
|
self._zoom = zoom
|
||
|
|
self.scale(factor, factor)
|
||
|
|
self.zoom_changed.emit(self._zoom)
|
||
|
|
|
||
|
|
def fit_to_view(self):
|
||
|
|
if self._pixmap_item:
|
||
|
|
self.fitInView(self._pixmap_item, Qt.AspectRatioMode.KeepAspectRatio)
|
||
|
|
self._zoom = self.transform().m11()
|
||
|
|
self.zoom_changed.emit(self._zoom)
|