From 3552c79aec8d797e1219cf1979a75eee12897c2f Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 10 Jul 2023 15:54:53 +0200 Subject: [PATCH 01/42] initial commit --- .../LevelingSensor/QsgNodeUtility.cpp | 1 + src/controls/LevelingSensor/QsgNodeUtility.h | 100 +++++ .../LevelingSensor/QskLevelingSensor.cpp | 142 ++++++ .../LevelingSensor/QskLevelingSensor.h | 60 +++ .../LevelingSensor/QskLevelingSensorNodes.cpp | 0 .../LevelingSensor/QskLevelingSensorNodes.h | 297 +++++++++++++ .../QskLevelingSensorSkinlet.cpp | 415 ++++++++++++++++++ .../LevelingSensor/QskLevelingSensorSkinlet.h | 56 +++ .../QskLevelingSensorUtility.cpp | 1 + .../LevelingSensor/QskLevelingSensorUtility.h | 94 ++++ .../QskLevelingSensorUtility_test.cpp | 190 ++++++++ 11 files changed, 1356 insertions(+) create mode 100644 src/controls/LevelingSensor/QsgNodeUtility.cpp create mode 100644 src/controls/LevelingSensor/QsgNodeUtility.h create mode 100644 src/controls/LevelingSensor/QskLevelingSensor.cpp create mode 100644 src/controls/LevelingSensor/QskLevelingSensor.h create mode 100644 src/controls/LevelingSensor/QskLevelingSensorNodes.cpp create mode 100644 src/controls/LevelingSensor/QskLevelingSensorNodes.h create mode 100644 src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp create mode 100644 src/controls/LevelingSensor/QskLevelingSensorSkinlet.h create mode 100644 src/controls/LevelingSensor/QskLevelingSensorUtility.cpp create mode 100644 src/controls/LevelingSensor/QskLevelingSensorUtility.h create mode 100644 src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp diff --git a/src/controls/LevelingSensor/QsgNodeUtility.cpp b/src/controls/LevelingSensor/QsgNodeUtility.cpp new file mode 100644 index 00000000..df2a333d --- /dev/null +++ b/src/controls/LevelingSensor/QsgNodeUtility.cpp @@ -0,0 +1 @@ +#include "QsgNodeUtility.h" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QsgNodeUtility.h b/src/controls/LevelingSensor/QsgNodeUtility.h new file mode 100644 index 00000000..11e3ac84 --- /dev/null +++ b/src/controls/LevelingSensor/QsgNodeUtility.h @@ -0,0 +1,100 @@ +#pragma once + +#include +#include + +namespace qsg +{ + using NodeType = QSGNode; + + template + struct seq; + + template<> + struct seq<> + { + static void append(NodeType* root) + { + } + }; + + template + struct seq + { + static void append(NodeType* root) + { + T::append(root); + } + }; + + template + struct seq + { + static void append(NodeType* root) + { + T::append(root); + seq::append(root); + } + }; + + template + struct par; + + template + struct par + { + static void append(NodeType* root) + { + const auto n = N; + for (int i = 0; i < N; ++i) + { + root->appendChildNode(new T); + } + } + }; + + template + struct par + { + static void append(NodeType* root) + { + const auto n = N; + for (int i = 0; i < N; ++i) + { + auto* const t = new T; + U::append(t); + root->appendChildNode(t); + } + } + }; + + template + struct ensure; + + template + struct ensure + { + static Q_REQUIRED_RESULT Root* node(NodeType* root = nullptr) + { + if(root == nullptr) + { + root = new Root; + } + return static_cast(root); + } + }; + + template + struct ensure + { + static Q_REQUIRED_RESULT Root* node(NodeType* root = nullptr) + { + if(root == nullptr) + { + root = new Root; + Append::append(root); + } + return static_cast(root); + } + }; +} \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/LevelingSensor/QskLevelingSensor.cpp new file mode 100644 index 00000000..a42de6fc --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensor.cpp @@ -0,0 +1,142 @@ +#include "QskLevelingSensor.h" +#include + +namespace +{ + template + bool compareExchange(T& dst, const T& src) + { + if (dst != src) + { + dst = src; + return true; + } + return false; + } + + template<> + bool compareExchange(float& dst, const float& src) + { + if (!qFuzzyCompare(dst, src)) + { + dst = src; + return true; + } + return false; + } + + inline bool isAxis(const Qt::Axis axis) { + return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; + } +} + +QSK_SUBCONTROL(LevelingSensor, OuterDisk) +QSK_SUBCONTROL(LevelingSensor, Horizon) +QSK_SUBCONTROL(LevelingSensor, TickmarksX) +QSK_SUBCONTROL(LevelingSensor, TickmarksXLabels) +QSK_SUBCONTROL(LevelingSensor, TickmarksY) +QSK_SUBCONTROL(LevelingSensor, TickmarksYLabels) +QSK_SUBCONTROL(LevelingSensor, TickmarksZ) +QSK_SUBCONTROL(LevelingSensor, TickmarksZLabels) + +#define RETURN_IF_FALSE(expr) if(!(expr)) return; + +LevelingSensor::LevelingSensor(QQuickItem* const parent) + : Inherited(parent) +{ +} + +void LevelingSensor::setRotation(const QVector3D& degree) +{ + if (m_rotation != degree) + { + setRotation(Qt::XAxis, degree.x()); + setRotation(Qt::YAxis, degree.y()); + setRotation(Qt::ZAxis, degree.z()); + } +} + +void LevelingSensor::setRotation(const Qt::Axis axis, const float degree) +{ + RETURN_IF_FALSE(isAxis(axis)); + + if (compareExchange(m_rotation[axis], degree)) + { + update(); + switch(axis) + { + case Qt::XAxis: Q_EMIT rotationXChanged(m_rotation[axis]); break; + case Qt::YAxis: Q_EMIT rotationYChanged(m_rotation[axis]); break; + case Qt::ZAxis: Q_EMIT rotationZChanged(m_rotation[axis]); break; + } + Q_EMIT rotationChanged(m_rotation); + } +} + +void LevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmarks) +{ + RETURN_IF_FALSE(isAxis(axis)); + + m_tickmarks[axis] = std::move(tickmarks); + update(); +} + +void LevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels labels) +{ + RETURN_IF_FALSE(isAxis(axis)); + + m_tickmarksLabels[axis] = std::move(labels); + update(); +} + +void LevelingSensor::setAngle(const QVector3D& degree) +{ + if (compareExchange(m_angle, degree)) + { + update(); + Q_EMIT anglesChanged(m_angle); + } +} + +void LevelingSensor::setAngle(const Qt::Axis axis, const float degree) +{ + RETURN_IF_FALSE(isAxis(axis)); + + if (compareExchange(m_angle[axis], degree)) + { + update(); + Q_EMIT anglesChanged(m_angle); + } +} + +const QskScaleTickmarks& LevelingSensor::tickmarks(Qt::Axis axis) const +{ + if (isAxis(axis)) + { + return m_tickmarks[axis]; + } + static const QskScaleTickmarks invalid; + return invalid; +} + +const LevelingSensor::TickmarksLabels& LevelingSensor::tickmarkLabels(Qt::Axis axis) const +{ + if (isAxis(axis)) + { + return m_tickmarksLabels[axis]; + } + static const LevelingSensor::TickmarksLabels invalid; + return invalid; +} + +const QVector3D& LevelingSensor::angle() const noexcept +{ + return m_angle; +} + +const QVector3D& LevelingSensor::rotation() const noexcept +{ + return m_rotation; +} + +#include "moc_QskLevelingSensor.cpp" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h new file mode 100644 index 00000000..63b02ddd --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include + +/// @brief This control can display the pitch, roll and yaw angles +/// @note x = pitch, y = yaw, z = roll +/// +/// ^y+ +/// | +/// | +/// | +/// +------------->x+ +/// / +/// / +/// v z+ +class LevelingSensor : public QskControl +{ + Q_OBJECT + using Inherited = QskControl; +public: + QSK_SUBCONTROLS( + OuterDisk, + Horizon, + TickmarksX, + TickmarksXLabels, + TickmarksY, + TickmarksYLabels, + TickmarksZ, + TickmarksZLabels) + using Tickmarks = QskScaleTickmarks; + using TickmarksLabels = QVector>; + explicit LevelingSensor(QQuickItem* parent = nullptr); +public Q_SLOTS: + void setRotation(const QVector3D& degree); + void setRotation(Qt::Axis axis, float degree); + void setTickmarks(Qt::Axis axis, Tickmarks tickmarks); + void setTickmarksLabels(Qt::Axis axis, TickmarksLabels labels); + void setAngle(const QVector3D& degree); + void setAngle(Qt::Axis axis, float degree); +signals: + void rotationXChanged(qreal degree); + void rotationYChanged(qreal degree); + void rotationZChanged(qreal degree); + void rotationChanged(const QVector3D& degree); + void anglesChanged(const QVector3D& degree); +public: + Q_REQUIRED_RESULT const QVector3D& rotation() const noexcept; + Q_REQUIRED_RESULT const Tickmarks& tickmarks(Qt::Axis axis) const; + Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels(Qt::Axis axis) const; + Q_REQUIRED_RESULT const QVector3D& angle() const noexcept; +private: + /// @brief The sensors rotation per axis: x := roll, y := pitch, z := yaw + QVector3D m_rotation; + QVector3D m_angle = { 45,45,45 }; + Tickmarks m_tickmarks[3]; + TickmarksLabels m_tickmarksLabels[3]; +}; \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.cpp b/src/controls/LevelingSensor/QskLevelingSensorNodes.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/LevelingSensor/QskLevelingSensorNodes.h new file mode 100644 index 00000000..1202136e --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorNodes.h @@ -0,0 +1,297 @@ +#pragma once + +#include +#include +#include + +#include + +class RadialTickmarksNode final : public QSGGeometryNode +{ +public: + RadialTickmarksNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + { + m_geometry.setDrawingMode(QSGGeometry::DrawLines); + m_geometry.setVertexDataPattern(QSGGeometry::StaticPattern); + + setGeometry(&m_geometry); + setMaterial(&m_material); + } + + void setMaterialProperties(const QColor& color) + { + if (m_material.color() != color) + { + m_material.setColor(color); + markDirty(QSGNode::DirtyMaterial); + } + } + + void setGeometryProperties(const QskScaleTickmarks& tickmarks, const qreal r1 = 0.0, const QVector3D& r2 = { 0.5, 0.75, 1.0 }, float lineWidth = 1.0) + { + auto dirty = false; + + if (dirty |= (m_geometry.lineWidth() != lineWidth)) + { + m_geometry.setLineWidth(lineWidth); + } + + dirty |= compare_exchange(m_r1, r1); + dirty |= compare_exchange(m_r2, r2); + dirty |= compare_exchange(m_tickmarksHash, tickmarks.hash()); + + if (dirty) + { + update(tickmarks); + } + } + +private: + void update(const QskScaleTickmarks& tickmarks) + { + if (m_geometry.vertexCount() != tickmarks.tickCount()) + { + m_geometry.allocate(tickmarks.tickCount() * 2); + } + + auto* vertexData = m_geometry.vertexDataAsPoint2D(); + + using T = QskScaleTickmarks::TickType; + for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + { + for (const auto tick : tickmarks.ticks(type)) + { + const auto i = static_cast(type); + const auto angleRad = qDegreesToRadians(tick); + const auto x1 = qFastCos(angleRad) * m_r1; + const auto y1 = qFastSin(angleRad) * m_r1; + const auto x2 = qFastCos(angleRad) * m_r2[i]; + const auto y2 = qFastSin(angleRad) * m_r2[i]; + + vertexData[0].set(x1, y1); + vertexData[1].set(x2, y2); + vertexData += 2; + } + } + + m_geometry.markVertexDataDirty(); + markDirty(QSGNode::DirtyGeometry); + } + + QSGGeometry m_geometry; + QSGFlatColorMaterial m_material; + qreal m_r1 = 0.0; + QVector3D m_r2 = { 0.5, 0.75, 1.0 }; + QskHashValue m_tickmarksHash{ 0 }; +}; + +class LinearTickmarksNode final : public QSGGeometryNode +{ +public: + LinearTickmarksNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + { + m_geometry.setDrawingMode(QSGGeometry::DrawLines); + m_geometry.setVertexDataPattern(QSGGeometry::StaticPattern); + + setGeometry(&m_geometry); + setMaterial(&m_material); + } + + void setMaterialProperties(const QColor& color) + { + auto dirty = false; + + if (dirty |= (m_material.color() != color)) + { + m_material.setColor(color); + } + + if (dirty) + { + markDirty(QSGNode::DirtyMaterial); + } + } + + void setGeometryProperties(const QskScaleTickmarks& tickmarks, const QVector3D& tickmarkSize, const QVector2D& scale = { 1.0,0.0f }, const QVector2D& offset = {}, const float lineWidth = 1.0f, const bool forceDirty = false) + { + auto dirty = forceDirty; + + if (dirty |= !qFuzzyCompare(m_geometry.lineWidth(), lineWidth)) + { + m_geometry.setLineWidth(lineWidth); + } + + dirty |= m_geometry.vertexCount() != tickmarks.tickCount() * 2; + dirty |= compare_exchange(m_tickmarkSize, tickmarkSize); + dirty |= compare_exchange(m_scale, scale); + dirty |= compare_exchange(m_offset, offset); + + if (dirty) + { + update(tickmarks); + markDirty(QSGNode::DirtyGeometry); + } + } + +private: + void update(const QskScaleTickmarks& tickmarks) + { + if (m_geometry.vertexCount() != tickmarks.tickCount() * 2) + { + m_geometry.allocate(tickmarks.tickCount() * 2); + } + + auto* vertexData = m_geometry.vertexDataAsPoint2D(); + + using T = QskScaleTickmarks::TickType; + for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + { + for (const auto tick : tickmarks.ticks(type)) + { + const auto i = static_cast(type); + + const auto p = m_scale * tick; + const auto d = QVector2D(-m_scale.y(), m_scale.x()).normalized(); + + const auto p1 = m_tickmarkSize[i] * +1 * d + p + m_offset; + const auto p2 = m_tickmarkSize[i] * -1 * d + p + m_offset; + + vertexData[0].set(p1.x(), p1.y()); + vertexData[1].set(p2.x(), p2.y()); + vertexData += 2; + } + } + + m_geometry.markVertexDataDirty(); + } + + QSGGeometry m_geometry; + QSGFlatColorMaterial m_material; + QVector2D m_scale = { 1.0f, 0.0f }; + QVector2D m_offset = { 0.0f, 0.0f }; + QVector3D m_tickmarkSize = { 1.0, 2.0, 4.0 }; +}; + +class PolygonClipNode final : public QSGClipNode +{ +public: + PolygonClipNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + { + m_geometry.setVertexDataPattern(QSGGeometry::DynamicPattern); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangleFan); + setGeometry(&m_geometry); + setIsRectangular(false); + } + + void setGeometryProperties(const qreal radius = 1.0, const qreal cx = 0.0, const qreal cy = 0.0, const int count = 360) + { + auto dirty = false; + dirty |= compare_exchange(m_radius, radius); + dirty |= compare_exchange(m_cx, cx); + dirty |= compare_exchange(m_cy, cy); + dirty |= compare_exchange(m_count, count); + + if (dirty) + { + update(); + } + } + +private: + void update() + { + const auto step = 2.0 * M_PI / m_count; + + if (m_geometry.vertexCount() != m_count) + { + m_geometry.allocate(m_count); + } + + auto* vertices = m_geometry.vertexDataAsPoint2D(); + + for (int i = 0; i < m_count; ++i) + { + vertices[i].x = qFastCos(i * step) * m_radius + m_cx; + vertices[i].y = qFastSin(i * step) * m_radius + m_cy; + } + + m_geometry.markVertexDataDirty(); + markDirty(QSGNode::DirtyGeometry); + } + + using QSGClipNode::setIsRectangular; + using QSGClipNode::setClipRect; + + QSGGeometry m_geometry; + qreal m_radius = 1.0; + qreal m_cx = 0; + qreal m_cy = 0; + int m_count = 360; +}; + +template +struct TickmarksLabelsNode : public QSGNode +{ +public: + QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + { + return static_cast(this)->value(v, s, o); + } + + void update(const QskSkinnable* const skinnable, const QskAspect::Subcontrol subControl, const QVector>& labels, const QVector2D& scale = { 1.0, 0.0 }, const QVector2D& offset = {}) + { + if (childCount() != labels.count()) + { + removeAllChildNodes(); + for (const auto& label : qAsConst(labels)) + { + appendChildNode(new QskTextNode); + } + } + + const QFontMetricsF metrics(skinnable->effectiveFont(subControl)); + const auto h = skinnable->effectiveFontHeight(subControl); + const auto a = skinnable->alignmentHint(subControl); + + auto* textNode = static_cast(firstChild()); + for (const auto& label : qAsConst(labels)) + { + const auto v = value({ (float)label.first, (float)label.first }, scale, offset); + auto x = v.x(); + auto y = v.y(); + + const auto w = metrics.horizontalAdvance(label.second); + + x -= a.testFlag(Qt::AlignRight) ? w : 0; + x -= a.testFlag(Qt::AlignHCenter) ? w / 2 : 0; + + y -= a.testFlag(Qt::AlignBottom) ? h : 0; + y -= a.testFlag(Qt::AlignVCenter) ? h / 2 : 0; + + QskSkinlet::updateTextNode(skinnable, textNode, { x,y,w,h }, a, label.second, subControl); + + textNode = static_cast(textNode->nextSibling()); + } + } +}; + +struct LinearTickmarksLabelsNode final : public TickmarksLabelsNode +{ +public: + QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + { + return v * s + o; + } +}; + +struct RadialTickmarksLabelsNode final : public TickmarksLabelsNode +{ +public: + QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + { + return QVector2D{ + (float)qFastCos(qDegreesToRadians(v.x())), + (float)qFastSin(qDegreesToRadians(v.y())) + } *s + o; + } +}; diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp new file mode 100644 index 00000000..78bda401 --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -0,0 +1,415 @@ +#include "QskLevelingSensorSkinlet.h" +#include "QskLevelingSensor.h" +#include "QskLevelingSensorUtility.h" +#include "QskLevelingSensorNodes.h" +#include "QsgNodeUtility.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using Q = LevelingSensor; +using R = LevelingSensorSkinlet::NodeRole; + +using namespace qsg; + +float LevelingSensorSkinlet::radius2(const QskSkinnable* const skinnable) +{ + // outer radius + const auto* const sensor = static_cast(skinnable); + const auto contentsRect = sensor->contentsRect(); + return 0.5f * qMin(contentsRect.width(), contentsRect.height()); +} + +float LevelingSensorSkinlet::radius1(const QskSkinnable* const skinnable) +{ + const auto scale = skinnable->strutSizeHint(Q::Horizon); + return radius2(skinnable) * scale.width(); +} + +QPointF LevelingSensorSkinlet::center(const QskSkinnable* const skinnable) +{ + const auto* const sensor = static_cast(skinnable); + return sensor->contentsRect().center(); +} + +LevelingSensorSkinlet::LevelingSensorSkinlet(QskSkin* skin) + : Inherited(skin) +{ + setNodeRoles({ + OuterDisk, + Horizon, + HorizonClip, + TickmarksX, + TickmarksXLabels, + TickmarksY, + TickmarksYLabels, + TickmarksZ, + TickmarksZLabels, }); +} + +template +Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, + const QRectF& contentsRect) const = delete; + +template<> +Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, + const QRectF& contentsRect) const +{ + const auto radius = radius2(sensor); + const auto scale = sensor->strutSizeHint(Q::OuterDisk); + const auto width = 2 * radius * scale.width(); + const auto height = width; + const auto x = contentsRect.center().x() - width / 2; + const auto y = contentsRect.center().y() - height / 2; + return { x, y, width, height }; +} + +template<> +Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, + const QRectF& contentsRect) const +{ + const auto scale = sensor->strutSizeHint(Q::Horizon); + const auto width = 2 * radius1(sensor) * scale.width(); + const auto height = width; + return { + center(sensor).x() - width / 2, + center(sensor).y() - height / 2, + width, + height + }; +} + +QRectF LevelingSensorSkinlet::subControlRect(const QskSkinnable* skinnable, + const QRectF& contentsRect, QskAspect::Subcontrol subControl) const +{ + const auto* const sensor = static_cast(skinnable); + + if (subControl == Q::OuterDisk) + { + return subControlRect(sensor, contentsRect); + } + if (subControl == Q::Horizon) + { + return subControlRect(sensor, contentsRect); + } + + return Inherited::subControlRect(skinnable, contentsRect, subControl); +} + +template +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const = delete; + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::OuterDisk; + const auto contentsRect = sensor->contentsRect(); + const auto boxRect = subControlRect(sensor, contentsRect); + const auto boxShapeMetrics = QskBoxShapeMetrics{ boxRect.width() / 2 }; + const auto boxBorderMetrics = sensor->boxBorderMetricsHint(subControl); + const auto boxBorderColors = sensor->boxBorderColorsHint(subControl); + const auto boxGradient = sensor->gradientHint(subControl); + + auto* const root = ensure>::node(node); + auto* const bNode = static_cast(root->firstChild()); + + const auto size = radius2(sensor) * sensor->strutSizeHint(Q::OuterDisk).width(); + updateBoxNode(sensor, bNode, { 0, 0, 2 * size, 2 * size }, boxShapeMetrics, boxBorderMetrics, boxBorderColors, boxGradient); + + const auto cX = center(sensor).x(); + const auto cY = center(sensor).y(); + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + + const auto matrix = + matrix_deg(0.0, 0.0, 0.0, cX, cY, 0) * + matrix_deg(0.0, 0.0, rZ, 0, 0, 0) * + matrix_deg(0.0, 0.0, 0.0, -size, -size, 0); + + root->setMatrix(matrix); + return root; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::Horizon; + const auto r1 = radius1(sensor); + const auto cX = center(sensor).x(); + const auto cY = center(sensor).y(); + const auto rX = sensor->rotation().x(); + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto dY = 2 * sensor->angle().y(); + const auto p = qBound(0.0, 0.5 + (-rX / dY), 1.0); + + const auto shape = QskBoxShapeMetrics{ r1 }; + const auto bmetrics = sensor->boxBorderMetricsHint(subControl); + const auto bcolors = sensor->boxBorderColorsHint(subControl); + + auto gradient = sensor->gradientHint(Q::Horizon); + gradient.setDirection(QskGradient::Linear); + gradient.setLinearDirection(Qt::Vertical); + gradient.setStops({ + {0.0, gradient.startColor()}, + {p, gradient.startColor()}, + {p, gradient.endColor()}, + {1.0, gradient.endColor()} + }); + + auto* const tNode = ensure>::node(node); + auto* const boxNode = static_cast(tNode->firstChild()); + updateBoxNode(sensor, boxNode, { 0, 0, 2 * r1, 2 * r1 }, shape, bmetrics, bcolors, gradient); + + const auto matrix = + matrix_deg(0, 0, 0, cX, cY, 0) * + matrix_deg(0, 0, rZ, 0, 0, 0) * + matrix_deg(0, 0, 0, -r1, -r1, 0); + + tNode->setMatrix(matrix); + return tNode; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksX; + const auto color = sensor->color(subControl); + const auto scale = sensor->strutSizeHint(subControl); + + const auto cX = center(sensor).x(); + const auto cY = center(sensor).y(); + + const auto rX = sensor->rotation().x(); + const auto rY = sensor->rotation().y(); + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + + const auto r1 = radius1(sensor); + const auto r3 = r1 * scale.height(); + + const auto sX = r1 / sensor->angle().x(); + const auto sY = r1 / sensor->angle().y(); + + const auto tX = static_cast(rY * sX); + const auto tY = 0.0; // static_cast(rX * sY); + + auto* const clipping = ensure>>::node(node); + auto* const transform = static_cast(clipping->firstChild()); + auto* const tickmarks = static_cast(transform->firstChild()); + + auto size = qvariant_cast(sensor->effectiveSkinHint(subControl)) * r3; + + clipping->setGeometryProperties(r1, cX, cY); + + tickmarks->setMaterialProperties(color); + tickmarks->setGeometryProperties(sensor->tickmarks(Qt::XAxis), size, {sX, 0.0f}, {tX, tY}); + + const auto matrix = matrix_deg(0, 0, rZ, cX, cY, 0); + transform->setMatrix(matrix); + return clipping; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksY; + const auto color = sensor->color(subControl); + const auto scale = sensor->strutSizeHint(subControl); + + const auto r1 = radius1(sensor); + const auto r3 = r1 * scale.width(); + + const auto rX = 0.00; + const auto rY = 0.00; + const auto rZ = sensor->rotation().z(); + + const auto tX = center(sensor).x(); + const auto tY = center(sensor).y(); + const auto tZ = 0.0; + + auto* const cNode = ensure>>::node(node); + auto* const tNode = static_cast(cNode->firstChild()); + auto* const lNode = static_cast(tNode->firstChild()); + + auto size = qvariant_cast(sensor->effectiveSkinHint(subControl)) * r3; + + cNode->setGeometryProperties(r1, tX, tY); + + const auto sY = static_cast(r1 / sensor->angle().y()); + lNode->setMaterialProperties(color); +#ifdef USE_FILTERING + using TickType = QskScaleTickmarks::TickType; + const auto filter = [=](TickType, qreal v){ return rY - r1 / sY <= v && v <= rY + r1 / sY; }; + lNode->setGeometryProperties(filtered(sensor->tickmarks(Qt::YAxis), filter), size, {0.0f, sY}, {}, 1.0f, true); +#else + lNode->setGeometryProperties(sensor->tickmarks(Qt::YAxis), size, {0.0f, sY}); +#endif + + const auto matrix = matrix_deg(rX, rY, rZ, tX, tY, tZ); + tNode->setMatrix(matrix); + return cNode; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksZ; + const auto color = sensor->color(subControl); + const auto scale = sensor->strutSizeHint(subControl); + + const auto r1 = radius1(sensor); + const auto r2 = radius2(sensor); + const auto r3 = qvariant_cast(sensor->effectiveSkinHint(subControl)) * (r2 - r1) + QVector3D{r1, r1, r1}; + + auto* const transform = ensure>::node(node); + auto* const tickmarksNode = static_cast(transform->firstChild()); + tickmarksNode->setMaterialProperties(color); + tickmarksNode->setGeometryProperties(sensor->tickmarks(Qt::ZAxis), r1, r3); + + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto tX = center(sensor).x(); + const auto tY = center(sensor).y(); + + const auto matrix = matrix_deg(0.0, 0.0, rZ, tX, tY); + transform->setMatrix(matrix); + return transform; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksXLabels; + + const auto r1 = radius1(sensor); + const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksX).height()); + const auto sX = r1 / sensor->angle().x(); + const auto sY = r1 / sensor->angle().y(); + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto cX = center(sensor).x(); + const auto cY = center(sensor).y(); + const auto tX = sensor->rotation().y() * sX; + const auto tY = r3; + + auto* const cNode = ensure>>::node(node); + auto* const tNode = static_cast(cNode->firstChild()); + auto* const lNode = static_cast(tNode->firstChild()); + tNode->setMatrix(matrix_deg(0.0, 0.0, rZ, cX, cY)); + cNode->setGeometryProperties(r1, center(sensor).x(), center(sensor).y()); + lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::XAxis), { sX , 0.0}, {tX, tY}); + return cNode; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksYLabels; + const auto r1 = radius1(sensor); + const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksY).width()); + const auto cX = static_cast(center(sensor).x()); + const auto cY = static_cast(center(sensor).y()); + const auto rZ = sensor->rotation().z(); + + auto* const cNode = ensure>>::node(node); + auto* const tNode = static_cast(cNode->firstChild()); + auto* const lNode = static_cast(tNode->firstChild()); + cNode->setGeometryProperties(r1, cX, cY); + tNode->setMatrix(matrix_deg(0.0, 0.0, 0, cX, cY)); + lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::YAxis), { 0.0, r1 / sensor->angle().y() }, {r3, 0.0}); + return cNode; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto subControl = Q::TickmarksZLabels; + auto* const tNode = ensure>::node(node); + auto* const lNode = static_cast(tNode->firstChild()); + const auto r1 = radius1(sensor); + const auto r3 = static_cast(r1 * sensor->strutSizeHint(subControl).width()); + const auto cX = static_cast(center(sensor).x()); + const auto cY = static_cast(center(sensor).y()); + const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::ZAxis), { r3, r3 }); + tNode->setMatrix(matrix_deg(0.0, 0.0, rZ, cX, cY)); + return tNode; +} + +template<> +QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node) const +{ + const auto cX = center(sensor).x(); + const auto cY = center(sensor).y(); + const auto r1 = radius1(sensor); + + auto* const clipNode = ensure::node(node); + clipNode->setGeometryProperties(r1, cX, cY); + return clipNode; +} + +QSGNode* LevelingSensorSkinlet::updateSubNode( + const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node) const +{ + const auto* const sensor = static_cast(skinnable); + + const auto subControl = [nodeRole, sensor](){ + switch(static_cast(nodeRole)) + { + case OuterDisk: return Q::OuterDisk; + case Horizon: return Q::Horizon; + case HorizonClip: return Q::Horizon; + case TickmarksX: return Q::TickmarksX; + case TickmarksXLabels: return Q::TickmarksXLabels; + case TickmarksY: return Q::TickmarksY; + case TickmarksYLabels: return Q::TickmarksYLabels; + case TickmarksZ: return Q::TickmarksZ; + case TickmarksZLabels: return Q::TickmarksZLabels; + default: return QskAspect::NoSubcontrol; + } + }(); + + if (qvariant_cast(sensor->effectiveSkinHint(subControl | QskAspect::Option))) + { + return nullptr; + } + + switch(static_cast(nodeRole)) + { + case OuterDisk: return updateSubNode(sensor, nodeRole, node); + case Horizon: return updateSubNode(sensor, nodeRole, node); + case HorizonClip: return updateSubNode(sensor, nodeRole, node); + case TickmarksX: return updateSubNode(sensor, nodeRole, node); + case TickmarksXLabels: return updateSubNode(sensor, nodeRole, node); + case TickmarksY: return updateSubNode(sensor, nodeRole, node); + case TickmarksYLabels: return updateSubNode(sensor, nodeRole, node); + case TickmarksZ: return updateSubNode(sensor, nodeRole, node); + case TickmarksZLabels: return updateSubNode(sensor, nodeRole, node); + default: return Inherited::updateSubNode(sensor, nodeRole, node); + } +} + +#include "moc_QskLevelingSensorSkinlet.cpp" diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h new file mode 100644 index 00000000..6be5b9fc --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +class LevelingSensor; + +class LevelingSensorSkinlet : public QskSkinlet +{ + Q_GADGET + + using Inherited = QskSkinlet; + +public: + enum NodeRole + { + OuterDisk, + Horizon, + HorizonClip, + TickmarksX, + TickmarksXLabels, + TickmarksY, + TickmarksYLabels, + TickmarksZ, + TickmarksZLabels, + TriangleBar, + TickmarksYIndicator, + RoleCount + }; + + Q_INVOKABLE LevelingSensorSkinlet(QskSkin* skin = nullptr); + ~LevelingSensorSkinlet() override = default; + + /// @returns Returns the inner radius of the @p skinnable + static Q_REQUIRED_RESULT float radius2(const QskSkinnable* const skinnable); + /// @returns Returns the outer radius of the @p skinnable + static Q_REQUIRED_RESULT float radius1(const QskSkinnable* const skinnable); + /// @returns Returns the center point of the control + static Q_REQUIRED_RESULT QPointF center(const QskSkinnable* const skinnable); + +protected: + + Q_REQUIRED_RESULT QRectF subControlRect(const QskSkinnable* skinnable, + const QRectF& contentsRect, QskAspect::Subcontrol subControl) const override; + + Q_REQUIRED_RESULT QSGNode* updateSubNode(const QskSkinnable* skinnable, + quint8 nodeRole, QSGNode* node) const override; + + template + Q_REQUIRED_RESULT QRectF subControlRect(const LevelingSensor* sensor, + const QRectF& contentsRect) const; + + template + Q_REQUIRED_RESULT QSGNode* updateSubNode(const LevelingSensor* sensor, + quint8 nodeRole, QSGNode* node) const; +}; diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp b/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp new file mode 100644 index 00000000..e28b1e35 --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp @@ -0,0 +1 @@ +#include "QskLevelingSensorUtility.h" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.h b/src/controls/LevelingSensor/QskLevelingSensorUtility.h new file mode 100644 index 00000000..cba2ea20 --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility.h @@ -0,0 +1,94 @@ +#pragma once + +#include +#include + +#include + +// create a homogenous transformation matrix +inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( + float rX = 0.0f, + float rY = 0.0f, + float rZ = 0.0f, + float tX = 0.0f, + float tY = 0.0f, + float tZ = 0.0f +) +{ + // Convert rotation angles to radians + float rotationX = qDegreesToRadians(rX); + float rotationY = qDegreesToRadians(rY); + float rotationZ = qDegreesToRadians(rZ); + + // Calculate sin and cos of the rotation angles + float cosX = qCos(rotationX); + float sinX = qSin(rotationX); + float cosY = qCos(rotationY); + float sinY = qSin(rotationY); + float cosZ = qCos(rotationZ); + float sinZ = qSin(rotationZ); + + // Create the transform matrix + return QMatrix4x4( + cosY * cosZ, sinX * sinY * cosZ - cosX * sinZ, cosX * sinY * cosZ + sinX * sinZ, tX, + cosY * sinZ, sinX * sinY * sinZ + cosX * cosZ, cosX * sinY * sinZ - sinX * cosZ, tY, + -sinY, sinX * cosY, cosX * cosY, tZ, + 0, 0, 0, 1 + ); +} + +template +inline bool compare_exchange(T& dst, const T& src) +{ + if (dst != src) + { + dst = src; + return true; + } + return false; +} + +template<> +inline bool compare_exchange(float& dst, const float& src) +{ + if (!qFuzzyCompare(dst, src)) + { + dst = src; + return true; + } + return false; +} + +template<> +inline bool compare_exchange(qreal& dst, const qreal& src) +{ + if (!qFuzzyCompare(dst, src)) + { + dst = src; + return true; + } + return false; +} + +inline QskScaleTickmarks filtered(const QskScaleTickmarks& tickmarks, const std::function& predicate) +{ + QskScaleTickmarks result; + QVector ticks[3]; + + using T = QskScaleTickmarks::TickType; + for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + { + for (const auto tick : tickmarks.ticks(type)) + { + if (predicate(type, tick)) + { + ticks[type] << tick; + } + } + } + + result.setMinorTicks(ticks[QskScaleTickmarks::MinorTick]); + result.setMediumTicks(ticks[QskScaleTickmarks::MediumTick]); + result.setMajorTicks(ticks[QskScaleTickmarks::MajorTick]); + return result; +} \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp b/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp new file mode 100644 index 00000000..f8baa02b --- /dev/null +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp @@ -0,0 +1,190 @@ +#include +#include +#include +#include + +#include + +#include "QskLevelingSensorUtility.h" + +#define ASSERT_TRUE(expr) if(!(expr)) { std::cerr << "ASSERT_TRUE(!" << #expr << "):" << __LINE__ << '\n'; return false; } + +class QSGNodeBase : public QSGNode +{ +public: + virtual std::string name() const = 0; +}; + +class QSGNodeA final : public QSGNodeBase{ public: QSGNodeA() { std::cout << name() << '\n'; } std::string name() const override { return "A"; }}; +class QSGNodeB final : public QSGNodeBase{ public: QSGNodeB() { std::cout << name() << '\n'; } std::string name() const override { return "B"; }}; +class QSGNodeC final : public QSGNodeBase{ public: QSGNodeC() { std::cout << name() << '\n'; } std::string name() const override { return "C"; }}; +class QSGNodeD final : public QSGNodeBase{ public: QSGNodeD() { std::cout << name() << '\n'; } std::string name() const override { return "D"; }}; +class QSGNodeE final : public QSGNodeBase{ public: QSGNodeE() { std::cout << name() << '\n'; } std::string name() const override { return "E"; }}; +class QSGNodeF final : public QSGNodeBase{ public: QSGNodeF() { std::cout << name() << '\n'; } std::string name() const override { return "F"; }}; +class QSGNodeG final : public QSGNodeBase{ public: QSGNodeG() { std::cout << name() << '\n'; } std::string name() const override { return "G"; }}; +class QSGNodeH final : public QSGNodeBase{ public: QSGNodeH() { std::cout << name() << '\n'; } std::string name() const override { return "H"; }}; + +using NodeType = QSGNode; + +bool testcase_ensure_node() +{ + NodeType* root = nullptr; + ASSERT_TRUE(root = ensure_node()); + ASSERT_TRUE(root->childCount() == 0); + delete root; + return true; +} + +// seq> + +/* + +bool testcase_seq() +{ + using namespace qsg; + { + auto* const root = ensure_node(); + seq, N, N>::append(root); + delete root; + } + { + auto* const root = ensure_node(); + ASSERT_TRUE(root); + ASSERT_TRUE(root->childCount() == 0); + qsg::seq<>::append(root); + ASSERT_TRUE(root->childCount() == 0); + delete root; + } + { + auto* const root = ensure_node(); + ASSERT_TRUE(root); + ASSERT_TRUE(root->childCount() == 0); + qsg::seq>::append(root); + ASSERT_TRUE(root->childCount() == 1); + delete root; + } + { + auto* const root = ensure_node(); + ASSERT_TRUE(root); + ASSERT_TRUE(root->childCount() == 0); + qsg::seq, N>::append(root); + ASSERT_TRUE(root->childCount() == 2); + delete root; + } + { + // - QSGNode + // - QSGNodeA + // - QSGNodeB + // - QSGNodeC + auto* const root = ensure_node(); + ASSERT_TRUE(root); + ASSERT_TRUE(root->childCount() == 0); + qsg::seq, N, N>::append(root); + ASSERT_TRUE(root->childCount() == 3); + delete root; + } + return true; +} + +*/ + +bool testcase_par() +{ + using namespace qsg; + { + std::cout << __func__ << 0 << '\n'; + //auto* const root = ensure_node(); + //ASSERT_TRUE(root->childCount() == 0); + //par<4, QSGNodeA, par<4, QSGNodeB>>::append(root); + //ASSERT_TRUE(root->childCount() == 4); + //for(int i = 0; i < 4; ++i) + //{ + // ASSERT_TRUE(root->childAtIndex(i)->childCount() == 4); + //} + //delete root; + } + { + std::cout << __func__ << 1 << '\n'; + // - QSGNode + // - QSGNodeA + // - QSGNodeB + // - QSGNodeC + // - QSGNodeD + // - QSGNodeA + // - QSGNodeB + // - QSGNodeC + // - QSGNodeD + // - QSGNodeA + // - QSGNodeB + // - QSGNodeC + // - QSGNodeD + // - QSGNodeA + // - QSGNodeB + // - QSGNodeC + // - QSGNodeD + auto* const root = ensure_node(); + ASSERT_TRUE(root->childCount() == 0); + par<4, QSGNodeA, + seq, + par<1, QSGNodeC>, + par<1, QSGNodeD>>>::append(root); + ASSERT_TRUE(root->childCount() == 4); + ASSERT_TRUE(root->childAtIndex(0)->childCount() == 3); + ASSERT_TRUE(root->childAtIndex(1)->childCount() == 3); + ASSERT_TRUE(root->childAtIndex(2)->childCount() == 3); + ASSERT_TRUE(root->childAtIndex(3)->childCount() == 3); + } + { + std::cout << __func__ << 3 << '\n'; + auto* const root = ensure_node(); + seq< + par<1, QSGNodeE, + seq< + par<1, QSGNodeA>, + par<1, QSGNodeB>, + par<1, QSGNodeC>>>, + par<1, QSGNodeF, + seq< + par<1, QSGNodeB>, + par<1, QSGNodeC>, + par<1, QSGNodeA>>>, + par<1, QSGNodeG, + seq< + par<1, QSGNodeC>, + par<1, QSGNodeA>, + par<1, QSGNodeB>>> + >::append(root); + ASSERT_TRUE(root->childCount() == 3); + for(int i = 0; i < root->childCount(); ++i) + { + ASSERT_TRUE(root->childAtIndex(i)->childCount() == 3); + for(int j = 0; j < root->childAtIndex(i)->childAtIndex(i)->childCount(); ++j) + { + ASSERT_TRUE(root->childAtIndex(i)->childCount() == 0); + } + } + ASSERT_TRUE(dynamic_cast(root->childAtIndex(0))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(0))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(1))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(2))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(1))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(0))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(1))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(2))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(2))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(0))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(1))); + ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(2))); + } + return true; +} + +int main() +{ + bool result = true; + // result &= testcase_ensure_node(); + // result &= testcase_seq(); + result &= testcase_par(); + std::cout << (result ? "ok" : "failed") << std::endl; + return result ? EXIT_SUCCESS : EXIT_FAILURE; +} \ No newline at end of file From 95f6a25094198c844a26ca4f48d29daf53d07ad0 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 13 Jul 2023 09:38:44 +0200 Subject: [PATCH 02/42] integrate leveling sensor into qskinny --- src/CMakeLists.txt | 19 +++++++++++++++++++ .../LevelingSensor/QskLevelingSensor.h | 4 ++-- .../LevelingSensor/QskLevelingSensorSkinlet.h | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07b1b761..57edb507 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -422,6 +422,22 @@ list(APPEND SOURCES inputpanel/QskVirtualKeyboard.cpp ) +list(APPEND HEADERS + controls/LevelingSensor/QsgNodeUtility.h + controls/LevelingSensor/QskLevelingSensor.h + controls/LevelingSensor/QskLevelingSensorNodes.h + controls/LevelingSensor/QskLevelingSensorSkinlet.h + controls/LevelingSensor/QskLevelingSensorUtility.h +) + +list(APPEND SOURCES + controls/LevelingSensor/QsgNodeUtility.cpp + controls/LevelingSensor/QskLevelingSensor.cpp + controls/LevelingSensor/QskLevelingSensorNodes.cpp + controls/LevelingSensor/QskLevelingSensorSkinlet.cpp + controls/LevelingSensor/QskLevelingSensorUtility.cpp +) + if(ENABLE_PINYIN) list(APPEND HEADERS inputpanel/QskPinyinTextPredictor.h) list(APPEND SOURCES inputpanel/QskPinyinTextPredictor.cpp) @@ -485,3 +501,6 @@ set_target_properties(${target} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) install(TARGETS ${target} ) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h index 63b02ddd..f077dfb2 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.h +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -16,7 +16,7 @@ /// / /// / /// v z+ -class LevelingSensor : public QskControl +class QSK_EXPORT LevelingSensor : public QskControl { Q_OBJECT using Inherited = QskControl; @@ -40,7 +40,7 @@ public Q_SLOTS: void setTickmarksLabels(Qt::Axis axis, TickmarksLabels labels); void setAngle(const QVector3D& degree); void setAngle(Qt::Axis axis, float degree); -signals: +Q_SIGNALS: void rotationXChanged(qreal degree); void rotationYChanged(qreal degree); void rotationZChanged(qreal degree); diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h index 6be5b9fc..5b2db976 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h @@ -5,7 +5,7 @@ class LevelingSensor; -class LevelingSensorSkinlet : public QskSkinlet +class QSK_EXPORT LevelingSensorSkinlet : public QskSkinlet { Q_GADGET From ff39396e47a4ae614937cd9d7847debfb8afb4b3 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:03:33 +0200 Subject: [PATCH 03/42] rename qsg namespace --- src/controls/LevelingSensor/QsgNodeUtility.h | 2 +- src/controls/LevelingSensor/QskLevelingSensor.h | 12 ------------ .../LevelingSensor/QskLevelingSensorSkinlet.cpp | 6 +++--- .../LevelingSensor/QskLevelingSensorUtility.h | 5 +++-- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/controls/LevelingSensor/QsgNodeUtility.h b/src/controls/LevelingSensor/QsgNodeUtility.h index 11e3ac84..70b26504 100644 --- a/src/controls/LevelingSensor/QsgNodeUtility.h +++ b/src/controls/LevelingSensor/QsgNodeUtility.h @@ -3,7 +3,7 @@ #include #include -namespace qsg +namespace QskSGNode { using NodeType = QSGNode; diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h index f077dfb2..b27229bc 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.h +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -5,17 +5,6 @@ #include #include -/// @brief This control can display the pitch, roll and yaw angles -/// @note x = pitch, y = yaw, z = roll -/// -/// ^y+ -/// | -/// | -/// | -/// +------------->x+ -/// / -/// / -/// v z+ class QSK_EXPORT LevelingSensor : public QskControl { Q_OBJECT @@ -52,7 +41,6 @@ public: Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels(Qt::Axis axis) const; Q_REQUIRED_RESULT const QVector3D& angle() const noexcept; private: - /// @brief The sensors rotation per axis: x := roll, y := pitch, z := yaw QVector3D m_rotation; QVector3D m_angle = { 45,45,45 }; Tickmarks m_tickmarks[3]; diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 78bda401..89025b12 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -27,7 +27,7 @@ using Q = LevelingSensor; using R = LevelingSensorSkinlet::NodeRole; -using namespace qsg; +using namespace QskSGNode; float LevelingSensorSkinlet::radius2(const QskSkinnable* const skinnable) { @@ -137,7 +137,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor const auto cX = center(sensor).x(); const auto cY = center(sensor).y(); - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto rZ = 0.0; const auto matrix = matrix_deg(0.0, 0.0, 0.0, cX, cY, 0) * @@ -157,7 +157,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const auto cX = center(sensor).x(); const auto cY = center(sensor).y(); const auto rX = sensor->rotation().x(); - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto rZ = 0.0; const auto dY = 2 * sensor->angle().y(); const auto p = qBound(0.0, 0.5 + (-rX / dY), 1.0); diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.h b/src/controls/LevelingSensor/QskLevelingSensorUtility.h index cba2ea20..99d73f9a 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorUtility.h +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility.h @@ -4,6 +4,7 @@ #include #include +#include // create a homogenous transformation matrix inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( @@ -51,7 +52,7 @@ inline bool compare_exchange(T& dst, const T& src) template<> inline bool compare_exchange(float& dst, const float& src) { - if (!qFuzzyCompare(dst, src)) + if (!qskFuzzyCompare (dst, src)) { dst = src; return true; @@ -62,7 +63,7 @@ inline bool compare_exchange(float& dst, const float& src) template<> inline bool compare_exchange(qreal& dst, const qreal& src) { - if (!qFuzzyCompare(dst, src)) + if (!qskFuzzyCompare (dst, src)) { dst = src; return true; From 6d5c89fffa6215651fde5594ebbd9e2944b17c8a Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:19:01 +0200 Subject: [PATCH 04/42] renamed utility files --- src/CMakeLists.txt | 4 ++-- src/controls/LevelingSensor/QsgNodeUtility.cpp | 1 - src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp | 2 +- src/controls/LevelingSensor/QskSGNodeUtility.cpp | 1 + .../LevelingSensor/{QsgNodeUtility.h => QskSGNodeUtility.h} | 0 5 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 src/controls/LevelingSensor/QsgNodeUtility.cpp create mode 100644 src/controls/LevelingSensor/QskSGNodeUtility.cpp rename src/controls/LevelingSensor/{QsgNodeUtility.h => QskSGNodeUtility.h} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 57edb507..527d6b84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -423,7 +423,7 @@ list(APPEND SOURCES ) list(APPEND HEADERS - controls/LevelingSensor/QsgNodeUtility.h + controls/LevelingSensor/QskSGNodeUtility.h controls/LevelingSensor/QskLevelingSensor.h controls/LevelingSensor/QskLevelingSensorNodes.h controls/LevelingSensor/QskLevelingSensorSkinlet.h @@ -431,7 +431,7 @@ list(APPEND HEADERS ) list(APPEND SOURCES - controls/LevelingSensor/QsgNodeUtility.cpp + controls/LevelingSensor/QskSGNodeUtility.cpp controls/LevelingSensor/QskLevelingSensor.cpp controls/LevelingSensor/QskLevelingSensorNodes.cpp controls/LevelingSensor/QskLevelingSensorSkinlet.cpp diff --git a/src/controls/LevelingSensor/QsgNodeUtility.cpp b/src/controls/LevelingSensor/QsgNodeUtility.cpp deleted file mode 100644 index df2a333d..00000000 --- a/src/controls/LevelingSensor/QsgNodeUtility.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "QsgNodeUtility.h" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 89025b12..3de8b6d5 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -2,7 +2,7 @@ #include "QskLevelingSensor.h" #include "QskLevelingSensorUtility.h" #include "QskLevelingSensorNodes.h" -#include "QsgNodeUtility.h" +#include "QskSGNodeUtility.h" #include #include diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.cpp b/src/controls/LevelingSensor/QskSGNodeUtility.cpp new file mode 100644 index 00000000..3955c56e --- /dev/null +++ b/src/controls/LevelingSensor/QskSGNodeUtility.cpp @@ -0,0 +1 @@ +#include "QskSGNodeUtility.h" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QsgNodeUtility.h b/src/controls/LevelingSensor/QskSGNodeUtility.h similarity index 100% rename from src/controls/LevelingSensor/QsgNodeUtility.h rename to src/controls/LevelingSensor/QskSGNodeUtility.h From f49f2f7c3a456c91a3762021e40e5323f79849b8 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:24:36 +0200 Subject: [PATCH 05/42] use qskFuzzyCompare --- src/controls/LevelingSensor/QskLevelingSensor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/LevelingSensor/QskLevelingSensor.cpp index a42de6fc..cfe28825 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensor.cpp @@ -1,5 +1,6 @@ #include "QskLevelingSensor.h" #include +#include namespace { @@ -17,7 +18,7 @@ namespace template<> bool compareExchange(float& dst, const float& src) { - if (!qFuzzyCompare(dst, src)) + if (!qskFuzzyCompare(dst, src)) { dst = src; return true; From 0f29ad0c72bc2f63d6982b8f2d27b8a226ec5d1d Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:28:59 +0200 Subject: [PATCH 06/42] remove test sub folder --- src/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 527d6b84..96e0b469 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -500,7 +500,4 @@ set_target_properties(${target} PROPERTIES PUBLIC_HEADER "${HEADERS}") set_target_properties(${target} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) -install(TARGETS ${target} ) - -enable_testing() -add_subdirectory(tests) \ No newline at end of file +install(TARGETS ${target} ) \ No newline at end of file From 5d973ea50824a3ffb46b9cdd22c619a7a464edee Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:32:15 +0200 Subject: [PATCH 07/42] rename compareExchange --- .../LevelingSensor/QskLevelingSensorNodes.h | 20 +++++++++---------- .../LevelingSensor/QskLevelingSensorUtility.h | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/LevelingSensor/QskLevelingSensorNodes.h index 1202136e..d245d703 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorNodes.h +++ b/src/controls/LevelingSensor/QskLevelingSensorNodes.h @@ -36,9 +36,9 @@ public: m_geometry.setLineWidth(lineWidth); } - dirty |= compare_exchange(m_r1, r1); - dirty |= compare_exchange(m_r2, r2); - dirty |= compare_exchange(m_tickmarksHash, tickmarks.hash()); + dirty |= compareExchange(m_r1, r1); + dirty |= compareExchange(m_r2, r2); + dirty |= compareExchange(m_tickmarksHash, tickmarks.hash()); if (dirty) { @@ -122,9 +122,9 @@ public: } dirty |= m_geometry.vertexCount() != tickmarks.tickCount() * 2; - dirty |= compare_exchange(m_tickmarkSize, tickmarkSize); - dirty |= compare_exchange(m_scale, scale); - dirty |= compare_exchange(m_offset, offset); + dirty |= compareExchange(m_tickmarkSize, tickmarkSize); + dirty |= compareExchange(m_scale, scale); + dirty |= compareExchange(m_offset, offset); if (dirty) { @@ -186,10 +186,10 @@ public: void setGeometryProperties(const qreal radius = 1.0, const qreal cx = 0.0, const qreal cy = 0.0, const int count = 360) { auto dirty = false; - dirty |= compare_exchange(m_radius, radius); - dirty |= compare_exchange(m_cx, cx); - dirty |= compare_exchange(m_cy, cy); - dirty |= compare_exchange(m_count, count); + dirty |= compareExchange(m_radius, radius); + dirty |= compareExchange(m_cx, cx); + dirty |= compareExchange(m_cy, cy); + dirty |= compareExchange(m_count, count); if (dirty) { diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.h b/src/controls/LevelingSensor/QskLevelingSensorUtility.h index 99d73f9a..42cee547 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorUtility.h +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility.h @@ -39,7 +39,7 @@ inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( } template -inline bool compare_exchange(T& dst, const T& src) +inline bool compareExchange(T& dst, const T& src) { if (dst != src) { @@ -50,7 +50,7 @@ inline bool compare_exchange(T& dst, const T& src) } template<> -inline bool compare_exchange(float& dst, const float& src) +inline bool compareExchange(float& dst, const float& src) { if (!qskFuzzyCompare (dst, src)) { @@ -61,7 +61,7 @@ inline bool compare_exchange(float& dst, const float& src) } template<> -inline bool compare_exchange(qreal& dst, const qreal& src) +inline bool compareExchange(qreal& dst, const qreal& src) { if (!qskFuzzyCompare (dst, src)) { From 53b139820aa885e1b7a83ed127f055fc6c0b0f83 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 10:41:29 +0200 Subject: [PATCH 08/42] rename inner and outer radius --- .../QskLevelingSensorSkinlet.cpp | 31 +++++++++---------- .../LevelingSensor/QskLevelingSensorSkinlet.h | 7 ++--- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 3de8b6d5..6328be43 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -29,18 +29,17 @@ using R = LevelingSensorSkinlet::NodeRole; using namespace QskSGNode; -float LevelingSensorSkinlet::radius2(const QskSkinnable* const skinnable) +float LevelingSensorSkinlet::outerRadius(const QskSkinnable* const skinnable) { - // outer radius const auto* const sensor = static_cast(skinnable); const auto contentsRect = sensor->contentsRect(); return 0.5f * qMin(contentsRect.width(), contentsRect.height()); } -float LevelingSensorSkinlet::radius1(const QskSkinnable* const skinnable) +float LevelingSensorSkinlet::innerRadius(const QskSkinnable* const skinnable) { const auto scale = skinnable->strutSizeHint(Q::Horizon); - return radius2(skinnable) * scale.width(); + return outerRadius(skinnable) * scale.width(); } QPointF LevelingSensorSkinlet::center(const QskSkinnable* const skinnable) @@ -72,7 +71,7 @@ template<> Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, const QRectF& contentsRect) const { - const auto radius = radius2(sensor); + const auto radius = outerRadius(sensor); const auto scale = sensor->strutSizeHint(Q::OuterDisk); const auto width = 2 * radius * scale.width(); const auto height = width; @@ -86,7 +85,7 @@ Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const const QRectF& contentsRect) const { const auto scale = sensor->strutSizeHint(Q::Horizon); - const auto width = 2 * radius1(sensor) * scale.width(); + const auto width = 2 * innerRadius(sensor) * scale.width(); const auto height = width; return { center(sensor).x() - width / 2, @@ -132,7 +131,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor auto* const root = ensure>::node(node); auto* const bNode = static_cast(root->firstChild()); - const auto size = radius2(sensor) * sensor->strutSizeHint(Q::OuterDisk).width(); + const auto size = outerRadius(sensor) * sensor->strutSizeHint(Q::OuterDisk).width(); updateBoxNode(sensor, bNode, { 0, 0, 2 * size, 2 * size }, boxShapeMetrics, boxBorderMetrics, boxBorderColors, boxGradient); const auto cX = center(sensor).x(); @@ -153,7 +152,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::Horizon; - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto cX = center(sensor).x(); const auto cY = center(sensor).y(); const auto rX = sensor->rotation().x(); @@ -203,7 +202,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso const auto rY = sensor->rotation().y(); const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto r3 = r1 * scale.height(); const auto sX = r1 / sensor->angle().x(); @@ -236,7 +235,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso const auto color = sensor->color(subControl); const auto scale = sensor->strutSizeHint(subControl); - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto r3 = r1 * scale.width(); const auto rX = 0.00; @@ -278,8 +277,8 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso const auto color = sensor->color(subControl); const auto scale = sensor->strutSizeHint(subControl); - const auto r1 = radius1(sensor); - const auto r2 = radius2(sensor); + const auto r1 = innerRadius(sensor); + const auto r2 = outerRadius(sensor); const auto r3 = qvariant_cast(sensor->effectiveSkinHint(subControl)) * (r2 - r1) + QVector3D{r1, r1, r1}; auto* const transform = ensure>::node(node); @@ -302,7 +301,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin { const auto subControl = Q::TickmarksXLabels; - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksX).height()); const auto sX = r1 / sensor->angle().x(); const auto sY = r1 / sensor->angle().y(); @@ -326,7 +325,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksYLabels; - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksY).width()); const auto cX = static_cast(center(sensor).x()); const auto cY = static_cast(center(sensor).y()); @@ -348,7 +347,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin const auto subControl = Q::TickmarksZLabels; auto* const tNode = ensure>::node(node); auto* const lNode = static_cast(tNode->firstChild()); - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); const auto r3 = static_cast(r1 * sensor->strutSizeHint(subControl).width()); const auto cX = static_cast(center(sensor).x()); const auto cY = static_cast(center(sensor).y()); @@ -364,7 +363,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSens { const auto cX = center(sensor).x(); const auto cY = center(sensor).y(); - const auto r1 = radius1(sensor); + const auto r1 = innerRadius(sensor); auto* const clipNode = ensure::node(node); clipNode->setGeometryProperties(r1, cX, cY); diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h index 5b2db976..0deb2b8e 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h @@ -31,11 +31,8 @@ public: Q_INVOKABLE LevelingSensorSkinlet(QskSkin* skin = nullptr); ~LevelingSensorSkinlet() override = default; - /// @returns Returns the inner radius of the @p skinnable - static Q_REQUIRED_RESULT float radius2(const QskSkinnable* const skinnable); - /// @returns Returns the outer radius of the @p skinnable - static Q_REQUIRED_RESULT float radius1(const QskSkinnable* const skinnable); - /// @returns Returns the center point of the control + static Q_REQUIRED_RESULT float outerRadius(const QskSkinnable* const skinnable); + static Q_REQUIRED_RESULT float innerRadius(const QskSkinnable* const skinnable); static Q_REQUIRED_RESULT QPointF center(const QskSkinnable* const skinnable); protected: From 0f452813ff6b730251e3e23ae6728dd234dc7cae Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 11:14:43 +0200 Subject: [PATCH 09/42] rename QskLevelingSensor class --- .../LevelingSensor/QskLevelingSensor.cpp | 40 ++++++++-------- .../LevelingSensor/QskLevelingSensor.h | 4 +- .../QskLevelingSensorSkinlet.cpp | 46 +++++++++---------- .../LevelingSensor/QskLevelingSensorSkinlet.h | 12 ++--- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/LevelingSensor/QskLevelingSensor.cpp index cfe28825..a04b84af 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensor.cpp @@ -31,23 +31,23 @@ namespace } } -QSK_SUBCONTROL(LevelingSensor, OuterDisk) -QSK_SUBCONTROL(LevelingSensor, Horizon) -QSK_SUBCONTROL(LevelingSensor, TickmarksX) -QSK_SUBCONTROL(LevelingSensor, TickmarksXLabels) -QSK_SUBCONTROL(LevelingSensor, TickmarksY) -QSK_SUBCONTROL(LevelingSensor, TickmarksYLabels) -QSK_SUBCONTROL(LevelingSensor, TickmarksZ) -QSK_SUBCONTROL(LevelingSensor, TickmarksZLabels) +QSK_SUBCONTROL(QskLevelingSensor, OuterDisk) +QSK_SUBCONTROL(QskLevelingSensor, Horizon) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksX) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksXLabels) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksY) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksYLabels) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksZ) +QSK_SUBCONTROL(QskLevelingSensor, TickmarksZLabels) #define RETURN_IF_FALSE(expr) if(!(expr)) return; -LevelingSensor::LevelingSensor(QQuickItem* const parent) +QskLevelingSensor::QskLevelingSensor(QQuickItem* const parent) : Inherited(parent) { } -void LevelingSensor::setRotation(const QVector3D& degree) +void QskLevelingSensor::setRotation(const QVector3D& degree) { if (m_rotation != degree) { @@ -57,7 +57,7 @@ void LevelingSensor::setRotation(const QVector3D& degree) } } -void LevelingSensor::setRotation(const Qt::Axis axis, const float degree) +void QskLevelingSensor::setRotation(const Qt::Axis axis, const float degree) { RETURN_IF_FALSE(isAxis(axis)); @@ -74,7 +74,7 @@ void LevelingSensor::setRotation(const Qt::Axis axis, const float degree) } } -void LevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmarks) +void QskLevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmarks) { RETURN_IF_FALSE(isAxis(axis)); @@ -82,7 +82,7 @@ void LevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmar update(); } -void LevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels labels) +void QskLevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels labels) { RETURN_IF_FALSE(isAxis(axis)); @@ -90,7 +90,7 @@ void LevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels lab update(); } -void LevelingSensor::setAngle(const QVector3D& degree) +void QskLevelingSensor::setAngle(const QVector3D& degree) { if (compareExchange(m_angle, degree)) { @@ -99,7 +99,7 @@ void LevelingSensor::setAngle(const QVector3D& degree) } } -void LevelingSensor::setAngle(const Qt::Axis axis, const float degree) +void QskLevelingSensor::setAngle(const Qt::Axis axis, const float degree) { RETURN_IF_FALSE(isAxis(axis)); @@ -110,7 +110,7 @@ void LevelingSensor::setAngle(const Qt::Axis axis, const float degree) } } -const QskScaleTickmarks& LevelingSensor::tickmarks(Qt::Axis axis) const +const QskScaleTickmarks& QskLevelingSensor::tickmarks(Qt::Axis axis) const { if (isAxis(axis)) { @@ -120,22 +120,22 @@ const QskScaleTickmarks& LevelingSensor::tickmarks(Qt::Axis axis) const return invalid; } -const LevelingSensor::TickmarksLabels& LevelingSensor::tickmarkLabels(Qt::Axis axis) const +const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels(Qt::Axis axis) const { if (isAxis(axis)) { return m_tickmarksLabels[axis]; } - static const LevelingSensor::TickmarksLabels invalid; + static const QskLevelingSensor::TickmarksLabels invalid; return invalid; } -const QVector3D& LevelingSensor::angle() const noexcept +const QVector3D& QskLevelingSensor::angle() const noexcept { return m_angle; } -const QVector3D& LevelingSensor::rotation() const noexcept +const QVector3D& QskLevelingSensor::rotation() const noexcept { return m_rotation; } diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h index b27229bc..2b514246 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.h +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -5,7 +5,7 @@ #include #include -class QSK_EXPORT LevelingSensor : public QskControl +class QSK_EXPORT QskLevelingSensor : public QskControl { Q_OBJECT using Inherited = QskControl; @@ -21,7 +21,7 @@ public: TickmarksZLabels) using Tickmarks = QskScaleTickmarks; using TickmarksLabels = QVector>; - explicit LevelingSensor(QQuickItem* parent = nullptr); + explicit QskLevelingSensor(QQuickItem* parent = nullptr); public Q_SLOTS: void setRotation(const QVector3D& degree); void setRotation(Qt::Axis axis, float degree); diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 6328be43..5e70632f 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -24,31 +24,31 @@ #include #include -using Q = LevelingSensor; -using R = LevelingSensorSkinlet::NodeRole; +using Q = QskLevelingSensor; +using R = QskLevelingSensorSkinlet::NodeRole; using namespace QskSGNode; -float LevelingSensorSkinlet::outerRadius(const QskSkinnable* const skinnable) +float QskLevelingSensorSkinlet::outerRadius(const QskSkinnable* const skinnable) { const auto* const sensor = static_cast(skinnable); const auto contentsRect = sensor->contentsRect(); return 0.5f * qMin(contentsRect.width(), contentsRect.height()); } -float LevelingSensorSkinlet::innerRadius(const QskSkinnable* const skinnable) +float QskLevelingSensorSkinlet::innerRadius(const QskSkinnable* const skinnable) { const auto scale = skinnable->strutSizeHint(Q::Horizon); return outerRadius(skinnable) * scale.width(); } -QPointF LevelingSensorSkinlet::center(const QskSkinnable* const skinnable) +QPointF QskLevelingSensorSkinlet::center(const QskSkinnable* const skinnable) { const auto* const sensor = static_cast(skinnable); return sensor->contentsRect().center(); } -LevelingSensorSkinlet::LevelingSensorSkinlet(QskSkin* skin) +QskLevelingSensorSkinlet::QskLevelingSensorSkinlet(QskSkin* skin) : Inherited(skin) { setNodeRoles({ @@ -63,12 +63,12 @@ LevelingSensorSkinlet::LevelingSensorSkinlet(QskSkin* skin) TickmarksZLabels, }); } -template -Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, +template +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, const QRectF& contentsRect) const = delete; template<> -Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, const QRectF& contentsRect) const { const auto radius = outerRadius(sensor); @@ -81,7 +81,7 @@ Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(con } template<> -Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const LevelingSensor* const sensor, +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, const QRectF& contentsRect) const { const auto scale = sensor->strutSizeHint(Q::Horizon); @@ -95,7 +95,7 @@ Q_REQUIRED_RESULT QRectF LevelingSensorSkinlet::subControlRect(const }; } -QRectF LevelingSensorSkinlet::subControlRect(const QskSkinnable* skinnable, +QRectF QskLevelingSensorSkinlet::subControlRect(const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl) const { const auto* const sensor = static_cast(skinnable); @@ -112,12 +112,12 @@ QRectF LevelingSensorSkinlet::subControlRect(const QskSkinnable* skinnable, return Inherited::subControlRect(skinnable, contentsRect, subControl); } -template -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +template +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const = delete; template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::OuterDisk; @@ -148,7 +148,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::Horizon; @@ -188,7 +188,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksX; @@ -228,7 +228,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksY; @@ -270,7 +270,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksZ; @@ -296,7 +296,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSenso } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksXLabels; @@ -321,7 +321,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksYLabels; @@ -341,7 +341,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto subControl = Q::TickmarksZLabels; @@ -358,7 +358,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const Levelin } template<> -QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSensor* const sensor, +QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node) const { const auto cX = center(sensor).x(); @@ -370,7 +370,7 @@ QSGNode* LevelingSensorSkinlet::updateSubNode(const LevelingSens return clipNode; } -QSGNode* LevelingSensorSkinlet::updateSubNode( +QSGNode* QskLevelingSensorSkinlet::updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node) const { const auto* const sensor = static_cast(skinnable); diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h index 0deb2b8e..625f31f4 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h @@ -3,9 +3,9 @@ #include #include -class LevelingSensor; +class QskLevelingSensor; -class QSK_EXPORT LevelingSensorSkinlet : public QskSkinlet +class QSK_EXPORT QskLevelingSensorSkinlet : public QskSkinlet { Q_GADGET @@ -28,8 +28,8 @@ public: RoleCount }; - Q_INVOKABLE LevelingSensorSkinlet(QskSkin* skin = nullptr); - ~LevelingSensorSkinlet() override = default; + Q_INVOKABLE QskLevelingSensorSkinlet(QskSkin* skin = nullptr); + ~QskLevelingSensorSkinlet() override = default; static Q_REQUIRED_RESULT float outerRadius(const QskSkinnable* const skinnable); static Q_REQUIRED_RESULT float innerRadius(const QskSkinnable* const skinnable); @@ -44,10 +44,10 @@ protected: quint8 nodeRole, QSGNode* node) const override; template - Q_REQUIRED_RESULT QRectF subControlRect(const LevelingSensor* sensor, + Q_REQUIRED_RESULT QRectF subControlRect(const QskLevelingSensor* sensor, const QRectF& contentsRect) const; template - Q_REQUIRED_RESULT QSGNode* updateSubNode(const LevelingSensor* sensor, + Q_REQUIRED_RESULT QSGNode* updateSubNode(const QskLevelingSensor* sensor, quint8 nodeRole, QSGNode* node) const; }; From 87b304e0c51986305a0b7e173526d06509e5682a Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 17 Jul 2023 12:50:36 +0200 Subject: [PATCH 10/42] added leveling sensor playground --- playground/CMakeLists.txt | 1 + playground/levelingsensor/CMakeLists.txt | 11 ++ playground/levelingsensor/Dashboard.cpp | 125 ++++++++++++++++ playground/levelingsensor/MainWindow.h | 16 +++ playground/levelingsensor/SkinFactory.cpp | 168 ++++++++++++++++++++++ playground/levelingsensor/SkinFactory.h | 17 +++ playground/levelingsensor/main.cpp | 159 ++++++++++++++++++++ 7 files changed, 497 insertions(+) create mode 100644 playground/levelingsensor/CMakeLists.txt create mode 100644 playground/levelingsensor/Dashboard.cpp create mode 100644 playground/levelingsensor/MainWindow.h create mode 100644 playground/levelingsensor/SkinFactory.cpp create mode 100644 playground/levelingsensor/SkinFactory.h create mode 100644 playground/levelingsensor/main.cpp diff --git a/playground/CMakeLists.txt b/playground/CMakeLists.txt index 7fc3449a..3b997bf1 100644 --- a/playground/CMakeLists.txt +++ b/playground/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(invoker) add_subdirectory(shadows) add_subdirectory(shapes) add_subdirectory(charts) +add_subdirectory(levelingsensor) if (BUILD_INPUTCONTEXT) add_subdirectory(inputpanel) diff --git a/playground/levelingsensor/CMakeLists.txt b/playground/levelingsensor/CMakeLists.txt new file mode 100644 index 00000000..b397f548 --- /dev/null +++ b/playground/levelingsensor/CMakeLists.txt @@ -0,0 +1,11 @@ +############################################################################ +# QSkinny - Copyright (C) 2016 Uwe Rathmann +# SPDX-License-Identifier: BSD-3-Clause +############################################################################ + +set(SOURCES + SkinFactory.h SkinFactory.cpp + main.cpp +) + +qsk_add_example(levelingsensor ${SOURCES}) diff --git a/playground/levelingsensor/Dashboard.cpp b/playground/levelingsensor/Dashboard.cpp new file mode 100644 index 00000000..5d960dff --- /dev/null +++ b/playground/levelingsensor/Dashboard.cpp @@ -0,0 +1,125 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include + +#include + +namespace +{ + class DashboardDial : public Dial + { + public: + DashboardDial( const QString& title, QQuickItem* parent = nullptr ) + : Dial( parent ) + { + setPolishOnResize( true ); + m_label = new QskTextLabel( title, this ); + } + + protected: + void updateLayout() override + { + const auto r = layoutRect(); + + const auto hint = m_label->sizeConstraint(); + + const qreal y = r.y() + 0.6 * r.height() - 0.5 * hint.height(); + const qreal x = r.center().x() - 0.5 * hint.width(); + + m_label->setGeometry( x, y, hint.width(), hint.height() ); + } + + private: + QskTextLabel* m_label; + }; + + class RevCounter : public DashboardDial + { + public: + RevCounter( QQuickItem* parent = nullptr ) + : DashboardDial( "x 1000 min^-1", parent ) + { + setMinimum( 145 ); + setMaximum( 305 ); + setValue( 200 ); + + constexpr int labelsCount = 8; + + QVector< QString > labels; + labels.reserve( labelsCount ); + + for ( int i = 0; i < labelsCount; i++ ) + labels += QString::number( i ); + + setTickLabels( labels ); + } + }; + + class SpeedoMeter : public DashboardDial + { + public: + SpeedoMeter( QQuickItem* parent = nullptr ) + : DashboardDial( "km/h", parent ) + { + setMinimum( -215 ); + setMaximum( 35 ); + setValue( -90 ); + + constexpr int labelsCount = 17; + + QVector< QString > labels; + labels.reserve( labelsCount ); + + for ( int i = 0; i < labelsCount; i++ ) + labels.append( QString::number( i * 10 ) ); + + setTickLabels( labels ); + } + + void updateValue() + { + setValue( value() + std::rand() % 3 - 0.95 ); + } + }; + + class FuelGauge : public DashboardDial + { + public: + FuelGauge( QQuickItem* parent = nullptr ) + : DashboardDial( "fuel", parent ) + { + setMinimum( 195 ); + setMaximum( 345 ); + setValue( 330 ); + + setTickLabels( { "0", "", "1/2", "", "1/1" } ); + } + + void updateValue() + { + setValue( 0.99997 * value() ); + } + }; +} + +Dashboard::Dashboard( QQuickItem* parent ) + : QskLinearBox( Qt::Horizontal, parent ) +{ + (void ) new RevCounter( this ); + auto speedometer = new SpeedoMeter( this ); + auto fuelGauge = new FuelGauge( this ); + + setMargins( 10 ); + setSpacing( 10 ); + + auto timer = new QTimer( this ); + + connect( timer, &QTimer::timeout, speedometer, &SpeedoMeter::updateValue ); + connect( timer, &QTimer::timeout, fuelGauge, &FuelGauge::updateValue ); + + timer->setInterval( 16 ); + timer->start(); +} diff --git a/playground/levelingsensor/MainWindow.h b/playground/levelingsensor/MainWindow.h new file mode 100644 index 00000000..f45b6733 --- /dev/null +++ b/playground/levelingsensor/MainWindow.h @@ -0,0 +1,16 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#pragma once + +#include + +class QQuickItem; + +class MainWindow : public QskWindow +{ + public: + MainWindow(); +}; diff --git a/playground/levelingsensor/SkinFactory.cpp b/playground/levelingsensor/SkinFactory.cpp new file mode 100644 index 00000000..894574f6 --- /dev/null +++ b/playground/levelingsensor/SkinFactory.cpp @@ -0,0 +1,168 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include "SkinFactory.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +namespace +{ + class Skin : public QskSkin + { + template< typename T > + void style( QskSkinHintTableEditor& editor ); + + template< typename Skinnable, typename Skinlet > + void declareSkinlet( ) + { + QskSkin::declareSkinlet< Skinnable, Skinlet >(); + } + + template< typename Skinnable, typename Skinlet > + void declareSkinlet( QskSkinHintTableEditor& editor ) + { + QskSkin::declareSkinlet< Skinnable, Skinlet >(); + style< Skinnable >( editor ); + } + + template<> + void style< QskSlider >( QskSkinHintTableEditor& editor ) + { + using A = QskAspect; + using Q = QskSlider; + + const qreal extent = 40; + + // Panel + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + const auto aspect = Q::Panel | variation; + + editor.setMetric( aspect | A::Size, extent ); + editor.setBoxBorderMetrics( aspect, 0 ); + editor.setBoxShape( aspect, 0 ); + editor.setGradient( aspect, QskGradient() ); + } + + // Groove, Fill + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + for ( auto subControl : { Q::Groove, Q::Fill } ) + { + const auto aspect = subControl | variation; + + editor.setMetric( aspect | A::Size, 0.3 * extent ); + + editor.setBoxBorderMetrics( aspect, 0 ); + editor.setBoxShape( aspect, 0.1 * extent ); + } + + editor.setGradient( Q::Groove | variation, Qt::lightGray ); + editor.setGradient( Q::Fill | variation, Qt::darkGray ); + } + + // Handle + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + const auto aspect = Q::Handle | variation; + editor.setColor( aspect, Qt::black ); + + editor.setBoxShape( aspect, 20.0, Qt::RelativeSize ); + + const qreal sz = 0.75 * extent; + editor.setStrutSize( aspect, sz, sz ); + } + } + + template<> + void style< QskLevelingSensor >( QskSkinHintTableEditor& ed ) + { + using Q = QskLevelingSensor; + + static constexpr auto r1 = 0.9; + static constexpr auto r2 = 1.0; + + QskGradient gradient{ { + { 0.5, Qt::lightGray }, + { 0.5, Qt::lightGray }, + { 0.5, Qt::darkGray }, + { 1.0, Qt::darkGray }, + } }; + gradient.setLinearDirection( Qt::Vertical ); + + ed.setColor( Q::Background, "dimgray" ); + + ed.setStrutSize( Q::OuterDisk, { r2, r2 } ); + ed.setColor( Q::OuterDisk, Qt::white ); + + ed.setGradient( Q::Horizon, gradient ); + ed.setStrutSize( Q::Horizon, { r1, r1 } ); + + ed.setColor( Q::TickmarksX, Qt::black ); + ed.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % + ed.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % + + ed.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % + ed.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); + + ed.setColor( Q::TickmarksY, Qt::black ); + ed.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % + ed.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % + + ed.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % + ed.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); + + ed.setColor( Q::TickmarksZ, "silver" ); + ed.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } ); + ed.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // % + + ed.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 % + ed.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter ); + } + + public: + Skin() + { + QskSkinHintTableEditor editor( &hintTable() ); + declareSkinlet< QskSlider, QskSliderSkinlet >( editor ); + declareSkinlet< QskTextLabel, QskTextLabelSkinlet >(); + declareSkinlet< QskLevelingSensor, QskLevelingSensorSkinlet >( editor ); + } + }; +} + +QStringList SkinFactory::skinNames() const +{ + return { "Skin" }; +} + +QskSkin* SkinFactory::createSkin( const QString& skinName ) +{ + if ( skinName == "Skin" ) + return new Skin(); + + return nullptr; +} + +#include "moc_SkinFactory.cpp" diff --git a/playground/levelingsensor/SkinFactory.h b/playground/levelingsensor/SkinFactory.h new file mode 100644 index 00000000..6bb0f2fa --- /dev/null +++ b/playground/levelingsensor/SkinFactory.h @@ -0,0 +1,17 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#pragma once + +#include + +class SkinFactory : public QskSkinFactory +{ + Q_OBJECT + + public: + QStringList skinNames() const override; + QskSkin* createSkin( const QString& ) override; +}; diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp new file mode 100644 index 00000000..694b1c40 --- /dev/null +++ b/playground/levelingsensor/main.cpp @@ -0,0 +1,159 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include "SkinFactory.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace +{ + void updateTickmarks( const Qt::Axis axis, const QskIntervalF& intervalA, + const QskIntervalF& intervalB, QskLevelingSensor* const sensor ) + { + QskScaleTickmarks tickmarks; + QVector< qreal > major; + QVector< qreal > medium; + QVector< qreal > minor; + + for ( const auto& interval : { intervalA, intervalB } ) + { + for ( int deg = ( int ) interval.lowerBound(); deg < ( int ) interval.upperBound(); + ++deg ) + { + if ( deg % 45 == 0 ) + { + major << deg; + } + if ( deg % 45 != 0 && deg % 5 == 0 ) + { + medium << deg; + } + if ( deg % 45 != 0 && deg % 5 != 0 ) + { + minor << deg; + } + } + } + + tickmarks.setMajorTicks( major ); + tickmarks.setMediumTicks( medium ); + tickmarks.setMinorTicks( minor ); + sensor->setTickmarks( axis, tickmarks ); + } + + void updateTickmarksLabels( const Qt::Axis axis, const QskIntervalF& intervalA, + const QskIntervalF& intervalB, int step, QskLevelingSensor* const sensor ) + { + QskLevelingSensor::TickmarksLabels labels; + for ( const auto& interval : { intervalA, intervalB } ) + { + for ( int deg = ( ( int ) interval.lowerBound() / step ) * step; + deg < ( int ) interval.upperBound(); deg += step ) + { + labels << QskLevelingSensor::TickmarksLabels::value_type{ ( float ) deg, + QString( deg > 0 ? "+" : "" ) + QString::number( deg ) }; + } + } + sensor->setTickmarksLabels( axis, labels ); + } + + Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis, QskLevelingSensor* const sensor, int min, int max, std::function intervalA, std::function intervalB, QQuickItem* const parent = nullptr ) + { + auto* const slider = new QskSlider( Qt::Horizontal, parent ); + slider->setMinimum( min ); + slider->setMaximum( max ); + + QObject::connect(slider, &QskSlider::valueChanged, sensor, [ = ]( const qreal degree ) { + updateTickmarks( axis, intervalA(degree), intervalB(degree), sensor ); + updateTickmarksLabels( axis, intervalA( degree ), intervalB( degree ), 10, sensor ); + } ); + + return slider; + } + + Q_REQUIRED_RESULT QskSlider* makeRotationSlider( + const Qt::Axis axis, QskLevelingSensor* const sensor, QQuickItem* const parent = nullptr ) + { + auto* const slider = new QskSlider( Qt::Horizontal, parent ); + slider->setMinimum( -360 ); + slider->setMaximum( +360 ); + + QObject::connect( sensor, &QskLevelingSensor::rotationChanged, slider, + [ slider, axis ]( const QVector3D& degree ) { slider->setValue( degree[ axis ] ); } ); + + QObject::connect( slider, &QskSlider::valueChanged, sensor, + [ sensor, axis ]( const qreal degree ) { sensor->setRotation( axis, degree ); } ); + + return slider; + } + + class Window : public QskWindow + { + public: + Window() + { + auto* const root = new QskLinearBox( Qt::Horizontal, contentItem() ); + auto* const left = new QskLinearBox( Qt::Vertical, root ); + auto* const right = new QskLinearBox( Qt::Vertical, root ); + auto* const sensor = new QskLevelingSensor( left ); + + auto linearIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};}; + auto linearIntervalB = [](const qreal degree)->QskIntervalF{ return {}; }; + + auto radialIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};}; + auto radialIntervalB = [](const qreal degree)->QskIntervalF{ return {180-degree, 180+degree};}; + + ( void ) new QskTextLabel( "Tickmarks X", right ); + auto* const sliderTickmarksX = makeTickmarksSlider( Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); + ( void ) new QskTextLabel( "Tickmarks Y", right ); + auto* const sliderTickmarksY = makeTickmarksSlider( Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); + ( void ) new QskTextLabel( "Tickmarks Z", right ); + auto* const sliderTickmarksZ = makeTickmarksSlider( Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right ); + + ( void ) new QskTextLabel( "Rotation X", right ); + ( void ) makeRotationSlider( Qt::XAxis, sensor, right ); + ( void ) new QskTextLabel( "Rotation Y", right ); + ( void ) makeRotationSlider( Qt::YAxis, sensor, right ); + ( void ) new QskTextLabel( "Rotation Z", right ); + ( void ) makeRotationSlider( Qt::ZAxis, sensor, right ); + + sliderTickmarksX->setValue(15); + sliderTickmarksY->setValue(15); + sliderTickmarksZ->setValue(30); + } + }; +} + +int main( int argc, char** argv ) +{ +#ifdef ITEM_STATISTICS + QskObjectCounter counter( true ); +#endif + + qskSkinManager->setPluginPaths( QStringList() ); // no skin plugins + qskSkinManager->registerFactory( QStringLiteral( "sample" ), new SkinFactory() ); + + QGuiApplication app( argc, argv ); + + SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); + + Window window; + window.showMaximized(); + + return app.exec(); +} From 77c39cdd05e422705945849f76055e0d9f3ed29a Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 20 Jul 2023 12:01:16 +0200 Subject: [PATCH 11/42] add rotation per subcontrol --- playground/levelingsensor/SkinFactory.cpp | 44 +- playground/levelingsensor/main.cpp | 37 +- .../LevelingSensor/QskLevelingSensor.cpp | 74 +-- .../LevelingSensor/QskLevelingSensor.h | 21 +- .../QskLevelingSensorSkinlet.cpp | 525 ++++++++++-------- 5 files changed, 405 insertions(+), 296 deletions(-) diff --git a/playground/levelingsensor/SkinFactory.cpp b/playground/levelingsensor/SkinFactory.cpp index 894574f6..12fb02f4 100644 --- a/playground/levelingsensor/SkinFactory.cpp +++ b/playground/levelingsensor/SkinFactory.cpp @@ -96,7 +96,7 @@ namespace } template<> - void style< QskLevelingSensor >( QskSkinHintTableEditor& ed ) + void style< QskLevelingSensor >( QskSkinHintTableEditor& editor ) { using Q = QskLevelingSensor; @@ -111,34 +111,36 @@ namespace } }; gradient.setLinearDirection( Qt::Vertical ); - ed.setColor( Q::Background, "dimgray" ); + editor.setColor( Q::Background, "dimgray" ); - ed.setStrutSize( Q::OuterDisk, { r2, r2 } ); - ed.setColor( Q::OuterDisk, Qt::white ); + editor.setStrutSize( Q::OuterDisk, { r2, r2 } ); + editor.setColor( Q::OuterDisk, Qt::white ); - ed.setGradient( Q::Horizon, gradient ); - ed.setStrutSize( Q::Horizon, { r1, r1 } ); + editor.setGradient( Q::Horizon, gradient ); + editor.setStrutSize( Q::Horizon, { r1, r1 } ); - ed.setColor( Q::TickmarksX, Qt::black ); - ed.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % - ed.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % + editor.setColor( Q::TickmarksX, Qt::black ); + editor.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % + editor.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % + editor.setAlignment(Q::TickmarksX, Qt::AlignCenter); - ed.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % - ed.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); + editor.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % + editor.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); - ed.setColor( Q::TickmarksY, Qt::black ); - ed.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % - ed.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % + editor.setColor( Q::TickmarksY, Qt::black ); + editor.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % + editor.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % + editor.setAlignment(Q::TickmarksY, Qt::AlignCenter); - ed.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % - ed.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); + editor.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % + editor.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); - ed.setColor( Q::TickmarksZ, "silver" ); - ed.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } ); - ed.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // % + editor.setColor( Q::TickmarksZ, "silver" ); + editor.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } ); + editor.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // % - ed.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 % - ed.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter ); + editor.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 % + editor.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter ); } public: diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index 694b1c40..ab93ceb3 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -87,17 +87,26 @@ namespace } Q_REQUIRED_RESULT QskSlider* makeRotationSlider( - const Qt::Axis axis, QskLevelingSensor* const sensor, QQuickItem* const parent = nullptr ) + const Qt::Axis axis, QskLevelingSensor* const sensor, const QskAspect::Subcontrol subControl, QQuickItem* const parent = nullptr ) { auto* const slider = new QskSlider( Qt::Horizontal, parent ); slider->setMinimum( -360 ); slider->setMaximum( +360 ); - QObject::connect( sensor, &QskLevelingSensor::rotationChanged, slider, - [ slider, axis ]( const QVector3D& degree ) { slider->setValue( degree[ axis ] ); } ); + QObject::connect( sensor, &QskLevelingSensor::subControlRotationChanged, slider, + [ = ]( const QskAspect::Subcontrol control, const QVector3D& degree ) { + if(control == subControl) + { + slider->setValue( degree[ axis ] ); + } + } ); QObject::connect( slider, &QskSlider::valueChanged, sensor, - [ sensor, axis ]( const qreal degree ) { sensor->setRotation( axis, degree ); } ); + [ = ]( const qreal degree ) { + auto d = sensor->subControlRotation( subControl ); + d[ axis ] = degree; + sensor->setSubControlRotation( subControl, d ); + } ); return slider; } @@ -108,6 +117,8 @@ namespace Window() { auto* const root = new QskLinearBox( Qt::Horizontal, contentItem() ); + root->setSpacing(8); + root->setMargins(8); auto* const left = new QskLinearBox( Qt::Vertical, root ); auto* const right = new QskLinearBox( Qt::Vertical, root ); auto* const sensor = new QskLevelingSensor( left ); @@ -125,12 +136,18 @@ namespace ( void ) new QskTextLabel( "Tickmarks Z", right ); auto* const sliderTickmarksZ = makeTickmarksSlider( Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right ); - ( void ) new QskTextLabel( "Rotation X", right ); - ( void ) makeRotationSlider( Qt::XAxis, sensor, right ); - ( void ) new QskTextLabel( "Rotation Y", right ); - ( void ) makeRotationSlider( Qt::YAxis, sensor, right ); - ( void ) new QskTextLabel( "Rotation Z", right ); - ( void ) makeRotationSlider( Qt::ZAxis, sensor, right ); + ( void ) new QskTextLabel( "Rotation X Plane", right ); + ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksX, right ); + ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksX, right ); + ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksX, right ); + ( void ) new QskTextLabel( "Rotation Y Plane", right ); + ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksY, right ); + ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksY, right ); + ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksY, right ); + ( void ) new QskTextLabel( "Rotation Z Plane", right ); + ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksZ, right ); + ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksZ, right ); + ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksZ, right ); sliderTickmarksX->setValue(15); sliderTickmarksY->setValue(15); diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/LevelingSensor/QskLevelingSensor.cpp index a04b84af..6295f651 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensor.cpp @@ -42,50 +42,23 @@ QSK_SUBCONTROL(QskLevelingSensor, TickmarksZLabels) #define RETURN_IF_FALSE(expr) if(!(expr)) return; +using Q = QskLevelingSensor; + QskLevelingSensor::QskLevelingSensor(QQuickItem* const parent) : Inherited(parent) { } -void QskLevelingSensor::setRotation(const QVector3D& degree) -{ - if (m_rotation != degree) - { - setRotation(Qt::XAxis, degree.x()); - setRotation(Qt::YAxis, degree.y()); - setRotation(Qt::ZAxis, degree.z()); - } -} - -void QskLevelingSensor::setRotation(const Qt::Axis axis, const float degree) -{ - RETURN_IF_FALSE(isAxis(axis)); - - if (compareExchange(m_rotation[axis], degree)) - { - update(); - switch(axis) - { - case Qt::XAxis: Q_EMIT rotationXChanged(m_rotation[axis]); break; - case Qt::YAxis: Q_EMIT rotationYChanged(m_rotation[axis]); break; - case Qt::ZAxis: Q_EMIT rotationZChanged(m_rotation[axis]); break; - } - Q_EMIT rotationChanged(m_rotation); - } -} - void QskLevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmarks) { RETURN_IF_FALSE(isAxis(axis)); - m_tickmarks[axis] = std::move(tickmarks); update(); } void QskLevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels labels) { - RETURN_IF_FALSE(isAxis(axis)); - + RETURN_IF_FALSE(isAxis(axis)); m_tickmarksLabels[axis] = std::move(labels); update(); } @@ -135,9 +108,46 @@ const QVector3D& QskLevelingSensor::angle() const noexcept return m_angle; } -const QVector3D& QskLevelingSensor::rotation() const noexcept +const QVector3D& QskLevelingSensor::subControlRotation(const QskAspect::Subcontrol subControl) const noexcept { - return m_rotation; + static const QVector3D notFound; + const auto found = m_subControlRotation.find(subControl); + if(found == m_subControlRotation.end()) { + return notFound; + } + return found->second; +} + +void QskLevelingSensor::setSubControlRotation(const QskAspect::Subcontrol subControl, const QVector3D& degree) +{ + auto updateSubControlRotation = [this](const QskAspect::Subcontrol subControl, const QVector3D& degree) + { + if ( compareExchange( m_subControlRotation[ subControl ], degree ) ) + { + Q_EMIT subControlRotationChanged(subControl, degree); + update(); + } + }; + + if(subControl == Q::TickmarksX || subControl == Q::TickmarksXLabels) + { + updateSubControlRotation(Q::TickmarksX, degree); + updateSubControlRotation(Q::TickmarksXLabels, degree); + } + else if(subControl == Q::TickmarksY || subControl == Q::TickmarksYLabels) + { + updateSubControlRotation(Q::TickmarksY, degree); + updateSubControlRotation(Q::TickmarksYLabels, degree); + } + else if(subControl == Q::TickmarksZ || subControl == TickmarksZLabels) + { + updateSubControlRotation(TickmarksZ, degree); + updateSubControlRotation(TickmarksZLabels, degree); + } + else + { + updateSubControlRotation(subControl, degree); + } } #include "moc_QskLevelingSensor.cpp" \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h index 2b514246..89a05032 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.h +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -5,6 +5,8 @@ #include #include +#include + class QSK_EXPORT QskLevelingSensor : public QskControl { Q_OBJECT @@ -23,26 +25,31 @@ public: using TickmarksLabels = QVector>; explicit QskLevelingSensor(QQuickItem* parent = nullptr); public Q_SLOTS: - void setRotation(const QVector3D& degree); - void setRotation(Qt::Axis axis, float degree); void setTickmarks(Qt::Axis axis, Tickmarks tickmarks); void setTickmarksLabels(Qt::Axis axis, TickmarksLabels labels); void setAngle(const QVector3D& degree); void setAngle(Qt::Axis axis, float degree); + + void setSubControlRotation(QskAspect::Subcontrol subControl, const QVector3D& degree); + Q_SIGNALS: - void rotationXChanged(qreal degree); - void rotationYChanged(qreal degree); - void rotationZChanged(qreal degree); - void rotationChanged(const QVector3D& degree); void anglesChanged(const QVector3D& degree); + void subControlRotationChanged(QskAspect::Subcontrol subControl, const QVector3D& degree); + public: - Q_REQUIRED_RESULT const QVector3D& rotation() const noexcept; Q_REQUIRED_RESULT const Tickmarks& tickmarks(Qt::Axis axis) const; Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels(Qt::Axis axis) const; Q_REQUIRED_RESULT const QVector3D& angle() const noexcept; + Q_REQUIRED_RESULT const QVector3D& subControlRotation(QskAspect::Subcontrol subControl) const noexcept; + private: + + // TODO use pimpl + QVector3D m_rotation; QVector3D m_angle = { 45,45,45 }; Tickmarks m_tickmarks[3]; TickmarksLabels m_tickmarksLabels[3]; + + std::unordered_map m_subControlRotation; }; \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 5e70632f..d904e8ba 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -1,7 +1,7 @@ #include "QskLevelingSensorSkinlet.h" #include "QskLevelingSensor.h" -#include "QskLevelingSensorUtility.h" #include "QskLevelingSensorNodes.h" +#include "QskLevelingSensorUtility.h" #include "QskSGNodeUtility.h" #include @@ -24,34 +24,86 @@ #include #include +namespace +{ + template< typename T > + struct State; + + template<> + struct State< QskLevelingSensor > + { + qreal r1 = 0.0; + qreal r2 = 0.0; + qreal cX = 0.0; + qreal cY = 0.0; + qreal sX = 0.0; + qreal sY = 0.0; + qreal sZ = 0.0; + + explicit State( const QskLevelingSensor* const sensor ) + : r1( QskLevelingSensorSkinlet::innerRadius( sensor ) ) + , r2( QskLevelingSensorSkinlet::outerRadius( sensor ) ) + , cX( QskLevelingSensorSkinlet::center( sensor ).x() ) + , cY( QskLevelingSensorSkinlet::center( sensor ).y() ) + , sX( r1 / sensor->angle().x() ) + , sY( r1 / sensor->angle().y() ) + , sZ( r1 / sensor->angle().z() ) + { + } + }; + + template<> + struct State< QskAspect::Subcontrol > : State< QskLevelingSensor > + { + qreal rX = 0.0; + qreal rY = 0.0; + qreal rZ = 0.0; + qreal tX = 0.0; + qreal tY = 0.0; + qreal tZ = 0.0; + + State( const QskLevelingSensor* const sensor, QskAspect::Subcontrol subcontrol ) + : State< QskLevelingSensor >( sensor ) + , rX( sensor->subControlRotation( subcontrol ).x() ) + , rY( sensor->subControlRotation( subcontrol ).y() ) + , rZ( sensor->subControlRotation( subcontrol ).z() ) + , tX( rY * sX ) + , tY( rX * sY ) + , tZ( 0.0 ) + { + } + }; + +} + using Q = QskLevelingSensor; using R = QskLevelingSensorSkinlet::NodeRole; using namespace QskSGNode; -float QskLevelingSensorSkinlet::outerRadius(const QskSkinnable* const skinnable) +float QskLevelingSensorSkinlet::outerRadius( const QskSkinnable* const skinnable ) { - const auto* const sensor = static_cast(skinnable); + const auto* const sensor = static_cast< const Q* >( skinnable ); const auto contentsRect = sensor->contentsRect(); - return 0.5f * qMin(contentsRect.width(), contentsRect.height()); + return 0.5f * qMin( contentsRect.width(), contentsRect.height() ); } -float QskLevelingSensorSkinlet::innerRadius(const QskSkinnable* const skinnable) +float QskLevelingSensorSkinlet::innerRadius( const QskSkinnable* const skinnable ) { - const auto scale = skinnable->strutSizeHint(Q::Horizon); - return outerRadius(skinnable) * scale.width(); + const auto scale = skinnable->strutSizeHint( Q::Horizon ); + return outerRadius( skinnable ) * scale.width(); } -QPointF QskLevelingSensorSkinlet::center(const QskSkinnable* const skinnable) +QPointF QskLevelingSensorSkinlet::center( const QskSkinnable* const skinnable ) { - const auto* const sensor = static_cast(skinnable); + const auto* const sensor = static_cast< const Q* >( skinnable ); return sensor->contentsRect().center(); } -QskLevelingSensorSkinlet::QskLevelingSensorSkinlet(QskSkin* skin) - : Inherited(skin) +QskLevelingSensorSkinlet::QskLevelingSensorSkinlet( QskSkin* skin ) + : Inherited( skin ) { - setNodeRoles({ + setNodeRoles( { OuterDisk, Horizon, HorizonClip, @@ -60,19 +112,20 @@ QskLevelingSensorSkinlet::QskLevelingSensorSkinlet(QskSkin* skin) TickmarksY, TickmarksYLabels, TickmarksZ, - TickmarksZLabels, }); + TickmarksZLabels, + } ); } -template -Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, - const QRectF& contentsRect) const = delete; +template< QskLevelingSensorSkinlet::NodeRole > +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect( + const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const = delete; template<> -Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, - const QRectF& contentsRect) const +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect< R::OuterDisk >( + const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const { - const auto radius = outerRadius(sensor); - const auto scale = sensor->strutSizeHint(Q::OuterDisk); + const auto radius = outerRadius( sensor ); + const auto scale = sensor->strutSizeHint( Q::OuterDisk ); const auto width = 2 * radius * scale.width(); const auto height = width; const auto x = contentsRect.center().x() - width / 2; @@ -81,333 +134,353 @@ Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect( } template<> -Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect(const QskLevelingSensor* const sensor, - const QRectF& contentsRect) const +Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect< R::Horizon >( + const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const { - const auto scale = sensor->strutSizeHint(Q::Horizon); - const auto width = 2 * innerRadius(sensor) * scale.width(); + const auto scale = sensor->strutSizeHint( Q::Horizon ); + const auto width = 2 * innerRadius( sensor ) * scale.width(); const auto height = width; - return { - center(sensor).x() - width / 2, - center(sensor).y() - height / 2, - width, - height - }; + return { center( sensor ).x() - width / 2, center( sensor ).y() - height / 2, width, height }; } -QRectF QskLevelingSensorSkinlet::subControlRect(const QskSkinnable* skinnable, - const QRectF& contentsRect, QskAspect::Subcontrol subControl) const +QRectF QskLevelingSensorSkinlet::subControlRect( const QskSkinnable* skinnable, + const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { - const auto* const sensor = static_cast(skinnable); + const auto* const sensor = static_cast< const Q* >( skinnable ); - if (subControl == Q::OuterDisk) + if ( subControl == Q::OuterDisk ) { - return subControlRect(sensor, contentsRect); + return subControlRect< OuterDisk >( sensor, contentsRect ); } - if (subControl == Q::Horizon) + if ( subControl == Q::Horizon ) { - return subControlRect(sensor, contentsRect); + return subControlRect< Horizon >( sensor, contentsRect ); } - return Inherited::subControlRect(skinnable, contentsRect, subControl); + return Inherited::subControlRect( skinnable, contentsRect, subControl ); } -template -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const = delete; +template< QskLevelingSensorSkinlet::NodeRole > +QSGNode* QskLevelingSensorSkinlet::updateSubNode( const QskLevelingSensor* const sensor, + const quint8 nodeRole, QSGNode* const node ) const = delete; template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::OuterDisk; const auto contentsRect = sensor->contentsRect(); - const auto boxRect = subControlRect(sensor, contentsRect); + const auto boxRect = subControlRect< OuterDisk >( sensor, contentsRect ); const auto boxShapeMetrics = QskBoxShapeMetrics{ boxRect.width() / 2 }; - const auto boxBorderMetrics = sensor->boxBorderMetricsHint(subControl); - const auto boxBorderColors = sensor->boxBorderColorsHint(subControl); - const auto boxGradient = sensor->gradientHint(subControl); + const auto boxBorderMetrics = sensor->boxBorderMetricsHint( subControl ); + const auto boxBorderColors = sensor->boxBorderColorsHint( subControl ); + const auto boxGradient = sensor->gradientHint( subControl ); - auto* const root = ensure>::node(node); - auto* const bNode = static_cast(root->firstChild()); + auto* const root = ensure< QSGTransformNode, par< 1, QskBoxNode > >::node( node ); + auto* const bNode = static_cast< QskBoxNode* >( root->firstChild() ); - const auto size = outerRadius(sensor) * sensor->strutSizeHint(Q::OuterDisk).width(); - updateBoxNode(sensor, bNode, { 0, 0, 2 * size, 2 * size }, boxShapeMetrics, boxBorderMetrics, boxBorderColors, boxGradient); + const auto size = outerRadius( sensor ) * sensor->strutSizeHint( Q::OuterDisk ).width(); + updateBoxNode( sensor, bNode, { 0, 0, 2 * size, 2 * size }, boxShapeMetrics, boxBorderMetrics, + boxBorderColors, boxGradient ); - const auto cX = center(sensor).x(); - const auto cY = center(sensor).y(); + const auto cX = center( sensor ).x(); + const auto cY = center( sensor ).y(); const auto rZ = 0.0; - const auto matrix = - matrix_deg(0.0, 0.0, 0.0, cX, cY, 0) * - matrix_deg(0.0, 0.0, rZ, 0, 0, 0) * - matrix_deg(0.0, 0.0, 0.0, -size, -size, 0); + const auto matrix = matrix_deg( 0.0, 0.0, 0.0, cX, cY, 0 ) * + matrix_deg( 0.0, 0.0, rZ, 0, 0, 0 ) * + matrix_deg( 0.0, 0.0, 0.0, -size, -size, 0 ); - root->setMatrix(matrix); + root->setMatrix( matrix ); return root; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::Horizon; - const auto r1 = innerRadius(sensor); - const auto cX = center(sensor).x(); - const auto cY = center(sensor).y(); - const auto rX = sensor->rotation().x(); + const auto r1 = innerRadius( sensor ); + const auto cX = center( sensor ).x(); + const auto cY = center( sensor ).y(); + const auto rX = sensor->subControlRotation( subControl ).x(); const auto rZ = 0.0; const auto dY = 2 * sensor->angle().y(); - const auto p = qBound(0.0, 0.5 + (-rX / dY), 1.0); + const auto p = qBound( 0.0, 0.5 + ( -rX / dY ), 1.0 ); const auto shape = QskBoxShapeMetrics{ r1 }; - const auto bmetrics = sensor->boxBorderMetricsHint(subControl); - const auto bcolors = sensor->boxBorderColorsHint(subControl); + const auto bmetrics = sensor->boxBorderMetricsHint( subControl ); + const auto bcolors = sensor->boxBorderColorsHint( subControl ); - auto gradient = sensor->gradientHint(Q::Horizon); - gradient.setDirection(QskGradient::Linear); - gradient.setLinearDirection(Qt::Vertical); - gradient.setStops({ - {0.0, gradient.startColor()}, - {p, gradient.startColor()}, - {p, gradient.endColor()}, - {1.0, gradient.endColor()} - }); + auto gradient = sensor->gradientHint( Q::Horizon ); + gradient.setDirection( QskGradient::Linear ); + gradient.setLinearDirection( Qt::Vertical ); + gradient.setStops( { { 0.0, gradient.startColor() }, { p, gradient.startColor() }, + { p, gradient.endColor() }, { 1.0, gradient.endColor() } } ); - auto* const tNode = ensure>::node(node); - auto* const boxNode = static_cast(tNode->firstChild()); - updateBoxNode(sensor, boxNode, { 0, 0, 2 * r1, 2 * r1 }, shape, bmetrics, bcolors, gradient); + auto* const tNode = ensure< QSGTransformNode, par< 1, QskBoxNode > >::node( node ); + auto* const boxNode = static_cast< QskBoxNode* >( tNode->firstChild() ); + updateBoxNode( sensor, boxNode, { 0, 0, 2 * r1, 2 * r1 }, shape, bmetrics, bcolors, gradient ); - const auto matrix = - matrix_deg(0, 0, 0, cX, cY, 0) * - matrix_deg(0, 0, rZ, 0, 0, 0) * - matrix_deg(0, 0, 0, -r1, -r1, 0); + const auto matrix = matrix_deg( 0, 0, 0, cX, cY, 0 ) * matrix_deg( 0, 0, rZ, 0, 0, 0 ) * + matrix_deg( 0, 0, 0, -r1, -r1, 0 ); - tNode->setMatrix(matrix); + tNode->setMatrix( matrix ); return tNode; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksX; - const auto color = sensor->color(subControl); - const auto scale = sensor->strutSizeHint(subControl); - - const auto cX = center(sensor).x(); - const auto cY = center(sensor).y(); + const auto color = sensor->color( subControl ); + const auto scale = sensor->strutSizeHint( subControl ); - const auto rX = sensor->rotation().x(); - const auto rY = sensor->rotation().y(); - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); + const auto cX = center( sensor ).x(); + const auto cY = center( sensor ).y(); - const auto r1 = innerRadius(sensor); + const auto rotation = sensor->subControlRotation( subControl ); + + const auto r1 = innerRadius( sensor ); + const auto r2 = outerRadius( sensor ); const auto r3 = r1 * scale.height(); const auto sX = r1 / sensor->angle().x(); const auto sY = r1 / sensor->angle().y(); - const auto tX = static_cast(rY * sX); - const auto tY = 0.0; // static_cast(rX * sY); + const auto tX = static_cast< float >( rotation.y() * sX ); + const auto tY = static_cast< float >( rotation.x() * sY ); - auto* const clipping = ensure>>::node(node); - auto* const transform = static_cast(clipping->firstChild()); - auto* const tickmarks = static_cast(transform->firstChild()); + auto* const clipping = + ensure< PolygonClipNode, par< 1, QSGTransformNode, par< 1, LinearTickmarksNode > > >::node( + node ); + auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); + auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); - auto size = qvariant_cast(sensor->effectiveSkinHint(subControl)) * r3; + auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3; - clipping->setGeometryProperties(r1, cX, cY); + clipping->setGeometryProperties( r1, cX, cY ); - tickmarks->setMaterialProperties(color); - tickmarks->setGeometryProperties(sensor->tickmarks(Qt::XAxis), size, {sX, 0.0f}, {tX, tY}); + tickmarks->setMaterialProperties( color ); + tickmarks->setGeometryProperties( + sensor->tickmarks( Qt::XAxis ), size, { sX, 0.0f }, { tX, tY } ); - const auto matrix = matrix_deg(0, 0, rZ, cX, cY, 0); - transform->setMatrix(matrix); + const auto matrix = matrix_deg( 0, 0, rotation.z(), cX, cY, 0 ); + transform->setMatrix( matrix ); return clipping; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksY; - const auto color = sensor->color(subControl); - const auto scale = sensor->strutSizeHint(subControl); + const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r1 = innerRadius(sensor); - const auto r3 = r1 * scale.width(); - - const auto rX = 0.00; - const auto rY = 0.00; - const auto rZ = sensor->rotation().z(); + const auto color = sensor->color( subControl ); + const auto scale = sensor->strutSizeHint( subControl ); - const auto tX = center(sensor).x(); - const auto tY = center(sensor).y(); - const auto tZ = 0.0; + const auto r3 = state.r1 * scale.width(); - auto* const cNode = ensure>>::node(node); - auto* const tNode = static_cast(cNode->firstChild()); - auto* const lNode = static_cast(tNode->firstChild()); + const auto rotation = sensor->subControlRotation( subControl ); - auto size = qvariant_cast(sensor->effectiveSkinHint(subControl)) * r3; + auto* const cNode = + ensure< PolygonClipNode, par< 1, QSGTransformNode, par< 1, LinearTickmarksNode > > >::node( + node ); + auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); + auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); - cNode->setGeometryProperties(r1, tX, tY); + auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3; - const auto sY = static_cast(r1 / sensor->angle().y()); - lNode->setMaterialProperties(color); -#ifdef USE_FILTERING - using TickType = QskScaleTickmarks::TickType; - const auto filter = [=](TickType, qreal v){ return rY - r1 / sY <= v && v <= rY + r1 / sY; }; - lNode->setGeometryProperties(filtered(sensor->tickmarks(Qt::YAxis), filter), size, {0.0f, sY}, {}, 1.0f, true); -#else - lNode->setGeometryProperties(sensor->tickmarks(Qt::YAxis), size, {0.0f, sY}); -#endif + cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - const auto matrix = matrix_deg(rX, rY, rZ, tX, tY, tZ); - tNode->setMatrix(matrix); + const auto sY = static_cast< float >( state.r1 / sensor->angle().y() ); + lNode->setMaterialProperties( color ); + lNode->setGeometryProperties( sensor->tickmarks( Qt::YAxis ), size, { 0.0f, sY }, + { ( float ) state.tX, ( float ) state.tY } ); + + const auto matrix = matrix_deg( 0, 0, state.rZ, state.cX, state.cY ); + tNode->setMatrix( matrix ); return cNode; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksZ; - const auto color = sensor->color(subControl); - const auto scale = sensor->strutSizeHint(subControl); - - const auto r1 = innerRadius(sensor); - const auto r2 = outerRadius(sensor); - const auto r3 = qvariant_cast(sensor->effectiveSkinHint(subControl)) * (r2 - r1) + QVector3D{r1, r1, r1}; + const auto color = sensor->color( subControl ); + const auto scale = sensor->strutSizeHint( subControl ); - auto* const transform = ensure>::node(node); - auto* const tickmarksNode = static_cast(transform->firstChild()); - tickmarksNode->setMaterialProperties(color); - tickmarksNode->setGeometryProperties(sensor->tickmarks(Qt::ZAxis), r1, r3); + const auto r1 = innerRadius( sensor ); + const auto r2 = outerRadius( sensor ); + const auto r3 = + qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( r2 - r1 ) + + QVector3D{ r1, r1, r1 }; - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); - const auto tX = center(sensor).x(); - const auto tY = center(sensor).y(); + auto* const transform = ensure< QSGTransformNode, par< 1, RadialTickmarksNode > >::node( node ); + auto* const tickmarksNode = static_cast< RadialTickmarksNode* >( transform->firstChild() ); + tickmarksNode->setMaterialProperties( color ); + tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), r1, r3 ); - const auto matrix = matrix_deg(0.0, 0.0, rZ, tX, tY); - transform->setMatrix(matrix); + const auto rZ = sensor->subControlRotation( subControl ).z(); + const auto tX = center( sensor ).x(); + const auto tY = center( sensor ).y(); + + const auto matrix = matrix_deg( 0.0, 0.0, rZ, tX, tY ); + transform->setMatrix( matrix ); return transform; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksXLabels; - - const auto r1 = innerRadius(sensor); - const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksX).height()); + + const auto r1 = innerRadius( sensor ); + const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); const auto sX = r1 / sensor->angle().x(); const auto sY = r1 / sensor->angle().y(); - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); - const auto cX = center(sensor).x(); - const auto cY = center(sensor).y(); - const auto tX = sensor->rotation().y() * sX; - const auto tY = r3; - auto* const cNode = ensure>>::node(node); - auto* const tNode = static_cast(cNode->firstChild()); - auto* const lNode = static_cast(tNode->firstChild()); - tNode->setMatrix(matrix_deg(0.0, 0.0, rZ, cX, cY)); - cNode->setGeometryProperties(r1, center(sensor).x(), center(sensor).y()); - lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::XAxis), { sX , 0.0}, {tX, tY}); + const auto rotation = sensor->subControlRotation( subControl ); + + const auto rZ = rotation.z(); + const auto cX = center( sensor ).x(); + const auto cY = center( sensor ).y(); + const auto tX = rotation.y() * sX; + const auto tY = r3 + rotation.x() * sY; + + auto* const cNode = ensure< PolygonClipNode, + par< 1, QSGTransformNode, par< 1, LinearTickmarksLabelsNode > > >::node( node ); + auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); + auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); + tNode->setMatrix( matrix_deg( 0.0, 0.0, rZ, cX, cY ) ); + cNode->setGeometryProperties( r1, center( sensor ).x(), center( sensor ).y() ); + lNode->update( + sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { sX, 0.0 }, { tX, tY } ); return cNode; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksYLabels; - const auto r1 = innerRadius(sensor); - const auto r3 = static_cast(r1 * sensor->strutSizeHint(Q::TickmarksY).width()); - const auto cX = static_cast(center(sensor).x()); - const auto cY = static_cast(center(sensor).y()); - const auto rZ = sensor->rotation().z(); - - auto* const cNode = ensure>>::node(node); - auto* const tNode = static_cast(cNode->firstChild()); - auto* const lNode = static_cast(tNode->firstChild()); - cNode->setGeometryProperties(r1, cX, cY); - tNode->setMatrix(matrix_deg(0.0, 0.0, 0, cX, cY)); - lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::YAxis), { 0.0, r1 / sensor->angle().y() }, {r3, 0.0}); + const auto r1 = innerRadius( sensor ); + const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); + const auto cX = static_cast< float >( center( sensor ).x() ); + const auto cY = static_cast< float >( center( sensor ).y() ); + + const auto scale = sensor->strutSizeHint( subControl ); + const auto angles = sensor->angle(); + const auto rotation = sensor->subControlRotation( subControl ); + const auto sX = r1 / angles.x(); + const auto sY = r1 / angles.y(); + const auto tX = static_cast< float >( rotation.y() * sX ); + const auto tY = static_cast< float >( rotation.x() * sY ); + + auto* const cNode = ensure< PolygonClipNode, + par< 1, QSGTransformNode, par< 1, LinearTickmarksLabelsNode > > >::node( node ); + auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); + auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); + cNode->setGeometryProperties( r1, cX, cY ); + tNode->setMatrix( matrix_deg( 0.0, 0.0, rotation.z(), cX, cY ) ); + lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), + { 0.0, r1 / sensor->angle().y() }, { r3 + tX, tY } ); return cNode; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksZLabels; - auto* const tNode = ensure>::node(node); - auto* const lNode = static_cast(tNode->firstChild()); - const auto r1 = innerRadius(sensor); - const auto r3 = static_cast(r1 * sensor->strutSizeHint(subControl).width()); - const auto cX = static_cast(center(sensor).x()); - const auto cY = static_cast(center(sensor).y()); - const auto rZ = sensor->arcMetricsHint(subControl).startAngle(); - lNode->update(sensor, subControl, sensor->tickmarkLabels(Qt::ZAxis), { r3, r3 }); - tNode->setMatrix(matrix_deg(0.0, 0.0, rZ, cX, cY)); + auto* const tNode = + ensure< QSGTransformNode, par< 1, RadialTickmarksLabelsNode > >::node( node ); + auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); + const auto r1 = innerRadius( sensor ); + const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( subControl ).width() ); + const auto cX = static_cast< float >( center( sensor ).x() ); + const auto cY = static_cast< float >( center( sensor ).y() ); + const auto rZ = sensor->subControlRotation( subControl ).z(); + lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::ZAxis ), { r3, r3 } ); + tNode->setMatrix( matrix_deg( 0.0, 0.0, rZ, cX, cY ) ); return tNode; } template<> -QSGNode* QskLevelingSensorSkinlet::updateSubNode(const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node) const +QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( + const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - const auto cX = center(sensor).x(); - const auto cY = center(sensor).y(); - const auto r1 = innerRadius(sensor); + const auto cX = center( sensor ).x(); + const auto cY = center( sensor ).y(); + const auto r1 = innerRadius( sensor ); - auto* const clipNode = ensure::node(node); - clipNode->setGeometryProperties(r1, cX, cY); + auto* const clipNode = ensure< PolygonClipNode >::node( node ); + clipNode->setGeometryProperties( r1, cX, cY ); return clipNode; } QSGNode* QskLevelingSensorSkinlet::updateSubNode( - const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node) const + const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const { - const auto* const sensor = static_cast(skinnable); + const auto* const sensor = static_cast< const Q* >( skinnable ); - const auto subControl = [nodeRole, sensor](){ - switch(static_cast(nodeRole)) + const auto subControl = [ nodeRole, sensor ]() { + switch ( static_cast< R >( nodeRole ) ) { - case OuterDisk: return Q::OuterDisk; - case Horizon: return Q::Horizon; - case HorizonClip: return Q::Horizon; - case TickmarksX: return Q::TickmarksX; - case TickmarksXLabels: return Q::TickmarksXLabels; - case TickmarksY: return Q::TickmarksY; - case TickmarksYLabels: return Q::TickmarksYLabels; - case TickmarksZ: return Q::TickmarksZ; - case TickmarksZLabels: return Q::TickmarksZLabels; - default: return QskAspect::NoSubcontrol; + case OuterDisk: + return Q::OuterDisk; + case Horizon: + return Q::Horizon; + case HorizonClip: + return Q::Horizon; + case TickmarksX: + return Q::TickmarksX; + case TickmarksXLabels: + return Q::TickmarksXLabels; + case TickmarksY: + return Q::TickmarksY; + case TickmarksYLabels: + return Q::TickmarksYLabels; + case TickmarksZ: + return Q::TickmarksZ; + case TickmarksZLabels: + return Q::TickmarksZLabels; + default: + return QskAspect::NoSubcontrol; } }(); - if (qvariant_cast(sensor->effectiveSkinHint(subControl | QskAspect::Option))) + if ( qvariant_cast< bool >( sensor->effectiveSkinHint( subControl | QskAspect::Option ) ) ) { return nullptr; } - switch(static_cast(nodeRole)) + switch ( static_cast< R >( nodeRole ) ) { - case OuterDisk: return updateSubNode(sensor, nodeRole, node); - case Horizon: return updateSubNode(sensor, nodeRole, node); - case HorizonClip: return updateSubNode(sensor, nodeRole, node); - case TickmarksX: return updateSubNode(sensor, nodeRole, node); - case TickmarksXLabels: return updateSubNode(sensor, nodeRole, node); - case TickmarksY: return updateSubNode(sensor, nodeRole, node); - case TickmarksYLabels: return updateSubNode(sensor, nodeRole, node); - case TickmarksZ: return updateSubNode(sensor, nodeRole, node); - case TickmarksZLabels: return updateSubNode(sensor, nodeRole, node); - default: return Inherited::updateSubNode(sensor, nodeRole, node); + case OuterDisk: + return updateSubNode< OuterDisk >( sensor, nodeRole, node ); + case Horizon: + return updateSubNode< Horizon >( sensor, nodeRole, node ); + case HorizonClip: + return updateSubNode< HorizonClip >( sensor, nodeRole, node ); + case TickmarksX: + return updateSubNode< TickmarksX >( sensor, nodeRole, node ); + case TickmarksXLabels: + return updateSubNode< TickmarksXLabels >( sensor, nodeRole, node ); + case TickmarksY: + return updateSubNode< TickmarksY >( sensor, nodeRole, node ); + case TickmarksYLabels: + return updateSubNode< TickmarksYLabels >( sensor, nodeRole, node ); + case TickmarksZ: + return updateSubNode< TickmarksZ >( sensor, nodeRole, node ); + case TickmarksZLabels: + return updateSubNode< TickmarksZLabels >( sensor, nodeRole, node ); + default: + return Inherited::updateSubNode( sensor, nodeRole, node ); } } From 10fa1e4a69a1d6ba3e5753072b4fde151173558a Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 20 Jul 2023 16:12:54 +0200 Subject: [PATCH 12/42] add rotation and state per subcontrol --- .../LevelingSensor/QskLevelingSensorNodes.h | 3 + .../QskLevelingSensorSkinlet.cpp | 162 +++++++-------- .../LevelingSensor/QskLevelingSensorUtility.h | 6 +- .../QskLevelingSensorUtility_test.cpp | 190 ------------------ .../LevelingSensor/QskSGNodeUtility.h | 104 +++------- 5 files changed, 97 insertions(+), 368 deletions(-) delete mode 100644 src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/LevelingSensor/QskLevelingSensorNodes.h index d245d703..82b5ad77 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorNodes.h +++ b/src/controls/LevelingSensor/QskLevelingSensorNodes.h @@ -1,10 +1,13 @@ #pragma once +#include "QskLevelingSensorUtility.h" + #include #include #include #include +#include class RadialTickmarksNode final : public QSGGeometryNode { diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index d904e8ba..b26a1e1d 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -1,7 +1,7 @@ #include "QskLevelingSensorSkinlet.h" #include "QskLevelingSensor.h" -#include "QskLevelingSensorNodes.h" #include "QskLevelingSensorUtility.h" +#include "QskLevelingSensorNodes.h" #include "QskSGNodeUtility.h" #include @@ -50,6 +50,11 @@ namespace , sZ( r1 / sensor->angle().z() ) { } + + Q_REQUIRED_RESULT QVector3D scale() const noexcept + { + return {(float)sX, (float)sY, (float)sZ}; + } }; template<> @@ -72,6 +77,16 @@ namespace , tZ( 0.0 ) { } + + Q_REQUIRED_RESULT QVector3D translation() const noexcept + { + return {(float)tX, (float)tY, (float)tZ}; + } + + Q_REQUIRED_RESULT QMatrix4x4 matrix() const noexcept + { + return matrix_deg( 0, 0, rZ, cX, cY ); + } }; } @@ -168,7 +183,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - const auto subControl = Q::OuterDisk; + const auto subControl = Q::OuterDisk; const auto contentsRect = sensor->contentsRect(); const auto boxRect = subControlRect< OuterDisk >( sensor, contentsRect ); const auto boxShapeMetrics = QskBoxShapeMetrics{ boxRect.width() / 2 }; @@ -176,7 +191,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const auto boxBorderColors = sensor->boxBorderColorsHint( subControl ); const auto boxGradient = sensor->gradientHint( subControl ); - auto* const root = ensure< QSGTransformNode, par< 1, QskBoxNode > >::node( node ); + auto* const root = ensureNode< QSGTransformNode, QskBoxNode >( node ); auto* const bNode = static_cast< QskBoxNode* >( root->firstChild() ); const auto size = outerRadius( sensor ) * sensor->strutSizeHint( Q::OuterDisk ).width(); @@ -200,30 +215,27 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::Horizon; - const auto r1 = innerRadius( sensor ); - const auto cX = center( sensor ).x(); - const auto cY = center( sensor ).y(); - const auto rX = sensor->subControlRotation( subControl ).x(); - const auto rZ = 0.0; + const State state(sensor, subControl); + const auto dY = 2 * sensor->angle().y(); - const auto p = qBound( 0.0, 0.5 + ( -rX / dY ), 1.0 ); + const auto pY = qBound( 0.0, 0.5 + ( -state.rX / dY ), 1.0 ); - const auto shape = QskBoxShapeMetrics{ r1 }; - const auto bmetrics = sensor->boxBorderMetricsHint( subControl ); - const auto bcolors = sensor->boxBorderColorsHint( subControl ); + const auto shape = QskBoxShapeMetrics{ state.r1 }; + const auto metrics = sensor->boxBorderMetricsHint( subControl ); + const auto colors = sensor->boxBorderColorsHint( subControl ); auto gradient = sensor->gradientHint( Q::Horizon ); gradient.setDirection( QskGradient::Linear ); gradient.setLinearDirection( Qt::Vertical ); - gradient.setStops( { { 0.0, gradient.startColor() }, { p, gradient.startColor() }, - { p, gradient.endColor() }, { 1.0, gradient.endColor() } } ); + gradient.setStops( { { 0.0, gradient.startColor() }, { pY, gradient.startColor() }, + { pY, gradient.endColor() }, { 1.0, gradient.endColor() } } ); - auto* const tNode = ensure< QSGTransformNode, par< 1, QskBoxNode > >::node( node ); + auto* const tNode = ensureNode< QSGTransformNode, QskBoxNode >( node ); auto* const boxNode = static_cast< QskBoxNode* >( tNode->firstChild() ); - updateBoxNode( sensor, boxNode, { 0, 0, 2 * r1, 2 * r1 }, shape, bmetrics, bcolors, gradient ); + updateBoxNode( sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient ); - const auto matrix = matrix_deg( 0, 0, 0, cX, cY, 0 ) * matrix_deg( 0, 0, rZ, 0, 0, 0 ) * - matrix_deg( 0, 0, 0, -r1, -r1, 0 ); + const auto matrix = matrix_deg( 0, 0, 0, state.cX, state.cY, 0 ) * + matrix_deg( 0, 0, 0, -state.r1, -state.r1, 0 ); tNode->setMatrix( matrix ); return tNode; @@ -234,39 +246,26 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksX; + State state(sensor, subControl); const auto color = sensor->color( subControl ); const auto scale = sensor->strutSizeHint( subControl ); - - const auto cX = center( sensor ).x(); - const auto cY = center( sensor ).y(); - - const auto rotation = sensor->subControlRotation( subControl ); - - const auto r1 = innerRadius( sensor ); - const auto r2 = outerRadius( sensor ); - const auto r3 = r1 * scale.height(); - - const auto sX = r1 / sensor->angle().x(); - const auto sY = r1 / sensor->angle().y(); - - const auto tX = static_cast< float >( rotation.y() * sX ); - const auto tY = static_cast< float >( rotation.x() * sY ); + const auto r3 = state.r1 * scale.height(); auto* const clipping = - ensure< PolygonClipNode, par< 1, QSGTransformNode, par< 1, LinearTickmarksNode > > >::node( + ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksNode >( node ); auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3; - clipping->setGeometryProperties( r1, cX, cY ); + clipping->setGeometryProperties( state.r1, state.cX, state.cY ); tickmarks->setMaterialProperties( color ); - tickmarks->setGeometryProperties( - sensor->tickmarks( Qt::XAxis ), size, { sX, 0.0f }, { tX, tY } ); + tickmarks->setGeometryProperties( sensor->tickmarks( Qt::XAxis ), size, + { state.scale().x(), 0.0f }, state.translation().toVector2D() ); - const auto matrix = matrix_deg( 0, 0, rotation.z(), cX, cY, 0 ); + const auto matrix = matrix_deg( 0, 0, state.rZ, state.cX, state.cY ); transform->setMatrix( matrix ); return clipping; } @@ -286,7 +285,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const auto rotation = sensor->subControlRotation( subControl ); auto* const cNode = - ensure< PolygonClipNode, par< 1, QSGTransformNode, par< 1, LinearTickmarksNode > > >::node( + ensureNode< PolygonClipNode,QSGTransformNode, LinearTickmarksNode>( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); @@ -297,11 +296,10 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const auto sY = static_cast< float >( state.r1 / sensor->angle().y() ); lNode->setMaterialProperties( color ); - lNode->setGeometryProperties( sensor->tickmarks( Qt::YAxis ), size, { 0.0f, sY }, + lNode->setGeometryProperties( sensor->tickmarks( Qt::YAxis ), size, { 0.0f, state.scale().y() }, { ( float ) state.tX, ( float ) state.tY } ); - const auto matrix = matrix_deg( 0, 0, state.rZ, state.cX, state.cY ); - tNode->setMatrix( matrix ); + tNode->setMatrix( state.matrix() ); return cNode; } @@ -310,25 +308,20 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksZ; + const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto color = sensor->color( subControl ); const auto scale = sensor->strutSizeHint( subControl ); - const auto r1 = innerRadius( sensor ); - const auto r2 = outerRadius( sensor ); const auto r3 = - qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( r2 - r1 ) + - QVector3D{ r1, r1, r1 }; + qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( state.r2 - state.r1 ) + + QVector3D{ (float)state.r1, (float)state.r1, (float)state.r1 }; - auto* const transform = ensure< QSGTransformNode, par< 1, RadialTickmarksNode > >::node( node ); + auto* const transform = ensureNode< QSGTransformNode, RadialTickmarksNode >( node ); auto* const tickmarksNode = static_cast< RadialTickmarksNode* >( transform->firstChild() ); tickmarksNode->setMaterialProperties( color ); - tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), r1, r3 ); + tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), state.r1, r3 ); - const auto rZ = sensor->subControlRotation( subControl ).z(); - const auto tX = center( sensor ).x(); - const auto tY = center( sensor ).y(); - - const auto matrix = matrix_deg( 0.0, 0.0, rZ, tX, tY ); + const auto matrix = matrix_deg( 0.0, 0.0, state.rZ, state.cX, state.cY ); transform->setMatrix( matrix ); return transform; } @@ -338,28 +331,18 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksXLabels; + const State< QskAspect::Subcontrol > state( sensor, subControl ); + const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); + const auto translation = state.translation().toVector2D() + QVector2D{0, r3}; - const auto r1 = innerRadius( sensor ); - const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); - const auto sX = r1 / sensor->angle().x(); - const auto sY = r1 / sensor->angle().y(); - - const auto rotation = sensor->subControlRotation( subControl ); - - const auto rZ = rotation.z(); - const auto cX = center( sensor ).x(); - const auto cY = center( sensor ).y(); - const auto tX = rotation.y() * sX; - const auto tY = r3 + rotation.x() * sY; - - auto* const cNode = ensure< PolygonClipNode, - par< 1, QSGTransformNode, par< 1, LinearTickmarksLabelsNode > > >::node( node ); + auto* const cNode = + ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); - tNode->setMatrix( matrix_deg( 0.0, 0.0, rZ, cX, cY ) ); - cNode->setGeometryProperties( r1, center( sensor ).x(), center( sensor ).y() ); + cNode->setGeometryProperties( state.r1, state.cX, state.cY ); + tNode->setMatrix( state.matrix() ); lNode->update( - sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { sX, 0.0 }, { tX, tY } ); + sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 }, translation ); return cNode; } @@ -368,27 +351,21 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksYLabels; - const auto r1 = innerRadius( sensor ); - const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); - const auto cX = static_cast< float >( center( sensor ).x() ); - const auto cY = static_cast< float >( center( sensor ).y() ); + const State< QskAspect::Subcontrol > state( sensor, subControl ); + const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); const auto scale = sensor->strutSizeHint( subControl ); const auto angles = sensor->angle(); const auto rotation = sensor->subControlRotation( subControl ); - const auto sX = r1 / angles.x(); - const auto sY = r1 / angles.y(); - const auto tX = static_cast< float >( rotation.y() * sX ); - const auto tY = static_cast< float >( rotation.x() * sY ); + const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 ); - auto* const cNode = ensure< PolygonClipNode, - par< 1, QSGTransformNode, par< 1, LinearTickmarksLabelsNode > > >::node( node ); + auto* const cNode = ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); - cNode->setGeometryProperties( r1, cX, cY ); - tNode->setMatrix( matrix_deg( 0.0, 0.0, rotation.z(), cX, cY ) ); + cNode->setGeometryProperties( state.r1, state.cX, state.cY ); + tNode->setMatrix( state.matrix() ); lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), - { 0.0, r1 / sensor->angle().y() }, { r3 + tX, tY } ); + { 0.0, state.scale().y() }, translation ); return cNode; } @@ -397,16 +374,12 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksZLabels; - auto* const tNode = - ensure< QSGTransformNode, par< 1, RadialTickmarksLabelsNode > >::node( node ); - auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); - const auto r1 = innerRadius( sensor ); - const auto r3 = static_cast< float >( r1 * sensor->strutSizeHint( subControl ).width() ); - const auto cX = static_cast< float >( center( sensor ).x() ); - const auto cY = static_cast< float >( center( sensor ).y() ); - const auto rZ = sensor->subControlRotation( subControl ).z(); + const State< QskAspect::Subcontrol > state( sensor, subControl ); + auto* const tNode = ensureNode< QSGTransformNode, RadialTickmarksLabelsNode>( node ); + auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); + const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( subControl ).width() ); lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::ZAxis ), { r3, r3 } ); - tNode->setMatrix( matrix_deg( 0.0, 0.0, rZ, cX, cY ) ); + tNode->setMatrix( state.matrix() ); return tNode; } @@ -418,7 +391,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( const auto cY = center( sensor ).y(); const auto r1 = innerRadius( sensor ); - auto* const clipNode = ensure< PolygonClipNode >::node( node ); + auto* const clipNode = ensureNode< PolygonClipNode >( node ); clipNode->setGeometryProperties( r1, cX, cY ); return clipNode; } @@ -454,6 +427,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode( } }(); + // use the subcontrol's option hint to hide it (default is visible) if ( qvariant_cast< bool >( sensor->effectiveSkinHint( subControl | QskAspect::Option ) ) ) { return nullptr; diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.h b/src/controls/LevelingSensor/QskLevelingSensorUtility.h index 42cee547..df745838 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorUtility.h +++ b/src/controls/LevelingSensor/QskLevelingSensorUtility.h @@ -39,7 +39,7 @@ inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( } template -inline bool compareExchange(T& dst, const T& src) +inline Q_REQUIRED_RESULT bool compareExchange(T& dst, const T& src) { if (dst != src) { @@ -50,7 +50,7 @@ inline bool compareExchange(T& dst, const T& src) } template<> -inline bool compareExchange(float& dst, const float& src) +inline Q_REQUIRED_RESULT bool compareExchange(float& dst, const float& src) { if (!qskFuzzyCompare (dst, src)) { @@ -61,7 +61,7 @@ inline bool compareExchange(float& dst, const float& src) } template<> -inline bool compareExchange(qreal& dst, const qreal& src) +inline Q_REQUIRED_RESULT bool compareExchange(qreal& dst, const qreal& src) { if (!qskFuzzyCompare (dst, src)) { diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp b/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp deleted file mode 100644 index f8baa02b..00000000 --- a/src/controls/LevelingSensor/QskLevelingSensorUtility_test.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "QskLevelingSensorUtility.h" - -#define ASSERT_TRUE(expr) if(!(expr)) { std::cerr << "ASSERT_TRUE(!" << #expr << "):" << __LINE__ << '\n'; return false; } - -class QSGNodeBase : public QSGNode -{ -public: - virtual std::string name() const = 0; -}; - -class QSGNodeA final : public QSGNodeBase{ public: QSGNodeA() { std::cout << name() << '\n'; } std::string name() const override { return "A"; }}; -class QSGNodeB final : public QSGNodeBase{ public: QSGNodeB() { std::cout << name() << '\n'; } std::string name() const override { return "B"; }}; -class QSGNodeC final : public QSGNodeBase{ public: QSGNodeC() { std::cout << name() << '\n'; } std::string name() const override { return "C"; }}; -class QSGNodeD final : public QSGNodeBase{ public: QSGNodeD() { std::cout << name() << '\n'; } std::string name() const override { return "D"; }}; -class QSGNodeE final : public QSGNodeBase{ public: QSGNodeE() { std::cout << name() << '\n'; } std::string name() const override { return "E"; }}; -class QSGNodeF final : public QSGNodeBase{ public: QSGNodeF() { std::cout << name() << '\n'; } std::string name() const override { return "F"; }}; -class QSGNodeG final : public QSGNodeBase{ public: QSGNodeG() { std::cout << name() << '\n'; } std::string name() const override { return "G"; }}; -class QSGNodeH final : public QSGNodeBase{ public: QSGNodeH() { std::cout << name() << '\n'; } std::string name() const override { return "H"; }}; - -using NodeType = QSGNode; - -bool testcase_ensure_node() -{ - NodeType* root = nullptr; - ASSERT_TRUE(root = ensure_node()); - ASSERT_TRUE(root->childCount() == 0); - delete root; - return true; -} - -// seq> - -/* - -bool testcase_seq() -{ - using namespace qsg; - { - auto* const root = ensure_node(); - seq, N, N>::append(root); - delete root; - } - { - auto* const root = ensure_node(); - ASSERT_TRUE(root); - ASSERT_TRUE(root->childCount() == 0); - qsg::seq<>::append(root); - ASSERT_TRUE(root->childCount() == 0); - delete root; - } - { - auto* const root = ensure_node(); - ASSERT_TRUE(root); - ASSERT_TRUE(root->childCount() == 0); - qsg::seq>::append(root); - ASSERT_TRUE(root->childCount() == 1); - delete root; - } - { - auto* const root = ensure_node(); - ASSERT_TRUE(root); - ASSERT_TRUE(root->childCount() == 0); - qsg::seq, N>::append(root); - ASSERT_TRUE(root->childCount() == 2); - delete root; - } - { - // - QSGNode - // - QSGNodeA - // - QSGNodeB - // - QSGNodeC - auto* const root = ensure_node(); - ASSERT_TRUE(root); - ASSERT_TRUE(root->childCount() == 0); - qsg::seq, N, N>::append(root); - ASSERT_TRUE(root->childCount() == 3); - delete root; - } - return true; -} - -*/ - -bool testcase_par() -{ - using namespace qsg; - { - std::cout << __func__ << 0 << '\n'; - //auto* const root = ensure_node(); - //ASSERT_TRUE(root->childCount() == 0); - //par<4, QSGNodeA, par<4, QSGNodeB>>::append(root); - //ASSERT_TRUE(root->childCount() == 4); - //for(int i = 0; i < 4; ++i) - //{ - // ASSERT_TRUE(root->childAtIndex(i)->childCount() == 4); - //} - //delete root; - } - { - std::cout << __func__ << 1 << '\n'; - // - QSGNode - // - QSGNodeA - // - QSGNodeB - // - QSGNodeC - // - QSGNodeD - // - QSGNodeA - // - QSGNodeB - // - QSGNodeC - // - QSGNodeD - // - QSGNodeA - // - QSGNodeB - // - QSGNodeC - // - QSGNodeD - // - QSGNodeA - // - QSGNodeB - // - QSGNodeC - // - QSGNodeD - auto* const root = ensure_node(); - ASSERT_TRUE(root->childCount() == 0); - par<4, QSGNodeA, - seq, - par<1, QSGNodeC>, - par<1, QSGNodeD>>>::append(root); - ASSERT_TRUE(root->childCount() == 4); - ASSERT_TRUE(root->childAtIndex(0)->childCount() == 3); - ASSERT_TRUE(root->childAtIndex(1)->childCount() == 3); - ASSERT_TRUE(root->childAtIndex(2)->childCount() == 3); - ASSERT_TRUE(root->childAtIndex(3)->childCount() == 3); - } - { - std::cout << __func__ << 3 << '\n'; - auto* const root = ensure_node(); - seq< - par<1, QSGNodeE, - seq< - par<1, QSGNodeA>, - par<1, QSGNodeB>, - par<1, QSGNodeC>>>, - par<1, QSGNodeF, - seq< - par<1, QSGNodeB>, - par<1, QSGNodeC>, - par<1, QSGNodeA>>>, - par<1, QSGNodeG, - seq< - par<1, QSGNodeC>, - par<1, QSGNodeA>, - par<1, QSGNodeB>>> - >::append(root); - ASSERT_TRUE(root->childCount() == 3); - for(int i = 0; i < root->childCount(); ++i) - { - ASSERT_TRUE(root->childAtIndex(i)->childCount() == 3); - for(int j = 0; j < root->childAtIndex(i)->childAtIndex(i)->childCount(); ++j) - { - ASSERT_TRUE(root->childAtIndex(i)->childCount() == 0); - } - } - ASSERT_TRUE(dynamic_cast(root->childAtIndex(0))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(0))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(1))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(0)->childAtIndex(2))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(1))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(0))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(1))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(1)->childAtIndex(2))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(2))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(0))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(1))); - ASSERT_TRUE(dynamic_cast(root->childAtIndex(2)->childAtIndex(2))); - } - return true; -} - -int main() -{ - bool result = true; - // result &= testcase_ensure_node(); - // result &= testcase_seq(); - result &= testcase_par(); - std::cout << (result ? "ok" : "failed") << std::endl; - return result ? EXIT_SUCCESS : EXIT_FAILURE; -} \ No newline at end of file diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.h b/src/controls/LevelingSensor/QskSGNodeUtility.h index 70b26504..d70c701b 100644 --- a/src/controls/LevelingSensor/QskSGNodeUtility.h +++ b/src/controls/LevelingSensor/QskSGNodeUtility.h @@ -1,100 +1,42 @@ #pragma once #include -#include namespace QskSGNode -{ - using NodeType = QSGNode; - - template - struct seq; - - template<> - struct seq<> +{ + namespace detail { - static void append(NodeType* root) - { - } - }; + template< typename... Ts > + struct append; - template - struct seq - { - static void append(NodeType* root) + template<> + struct append<> { - T::append(root); - } - }; - - template - struct seq - { - static void append(NodeType* root) - { - T::append(root); - seq::append(root); - } - }; - - template - struct par; - - template - struct par - { - static void append(NodeType* root) - { - const auto n = N; - for (int i = 0; i < N; ++i) + static void nodes( QSGNode* root ) { - root->appendChildNode(new T); } - } - }; + }; - template - struct par - { - static void append(NodeType* root) + template< typename Child, typename... Children > + struct append< Child, Children... > { - const auto n = N; - for (int i = 0; i < N; ++i) + static void nodes( QSGNode* root ) { - auto* const t = new T; - U::append(t); - root->appendChildNode(t); + auto* const child = new Child; + root->appendChildNode( child ); + append< Children... >::nodes( child ); } - } - }; + }; + } - template - struct ensure; - - template - struct ensure + template< typename Root, typename... Children > + inline Q_REQUIRED_RESULT Root* ensureNode( QSGNode* root = nullptr ) { - static Q_REQUIRED_RESULT Root* node(NodeType* root = nullptr) + if ( root == nullptr ) { - if(root == nullptr) - { - root = new Root; - } - return static_cast(root); + root = new Root; + detail::append< Children... >::nodes( root ); } - }; - - template - struct ensure - { - static Q_REQUIRED_RESULT Root* node(NodeType* root = nullptr) - { - if(root == nullptr) - { - root = new Root; - Append::append(root); - } - return static_cast(root); - } - }; + return static_cast< Root* >( root ); + } } \ No newline at end of file From 2ad90ac2bb764affface72af1cba2e80143d9965 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 24 Jul 2023 09:39:32 +0200 Subject: [PATCH 13/42] remove unused files --- playground/levelingsensor/main.cpp | 64 +++++++++++-------- .../LevelingSensor/QskLevelingSensorNodes.cpp | 0 .../LevelingSensor/QskLevelingSensorNodes.h | 4 +- .../QskLevelingSensorSkinlet.cpp | 10 +-- .../QskLevelingSensorUtility.cpp | 1 - 5 files changed, 45 insertions(+), 34 deletions(-) delete mode 100644 src/controls/LevelingSensor/QskLevelingSensorNodes.cpp delete mode 100644 src/controls/LevelingSensor/QskLevelingSensorUtility.cpp diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index ab93ceb3..587365f5 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -72,41 +72,44 @@ namespace sensor->setTickmarksLabels( axis, labels ); } - Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis, QskLevelingSensor* const sensor, int min, int max, std::function intervalA, std::function intervalB, QQuickItem* const parent = nullptr ) + Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis, + QskLevelingSensor* const sensor, int min, int max, + std::function< QskIntervalF( qreal ) > intervalA, + std::function< QskIntervalF( qreal ) > intervalB, QQuickItem* const parent = nullptr ) { auto* const slider = new QskSlider( Qt::Horizontal, parent ); slider->setMinimum( min ); slider->setMaximum( max ); - QObject::connect(slider, &QskSlider::valueChanged, sensor, [ = ]( const qreal degree ) { - updateTickmarks( axis, intervalA(degree), intervalB(degree), sensor ); + QObject::connect( slider, &QskSlider::valueChanged, sensor, [ = ]( const qreal degree ) { + updateTickmarks( axis, intervalA( degree ), intervalB( degree ), sensor ); updateTickmarksLabels( axis, intervalA( degree ), intervalB( degree ), 10, sensor ); } ); return slider; } - Q_REQUIRED_RESULT QskSlider* makeRotationSlider( - const Qt::Axis axis, QskLevelingSensor* const sensor, const QskAspect::Subcontrol subControl, QQuickItem* const parent = nullptr ) + Q_REQUIRED_RESULT QskSlider* makeRotationSlider( const Qt::Axis axis, + QskLevelingSensor* const sensor, const QskAspect::Subcontrol subControl, + QQuickItem* const parent = nullptr ) { auto* const slider = new QskSlider( Qt::Horizontal, parent ); slider->setMinimum( -360 ); slider->setMaximum( +360 ); QObject::connect( sensor, &QskLevelingSensor::subControlRotationChanged, slider, - [ = ]( const QskAspect::Subcontrol control, const QVector3D& degree ) { - if(control == subControl) + [ = ]( const QskAspect::Subcontrol control, const QVector3D& degree ) { + if ( control == subControl ) { slider->setValue( degree[ axis ] ); } } ); - QObject::connect( slider, &QskSlider::valueChanged, sensor, - [ = ]( const qreal degree ) { - auto d = sensor->subControlRotation( subControl ); - d[ axis ] = degree; - sensor->setSubControlRotation( subControl, d ); - } ); + QObject::connect( slider, &QskSlider::valueChanged, sensor, [ = ]( const qreal degree ) { + auto d = sensor->subControlRotation( subControl ); + d[ axis ] = degree; + sensor->setSubControlRotation( subControl, d ); + } ); return slider; } @@ -117,24 +120,33 @@ namespace Window() { auto* const root = new QskLinearBox( Qt::Horizontal, contentItem() ); - root->setSpacing(8); - root->setMargins(8); + root->setSpacing( 8 ); + root->setMargins( 8 ); auto* const left = new QskLinearBox( Qt::Vertical, root ); auto* const right = new QskLinearBox( Qt::Vertical, root ); auto* const sensor = new QskLevelingSensor( left ); - auto linearIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};}; - auto linearIntervalB = [](const qreal degree)->QskIntervalF{ return {}; }; - - auto radialIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};}; - auto radialIntervalB = [](const qreal degree)->QskIntervalF{ return {180-degree, 180+degree};}; + auto linearIntervalA = []( const qreal degree ) -> QskIntervalF { + return { -degree, +degree }; + }; + auto linearIntervalB = []( const qreal degree ) -> QskIntervalF { return {}; }; + + auto radialIntervalA = []( const qreal degree ) -> QskIntervalF { + return { -degree, +degree }; + }; + auto radialIntervalB = []( const qreal degree ) -> QskIntervalF { + return { 180 - degree, 180 + degree }; + }; ( void ) new QskTextLabel( "Tickmarks X", right ); - auto* const sliderTickmarksX = makeTickmarksSlider( Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); + auto* const sliderTickmarksX = makeTickmarksSlider( + Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); ( void ) new QskTextLabel( "Tickmarks Y", right ); - auto* const sliderTickmarksY = makeTickmarksSlider( Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); + auto* const sliderTickmarksY = makeTickmarksSlider( + Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); ( void ) new QskTextLabel( "Tickmarks Z", right ); - auto* const sliderTickmarksZ = makeTickmarksSlider( Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right ); + auto* const sliderTickmarksZ = makeTickmarksSlider( + Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right ); ( void ) new QskTextLabel( "Rotation X Plane", right ); ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksX, right ); @@ -149,9 +161,9 @@ namespace ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksZ, right ); ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksZ, right ); - sliderTickmarksX->setValue(15); - sliderTickmarksY->setValue(15); - sliderTickmarksZ->setValue(30); + sliderTickmarksX->setValue( 15 ); + sliderTickmarksY->setValue( 15 ); + sliderTickmarksZ->setValue( 30 ); } }; } diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.cpp b/src/controls/LevelingSensor/QskLevelingSensorNodes.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/LevelingSensor/QskLevelingSensorNodes.h index 82b5ad77..6bf2a8c4 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorNodes.h +++ b/src/controls/LevelingSensor/QskLevelingSensorNodes.h @@ -175,10 +175,10 @@ private: QVector3D m_tickmarkSize = { 1.0, 2.0, 4.0 }; }; -class PolygonClipNode final : public QSGClipNode +class RadialClipNode final : public QSGClipNode { public: - PolygonClipNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + RadialClipNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) { m_geometry.setVertexDataPattern(QSGGeometry::DynamicPattern); m_geometry.setDrawingMode(QSGGeometry::DrawTriangleFan); diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index b26a1e1d..0ecd312e 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -252,7 +252,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const auto r3 = state.r1 * scale.height(); auto* const clipping = - ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksNode >( + ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); @@ -285,7 +285,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const auto rotation = sensor->subControlRotation( subControl ); auto* const cNode = - ensureNode< PolygonClipNode,QSGTransformNode, LinearTickmarksNode>( + ensureNode< RadialClipNode,QSGTransformNode, LinearTickmarksNode>( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); @@ -336,7 +336,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( const auto translation = state.translation().toVector2D() + QVector2D{0, r3}; auto* const cNode = - ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); @@ -359,7 +359,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( const auto rotation = sensor->subControlRotation( subControl ); const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 ); - auto* const cNode = ensureNode< PolygonClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); @@ -391,7 +391,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( const auto cY = center( sensor ).y(); const auto r1 = innerRadius( sensor ); - auto* const clipNode = ensureNode< PolygonClipNode >( node ); + auto* const clipNode = ensureNode< RadialClipNode >( node ); clipNode->setGeometryProperties( r1, cX, cY ); return clipNode; } diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp b/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp deleted file mode 100644 index e28b1e35..00000000 --- a/src/controls/LevelingSensor/QskLevelingSensorUtility.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "QskLevelingSensorUtility.h" \ No newline at end of file From 5cb4fea788caf7b69eed7fed70008c4b05fa0ea2 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 24 Jul 2023 10:08:53 +0200 Subject: [PATCH 14/42] resize nodes list --- src/CMakeLists.txt | 2 -- .../LevelingSensor/QskLevelingSensorNodes.h | 15 +++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96e0b469..f43492b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -433,9 +433,7 @@ list(APPEND HEADERS list(APPEND SOURCES controls/LevelingSensor/QskSGNodeUtility.cpp controls/LevelingSensor/QskLevelingSensor.cpp - controls/LevelingSensor/QskLevelingSensorNodes.cpp controls/LevelingSensor/QskLevelingSensorSkinlet.cpp - controls/LevelingSensor/QskLevelingSensorUtility.cpp ) if(ENABLE_PINYIN) diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/LevelingSensor/QskLevelingSensorNodes.h index 6bf2a8c4..4ded2f7f 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorNodes.h +++ b/src/controls/LevelingSensor/QskLevelingSensorNodes.h @@ -243,15 +243,18 @@ public: void update(const QskSkinnable* const skinnable, const QskAspect::Subcontrol subControl, const QVector>& labels, const QVector2D& scale = { 1.0, 0.0 }, const QVector2D& offset = {}) { - if (childCount() != labels.count()) + const auto count = labels.count(); + + for ( int i = childCount(); i > count; --i ) { - removeAllChildNodes(); - for (const auto& label : qAsConst(labels)) - { - appendChildNode(new QskTextNode); - } + removeChildNode(lastChild()); } + for ( int i = childCount(); i < count; ++i ) + { + appendChildNode(new QskTextNode); + } + const QFontMetricsF metrics(skinnable->effectiveFont(subControl)); const auto h = skinnable->effectiveFontHeight(subControl); const auto a = skinnable->alignmentHint(subControl); From 37183bb637577c20c7b3f7d5f8310fab289ff228 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Mon, 24 Jul 2023 10:56:26 +0200 Subject: [PATCH 15/42] using private data --- playground/levelingsensor/main.cpp | 1 + .../LevelingSensor/QskLevelingSensor.cpp | 136 ++++++++++-------- .../LevelingSensor/QskLevelingSensor.h | 72 ++++------ 3 files changed, 111 insertions(+), 98 deletions(-) diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index 587365f5..de61fb25 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/LevelingSensor/QskLevelingSensor.cpp index 6295f651..8c73f0b0 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensor.cpp @@ -1,13 +1,17 @@ #include "QskLevelingSensor.h" -#include #include +#include +#include + +#include +#include namespace { - template - bool compareExchange(T& dst, const T& src) + template< typename T > + bool compareExchange( T& dst, const T& src ) { - if (dst != src) + if ( dst != src ) { dst = src; return true; @@ -16,9 +20,9 @@ namespace } template<> - bool compareExchange(float& dst, const float& src) + bool compareExchange< float >( float& dst, const float& src ) { - if (!qskFuzzyCompare(dst, src)) + if ( !qskFuzzyCompare( dst, src ) ) { dst = src; return true; @@ -26,78 +30,93 @@ namespace return false; } - inline bool isAxis(const Qt::Axis axis) { + inline bool isAxis( const Qt::Axis axis ) + { return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; } } -QSK_SUBCONTROL(QskLevelingSensor, OuterDisk) -QSK_SUBCONTROL(QskLevelingSensor, Horizon) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksX) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksXLabels) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksY) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksYLabels) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksZ) -QSK_SUBCONTROL(QskLevelingSensor, TickmarksZLabels) +QSK_SUBCONTROL( QskLevelingSensor, OuterDisk ) +QSK_SUBCONTROL( QskLevelingSensor, Horizon ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksX ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksXLabels ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksY ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksYLabels ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksZ ) +QSK_SUBCONTROL( QskLevelingSensor, TickmarksZLabels ) -#define RETURN_IF_FALSE(expr) if(!(expr)) return; +#define RETURN_IF_FALSE( expr ) \ + if ( !( expr ) ) \ + return; using Q = QskLevelingSensor; -QskLevelingSensor::QskLevelingSensor(QQuickItem* const parent) - : Inherited(parent) +class QskLevelingSensor::PrivateData +{ + public: + QVector3D m_angle = { 45, 45, 45 }; + Tickmarks m_tickmarks[ 3 ]; + TickmarksLabels m_tickmarksLabels[ 3 ]; + std::unordered_map< QskAspect::Subcontrol, QVector3D > m_subControlRotation; +}; + +QskLevelingSensor::QskLevelingSensor( QQuickItem* const parent ) + : Inherited( parent ) + , m_data( std::make_unique< QskLevelingSensor::PrivateData >() ) { } -void QskLevelingSensor::setTickmarks(const Qt::Axis axis, QskScaleTickmarks tickmarks) +QskLevelingSensor::~QskLevelingSensor() = default; + +void QskLevelingSensor::setTickmarks( const Qt::Axis axis, QskScaleTickmarks tickmarks ) { - RETURN_IF_FALSE(isAxis(axis)); - m_tickmarks[axis] = std::move(tickmarks); + RETURN_IF_FALSE( isAxis( axis ) ); + m_data->m_tickmarks[ axis ] = std::move( tickmarks ); update(); } -void QskLevelingSensor::setTickmarksLabels(const Qt::Axis axis, TickmarksLabels labels) +void QskLevelingSensor::setTickmarksLabels( const Qt::Axis axis, TickmarksLabels labels ) { - RETURN_IF_FALSE(isAxis(axis)); - m_tickmarksLabels[axis] = std::move(labels); + RETURN_IF_FALSE( isAxis( axis ) ); + m_data->m_tickmarksLabels[ axis ] = std::move( labels ); update(); } -void QskLevelingSensor::setAngle(const QVector3D& degree) +void QskLevelingSensor::setAngle( const QVector3D& degree ) { - if (compareExchange(m_angle, degree)) + if ( compareExchange( m_data->m_angle, degree ) ) { update(); - Q_EMIT anglesChanged(m_angle); + Q_EMIT anglesChanged( m_data->m_angle ); } } -void QskLevelingSensor::setAngle(const Qt::Axis axis, const float degree) +void QskLevelingSensor::setAngle( const Qt::Axis axis, const float degree ) { - RETURN_IF_FALSE(isAxis(axis)); + RETURN_IF_FALSE( isAxis( axis ) ); - if (compareExchange(m_angle[axis], degree)) + if ( compareExchange( m_data->m_angle[ axis ], degree ) ) { update(); - Q_EMIT anglesChanged(m_angle); + Q_EMIT anglesChanged( m_data->m_angle ); } } -const QskScaleTickmarks& QskLevelingSensor::tickmarks(Qt::Axis axis) const +const QskScaleTickmarks& QskLevelingSensor::tickmarks( Qt::Axis axis ) const { - if (isAxis(axis)) + if ( isAxis( axis ) ) { - return m_tickmarks[axis]; + return m_data->m_tickmarks[ axis ]; } static const QskScaleTickmarks invalid; return invalid; } -const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels(Qt::Axis axis) const +const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( Qt::Axis axis ) const { - if (isAxis(axis)) + if ( isAxis( axis ) ) { - return m_tickmarksLabels[axis]; + return m_data->m_tickmarksLabels[ axis ]; } static const QskLevelingSensor::TickmarksLabels invalid; return invalid; @@ -105,48 +124,51 @@ const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels(Qt:: const QVector3D& QskLevelingSensor::angle() const noexcept { - return m_angle; + return m_data->m_angle; } -const QVector3D& QskLevelingSensor::subControlRotation(const QskAspect::Subcontrol subControl) const noexcept +const QVector3D& QskLevelingSensor::subControlRotation( + const QskAspect::Subcontrol subControl ) const noexcept { static const QVector3D notFound; - const auto found = m_subControlRotation.find(subControl); - if(found == m_subControlRotation.end()) { + const auto found = m_data->m_subControlRotation.find( subControl ); + if ( found == m_data->m_subControlRotation.end() ) + { return notFound; } return found->second; } -void QskLevelingSensor::setSubControlRotation(const QskAspect::Subcontrol subControl, const QVector3D& degree) +void QskLevelingSensor::setSubControlRotation( + const QskAspect::Subcontrol subControl, const QVector3D& degree ) { - auto updateSubControlRotation = [this](const QskAspect::Subcontrol subControl, const QVector3D& degree) - { - if ( compareExchange( m_subControlRotation[ subControl ], degree ) ) + auto updateSubControlRotation = [ this ]( const QskAspect::Subcontrol subControl, + const QVector3D& degree ) { + if ( compareExchange( m_data->m_subControlRotation[ subControl ], degree ) ) { - Q_EMIT subControlRotationChanged(subControl, degree); + Q_EMIT subControlRotationChanged( subControl, degree ); update(); } }; - if(subControl == Q::TickmarksX || subControl == Q::TickmarksXLabels) + if ( subControl == Q::TickmarksX || subControl == Q::TickmarksXLabels ) { - updateSubControlRotation(Q::TickmarksX, degree); - updateSubControlRotation(Q::TickmarksXLabels, degree); + updateSubControlRotation( Q::TickmarksX, degree ); + updateSubControlRotation( Q::TickmarksXLabels, degree ); } - else if(subControl == Q::TickmarksY || subControl == Q::TickmarksYLabels) + else if ( subControl == Q::TickmarksY || subControl == Q::TickmarksYLabels ) { - updateSubControlRotation(Q::TickmarksY, degree); - updateSubControlRotation(Q::TickmarksYLabels, degree); + updateSubControlRotation( Q::TickmarksY, degree ); + updateSubControlRotation( Q::TickmarksYLabels, degree ); } - else if(subControl == Q::TickmarksZ || subControl == TickmarksZLabels) + else if ( subControl == Q::TickmarksZ || subControl == TickmarksZLabels ) { - updateSubControlRotation(TickmarksZ, degree); - updateSubControlRotation(TickmarksZLabels, degree); + updateSubControlRotation( TickmarksZ, degree ); + updateSubControlRotation( TickmarksZLabels, degree ); } - else + else { - updateSubControlRotation(subControl, degree); + updateSubControlRotation( subControl, degree ); } } diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/LevelingSensor/QskLevelingSensor.h index 89a05032..2949c8a3 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.h +++ b/src/controls/LevelingSensor/QskLevelingSensor.h @@ -1,55 +1,45 @@ #pragma once #include -#include -#include -#include +#include -#include +class QskScaleTickmarks; class QSK_EXPORT QskLevelingSensor : public QskControl { Q_OBJECT - using Inherited = QskControl; -public: - QSK_SUBCONTROLS( - OuterDisk, - Horizon, - TickmarksX, - TickmarksXLabels, - TickmarksY, - TickmarksYLabels, - TickmarksZ, - TickmarksZLabels) - using Tickmarks = QskScaleTickmarks; - using TickmarksLabels = QVector>; - explicit QskLevelingSensor(QQuickItem* parent = nullptr); -public Q_SLOTS: - void setTickmarks(Qt::Axis axis, Tickmarks tickmarks); - void setTickmarksLabels(Qt::Axis axis, TickmarksLabels labels); - void setAngle(const QVector3D& degree); - void setAngle(Qt::Axis axis, float degree); + using Inherited = QskControl; - void setSubControlRotation(QskAspect::Subcontrol subControl, const QVector3D& degree); + public: + QSK_SUBCONTROLS( OuterDisk, Horizon, TickmarksX, TickmarksXLabels, TickmarksY, TickmarksYLabels, + TickmarksZ, TickmarksZLabels ) -Q_SIGNALS: - void anglesChanged(const QVector3D& degree); - void subControlRotationChanged(QskAspect::Subcontrol subControl, const QVector3D& degree); + using Tickmarks = QskScaleTickmarks; + using TickmarksLabels = QVector< QPair< qreal, QString > >; -public: - Q_REQUIRED_RESULT const Tickmarks& tickmarks(Qt::Axis axis) const; - Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels(Qt::Axis axis) const; + explicit QskLevelingSensor( QQuickItem* parent = nullptr ); + ~QskLevelingSensor(); + + public Q_SLOTS: + void setTickmarks( Qt::Axis axis, Tickmarks tickmarks ); + void setTickmarksLabels( Qt::Axis axis, TickmarksLabels labels ); + void setAngle( const QVector3D& degree ); + void setAngle( Qt::Axis axis, float degree ); + + void setSubControlRotation( QskAspect::Subcontrol subControl, const QVector3D& degree ); + + Q_SIGNALS: + void anglesChanged( const QVector3D& degree ); + void subControlRotationChanged( QskAspect::Subcontrol subControl, const QVector3D& degree ); + + public: + Q_REQUIRED_RESULT const Tickmarks& tickmarks( Qt::Axis axis ) const; + Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels( Qt::Axis axis ) const; Q_REQUIRED_RESULT const QVector3D& angle() const noexcept; - Q_REQUIRED_RESULT const QVector3D& subControlRotation(QskAspect::Subcontrol subControl) const noexcept; + Q_REQUIRED_RESULT const QVector3D& subControlRotation( + QskAspect::Subcontrol subControl ) const noexcept; -private: - - // TODO use pimpl - - QVector3D m_rotation; - QVector3D m_angle = { 45,45,45 }; - Tickmarks m_tickmarks[3]; - TickmarksLabels m_tickmarksLabels[3]; - - std::unordered_map m_subControlRotation; + private: + class PrivateData; + std::unique_ptr< PrivateData > m_data; }; \ No newline at end of file From 4acd03c21beb83c2fa974f82bb097d349e0177b2 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 10:59:03 +0200 Subject: [PATCH 16/42] remove hiding; provide recursive/sequential ensureNodes --- .../QskLevelingSensorSkinlet.cpp | 56 +++++-------------- .../LevelingSensor/QskSGNodeUtility.h | 42 +++++++++++--- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index 0ecd312e..dae31e2f 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -96,6 +96,12 @@ using R = QskLevelingSensorSkinlet::NodeRole; using namespace QskSGNode; +template< typename Root, typename... Children > +inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) +{ + return ensureNodes(root); +} + float QskLevelingSensorSkinlet::outerRadius( const QskSkinnable* const skinnable ) { const auto* const sensor = static_cast< const Q* >( skinnable ); @@ -191,7 +197,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const auto boxBorderColors = sensor->boxBorderColorsHint( subControl ); const auto boxGradient = sensor->gradientHint( subControl ); - auto* const root = ensureNode< QSGTransformNode, QskBoxNode >( node ); + auto* const root = ensureNodes( node ); auto* const bNode = static_cast< QskBoxNode* >( root->firstChild() ); const auto size = outerRadius( sensor ) * sensor->strutSizeHint( Q::OuterDisk ).width(); @@ -230,7 +236,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( gradient.setStops( { { 0.0, gradient.startColor() }, { pY, gradient.startColor() }, { pY, gradient.endColor() }, { 1.0, gradient.endColor() } } ); - auto* const tNode = ensureNode< QSGTransformNode, QskBoxNode >( node ); + auto* const tNode = ensureNodes< QSGTransformNode, QskBoxNode >( node ); auto* const boxNode = static_cast< QskBoxNode* >( tNode->firstChild() ); updateBoxNode( sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient ); @@ -252,7 +258,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const auto r3 = state.r1 * scale.height(); auto* const clipping = - ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); @@ -285,7 +291,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const auto rotation = sensor->subControlRotation( subControl ); auto* const cNode = - ensureNode< RadialClipNode,QSGTransformNode, LinearTickmarksNode>( + ensureNodes< RadialClipNode,QSGTransformNode, LinearTickmarksNode>( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); @@ -316,7 +322,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( state.r2 - state.r1 ) + QVector3D{ (float)state.r1, (float)state.r1, (float)state.r1 }; - auto* const transform = ensureNode< QSGTransformNode, RadialTickmarksNode >( node ); + auto* const transform = ensureNodes< QSGTransformNode, RadialTickmarksNode >( node ); auto* const tickmarksNode = static_cast< RadialTickmarksNode* >( transform->firstChild() ); tickmarksNode->setMaterialProperties( color ); tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), state.r1, r3 ); @@ -336,7 +342,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( const auto translation = state.translation().toVector2D() + QVector2D{0, r3}; auto* const cNode = - ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); @@ -359,7 +365,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( const auto rotation = sensor->subControlRotation( subControl ); const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 ); - auto* const cNode = ensureNode< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); @@ -375,7 +381,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( { const auto subControl = Q::TickmarksZLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - auto* const tNode = ensureNode< QSGTransformNode, RadialTickmarksLabelsNode>( node ); + auto* const tNode = ensureNodes< QSGTransformNode, RadialTickmarksLabelsNode>( node ); auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( subControl ).width() ); lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::ZAxis ), { r3, r3 } ); @@ -391,7 +397,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( const auto cY = center( sensor ).y(); const auto r1 = innerRadius( sensor ); - auto* const clipNode = ensureNode< RadialClipNode >( node ); + auto* const clipNode = ensureNodes< RadialClipNode >( node ); clipNode->setGeometryProperties( r1, cX, cY ); return clipNode; } @@ -401,38 +407,6 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode( { const auto* const sensor = static_cast< const Q* >( skinnable ); - const auto subControl = [ nodeRole, sensor ]() { - switch ( static_cast< R >( nodeRole ) ) - { - case OuterDisk: - return Q::OuterDisk; - case Horizon: - return Q::Horizon; - case HorizonClip: - return Q::Horizon; - case TickmarksX: - return Q::TickmarksX; - case TickmarksXLabels: - return Q::TickmarksXLabels; - case TickmarksY: - return Q::TickmarksY; - case TickmarksYLabels: - return Q::TickmarksYLabels; - case TickmarksZ: - return Q::TickmarksZ; - case TickmarksZLabels: - return Q::TickmarksZLabels; - default: - return QskAspect::NoSubcontrol; - } - }(); - - // use the subcontrol's option hint to hide it (default is visible) - if ( qvariant_cast< bool >( sensor->effectiveSkinHint( subControl | QskAspect::Option ) ) ) - { - return nullptr; - } - switch ( static_cast< R >( nodeRole ) ) { case OuterDisk: diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.h b/src/controls/LevelingSensor/QskSGNodeUtility.h index d70c701b..31ea9c5c 100644 --- a/src/controls/LevelingSensor/QskSGNodeUtility.h +++ b/src/controls/LevelingSensor/QskSGNodeUtility.h @@ -4,13 +4,26 @@ namespace QskSGNode { + enum AppendMode : bool { + Sequential = false, + Recursive = true + }; + namespace detail { - template< typename... Ts > + template< AppendMode Mode, typename... Ts > struct append; template<> - struct append<> + struct append + { + static void nodes( QSGNode* root ) + { + } + }; + + template<> + struct append { static void nodes( QSGNode* root ) { @@ -18,25 +31,36 @@ namespace QskSGNode }; template< typename Child, typename... Children > - struct append< Child, Children... > + struct append< AppendMode::Recursive, Child, Children... > { static void nodes( QSGNode* root ) { auto* const child = new Child; root->appendChildNode( child ); - append< Children... >::nodes( child ); + append< AppendMode::Recursive, Children... >::nodes( child ); + } + }; + + template< typename Child, typename... Children > + struct append< AppendMode::Sequential, Child, Children... > + { + static void nodes( QSGNode* root ) + { + auto* const child = new Child; + root->appendChildNode( child ); + append< AppendMode::Sequential, Children... >::nodes( root ); } }; } - template< typename Root, typename... Children > - inline Q_REQUIRED_RESULT Root* ensureNode( QSGNode* root = nullptr ) + template< AppendMode mode, typename Root, typename... Children > + inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) { if ( root == nullptr ) { - root = new Root; - detail::append< Children... >::nodes( root ); + root = new std::remove_const_t(); + detail::append< mode, Children... >::nodes( root ); } - return static_cast< Root* >( root ); + return static_cast(root); } } \ No newline at end of file From bfc5dab5b1985c805c42c8f4552933a55f967bd1 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 12:36:13 +0200 Subject: [PATCH 17/42] use fold expressiong for ensureNodes --- .../QskLevelingSensorSkinlet.cpp | 2 +- .../LevelingSensor/QskSGNodeUtility.h | 74 ++++++------------- 2 files changed, 24 insertions(+), 52 deletions(-) diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp index dae31e2f..51102fb5 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp @@ -406,7 +406,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const { const auto* const sensor = static_cast< const Q* >( skinnable ); - + switch ( static_cast< R >( nodeRole ) ) { case OuterDisk: diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.h b/src/controls/LevelingSensor/QskSGNodeUtility.h index 31ea9c5c..399e7c84 100644 --- a/src/controls/LevelingSensor/QskSGNodeUtility.h +++ b/src/controls/LevelingSensor/QskSGNodeUtility.h @@ -3,64 +3,36 @@ #include namespace QskSGNode -{ - enum AppendMode : bool { - Sequential = false, - Recursive = true - }; - - namespace detail +{ + enum AppendMode { - template< AppendMode Mode, typename... Ts > - struct append; - - template<> - struct append - { - static void nodes( QSGNode* root ) - { - } - }; - - template<> - struct append - { - static void nodes( QSGNode* root ) - { - } - }; - - template< typename Child, typename... Children > - struct append< AppendMode::Recursive, Child, Children... > - { - static void nodes( QSGNode* root ) - { - auto* const child = new Child; - root->appendChildNode( child ); - append< AppendMode::Recursive, Children... >::nodes( child ); - } - }; - - template< typename Child, typename... Children > - struct append< AppendMode::Sequential, Child, Children... > - { - static void nodes( QSGNode* root ) - { - auto* const child = new Child; - root->appendChildNode( child ); - append< AppendMode::Sequential, Children... >::nodes( root ); - } - }; - } + Sequential, + Recursive + }; template< AppendMode mode, typename Root, typename... Children > inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) { if ( root == nullptr ) { - root = new std::remove_const_t(); - detail::append< mode, Children... >::nodes( root ); + root = new Root; } - return static_cast(root); + + if constexpr ( mode == Recursive ) + { + QSGNode* current = root; + ( + [ & ]( QSGNode* const child ) { + current->appendChildNode( child ); + current = child; + }( new Children ), + ... ); + } + else + { + ( root->appendChildNode( new Children ), ... ); + } + + return static_cast< Root* >( root ); } } \ No newline at end of file From 67b1afd1bda94e73e51e44837ebbd868b465a393 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 13:02:06 +0200 Subject: [PATCH 18/42] introduce private controls directory --- src/CMakeLists.txt | 26 +++++++++++++------ .../{LevelingSensor => }/QskLevelingSensor.h | 0 .../QskLevelingSensorSkinlet.h | 0 .../QskLevelingSensor.cpp | 2 +- .../QskLevelingSensorNodes.h | 0 .../QskLevelingSensorSkinlet.cpp | 4 +-- .../QskLevelingSensorUtility.h | 0 .../QskSGNodeUtility.cpp | 0 .../QskSGNodeUtility.h | 0 9 files changed, 21 insertions(+), 11 deletions(-) rename src/controls/{LevelingSensor => }/QskLevelingSensor.h (100%) rename src/controls/{LevelingSensor => }/QskLevelingSensorSkinlet.h (100%) rename src/controls/{LevelingSensor => private}/QskLevelingSensor.cpp (98%) rename src/controls/{LevelingSensor => private}/QskLevelingSensorNodes.h (100%) rename src/controls/{LevelingSensor => private}/QskLevelingSensorSkinlet.cpp (99%) rename src/controls/{LevelingSensor => private}/QskLevelingSensorUtility.h (100%) rename src/controls/{LevelingSensor => private}/QskSGNodeUtility.cpp (100%) rename src/controls/{LevelingSensor => private}/QskSGNodeUtility.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f43492b7..2adf192d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -423,17 +423,20 @@ list(APPEND SOURCES ) list(APPEND HEADERS - controls/LevelingSensor/QskSGNodeUtility.h - controls/LevelingSensor/QskLevelingSensor.h - controls/LevelingSensor/QskLevelingSensorNodes.h - controls/LevelingSensor/QskLevelingSensorSkinlet.h - controls/LevelingSensor/QskLevelingSensorUtility.h + controls/QskLevelingSensor.h + controls/QskLevelingSensorSkinlet.h +) + +list(APPEND PRIVATE_HEADERS + controls/private/QskSGNodeUtility.h + controls/private/QskLevelingSensorNodes.h + controls/private/QskLevelingSensorUtility.h ) list(APPEND SOURCES - controls/LevelingSensor/QskSGNodeUtility.cpp - controls/LevelingSensor/QskLevelingSensor.cpp - controls/LevelingSensor/QskLevelingSensorSkinlet.cpp + controls/private/QskSGNodeUtility.cpp + controls/private/QskLevelingSensor.cpp + controls/private/QskLevelingSensorSkinlet.cpp ) if(ENABLE_PINYIN) @@ -468,6 +471,9 @@ target_include_directories(${target} PUBLIC $ $) +target_include_directories(${target} PRIVATE + $) + target_link_libraries(${target} PUBLIC Qt::Core Qt::CorePrivate Qt::Quick Qt::QuickPrivate) @@ -495,6 +501,10 @@ set_target_properties(${target} list(TRANSFORM HEADERS PREPEND "${CMAKE_CURRENT_LIST_DIR}/") set_target_properties(${target} PROPERTIES PUBLIC_HEADER "${HEADERS}") + +list(TRANSFORM PRIVATE_HEADERS PREPEND "${CMAKE_CURRENT_LIST_DIR}/") +set_target_properties(${target} PROPERTIES PRIVATE_HEADER "${PRIVATE_HEADERS}") + set_target_properties(${target} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) diff --git a/src/controls/LevelingSensor/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h similarity index 100% rename from src/controls/LevelingSensor/QskLevelingSensor.h rename to src/controls/QskLevelingSensor.h diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.h b/src/controls/QskLevelingSensorSkinlet.h similarity index 100% rename from src/controls/LevelingSensor/QskLevelingSensorSkinlet.h rename to src/controls/QskLevelingSensorSkinlet.h diff --git a/src/controls/LevelingSensor/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp similarity index 98% rename from src/controls/LevelingSensor/QskLevelingSensor.cpp rename to src/controls/private/QskLevelingSensor.cpp index 8c73f0b0..fd4f7bd9 100644 --- a/src/controls/LevelingSensor/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -1,4 +1,4 @@ -#include "QskLevelingSensor.h" +#include #include #include #include diff --git a/src/controls/LevelingSensor/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h similarity index 100% rename from src/controls/LevelingSensor/QskLevelingSensorNodes.h rename to src/controls/private/QskLevelingSensorNodes.h diff --git a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp similarity index 99% rename from src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp rename to src/controls/private/QskLevelingSensorSkinlet.cpp index 51102fb5..c56cdd8e 100644 --- a/src/controls/LevelingSensor/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -1,5 +1,5 @@ -#include "QskLevelingSensorSkinlet.h" -#include "QskLevelingSensor.h" +#include +#include #include "QskLevelingSensorUtility.h" #include "QskLevelingSensorNodes.h" #include "QskSGNodeUtility.h" diff --git a/src/controls/LevelingSensor/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h similarity index 100% rename from src/controls/LevelingSensor/QskLevelingSensorUtility.h rename to src/controls/private/QskLevelingSensorUtility.h diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.cpp b/src/controls/private/QskSGNodeUtility.cpp similarity index 100% rename from src/controls/LevelingSensor/QskSGNodeUtility.cpp rename to src/controls/private/QskSGNodeUtility.cpp diff --git a/src/controls/LevelingSensor/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h similarity index 100% rename from src/controls/LevelingSensor/QskSGNodeUtility.h rename to src/controls/private/QskSGNodeUtility.h From 3d5be899c33476665d62bf324ecc36b5f9da6f78 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 13:05:15 +0200 Subject: [PATCH 19/42] fix playground includes --- playground/levelingsensor/SkinFactory.cpp | 4 ++-- playground/levelingsensor/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/playground/levelingsensor/SkinFactory.cpp b/playground/levelingsensor/SkinFactory.cpp index 12fb02f4..fe23b8e0 100644 --- a/playground/levelingsensor/SkinFactory.cpp +++ b/playground/levelingsensor/SkinFactory.cpp @@ -14,8 +14,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index de61fb25..6a514121 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include From 67f30658fa2a4c2a45ce09bd8bae59213f84cd7d Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 13:40:08 +0200 Subject: [PATCH 20/42] remove PRIVATE_HEADER property --- src/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2adf192d..1062b2f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -502,9 +502,6 @@ set_target_properties(${target} list(TRANSFORM HEADERS PREPEND "${CMAKE_CURRENT_LIST_DIR}/") set_target_properties(${target} PROPERTIES PUBLIC_HEADER "${HEADERS}") -list(TRANSFORM PRIVATE_HEADERS PREPEND "${CMAKE_CURRENT_LIST_DIR}/") -set_target_properties(${target} PROPERTIES PRIVATE_HEADER "${PRIVATE_HEADERS}") - set_target_properties(${target} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) From 33beb90da27e76fb2293c508f1e1d2a3f90e2548 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 13:46:24 +0200 Subject: [PATCH 21/42] reverted private include directory --- src/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1062b2f4..1e776b1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -471,9 +471,6 @@ target_include_directories(${target} PUBLIC $ $) -target_include_directories(${target} PRIVATE - $) - target_link_libraries(${target} PUBLIC Qt::Core Qt::CorePrivate Qt::Quick Qt::QuickPrivate) From 0a70efc7f30d25d07e424cf5cdee22a688ecc7b6 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 14:16:02 +0200 Subject: [PATCH 22/42] remove unused files --- playground/levelingsensor/Dashboard.cpp | 125 ------------------------ playground/levelingsensor/MainWindow.h | 16 --- 2 files changed, 141 deletions(-) delete mode 100644 playground/levelingsensor/Dashboard.cpp delete mode 100644 playground/levelingsensor/MainWindow.h diff --git a/playground/levelingsensor/Dashboard.cpp b/playground/levelingsensor/Dashboard.cpp deleted file mode 100644 index 5d960dff..00000000 --- a/playground/levelingsensor/Dashboard.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * SPDX-License-Identifier: BSD-3-Clause - *****************************************************************************/ - -#include - -#include - -namespace -{ - class DashboardDial : public Dial - { - public: - DashboardDial( const QString& title, QQuickItem* parent = nullptr ) - : Dial( parent ) - { - setPolishOnResize( true ); - m_label = new QskTextLabel( title, this ); - } - - protected: - void updateLayout() override - { - const auto r = layoutRect(); - - const auto hint = m_label->sizeConstraint(); - - const qreal y = r.y() + 0.6 * r.height() - 0.5 * hint.height(); - const qreal x = r.center().x() - 0.5 * hint.width(); - - m_label->setGeometry( x, y, hint.width(), hint.height() ); - } - - private: - QskTextLabel* m_label; - }; - - class RevCounter : public DashboardDial - { - public: - RevCounter( QQuickItem* parent = nullptr ) - : DashboardDial( "x 1000 min^-1", parent ) - { - setMinimum( 145 ); - setMaximum( 305 ); - setValue( 200 ); - - constexpr int labelsCount = 8; - - QVector< QString > labels; - labels.reserve( labelsCount ); - - for ( int i = 0; i < labelsCount; i++ ) - labels += QString::number( i ); - - setTickLabels( labels ); - } - }; - - class SpeedoMeter : public DashboardDial - { - public: - SpeedoMeter( QQuickItem* parent = nullptr ) - : DashboardDial( "km/h", parent ) - { - setMinimum( -215 ); - setMaximum( 35 ); - setValue( -90 ); - - constexpr int labelsCount = 17; - - QVector< QString > labels; - labels.reserve( labelsCount ); - - for ( int i = 0; i < labelsCount; i++ ) - labels.append( QString::number( i * 10 ) ); - - setTickLabels( labels ); - } - - void updateValue() - { - setValue( value() + std::rand() % 3 - 0.95 ); - } - }; - - class FuelGauge : public DashboardDial - { - public: - FuelGauge( QQuickItem* parent = nullptr ) - : DashboardDial( "fuel", parent ) - { - setMinimum( 195 ); - setMaximum( 345 ); - setValue( 330 ); - - setTickLabels( { "0", "", "1/2", "", "1/1" } ); - } - - void updateValue() - { - setValue( 0.99997 * value() ); - } - }; -} - -Dashboard::Dashboard( QQuickItem* parent ) - : QskLinearBox( Qt::Horizontal, parent ) -{ - (void ) new RevCounter( this ); - auto speedometer = new SpeedoMeter( this ); - auto fuelGauge = new FuelGauge( this ); - - setMargins( 10 ); - setSpacing( 10 ); - - auto timer = new QTimer( this ); - - connect( timer, &QTimer::timeout, speedometer, &SpeedoMeter::updateValue ); - connect( timer, &QTimer::timeout, fuelGauge, &FuelGauge::updateValue ); - - timer->setInterval( 16 ); - timer->start(); -} diff --git a/playground/levelingsensor/MainWindow.h b/playground/levelingsensor/MainWindow.h deleted file mode 100644 index f45b6733..00000000 --- a/playground/levelingsensor/MainWindow.h +++ /dev/null @@ -1,16 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * SPDX-License-Identifier: BSD-3-Clause - *****************************************************************************/ - -#pragma once - -#include - -class QQuickItem; - -class MainWindow : public QskWindow -{ - public: - MainWindow(); -}; From 969de1bee4d5b17c7df8edcfc51b556795d43d4d Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 14:56:22 +0200 Subject: [PATCH 23/42] minor refactorings --- src/controls/QskLevelingSensor.h | 13 ++--- src/controls/private/QskLevelingSensor.cpp | 65 +++++++++++----------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/controls/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h index 2949c8a3..84b15fc6 100644 --- a/src/controls/QskLevelingSensor.h +++ b/src/controls/QskLevelingSensor.h @@ -23,21 +23,18 @@ class QSK_EXPORT QskLevelingSensor : public QskControl public Q_SLOTS: void setTickmarks( Qt::Axis axis, Tickmarks tickmarks ); void setTickmarksLabels( Qt::Axis axis, TickmarksLabels labels ); - void setAngle( const QVector3D& degree ); - void setAngle( Qt::Axis axis, float degree ); - - void setSubControlRotation( QskAspect::Subcontrol subControl, const QVector3D& degree ); + void setAngle( const QVector3D& degrees ); + void setSubControlRotation( QskAspect::Subcontrol subControl, const QVector3D& degrees ); Q_SIGNALS: void anglesChanged( const QVector3D& degree ); - void subControlRotationChanged( QskAspect::Subcontrol subControl, const QVector3D& degree ); + void subControlRotationChanged( QskAspect::Subcontrol subControl, const QVector3D& degrees ); public: Q_REQUIRED_RESULT const Tickmarks& tickmarks( Qt::Axis axis ) const; Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels( Qt::Axis axis ) const; - Q_REQUIRED_RESULT const QVector3D& angle() const noexcept; - Q_REQUIRED_RESULT const QVector3D& subControlRotation( - QskAspect::Subcontrol subControl ) const noexcept; + Q_REQUIRED_RESULT const QVector3D& angle() const; + Q_REQUIRED_RESULT const QVector3D& subControlRotation( QskAspect::Subcontrol subControl ) const; private: class PrivateData; diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index fd4f7bd9..7788e838 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -1,6 +1,8 @@ -#include #include +#include #include + +#include #include #include @@ -30,6 +32,17 @@ namespace return false; } + template<> + bool compareExchange< double >( double& dst, const double& src ) + { + if ( !qskFuzzyCompare( dst, src ) ) + { + dst = src; + return true; + } + return false; + } + inline bool isAxis( const Qt::Axis axis ) { return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; @@ -49,8 +62,6 @@ QSK_SUBCONTROL( QskLevelingSensor, TickmarksZLabels ) if ( !( expr ) ) \ return; -using Q = QskLevelingSensor; - class QskLevelingSensor::PrivateData { public: @@ -82,27 +93,16 @@ void QskLevelingSensor::setTickmarksLabels( const Qt::Axis axis, TickmarksLabels update(); } -void QskLevelingSensor::setAngle( const QVector3D& degree ) +void QskLevelingSensor::setAngle( const QVector3D& degrees ) { - if ( compareExchange( m_data->m_angle, degree ) ) + if ( compareExchange( m_data->m_angle, degrees ) ) { update(); Q_EMIT anglesChanged( m_data->m_angle ); } } -void QskLevelingSensor::setAngle( const Qt::Axis axis, const float degree ) -{ - RETURN_IF_FALSE( isAxis( axis ) ); - - if ( compareExchange( m_data->m_angle[ axis ], degree ) ) - { - update(); - Q_EMIT anglesChanged( m_data->m_angle ); - } -} - -const QskScaleTickmarks& QskLevelingSensor::tickmarks( Qt::Axis axis ) const +const QskScaleTickmarks& QskLevelingSensor::tickmarks( const Qt::Axis axis ) const { if ( isAxis( axis ) ) { @@ -112,7 +112,8 @@ const QskScaleTickmarks& QskLevelingSensor::tickmarks( Qt::Axis axis ) const return invalid; } -const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( Qt::Axis axis ) const +const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( + const Qt::Axis axis ) const { if ( isAxis( axis ) ) { @@ -122,13 +123,13 @@ const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( Qt: return invalid; } -const QVector3D& QskLevelingSensor::angle() const noexcept +const QVector3D& QskLevelingSensor::angle() const { return m_data->m_angle; } const QVector3D& QskLevelingSensor::subControlRotation( - const QskAspect::Subcontrol subControl ) const noexcept + const QskAspect::Subcontrol subControl ) const { static const QVector3D notFound; const auto found = m_data->m_subControlRotation.find( subControl ); @@ -140,35 +141,37 @@ const QVector3D& QskLevelingSensor::subControlRotation( } void QskLevelingSensor::setSubControlRotation( - const QskAspect::Subcontrol subControl, const QVector3D& degree ) + const QskAspect::Subcontrol subControl, const QVector3D& degrees ) { auto updateSubControlRotation = [ this ]( const QskAspect::Subcontrol subControl, - const QVector3D& degree ) { - if ( compareExchange( m_data->m_subControlRotation[ subControl ], degree ) ) + const QVector3D& degrees ) { + if ( compareExchange( m_data->m_subControlRotation[ subControl ], degrees ) ) { - Q_EMIT subControlRotationChanged( subControl, degree ); + Q_EMIT subControlRotationChanged( subControl, degrees ); update(); } }; + using Q = QskLevelingSensor; + if ( subControl == Q::TickmarksX || subControl == Q::TickmarksXLabels ) { - updateSubControlRotation( Q::TickmarksX, degree ); - updateSubControlRotation( Q::TickmarksXLabels, degree ); + updateSubControlRotation( Q::TickmarksX, degrees ); + updateSubControlRotation( Q::TickmarksXLabels, degrees ); } else if ( subControl == Q::TickmarksY || subControl == Q::TickmarksYLabels ) { - updateSubControlRotation( Q::TickmarksY, degree ); - updateSubControlRotation( Q::TickmarksYLabels, degree ); + updateSubControlRotation( Q::TickmarksY, degrees ); + updateSubControlRotation( Q::TickmarksYLabels, degrees ); } else if ( subControl == Q::TickmarksZ || subControl == TickmarksZLabels ) { - updateSubControlRotation( TickmarksZ, degree ); - updateSubControlRotation( TickmarksZLabels, degree ); + updateSubControlRotation( TickmarksZ, degrees ); + updateSubControlRotation( TickmarksZLabels, degrees ); } else { - updateSubControlRotation( subControl, degree ); + updateSubControlRotation( subControl, degrees ); } } From f3727a79e134f981380c69f0d1c470427ad7a978 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 15:01:07 +0200 Subject: [PATCH 24/42] removed empty file --- src/CMakeLists.txt | 1 - src/controls/private/QskSGNodeUtility.cpp | 1 - 2 files changed, 2 deletions(-) delete mode 100644 src/controls/private/QskSGNodeUtility.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e776b1d..4b9bdd77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -434,7 +434,6 @@ list(APPEND PRIVATE_HEADERS ) list(APPEND SOURCES - controls/private/QskSGNodeUtility.cpp controls/private/QskLevelingSensor.cpp controls/private/QskLevelingSensorSkinlet.cpp ) diff --git a/src/controls/private/QskSGNodeUtility.cpp b/src/controls/private/QskSGNodeUtility.cpp deleted file mode 100644 index 3955c56e..00000000 --- a/src/controls/private/QskSGNodeUtility.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "QskSGNodeUtility.h" \ No newline at end of file From 7a740142572ec1231c04617c1cbd0dbec446feee Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 25 Jul 2023 15:08:00 +0200 Subject: [PATCH 25/42] clang-format --- playground/levelingsensor/SkinFactory.cpp | 8 +- playground/levelingsensor/main.cpp | 4 +- src/controls/QskLevelingSensorSkinlet.h | 37 ++- src/controls/private/QskLevelingSensorNodes.h | 246 +++++++++--------- .../private/QskLevelingSensorSkinlet.cpp | 64 ++--- .../private/QskLevelingSensorUtility.h | 72 +++-- src/controls/private/QskSGNodeUtility.h | 2 +- 7 files changed, 218 insertions(+), 215 deletions(-) diff --git a/playground/levelingsensor/SkinFactory.cpp b/playground/levelingsensor/SkinFactory.cpp index fe23b8e0..dbf790aa 100644 --- a/playground/levelingsensor/SkinFactory.cpp +++ b/playground/levelingsensor/SkinFactory.cpp @@ -31,11 +31,11 @@ namespace void style( QskSkinHintTableEditor& editor ); template< typename Skinnable, typename Skinlet > - void declareSkinlet( ) + void declareSkinlet() { QskSkin::declareSkinlet< Skinnable, Skinlet >(); } - + template< typename Skinnable, typename Skinlet > void declareSkinlet( QskSkinHintTableEditor& editor ) { @@ -122,7 +122,7 @@ namespace editor.setColor( Q::TickmarksX, Qt::black ); editor.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % editor.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % - editor.setAlignment(Q::TickmarksX, Qt::AlignCenter); + editor.setAlignment( Q::TickmarksX, Qt::AlignCenter ); editor.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % editor.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); @@ -130,7 +130,7 @@ namespace editor.setColor( Q::TickmarksY, Qt::black ); editor.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % editor.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % - editor.setAlignment(Q::TickmarksY, Qt::AlignCenter); + editor.setAlignment( Q::TickmarksY, Qt::AlignCenter ); editor.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % editor.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index 6a514121..63e2bfe1 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -11,12 +11,12 @@ #include #include -#include #include +#include #include +#include #include #include -#include #include #include diff --git a/src/controls/QskLevelingSensorSkinlet.h b/src/controls/QskLevelingSensorSkinlet.h index 625f31f4..c60a5084 100644 --- a/src/controls/QskLevelingSensorSkinlet.h +++ b/src/controls/QskLevelingSensorSkinlet.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include class QskLevelingSensor; @@ -9,9 +9,9 @@ class QSK_EXPORT QskLevelingSensorSkinlet : public QskSkinlet { Q_GADGET - using Inherited = QskSkinlet; + using Inherited = QskSkinlet; -public: + public: enum NodeRole { OuterDisk, @@ -28,26 +28,25 @@ public: RoleCount }; - Q_INVOKABLE QskLevelingSensorSkinlet(QskSkin* skin = nullptr); + Q_INVOKABLE QskLevelingSensorSkinlet( QskSkin* skin = nullptr ); ~QskLevelingSensorSkinlet() override = default; - static Q_REQUIRED_RESULT float outerRadius(const QskSkinnable* const skinnable); - static Q_REQUIRED_RESULT float innerRadius(const QskSkinnable* const skinnable); - static Q_REQUIRED_RESULT QPointF center(const QskSkinnable* const skinnable); + static Q_REQUIRED_RESULT float outerRadius( const QskSkinnable* const skinnable ); + static Q_REQUIRED_RESULT float innerRadius( const QskSkinnable* const skinnable ); + static Q_REQUIRED_RESULT QPointF center( const QskSkinnable* const skinnable ); -protected: + protected: + Q_REQUIRED_RESULT QRectF subControlRect( const QskSkinnable* skinnable, + const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const override; - Q_REQUIRED_RESULT QRectF subControlRect(const QskSkinnable* skinnable, - const QRectF& contentsRect, QskAspect::Subcontrol subControl) const override; + Q_REQUIRED_RESULT QSGNode* updateSubNode( + const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const override; - Q_REQUIRED_RESULT QSGNode* updateSubNode(const QskSkinnable* skinnable, - quint8 nodeRole, QSGNode* node) const override; + template< NodeRole > + Q_REQUIRED_RESULT QRectF subControlRect( + const QskLevelingSensor* sensor, const QRectF& contentsRect ) const; - template - Q_REQUIRED_RESULT QRectF subControlRect(const QskLevelingSensor* sensor, - const QRectF& contentsRect) const; - - template - Q_REQUIRED_RESULT QSGNode* updateSubNode(const QskLevelingSensor* sensor, - quint8 nodeRole, QSGNode* node) const; + template< NodeRole > + Q_REQUIRED_RESULT QSGNode* updateSubNode( + const QskLevelingSensor* sensor, quint8 nodeRole, QSGNode* node ) const; }; diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index 4ded2f7f..d3437a94 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -2,83 +2,85 @@ #include "QskLevelingSensorUtility.h" +#include #include #include -#include #include #include class RadialTickmarksNode final : public QSGGeometryNode { -public: - RadialTickmarksNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + public: + RadialTickmarksNode() + : m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 ) { - m_geometry.setDrawingMode(QSGGeometry::DrawLines); - m_geometry.setVertexDataPattern(QSGGeometry::StaticPattern); + m_geometry.setDrawingMode( QSGGeometry::DrawLines ); + m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern ); - setGeometry(&m_geometry); - setMaterial(&m_material); + setGeometry( &m_geometry ); + setMaterial( &m_material ); } - void setMaterialProperties(const QColor& color) + void setMaterialProperties( const QColor& color ) { - if (m_material.color() != color) + if ( m_material.color() != color ) { - m_material.setColor(color); - markDirty(QSGNode::DirtyMaterial); + m_material.setColor( color ); + markDirty( QSGNode::DirtyMaterial ); } } - void setGeometryProperties(const QskScaleTickmarks& tickmarks, const qreal r1 = 0.0, const QVector3D& r2 = { 0.5, 0.75, 1.0 }, float lineWidth = 1.0) + void setGeometryProperties( const QskScaleTickmarks& tickmarks, const qreal r1 = 0.0, + const QVector3D& r2 = { 0.5, 0.75, 1.0 }, float lineWidth = 1.0 ) { auto dirty = false; - if (dirty |= (m_geometry.lineWidth() != lineWidth)) + if ( dirty |= ( m_geometry.lineWidth() != lineWidth ) ) { - m_geometry.setLineWidth(lineWidth); + m_geometry.setLineWidth( lineWidth ); } - dirty |= compareExchange(m_r1, r1); - dirty |= compareExchange(m_r2, r2); - dirty |= compareExchange(m_tickmarksHash, tickmarks.hash()); + dirty |= compareExchange( m_r1, r1 ); + dirty |= compareExchange( m_r2, r2 ); + dirty |= compareExchange( m_tickmarksHash, tickmarks.hash() ); - if (dirty) + if ( dirty ) { - update(tickmarks); + update( tickmarks ); } } -private: - void update(const QskScaleTickmarks& tickmarks) + private: + void update( const QskScaleTickmarks& tickmarks ) { - if (m_geometry.vertexCount() != tickmarks.tickCount()) + if ( m_geometry.vertexCount() != tickmarks.tickCount() ) { - m_geometry.allocate(tickmarks.tickCount() * 2); + m_geometry.allocate( tickmarks.tickCount() * 2 ); } auto* vertexData = m_geometry.vertexDataAsPoint2D(); using T = QskScaleTickmarks::TickType; - for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + for ( auto type : { T::MinorTick, T::MediumTick, T::MajorTick } ) { - for (const auto tick : tickmarks.ticks(type)) + for ( const auto tick : tickmarks.ticks( type ) ) { - const auto i = static_cast(type); - const auto angleRad = qDegreesToRadians(tick); - const auto x1 = qFastCos(angleRad) * m_r1; - const auto y1 = qFastSin(angleRad) * m_r1; - const auto x2 = qFastCos(angleRad) * m_r2[i]; - const auto y2 = qFastSin(angleRad) * m_r2[i]; + const auto i = static_cast< int >( type ); + const auto angleRad = qDegreesToRadians( tick ); + const auto x1 = qFastCos( angleRad ) * m_r1; + const auto y1 = qFastSin( angleRad ) * m_r1; + const auto x2 = qFastCos( angleRad ) * m_r2[ i ]; + const auto y2 = qFastSin( angleRad ) * m_r2[ i ]; - vertexData[0].set(x1, y1); - vertexData[1].set(x2, y2); + vertexData[ 0 ].set( x1, y1 ); + vertexData[ 1 ].set( x2, y2 ); vertexData += 2; } } m_geometry.markVertexDataDirty(); - markDirty(QSGNode::DirtyGeometry); + markDirty( QSGNode::DirtyGeometry ); } QSGGeometry m_geometry; @@ -90,77 +92,80 @@ private: class LinearTickmarksNode final : public QSGGeometryNode { -public: - LinearTickmarksNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + public: + LinearTickmarksNode() + : m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 ) { - m_geometry.setDrawingMode(QSGGeometry::DrawLines); - m_geometry.setVertexDataPattern(QSGGeometry::StaticPattern); + m_geometry.setDrawingMode( QSGGeometry::DrawLines ); + m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern ); - setGeometry(&m_geometry); - setMaterial(&m_material); + setGeometry( &m_geometry ); + setMaterial( &m_material ); } - void setMaterialProperties(const QColor& color) + void setMaterialProperties( const QColor& color ) { auto dirty = false; - if (dirty |= (m_material.color() != color)) + if ( dirty |= ( m_material.color() != color ) ) { - m_material.setColor(color); + m_material.setColor( color ); } - if (dirty) + if ( dirty ) { - markDirty(QSGNode::DirtyMaterial); + markDirty( QSGNode::DirtyMaterial ); } } - void setGeometryProperties(const QskScaleTickmarks& tickmarks, const QVector3D& tickmarkSize, const QVector2D& scale = { 1.0,0.0f }, const QVector2D& offset = {}, const float lineWidth = 1.0f, const bool forceDirty = false) + void setGeometryProperties( const QskScaleTickmarks& tickmarks, const QVector3D& tickmarkSize, + const QVector2D& scale = { 1.0, 0.0f }, const QVector2D& offset = {}, + const float lineWidth = 1.0f, const bool forceDirty = false ) { auto dirty = forceDirty; - if (dirty |= !qFuzzyCompare(m_geometry.lineWidth(), lineWidth)) + if ( dirty |= !qFuzzyCompare( m_geometry.lineWidth(), lineWidth ) ) { - m_geometry.setLineWidth(lineWidth); + m_geometry.setLineWidth( lineWidth ); } dirty |= m_geometry.vertexCount() != tickmarks.tickCount() * 2; - dirty |= compareExchange(m_tickmarkSize, tickmarkSize); - dirty |= compareExchange(m_scale, scale); - dirty |= compareExchange(m_offset, offset); + dirty |= compareExchange( m_tickmarkSize, tickmarkSize ); + dirty |= compareExchange( m_scale, scale ); + dirty |= compareExchange( m_offset, offset ); - if (dirty) + if ( dirty ) { - update(tickmarks); - markDirty(QSGNode::DirtyGeometry); + update( tickmarks ); + markDirty( QSGNode::DirtyGeometry ); } } -private: - void update(const QskScaleTickmarks& tickmarks) + private: + void update( const QskScaleTickmarks& tickmarks ) { - if (m_geometry.vertexCount() != tickmarks.tickCount() * 2) + if ( m_geometry.vertexCount() != tickmarks.tickCount() * 2 ) { - m_geometry.allocate(tickmarks.tickCount() * 2); + m_geometry.allocate( tickmarks.tickCount() * 2 ); } auto* vertexData = m_geometry.vertexDataAsPoint2D(); using T = QskScaleTickmarks::TickType; - for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + for ( auto type : { T::MinorTick, T::MediumTick, T::MajorTick } ) { - for (const auto tick : tickmarks.ticks(type)) + for ( const auto tick : tickmarks.ticks( type ) ) { - const auto i = static_cast(type); + const auto i = static_cast< int >( type ); const auto p = m_scale * tick; - const auto d = QVector2D(-m_scale.y(), m_scale.x()).normalized(); + const auto d = QVector2D( -m_scale.y(), m_scale.x() ).normalized(); - const auto p1 = m_tickmarkSize[i] * +1 * d + p + m_offset; - const auto p2 = m_tickmarkSize[i] * -1 * d + p + m_offset; + const auto p1 = m_tickmarkSize[ i ] * +1 * d + p + m_offset; + const auto p2 = m_tickmarkSize[ i ] * -1 * d + p + m_offset; - vertexData[0].set(p1.x(), p1.y()); - vertexData[1].set(p2.x(), p2.y()); + vertexData[ 0 ].set( p1.x(), p1.y() ); + vertexData[ 1 ].set( p2.x(), p2.y() ); vertexData += 2; } } @@ -177,53 +182,55 @@ private: class RadialClipNode final : public QSGClipNode { -public: - RadialClipNode() : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0) + public: + RadialClipNode() + : m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 ) { - m_geometry.setVertexDataPattern(QSGGeometry::DynamicPattern); - m_geometry.setDrawingMode(QSGGeometry::DrawTriangleFan); - setGeometry(&m_geometry); - setIsRectangular(false); + m_geometry.setVertexDataPattern( QSGGeometry::DynamicPattern ); + m_geometry.setDrawingMode( QSGGeometry::DrawTriangleFan ); + setGeometry( &m_geometry ); + setIsRectangular( false ); } - void setGeometryProperties(const qreal radius = 1.0, const qreal cx = 0.0, const qreal cy = 0.0, const int count = 360) + void setGeometryProperties( const qreal radius = 1.0, const qreal cx = 0.0, + const qreal cy = 0.0, const int count = 360 ) { auto dirty = false; - dirty |= compareExchange(m_radius, radius); - dirty |= compareExchange(m_cx, cx); - dirty |= compareExchange(m_cy, cy); - dirty |= compareExchange(m_count, count); + dirty |= compareExchange( m_radius, radius ); + dirty |= compareExchange( m_cx, cx ); + dirty |= compareExchange( m_cy, cy ); + dirty |= compareExchange( m_count, count ); - if (dirty) + if ( dirty ) { update(); } } -private: + private: void update() { const auto step = 2.0 * M_PI / m_count; - if (m_geometry.vertexCount() != m_count) + if ( m_geometry.vertexCount() != m_count ) { - m_geometry.allocate(m_count); + m_geometry.allocate( m_count ); } auto* vertices = m_geometry.vertexDataAsPoint2D(); - for (int i = 0; i < m_count; ++i) + for ( int i = 0; i < m_count; ++i ) { - vertices[i].x = qFastCos(i * step) * m_radius + m_cx; - vertices[i].y = qFastSin(i * step) * m_radius + m_cy; + vertices[ i ].x = qFastCos( i * step ) * m_radius + m_cx; + vertices[ i ].y = qFastSin( i * step ) * m_radius + m_cy; } m_geometry.markVertexDataDirty(); - markDirty(QSGNode::DirtyGeometry); + markDirty( QSGNode::DirtyGeometry ); } - using QSGClipNode::setIsRectangular; using QSGClipNode::setClipRect; + using QSGClipNode::setIsRectangular; QSGGeometry m_geometry; qreal m_radius = 1.0; @@ -232,72 +239,75 @@ private: int m_count = 360; }; -template +template< typename CRTP > struct TickmarksLabelsNode : public QSGNode { -public: - QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + public: + QVector2D value( const QVector2D& v, const QVector2D& s, const QVector2D& o ) const { - return static_cast(this)->value(v, s, o); + return static_cast< const CRTP* >( this )->value( v, s, o ); } - void update(const QskSkinnable* const skinnable, const QskAspect::Subcontrol subControl, const QVector>& labels, const QVector2D& scale = { 1.0, 0.0 }, const QVector2D& offset = {}) + void update( const QskSkinnable* const skinnable, const QskAspect::Subcontrol subControl, + const QVector< QPair< double, QString > >& labels, const QVector2D& scale = { 1.0, 0.0 }, + const QVector2D& offset = {} ) { const auto count = labels.count(); - for ( int i = childCount(); i > count; --i ) + for ( int i = childCount(); i > count; --i ) { - removeChildNode(lastChild()); + removeChildNode( lastChild() ); } - for ( int i = childCount(); i < count; ++i ) + for ( int i = childCount(); i < count; ++i ) { - appendChildNode(new QskTextNode); - } + appendChildNode( new QskTextNode ); + } - const QFontMetricsF metrics(skinnable->effectiveFont(subControl)); - const auto h = skinnable->effectiveFontHeight(subControl); - const auto a = skinnable->alignmentHint(subControl); + const QFontMetricsF metrics( skinnable->effectiveFont( subControl ) ); + const auto h = skinnable->effectiveFontHeight( subControl ); + const auto a = skinnable->alignmentHint( subControl ); - auto* textNode = static_cast(firstChild()); - for (const auto& label : qAsConst(labels)) + auto* textNode = static_cast< QskTextNode* >( firstChild() ); + for ( const auto& label : qAsConst( labels ) ) { - const auto v = value({ (float)label.first, (float)label.first }, scale, offset); + const auto v = value( { ( float ) label.first, ( float ) label.first }, scale, offset ); auto x = v.x(); auto y = v.y(); - const auto w = metrics.horizontalAdvance(label.second); + const auto w = metrics.horizontalAdvance( label.second ); - x -= a.testFlag(Qt::AlignRight) ? w : 0; - x -= a.testFlag(Qt::AlignHCenter) ? w / 2 : 0; + x -= a.testFlag( Qt::AlignRight ) ? w : 0; + x -= a.testFlag( Qt::AlignHCenter ) ? w / 2 : 0; - y -= a.testFlag(Qt::AlignBottom) ? h : 0; - y -= a.testFlag(Qt::AlignVCenter) ? h / 2 : 0; + y -= a.testFlag( Qt::AlignBottom ) ? h : 0; + y -= a.testFlag( Qt::AlignVCenter ) ? h / 2 : 0; - QskSkinlet::updateTextNode(skinnable, textNode, { x,y,w,h }, a, label.second, subControl); + QskSkinlet::updateTextNode( + skinnable, textNode, { x, y, w, h }, a, label.second, subControl ); - textNode = static_cast(textNode->nextSibling()); + textNode = static_cast< QskTextNode* >( textNode->nextSibling() ); } } }; -struct LinearTickmarksLabelsNode final : public TickmarksLabelsNode +struct LinearTickmarksLabelsNode final : public TickmarksLabelsNode< LinearTickmarksLabelsNode > { -public: - QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + public: + QVector2D value( const QVector2D& v, const QVector2D& s, const QVector2D& o ) const { return v * s + o; } }; -struct RadialTickmarksLabelsNode final : public TickmarksLabelsNode +struct RadialTickmarksLabelsNode final : public TickmarksLabelsNode< RadialTickmarksLabelsNode > { -public: - QVector2D value(const QVector2D& v, const QVector2D& s, const QVector2D& o) const + public: + QVector2D value( const QVector2D& v, const QVector2D& s, const QVector2D& o ) const { return QVector2D{ - (float)qFastCos(qDegreesToRadians(v.x())), - (float)qFastSin(qDegreesToRadians(v.y())) - } *s + o; + ( float ) qFastCos( qDegreesToRadians( v.x() ) ), + ( float ) qFastSin( qDegreesToRadians( v.y() ) ) + } * s + o; } }; diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index c56cdd8e..4f741a0c 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -1,8 +1,8 @@ -#include -#include -#include "QskLevelingSensorUtility.h" #include "QskLevelingSensorNodes.h" +#include "QskLevelingSensorUtility.h" #include "QskSGNodeUtility.h" +#include +#include #include #include @@ -51,9 +51,9 @@ namespace { } - Q_REQUIRED_RESULT QVector3D scale() const noexcept + Q_REQUIRED_RESULT QVector3D scale() const noexcept { - return {(float)sX, (float)sY, (float)sZ}; + return { ( float ) sX, ( float ) sY, ( float ) sZ }; } }; @@ -78,9 +78,9 @@ namespace { } - Q_REQUIRED_RESULT QVector3D translation() const noexcept + Q_REQUIRED_RESULT QVector3D translation() const noexcept { - return {(float)tX, (float)tY, (float)tZ}; + return { ( float ) tX, ( float ) tY, ( float ) tZ }; } Q_REQUIRED_RESULT QMatrix4x4 matrix() const noexcept @@ -99,7 +99,7 @@ using namespace QskSGNode; template< typename Root, typename... Children > inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) { - return ensureNodes(root); + return ensureNodes< AppendMode::Recursive, Root, Children... >( root ); } float QskLevelingSensorSkinlet::outerRadius( const QskSkinnable* const skinnable ) @@ -189,7 +189,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - const auto subControl = Q::OuterDisk; + const auto subControl = Q::OuterDisk; const auto contentsRect = sensor->contentsRect(); const auto boxRect = subControlRect< OuterDisk >( sensor, contentsRect ); const auto boxShapeMetrics = QskBoxShapeMetrics{ boxRect.width() / 2 }; @@ -197,7 +197,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const auto boxBorderColors = sensor->boxBorderColorsHint( subControl ); const auto boxGradient = sensor->gradientHint( subControl ); - auto* const root = ensureNodes( node ); + auto* const root = ensureNodes< QSGTransformNode, QskBoxNode >( node ); auto* const bNode = static_cast< QskBoxNode* >( root->firstChild() ); const auto size = outerRadius( sensor ) * sensor->strutSizeHint( Q::OuterDisk ).width(); @@ -221,8 +221,8 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::Horizon; - const State state(sensor, subControl); - + const State< QskAspect::Subcontrol > state( sensor, subControl ); + const auto dY = 2 * sensor->angle().y(); const auto pY = qBound( 0.0, 0.5 + ( -state.rX / dY ), 1.0 ); @@ -238,7 +238,8 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( auto* const tNode = ensureNodes< QSGTransformNode, QskBoxNode >( node ); auto* const boxNode = static_cast< QskBoxNode* >( tNode->firstChild() ); - updateBoxNode( sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient ); + updateBoxNode( + sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient ); const auto matrix = matrix_deg( 0, 0, 0, state.cX, state.cY, 0 ) * matrix_deg( 0, 0, 0, -state.r1, -state.r1, 0 ); @@ -252,14 +253,13 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksX; - State state(sensor, subControl); + State< QskAspect::Subcontrol > state( sensor, subControl ); const auto color = sensor->color( subControl ); const auto scale = sensor->strutSizeHint( subControl ); const auto r3 = state.r1 * scale.height(); auto* const clipping = - ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( - node ); + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); @@ -291,8 +291,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const auto rotation = sensor->subControlRotation( subControl ); auto* const cNode = - ensureNodes< RadialClipNode,QSGTransformNode, LinearTickmarksNode>( - node ); + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); @@ -318,9 +317,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( const auto color = sensor->color( subControl ); const auto scale = sensor->strutSizeHint( subControl ); - const auto r3 = - qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( state.r2 - state.r1 ) + - QVector3D{ (float)state.r1, (float)state.r1, (float)state.r1 }; + const auto r3 = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * + ( state.r2 - state.r1 ) + + QVector3D{ ( float ) state.r1, ( float ) state.r1, ( float ) state.r1 }; auto* const transform = ensureNodes< QSGTransformNode, RadialTickmarksNode >( node ); auto* const tickmarksNode = static_cast< RadialTickmarksNode* >( transform->firstChild() ); @@ -338,8 +337,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( { const auto subControl = Q::TickmarksXLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); - const auto translation = state.translation().toVector2D() + QVector2D{0, r3}; + const auto r3 = + static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); + const auto translation = state.translation().toVector2D() + QVector2D{ 0, r3 }; auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); @@ -347,8 +347,8 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); tNode->setMatrix( state.matrix() ); - lNode->update( - sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 }, translation ); + lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), + { state.scale().x(), 0.0 }, translation ); return cNode; } @@ -358,14 +358,16 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( { const auto subControl = Q::TickmarksYLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); + const auto r3 = + static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); const auto scale = sensor->strutSizeHint( subControl ); const auto angles = sensor->angle(); const auto rotation = sensor->subControlRotation( subControl ); const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 ); - auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); @@ -380,9 +382,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { const auto subControl = Q::TickmarksZLabels; - const State< QskAspect::Subcontrol > state( sensor, subControl ); - auto* const tNode = ensureNodes< QSGTransformNode, RadialTickmarksLabelsNode>( node ); - auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); + const State< QskAspect::Subcontrol > state( sensor, subControl ); + auto* const tNode = ensureNodes< QSGTransformNode, RadialTickmarksLabelsNode >( node ); + auto* const lNode = static_cast< RadialTickmarksLabelsNode* >( tNode->firstChild() ); const auto r3 = static_cast< float >( state.r1 * sensor->strutSizeHint( subControl ).width() ); lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::ZAxis ), { r3, r3 } ); tNode->setMatrix( state.matrix() ); @@ -406,7 +408,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const { const auto* const sensor = static_cast< const Q* >( skinnable ); - + switch ( static_cast< R >( nodeRole ) ) { case OuterDisk: diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index df745838..54ec58ad 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -3,45 +3,36 @@ #include #include -#include #include +#include // create a homogenous transformation matrix -inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( - float rX = 0.0f, - float rY = 0.0f, - float rZ = 0.0f, - float tX = 0.0f, - float tY = 0.0f, - float tZ = 0.0f -) +inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rX = 0.0f, float rY = 0.0f, float rZ = 0.0f, + float tX = 0.0f, float tY = 0.0f, float tZ = 0.0f ) { // Convert rotation angles to radians - float rotationX = qDegreesToRadians(rX); - float rotationY = qDegreesToRadians(rY); - float rotationZ = qDegreesToRadians(rZ); + float rotationX = qDegreesToRadians( rX ); + float rotationY = qDegreesToRadians( rY ); + float rotationZ = qDegreesToRadians( rZ ); // Calculate sin and cos of the rotation angles - float cosX = qCos(rotationX); - float sinX = qSin(rotationX); - float cosY = qCos(rotationY); - float sinY = qSin(rotationY); - float cosZ = qCos(rotationZ); - float sinZ = qSin(rotationZ); + float cosX = qCos( rotationX ); + float sinX = qSin( rotationX ); + float cosY = qCos( rotationY ); + float sinY = qSin( rotationY ); + float cosZ = qCos( rotationZ ); + float sinZ = qSin( rotationZ ); // Create the transform matrix - return QMatrix4x4( - cosY * cosZ, sinX * sinY * cosZ - cosX * sinZ, cosX * sinY * cosZ + sinX * sinZ, tX, - cosY * sinZ, sinX * sinY * sinZ + cosX * cosZ, cosX * sinY * sinZ - sinX * cosZ, tY, - -sinY, sinX * cosY, cosX * cosY, tZ, - 0, 0, 0, 1 - ); + return QMatrix4x4( cosY * cosZ, sinX * sinY * cosZ - cosX * sinZ, + cosX * sinY * cosZ + sinX * sinZ, tX, cosY * sinZ, sinX * sinY * sinZ + cosX * cosZ, + cosX * sinY * sinZ - sinX * cosZ, tY, -sinY, sinX * cosY, cosX * cosY, tZ, 0, 0, 0, 1 ); } -template -inline Q_REQUIRED_RESULT bool compareExchange(T& dst, const T& src) +template< typename T > +inline Q_REQUIRED_RESULT bool compareExchange( T& dst, const T& src ) { - if (dst != src) + if ( dst != src ) { dst = src; return true; @@ -50,9 +41,9 @@ inline Q_REQUIRED_RESULT bool compareExchange(T& dst, const T& src) } template<> -inline Q_REQUIRED_RESULT bool compareExchange(float& dst, const float& src) +inline Q_REQUIRED_RESULT bool compareExchange< float >( float& dst, const float& src ) { - if (!qskFuzzyCompare (dst, src)) + if ( !qskFuzzyCompare( dst, src ) ) { dst = src; return true; @@ -61,9 +52,9 @@ inline Q_REQUIRED_RESULT bool compareExchange(float& dst, const float& sr } template<> -inline Q_REQUIRED_RESULT bool compareExchange(qreal& dst, const qreal& src) +inline Q_REQUIRED_RESULT bool compareExchange< qreal >( qreal& dst, const qreal& src ) { - if (!qskFuzzyCompare (dst, src)) + if ( !qskFuzzyCompare( dst, src ) ) { dst = src; return true; @@ -71,25 +62,26 @@ inline Q_REQUIRED_RESULT bool compareExchange(qreal& dst, const qreal& sr return false; } -inline QskScaleTickmarks filtered(const QskScaleTickmarks& tickmarks, const std::function& predicate) +inline QskScaleTickmarks filtered( const QskScaleTickmarks& tickmarks, + const std::function< bool( QskScaleTickmarks::TickType, qreal ) >& predicate ) { QskScaleTickmarks result; - QVector ticks[3]; + QVector< qreal > ticks[ 3 ]; using T = QskScaleTickmarks::TickType; - for (auto type : { T::MinorTick, T::MediumTick, T::MajorTick }) + for ( auto type : { T::MinorTick, T::MediumTick, T::MajorTick } ) { - for (const auto tick : tickmarks.ticks(type)) + for ( const auto tick : tickmarks.ticks( type ) ) { - if (predicate(type, tick)) + if ( predicate( type, tick ) ) { - ticks[type] << tick; + ticks[ type ] << tick; } } } - result.setMinorTicks(ticks[QskScaleTickmarks::MinorTick]); - result.setMediumTicks(ticks[QskScaleTickmarks::MediumTick]); - result.setMajorTicks(ticks[QskScaleTickmarks::MajorTick]); + result.setMinorTicks( ticks[ QskScaleTickmarks::MinorTick ] ); + result.setMediumTicks( ticks[ QskScaleTickmarks::MediumTick ] ); + result.setMajorTicks( ticks[ QskScaleTickmarks::MajorTick ] ); return result; } \ No newline at end of file diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index 399e7c84..12ba5683 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -17,7 +17,7 @@ namespace QskSGNode { root = new Root; } - + if constexpr ( mode == Recursive ) { QSGNode* current = root; From cf890b582403f23f23837bba1c9f524e04eb5187 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 26 Jul 2023 17:39:13 +0200 Subject: [PATCH 26/42] use QTransform; use QskTickmarksNodes --- playground/levelingsensor/main.cpp | 30 ++- src/controls/private/QskLevelingSensorNodes.h | 5 + .../private/QskLevelingSensorSkinlet.cpp | 200 +++++++++++------- .../private/QskLevelingSensorUtility.h | 25 +-- 4 files changed, 162 insertions(+), 98 deletions(-) diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index 63e2bfe1..b2863a1c 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -73,6 +73,23 @@ namespace sensor->setTickmarksLabels( axis, labels ); } + Q_REQUIRED_RESULT QskSlider* makeAngleSlider( const Qt::Axis axis, + QskLevelingSensor* const sensor, double min = 0, double max = 90, QQuickItem* const parent = nullptr) + { + auto* const slider = new QskSlider( Qt::Horizontal, parent ); + slider->setMinimum( min ); + slider->setMaximum( max ); + slider->setValue( sensor->angle()[ axis ] ); + + QObject::connect(slider, &QskSlider::valueChanged, sensor, [axis, sensor](const qreal v){ + auto angles = sensor->angle(); + angles[axis] = v; + sensor->setAngle(angles); + }); + + return slider; + } + Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis, QskLevelingSensor* const sensor, int min, int max, std::function< QskIntervalF( qreal ) > intervalA, @@ -139,13 +156,16 @@ namespace return { 180 - degree, 180 + degree }; }; - ( void ) new QskTextLabel( "Tickmarks X", right ); + ( void ) new QskTextLabel( "Angles XYZ", right ); + (void) makeAngleSlider(Qt::XAxis, sensor, 0, 45, right); + (void) makeAngleSlider(Qt::YAxis, sensor, 0, 45, right); + (void) makeAngleSlider(Qt::ZAxis, sensor, 0, 45, right); + + ( void ) new QskTextLabel( "Tickmarks XXZ", right ); auto* const sliderTickmarksX = makeTickmarksSlider( Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); - ( void ) new QskTextLabel( "Tickmarks Y", right ); auto* const sliderTickmarksY = makeTickmarksSlider( Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right ); - ( void ) new QskTextLabel( "Tickmarks Z", right ); auto* const sliderTickmarksZ = makeTickmarksSlider( Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right ); @@ -161,6 +181,10 @@ namespace ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksZ, right ); ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksZ, right ); ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksZ, right ); + ( void ) new QskTextLabel( "Horizon", right ); + ( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::Horizon, right ); + ( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::Horizon, right ); + ( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::Horizon, right ); sliderTickmarksX->setValue( 15 ); sliderTickmarksY->setValue( 15 ); diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index d3437a94..23f3dbd1 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -2,6 +2,9 @@ #include "QskLevelingSensorUtility.h" +#include +#include + #include #include #include @@ -9,6 +12,8 @@ #include #include +class QskSkinnable; + class RadialTickmarksNode final : public QSGGeometryNode { public: diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 4f741a0c..5001d030 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -23,6 +23,11 @@ #include #include #include +#include + +#include +#include +#include namespace { @@ -51,6 +56,11 @@ namespace { } + Q_REQUIRED_RESULT QVector2D center() const noexcept + { + return { ( float ) cX, ( float ) cY}; + } + Q_REQUIRED_RESULT QVector3D scale() const noexcept { return { ( float ) sX, ( float ) sY, ( float ) sZ }; @@ -76,7 +86,7 @@ namespace , tY( rX * sY ) , tZ( 0.0 ) { - } + } Q_REQUIRED_RESULT QVector3D translation() const noexcept { @@ -85,10 +95,63 @@ namespace Q_REQUIRED_RESULT QMatrix4x4 matrix() const noexcept { - return matrix_deg( 0, 0, rZ, cX, cY ); + return matrix_deg( rZ, cX, cY ); } }; + Q_REQUIRED_RESULT std::optional< std::pair< qreal, qreal > > minmax( + const QVector< qreal >& tickmarks ) + { + if ( tickmarks.empty() ) + { + return {}; + } + + const auto [ pmin, pmax ] = std::minmax_element( tickmarks.begin(), tickmarks.end() ); + return std::make_pair( *pmin, *pmax ); + } + + Q_REQUIRED_RESULT std::optional< std::pair< qreal, qreal > > minmax( + const QskScaleTickmarks& tickmarks ) + { + if ( tickmarks.tickCount() == 0 ) + { + return {}; + } + + const auto majorTicks = tickmarks.majorTicks(); + const auto mediumTicks = tickmarks.mediumTicks(); + const auto minorTicks = tickmarks.minorTicks(); + + const auto item = !majorTicks.empty() ? majorTicks[ 0 ] + : !mediumTicks.empty() ? mediumTicks[ 0 ] + : !minorTicks.empty() ? minorTicks[ 0 ] + : std::numeric_limits< qreal >::quiet_NaN(); + + Q_ASSERT_X( !std::isnan( item ), __func__, "NaN should not be possible!" ); + + std::array< qreal, 6 > local = { item }; + + if ( const auto opt = minmax( tickmarks.majorTicks() ) ) + { + local[ 0 ] = opt->first; + local[ 1 ] = opt->second; + } + if ( const auto opt = minmax( tickmarks.mediumTicks() ) ) + { + local[ 2 ] = opt->first; + local[ 3 ] = opt->second; + } + if ( const auto opt = minmax( tickmarks.minorTicks() ) ) + { + local[ 4 ] = opt->first; + local[ 5 ] = opt->second; + } + + const auto [ pmin, pmax ] = std::minmax_element( local.begin(), local.end() ); + return std::make_pair( *pmin, *pmax ); + } + } using Q = QskLevelingSensor; @@ -208,9 +271,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const auto cY = center( sensor ).y(); const auto rZ = 0.0; - const auto matrix = matrix_deg( 0.0, 0.0, 0.0, cX, cY, 0 ) * - matrix_deg( 0.0, 0.0, rZ, 0, 0, 0 ) * - matrix_deg( 0.0, 0.0, 0.0, -size, -size, 0 ); + const auto matrix = matrix_deg( 0.0, cX, cY ) * + matrix_deg( rZ, 0, 0 ) * + matrix_deg( 0.0, -size, -size ); root->setMatrix( matrix ); return root; @@ -241,71 +304,64 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( updateBoxNode( sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient ); - const auto matrix = matrix_deg( 0, 0, 0, state.cX, state.cY, 0 ) * - matrix_deg( 0, 0, 0, -state.r1, -state.r1, 0 ); + const auto matrix = matrix_deg( 0, state.cX, state.cY ) * matrix_deg( state.rZ, 0, 0 ) * + matrix_deg( 0, -state.r1, -state.r1 ); tNode->setMatrix( matrix ); return tNode; } +Q_REQUIRED_RESULT QSGNode* updateLinearTickmarksNode( + const QskLevelingSensor* const sensor, + const QskAspect::Subcontrol subControl, + const QskScaleTickmarks& tickmarks, + const Qt::Orientation orientation, + QSGNode* const node ) +{ + const auto state = State< QskAspect::Subcontrol >( sensor, subControl ); + const auto color = sensor->color( subControl ); + const auto scale = sensor->strutSizeHint( subControl ); + const auto width = state.r1 * scale.width(); + const auto height = state.r1 * scale.height(); + const auto alignment = sensor->alignmentHint( subControl ); + + const auto opt = minmax( tickmarks ); + const auto min = opt ? opt->first : 0.0; + const auto max = opt ? opt->second : 0.0; + const auto interval = QskIntervalF{min,max}; + + const auto rect = + orientation == Qt::Horizontal + ? QRectF{ QPointF{ min * state.sX, -height }, QPointF{ max * state.sX, +height } } + : QRectF{ QPointF{ -width, min * state.sY }, QPointF{ +width, max * state.sY } }; + + const auto translation = QPointF{state.tX + state.cX, state.tY + state.cY}; + + auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, QskTickmarksNode >( node ); + auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); + auto* const qNode = static_cast< QskTickmarksNode* >( tNode->firstChild() ); + + cNode->setGeometryProperties( state.r1, state.cX, state.cY ); + tNode->setMatrix( matrix_deg( state.rZ, translation.x(), translation.y() )); + qNode->update( color, rect, interval, tickmarks, 1, orientation, alignment ); + + return cNode; +} + template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - const auto subControl = Q::TickmarksX; - State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto color = sensor->color( subControl ); - const auto scale = sensor->strutSizeHint( subControl ); - const auto r3 = state.r1 * scale.height(); - - auto* const clipping = - ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); - auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() ); - auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() ); - - auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3; - - clipping->setGeometryProperties( state.r1, state.cX, state.cY ); - - tickmarks->setMaterialProperties( color ); - tickmarks->setGeometryProperties( sensor->tickmarks( Qt::XAxis ), size, - { state.scale().x(), 0.0f }, state.translation().toVector2D() ); - - const auto matrix = matrix_deg( 0, 0, state.rZ, state.cX, state.cY ); - transform->setMatrix( matrix ); - return clipping; + return updateLinearTickmarksNode( + sensor, Q::TickmarksX, sensor->tickmarks( Qt::XAxis ), Qt::Horizontal, node ); } template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - const auto subControl = Q::TickmarksY; - const State< QskAspect::Subcontrol > state( sensor, subControl ); - - const auto color = sensor->color( subControl ); - const auto scale = sensor->strutSizeHint( subControl ); - - const auto r3 = state.r1 * scale.width(); - - const auto rotation = sensor->subControlRotation( subControl ); - - auto* const cNode = - ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node ); - auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); - auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() ); - - auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3; - - cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - - const auto sY = static_cast< float >( state.r1 / sensor->angle().y() ); - lNode->setMaterialProperties( color ); - lNode->setGeometryProperties( sensor->tickmarks( Qt::YAxis ), size, { 0.0f, state.scale().y() }, - { ( float ) state.tX, ( float ) state.tY } ); - - tNode->setMatrix( state.matrix() ); - return cNode; + return updateLinearTickmarksNode( + sensor, Q::TickmarksY, sensor->tickmarks( Qt::YAxis ), Qt::Vertical, node ); } template<> @@ -326,7 +382,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( tickmarksNode->setMaterialProperties( color ); tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), state.r1, r3 ); - const auto matrix = matrix_deg( 0.0, 0.0, state.rZ, state.cX, state.cY ); + const auto matrix = matrix_deg( state.rZ, state.cX, state.cY ); transform->setMatrix( matrix ); return transform; } @@ -337,18 +393,16 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( { const auto subControl = Q::TickmarksXLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r3 = - static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height() ); - const auto translation = state.translation().toVector2D() + QVector2D{ 0, r3 }; + const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height(); + const auto dX = qFastCos(qDegreesToRadians(90 + state.rZ)) * r3; + const auto dY = qFastSin(qDegreesToRadians(90 + state.rZ)) * r3; - auto* const cNode = - ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - tNode->setMatrix( state.matrix() ); - lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), - { state.scale().x(), 0.0 }, translation ); + tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) ); + lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 } ); return cNode; } @@ -358,22 +412,16 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( { const auto subControl = Q::TickmarksYLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r3 = - static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width() ); + const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width(); + const auto dX = qFastCos(qDegreesToRadians(state.rZ)) * r3; + const auto dY = qFastSin(qDegreesToRadians(state.rZ)) * r3; - const auto scale = sensor->strutSizeHint( subControl ); - const auto angles = sensor->angle(); - const auto rotation = sensor->subControlRotation( subControl ); - const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 ); - - auto* const cNode = - ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - tNode->setMatrix( state.matrix() ); - lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), - { 0.0, state.scale().y() }, translation ); + tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) ); + lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), { 0.0, state.scale().y() } ); return cNode; } diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index 54ec58ad..404092b5 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -2,31 +2,18 @@ #include #include +#include #include #include -// create a homogenous transformation matrix -inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rX = 0.0f, float rY = 0.0f, float rZ = 0.0f, +inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f, float tY = 0.0f, float tZ = 0.0f ) { - // Convert rotation angles to radians - float rotationX = qDegreesToRadians( rX ); - float rotationY = qDegreesToRadians( rY ); - float rotationZ = qDegreesToRadians( rZ ); - - // Calculate sin and cos of the rotation angles - float cosX = qCos( rotationX ); - float sinX = qSin( rotationX ); - float cosY = qCos( rotationY ); - float sinY = qSin( rotationY ); - float cosZ = qCos( rotationZ ); - float sinZ = qSin( rotationZ ); - - // Create the transform matrix - return QMatrix4x4( cosY * cosZ, sinX * sinY * cosZ - cosX * sinZ, - cosX * sinY * cosZ + sinX * sinZ, tX, cosY * sinZ, sinX * sinY * sinZ + cosX * cosZ, - cosX * sinY * sinZ - sinX * cosZ, tY, -sinY, sinX * cosY, cosX * cosY, tZ, 0, 0, 0, 1 ); + QTransform transform; + transform.translate( tX, tY ); + transform.rotate(rZ, Qt::ZAxis); + return transform.toAffine(); } template< typename T > From a7b3b26f20e1c662c35e18a1f8ed92d33e6900d7 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 09:11:01 +0200 Subject: [PATCH 27/42] include guards --- src/controls/QskLevelingSensor.h | 7 +++++-- src/controls/QskLevelingSensorSkinlet.h | 5 ++++- src/controls/private/QskLevelingSensorNodes.h | 5 ++++- src/controls/private/QskLevelingSensorUtility.h | 7 +++++-- src/controls/private/QskSGNodeUtility.h | 7 +++++-- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/controls/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h index 84b15fc6..8aae2eee 100644 --- a/src/controls/QskLevelingSensor.h +++ b/src/controls/QskLevelingSensor.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef QSK_LEVELING_SENSOR_H +#define QSK_LEVELING_SENSOR_H #include #include @@ -39,4 +40,6 @@ class QSK_EXPORT QskLevelingSensor : public QskControl private: class PrivateData; std::unique_ptr< PrivateData > m_data; -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/controls/QskLevelingSensorSkinlet.h b/src/controls/QskLevelingSensorSkinlet.h index c60a5084..9b5f7ba7 100644 --- a/src/controls/QskLevelingSensorSkinlet.h +++ b/src/controls/QskLevelingSensorSkinlet.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef QSK_LEVELING_SENSOR_SKINLET_H +#define QSK_LEVELING_SENSOR_SKINLET_H #include #include @@ -50,3 +51,5 @@ class QSK_EXPORT QskLevelingSensorSkinlet : public QskSkinlet Q_REQUIRED_RESULT QSGNode* updateSubNode( const QskLevelingSensor* sensor, quint8 nodeRole, QSGNode* node ) const; }; + +#endif \ No newline at end of file diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index 23f3dbd1..6fd02425 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef QSK_LEVELING_SENSOR_NODES_H +#define QSK_LEVELING_SENSOR_NODES_H #include "QskLevelingSensorUtility.h" @@ -316,3 +317,5 @@ struct RadialTickmarksLabelsNode final : public TickmarksLabelsNode< RadialTickm } * s + o; } }; + +#endif \ No newline at end of file diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index 404092b5..e51e89cd 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef QSK_LEVELING_SENSOR_UTILITY_H +#define QSK_LEVELING_SENSOR_UTILITY_H #include #include @@ -71,4 +72,6 @@ inline QskScaleTickmarks filtered( const QskScaleTickmarks& tickmarks, result.setMediumTicks( ticks[ QskScaleTickmarks::MediumTick ] ); result.setMajorTicks( ticks[ QskScaleTickmarks::MajorTick ] ); return result; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index 12ba5683..42bdf208 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef QSK_SGNODE_UTILITY_H +#define QSK_SGNODE_UTILITY_H #include @@ -35,4 +36,6 @@ namespace QskSGNode return static_cast< Root* >( root ); } -} \ No newline at end of file +} + +#endif \ No newline at end of file From b618599e6200b0b570a0910f81350f18a9588788 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 09:16:33 +0200 Subject: [PATCH 28/42] return by value --- playground/levelingsensor/main.cpp | 4 ++-- src/controls/QskLevelingSensor.h | 8 ++++---- src/controls/private/QskLevelingSensor.cpp | 16 ++++++++-------- .../private/QskLevelingSensorSkinlet.cpp | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index b2863a1c..2d1f4a6f 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -79,10 +79,10 @@ namespace auto* const slider = new QskSlider( Qt::Horizontal, parent ); slider->setMinimum( min ); slider->setMaximum( max ); - slider->setValue( sensor->angle()[ axis ] ); + slider->setValue( sensor->angles()[ axis ] ); QObject::connect(slider, &QskSlider::valueChanged, sensor, [axis, sensor](const qreal v){ - auto angles = sensor->angle(); + auto angles = sensor->angles(); angles[axis] = v; sensor->setAngle(angles); }); diff --git a/src/controls/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h index 8aae2eee..1d88c957 100644 --- a/src/controls/QskLevelingSensor.h +++ b/src/controls/QskLevelingSensor.h @@ -32,10 +32,10 @@ class QSK_EXPORT QskLevelingSensor : public QskControl void subControlRotationChanged( QskAspect::Subcontrol subControl, const QVector3D& degrees ); public: - Q_REQUIRED_RESULT const Tickmarks& tickmarks( Qt::Axis axis ) const; - Q_REQUIRED_RESULT const TickmarksLabels& tickmarkLabels( Qt::Axis axis ) const; - Q_REQUIRED_RESULT const QVector3D& angle() const; - Q_REQUIRED_RESULT const QVector3D& subControlRotation( QskAspect::Subcontrol subControl ) const; + Q_REQUIRED_RESULT Tickmarks tickmarks( Qt::Axis axis ) const; + Q_REQUIRED_RESULT TickmarksLabels tickmarkLabels( Qt::Axis axis ) const; + Q_REQUIRED_RESULT QVector3D angles() const; + Q_REQUIRED_RESULT QVector3D subControlRotation( QskAspect::Subcontrol subControl ) const; private: class PrivateData; diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index 7788e838..4514c9f6 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -65,7 +65,7 @@ QSK_SUBCONTROL( QskLevelingSensor, TickmarksZLabels ) class QskLevelingSensor::PrivateData { public: - QVector3D m_angle = { 45, 45, 45 }; + QVector3D m_angles = { 45, 45, 45 }; Tickmarks m_tickmarks[ 3 ]; TickmarksLabels m_tickmarksLabels[ 3 ]; std::unordered_map< QskAspect::Subcontrol, QVector3D > m_subControlRotation; @@ -95,14 +95,14 @@ void QskLevelingSensor::setTickmarksLabels( const Qt::Axis axis, TickmarksLabels void QskLevelingSensor::setAngle( const QVector3D& degrees ) { - if ( compareExchange( m_data->m_angle, degrees ) ) + if ( compareExchange( m_data->m_angles, degrees ) ) { update(); - Q_EMIT anglesChanged( m_data->m_angle ); + Q_EMIT anglesChanged( m_data->m_angles ); } } -const QskScaleTickmarks& QskLevelingSensor::tickmarks( const Qt::Axis axis ) const +QskScaleTickmarks QskLevelingSensor::tickmarks( const Qt::Axis axis ) const { if ( isAxis( axis ) ) { @@ -112,7 +112,7 @@ const QskScaleTickmarks& QskLevelingSensor::tickmarks( const Qt::Axis axis ) con return invalid; } -const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( +QskLevelingSensor::TickmarksLabels QskLevelingSensor::tickmarkLabels( const Qt::Axis axis ) const { if ( isAxis( axis ) ) @@ -123,12 +123,12 @@ const QskLevelingSensor::TickmarksLabels& QskLevelingSensor::tickmarkLabels( return invalid; } -const QVector3D& QskLevelingSensor::angle() const +QVector3D QskLevelingSensor::angles() const { - return m_data->m_angle; + return m_data->m_angles; } -const QVector3D& QskLevelingSensor::subControlRotation( +QVector3D QskLevelingSensor::subControlRotation( const QskAspect::Subcontrol subControl ) const { static const QVector3D notFound; diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 5001d030..457ff503 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -50,9 +50,9 @@ namespace , r2( QskLevelingSensorSkinlet::outerRadius( sensor ) ) , cX( QskLevelingSensorSkinlet::center( sensor ).x() ) , cY( QskLevelingSensorSkinlet::center( sensor ).y() ) - , sX( r1 / sensor->angle().x() ) - , sY( r1 / sensor->angle().y() ) - , sZ( r1 / sensor->angle().z() ) + , sX( r1 / sensor->angles().x() ) + , sY( r1 / sensor->angles().y() ) + , sZ( r1 / sensor->angles().z() ) { } @@ -286,7 +286,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( const auto subControl = Q::Horizon; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto dY = 2 * sensor->angle().y(); + const auto dY = 2 * sensor->angles().y(); const auto pY = qBound( 0.0, 0.5 + ( -state.rX / dY ), 1.0 ); const auto shape = QskBoxShapeMetrics{ state.r1 }; From 667c1d8b0d55d199ea832a7e63b11ed851bd2233 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 09:47:30 +0200 Subject: [PATCH 29/42] remove deprecated toAffine --- src/controls/private/QskLevelingSensorSkinlet.cpp | 1 - src/controls/private/QskLevelingSensorUtility.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 457ff503..d824f462 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index e51e89cd..3b4b89d5 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -14,7 +14,7 @@ inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, QTransform transform; transform.translate( tX, tY ); transform.rotate(rZ, Qt::ZAxis); - return transform.toAffine(); + return transform; } template< typename T > From 4dfbcc00ed9d516db670f2f077405db9fa9effcd Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 10:07:52 +0200 Subject: [PATCH 30/42] add missing include --- src/controls/private/QskLevelingSensorNodes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index 6fd02425..ff58db24 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -5,6 +5,7 @@ #include #include +#include #include #include From bfb7f633dad3fb9c0d9e9299a2998a2cdb5ba4f6 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 10:36:01 +0200 Subject: [PATCH 31/42] add missing include --- src/controls/private/QskLevelingSensorNodes.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index ff58db24..76bd8db1 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -14,8 +15,6 @@ #include #include -class QskSkinnable; - class RadialTickmarksNode final : public QSGGeometryNode { public: From a8736be3cd71dcc4647dfd87827daf59ff7ef0fc Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 11:54:16 +0200 Subject: [PATCH 32/42] remove unused variables and functions --- src/controls/private/QskLevelingSensor.cpp | 11 ----------- src/controls/private/QskLevelingSensorSkinlet.cpp | 12 ++++++++++++ src/controls/private/QskLevelingSensorUtility.h | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index 4514c9f6..dec03f26 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -32,17 +32,6 @@ namespace return false; } - template<> - bool compareExchange< double >( double& dst, const double& src ) - { - if ( !qskFuzzyCompare( dst, src ) ) - { - dst = src; - return true; - } - return false; - } - inline bool isAxis( const Qt::Axis axis ) { return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index d824f462..77d0b53c 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -220,6 +220,7 @@ template<> Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect< R::Horizon >( const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const { + Q_UNUSED(contentsRect) const auto scale = sensor->strutSizeHint( Q::Horizon ); const auto width = 2 * innerRadius( sensor ) * scale.width(); const auto height = width; @@ -251,6 +252,8 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) + const auto subControl = Q::OuterDisk; const auto contentsRect = sensor->contentsRect(); const auto boxRect = subControlRect< OuterDisk >( sensor, contentsRect ); @@ -282,6 +285,8 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) + const auto subControl = Q::Horizon; const State< QskAspect::Subcontrol > state( sensor, subControl ); @@ -351,6 +356,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) return updateLinearTickmarksNode( sensor, Q::TickmarksX, sensor->tickmarks( Qt::XAxis ), Qt::Horizontal, node ); } @@ -359,6 +365,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) return updateLinearTickmarksNode( sensor, Q::TickmarksY, sensor->tickmarks( Qt::YAxis ), Qt::Vertical, node ); } @@ -367,6 +374,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) const auto subControl = Q::TickmarksZ; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto color = sensor->color( subControl ); @@ -390,6 +398,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) const auto subControl = Q::TickmarksXLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height(); @@ -409,6 +418,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) const auto subControl = Q::TickmarksYLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width(); @@ -428,6 +438,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) const auto subControl = Q::TickmarksZLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); auto* const tNode = ensureNodes< QSGTransformNode, RadialTickmarksLabelsNode >( node ); @@ -442,6 +453,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { + Q_UNUSED(nodeRole) const auto cX = center( sensor ).x(); const auto cY = center( sensor ).y(); const auto r1 = innerRadius( sensor ); diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index 3b4b89d5..bee11064 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -8,8 +8,7 @@ #include #include -inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, - float tX = 0.0f, float tY = 0.0f, float tZ = 0.0f ) +inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f, float tY = 0.0f ) { QTransform transform; transform.translate( tX, tY ); From 4e126156a2bdf7f2f912fb4443f7b43c87def5e6 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 12:10:30 +0200 Subject: [PATCH 33/42] add fuzzy vector compare --- src/controls/private/QskLevelingSensor.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index dec03f26..56a61a3e 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -32,6 +32,17 @@ namespace return false; } + template<> + bool compareExchange< QVector3D >( QVector3D& dst, const QVector3D& src ) + { + auto dirty = false; + dirty |= compareExchange(dst[Qt::XAxis], src[Qt::XAxis]); + dirty |= compareExchange(dst[Qt::YAxis], src[Qt::YAxis]); + dirty |= compareExchange(dst[Qt::ZAxis], src[Qt::ZAxis]); + return dirty; + } + + inline bool isAxis( const Qt::Axis axis ) { return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; From 6542c061c984c69f9773000f6832e4a97c2a98cf Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 15:13:17 +0200 Subject: [PATCH 34/42] fix compiler errors --- src/controls/QskLevelingSensor.h | 3 +-- src/controls/private/QskLevelingSensorNodes.h | 6 ++++-- src/controls/private/QskLevelingSensorSkinlet.cpp | 9 --------- src/controls/private/QskSGNodeUtility.h | 3 +-- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/controls/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h index 1d88c957..59fcc29a 100644 --- a/src/controls/QskLevelingSensor.h +++ b/src/controls/QskLevelingSensor.h @@ -2,10 +2,9 @@ #define QSK_LEVELING_SENSOR_H #include +#include #include -class QskScaleTickmarks; - class QSK_EXPORT QskLevelingSensor : public QskControl { Q_OBJECT diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index 76bd8db1..418f5044 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -3,10 +3,12 @@ #include "QskLevelingSensorUtility.h" -#include #include -#include +#include +#include #include +#include +#include #include #include diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 77d0b53c..88acaf5c 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -199,10 +199,6 @@ QskLevelingSensorSkinlet::QskLevelingSensorSkinlet( QskSkin* skin ) } ); } -template< QskLevelingSensorSkinlet::NodeRole > -Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect( - const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const = delete; - template<> Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect< R::OuterDisk >( const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const @@ -244,10 +240,6 @@ QRectF QskLevelingSensorSkinlet::subControlRect( const QskSkinnable* skinnable, return Inherited::subControlRect( skinnable, contentsRect, subControl ); } -template< QskLevelingSensorSkinlet::NodeRole > -QSGNode* QskLevelingSensorSkinlet::updateSubNode( const QskLevelingSensor* const sensor, - const quint8 nodeRole, QSGNode* const node ) const = delete; - template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const @@ -378,7 +370,6 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( const auto subControl = Q::TickmarksZ; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto color = sensor->color( subControl ); - const auto scale = sensor->strutSizeHint( subControl ); const auto r3 = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * ( state.r2 - state.r1 ) + diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index 42bdf208..ab7abe42 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -21,9 +21,8 @@ namespace QskSGNode if constexpr ( mode == Recursive ) { - QSGNode* current = root; ( - [ & ]( QSGNode* const child ) { + [ current = root ]( QSGNode* const child ) mutable { current->appendChildNode( child ); current = child; }( new Children ), From e5c0e7ea725caac399e100a2dc2c9e19cc6a783d Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Wed, 2 Aug 2023 17:07:44 +0200 Subject: [PATCH 35/42] fix more gcc compiler errors --- playground/levelingsensor/SkinFactory.cpp | 200 +++++++++++----------- playground/levelingsensor/main.cpp | 2 +- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/playground/levelingsensor/SkinFactory.cpp b/playground/levelingsensor/SkinFactory.cpp index dbf790aa..04fbf08b 100644 --- a/playground/levelingsensor/SkinFactory.cpp +++ b/playground/levelingsensor/SkinFactory.cpp @@ -43,106 +43,6 @@ namespace style< Skinnable >( editor ); } - template<> - void style< QskSlider >( QskSkinHintTableEditor& editor ) - { - using A = QskAspect; - using Q = QskSlider; - - const qreal extent = 40; - - // Panel - - for ( auto variation : { A::Horizontal, A::Vertical } ) - { - const auto aspect = Q::Panel | variation; - - editor.setMetric( aspect | A::Size, extent ); - editor.setBoxBorderMetrics( aspect, 0 ); - editor.setBoxShape( aspect, 0 ); - editor.setGradient( aspect, QskGradient() ); - } - - // Groove, Fill - - for ( auto variation : { A::Horizontal, A::Vertical } ) - { - for ( auto subControl : { Q::Groove, Q::Fill } ) - { - const auto aspect = subControl | variation; - - editor.setMetric( aspect | A::Size, 0.3 * extent ); - - editor.setBoxBorderMetrics( aspect, 0 ); - editor.setBoxShape( aspect, 0.1 * extent ); - } - - editor.setGradient( Q::Groove | variation, Qt::lightGray ); - editor.setGradient( Q::Fill | variation, Qt::darkGray ); - } - - // Handle - - for ( auto variation : { A::Horizontal, A::Vertical } ) - { - const auto aspect = Q::Handle | variation; - editor.setColor( aspect, Qt::black ); - - editor.setBoxShape( aspect, 20.0, Qt::RelativeSize ); - - const qreal sz = 0.75 * extent; - editor.setStrutSize( aspect, sz, sz ); - } - } - - template<> - void style< QskLevelingSensor >( QskSkinHintTableEditor& editor ) - { - using Q = QskLevelingSensor; - - static constexpr auto r1 = 0.9; - static constexpr auto r2 = 1.0; - - QskGradient gradient{ { - { 0.5, Qt::lightGray }, - { 0.5, Qt::lightGray }, - { 0.5, Qt::darkGray }, - { 1.0, Qt::darkGray }, - } }; - gradient.setLinearDirection( Qt::Vertical ); - - editor.setColor( Q::Background, "dimgray" ); - - editor.setStrutSize( Q::OuterDisk, { r2, r2 } ); - editor.setColor( Q::OuterDisk, Qt::white ); - - editor.setGradient( Q::Horizon, gradient ); - editor.setStrutSize( Q::Horizon, { r1, r1 } ); - - editor.setColor( Q::TickmarksX, Qt::black ); - editor.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % - editor.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % - editor.setAlignment( Q::TickmarksX, Qt::AlignCenter ); - - editor.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % - editor.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); - - editor.setColor( Q::TickmarksY, Qt::black ); - editor.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % - editor.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % - editor.setAlignment( Q::TickmarksY, Qt::AlignCenter ); - - editor.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % - editor.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); - - editor.setColor( Q::TickmarksZ, "silver" ); - editor.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } ); - editor.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // % - - editor.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 % - editor.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter ); - } - public: Skin() { @@ -152,6 +52,106 @@ namespace declareSkinlet< QskLevelingSensor, QskLevelingSensorSkinlet >( editor ); } }; + + template<> + void Skin::style< QskSlider >( QskSkinHintTableEditor& editor ) + { + using A = QskAspect; + using Q = QskSlider; + + const qreal extent = 40; + + // Panel + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + const auto aspect = Q::Panel | variation; + + editor.setMetric( aspect | A::Size, extent ); + editor.setBoxBorderMetrics( aspect, 0 ); + editor.setBoxShape( aspect, 0 ); + editor.setGradient( aspect, QskGradient() ); + } + + // Groove, Fill + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + for ( auto subControl : { Q::Groove, Q::Fill } ) + { + const auto aspect = subControl | variation; + + editor.setMetric( aspect | A::Size, 0.3 * extent ); + + editor.setBoxBorderMetrics( aspect, 0 ); + editor.setBoxShape( aspect, 0.1 * extent ); + } + + editor.setGradient( Q::Groove | variation, Qt::lightGray ); + editor.setGradient( Q::Fill | variation, Qt::darkGray ); + } + + // Handle + + for ( auto variation : { A::Horizontal, A::Vertical } ) + { + const auto aspect = Q::Handle | variation; + editor.setColor( aspect, Qt::black ); + + editor.setBoxShape( aspect, 20.0, Qt::RelativeSize ); + + const qreal sz = 0.75 * extent; + editor.setStrutSize( aspect, sz, sz ); + } + } + + template<> + void Skin::style< QskLevelingSensor >( QskSkinHintTableEditor& editor ) + { + using Q = QskLevelingSensor; + + static constexpr auto r1 = 0.9; + static constexpr auto r2 = 1.0; + + QskGradient gradient{ { + { 0.5, Qt::lightGray }, + { 0.5, Qt::lightGray }, + { 0.5, Qt::darkGray }, + { 1.0, Qt::darkGray }, + } }; + gradient.setLinearDirection( Qt::Vertical ); + + editor.setColor( Q::Background, "dimgray" ); + + editor.setStrutSize( Q::OuterDisk, { r2, r2 } ); + editor.setColor( Q::OuterDisk, Qt::white ); + + editor.setGradient( Q::Horizon, gradient ); + editor.setStrutSize( Q::Horizon, { r1, r1 } ); + + editor.setColor( Q::TickmarksX, Qt::black ); + editor.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h % + editor.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // % + editor.setAlignment( Q::TickmarksX, Qt::AlignCenter ); + + editor.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h % + editor.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter ); + + editor.setColor( Q::TickmarksY, Qt::black ); + editor.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h % + editor.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // % + editor.setAlignment( Q::TickmarksY, Qt::AlignCenter ); + + editor.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h % + editor.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter ); + + editor.setColor( Q::TickmarksZ, "silver" ); + editor.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } ); + editor.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // % + + editor.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 % + editor.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter ); + } } QStringList SkinFactory::skinNames() const diff --git a/playground/levelingsensor/main.cpp b/playground/levelingsensor/main.cpp index 2d1f4a6f..0182edf1 100644 --- a/playground/levelingsensor/main.cpp +++ b/playground/levelingsensor/main.cpp @@ -147,7 +147,7 @@ namespace auto linearIntervalA = []( const qreal degree ) -> QskIntervalF { return { -degree, +degree }; }; - auto linearIntervalB = []( const qreal degree ) -> QskIntervalF { return {}; }; + auto linearIntervalB = []( const qreal /*degree*/ ) -> QskIntervalF { return {}; }; auto radialIntervalA = []( const qreal degree ) -> QskIntervalF { return { -degree, +degree }; From 34f7bac935ddb5596fad63770a33ee52982f7318 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 09:57:35 +0200 Subject: [PATCH 36/42] add copyrights --- src/controls/QskLevelingSensor.h | 5 +++++ src/controls/QskLevelingSensorSkinlet.h | 11 ++++++++--- src/controls/private/QskLevelingSensor.cpp | 5 +++++ src/controls/private/QskLevelingSensorNodes.h | 5 +++++ src/controls/private/QskLevelingSensorSkinlet.cpp | 7 ++++++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/controls/QskLevelingSensor.h b/src/controls/QskLevelingSensor.h index 59fcc29a..7ac11653 100644 --- a/src/controls/QskLevelingSensor.h +++ b/src/controls/QskLevelingSensor.h @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #ifndef QSK_LEVELING_SENSOR_H #define QSK_LEVELING_SENSOR_H diff --git a/src/controls/QskLevelingSensorSkinlet.h b/src/controls/QskLevelingSensorSkinlet.h index 9b5f7ba7..2b53c0d7 100644 --- a/src/controls/QskLevelingSensorSkinlet.h +++ b/src/controls/QskLevelingSensorSkinlet.h @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #ifndef QSK_LEVELING_SENSOR_SKINLET_H #define QSK_LEVELING_SENSOR_SKINLET_H @@ -32,9 +37,9 @@ class QSK_EXPORT QskLevelingSensorSkinlet : public QskSkinlet Q_INVOKABLE QskLevelingSensorSkinlet( QskSkin* skin = nullptr ); ~QskLevelingSensorSkinlet() override = default; - static Q_REQUIRED_RESULT float outerRadius( const QskSkinnable* const skinnable ); - static Q_REQUIRED_RESULT float innerRadius( const QskSkinnable* const skinnable ); - static Q_REQUIRED_RESULT QPointF center( const QskSkinnable* const skinnable ); + Q_REQUIRED_RESULT static float outerRadius( const QskSkinnable* const skinnable ); + Q_REQUIRED_RESULT static float innerRadius( const QskSkinnable* const skinnable ); + Q_REQUIRED_RESULT static QPointF center( const QskSkinnable* const skinnable ); protected: Q_REQUIRED_RESULT QRectF subControlRect( const QskSkinnable* skinnable, diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index 56a61a3e..e201b4d9 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #include #include #include diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index 418f5044..f5dec598 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #ifndef QSK_LEVELING_SENSOR_NODES_H #define QSK_LEVELING_SENSOR_NODES_H diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 88acaf5c..12d1258c 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #include "QskLevelingSensorNodes.h" #include "QskLevelingSensorUtility.h" #include "QskSGNodeUtility.h" @@ -159,7 +164,7 @@ using R = QskLevelingSensorSkinlet::NodeRole; using namespace QskSGNode; template< typename Root, typename... Children > -inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) +Q_REQUIRED_RESULT inline Root* ensureNodes( QSGNode* root = nullptr ) { return ensureNodes< AppendMode::Recursive, Root, Children... >( root ); } From acd25223c0775165e5767315bbeba2c1f7ee4828 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 10:20:34 +0200 Subject: [PATCH 37/42] fix inline nodiscard for clang --- src/controls/private/QskLevelingSensorUtility.h | 15 ++++++++++----- src/controls/private/QskSGNodeUtility.h | 7 ++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index bee11064..fae0f581 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #ifndef QSK_LEVELING_SENSOR_UTILITY_H #define QSK_LEVELING_SENSOR_UTILITY_H @@ -8,7 +13,7 @@ #include #include -inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f, float tY = 0.0f ) +Q_REQUIRED_RESULT inline QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f, float tY = 0.0f ) { QTransform transform; transform.translate( tX, tY ); @@ -17,7 +22,7 @@ inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f } template< typename T > -inline Q_REQUIRED_RESULT bool compareExchange( T& dst, const T& src ) +Q_REQUIRED_RESULT inline bool compareExchange( T& dst, const T& src ) { if ( dst != src ) { @@ -28,7 +33,7 @@ inline Q_REQUIRED_RESULT bool compareExchange( T& dst, const T& src ) } template<> -inline Q_REQUIRED_RESULT bool compareExchange< float >( float& dst, const float& src ) +Q_REQUIRED_RESULT inline bool compareExchange< float >( float& dst, const float& src ) { if ( !qskFuzzyCompare( dst, src ) ) { @@ -39,7 +44,7 @@ inline Q_REQUIRED_RESULT bool compareExchange< float >( float& dst, const float& } template<> -inline Q_REQUIRED_RESULT bool compareExchange< qreal >( qreal& dst, const qreal& src ) +Q_REQUIRED_RESULT inline bool compareExchange< qreal >( qreal& dst, const qreal& src ) { if ( !qskFuzzyCompare( dst, src ) ) { @@ -49,7 +54,7 @@ inline Q_REQUIRED_RESULT bool compareExchange< qreal >( qreal& dst, const qreal& return false; } -inline QskScaleTickmarks filtered( const QskScaleTickmarks& tickmarks, +Q_REQUIRED_RESULT inline QskScaleTickmarks filtered( const QskScaleTickmarks& tickmarks, const std::function< bool( QskScaleTickmarks::TickType, qreal ) >& predicate ) { QskScaleTickmarks result; diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index ab7abe42..fbcfd256 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -1,3 +1,8 @@ +/****************************************************************************** + * QSkinny - Copyright (C) 2016 Uwe Rathmann + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + #ifndef QSK_SGNODE_UTILITY_H #define QSK_SGNODE_UTILITY_H @@ -12,7 +17,7 @@ namespace QskSGNode }; template< AppendMode mode, typename Root, typename... Children > - inline Q_REQUIRED_RESULT Root* ensureNodes( QSGNode* root = nullptr ) + Q_REQUIRED_RESULT inline Root* ensureNodes( QSGNode* root = nullptr ) { if ( root == nullptr ) { From 00d98fd1d0747f07534b10d7eac49c6a2994d2a6 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 11:39:38 +0200 Subject: [PATCH 38/42] move make_unique; remove static constants --- src/controls/private/QskLevelingSensor.cpp | 37 ++++++---------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index e201b4d9..342c120c 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -41,13 +41,12 @@ namespace bool compareExchange< QVector3D >( QVector3D& dst, const QVector3D& src ) { auto dirty = false; - dirty |= compareExchange(dst[Qt::XAxis], src[Qt::XAxis]); - dirty |= compareExchange(dst[Qt::YAxis], src[Qt::YAxis]); - dirty |= compareExchange(dst[Qt::ZAxis], src[Qt::ZAxis]); + dirty |= compareExchange( dst[ Qt::XAxis ], src[ Qt::XAxis ] ); + dirty |= compareExchange( dst[ Qt::YAxis ], src[ Qt::YAxis ] ); + dirty |= compareExchange( dst[ Qt::ZAxis ], src[ Qt::ZAxis ] ); return dirty; } - inline bool isAxis( const Qt::Axis axis ) { return axis == Qt::XAxis || axis == Qt::YAxis || axis == Qt::ZAxis; @@ -78,7 +77,7 @@ class QskLevelingSensor::PrivateData QskLevelingSensor::QskLevelingSensor( QQuickItem* const parent ) : Inherited( parent ) - , m_data( std::make_unique< QskLevelingSensor::PrivateData >() ) + , m_data( new QskLevelingSensor::PrivateData ) { } @@ -109,23 +108,13 @@ void QskLevelingSensor::setAngle( const QVector3D& degrees ) QskScaleTickmarks QskLevelingSensor::tickmarks( const Qt::Axis axis ) const { - if ( isAxis( axis ) ) - { - return m_data->m_tickmarks[ axis ]; - } - static const QskScaleTickmarks invalid; - return invalid; + return isAxis( axis ) ? m_data->m_tickmarks[ axis ] : QskScaleTickmarks{}; } -QskLevelingSensor::TickmarksLabels QskLevelingSensor::tickmarkLabels( - const Qt::Axis axis ) const +QskLevelingSensor::TickmarksLabels QskLevelingSensor::tickmarkLabels( const Qt::Axis axis ) const { - if ( isAxis( axis ) ) - { - return m_data->m_tickmarksLabels[ axis ]; - } - static const QskLevelingSensor::TickmarksLabels invalid; - return invalid; + return isAxis( axis ) ? m_data->m_tickmarksLabels[ axis ] + : QskLevelingSensor::TickmarksLabels{}; } QVector3D QskLevelingSensor::angles() const @@ -133,16 +122,10 @@ QVector3D QskLevelingSensor::angles() const return m_data->m_angles; } -QVector3D QskLevelingSensor::subControlRotation( - const QskAspect::Subcontrol subControl ) const +QVector3D QskLevelingSensor::subControlRotation( const QskAspect::Subcontrol subControl ) const { - static const QVector3D notFound; const auto found = m_data->m_subControlRotation.find( subControl ); - if ( found == m_data->m_subControlRotation.end() ) - { - return notFound; - } - return found->second; + return found != m_data->m_subControlRotation.end() ? found->second : QVector3D{}; } void QskLevelingSensor::setSubControlRotation( From 6222667f585c715e55c06b5121fe95cd202f1618 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 11:41:19 +0200 Subject: [PATCH 39/42] clang-format --- .../private/QskLevelingSensorSkinlet.cpp | 72 +++++++++---------- .../private/QskLevelingSensorUtility.h | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/controls/private/QskLevelingSensorSkinlet.cpp b/src/controls/private/QskLevelingSensorSkinlet.cpp index 12d1258c..301014df 100644 --- a/src/controls/private/QskLevelingSensorSkinlet.cpp +++ b/src/controls/private/QskLevelingSensorSkinlet.cpp @@ -62,7 +62,7 @@ namespace Q_REQUIRED_RESULT QVector2D center() const noexcept { - return { ( float ) cX, ( float ) cY}; + return { ( float ) cX, ( float ) cY }; } Q_REQUIRED_RESULT QVector3D scale() const noexcept @@ -90,7 +90,7 @@ namespace , tY( rX * sY ) , tZ( 0.0 ) { - } + } Q_REQUIRED_RESULT QVector3D translation() const noexcept { @@ -221,7 +221,7 @@ template<> Q_REQUIRED_RESULT QRectF QskLevelingSensorSkinlet::subControlRect< R::Horizon >( const QskLevelingSensor* const sensor, const QRectF& contentsRect ) const { - Q_UNUSED(contentsRect) + Q_UNUSED( contentsRect ) const auto scale = sensor->strutSizeHint( Q::Horizon ); const auto width = 2 * innerRadius( sensor ) * scale.width(); const auto height = width; @@ -249,7 +249,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::OuterDisk; const auto contentsRect = sensor->contentsRect(); @@ -270,9 +270,8 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >( const auto cY = center( sensor ).y(); const auto rZ = 0.0; - const auto matrix = matrix_deg( 0.0, cX, cY ) * - matrix_deg( rZ, 0, 0 ) * - matrix_deg( 0.0, -size, -size ); + const auto matrix = + matrix_deg( 0.0, cX, cY ) * matrix_deg( rZ, 0, 0 ) * matrix_deg( 0.0, -size, -size ); root->setMatrix( matrix ); return root; @@ -282,7 +281,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::Horizon; const State< QskAspect::Subcontrol > state( sensor, subControl ); @@ -312,12 +311,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >( return tNode; } -Q_REQUIRED_RESULT QSGNode* updateLinearTickmarksNode( - const QskLevelingSensor* const sensor, - const QskAspect::Subcontrol subControl, - const QskScaleTickmarks& tickmarks, - const Qt::Orientation orientation, - QSGNode* const node ) +Q_REQUIRED_RESULT QSGNode* updateLinearTickmarksNode( const QskLevelingSensor* const sensor, + const QskAspect::Subcontrol subControl, const QskScaleTickmarks& tickmarks, + const Qt::Orientation orientation, QSGNode* const node ) { const auto state = State< QskAspect::Subcontrol >( sensor, subControl ); const auto color = sensor->color( subControl ); @@ -329,21 +325,21 @@ Q_REQUIRED_RESULT QSGNode* updateLinearTickmarksNode( const auto opt = minmax( tickmarks ); const auto min = opt ? opt->first : 0.0; const auto max = opt ? opt->second : 0.0; - const auto interval = QskIntervalF{min,max}; + const auto interval = QskIntervalF{ min, max }; const auto rect = orientation == Qt::Horizontal ? QRectF{ QPointF{ min * state.sX, -height }, QPointF{ max * state.sX, +height } } : QRectF{ QPointF{ -width, min * state.sY }, QPointF{ +width, max * state.sY } }; - const auto translation = QPointF{state.tX + state.cX, state.tY + state.cY}; + const auto translation = QPointF{ state.tX + state.cX, state.tY + state.cY }; auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, QskTickmarksNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const qNode = static_cast< QskTickmarksNode* >( tNode->firstChild() ); - + cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - tNode->setMatrix( matrix_deg( state.rZ, translation.x(), translation.y() )); + tNode->setMatrix( matrix_deg( state.rZ, translation.x(), translation.y() ) ); qNode->update( color, rect, interval, tickmarks, 1, orientation, alignment ); return cNode; @@ -353,7 +349,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) return updateLinearTickmarksNode( sensor, Q::TickmarksX, sensor->tickmarks( Qt::XAxis ), Qt::Horizontal, node ); } @@ -362,7 +358,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) return updateLinearTickmarksNode( sensor, Q::TickmarksY, sensor->tickmarks( Qt::YAxis ), Qt::Vertical, node ); } @@ -371,7 +367,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::TickmarksZ; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto color = sensor->color( subControl ); @@ -394,19 +390,21 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::TickmarksXLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); - const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height(); - const auto dX = qFastCos(qDegreesToRadians(90 + state.rZ)) * r3; - const auto dY = qFastSin(qDegreesToRadians(90 + state.rZ)) * r3; + const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height(); + const auto dX = qFastCos( qDegreesToRadians( 90 + state.rZ ) ) * r3; + const auto dY = qFastSin( qDegreesToRadians( 90 + state.rZ ) ) * r3; - auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) ); - lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 } ); + tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY ) ); + lNode->update( + sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 } ); return cNode; } @@ -414,19 +412,21 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::TickmarksYLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width(); - const auto dX = qFastCos(qDegreesToRadians(state.rZ)) * r3; - const auto dY = qFastSin(qDegreesToRadians(state.rZ)) * r3; + const auto dX = qFastCos( qDegreesToRadians( state.rZ ) ) * r3; + const auto dY = qFastSin( qDegreesToRadians( state.rZ ) ) * r3; - auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); + auto* const cNode = + ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node ); auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() ); auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() ); cNode->setGeometryProperties( state.r1, state.cX, state.cY ); - tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) ); - lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), { 0.0, state.scale().y() } ); + tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY ) ); + lNode->update( + sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), { 0.0, state.scale().y() } ); return cNode; } @@ -434,7 +434,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZLabels >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto subControl = Q::TickmarksZLabels; const State< QskAspect::Subcontrol > state( sensor, subControl ); auto* const tNode = ensureNodes< QSGTransformNode, RadialTickmarksLabelsNode >( node ); @@ -449,7 +449,7 @@ template<> QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::HorizonClip >( const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const { - Q_UNUSED(nodeRole) + Q_UNUSED( nodeRole ) const auto cX = center( sensor ).x(); const auto cY = center( sensor ).y(); const auto r1 = innerRadius( sensor ); diff --git a/src/controls/private/QskLevelingSensorUtility.h b/src/controls/private/QskLevelingSensorUtility.h index fae0f581..faecbca2 100644 --- a/src/controls/private/QskLevelingSensorUtility.h +++ b/src/controls/private/QskLevelingSensorUtility.h @@ -17,7 +17,7 @@ Q_REQUIRED_RESULT inline QMatrix4x4 matrix_deg( float rZ = 0.0f, float tX = 0.0f { QTransform transform; transform.translate( tX, tY ); - transform.rotate(rZ, Qt::ZAxis); + transform.rotate( rZ, Qt::ZAxis ); return transform; } From 7eea017b7dc5853f3348f23331d869450bd305e9 Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 13:05:25 +0200 Subject: [PATCH 40/42] revert changes --- src/controls/private/QskSGNodeUtility.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index fbcfd256..a83de54f 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -26,8 +26,9 @@ namespace QskSGNode if constexpr ( mode == Recursive ) { + QSGNode* current = root; ( - [ current = root ]( QSGNode* const child ) mutable { + [ ¤t ]( QSGNode* const child ) mutable { current->appendChildNode( child ); current = child; }( new Children ), From a7f874c665c20ea28ab6b680f6ed424d13d6d0ee Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Thu, 3 Aug 2023 13:12:49 +0200 Subject: [PATCH 41/42] add unused macro although not unused --- src/controls/private/QskSGNodeUtility.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controls/private/QskSGNodeUtility.h b/src/controls/private/QskSGNodeUtility.h index a83de54f..8ff007bb 100644 --- a/src/controls/private/QskSGNodeUtility.h +++ b/src/controls/private/QskSGNodeUtility.h @@ -27,6 +27,7 @@ namespace QskSGNode if constexpr ( mode == Recursive ) { QSGNode* current = root; + Q_UNUSED( current ) ( [ ¤t ]( QSGNode* const child ) mutable { current->appendChildNode( child ); From 4ed5f7e43100c9178da8da5ceded030fba46b1df Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Tue, 8 Aug 2023 11:11:01 +0200 Subject: [PATCH 42/42] simplyfy setter --- src/controls/private/QskLevelingSensor.cpp | 31 +------ src/controls/private/QskLevelingSensorNodes.h | 90 ------------------- 2 files changed, 3 insertions(+), 118 deletions(-) diff --git a/src/controls/private/QskLevelingSensor.cpp b/src/controls/private/QskLevelingSensor.cpp index 342c120c..1be277a3 100644 --- a/src/controls/private/QskLevelingSensor.cpp +++ b/src/controls/private/QskLevelingSensor.cpp @@ -131,35 +131,10 @@ QVector3D QskLevelingSensor::subControlRotation( const QskAspect::Subcontrol sub void QskLevelingSensor::setSubControlRotation( const QskAspect::Subcontrol subControl, const QVector3D& degrees ) { - auto updateSubControlRotation = [ this ]( const QskAspect::Subcontrol subControl, - const QVector3D& degrees ) { - if ( compareExchange( m_data->m_subControlRotation[ subControl ], degrees ) ) - { - Q_EMIT subControlRotationChanged( subControl, degrees ); - update(); - } - }; - - using Q = QskLevelingSensor; - - if ( subControl == Q::TickmarksX || subControl == Q::TickmarksXLabels ) + if ( compareExchange( m_data->m_subControlRotation[ subControl ], degrees ) ) { - updateSubControlRotation( Q::TickmarksX, degrees ); - updateSubControlRotation( Q::TickmarksXLabels, degrees ); - } - else if ( subControl == Q::TickmarksY || subControl == Q::TickmarksYLabels ) - { - updateSubControlRotation( Q::TickmarksY, degrees ); - updateSubControlRotation( Q::TickmarksYLabels, degrees ); - } - else if ( subControl == Q::TickmarksZ || subControl == TickmarksZLabels ) - { - updateSubControlRotation( TickmarksZ, degrees ); - updateSubControlRotation( TickmarksZLabels, degrees ); - } - else - { - updateSubControlRotation( subControl, degrees ); + update(); + Q_EMIT subControlRotationChanged( subControl, degrees ); } } diff --git a/src/controls/private/QskLevelingSensorNodes.h b/src/controls/private/QskLevelingSensorNodes.h index f5dec598..50e713b2 100644 --- a/src/controls/private/QskLevelingSensorNodes.h +++ b/src/controls/private/QskLevelingSensorNodes.h @@ -103,96 +103,6 @@ class RadialTickmarksNode final : public QSGGeometryNode QskHashValue m_tickmarksHash{ 0 }; }; -class LinearTickmarksNode final : public QSGGeometryNode -{ - public: - LinearTickmarksNode() - : m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 ) - { - m_geometry.setDrawingMode( QSGGeometry::DrawLines ); - m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern ); - - setGeometry( &m_geometry ); - setMaterial( &m_material ); - } - - void setMaterialProperties( const QColor& color ) - { - auto dirty = false; - - if ( dirty |= ( m_material.color() != color ) ) - { - m_material.setColor( color ); - } - - if ( dirty ) - { - markDirty( QSGNode::DirtyMaterial ); - } - } - - void setGeometryProperties( const QskScaleTickmarks& tickmarks, const QVector3D& tickmarkSize, - const QVector2D& scale = { 1.0, 0.0f }, const QVector2D& offset = {}, - const float lineWidth = 1.0f, const bool forceDirty = false ) - { - auto dirty = forceDirty; - - if ( dirty |= !qFuzzyCompare( m_geometry.lineWidth(), lineWidth ) ) - { - m_geometry.setLineWidth( lineWidth ); - } - - dirty |= m_geometry.vertexCount() != tickmarks.tickCount() * 2; - dirty |= compareExchange( m_tickmarkSize, tickmarkSize ); - dirty |= compareExchange( m_scale, scale ); - dirty |= compareExchange( m_offset, offset ); - - if ( dirty ) - { - update( tickmarks ); - markDirty( QSGNode::DirtyGeometry ); - } - } - - private: - void update( const QskScaleTickmarks& tickmarks ) - { - if ( m_geometry.vertexCount() != tickmarks.tickCount() * 2 ) - { - m_geometry.allocate( tickmarks.tickCount() * 2 ); - } - - auto* vertexData = m_geometry.vertexDataAsPoint2D(); - - using T = QskScaleTickmarks::TickType; - for ( auto type : { T::MinorTick, T::MediumTick, T::MajorTick } ) - { - for ( const auto tick : tickmarks.ticks( type ) ) - { - const auto i = static_cast< int >( type ); - - const auto p = m_scale * tick; - const auto d = QVector2D( -m_scale.y(), m_scale.x() ).normalized(); - - const auto p1 = m_tickmarkSize[ i ] * +1 * d + p + m_offset; - const auto p2 = m_tickmarkSize[ i ] * -1 * d + p + m_offset; - - vertexData[ 0 ].set( p1.x(), p1.y() ); - vertexData[ 1 ].set( p2.x(), p2.y() ); - vertexData += 2; - } - } - - m_geometry.markVertexDataDirty(); - } - - QSGGeometry m_geometry; - QSGFlatColorMaterial m_material; - QVector2D m_scale = { 1.0f, 0.0f }; - QVector2D m_offset = { 0.0f, 0.0f }; - QVector3D m_tickmarkSize = { 1.0, 2.0, 4.0 }; -}; - class RadialClipNode final : public QSGClipNode { public: