Speedometer: Make it skinnable
This commit is contained in:
parent
41d97c8c91
commit
847500fb7c
|
@ -74,7 +74,7 @@ namespace {
|
|||
return font;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
DefaultSkin::DefaultSkin( const QString& name, QObject* parent ):
|
||||
QskSkin( parent ),
|
||||
|
@ -101,7 +101,8 @@ void DefaultSkin::initHints()
|
|||
|
||||
setColor( QskTextLabel::Text, m_palette->color4 );
|
||||
|
||||
// - sound control
|
||||
// -- sound control
|
||||
|
||||
setGradient( SoundControl::Overlay, 0 );
|
||||
setGradient( SoundControl::CrossHair, m_palette->color3 );
|
||||
setGradient( SoundControl::Marker, m_palette->color5 );
|
||||
|
@ -146,6 +147,30 @@ void DefaultSkin::initHints()
|
|||
setBoxShape( QskSlider::Handle, 100.0, Qt::RelativeSize );
|
||||
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
|
||||
for ( auto state : { QskAspect::NoState, QskSlider::Pressed } )
|
||||
{
|
||||
|
|
|
@ -140,6 +140,29 @@ void OtherSkin::initHints()
|
|||
setBoxBorderMetrics( QskSlider::Handle, 0 );
|
||||
setBoxShape( QskSlider::Handle, 6 );
|
||||
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()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
QSK_SUBCONTROL( Speedometer, Panel )
|
||||
QSK_SUBCONTROL( Speedometer, Labels )
|
||||
QSK_SUBCONTROL( Speedometer, NeedleHead )
|
||||
QSK_SUBCONTROL( Speedometer, Needle )
|
||||
|
||||
Speedometer::Speedometer( QQuickItem* parent ) :
|
||||
|
|
|
@ -8,7 +8,7 @@ class Speedometer : public QskRangeControl
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel, Labels, Needle )
|
||||
QSK_SUBCONTROLS( Panel, Labels, NeedleHead, Needle )
|
||||
|
||||
Speedometer( QQuickItem* parent = nullptr );
|
||||
|
||||
|
|
|
@ -15,22 +15,24 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
|
||||
class TicksNode : public QSGGeometryNode
|
||||
{
|
||||
public:
|
||||
TicksNode( const QColor& color ):
|
||||
TicksNode():
|
||||
m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||
{
|
||||
m_geometry.setDrawingMode( GL_LINES );
|
||||
m_geometry.setVertexDataPattern( QSGGeometry::StaticPattern );
|
||||
|
||||
m_material.setColor( color );
|
||||
|
||||
setGeometry( &m_geometry );
|
||||
setMaterial( &m_material );
|
||||
}
|
||||
|
||||
void setColor( const QColor& color )
|
||||
{
|
||||
m_material.setColor( color );
|
||||
}
|
||||
|
||||
private:
|
||||
QSGFlatColorMaterial m_material;
|
||||
QSGGeometry m_geometry;
|
||||
|
@ -87,9 +89,9 @@ QSGNode* SpeedometerSkinlet::updatePanelNode( const Speedometer* speedometer, QS
|
|||
QRectF panelRect = subControlRect( speedometer, Speedometer::Panel );
|
||||
qreal radius = panelRect.width() / 2;
|
||||
QskBoxShapeMetrics shapeMetrics( radius, radius, radius, radius );
|
||||
QskBoxBorderMetrics borderMetrics( 2 );
|
||||
QskBoxBorderColors borderColors( Qt::white );
|
||||
QskGradient gradient( Qt::black );
|
||||
QskBoxBorderMetrics borderMetrics = speedometer->boxBorderMetricsHint( Speedometer::Panel );
|
||||
QskBoxBorderColors borderColors = speedometer->boxBorderColorsHint( Speedometer::Panel );
|
||||
QskGradient gradient = speedometer->gradientHint( Speedometer::Panel );
|
||||
boxNode->setBoxData( panelRect, shapeMetrics, borderMetrics, borderColors, gradient );
|
||||
|
||||
return boxNode;
|
||||
|
@ -109,9 +111,12 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
|||
|
||||
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 endAngle = speedometer->maximum();
|
||||
const auto step = ( endAngle - startAngle ) / ( labelsCount - 1 );
|
||||
|
@ -130,10 +135,12 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
|||
panelRect.y() + panelRect.height() / 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 ) );
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
// ### skin hint for each of highlighted / normal marks
|
||||
qreal length = 15;
|
||||
auto xEnd = center.x() + ( radius - length ) * cosine;
|
||||
auto yEnd = center.y() + ( radius - length ) * sine;
|
||||
|
||||
|
@ -154,8 +160,6 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
|||
|
||||
vertexData += 2;
|
||||
|
||||
QVector< QString > labels = speedometer->labels();
|
||||
|
||||
// only create a text node if there is a label for it:
|
||||
if ( labels.count() > i )
|
||||
{
|
||||
|
@ -182,8 +186,9 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q
|
|||
numbersNode = new QskTextNode();
|
||||
}
|
||||
|
||||
numbersNode->setTextData( speedometer, text, numbersRect, QFont(),
|
||||
QskTextOptions(), QskTextColors( Qt::white ),
|
||||
QFont font = speedometer->effectiveFont( Speedometer::Labels );
|
||||
numbersNode->setTextData( speedometer, text, numbersRect, font,
|
||||
QskTextOptions(), QskTextColors( color ),
|
||||
Qt::AlignCenter | Qt::AlignHCenter, Qsk::Normal );
|
||||
|
||||
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();
|
||||
|
||||
ticksNode->markDirty( QSGNode::DirtyGeometry );
|
||||
|
@ -206,7 +212,7 @@ QSGNode* SpeedometerSkinlet::updateNeedleNode( const Speedometer* speedometer, Q
|
|||
{
|
||||
QMarginsF margins = speedometer->marginsHint( Speedometer::Panel | QskAspect::Margin );
|
||||
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,
|
||||
panelRect.y() + panelRect.height() / 2 );
|
||||
|
||||
|
@ -217,38 +223,43 @@ QSGNode* SpeedometerSkinlet::updateNeedleNode( const Speedometer* speedometer, Q
|
|||
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,
|
||||
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 );
|
||||
|
||||
TicksNode* needleNode;
|
||||
|
||||
if ( boxNode->childCount() == 0 )
|
||||
{
|
||||
needleNode = new TicksNode( Qt::red );
|
||||
needleNode = new TicksNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
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 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 ,
|
||||
panelRadius - ( needleWidth + 10 ), 2 * needleWidth );
|
||||
float xStart = center.x() - needleWidth ;
|
||||
panelRadius - ( needleWidth + needleMargin ), 2 * needleWidth );
|
||||
float xStart = center.x();
|
||||
float yStart = center.y();
|
||||
|
||||
float angle = speedometer->value();
|
||||
qreal cosine = qCos( 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 yEnd = center.y() + needleRadius * sine;
|
||||
|
||||
|
|
Loading…
Reference in New Issue