summaryrefslogtreecommitdiffstats
path: root/Cluster/plugins/gaugefiller
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2017-03-02 13:01:20 +0200
committerKatja Marttila <katja.marttila@qt.io>2017-03-16 13:10:30 +0000
commit77ecd7d03aeea3bb7d10ac8ef448920da11ae306 (patch)
tree09e9db05fee7102cfe6dff7c6172e0929a643457 /Cluster/plugins/gaugefiller
parent2bb4aedd6b16dd581c299f1bfdd4073d5c827e4a (diff)
Add multiscreen-demo sources
Change-Id: I96652b6d05285b751b6d8a99c81102facc2e8adb Reviewed-by: Alistair Adams <alistair.adams@qt.io> Reviewed-by: Risto Avila <risto.avila@qt.io> Reviewed-by: Tuukka Turunen <tuukka.turunen@theqtcompany.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
Diffstat (limited to 'Cluster/plugins/gaugefiller')
-rw-r--r--Cluster/plugins/gaugefiller/gauge.cpp264
-rw-r--r--Cluster/plugins/gaugefiller/gauge.h138
-rw-r--r--Cluster/plugins/gaugefiller/gaugefiller.pro23
-rw-r--r--Cluster/plugins/gaugefiller/gaugenode.cpp306
-rw-r--r--Cluster/plugins/gaugefiller/gaugenode.h164
-rw-r--r--Cluster/plugins/gaugefiller/plugin.cpp52
-rw-r--r--Cluster/plugins/gaugefiller/qmldir2
7 files changed, 949 insertions, 0 deletions
diff --git a/Cluster/plugins/gaugefiller/gauge.cpp b/Cluster/plugins/gaugefiller/gauge.cpp
new file mode 100644
index 0000000..419196f
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gauge.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gauge.h"
+#include "gaugenode.h"
+
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgflatcolormaterial.h>
+#include <QtMath>
+
+Gauge::Gauge(QQuickItem *parent)
+ : QQuickItem(parent)
+ , m_value(0)
+ , m_angle(0)
+ , m_numVertices(128)
+ , m_fillWidth(10)
+ , m_radius(0)
+ , m_updateGeometry(true)
+ , m_lefttoright(true)
+ , m_minAngle(0)
+ , m_maxAngle(270)
+ , m_minValue(0)
+ , m_maxValue(240)
+ , m_doNotFill(false)
+ , m_color(QColor(255, 0, 0))
+ , arc_length(0)
+ , arc_dist_per_vertices(0)
+ , frontCutDeg(0.0)
+ , backCutDeg(0.0)
+ , frontCutRad(0.0)
+ , backCutRad(0.0)
+ , m_cutRad(0)
+{
+ setFlag(ItemHasContents, true);
+}
+
+Gauge::~Gauge()
+{
+}
+
+void Gauge::setValue(qreal value)
+{
+ if (m_value == value || value > m_maxValue || value < m_minValue)
+ return;
+
+ m_value = value;
+ updateValue();
+
+ emit valueChanged(value);
+ update();
+}
+
+void Gauge::setNumVertices(int numVertices)
+{
+ if (m_numVertices == numVertices)
+ return;
+
+ m_numVertices = numVertices;
+ emit numVerticesChanged(numVertices);
+ update();
+}
+
+void Gauge::setFillWidth(double fillWidth)
+{
+ if (m_fillWidth == fillWidth)
+ return;
+
+ m_fillWidth = fillWidth;
+ emit fillWidthChanged(m_fillWidth);
+ update();
+}
+
+void Gauge::setRadius(int radius)
+{
+ if (m_radius == radius)
+ return;
+
+ m_radius = radius;
+ emit radiusChanged(m_radius);
+ update();
+}
+
+void Gauge::setMinAngle(double minAngle)
+{
+ if (m_minAngle == minAngle)
+ return;
+
+ m_minAngle = minAngle;
+
+ backCutDeg = m_minAngle;
+ backCutRad = qDegreesToRadians(backCutDeg);
+
+ if (m_minAngle < m_maxAngle)
+ m_lefttoright = true;
+ else
+ m_lefttoright = false;
+
+ updateValue();
+
+ emit minAngleChanged(m_minAngle);
+ update();
+}
+
+void Gauge::setMaxAngle(double maxAngle)
+{
+ if (m_maxAngle == maxAngle)
+ return;
+
+ m_maxAngle = maxAngle;
+
+ if (m_minAngle < m_maxAngle)
+ m_lefttoright = true;
+ else
+ m_lefttoright = false;
+
+ updateValue();
+ emit maxAngleChanged(m_maxAngle);
+ update();
+}
+
+void Gauge::setMinValue(double minValue)
+{
+ if (m_minValue == minValue)
+ return;
+
+ m_minValue = minValue;
+ emit minValueChanged(m_minValue);
+ update();
+}
+
+void Gauge::setMaxValue(double maxValue)
+{
+ if (m_maxValue == maxValue)
+ return;
+
+ m_maxValue = maxValue;
+ emit maxValueChanged(m_maxValue);
+ update();
+}
+
+void Gauge::setDoNotFill(bool doNotFill)
+{
+ if (m_doNotFill == doNotFill)
+ return;
+
+ m_doNotFill = doNotFill;
+ emit doNotFillChanged(m_doNotFill);
+ update();
+}
+
+void Gauge::setColor(QColor color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ emit colorChanged(m_color);
+ update();
+}
+
+void Gauge::setUpdateGeometry(bool updateGeometry)
+{
+ if (m_updateGeometry == updateGeometry)
+ return;
+ m_updateGeometry = updateGeometry;
+
+ if (m_updateGeometry)
+ calcArc();
+ else
+ m_cutRad = calcValueAsRad(m_value);
+
+ update();
+}
+
+float Gauge::calcValueAsRad(qreal value)
+{
+ return qDegreesToRadians((m_minAngle + ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (value - m_minValue)) - 180.);
+}
+
+void Gauge::updateValue()
+{
+ if (m_updateGeometry)
+ calcArc();
+ else
+ m_cutRad = calcValueAsRad(m_value);
+}
+
+void Gauge::calcArc()
+{
+ backCutDeg = m_minAngle;
+ backCutRad = qDegreesToRadians(backCutDeg - 270);
+
+ if (m_updateGeometry) {
+ m_angle = ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (m_value - m_minValue);
+ } else {
+ m_angle = ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (m_maxValue - m_minValue);
+ }
+
+ arc_length = qDegreesToRadians(m_angle);
+ arc_dist_per_vertices = arc_length / m_numVertices;
+
+ emit angleChanged(m_angle);
+}
+
+QSGNode *Gauge::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ GaugeNode *n = static_cast<GaugeNode *>(oldNode);
+
+ if (!n)
+ n = new GaugeNode(m_numVertices, m_color, m_doNotFill);
+
+ n->setLeftToRight(m_lefttoright);
+ n->setColor(m_color);
+ n->setBoundingRect(boundingRect());
+ n->setUpdateGeometry(m_updateGeometry);
+ n->setDoNotFill(m_doNotFill);
+ n->setBackCutRad(backCutRad);
+ n->setRadius(m_radius);
+ n->setArcDistPerVert(arc_dist_per_vertices);
+ n->setNumVertices(m_numVertices);
+ n->setFillWidth(m_fillWidth);
+ if (!m_updateGeometry)
+ n->setCutRad(m_cutRad);
+ n->draw();
+ return n;
+}
+
+void Gauge::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ if (m_radius == 0)
+ setRadius(newGeometry.height() * 0.5);
+
+ calcArc();
+ update();
+}
diff --git a/Cluster/plugins/gaugefiller/gauge.h b/Cluster/plugins/gaugefiller/gauge.h
new file mode 100644
index 0000000..f75f23a
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gauge.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAUGE_H
+#define GAUGE_H
+
+#include <QQuickItem>
+
+class Gauge : public QQuickItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
+ Q_PROPERTY(int numVertices READ numVertices WRITE setNumVertices NOTIFY numVerticesChanged)
+
+ Q_PROPERTY(bool updateGeometry READ updateGeometry WRITE setUpdateGeometry NOTIFY updateGeometryChanged)
+ Q_PROPERTY(double fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged)
+ Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
+
+ Q_PROPERTY(double minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
+ Q_PROPERTY(double maxAngle READ maxAngle WRITE setMaxAngle NOTIFY maxAngleChanged)
+
+ Q_PROPERTY(double minValue READ minValue WRITE setMinValue NOTIFY minValueChanged)
+ Q_PROPERTY(double maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged)
+
+ Q_PROPERTY(bool doNotFill READ doNotFill WRITE setDoNotFill NOTIFY doNotFillChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+
+public:
+ Gauge(QQuickItem *parent = 0);
+ ~Gauge();
+
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+
+ qreal value() const { return m_value; }
+ qreal angle() const { return m_angle; }
+ bool updateGeometry() const { return m_updateGeometry; }
+ int numVertices() const { return m_numVertices; }
+ double fillWidth() const { return m_fillWidth; }
+ int radius() const { return m_radius; }
+ double minAngle() const { return m_minAngle; }
+ double maxAngle() const { return m_maxAngle; }
+ double minValue() const { return m_minValue; }
+ double maxValue() const { return m_maxValue; }
+ bool doNotFill() const { return m_doNotFill; }
+ QColor color() const { return m_color; }
+
+ void setValue(qreal value);
+ void setNumVertices(int numVertices);
+ void setFillWidth(double fillWidth);
+ void setRadius(int radius);
+ void setMinAngle(double minAngle);
+ void setMaxAngle(double maxAngle);
+ void setMinValue(double minValue);
+ void setMaxValue(double maxValue);
+ void setDoNotFill(bool doNotFill);
+ void setColor(QColor color);
+ void setUpdateGeometry(bool updateGeometry);
+
+signals:
+ void valueChanged(qreal value);
+ void angleChanged(qreal angle);
+ void numVerticesChanged(int numVertices);
+ void fillWidthChanged(double fillWidth);
+ void radiusChanged(int radius);
+ void minAngleChanged(double minAngle);
+ void maxAngleChanged(double maxAngle);
+ void minValueChanged(double minValue);
+ void maxValueChanged(double maxValue);
+ void doNotFillChanged(bool doNotFill);
+ void colorChanged(QColor color);
+ void updateGeometryChanged(bool updateGeometry);
+
+public slots:
+
+private:
+ void calcArc();
+ float calcValueAsRad(qreal value);
+ void updateValue();
+
+private:
+ qreal m_value;
+ double m_angle;
+ int m_numVertices;
+ double m_fillWidth;
+ int m_radius;
+ bool m_updateGeometry;
+ bool m_lefttoright;
+
+ double m_minAngle;
+ double m_maxAngle;
+ double m_minValue;
+ double m_maxValue;
+
+ bool m_doNotFill;
+ QColor m_color;
+
+ //Internal
+ double arc_length;
+ double arc_dist_per_vertices;
+
+ double frontCutDeg;
+ double backCutDeg;
+
+ double frontCutRad;
+ double backCutRad;
+
+ float m_cutRad;
+};
+
+#endif // GAUGE_H
diff --git a/Cluster/plugins/gaugefiller/gaugefiller.pro b/Cluster/plugins/gaugefiller/gaugefiller.pro
new file mode 100644
index 0000000..01165c0
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugefiller.pro
@@ -0,0 +1,23 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = clustergaugefillerplugin
+QT += qml quick
+CONFIG += qt plugin c++11
+
+TARGET = $$qtLibraryTarget($$TARGET)
+uri = com.qtcompany.clustergaugefiller
+
+SOURCES += \
+ plugin.cpp \
+ gauge.cpp \
+ gaugenode.cpp
+
+HEADERS += \
+ gauge.h
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/Cluster/plugins/gaugefiller/gaugenode.cpp b/Cluster/plugins/gaugefiller/gaugenode.cpp
new file mode 100644
index 0000000..8b9703d
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugenode.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gaugenode.h"
+
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgflatcolormaterial.h>
+#include <QtMath>
+
+#define EXTRAVERTICES 3
+
+GaugeNode::GaugeNode(const int &numVertices, const QColor &color = QColor(255, 0, 0),
+ const bool &doNotFill = false)
+ : QSGGeometryNode()
+ //Could be optimized more. If only geometry update used we do not need to map textured points.
+ //, m_geometry(QSGGeometry::defaultAttributes_Point2D(), numVertices+EXTRAVERTICES)
+ , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), numVertices+EXTRAVERTICES)
+ , m_material(nullptr)
+ , m_numVertices(numVertices)
+ , m_doNotFill(doNotFill)
+ , m_color(color)
+ , m_cutRad(0.0)
+ , m_updateGeometry(true)
+ , m_lefttoright(true)
+ , m_dirtyBits(0)
+{
+ initGeometry();
+}
+
+GaugeNode::~GaugeNode()
+{
+ if (m_material)
+ delete m_material;
+}
+
+void GaugeNode::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+ m_color = color;
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setCutRad(const float &cutRad)
+{
+ if (m_cutRad == cutRad)
+ return;
+
+ m_cutRad = cutRad;
+ if (!m_updateGeometry)
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setDoNotFill(const bool &doNotFill)
+{
+ if (m_doNotFill == doNotFill)
+ return;
+
+ m_doNotFill = doNotFill;
+
+ if (m_doNotFill)
+ m_geometry.setDrawingMode(GL_LINE_STRIP);
+ else
+ m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
+
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setBackCutRad(const double &backCutRad)
+{
+ if (backCutRad == m_backCutRad)
+ return;
+
+ m_backCutRad = backCutRad;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setRadius(const double &radius)
+{
+ if (m_radius == radius)
+ return;
+
+ m_radius = radius;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setArcDistPerVert(const double &dist)
+{
+ if (dist == m_arc_dist_per_vertices)
+ return;
+ m_arc_dist_per_vertices = dist;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setNumVertices(const int &numVertices)
+{
+ if (numVertices == m_numVertices)
+ return;
+
+ m_numVertices = numVertices;
+ m_geometry.allocate(m_numVertices + 3);
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setFillWidth(const double &fillWidth)
+{
+ if (m_fillWidth == fillWidth)
+ return;
+
+ m_fillWidth = fillWidth;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setBoundingRect(const QRectF &rect)
+{
+ if (rect.width() == m_width && rect.height() == m_height)
+ return;
+
+ m_height = rect.height();
+ m_width = rect.width();
+ setCenterPoint(rect.center());
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setCenterPoint(const QPointF &center)
+{
+ m_center_x = center.x();
+ m_center_y = center.y();
+}
+
+void GaugeNode::setUpdateGeometry(const bool &updateGeometry)
+{
+ if (m_updateGeometry == updateGeometry)
+ return;
+
+ m_updateGeometry = updateGeometry;
+
+ if (m_material)
+ delete m_material;
+
+ if (m_updateGeometry) {
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ m_material = static_cast<QSGMaterial *>(material);
+ material->setColor(m_color);
+ setMaterial(m_material);
+ } else {
+ QSGSimpleMaterial<GaugeState> *material = GaugeShader::createMaterial();
+ m_material = static_cast<QSGMaterial *>(material);
+ material->state()->color = m_color;
+ material->state()->cutRad = m_cutRad;
+ material->state()->leftToRight = m_lefttoright;
+ material->setFlag(QSGMaterial::Blending);
+ setMaterial(m_material);
+ }
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setLeftToRight(const bool &ltr)
+{
+ if (m_lefttoright == ltr)
+ return;
+
+ m_lefttoright = ltr;
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::drawGeometryTexturePoint2D()
+{
+ QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D();
+
+ double current_angle_rad = 0.0;
+ double currentRadius = m_radius;
+ double d_arc_point_x = m_center_x + (currentRadius - m_fillWidth) * cos(m_backCutRad);
+ double d_arc_point_y = m_center_y + (currentRadius - m_fillWidth) * sin(m_backCutRad);
+
+ vertices[0].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ d_arc_point_x = m_center_x + currentRadius * cos(m_backCutRad);
+ d_arc_point_y = m_center_y + currentRadius * sin(m_backCutRad);
+ vertices[1].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ d_arc_point_x = 0;
+ d_arc_point_y = 0;
+
+ for (int i = 0; i < m_numVertices; ++i) {
+ current_angle_rad = m_backCutRad + i * m_arc_dist_per_vertices + m_arc_dist_per_vertices;
+
+ if (i % 2 == 0)
+ currentRadius -= m_fillWidth;
+ else
+ currentRadius += m_fillWidth;
+
+ d_arc_point_x = m_center_x + currentRadius * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + currentRadius * sin(current_angle_rad);
+ vertices[i + 2].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ }
+ d_arc_point_x = m_center_x + (currentRadius - m_fillWidth) * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + (currentRadius - m_fillWidth) * sin(current_angle_rad);
+
+ vertices[m_numVertices + 2].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+}
+
+void GaugeNode::drawMaterial()
+{
+ if (m_updateGeometry) {
+ static_cast<QSGFlatColorMaterial *>(m_material)->setColor(m_color);
+ } else {
+ GaugeState *s = static_cast<QSGSimpleMaterial<GaugeState> *>(m_material)->state();
+ s->color = m_color;
+ s->cutRad = m_cutRad;
+ s->leftToRight = m_lefttoright;
+ }
+}
+
+void GaugeNode::draw()
+{
+ if (m_dirtyBits == 0)
+ return;
+
+ if (m_dirtyBits.testFlag(QSGNode::DirtyGeometry))
+ drawGeometryTexturePoint2D();
+ if (m_dirtyBits.testFlag(QSGNode::DirtyMaterial))
+ drawMaterial();
+
+ markDirty(m_dirtyBits);
+ m_dirtyBits = 0;
+}
+
+//Could be used to optimize vertices if only geometry is changed
+void GaugeNode::drawGeometry()
+{
+ QSGGeometry::Point2D *vertices = m_geometry.vertexDataAsPoint2D();
+
+ double d_arc_point_x = 0.0;
+ double d_arc_point_y = 0.0;
+ double current_angle_rad = 0.0;
+ double currentRadius = m_radius;
+
+ vertices[0].set(m_center_x + (currentRadius - m_fillWidth) * cos(m_backCutRad), m_center_y
+ + (currentRadius - m_fillWidth) * sin(m_backCutRad));
+ vertices[1].set(m_center_x + currentRadius * cos(m_backCutRad), m_center_y
+ + currentRadius * sin(m_backCutRad));
+
+ for (int i = 0; i < m_numVertices; ++i) {
+ current_angle_rad = m_backCutRad + i * m_arc_dist_per_vertices + m_arc_dist_per_vertices;
+
+ if (i % 2 == 0)
+ currentRadius -= m_fillWidth;
+ else
+ currentRadius += m_fillWidth;
+
+ d_arc_point_x = m_center_x + currentRadius * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + currentRadius * sin(current_angle_rad);
+ vertices[i + 2].set(d_arc_point_x, d_arc_point_y);
+ }
+
+ vertices[m_numVertices + 2].set(m_center_x + (currentRadius - m_fillWidth)
+ * cos(current_angle_rad), m_center_y
+ + (currentRadius - m_fillWidth) * sin(current_angle_rad));
+
+ markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
+}
+
+void GaugeNode::initGeometry()
+{
+ m_geometry.setLineWidth(1);
+ if (m_doNotFill)
+ m_geometry.setDrawingMode(GL_LINE_STRIP);
+ else
+ m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
+
+ setGeometry(&m_geometry);
+
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ material->setColor(m_color);
+
+ m_material = static_cast<QSGMaterial *>(material);
+ setMaterial(m_material);
+}
diff --git a/Cluster/plugins/gaugefiller/gaugenode.h b/Cluster/plugins/gaugefiller/gaugenode.h
new file mode 100644
index 0000000..17e2a49
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugenode.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAUGENODE_H
+#define GAUGENODE_H
+
+#include <QSGNode>
+#include <QSGSimpleMaterial>
+#include <QColor>
+
+struct GaugeState
+{
+ QColor color;
+ GLfloat cutRad;
+ bool leftToRight;
+
+ int compare(const GaugeState *other) const
+ {
+ const unsigned int c = color.rgba();
+ const unsigned int co = other->color.rgba();
+ return std::tie(c, cutRad) > std::tie(co, other->cutRad);
+ }
+};
+
+class GaugeShader : public QSGSimpleMaterialShader<GaugeState>
+{
+ QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(GaugeShader, GaugeState)
+
+public:
+ const char *vertexShader() const {
+ return
+ "attribute highp vec4 aVertex; \n"
+ "attribute highp vec2 aTexCoord; \n"
+ "uniform highp mat4 qt_Matrix; \n"
+ "varying highp vec2 texCoord; \n"
+ "void main() { \n"
+ " gl_Position = qt_Matrix * aVertex; \n"
+ " texCoord = aTexCoord; \n"
+ "}";
+ }
+
+ const char *fragmentShader() const {
+ return
+ "uniform lowp float qt_Opacity; \n"
+ "uniform lowp vec4 color; \n"
+ "uniform highp float cutRad; \n"
+ "uniform lowp bool leftToRight; \n"
+ "varying highp vec2 texCoord; \n"
+ "void main() {\n"
+ " highp vec2 uv = vec2(.5 - texCoord.y, .5 - texCoord.x);\n"
+ " if (leftToRight ? (-atan(uv.y,uv.x) < cutRad) : (-atan(uv.y,uv.x) > cutRad)) {\n"
+ " gl_FragColor = color * qt_Opacity;\n"
+ " } else {\n"
+//debug color " gl_FragColor = vec4(0.,1.,0.,1.0);\n"
+ " gl_FragColor = vec4(0.,0.,0.,0.);\n"
+ " } \n"
+ "}\n";
+ }
+
+ QList<QByteArray> attributes() const
+ {
+ return QList<QByteArray>() << "aVertex" << "aTexCoord";
+ }
+
+ void updateState(const GaugeState *state, const GaugeState *)
+ {
+ program()->setUniformValue(id_color, state->color);
+ program()->setUniformValue(id_cutRad, state->cutRad);
+ program()->setUniformValue(id_leftToRight, state->leftToRight);
+ }
+
+ void resolveUniforms()
+ {
+ id_color = program()->uniformLocation("color");
+ id_cutRad = program()->uniformLocation("cutRad");
+ id_leftToRight = program()->uniformLocation("leftToRight");
+ }
+
+private:
+ int id_color;
+ int id_cutRad;
+ int id_leftToRight;
+};
+
+class GaugeNode : public QSGGeometryNode
+{
+public:
+ GaugeNode(const int &numVertices, const QColor &color, const bool &doNotFill);
+ ~GaugeNode();
+
+ void setColor(const QColor &color);
+ void setCutRad(const float &cutRad);
+
+ void setDoNotFill(const bool &doNotFill);
+
+ void setBackCutRad(const double &backCutRad);
+ void setRadius(const double &radius);
+ void setArcDistPerVert(const double &dist);
+ void setNumVertices(const int &numVertices);
+
+ void setFillWidth(const double &fillWidth);
+ void setBoundingRect(const QRectF &rect);
+ void setUpdateGeometry(const bool &updateGeometry);
+
+ void setLeftToRight(const bool &ltr);
+
+ void draw();
+
+private:
+ void initGeometry();
+ void setCenterPoint(const QPointF &center);
+
+ void drawGeometry();
+ void drawGeometryTexturePoint2D();
+ void drawMaterial();
+
+private:
+ QSGGeometry m_geometry;
+ QSGMaterial *m_material;
+ int m_numVertices;
+ bool m_doNotFill;
+ QColor m_color;
+ float m_cutRad;
+ double m_radius;
+ bool m_updateGeometry;
+ bool m_lefttoright;
+
+ qreal m_width;
+ qreal m_height;
+ double m_center_y;
+ double m_center_x;
+ double m_backCutRad;
+ double m_fillWidth;
+ double m_arc_dist_per_vertices;
+
+ DirtyState m_dirtyBits;
+};
+
+#endif // GAUGENODE_H
diff --git a/Cluster/plugins/gaugefiller/plugin.cpp b/Cluster/plugins/gaugefiller/plugin.cpp
new file mode 100644
index 0000000..e6732fd
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/plugin.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/qqmlextensionplugin.h>
+#include <qqml.h>
+#include "gauge.h"
+
+static QObject *clusterGaugeFillerSingletonFactory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(scriptEngine)
+ Q_UNUSED(engine)
+
+ return new Gauge();
+}
+
+class HoundPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("com.qtcompany.clustergaugefiller"));
+ qmlRegisterType<Gauge>(uri, 1, 0, "GaugeFiller");
+ }
+};
+
+#include "plugin.moc"
diff --git a/Cluster/plugins/gaugefiller/qmldir b/Cluster/plugins/gaugefiller/qmldir
new file mode 100644
index 0000000..1416273
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/qmldir
@@ -0,0 +1,2 @@
+module com.qtcompany.clustergaugefiller
+plugin clustergaugefillerplugin