Speedometer: Make it skinnable
This commit is contained in:
parent
41d97c8c91
commit
847500fb7c
|
@ -74,7 +74,7 @@ namespace {
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
DefaultSkin::DefaultSkin( const QString& name, QObject* parent ):
|
DefaultSkin::DefaultSkin( const QString& name, QObject* parent ):
|
||||||
QskSkin( parent ),
|
QskSkin( parent ),
|
||||||
|
@ -101,7 +101,8 @@ void DefaultSkin::initHints()
|
||||||
|
|
||||||
setColor( QskTextLabel::Text, m_palette->color4 );
|
setColor( QskTextLabel::Text, m_palette->color4 );
|
||||||
|
|
||||||
// - sound control
|
// -- sound control
|
||||||
|
|
||||||
setGradient( SoundControl::Overlay, 0 );
|
setGradient( SoundControl::Overlay, 0 );
|
||||||
setGradient( SoundControl::CrossHair, m_palette->color3 );
|
setGradient( SoundControl::CrossHair, m_palette->color3 );
|
||||||
setGradient( SoundControl::Marker, m_palette->color5 );
|
setGradient( SoundControl::Marker, m_palette->color5 );
|
||||||
|
@ -146,6 +147,30 @@ void DefaultSkin::initHints()
|
||||||
setBoxShape( QskSlider::Handle, 100.0, Qt::RelativeSize );
|
setBoxShape( QskSlider::Handle, 100.0, Qt::RelativeSize );
|
||||||
setGradient( QskSlider::Handle, m_palette->color5 );
|
setGradient( QskSlider::Handle, m_palette->color5 );
|
||||||
|
|
||||||
|
// -- speedometers
|
||||||
|
|
||||||
|
setBoxBorderMetrics( Speedometer::Panel, 2 );
|
||||||
|
setGradient( Speedometer::Panel, m_palette->color1 );
|
||||||
|
setBoxBorderColors( Speedometer::Panel, m_palette->color3 );
|
||||||
|
|
||||||
|
setBoxBorderMetrics( Speedometer::NeedleHead, 2 );
|
||||||
|
setMetric( Speedometer::NeedleHead | QskAspect::Size, 15 );
|
||||||
|
setGradient( Speedometer::NeedleHead, QskGradient( QskGradient::Diagonal,
|
||||||
|
m_palette->color2, m_palette->color1 ) );
|
||||||
|
// setBoxBorderColors( Speedometer::NeedleHead, m_palette->color4 );
|
||||||
|
|
||||||
|
setMetric( Speedometer::Needle | QskAspect::MinimumWidth, 2 );
|
||||||
|
setMetric( Speedometer::Needle | QskAspect::Margin, 10 );
|
||||||
|
setColor( Speedometer::Needle, m_palette->color2 );
|
||||||
|
|
||||||
|
// margins between numbers and ticks:
|
||||||
|
setMargins( Speedometer::Labels, QskMargins( 4, 4, 4, 4 ) );
|
||||||
|
setMetric( Speedometer::Labels | QskAspect::MinimumWidth, 2 );
|
||||||
|
setMetric( Speedometer::Labels | QskAspect::Size, 15 ); // ticks size
|
||||||
|
setColor( Speedometer::Labels, m_palette->color4 );
|
||||||
|
setFontRole( Speedometer::Labels, QskSkin::SmallFont );
|
||||||
|
|
||||||
|
|
||||||
// handle expanding, when being pressed
|
// handle expanding, when being pressed
|
||||||
for ( auto state : { QskAspect::NoState, QskSlider::Pressed } )
|
for ( auto state : { QskAspect::NoState, QskSlider::Pressed } )
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,6 +140,29 @@ void OtherSkin::initHints()
|
||||||
setBoxBorderMetrics( QskSlider::Handle, 0 );
|
setBoxBorderMetrics( QskSlider::Handle, 0 );
|
||||||
setBoxShape( QskSlider::Handle, 6 );
|
setBoxShape( QskSlider::Handle, 6 );
|
||||||
setGradient( QskSlider::Handle, m_palette->color3 );
|
setGradient( QskSlider::Handle, m_palette->color3 );
|
||||||
|
|
||||||
|
// -- speedometers
|
||||||
|
|
||||||
|
setBoxBorderMetrics( Speedometer::Panel, 5 );
|
||||||
|
setGradient( Speedometer::Panel, QskGradient( QskGradient::Vertical,
|
||||||
|
m_palette->color2, m_palette->color4 ) );
|
||||||
|
setBoxBorderColors( Speedometer::Panel, m_palette->color3 );
|
||||||
|
|
||||||
|
setBoxBorderMetrics( Speedometer::NeedleHead, 5 );
|
||||||
|
setMetric( Speedometer::NeedleHead | QskAspect::Size, 10 );
|
||||||
|
setGradient( Speedometer::NeedleHead, m_palette->color2 );
|
||||||
|
setBoxBorderColors( Speedometer::NeedleHead, m_palette->color4 );
|
||||||
|
|
||||||
|
setMetric( Speedometer::Needle | QskAspect::MinimumWidth, 4 );
|
||||||
|
setMetric( Speedometer::Needle | QskAspect::Margin, 15 );
|
||||||
|
setColor( Speedometer::Needle, m_palette->color4 );
|
||||||
|
|
||||||
|
// margins between numbers and ticks:
|
||||||
|
setMargins( Speedometer::Labels, QskMargins( 3, 3, 3, 3 ) );
|
||||||
|
setMetric( Speedometer::Labels | QskAspect::MinimumWidth, 3 );
|
||||||
|
setMetric( Speedometer::Labels | QskAspect::Size, 25 ); // ticks size
|
||||||
|
setColor( Speedometer::Labels, m_palette->color4 );
|
||||||
|
setFontRole( Speedometer::Labels, QskSkin::SmallFont );
|
||||||
}
|
}
|
||||||
|
|
||||||
void OtherSkin::initGraphicFilters()
|
void OtherSkin::initGraphicFilters()
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
QSK_SUBCONTROL( Speedometer, Panel )
|
QSK_SUBCONTROL( Speedometer, Panel )
|
||||||
QSK_SUBCONTROL( Speedometer, Labels )
|
QSK_SUBCONTROL( Speedometer, Labels )
|
||||||
|
QSK_SUBCONTROL( Speedometer, NeedleHead )
|
||||||
QSK_SUBCONTROL( Speedometer, Needle )
|
QSK_SUBCONTROL( Speedometer, Needle )
|
||||||
|
|
||||||
Speedometer::Speedometer( QQuickItem* parent ) :
|
Speedometer::Speedometer( QQuickItem* parent ) :
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Speedometer : public QskRangeControl
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSK_SUBCONTROLS( Panel, Labels, Needle )
|
QSK_SUBCONTROLS( Panel, Labels, NeedleHead, Needle )
|
||||||
|
|
||||||
Speedometer( QQuickItem* parent = nullptr );
|
Speedometer( QQuickItem* parent = nullptr );
|
||||||
|
|
||||||
|
|
|
@ -15,22 +15,24 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
class TicksNode : public QSGGeometryNode
|
class TicksNode : public QSGGeometryNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TicksNode( const QColor& color ):
|
TicksNode():
|
||||||
m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||||
{
|
{
|
||||||
m_geometry.setDrawingMode( GL_LINES );
|
m_geometry.setDrawingMode( GL_LINES );
|
||||||
m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern );
|
m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern );
|
||||||
|
|
||||||
m_material.setColor( color );
|
|
||||||
|
|
||||||
setGeometry( &m_geometry );
|
setGeometry( &m_geometry );
|
||||||
setMaterial( &m_material );
|
setMaterial( &m_material );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setColor( const QColor& color )
|
||||||
|
{
|
||||||
|
m_material.setColor( color );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSGFlatColorMaterial m_material;
|
QSGFlatColorMaterial m_material;
|
||||||
QSGGeometry m_geometry;
|
QSGGeometry m_geometry;
|
||||||
|
@ -87,9 +89,9 @@ QSGNode* SpeedometerSkinlet::updatePanelNode( const Speedometer* speedometer, QS
|
||||||
QRectF panelRect = subControlRect( speedometer, Speedometer::Panel );
|
QRectF panelRect = subControlRect( speedometer, Speedometer::Panel );
|
||||||
qreal radius = panelRect.width() / 2;
|
qreal radius = panelRect.width() / 2;
|
||||||
QskBoxShapeMetrics shapeMetrics( radius, radius, radius, radius );
|
QskBoxShapeMetrics shapeMetrics( radius, radius, radius, radius );
|
||||||
QskBoxBorderMetrics borderMetrics( 2 );
|
QskBoxBorderMetrics borderMetrics = speedometer->boxBorderMetricsHint( Speedometer::Panel );
|
||||||
QskBoxBorderColors borderColors( Qt::white );
|
QskBoxBorderColors borderColors = speedometer->boxBorderColorsHint( Speedometer::Panel );
|
||||||
QskGradient gradient( Qt::black );
|
QskGradient gradient = speedometer->gradientHint( Speedometer::Panel );
|
||||||
boxNode->setBoxData( panelRect, shapeMetrics, borderMetrics, borderColors, gradient );
|
boxNode->setBoxData( panelRect, shapeMetrics, borderMetrics, borderColors, gradient );
|
||||||
|
|
||||||
return boxNode;
|
return boxNode;
|
||||||
|
@ -109,9 +111,12 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
|
|
||||||
if ( ticksNode == nullptr )
|
if ( ticksNode == nullptr )
|
||||||
{
|
{
|
||||||
ticksNode = new TicksNode( Qt::white );
|
ticksNode = new TicksNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QColor color = speedometer->color( Speedometer::Labels );
|
||||||
|
ticksNode->setColor( color );
|
||||||
|
|
||||||
const auto startAngle = speedometer->minimum();
|
const auto startAngle = speedometer->minimum();
|
||||||
const auto endAngle = speedometer->maximum();
|
const auto endAngle = speedometer->maximum();
|
||||||
const auto step = ( endAngle - startAngle ) / ( labelsCount - 1 );
|
const auto step = ( endAngle - startAngle ) / ( labelsCount - 1 );
|
||||||
|
@ -130,10 +135,12 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
panelRect.y() + panelRect.height() / 2 );
|
panelRect.y() + panelRect.height() / 2 );
|
||||||
auto radius = static_cast< float >( panelRect.width() / 2 );
|
auto radius = static_cast< float >( panelRect.width() / 2 );
|
||||||
|
|
||||||
const QMarginsF numbersMargins = speedometer->marginsHint( Speedometer::Labels | QskAspect::Margin );
|
const QMarginsF numbersMargins = speedometer->marginsHint( Speedometer::Labels );
|
||||||
QFontMetrics fontMetrics( speedometer->effectiveFont( Speedometer::Labels ) );
|
QFontMetrics fontMetrics( speedometer->effectiveFont( Speedometer::Labels ) );
|
||||||
|
|
||||||
auto angle = startAngle;
|
auto angle = startAngle;
|
||||||
|
qreal length = speedometer->metric( Speedometer::Labels | QskAspect::Size );
|
||||||
|
QVector< QString > labels = speedometer->labels();
|
||||||
|
|
||||||
// Create a series of tickmarks from minimum to maximum
|
// Create a series of tickmarks from minimum to maximum
|
||||||
for( int i = 0; i < labelsCount; ++i, angle += step )
|
for( int i = 0; i < labelsCount; ++i, angle += step )
|
||||||
|
@ -145,7 +152,6 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
auto yStart = center.y() + radius * sine;
|
auto yStart = center.y() + radius * sine;
|
||||||
|
|
||||||
// ### skin hint for each of highlighted / normal marks
|
// ### skin hint for each of highlighted / normal marks
|
||||||
qreal length = 15;
|
|
||||||
auto xEnd = center.x() + ( radius - length ) * cosine;
|
auto xEnd = center.x() + ( radius - length ) * cosine;
|
||||||
auto yEnd = center.y() + ( radius - length ) * sine;
|
auto yEnd = center.y() + ( radius - length ) * sine;
|
||||||
|
|
||||||
|
@ -154,8 +160,6 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
|
|
||||||
vertexData += 2;
|
vertexData += 2;
|
||||||
|
|
||||||
QVector< QString > labels = speedometer->labels();
|
|
||||||
|
|
||||||
// only create a text node if there is a label for it:
|
// only create a text node if there is a label for it:
|
||||||
if ( labels.count() > i )
|
if ( labels.count() > i )
|
||||||
{
|
{
|
||||||
|
@ -182,8 +186,9 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
numbersNode = new QskTextNode();
|
numbersNode = new QskTextNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
numbersNode->setTextData( speedometer, text, numbersRect, QFont(),
|
QFont font = speedometer->effectiveFont( Speedometer::Labels );
|
||||||
QskTextOptions(), QskTextColors( Qt::white ),
|
numbersNode->setTextData( speedometer, text, numbersRect, font,
|
||||||
|
QskTextOptions(), QskTextColors( color ),
|
||||||
Qt::AlignCenter | Qt::AlignHCenter, Qsk::Normal );
|
Qt::AlignCenter | Qt::AlignHCenter, Qsk::Normal );
|
||||||
|
|
||||||
if ( ticksNode->childCount() <= i )
|
if ( ticksNode->childCount() <= i )
|
||||||
|
@ -194,7 +199,8 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry->setLineWidth( 2 );
|
auto lineWidth = speedometer->metric( Speedometer::Labels | QskAspect::MinimumWidth );
|
||||||
|
geometry->setLineWidth( lineWidth );
|
||||||
geometry->markVertexDataDirty();
|
geometry->markVertexDataDirty();
|
||||||
|
|
||||||
ticksNode->markDirty( QSGNode::DirtyGeometry );
|
ticksNode->markDirty( QSGNode::DirtyGeometry );
|
||||||
|
@ -206,7 +212,7 @@ QSGNode* SpeedometerSkinlet::updateNeedleNode( const Speedometer* speedometer, Q
|
||||||
{
|
{
|
||||||
QMarginsF margins = speedometer->marginsHint( Speedometer::Panel | QskAspect::Margin );
|
QMarginsF margins = speedometer->marginsHint( Speedometer::Panel | QskAspect::Margin );
|
||||||
const QRectF panelRect = subControlRect( speedometer, Speedometer::Panel ).marginsRemoved( margins );
|
const QRectF panelRect = subControlRect( speedometer, Speedometer::Panel ).marginsRemoved( margins );
|
||||||
auto radius = 15; // ### skin hint
|
auto radius = speedometer->metric( Speedometer::NeedleHead | QskAspect::Size );
|
||||||
QPointF center = QPointF( panelRect.x() + panelRect.width() / 2,
|
QPointF center = QPointF( panelRect.x() + panelRect.width() / 2,
|
||||||
panelRect.y() + panelRect.height() / 2 );
|
panelRect.y() + panelRect.height() / 2 );
|
||||||
|
|
||||||
|
@ -217,38 +223,43 @@ QSGNode* SpeedometerSkinlet::updateNeedleNode( const Speedometer* speedometer, Q
|
||||||
boxNode = new QskBoxNode;
|
boxNode = new QskBoxNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskBoxShapeMetrics shapeMetrics( radius, radius, radius, radius );
|
||||||
|
QskBoxBorderMetrics borderMetrics = speedometer->boxBorderMetricsHint( Speedometer::NeedleHead );
|
||||||
|
QskBoxBorderColors borderColors = speedometer->boxBorderColorsHint( Speedometer::NeedleHead );
|
||||||
|
QskGradient gradient = speedometer->gradientHint( Speedometer::NeedleHead );
|
||||||
QRectF centerNodeRect( center.x() - radius, center.y() - radius,
|
QRectF centerNodeRect( center.x() - radius, center.y() - radius,
|
||||||
2 * radius, 2 * radius );
|
2 * radius, 2 * radius );
|
||||||
QskBoxShapeMetrics shapeMetrics( radius, radius, radius, radius );
|
|
||||||
QskBoxBorderMetrics borderMetrics( 2 );
|
|
||||||
QskBoxBorderColors borderColors( Qt::red );
|
|
||||||
QskGradient gradient( Qt::red );
|
|
||||||
boxNode->setBoxData( centerNodeRect, shapeMetrics, borderMetrics, borderColors, gradient );
|
boxNode->setBoxData( centerNodeRect, shapeMetrics, borderMetrics, borderColors, gradient );
|
||||||
|
|
||||||
TicksNode* needleNode;
|
TicksNode* needleNode;
|
||||||
|
|
||||||
if ( boxNode->childCount() == 0 )
|
if ( boxNode->childCount() == 0 )
|
||||||
{
|
{
|
||||||
needleNode = new TicksNode( Qt::red );
|
needleNode = new TicksNode();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
needleNode = static_cast< TicksNode* >( boxNode->childAtIndex( 0 ) );
|
needleNode = static_cast< TicksNode* >( boxNode->childAtIndex( 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QColor color = speedometer->color( Speedometer::Needle );
|
||||||
|
needleNode->setColor( color );
|
||||||
|
|
||||||
auto panelRadius = static_cast< float >( panelRect.width() / 2 );
|
auto panelRadius = static_cast< float >( panelRect.width() / 2 );
|
||||||
|
|
||||||
auto needleWidth = 2; // ### do differently somehow
|
auto needleWidth = speedometer->metric( Speedometer::Needle | QskAspect::MinimumWidth );
|
||||||
|
auto needleMargin = speedometer->metric( Speedometer::Needle | QskAspect::Margin );
|
||||||
|
|
||||||
QRectF needleRect( center.x() - needleWidth , center.y() - needleWidth ,
|
QRectF needleRect( center.x() - needleWidth , center.y() - needleWidth ,
|
||||||
panelRadius - ( needleWidth + 10 ), 2 * needleWidth );
|
panelRadius - ( needleWidth + needleMargin ), 2 * needleWidth );
|
||||||
float xStart = center.x() - needleWidth ;
|
float xStart = center.x();
|
||||||
float yStart = center.y();
|
float yStart = center.y();
|
||||||
|
|
||||||
float angle = speedometer->value();
|
float angle = speedometer->value();
|
||||||
qreal cosine = qCos( qDegreesToRadians( angle ) );
|
qreal cosine = qCos( qDegreesToRadians( angle ) );
|
||||||
qreal sine = qSin( qDegreesToRadians( angle ) );
|
qreal sine = qSin( qDegreesToRadians( angle ) );
|
||||||
|
|
||||||
float needleRadius = panelRadius - 10; // 10 == margins ### skinhint
|
float needleRadius = panelRadius - needleMargin;
|
||||||
float xEnd = center.x() + needleRadius * cosine;
|
float xEnd = center.x() + needleRadius * cosine;
|
||||||
float yEnd = center.y() + needleRadius * sine;
|
float yEnd = center.y() + needleRadius * sine;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue