C
Qt Cluster: Rendering and Recovery from Main UI Failure
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
// This file is part of the Qt Safe Renderer module
#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_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)
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::updateValue()
{
calcArc();
}
void Gauge::calcArc()
{
backCutDeg = m_minAngle;
backCutRad = qDegreesToRadians(backCutDeg - 270);
m_angle = ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
* (m_value - 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->setDoNotFill(m_doNotFill);
n->setBackCutRad(backCutRad);
n->setRadius(m_radius);
n->setArcDistPerVert(arc_dist_per_vertices);
n->setNumVertices(m_numVertices);
n->setFillWidth(m_fillWidth);
n->draw();
return n;
}
#if QT_VERSION >= 0x060000
void Gauge::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChange(newGeometry, oldGeometry);
#else
void Gauge::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChanged(newGeometry, oldGeometry);
#endif
if (m_radius == 0)
setRadius(newGeometry.height() * 0.5);
calcArc();
update();
}