diff --git a/examples/automotive/DefaultSkin.cpp b/examples/automotive/DefaultSkin.cpp index 817a80ec..38aec733 100644 --- a/examples/automotive/DefaultSkin.cpp +++ b/examples/automotive/DefaultSkin.cpp @@ -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 } ) { diff --git a/examples/automotive/MainWindow.cpp b/examples/automotive/MainWindow.cpp index f648a107..8972a10b 100644 --- a/examples/automotive/MainWindow.cpp +++ b/examples/automotive/MainWindow.cpp @@ -13,7 +13,7 @@ #include #include -#define SPEEDO 0 +#define SPEEDO 1 MainWindow::MainWindow() { diff --git a/examples/automotive/OtherSkin.cpp b/examples/automotive/OtherSkin.cpp index c0a34fbe..3512d1d0 100644 --- a/examples/automotive/OtherSkin.cpp +++ b/examples/automotive/OtherSkin.cpp @@ -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() diff --git a/examples/automotive/SkinFactory.cpp b/examples/automotive/SkinFactory.cpp index 9248478f..ed3036cc 100644 --- a/examples/automotive/SkinFactory.cpp +++ b/examples/automotive/SkinFactory.cpp @@ -16,7 +16,7 @@ QStringList SkinFactory::skinNames() const { - return { "DefaultSkin", "OtherSkin", "SquiekSkin", "MaterialSkin" }; + return { "DefaultSkin", "OtherSkin" }; } QskSkin* SkinFactory::createSkin( const QString& skinName ) diff --git a/examples/automotive/Speedometer.cpp b/examples/automotive/Speedometer.cpp index b3f439f6..769ebefc 100644 --- a/examples/automotive/Speedometer.cpp +++ b/examples/automotive/Speedometer.cpp @@ -5,47 +5,14 @@ QSK_SUBCONTROL( Speedometer, Panel ) QSK_SUBCONTROL( Speedometer, Labels ) +QSK_SUBCONTROL( Speedometer, NeedleHead ) QSK_SUBCONTROL( Speedometer, Needle ) Speedometer::Speedometer( QQuickItem* parent ) : - QskControl( parent ), - m_value( 0.0 ), - m_startAngle( -215 ), - m_endAngle( 35 ) + QskRangeControl( parent ) { } -float Speedometer::value() const -{ - return m_value; -} - -void Speedometer::setValue( float value ) -{ - m_value = value; - update(); -} - -float Speedometer::startAngle() const -{ - return m_startAngle; -} - -void Speedometer::setStartAngle( float startAngle ) -{ - m_startAngle = startAngle; -} - -float Speedometer::endAngle() const -{ - return m_endAngle; -} - -void Speedometer::setEndAngle( float endAngle ) -{ - m_endAngle = endAngle; -} - QVector< QString > Speedometer::labels() const { return m_labels; diff --git a/examples/automotive/Speedometer.h b/examples/automotive/Speedometer.h index 70b083df..a3ee8051 100644 --- a/examples/automotive/Speedometer.h +++ b/examples/automotive/Speedometer.h @@ -1,33 +1,21 @@ #ifndef SPEEDOMETER_H #define SPEEDOMETER_H -#include +#include -class Speedometer : public QskControl +class Speedometer : public QskRangeControl { Q_OBJECT public: - QSK_SUBCONTROLS( Panel, Labels, Needle ) + QSK_SUBCONTROLS( Panel, Labels, NeedleHead, Needle ) Speedometer( QQuickItem* parent = nullptr ); - float value() const; - void setValue( float value ); // angle; should be within a set range - - float startAngle() const; - void setStartAngle( float startAngle ); - - float endAngle() const; - void setEndAngle( float endAngle ); - QVector< QString > labels() const; void setLabels( const QVector< QString >& labels ); private: - float m_value; - float m_startAngle; - float m_endAngle; float m_labelsStep; QVector< QString > m_labels; }; diff --git a/examples/automotive/SpeedometerDisplay.cpp b/examples/automotive/SpeedometerDisplay.cpp index 86cfd28b..859bec74 100644 --- a/examples/automotive/SpeedometerDisplay.cpp +++ b/examples/automotive/SpeedometerDisplay.cpp @@ -29,11 +29,12 @@ SpeedometerDisplay::SpeedometerDisplay( QQuickItem *parent ) : m_box->setSpacing( 20 ); m_revCounter->setObjectName( QStringLiteral( "RevCounter" ) ); - int startAngle = 145, endAngle = 305, value = 200, numberLabels = 8; - m_revCounter->setStartAngle( startAngle ); - m_revCounter->setEndAngle( endAngle ); - m_revCounter->setValue( value ); + m_revCounter->setMinimum( 145 ); + m_revCounter->setMaximum( 305 ); + m_revCounter->setValue( 200 ); QVector< QString > revCounterLabels; + int numberLabels = 8; + revCounterLabels.reserve( numberLabels ); for ( int i = 0; i < numberLabels; ++i ) { @@ -43,14 +44,11 @@ SpeedometerDisplay::SpeedometerDisplay( QQuickItem *parent ) : m_revCounter->setLabels( revCounterLabels ); m_speedometer->setObjectName( QStringLiteral( "Speedometer" ) ); - value = 280; - numberLabels = 23; - startAngle = -215; - endAngle = 35; - m_speedometer->setStartAngle( startAngle ); - m_speedometer->setEndAngle( endAngle ); - m_speedometer->setValue( value ); + m_speedometer->setMinimum( -215 ); + m_speedometer->setMaximum( 35 ); + m_speedometer->setValue( -90 ); QVector< QString > speedometerLabels; + numberLabels = 23; speedometerLabels.reserve( numberLabels ); for ( int i = 0; i < numberLabels; ++i ) @@ -76,8 +74,8 @@ SpeedometerDisplay::SpeedometerDisplay( QQuickItem *parent ) : m_fuelGauge->setObjectName( QStringLiteral( "Fuel Gauge" ) ); - m_fuelGauge->setStartAngle( 195 ); - m_fuelGauge->setEndAngle( 345 ); + m_fuelGauge->setMinimum( 195 ); + m_fuelGauge->setMaximum( 345 ); m_fuelGauge->setValue( 330 ); QVector< QString > fuelGaugeLabels; diff --git a/examples/automotive/SpeedometerSkinlet.cpp b/examples/automotive/SpeedometerSkinlet.cpp index 8d4fee4b..67fcd3a9 100644 --- a/examples/automotive/SpeedometerSkinlet.cpp +++ b/examples/automotive/SpeedometerSkinlet.cpp @@ -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,11 +111,14 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q if ( ticksNode == nullptr ) { - ticksNode = new TicksNode( Qt::white ); + ticksNode = new TicksNode(); } - const float startAngle = speedometer->startAngle(); - const float endAngle = speedometer->endAngle(); + 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 ); auto geometry = ticksNode->geometry(); @@ -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 ) ); - float 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 for( int i = 0; i < labelsCount; ++i, angle += step ) @@ -141,33 +148,30 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode( const Speedometer* speedometer, Q qreal cosine = qCos( qDegreesToRadians( angle ) ); qreal sine = qSin( qDegreesToRadians( angle ) ); - float xStart = center.x() + radius * cosine; - float yStart = center.y() + radius * sine; + auto xStart = center.x() + radius * cosine; + auto yStart = center.y() + radius * sine; // ### skin hint for each of highlighted / normal marks - qreal length = 15; - float xEnd = center.x() + ( radius - length ) * cosine; - float yEnd = center.y() + ( radius - length ) * sine; + auto xEnd = center.x() + ( radius - length ) * cosine; + auto yEnd = center.y() + ( radius - length ) * sine; vertexData[0].set( xStart, yStart ); vertexData[1].set( xEnd, yEnd ); vertexData += 2; - QVector< QString > labels = speedometer->labels(); - // only create a text node if there is a label for it: if ( labels.count() > i ) { const QString& text = labels.at( i ); - float w = fontMetrics.width( text ); - float h = fontMetrics.height(); - float adjustX = ( -0.5 * cosine - 0.5 ) * w; - float adjustY = ( -0.5 * sine - 0.5 ) * h; + auto w = fontMetrics.width( text ); + auto h = fontMetrics.height(); + auto adjustX = ( -0.5 * cosine - 0.5 ) * w; + auto adjustY = ( -0.5 * sine - 0.5 ) * h; - float numbersX = xEnd + ( -1 * numbersMargins.left() * cosine ) + adjustX; - float numbersY = yEnd + ( -1 * numbersMargins.top() * sine ) + adjustY; + auto numbersX = xEnd + ( -1 * numbersMargins.left() * cosine ) + adjustX; + auto numbersY = yEnd + ( -1 * numbersMargins.top() * sine ) + adjustY; QRectF numbersRect( numbersX, numbersY, w, h ); @@ -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; } - 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 ); + 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 ); 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;