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"