diff options
author | Katja Marttila <katja.marttila@qt.io> | 2017-03-02 13:01:20 +0200 |
---|---|---|
committer | Katja Marttila <katja.marttila@qt.io> | 2017-03-16 13:10:30 +0000 |
commit | 77ecd7d03aeea3bb7d10ac8ef448920da11ae306 (patch) | |
tree | 09e9db05fee7102cfe6dff7c6172e0929a643457 /Cluster/plugins/gaugefiller | |
parent | 2bb4aedd6b16dd581c299f1bfdd4073d5c827e4a (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.cpp | 264 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/gauge.h | 138 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/gaugefiller.pro | 23 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/gaugenode.cpp | 306 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/gaugenode.h | 164 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/plugin.cpp | 52 | ||||
-rw-r--r-- | Cluster/plugins/gaugefiller/qmldir | 2 |
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 ¢er) +{ + 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 <r) +{ + 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 <r); + + void draw(); + +private: + void initGeometry(); + void setCenterPoint(const QPointF ¢er); + + 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 |