File indexing completed on 2024-04-28 04:32:06

0001 /*
0002  * Copyright (C) 2010-2022 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 #include "Preview.h"
0012 
0013 #include <QMouseEvent>
0014 #include <QPainter>
0015 #include <QScrollArea>
0016 #include <QStyleOptionRubberBand>
0017 
0018 #include "Document.h"
0019 #include "configuration.h"
0020 
0021 Preview::Preview(QWidget *parent)
0022     : QWidget(parent)
0023     , m_document(nullptr)
0024     , m_zoomFactor(1.0)
0025 {
0026     setObjectName(QStringLiteral("Preview#"));
0027     m_renderer.setRenderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::ColorBlocks);
0028     m_renderer.setRenderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::ColorLines);
0029     m_renderer.setRenderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::ColorBlocks);
0030 }
0031 
0032 void Preview::setDocument(Document *document)
0033 {
0034     m_document = document;
0035     readDocumentSettings();
0036 }
0037 
0038 Document *Preview::document()
0039 {
0040     return m_document;
0041 }
0042 
0043 void Preview::readDocumentSettings()
0044 {
0045     int width = m_document->pattern()->stitches().width();
0046     int height = m_document->pattern()->stitches().height();
0047     m_cellWidth = 4;
0048     m_cellHeight =
0049         4 * m_document->property(QStringLiteral("horizontalClothCount")).toDouble() / m_document->property(QStringLiteral("verticalClothCount")).toDouble();
0050     m_previewWidth = m_cellWidth * width * m_zoomFactor;
0051     m_previewHeight = m_cellHeight * height * m_zoomFactor;
0052     resize(m_previewWidth, m_previewHeight);
0053     m_cachedContents = QPixmap(m_previewWidth, m_previewHeight);
0054     drawContents();
0055 }
0056 
0057 void Preview::setVisibleCells(const QRect &cells)
0058 {
0059     m_visible = cells;
0060     update();
0061 }
0062 
0063 void Preview::loadSettings()
0064 {
0065     drawContents();
0066 }
0067 
0068 void Preview::mousePressEvent(QMouseEvent *e)
0069 {
0070     if (e->buttons() & Qt::LeftButton) {
0071         m_start = m_tracking = m_end = contentToCell(e->pos());
0072     }
0073 }
0074 
0075 void Preview::mouseMoveEvent(QMouseEvent *e)
0076 {
0077     if (e->buttons() & Qt::LeftButton) {
0078         m_tracking = contentToCell(e->pos());
0079 
0080         if (m_tracking != m_start) {
0081             m_end = m_tracking;
0082             m_rubberBand = QRect(m_start, m_end).normalized();
0083             update();
0084         }
0085     }
0086 }
0087 
0088 void Preview::mouseReleaseEvent(QMouseEvent *)
0089 {
0090     if (m_start == m_end) {
0091         emit clicked(m_start);
0092     } else {
0093         emit clicked(QRect(m_start, m_end).normalized());
0094     }
0095 
0096     m_rubberBand = QRect();
0097     update();
0098 }
0099 
0100 void Preview::drawContents()
0101 {
0102     if ((m_document == nullptr) || (m_cachedContents.isNull())) {
0103         return;
0104     }
0105 
0106     m_cachedContents.fill(m_document->property(QStringLiteral("fabricColor")).value<QColor>());
0107 
0108     QPainter painter(&m_cachedContents);
0109     painter.setRenderHint(QPainter::Antialiasing, true);
0110     painter.setWindow(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height());
0111 
0112     m_renderer.render(&painter, m_document->pattern(), painter.window(), false, true, true, true, -1);
0113 
0114     painter.end();
0115     update();
0116 }
0117 
0118 void Preview::paintEvent(QPaintEvent *)
0119 {
0120     if (m_cachedContents.isNull()) {
0121         return;
0122     }
0123 
0124     QPainter painter(this);
0125 
0126     painter.drawPixmap(0, 0, m_cachedContents);
0127 
0128     QPen visibleAreaPen(Qt::white);
0129     visibleAreaPen.setCosmetic(true);
0130 
0131     painter.setPen(visibleAreaPen);
0132     painter.setBrush(Qt::NoBrush);
0133     painter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
0134     painter.setWindow(0, 0, m_document->pattern()->stitches().width(), m_document->pattern()->stitches().height());
0135     painter.drawRect(m_visible);
0136 
0137     if (m_rubberBand.isValid()) {
0138         QStyleOptionRubberBand opt;
0139         opt.initFrom(this);
0140         opt.shape = QRubberBand::Rectangle;
0141         opt.opaque = false;
0142         opt.rect = m_rubberBand;
0143         style()->drawControl(QStyle::CE_RubberBand, &opt, &painter);
0144     }
0145 
0146     painter.end();
0147 }
0148 
0149 QPoint Preview::contentToCell(const QPoint &content) const
0150 {
0151     return QPoint(content.x() / m_cellWidth, content.y() / m_cellHeight);
0152 }
0153 
0154 #include "moc_Preview.cpp"