diff options
Diffstat (limited to 'tagview.cpp')
-rw-r--r-- | tagview.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/tagview.cpp b/tagview.cpp new file mode 100644 index 0000000..abaefcb --- /dev/null +++ b/tagview.cpp @@ -0,0 +1,96 @@ +#include "tagview.h" + +#include <QWheelEvent> +#include <QScrollBar> +#include <cmath> + +TagView::TagView(SQLiteSaveFile &proj) + : proj(proj) + , saveCenterTimer() +{ + setDragMode(QGraphicsView::ScrollHandDrag); + setScene(&scene); + + saveCenterTimer.setSingleShot(true); + saveCenterTimer.setInterval(500); + connect(&saveCenterTimer, &QTimer::timeout, + this, &TagView::saveCenter); +} + +void TagView::zoomToFit() +{ + QTransform tx = QTransform().rotate(-rotation); + QRectF rect = tx.mapRect(scene.itemsBoundingRect()); + QRectF vp = viewport()->rect(); + + setZoom(qMin(vp.width()/rect.width(), vp.height()/rect.height())); +} + +void TagView::setZoom(qreal zoom) +{ + this->zoom = zoom; + proj.setMeta("view_zoom", zoom); + setTransform(QTransform::fromScale(zoom, zoom).rotate(rotation)); +} + +void TagView::zoomIn(qreal delta) +{ + setZoom(qMax(1.0/16, qMin(4.0, zoom * qPow(1.2, delta/120)))); +} + +void TagView::rotate(int angle) +{ + QGraphicsView::rotate(angle); + int tmp = (rotation + angle) % 360; + if (tmp < 0) + tmp += 360; + rotation = tmp; + proj.setMeta("view_rotation", rotation); +} + +void TagView::wheelEvent(QWheelEvent *evt) +{ + if (evt->modifiers() == Qt::ControlModifier) { + zoomIn(evt->angleDelta().y()); + } else { + if (qAbs(evt->angleDelta().x()) > qAbs(evt->angleDelta().y())) { + QCoreApplication::sendEvent(horizontalScrollBar(), evt); + } else { + QCoreApplication::sendEvent(verticalScrollBar(), evt); + } + } +} + +void TagView::saveCenter() +{ + QPointF p = mapToScene(viewport()->rect().center()); + proj.setMeta("view_center", QJsonDocument(QJsonArray({p.x(), p.y()})).toJson()); +} + +void TagView::restoreViewport() +{ + QVariant v_rot = proj.getMeta("view_rotation"); + if (v_rot.isValid()) { + rotation = v_rot.toInt(); + } else { + rotation = 0; + } + + QVariant v_zoom = proj.getMeta("view_zoom"); + if (v_zoom.isValid()) { + zoom = v_zoom.toDouble(); + setTransform(QTransform::fromScale(zoom, zoom).rotate(rotation)); + } else { + zoomToFit(); + } + + QVariant v_center = proj.getMeta("view_center"); + if (v_center.isValid()) { + QJsonArray arr = QJsonDocument::fromJson(v_center.toByteArray()).toVariant().toJsonArray(); + assert(arr.size() == 2); + assert(arr[0].isDouble() && arr[1].isDouble()); + centerOn(QPointF(arr[0].toDouble(), arr[1].toDouble())); + } else { + centerOn(scene.itemsBoundingRect().center()); + } +} |