File indexing completed on 2022-09-27 12:21:23

0001 /*************************************************************************************
0002  *  Copyright (C) 2011 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "graph2dmobile.h"
0020 #include <QPainter>
0021 #include <QEvent>
0022 #include <QSGSimpleTextureNode>
0023 #include <QQuickWindow>
0024 #include <analitza/variables.h>
0025 #include <analitzaplot/planecurve.h>
0026 #include <analitzaplot/plotsmodel.h>
0027 #include <analitzaplot/plotsfactory.h>
0028 
0029 using namespace Analitza;
0030 
0031 Graph2DMobile::Graph2DMobile(QQuickItem* parent)
0032     : QQuickItem(parent), Plotter2D(boundingRect().size())
0033     , m_dirty(true), m_currentFunction(-1)
0034 {
0035     setSize(QSizeF(100,100));
0036     
0037     defViewport = QRectF(QPointF(-5., 5.), QSizeF(10., -10.));
0038     resetViewport();
0039     setFlags(QQuickItem::ItemHasContents);
0040 }
0041 
0042 void Graph2DMobile::paint()
0043 {
0044     if (!m_dirty)
0045         return;
0046 
0047 //     qDebug() << "hellooo" << boundingRect();
0048     const auto dpr = window()->effectiveDevicePixelRatio();
0049     const QSize bounding = (boundingRect().size() * dpr).toSize();
0050     if(bounding.isEmpty())
0051         return;
0052     
0053     if(m_buffer.size()!=bounding) {
0054         m_buffer = QImage(bounding, QImage::Format_ARGB32);
0055         m_buffer.setDevicePixelRatio(dpr);
0056         setDevicePixelRatio(dpr);
0057         setPaintedSize(bounding);
0058     }
0059     
0060     Q_ASSERT(!m_buffer.isNull());
0061     
0062     if(m_dirty) {
0063         m_buffer.fill(Qt::transparent);
0064         drawFunctions(&m_buffer);
0065         m_dirty=false;
0066     }
0067 }
0068 
0069 void Graph2DMobile::forceRepaint()
0070 {
0071     m_dirty=true;
0072     update();
0073 }
0074 
0075 void Graph2DMobile::resetViewport()
0076 {
0077     setViewport(defViewport);
0078 }
0079 
0080 void Graph2DMobile::modelChanged()
0081 {
0082     Q_EMIT modelHasChanged();
0083 }
0084 
0085 void Graph2DMobile::scale(qreal s, int x, int y)
0086 {
0087     QRectF userViewport = lastUserViewport();
0088     if(s>1 || (userViewport.height() < -3. && userViewport.width() > 3.)) {
0089         scaleViewport(s, QPoint(x,y));
0090     }
0091 }
0092 
0093 void Graph2DMobile::translate(qreal x, qreal y)
0094 {
0095     moveViewport(QPoint(x,y) * window()->effectiveDevicePixelRatio());
0096 }
0097 
0098 QStringList Graph2DMobile::addFunction(const QString& expression, const QSharedPointer<Analitza::Variables>& vars)
0099 {
0100     PlotsModel* plotsmodel = qobject_cast<PlotsModel*>(model());
0101     if(!plotsmodel)
0102         qWarning() << "only can add plots to a PlotsModel instance";
0103     else
0104         return plotsmodel->addFunction(expression, Dim2D, vars);
0105     return {};
0106 }
0107 
0108 void Graph2DMobile::setTicksShownAtAll(bool shown)
0109 {
0110     Qt::Orientations show = shown ? Qt::Vertical|Qt::Horizontal : Qt::Orientations{};
0111     setShowTicks(show);
0112     setShowTickLabels(show);
0113 }
0114 
0115 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0116 void Graph2DMobile::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
0117 #else
0118 void Graph2DMobile::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry)
0119 #endif
0120 {
0121     m_dirty = true;
0122 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0123     QQuickItem::geometryChanged(newGeometry, oldGeometry);
0124 #else
0125     QQuickItem::geometryChange(newGeometry, oldGeometry);
0126 #endif
0127 }
0128 
0129 QSGNode* Graph2DMobile::updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeData* /*data*/)
0130 {
0131     if (!window()) {
0132         delete node;
0133         return nullptr;
0134     }
0135 
0136     QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
0137     if (!n) {
0138         n = new QSGSimpleTextureNode();
0139         n->setOwnsTexture(true);
0140     }
0141     paint();
0142     n->setTexture(window()->createTextureFromImage(m_buffer));
0143     n->setRect(boundingRect());
0144     return n;
0145 }
0146 
0147 QStringList Graph2DMobile::filters() const
0148 {
0149     return {QObject::tr("PNG Image (*.png)")};
0150 }
0151 
0152 bool Graph2DMobile::save(const QUrl& url) const
0153 {
0154     if(!url.isLocalFile())
0155         return false;
0156 
0157     return m_buffer.save(url.toLocalFile());
0158 }