File indexing completed on 2024-04-21 04:32:02

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 /** @file
0012  * This file implements an overlay rectangle with corner nodes to be used on top
0013  * of an element on the print layout pages allowing the user to change the size
0014  * and position of the underlying element.
0015  */
0016 
0017 // Class include
0018 #include "Boundary.h"
0019 
0020 // Qt includes
0021 #include <QPainter>
0022 
0023 // Application includes
0024 #include "Element.h"
0025 
0026 Boundary::Boundary()
0027     : m_element(nullptr)
0028 {
0029 }
0030 
0031 Element *Boundary::element() const
0032 {
0033     return m_element;
0034 }
0035 
0036 const QPoint *Boundary::node(const QPoint &point) const
0037 {
0038     int snapDistance = Configuration::page_SelectNodeSnapDistance();
0039 
0040     for (int node = 0; node < 4; node++) {
0041         if (QRect(-snapDistance, -snapDistance, snapDistance * 2, snapDistance * 2).translated(m_nodes[node]).contains(point)) {
0042             return &m_nodes[node];
0043         }
0044     }
0045 
0046     return nullptr;
0047 }
0048 
0049 QRect Boundary::rectangle() const
0050 {
0051     return m_rectangle;
0052 }
0053 
0054 Qt::CursorShape Boundary::cursor(const QPoint *node)
0055 {
0056     static const Qt::CursorShape nodeCursors[2] = {Qt::SizeFDiagCursor, Qt::SizeBDiagCursor};
0057     Qt::CursorShape shape = Qt::ArrowCursor;
0058 
0059     for (int i = 0; i < 4; i++) {
0060         if (m_nodes[i] == *node) {
0061             shape = nodeCursors[i % 2];
0062         }
0063     }
0064 
0065     return shape;
0066 }
0067 
0068 bool Boundary::isValid() const
0069 {
0070     return (m_element && m_rectangle.isValid());
0071 }
0072 
0073 void Boundary::setElement(Element *element)
0074 {
0075     if (element != m_element) {
0076         m_element = element;
0077 
0078         if (m_element) {
0079             setRectangle(element->rectangle());
0080         }
0081     }
0082 }
0083 
0084 void Boundary::setRectangle(const QRect &rectangle)
0085 {
0086     m_rectangle = rectangle;
0087     m_nodes[0] = rectangle.topLeft();
0088     m_nodes[1] = rectangle.topRight() + QPoint(1, 0);
0089     m_nodes[2] = rectangle.bottomRight() + QPoint(1, 1);
0090     m_nodes[3] = rectangle.bottomLeft() + QPoint(0, 1);
0091 }
0092 
0093 void Boundary::moveNode(const QPoint *node, const QPoint &point)
0094 {
0095     for (int i = 0; i < 4; i++) {
0096         if (m_nodes[i] == *node) {
0097             int dx = point.x() - node->x();
0098             int dy = point.y() - node->y();
0099             m_nodes[i] = point;
0100 
0101             switch (i) {
0102             case 0:
0103                 m_nodes[1] += QPoint(0, dy);
0104                 m_nodes[3] += QPoint(dx, 0);
0105                 break;
0106 
0107             case 1:
0108                 m_nodes[0] += QPoint(0, dy);
0109                 m_nodes[2] += QPoint(dx, 0);
0110                 break;
0111 
0112             case 2:
0113                 m_nodes[1] += QPoint(dx, 0);
0114                 m_nodes[3] += QPoint(0, dy);
0115                 break;
0116 
0117             case 3:
0118                 m_nodes[0] += QPoint(dx, 0);
0119                 m_nodes[2] += QPoint(0, dy);
0120                 break;
0121             }
0122 
0123             m_rectangle = QRect(m_nodes[0], m_nodes[2] - QPoint(1, 1));
0124             m_element->setRectangle(m_rectangle);
0125             break;
0126         }
0127     }
0128 }
0129 
0130 void Boundary::render(QPainter *painter)
0131 {
0132     if (!m_element) {
0133         return;
0134     }
0135 
0136     painter->save();
0137 
0138     QTransform transform = painter->combinedTransform();
0139     painter->resetTransform();
0140 
0141     QPen pen(Qt::blue);
0142     pen.setWidth(0);
0143     painter->setPen(pen);
0144     painter->setBrush(Qt::blue);
0145 
0146     int nodeSize = Configuration::page_SelectNodeSize();
0147 
0148     for (int node = 0; node < 4; node++) {
0149         painter->drawRect(QRect(-nodeSize, -nodeSize, nodeSize * 2, nodeSize * 2).translated(transform.map(QPoint(m_nodes[node]))));
0150     }
0151 
0152     painter->drawLine(transform.map(QLine(m_nodes[0], m_nodes[1])));
0153     painter->drawLine(transform.map(QLine(m_nodes[1], m_nodes[2])));
0154     painter->drawLine(transform.map(QLine(m_nodes[2], m_nodes[3])));
0155     painter->drawLine(transform.map(QLine(m_nodes[3], m_nodes[0])));
0156 
0157     painter->restore();
0158 }