#include "tagview.h" #include #include #include #include TagView::TagView(QWidget *parent) : QGraphicsView(parent) , saveCenterTimer(this) { setDragMode(QGraphicsView::RubberBandDrag); setScene(&m_scene); connect(&m_scene, &TagScene::tagDoubleClicked, this, &TagView::tagDoubleClicked); connect(&m_scene, &TagScene::imageLoaded, this, &TagView::zoomToFit); saveCenterTimer.setSingleShot(true); saveCenterTimer.setInterval(500); connect(&saveCenterTimer, &QTimer::timeout, this, &TagView::saveCenter); } TagView::~TagView() { were_done = true; } void TagView::zoomToFit() { QTransform tx = QTransform().rotate(-rotation); QRectF rect = tx.mapRect(m_scene.itemsBoundingRect()); QRectF vp = viewport()->rect(); setZoom(qMin(vp.width()/rect.width(), vp.height()/rect.height())); centerOn(m_scene.backgroundPixmapItem()); qDebug() << "TagView::zoomToFit():" << sceneRect() << rect << viewport()->rect(); } void TagView::setZoom(qreal zoom) { this->zoom = zoom; if (m_proj) m_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; if (m_proj) m_proj->setMeta("view_rotation", rotation); } void TagView::setProject(SQLiteSaveFile *proj) { m_proj = proj; m_scene.setProject(m_proj); restoreViewport(); } 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::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); /* Hackety hack: On object destruction this method is called downstream in the destructor chain. Prevent segfaults from calling an uninitialized timer. */ if (!were_done) saveCenterTimer.start(); } void TagView::keyPressEvent(QKeyEvent *event) { if (event->modifiers() & Qt::ControlModifier) setDragMode(QGraphicsView::ScrollHandDrag); else setDragMode(QGraphicsView::RubberBandDrag); } void TagView::keyReleaseEvent(QKeyEvent *event) { if (event->modifiers() & Qt::ControlModifier) setDragMode(QGraphicsView::ScrollHandDrag); else setDragMode(QGraphicsView::RubberBandDrag); } void TagView::focusInEvent(QFocusEvent *event) { Q_UNUSED(event); if (QApplication::keyboardModifiers() & Qt::ControlModifier) setDragMode(QGraphicsView::ScrollHandDrag); else setDragMode(QGraphicsView::RubberBandDrag); } void TagView::saveCenter() { QPointF p = mapToScene(viewport()->rect().center()); if (m_proj) m_proj->setMeta("view_center", QJsonDocument(QJsonArray({p.x(), p.y()})).toJson()); } void TagView::restoreViewport() { if (!m_proj) return; QVariant v_rot = m_proj->getMeta("view_rotation"); if (v_rot.isValid()) { rotation = v_rot.toInt(); } else { rotation = 0; } QVariant v_zoom = m_proj->getMeta("view_zoom"); if (v_zoom.isValid()) { zoom = v_zoom.toDouble(); setTransform(QTransform::fromScale(zoom, zoom).rotate(rotation)); } else { zoomToFit(); } QVariant v_center = m_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(m_scene.itemsBoundingRect().center()); } }