File indexing completed on 2024-05-12 04:06:25
0001 /* 0002 SPDX-FileCopyrightText: 2010 Johannes Loehnert <loehnert.kde@gmx.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "puzzlepreview.h" 0008 0009 #include "../file-io/puzzlestructs.h" 0010 #include "settings.h" 0011 0012 #include <cmath> 0013 #include <QMouseEvent> 0014 #include <QPainter> 0015 #include <KLocalizedString> 0016 0017 Palapeli::PuzzlePreview::PuzzlePreview(QWidget* parent) 0018 { 0019 m_settingsSaveTimer = new QTimer(this); 0020 connect(m_settingsSaveTimer, &QTimer::timeout, this, &PuzzlePreview::writeConfigIfGeometryChanged); 0021 m_geometryChanged = false; 0022 0023 m_hoverZoom = 1.0; 0024 m_isZoomed = false; 0025 m_mousePos = QPoint(); 0026 0027 setScene(new QGraphicsScene(this)); 0028 setParent(parent); 0029 setWindowTitle(i18nc("@title:window", "Preview of completed puzzle")); 0030 setWindowFlags(Qt::Tool | Qt::WindowTitleHint); 0031 setAttribute (Qt::WA_NoMousePropagation); // Accept all mouse events. 0032 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0033 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0034 setRenderHint(QPainter::SmoothPixmapTransform); 0035 scene()->addText(i18nc("text in preview window", 0036 "Image is not available.")); // Seen if image-data not found. 0037 setSceneRect(scene()->itemsBoundingRect()); 0038 0039 // read size and position settings 0040 QRect geometry = Settings::puzzlePreviewGeometry(); 0041 resize(geometry.size()); 0042 0043 // default (-1/-1) toprect: don't change position 0044 if (geometry.left() >= 0 && geometry.top() >= 0) 0045 move(geometry.topLeft()); 0046 0047 m_settingsSaveTimer->start(500); 0048 hide(); 0049 updateViewport(); 0050 } 0051 0052 void Palapeli::PuzzlePreview::setImage(const QImage &image) 0053 { 0054 scene()->clear(); 0055 scene()->addPixmap(QPixmap::fromImage(image)); 0056 setSceneRect(image.rect()); 0057 updateViewport(); 0058 } 0059 0060 void Palapeli::PuzzlePreview::loadImageFrom(const Palapeli::PuzzleMetadata& md) 0061 { 0062 // Metadata is assumed to have been loaded by the caller. 0063 setImage(md.image); 0064 setWindowTitle(i18nc("@title:window", "%1 - Preview", md.name)); 0065 // Set hover-zoom so that 3x3 pieces would be visible on a square grid. 0066 m_hoverZoom = sqrt(md.pieceCount)/3.0; 0067 if (m_hoverZoom < 1) 0068 m_hoverZoom = 1; 0069 } 0070 0071 void Palapeli::PuzzlePreview::toggleVisible() 0072 { 0073 setVisible(!isVisible()); 0074 Settings::setPuzzlePreviewVisible(isVisible()); 0075 Settings::self()->save(); 0076 } 0077 0078 void Palapeli::PuzzlePreview::mouseMoveEvent(QMouseEvent* event) 0079 { 0080 m_mousePos = event->pos(); 0081 updateViewport(); 0082 QGraphicsView::mouseMoveEvent(event); 0083 } 0084 0085 void Palapeli::PuzzlePreview::enterEvent(QEnterEvent* event) 0086 { 0087 setMouseTracking(true); 0088 m_isZoomed = true; 0089 m_mousePos = QPoint(); 0090 // wait with update for first mouseMoveEvent 0091 QGraphicsView::enterEvent(event); 0092 } 0093 0094 void Palapeli::PuzzlePreview::leaveEvent(QEvent* event) 0095 { 0096 setMouseTracking(false); 0097 m_isZoomed = false; 0098 updateViewport(); 0099 QGraphicsView::leaveEvent(event); 0100 } 0101 0102 void Palapeli::PuzzlePreview::resizeEvent(QResizeEvent* event) 0103 { 0104 updateViewport(); 0105 m_geometryChanged = true; 0106 QGraphicsView::resizeEvent(event); 0107 } 0108 0109 void Palapeli::PuzzlePreview::moveEvent(QMoveEvent* event) 0110 { 0111 m_geometryChanged = true; 0112 QGraphicsView::moveEvent(event); 0113 } 0114 0115 void Palapeli::PuzzlePreview::closeEvent(QCloseEvent* event) 0116 { 0117 // Triggered by the preview window's Close button. 0118 event->accept(); 0119 Q_EMIT closing(); 0120 } 0121 0122 void Palapeli::PuzzlePreview::writeConfigIfGeometryChanged() 0123 { 0124 if (!m_geometryChanged) return; 0125 0126 // move() includes window frame, resize() doesn't :-/ 0127 Settings::setPuzzlePreviewGeometry(QRect(frameGeometry().topLeft(), size())); 0128 Settings::self()->save(); 0129 m_geometryChanged = false; 0130 } 0131 0132 void Palapeli::PuzzlePreview::updateViewport() 0133 { 0134 qreal zoom; 0135 // calculate zoom for fit-in-window 0136 zoom = width() / sceneRect().width(); 0137 if (zoom > height() / sceneRect().height()) 0138 zoom = height() / sceneRect().height(); 0139 0140 if (m_isZoomed) 0141 zoom *= m_hoverZoom; 0142 0143 // do not enlarge 0144 if (zoom>1) 0145 zoom = 1; 0146 0147 resetTransform(); 0148 scale(zoom, zoom); 0149 0150 if (m_isZoomed) 0151 { 0152 // focus moves with cursor position 0153 QPointF pos = m_mousePos; 0154 pos.rx() *= sceneRect().width() / width(); 0155 pos.ry() *= sceneRect().height() / height(); 0156 centerOn(pos); 0157 } 0158 } 0159 0160 #include "moc_puzzlepreview.cpp"