10#include <QElapsedTimer>
11#include <QGraphicsItem>
21constexpr int kMaxViewZoomLevel = 7;
22constexpr int kMinViewZoomLevel = -9;
26 : QGraphicsView(parent)
28 setAccessibleName(tr(
"Circuit canvas"));
29 setWhatsThis(tr(
"The circuit canvas. Drag elements here from the palette to build a "
30 "circuit, drag between ports to wire them together, and drag a "
31 "selection to move it."));
36 setMouseTracking(
true);
40 setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
41 setResizeAnchor(QGraphicsView::AnchorUnderMouse);
46 setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
48 setCacheMode(QGraphicsView::CacheBackground);
58 QGraphicsView::paintEvent(event);
60 if (
auto *scene_ = qobject_cast<Scene *>(scene())) {
61 scene_->recordWirePaintPass(timer.nsecsElapsed());
77 if (event->button() == Qt::MiddleButton) {
81 m_panStartX =
event->pos().x();
82 m_panStartY =
event->pos().y();
83 viewport()->setCursor(Qt::ClosedHandCursor);
88 QGraphicsView::mousePressEvent(event);
93 if (m_pan || m_space) {
96 horizontalScrollBar()->setValue(horizontalScrollBar()->value() - (event->pos().x() - m_panStartX));
97 verticalScrollBar()->setValue(verticalScrollBar()->value() - (event->pos().y() - m_panStartY));
99 m_panStartX =
event->pos().x();
100 m_panStartY =
event->pos().y();
107 m_panStartX =
event->pos().x();
108 m_panStartY =
event->pos().y();
110 QGraphicsView::mouseMoveEvent(event);
115 if (event->button() == Qt::MiddleButton) {
117 viewport()->unsetCursor();
122 QGraphicsView::mouseReleaseEvent(event);
130 if (event->isAutoRepeat()) {
131 QGraphicsView::keyPressEvent(event);
135 if (event->key() == Qt::Key_Space) {
139 viewport()->setCursor(Qt::ClosedHandCursor);
143 QGraphicsView::keyPressEvent(event);
150 if (event->isAutoRepeat()) {
151 QGraphicsView::keyReleaseEvent(event);
155 if (event->key() == Qt::Key_Space) {
157 viewport()->unsetCursor();
161 QGraphicsView::keyReleaseEvent(event);
166 const int zoomDirection =
event->angleDelta().y();
172 }
else if (zoomDirection < 0 &&
canZoomOut()) {
181 centerOn(mapToScene(event->position().toPoint()));
191 setRenderHint(QPainter::Antialiasing, !fastMode);
192 setRenderHint(QPainter::TextAntialiasing, !fastMode);
193 setRenderHint(QPainter::SmoothPixmapTransform, !fastMode);
230 const auto selected = scene()->selectedItems();
231 if (!selected.isEmpty()) {
232 for (
auto *item : selected) {
233 target |= item->sceneBoundingRect();
235 }
else if (
auto *scene_ = qobject_cast<Scene *>(scene())) {
236 target = scene_->cachedItemsBoundingRect();
238 target = scene()->itemsBoundingRect();
241 if (!target.isValid() || target.isEmpty()) {
246 target.adjust(-16.0, -16.0, 16.0, 16.0);
252 fitInView(target, Qt::KeepAspectRatio);
253 const double fitScale = transform().m11();
254 const int level = qBound(kMinViewZoomLevel,
static_cast<int>(std::floor(std::log(fitScale) / std::log(1.25))), kMaxViewZoomLevel);
257 const double scaleFactor = std::pow(1.25, level);
258 scale(scaleFactor, scaleFactor);
260 centerOn(target.center());
Extended QGraphicsView with zoom, pan, and fast-rendering modes.
Main circuit editing scene with undo/redo and user interaction.
Lightweight Sentry helpers gated behind HAVE_SENTRY.
void sentryBreadcrumb(const char *category, const QString &message)
void zoomOut()
Decreases the view magnification by one zoom step.
void paintEvent(QPaintEvent *event) override
void mousePressEvent(QMouseEvent *event) override
void keyPressEvent(QKeyEvent *event) override
int m_zoomLevel
Current zoom step (0 = 1:1, positive = zoomed in).
void mouseReleaseEvent(QMouseEvent *event) override
bool canZoomOut() const
Returns true if zooming out further is possible.
GraphicsView(QWidget *parent=nullptr)
Constructs the view with optional parent.
void zoomIn()
Increases the view magnification by one zoom step.
void zoomChanged()
Emitted whenever the zoom level changes.
void keyReleaseEvent(QKeyEvent *event) override
void resetZoom()
Resets the view scale to 1:1.
bool canZoomIn() const
Returns true if zooming in further is possible.
void wheelEvent(QWheelEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
void setFastMode(const bool fastMode)
Enables or disables fast rendering mode (disables antialiasing).