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

0001 /*
0002  * Copyright (C) 2010-2015 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 "SelectArea.h"
0012 
0013 #include <QMouseEvent>
0014 #include <QPainter>
0015 #include <QRubberBand>
0016 #include <QScrollArea>
0017 #include <QStyleOptionRubberBand>
0018 #include <QToolTip>
0019 
0020 #include "Document.h"
0021 #include "Element.h"
0022 
0023 SelectArea::SelectArea(QWidget *parent, PatternElement *patternElement, Document *document, const QMap<int, QList<QRect>> &patternRects)
0024     : QWidget(parent)
0025     , m_patternElement(patternElement)
0026     , m_document(document)
0027     , m_patternRect(patternElement->patternRect())
0028     , m_patternRects(patternRects)
0029 {
0030     m_width = m_document->pattern()->stitches().width();
0031     m_height = m_document->pattern()->stitches().height();
0032     resize(m_width * 8, m_height * 8);
0033     m_fullPatternElement = new PatternElement(nullptr, QRect(QPoint(0, 0), size()));
0034     m_fullPatternElement->setPatternRect(QRect(0, 0, m_width, m_height));
0035     m_fullPatternElement->setRenderStitchesAs(patternElement->renderStitchesAs());
0036     m_fullPatternElement->setRenderBackstitchesAs(patternElement->renderBackstitchesAs());
0037     m_fullPatternElement->setRenderKnotsAs(patternElement->renderKnotsAs());
0038 }
0039 
0040 QRect SelectArea::patternRect() const
0041 {
0042     return m_patternRect;
0043 }
0044 
0045 void SelectArea::setPatternRect(const QRect &rect)
0046 {
0047     m_patternRect = rect;
0048 }
0049 
0050 void SelectArea::mousePressEvent(QMouseEvent *event)
0051 {
0052     if (event->buttons() & Qt::LeftButton) {
0053         if (m_rubberBand.isValid()) {
0054             QRect r = m_rubberBand;
0055             m_rubberBand = QRect(0, 0, 0, 0);
0056             repaint(r);
0057         }
0058 
0059         m_cellStart = m_cellTracking = m_cellEnd = contentsToCell(event->pos());
0060         QRect updateArea = cellToRect(m_cellStart);
0061         m_rubberBand = updateArea;
0062         repaint(updateArea.adjusted(-8, -8, 8, 8));
0063     }
0064 }
0065 
0066 void SelectArea::mouseMoveEvent(QMouseEvent *event)
0067 {
0068     QPoint p = event->pos();
0069 
0070     dynamic_cast<QScrollArea *>(parentWidget()->parentWidget())->ensureVisible(p.x(), p.y());
0071 
0072     m_cellTracking = contentsToCell(p);
0073     QRect selectedArea = QRect(m_cellStart, m_cellTracking).normalized();
0074 
0075     if (m_cellTracking != m_cellEnd) {
0076         m_cellEnd = m_cellTracking;
0077         QRect updateArea = (cellToRect(m_cellStart).united(cellToRect(m_cellEnd))).normalized();
0078         m_rubberBand = updateArea;
0079         repaint(updateArea.adjusted(-8, -8, 8, 8));
0080     }
0081 
0082     QToolTip::showText(
0083         QCursor::pos(),
0084         QString::fromLatin1("%1,%2 %3 x %4").arg(selectedArea.left()).arg(selectedArea.top()).arg(selectedArea.width()).arg(selectedArea.height()));
0085 }
0086 
0087 void SelectArea::mouseReleaseEvent(QMouseEvent *)
0088 {
0089     m_patternRect.setTopLeft(m_cellStart);
0090     m_patternRect.setBottomRight(m_cellEnd);
0091     m_patternRect = m_patternRect.normalized();
0092 }
0093 
0094 void SelectArea::paintEvent(QPaintEvent *event)
0095 {
0096     QPainter painter;
0097     painter.begin(this);
0098     QFont font = painter.font();
0099     font.setPointSize(30);
0100     painter.setFont(font);
0101 
0102     painter.fillRect(event->rect(), Qt::white);
0103     m_fullPatternElement->render(m_document, &painter);
0104 
0105     QMapIterator<int, QList<QRect>> pageIterator(m_patternRects);
0106 
0107     while (pageIterator.hasNext()) {
0108         pageIterator.next();
0109         int page = pageIterator.key();
0110 
0111         QListIterator<QRect> patternRectIterator(pageIterator.value());
0112         QColor color(Configuration::patternElement_SelectedAreaColor());
0113         color.setAlpha(100);
0114         QPen outline(Qt::black);
0115         outline.setWidth(3);
0116 
0117         while (patternRectIterator.hasNext()) {
0118             QRect rect = patternRectIterator.next();
0119             QRect previewRect(rect.left() * 8, rect.top() * 8, rect.width() * 8, rect.height() * 8);
0120             painter.setPen(outline);
0121             painter.setBrush(color);
0122             painter.drawRect(previewRect);
0123             painter.drawText(previewRect, Qt::AlignCenter, QString::fromLatin1("%1").arg(page));
0124         }
0125     }
0126 
0127     if (m_rubberBand.isValid()) {
0128         QStyleOptionRubberBand opt;
0129         opt.initFrom(this);
0130         opt.shape = QRubberBand::Rectangle;
0131         opt.opaque = false;
0132         opt.rect = m_rubberBand;
0133         style()->drawControl(QStyle::CE_RubberBand, &opt, &painter);
0134     }
0135 
0136     painter.end();
0137 }
0138 
0139 QPoint SelectArea::contentsToCell(const QPoint &point) const
0140 {
0141     return QPoint(point.x() / 8, point.y() / 8);
0142 }
0143 
0144 QRect SelectArea::cellToRect(const QPoint &cell) const
0145 {
0146     int x = cell.x() * 8;
0147     int y = cell.y() * 8;
0148     return QRect(x, y, 8, 8);
0149 }
0150 
0151 #include "moc_SelectArea.cpp"