add tickmarks node
This commit is contained in:
parent
3d37ee8f23
commit
9a9bc596ab
|
@ -7,6 +7,7 @@
|
||||||
#include "LightDisplay.h"
|
#include "LightDisplay.h"
|
||||||
|
|
||||||
#include "nodes/BoxShadowNode.h"
|
#include "nodes/BoxShadowNode.h"
|
||||||
|
#include "nodes/RadialTickmarksNode.h"
|
||||||
|
|
||||||
#include <QskArcMetrics.h>
|
#include <QskArcMetrics.h>
|
||||||
#include <QskTextOptions.h>
|
#include <QskTextOptions.h>
|
||||||
|
@ -30,6 +31,7 @@ QRectF LightDisplaySkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
{
|
{
|
||||||
auto* display = static_cast< const LightDisplay* >( skinnable );
|
auto* display = static_cast< const LightDisplay* >( skinnable );
|
||||||
QRectF rect = contentsRect;
|
QRectF rect = contentsRect;
|
||||||
|
const qreal ticksSpacing = 4; // space between the ticks and the arc
|
||||||
|
|
||||||
if( subControl == LightDisplay::Groove
|
if( subControl == LightDisplay::Groove
|
||||||
|| subControl == LightDisplay::Panel
|
|| subControl == LightDisplay::Panel
|
||||||
|
@ -37,7 +39,7 @@ QRectF LightDisplaySkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
{
|
{
|
||||||
QSizeF textSize = textLabelsSize( display );
|
QSizeF textSize = textLabelsSize( display );
|
||||||
QskArcMetrics arcMetrics = display->arcMetricsHint( LightDisplay::ColdAndWarmArc );
|
QskArcMetrics arcMetrics = display->arcMetricsHint( LightDisplay::ColdAndWarmArc );
|
||||||
const qreal ticksWidth = display->metric( LightDisplay::Tickmarks );
|
const qreal ticksWidth = display->arcMetricsHint( LightDisplay::Tickmarks ).width() + ticksSpacing;
|
||||||
|
|
||||||
const qreal x = textSize.width() + arcMetrics.width() + ticksWidth;
|
const qreal x = textSize.width() + arcMetrics.width() + ticksWidth;
|
||||||
const qreal w = contentsRect.width() - ( 2 * ( textSize.width() + arcMetrics.width() + ticksWidth ) );
|
const qreal w = contentsRect.width() - ( 2 * ( textSize.width() + arcMetrics.width() + ticksWidth ) );
|
||||||
|
@ -61,8 +63,8 @@ QRectF LightDisplaySkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
{
|
{
|
||||||
const QRectF arcRect = subControlRect( skinnable, contentsRect,
|
const QRectF arcRect = subControlRect( skinnable, contentsRect,
|
||||||
LightDisplay::ColdAndWarmArc );
|
LightDisplay::ColdAndWarmArc );
|
||||||
auto tickWidth = display->metric( LightDisplay::Tickmarks );
|
const qreal ticksWidth = display->arcMetricsHint( LightDisplay::Tickmarks ).width() + ticksSpacing;
|
||||||
auto rect = arcRect.marginsAdded( { tickWidth, tickWidth, tickWidth, tickWidth } );
|
const QRectF rect = arcRect.marginsAdded( { ticksWidth, ticksWidth, ticksWidth, ticksWidth } );
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
else if( subControl == LightDisplay::LeftLabel )
|
else if( subControl == LightDisplay::LeftLabel )
|
||||||
|
@ -151,7 +153,22 @@ QSGNode* LightDisplaySkinlet::updateSubNode(
|
||||||
}
|
}
|
||||||
case TickmarksRole:
|
case TickmarksRole:
|
||||||
{
|
{
|
||||||
return nullptr;
|
auto ticksNode = static_cast< RadialTickmarksNode* >( node );
|
||||||
|
if ( ticksNode == nullptr )
|
||||||
|
ticksNode = new RadialTickmarksNode();
|
||||||
|
|
||||||
|
QColor color = display->color( LightDisplay::Tickmarks );
|
||||||
|
QRectF ticksRect = display->subControlRect( LightDisplay::Tickmarks );
|
||||||
|
QskArcMetrics arcMetrics = display->arcMetricsHint( LightDisplay::Tickmarks );
|
||||||
|
QskIntervalF boundaries = display->boundaries();
|
||||||
|
QskScaleTickmarks tickmarks;
|
||||||
|
tickmarks.setMajorTicks( {0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180 } );
|
||||||
|
int tickLineWidth = display->metric( LightDisplay::Tickmarks );
|
||||||
|
|
||||||
|
ticksNode->update( color, ticksRect, arcMetrics, boundaries,
|
||||||
|
tickmarks, tickLineWidth, Qt::Horizontal );
|
||||||
|
|
||||||
|
return ticksNode;
|
||||||
}
|
}
|
||||||
case ValueTextRole:
|
case ValueTextRole:
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,7 +192,9 @@ void Skin::initHints( const Palette& palette )
|
||||||
{ 1.0, Qt::black } } );
|
{ 1.0, Qt::black } } );
|
||||||
ed.setGradient( LightDisplay::ColdAndWarmArc, coldGradient );
|
ed.setGradient( LightDisplay::ColdAndWarmArc, coldGradient );
|
||||||
|
|
||||||
ed.setMetric( LightDisplay::Tickmarks, 4.69 );
|
ed.setMetric( LightDisplay::Tickmarks, 1 );
|
||||||
|
ed.setArcMetrics( LightDisplay::Tickmarks, { 4.69, 0, 180 * 16 } );
|
||||||
|
ed.setColor( LightDisplay::Tickmarks, 0x55929CB2 );
|
||||||
|
|
||||||
ed.setFontRole( LightDisplay::ValueText, QskSkin::LargeFont );
|
ed.setFontRole( LightDisplay::ValueText, QskSkin::LargeFont );
|
||||||
ed.setColor( LightDisplay::ValueText, "#929cb2" );
|
ed.setColor( LightDisplay::ValueText, "#929cb2" );
|
||||||
|
|
|
@ -29,9 +29,10 @@ SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
nodes/BoxShadowNode.cpp \
|
||||||
nodes/DiagramDataNode.cpp \
|
nodes/DiagramDataNode.cpp \
|
||||||
nodes/DiagramSegmentsNode.cpp \
|
nodes/DiagramSegmentsNode.cpp \
|
||||||
nodes/BoxShadowNode.cpp
|
nodes/RadialTickmarksNode.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Box.h \
|
Box.h \
|
||||||
|
@ -59,9 +60,10 @@ HEADERS += \
|
||||||
UsageDiagram.h
|
UsageDiagram.h
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
nodes/BoxShadowNode.h \
|
||||||
nodes/DiagramDataNode.h \
|
nodes/DiagramDataNode.h \
|
||||||
nodes/DiagramSegmentsNode.h \
|
nodes/DiagramSegmentsNode.h \
|
||||||
nodes/BoxShadowNode.h
|
nodes/RadialTickmarksNode.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
images.qrc \
|
images.qrc \
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the 3-clause BSD License
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "RadialTickmarksNode.h"
|
||||||
|
|
||||||
|
#include <QSGFlatColorMaterial>
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qsgnode_p.h>
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
static constexpr inline qreal qskTickFactor( QskScaleTickmarks::TickType type )
|
||||||
|
{
|
||||||
|
using TM = QskScaleTickmarks;
|
||||||
|
return type == TM::MinorTick ? 0.7 : ( type == TM::MinorTick ? 0.85 : 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
class RadialTickmarksNodePrivate final : public QSGGeometryNodePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RadialTickmarksNodePrivate()
|
||||||
|
: geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 5, 8, 0 )
|
||||||
|
geometry.setDrawingMode( QSGGeometry::DrawLines );
|
||||||
|
#else
|
||||||
|
geometry.setDrawingMode( GL_LINES );
|
||||||
|
#endif
|
||||||
|
geometry.setVertexDataPattern( QSGGeometry::StaticPattern );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGGeometry geometry;
|
||||||
|
QSGFlatColorMaterial material;
|
||||||
|
|
||||||
|
QskIntervalF boundaries;
|
||||||
|
QskScaleTickmarks tickmarks;
|
||||||
|
|
||||||
|
QRectF rect;
|
||||||
|
int lineWidth = 0;
|
||||||
|
|
||||||
|
uint hash = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
RadialTickmarksNode::RadialTickmarksNode()
|
||||||
|
: QSGGeometryNode( *new RadialTickmarksNodePrivate )
|
||||||
|
{
|
||||||
|
Q_D( RadialTickmarksNode );
|
||||||
|
|
||||||
|
setGeometry( &d->geometry );
|
||||||
|
setMaterial( &d->material );
|
||||||
|
}
|
||||||
|
|
||||||
|
RadialTickmarksNode::~RadialTickmarksNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadialTickmarksNode::update(const QColor& color, const QRectF& rect,
|
||||||
|
const QskArcMetrics &arcMetrics, const QskIntervalF& boundaries,
|
||||||
|
const QskScaleTickmarks& tickmarks, int lineWidth,
|
||||||
|
Qt::Orientation /*orientation*/ )
|
||||||
|
{
|
||||||
|
Q_D( RadialTickmarksNode );
|
||||||
|
|
||||||
|
if( lineWidth != d->lineWidth )
|
||||||
|
{
|
||||||
|
d->lineWidth = lineWidth;
|
||||||
|
d->geometry.setLineWidth( lineWidth );
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint hash = tickmarks.hash( 17435 );
|
||||||
|
|
||||||
|
if( ( hash != d->hash ) || ( rect != d->rect ) )
|
||||||
|
{
|
||||||
|
d->hash = hash;
|
||||||
|
d->rect = rect;
|
||||||
|
|
||||||
|
d->geometry.allocate( tickmarks.tickCount() * 2 );
|
||||||
|
auto vertexData = d->geometry.vertexDataAsPoint2D();
|
||||||
|
|
||||||
|
const auto center = rect.center();
|
||||||
|
const auto radius = 0.5 * rect.width();
|
||||||
|
const auto needleRadius = radius - arcMetrics.width();
|
||||||
|
|
||||||
|
using TM = QskScaleTickmarks;
|
||||||
|
|
||||||
|
for( int i = TM::MinorTick; i <= TM::MajorTick; i++ )
|
||||||
|
{
|
||||||
|
const auto tickType = static_cast< TM::TickType >( i );
|
||||||
|
const auto ticks = tickmarks.ticks( tickType );
|
||||||
|
|
||||||
|
const auto startAngle = arcMetrics.startAngle();
|
||||||
|
const auto endAngle = startAngle + arcMetrics.spanAngle();
|
||||||
|
|
||||||
|
for( const auto tick : ticks )
|
||||||
|
{
|
||||||
|
const qreal ratio = ( tick - startAngle ) / ( endAngle - startAngle );
|
||||||
|
const qreal angle = ratio * ( endAngle - startAngle );
|
||||||
|
|
||||||
|
const qreal cos = qFastCos( qDegreesToRadians( angle ) );
|
||||||
|
const qreal sin = qFastSin( qDegreesToRadians( angle ) );
|
||||||
|
|
||||||
|
const auto xStart = center.x() - radius * cos;
|
||||||
|
const auto yStart = center.y() - radius * sin;
|
||||||
|
|
||||||
|
const auto xEnd = center.x() - needleRadius * cos;
|
||||||
|
const auto yEnd = center.y() - needleRadius * sin;
|
||||||
|
|
||||||
|
vertexData[ 0 ].set( xStart, yStart );
|
||||||
|
vertexData[ 1 ].set( xEnd, yEnd );
|
||||||
|
|
||||||
|
vertexData += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->geometry.markVertexDataDirty();
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( color != d->material.color() )
|
||||||
|
{
|
||||||
|
d->material.setColor( color );
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the 3-clause BSD License
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskArcMetrics.h>
|
||||||
|
#include <QskIntervalF.h>
|
||||||
|
#include <QskScaleTickmarks.h>
|
||||||
|
|
||||||
|
#include <QSGGeometryNode>
|
||||||
|
|
||||||
|
class RadialTickmarksNodePrivate;
|
||||||
|
|
||||||
|
class RadialTickmarksNode : public QSGGeometryNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RadialTickmarksNode();
|
||||||
|
~RadialTickmarksNode() override;
|
||||||
|
|
||||||
|
void update( const QColor&, const QRectF&, const QskArcMetrics&,
|
||||||
|
const QskIntervalF&, const QskScaleTickmarks&, int, Qt::Orientation );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE( RadialTickmarksNode )
|
||||||
|
};
|
Loading…
Reference in New Issue