File indexing completed on 2024-04-28 03:56:45

0001 /*
0002  * This file is part of KQuickCharts
0003  * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006  */
0007 
0008 #include "LineGridNode.h"
0009 
0010 #include <cmath>
0011 
0012 #include <QSGFlatColorMaterial>
0013 
0014 LineGridNode::LineGridNode()
0015 {
0016     m_geometry = new QSGGeometry{QSGGeometry::defaultAttributes_Point2D(), 0};
0017     m_geometry->setDrawingMode(QSGGeometry::DrawLines);
0018     m_geometry->setLineWidth(m_lineWidth);
0019     setGeometry(m_geometry);
0020 
0021     m_material = new QSGFlatColorMaterial{};
0022     m_material->setColor(QColor(255, 0, 0, 255));
0023     setMaterial(m_material);
0024 
0025     setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial);
0026 }
0027 
0028 LineGridNode::~LineGridNode()
0029 {
0030 }
0031 
0032 void LineGridNode::setVisible(bool visible)
0033 {
0034     if (visible == m_visible) {
0035         return;
0036     }
0037 
0038     m_visible = visible;
0039     markDirty(QSGNode::DirtySubtreeBlocked);
0040 }
0041 
0042 void LineGridNode::setVertical(bool vertical)
0043 {
0044     if (vertical == m_vertical) {
0045         return;
0046     }
0047 
0048     m_vertical = vertical;
0049 }
0050 
0051 void LineGridNode::setRect(const QRectF &rect)
0052 {
0053     if (rect == m_rect) {
0054         return;
0055     }
0056 
0057     m_rect = rect;
0058 }
0059 
0060 void LineGridNode::setColor(const QColor &color)
0061 {
0062     if (color == m_material->color()) {
0063         return;
0064     }
0065 
0066     m_material->setColor(color);
0067     markDirty(QSGNode::DirtyMaterial);
0068 }
0069 
0070 void LineGridNode::setSpacing(float spacing)
0071 {
0072     if (qFuzzyCompare(spacing, m_spacing)) {
0073         return;
0074     }
0075 
0076     m_spacing = spacing;
0077 }
0078 
0079 void LineGridNode::setLineWidth(float lineWidth)
0080 {
0081     if (qFuzzyCompare(lineWidth, m_lineWidth)) {
0082         return;
0083     }
0084 
0085     m_lineWidth = lineWidth;
0086     m_geometry->setLineWidth(lineWidth);
0087     markDirty(QSGNode::DirtyGeometry);
0088 }
0089 
0090 bool LineGridNode::isSubtreeBlocked() const
0091 {
0092     return !m_visible;
0093 }
0094 
0095 void LineGridNode::update()
0096 {
0097     if (!m_rect.isValid()) {
0098         return;
0099     }
0100 
0101     int totalVertices = 0;
0102     if (!m_vertical) {
0103         totalVertices = std::floor(m_rect.width() / std::ceil(m_spacing)) * 2 + 4;
0104     } else {
0105         totalVertices = std::floor(m_rect.height() / std::ceil(m_spacing)) * 2 + 4;
0106     }
0107 
0108     if (totalVertices < 4) {
0109         return;
0110     }
0111 
0112     if (totalVertices != m_geometry->vertexCount()) {
0113         m_geometry->allocate(totalVertices, totalVertices);
0114     }
0115 
0116     auto vertices = m_geometry->vertexDataAsPoint2D();
0117     auto indices = m_geometry->indexDataAsUShort();
0118 
0119     if (!vertices || !indices) {
0120         return;
0121     }
0122 
0123     int index = 0;
0124     if (m_vertical) {
0125         line(vertices, indices, index, m_rect.left(), m_rect.top(), m_rect.right(), m_rect.top());
0126 
0127         auto y = m_spacing;
0128         for (auto i = 0; i < (totalVertices - 4) / 2; ++i) {
0129             line(vertices, indices, index, m_rect.left(), y, m_rect.right(), y);
0130             y += m_spacing;
0131         }
0132 
0133         line(vertices, indices, index, m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
0134     } else {
0135         line(vertices, indices, index, m_rect.left(), m_rect.top(), m_rect.left(), m_rect.bottom());
0136 
0137         auto x = m_spacing;
0138         for (auto i = 0; i < (totalVertices - 4) / 2; ++i) {
0139             line(vertices, indices, index, x, m_rect.top(), x, m_rect.bottom());
0140             x += m_spacing;
0141         }
0142 
0143         line(vertices, indices, index, m_rect.right(), m_rect.top(), m_rect.right(), m_rect.bottom());
0144     }
0145 
0146     m_geometry->markVertexDataDirty();
0147     m_geometry->markIndexDataDirty();
0148     markDirty(QSGNode::DirtyGeometry);
0149 }
0150 
0151 void LineGridNode::line(QSGGeometry::Point2D *vertices, quint16 *indices, int &index, qreal fromX, qreal fromY, qreal toX, qreal toY)
0152 {
0153     indices[index] = index;
0154     vertices[index++].set(fromX, fromY);
0155     indices[index] = index;
0156     vertices[index++].set(toX, toY);
0157 }