diff --git a/examples/iotdashboard/BoxWithButtons.cpp b/examples/iotdashboard/BoxWithButtons.cpp index 87cf442b..153dd45d 100644 --- a/examples/iotdashboard/BoxWithButtons.cpp +++ b/examples/iotdashboard/BoxWithButtons.cpp @@ -4,19 +4,33 @@ *****************************************************************************/ #include "BoxWithButtons.h" - +#include "RoundButton.h" #include "RoundedIcon.h" #include "Skin.h" -#include "UpAndDownButton.h" #include +#include -QSK_SUBCONTROL( ButtonValueLabel, Text ) -QSK_SUBCONTROL( TitleAndValueBox, Panel ) +QSK_SUBCONTROL( BoxWithButtons, ValueText ) +QSK_SUBCONTROL( BoxWithButtons, ValuePanel ) QSK_SUBCONTROL( BoxWithButtons, Panel ) -QSK_SUBCONTROL( IndoorTemperature, Panel ) -QSK_SUBCONTROL( Humidity, Panel ) +namespace +{ + class UpAndDownBox : public QskLinearBox + { + public: + UpAndDownBox( QQuickItem* parent ) + : QskLinearBox( Qt::Vertical, parent ) + { + setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed ); + setSpacing( 0 ); + + new RoundButton( QskAspect::Top, this ); + new RoundButton( QskAspect::Bottom, this ); + } + }; +} BoxWithButtons::BoxWithButtons( const QString& title, const QString& value, bool isBright, QQuickItem* parent ) @@ -34,14 +48,15 @@ BoxWithButtons::BoxWithButtons( const QString& title, const QString& value, iconFile = iconFile.replace( ' ', '-' ); new RoundedIcon( iconFile, isBright, false, layout ); - auto* titleAndValue = new TitleAndValueBox( Qt::Vertical, layout ); + auto titleAndValue = new QskLinearBox( Qt::Vertical, layout ); + titleAndValue->setPanel( true ); + titleAndValue->setSubcontrolProxy( QskBox::Panel, ValuePanel ); auto* titleLabel = new QskTextLabel( title, titleAndValue ); titleLabel->setFontRole( Skin::TitleFont ); - new ButtonValueLabel( value, titleAndValue ); + auto valueLabel = new QskTextLabel( value, titleAndValue ); + valueLabel->setSubcontrolProxy( QskTextLabel::Text, ValueText ); - new UpAndDownButton( layout ); + new UpAndDownBox( layout ); } - -#include "moc_BoxWithButtons.cpp" diff --git a/examples/iotdashboard/BoxWithButtons.h b/examples/iotdashboard/BoxWithButtons.h index 53df80b6..03bba159 100644 --- a/examples/iotdashboard/BoxWithButtons.h +++ b/examples/iotdashboard/BoxWithButtons.h @@ -6,67 +6,12 @@ #pragma once #include "Box.h" -#include "RoundedIcon.h" - -#include -#include - -class ButtonValueLabel : public QskTextLabel -{ - Q_OBJECT - - public: - QSK_SUBCONTROLS( Text ) - - ButtonValueLabel( const QString& text, QQuickItem* parent ) - : QskTextLabel( text, parent ) - { - setSubcontrolProxy( QskTextLabel::Text, Text ); - } -}; - -class TitleAndValueBox : public QskLinearBox -{ - Q_OBJECT - - public: - QSK_SUBCONTROLS( Panel ) - - TitleAndValueBox( Qt::Orientation orientation, QQuickItem* parent ) - : QskLinearBox( orientation, parent ) - { - setPanel( true ); - setSubcontrolProxy( QskLinearBox::Panel, Panel ); - } -}; class BoxWithButtons : public Box { public: - QSK_SUBCONTROLS( Panel ) + QSK_SUBCONTROLS( Panel, ValuePanel, ValueText ) BoxWithButtons( const QString& title, const QString& value, bool isBright, QQuickItem* parent = nullptr ); }; - -class IndoorTemperature : public BoxWithButtons -{ - public: - QSK_SUBCONTROLS( Panel ) - - IndoorTemperature( QQuickItem* parent ) - : BoxWithButtons( "Indoor Temperature", "+24", true, parent ) - { - } -}; - -class Humidity : public BoxWithButtons -{ - public: - QSK_SUBCONTROLS( Panel ) - - Humidity( QQuickItem* parent ) - : BoxWithButtons( "Humidity", "30%", false, parent ) - { - } -}; diff --git a/examples/iotdashboard/CircularProgressBar.cpp b/examples/iotdashboard/CircularProgressBar.cpp index 7998e430..6db088d2 100644 --- a/examples/iotdashboard/CircularProgressBar.cpp +++ b/examples/iotdashboard/CircularProgressBar.cpp @@ -32,6 +32,36 @@ CircularProgressBar::CircularProgressBar( const QskGradient& gradient, int progr } ); } +double CircularProgressBar::width() const +{ + return m_width; +} + +void CircularProgressBar::setWidth( double width ) +{ + m_width = width; +} + +QColor CircularProgressBar::backgroundColor() const +{ + return m_backgroundColor; +} + +void CircularProgressBar::setBackgroundColor( const QColor& color ) +{ + m_backgroundColor = color; +} + +QRadialGradient CircularProgressBar::ringGradient() const +{ + return m_ringGradient; +} + +void CircularProgressBar::setRingGradient( const QRadialGradient& gradient ) +{ + m_ringGradient = gradient; +} + void CircularProgressBar::paint( QPainter* painter ) { auto size = contentsSize(); diff --git a/examples/iotdashboard/CircularProgressBar.h b/examples/iotdashboard/CircularProgressBar.h index 10acfc15..303ec346 100644 --- a/examples/iotdashboard/CircularProgressBar.h +++ b/examples/iotdashboard/CircularProgressBar.h @@ -17,35 +17,14 @@ class CircularProgressBar : public QQuickPaintedItem virtual void paint( QPainter* painter ) override; - double width() const - { - return m_width; - } + double width() const; + void setWidth( double width ); - void setWidth( double width ) - { - m_width = width; - } + QColor backgroundColor() const; + void setBackgroundColor( const QColor& ); - QColor backgroundColor() const - { - return m_backgroundColor; - } - - void setBackgroundColor( const QColor& color ) - { - m_backgroundColor = color; - } - - QRadialGradient ringGradient() const - { - return m_ringGradient; - } - - void setRingGradient( const QRadialGradient& gradient ) - { - m_ringGradient = gradient; - } + QRadialGradient ringGradient() const; + void setRingGradient( const QRadialGradient& ); private: QGradient m_gradient; diff --git a/examples/iotdashboard/LightIntensity.cpp b/examples/iotdashboard/LightIntensity.cpp index 345a0ebd..156845d9 100644 --- a/examples/iotdashboard/LightIntensity.cpp +++ b/examples/iotdashboard/LightIntensity.cpp @@ -10,104 +10,168 @@ #include #include #include +#include #include #include +#include #include #include -QSK_SUBCONTROL( LightIntensityValueLabel, Text ) - QSK_SUBCONTROL( LightDisplay, Panel ) QSK_SUBCONTROL( LightDisplay, ColdPart ) QSK_SUBCONTROL( LightDisplay, WarmPart ) +QSK_SUBCONTROL( LightDisplay, ValueText ) namespace { + class LightDimmer; + QColor invertedColor( const QColor& c ) { QColor ret = { 255 - c.red(), 255 - c.green(), 255 - c.blue()}; return ret; } -} -// ### There must be an easier way to do this -class DimmerAnimator : public QskAnimator -{ - public: - DimmerAnimator( LightDisplay* display, LightDimmer* dimmer ) - : m_display( display ) - , m_dimmer( dimmer ) + class LightDimmer : public QQuickPaintedItem { - QQuickWindow* w = static_cast< QQuickWindow* >( qGuiApp->allWindows().at( 0 ) ); - setWindow( w ); - setDuration( 500 ); - setEasingCurve( QEasingCurve::Linear ); - setAutoRepeat( false ); - } + public: + LightDimmer( const QskGradient& coldGradient, + const QskGradient& warmGradient, QQuickItem* parent ); - void setup() override - { - m_backgroundColor = m_display->color( LightDisplay::Panel ); - m_ringGradient = m_dimmer->ringGradient(); - } - - void advance( qreal value ) override - { - const QColor c = m_backgroundColor; - const QColor c2 = invertedColor( c ); - const QColor newColor = QskRgb::interpolated( c2, c, value ); - m_dimmer->setBackgroundColor( newColor ); - - QRadialGradient gradient = m_ringGradient; - QRadialGradient newGradient = gradient; - - for( const QGradientStop& stop : gradient.stops() ) + double thickness() const { - QColor c = stop.second; - QColor c2 = invertedColor( c ); - const QColor newColor = QskRgb::interpolated( c, c2, value ); - newGradient.setColorAt( stop.first, newColor ); + return m_thickness; } - m_dimmer->setRingGradient( newGradient ); - m_dimmer->update(); - } + void setThickness( double thickness ) + { + m_thickness = thickness; + } - private: - QColor m_backgroundColor; - QRadialGradient m_ringGradient; - LightDisplay* m_display; - LightDimmer* m_dimmer; -}; + QColor backgroundColor() const + { + return m_backgroundColor; + } -LightDimmer::LightDimmer( const QskGradient& coldGradient, const QskGradient& warmGradient, QQuickItem* parent ) + void setBackgroundColor( const QColor& color ) + { + m_backgroundColor = color; + } + + QRadialGradient ringGradient() const + { + return m_ringGradient; + } + + void setRingGradient( const QRadialGradient& gradient ) + { + m_ringGradient = gradient; + } + + QRectF ringRect() const + { + const qreal r = qMin( width(), height() ) - 4; + return QRectF( 0.0, 0.0, r, r ); + } + + private: + void paint( QPainter* ) override; + void updateGradient(); + + double m_thickness = 17.57; + QColor m_backgroundColor; + QRadialGradient m_ringGradient; + QskGradient m_coldGradient; + QskGradient m_warmGradient; + }; + + // ### There must be an easier way to do this + class DimmerAnimator : public QskAnimator + { + public: + DimmerAnimator( LightDisplay* display, LightDimmer* dimmer ) + : m_display( display ) + , m_dimmer( dimmer ) + { + QQuickWindow* w = static_cast< QQuickWindow* >( qGuiApp->allWindows().at( 0 ) ); + setWindow( w ); + setDuration( 500 ); + setEasingCurve( QEasingCurve::Linear ); + } + + void setup() override + { + m_backgroundColor = m_display->color( LightDisplay::Panel ); + m_ringGradient = m_dimmer->ringGradient(); + } + + void advance( qreal value ) override + { + const QColor c = m_backgroundColor; + const QColor c2 = invertedColor( c ); + const QColor newColor = QskRgb::interpolated( c2, c, value ); + m_dimmer->setBackgroundColor( newColor ); + + QRadialGradient gradient = m_ringGradient; + QRadialGradient newGradient = gradient; + + for( const QGradientStop& stop : gradient.stops() ) + { + QColor c = stop.second; + QColor c2 = invertedColor( c ); + const QColor newColor = QskRgb::interpolated( c, c2, value ); + newGradient.setColorAt( stop.first, newColor ); + } + + m_dimmer->setRingGradient( newGradient ); + m_dimmer->update(); + } + + private: + QColor m_backgroundColor; + QRadialGradient m_ringGradient; + LightDisplay* m_display; + LightDimmer* m_dimmer; + }; +} + +LightDimmer::LightDimmer( const QskGradient& coldGradient, + const QskGradient& warmGradient, QQuickItem* parent ) : QQuickPaintedItem( parent ) , m_coldGradient( coldGradient ) , m_warmGradient( warmGradient ) { - connect( this, &QQuickPaintedItem::contentsSizeChanged, [this]() - { - auto size = contentsSize(); - QRadialGradient ringGradient( size.width() / 2, size.height() / 2, 110 ); - QGradientStop stop1( 0.0, "#c0c0c0" ); - QGradientStop stop2( 0.5, "#f0f0f0" ); - QGradientStop stop3( 1.0, "#c0c0c0" ); - ringGradient.setStops( {stop1, stop2, stop3} ); + connect( this, &QQuickPaintedItem::widthChanged, + this, &LightDimmer::updateGradient ); - m_ringGradient = ringGradient; - } ); + connect( this, &QQuickPaintedItem::heightChanged, + this, &LightDimmer::updateGradient ); +} + +void LightDimmer::updateGradient() +{ + const auto sz = ringRect().size(); + + QRadialGradient ringGradient( sz.width() / 2, sz.height() / 2, 110 ); + QGradientStop stop1( 0.0, "#c0c0c0" ); + QGradientStop stop2( 0.5, "#f0f0f0" ); + QGradientStop stop3( 1.0, "#c0c0c0" ); + ringGradient.setStops( {stop1, stop2, stop3} ); + + m_ringGradient = ringGradient; } void LightDimmer::paint( QPainter* painter ) { + const auto sz = ringRect().size(); + const qreal knobDiameter = 15.65; const qreal offset = ( thickness() - knobDiameter ) + 2; painter->setRenderHint( QPainter::Antialiasing, true ); - auto size = contentsSize(); - QRectF outerRect( {0, offset}, size ); + QRectF outerRect( 0, offset, sz.width(), sz.height() ); painter->setBrush( m_ringGradient ); @@ -133,66 +197,52 @@ void LightDimmer::paint( QPainter* painter ) painter->setBrush( m_backgroundColor ); painter->setPen( m_backgroundColor ); - QRectF innerRect( thickness() / 2, thickness() / 2 + offset, size.width() - thickness(), size.height() - thickness() ); + QRectF innerRect( thickness() / 2, thickness() / 2 + offset, sz.width() - thickness(), sz.height() - thickness() ); painter->drawEllipse( innerRect ); painter->setBrush( m_backgroundColor ); painter->setPen( "#c4c4c4" ); - QRectF knobRect( ( contentsSize().width() - knobDiameter ) / 2, 1, knobDiameter, knobDiameter ); + QRectF knobRect( ( sz.width() - knobDiameter ) / 2, 1, knobDiameter, knobDiameter ); painter->drawEllipse( knobRect ); } LightDisplay::LightDisplay( QQuickItem* parent ) - : QskControl( parent ) - , m_leftLabel( new QskTextLabel( QString::number( 0 ), this ) ) - , m_centreLabel( new LightIntensityValueLabel( QString::number( 50 ) + "%", this ) ) - , m_rightLabel( new QskTextLabel( QString::number( 100 ), this ) ) - , m_dimmer( new LightDimmer( gradientHint( ColdPart ), gradientHint( WarmPart ), this ) ) - , m_animator( new DimmerAnimator( this, m_dimmer ) ) + : QskLinearBox( Qt::Horizontal, parent ) { setSubcontrolProxy( QskBox::Panel, LightDisplay::Panel ); - m_leftLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Maximum ); - m_centreLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Maximum ); - m_centreLabel->setZ( 1 ); - m_rightLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Maximum ); - m_rightLabel->setZ( 1 ); + auto leftLabel = new QskTextLabel( QString::number( 0 ), this ); + leftLabel->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); - setAutoLayoutChildren( true ); + auto rightLabel = new QskTextLabel( QString::number( 100 ), this ); + rightLabel->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); - const QColor c = color( Panel ); - m_dimmer->setBackgroundColor( c ); + auto dimmer = new LightDimmer( gradientHint( ColdPart ), gradientHint( WarmPart ), this ); + dimmer->setBackgroundColor( color( Panel ) ); - connect( qskSetup, &QskSetup::skinChanged, [this]() - { - m_animator->start(); - } ); + m_valueLabel = new QskTextLabel( QString::number( 50 ) + "%", dimmer ); + m_valueLabel->setSubcontrolProxy( QskTextLabel::Text, LightDisplay::ValueText ); + + addItem( leftLabel ); + addItem( dimmer ); + addItem( rightLabel ); + + auto animator = new DimmerAnimator( this, dimmer ); + connect( qskSetup, &QskSetup::skinChanged, + [animator]() { animator->start(); } ); } void LightDisplay::updateLayout() { - const qreal w = width() - ( m_leftLabel->width() + m_rightLabel->width() ); - const int r = qMin( w, height() ); - m_dimmer->setContentsSize( {r - 4, r - 4} ); // for some reason we need some padding, hence the 4 - m_dimmer->setSize( QSizeF( r, r ) ); - const qreal padding = 8; - const qreal x = ( width() - ( m_leftLabel->width() + 2 * padding + m_dimmer->width() + m_rightLabel->width() ) ) / 2; - const qreal offset = 2; // circle doesn't start at 0 - m_leftLabel->setPosition( {x, ( m_dimmer->height() - m_leftLabel->height() ) / 2 + offset} ); + QskLinearBox::updateLayout(); - m_dimmer->setPosition( {m_leftLabel->x() + m_leftLabel->width() + padding, 0} ); + auto dimmer = static_cast< const LightDimmer* >( m_valueLabel->parentItem() ); - qreal centreX = m_dimmer->x() + ( m_dimmer->width() - m_centreLabel->width() ) / 2; - qreal centreY = m_dimmer->y() + ( m_dimmer->height() - m_centreLabel->height() ) / 2; - m_centreLabel->setPosition( {centreX, centreY + offset} ); + QRectF r; + r.setSize( m_valueLabel->sizeConstraint() ); + r.moveCenter( dimmer->ringRect().center() + QPointF( 0, 4 ) ); - m_rightLabel->setPosition( {m_dimmer->x() + m_dimmer->width() + padding, m_leftLabel->y()} ); -} - -LightIntensity::LightIntensity( QQuickItem* parent ) - : Box( "Light intensity", parent ) -{ - new LightDisplay( this ); + m_valueLabel->setGeometry( r ); } #include "moc_LightIntensity.cpp" diff --git a/examples/iotdashboard/LightIntensity.h b/examples/iotdashboard/LightIntensity.h index b2d202d0..ccdb4755 100644 --- a/examples/iotdashboard/LightIntensity.h +++ b/examples/iotdashboard/LightIntensity.h @@ -5,102 +5,22 @@ #pragma once -#include "Box.h" +#include -#include - -#include -#include - -class DimmerAnimator; class QskTextLabel; -class LightIntensityValueLabel : public QskTextLabel +class LightDisplay : public QskLinearBox { Q_OBJECT public: - QSK_SUBCONTROLS( Text ) + QSK_SUBCONTROLS( Panel, ColdPart, WarmPart, ValueText ) - LightIntensityValueLabel( const QString& text, QQuickItem* parent ) - : QskTextLabel( text, parent ) - { - setSubcontrolProxy( QskTextLabel::Text, Text ); - } -}; - -class LightDimmer : public QQuickPaintedItem -{ - Q_OBJECT - - public: - LightDimmer( const QskGradient& coldGradient, - const QskGradient& warmGradient, QQuickItem* parent ); - - double thickness() const - { - return m_thickness; - } - - void setThickness( double thickness ) - { - m_thickness = thickness; - } - - QColor backgroundColor() const - { - return m_backgroundColor; - } - - void setBackgroundColor( const QColor& color ) - { - m_backgroundColor = color; - } - - QRadialGradient ringGradient() const - { - return m_ringGradient; - } - - void setRingGradient( const QRadialGradient& gradient ) - { - m_ringGradient = gradient; - } - - private: - virtual void paint( QPainter* painter ) override; - - double m_thickness = 17.57; - QColor m_backgroundColor; - QRadialGradient m_ringGradient; - QskGradient m_coldGradient; - QskGradient m_warmGradient; -}; - -class LightDisplay : public QskControl -{ - Q_OBJECT - - public: - QSK_SUBCONTROLS( Panel, ColdPart, WarmPart ) - - LightDisplay( QQuickItem* parent ); + LightDisplay( QQuickItem* parent = nullptr ); protected: void updateLayout() override; private: - QskTextLabel* m_leftLabel; - LightIntensityValueLabel* m_centreLabel; - QskTextLabel* m_rightLabel; - LightDimmer* m_dimmer; - DimmerAnimator* m_animator; -}; - -class LightIntensity : public Box -{ - Q_OBJECT - - public: - LightIntensity( QQuickItem* parent ); + QskTextLabel* m_valueLabel; }; diff --git a/examples/iotdashboard/MainContent.cpp b/examples/iotdashboard/MainContent.cpp index a17cb61b..a2f8fe1b 100644 --- a/examples/iotdashboard/MainContent.cpp +++ b/examples/iotdashboard/MainContent.cpp @@ -12,7 +12,7 @@ #include "MyDevices.h" #include "PieChart.h" #include "TopBar.h" -#include "Usage.h" +#include "UsageBox.h" #include #include @@ -32,6 +32,37 @@ QSK_SUBCONTROL( ShadowPositioner, Panel ) QSK_SUBCONTROL( MainContent, Panel ) QSK_SUBCONTROL( MainContentGridBox, Panel ) +namespace +{ + class IndoorTemperature : public BoxWithButtons + { + public: + IndoorTemperature( QQuickItem* parent = nullptr ) + : BoxWithButtons( "Indoor Temperature", "+24", true, parent ) + { + } + }; + + class Humidity : public BoxWithButtons + { + public: + Humidity( QQuickItem* parent = nullptr ) + : BoxWithButtons( "Humidity", "30%", false, parent ) + { + } + }; + + class LightIntensity : public Box + { + public: + LightIntensity( QQuickItem* parent = nullptr ) + : Box( "Light intensity", parent ) + { + new LightDisplay( this ); + } + }; +} + ShadowPositioner::ShadowPositioner( QQuickItem* parent ) : QskControl( parent ) { @@ -45,7 +76,7 @@ void ShadowPositioner::setGridBox( QskGridBox* gridBox ) for( int i = 0; i < m_gridBox->elementCount(); ++i ) { - auto* r = new ShadowedRectangle( this ); + auto r = new ShadowedRectangle( this ); r->setZ( 5 ); r->setColor( Qt::transparent ); r->shadow()->setColor( color( ShadowPositioner::Panel ) ); @@ -69,15 +100,18 @@ void ShadowPositioner::setGridBox( QskGridBox* gridBox ) void ShadowPositioner::updateLayout() { - auto* mainContent = static_cast< QskLinearBox* >( parentItem() ); + auto mainContent = static_cast< QskLinearBox* >( parentItem() ); QTimer::singleShot( 0, this, [this, mainContent]() { + const auto pos0 = mainContent->itemAtIndex( 1 )->position(); + for( int i = 0; i < m_rectangles.count(); ++i ) { - auto* item = m_gridBox->itemAtIndex( i ); + const auto item = m_gridBox->itemAtIndex( i ); + + m_rectangles[i]->setPosition( pos0 + item->position() ); m_rectangles[i]->setSize( qskItemSize( item ) ); - m_rectangles[i]->setPosition( mainContent->itemAtIndex( 1 )->position() + item->position() ); } } ); } @@ -93,37 +127,26 @@ MainContent::MainContent( QQuickItem* parent ) setDefaultAlignment( Qt::AlignTop ); setSpacing( 24 ); - auto* topBar = new TopBar( this ); - addItem( topBar ); + auto topBar = new TopBar(); - auto* gridBox = new MainContentGridBox( this ); + auto gridBox = new MainContentGridBox(); gridBox->setPanel( true ); gridBox->setSpacing( 15 ); - addItem( gridBox ); - auto* usage = new Usage( gridBox ); - - gridBox->addItem( usage, 0, 0, 2, 1 ); - - auto* indoorTemperature = new IndoorTemperature( gridBox ); - gridBox->addItem( indoorTemperature, 0, 1 ); - - auto* humidity = new Humidity( gridBox ); - gridBox->addItem( humidity, 1, 1 ); - - auto* myDevices = new MyDevices( gridBox ); - gridBox->addItem( myDevices, 0, 2, 2, 1 ); - - auto* diagram = new UsageDiagram( gridBox ); - gridBox->addItem( diagram, 2, 0, 0, 2 ); - - auto* lightIntensity = new LightIntensity( gridBox ); - gridBox->addItem( lightIntensity, 2, 2 ); + gridBox->addItem( new UsageBox(), 0, 0, 2, 1 ); + gridBox->addItem( new IndoorTemperature(), 0, 1 ); + gridBox->addItem( new Humidity(), 1, 1 ); + gridBox->addItem( new MyDevices(), 0, 2, 2, 1 ); + gridBox->addItem( new UsageDiagram(), 2, 0, 0, 2 ); + gridBox->addItem( new LightIntensity(), 2, 2 ); gridBox->setColumnStretchFactor( 0, 37 ); // factors add up to 100 gridBox->setColumnStretchFactor( 1, 37 ); gridBox->setColumnStretchFactor( 2, 26 ); + addItem( topBar ); + addItem( gridBox ); + m_shadowPositioner = new ShadowPositioner( this ); m_shadowPositioner->setGridBox( gridBox ); } diff --git a/examples/iotdashboard/MainWindow.cpp b/examples/iotdashboard/MainWindow.cpp index cb1a0b70..3794c622 100644 --- a/examples/iotdashboard/MainWindow.cpp +++ b/examples/iotdashboard/MainWindow.cpp @@ -4,22 +4,21 @@ *****************************************************************************/ #include "MainWindow.h" - #include "MainContent.h" #include "MenuBar.h" #include MainWindow::MainWindow() - : QskWindow() - , m_mainLayout( new QskLinearBox( Qt::Horizontal, contentItem() ) ) - , m_menuBar( new MenuBar( m_mainLayout ) ) - , m_mainContent( new MainContent( m_mainLayout ) ) { - setPreferredSize( { 1024, 600 } ); + setPreferredSize( QSize( 1024, 600 ) ); setTitle( "IOT dashboard" ); - m_mainLayout->setSpacing( 0 ); + auto layout = new QskLinearBox( Qt::Horizontal, contentItem() ); + layout->setSpacing( 0 ); + + (void) new MenuBar( layout ); + (void) new MainContent( layout ); } #include "moc_MainWindow.cpp" diff --git a/examples/iotdashboard/MainWindow.h b/examples/iotdashboard/MainWindow.h index 51d2e0fd..a03b36f3 100644 --- a/examples/iotdashboard/MainWindow.h +++ b/examples/iotdashboard/MainWindow.h @@ -7,19 +7,10 @@ #include -class MainContent; -class MenuBar; -class QskLinearBox; - class MainWindow : public QskWindow { Q_OBJECT public: MainWindow(); - - private: - QskLinearBox* m_mainLayout; - MenuBar* m_menuBar; - MainContent* m_mainContent; }; diff --git a/examples/iotdashboard/MenuBar.cpp b/examples/iotdashboard/MenuBar.cpp index c1eda93b..54a8ada4 100644 --- a/examples/iotdashboard/MenuBar.cpp +++ b/examples/iotdashboard/MenuBar.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include QSK_SUBCONTROL( MenuBarTopLabel, Graphic ) QSK_SUBCONTROL( MenuBarGraphicLabel, Graphic ) @@ -23,11 +23,8 @@ QSK_STATE( MenuItem, Active, ( QskAspect::FirstUserState << 1 ) ) MenuItem::MenuItem( const QString& name, QQuickItem* parent ) : QskLinearBox( Qt::Horizontal, parent ) - , m_name( name ) { - setAutoLayoutChildren( true ); - setAutoAddChildren( true ); - setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); + initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); setSpacing( 6 ); setAcceptHoverEvents( true ); @@ -38,7 +35,8 @@ MenuItem::MenuItem( const QString& name, QQuickItem* parent ) QString fileName = ":/images/" + name.toLower() + ".png"; QImage image( fileName ); auto graphic = QskGraphic::fromImage( image ); - auto* graphicLabel = new MenuBarGraphicLabel( graphic, this ); + + auto graphicLabel = new MenuBarGraphicLabel( graphic, this ); graphicLabel->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); graphicLabel->setFixedWidth( metric( MenuBarGraphicLabel::Graphic | QskAspect::Size ) ); @@ -51,13 +49,12 @@ MenuBar::MenuBar( QQuickItem* parent ) setPanel( true ); setSubcontrolProxy( QskBox::Panel, MenuBar::Panel ); - setSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Preferred ); + initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Preferred ); setSpacing( 8 ); - auto* mainIcon = ":/images/main-icon.png"; - QImage image( mainIcon ); - auto graphic = QskGraphic::fromImage( image ); - auto* graphicLabel = new MenuBarTopLabel( graphic, this ); + auto graphic = QskGraphic::fromImage( QImage( ":/images/main-icon.png" ) ); + + auto graphicLabel = new MenuBarTopLabel( graphic, this ); graphicLabel->setMargins( marginHint( MenuBarTopLabel::Graphic ) ); graphicLabel->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); diff --git a/examples/iotdashboard/MenuBar.h b/examples/iotdashboard/MenuBar.h index bf2718fb..a0a6f5fe 100644 --- a/examples/iotdashboard/MenuBar.h +++ b/examples/iotdashboard/MenuBar.h @@ -60,9 +60,6 @@ class MenuItem final : public QskLinearBox QSK_STATES( Active ) MenuItem( const QString& name, QQuickItem* parent ); - - private: - QString m_name; }; class MenuBar final : public QskLinearBox diff --git a/examples/iotdashboard/MyDevices.cpp b/examples/iotdashboard/MyDevices.cpp index 4c6bb938..e947275b 100644 --- a/examples/iotdashboard/MyDevices.cpp +++ b/examples/iotdashboard/MyDevices.cpp @@ -52,9 +52,11 @@ namespace // We cannot use the icon from RoundedIcon here because // it would inherit the transparency const qreal size = metric( RoundedIcon::Icon | QskAspect::Size ); - m_graphicLabel->setSize( {size, size} ); - m_graphicLabel->setPosition( { m_icon->position().x() + ( m_icon->width() - m_graphicLabel->width() ) / 2, - ( m_icon->position().y() + m_icon->height() - m_graphicLabel->height() ) / 2 } ); + + const qreal x = m_icon->x() + ( m_icon->width() - m_graphicLabel->width() ) / 2; + const qreal y = ( m_icon->y() + m_icon->height() - m_graphicLabel->height() ) / 2; + + m_graphicLabel->setGeometry( x, y, size, size ); } private: diff --git a/examples/iotdashboard/MyDevices.h b/examples/iotdashboard/MyDevices.h index c2f2fee9..b22961d8 100644 --- a/examples/iotdashboard/MyDevices.h +++ b/examples/iotdashboard/MyDevices.h @@ -10,5 +10,5 @@ class MyDevices : public Box { public: - MyDevices( QQuickItem* parent ); + MyDevices( QQuickItem* parent = nullptr ); }; diff --git a/examples/iotdashboard/PieChartPainted.cpp b/examples/iotdashboard/PieChartPainted.cpp index 2a3c0324..d6e2e23f 100644 --- a/examples/iotdashboard/PieChartPainted.cpp +++ b/examples/iotdashboard/PieChartPainted.cpp @@ -119,6 +119,6 @@ void PieChartPainted::updateLayout() auto posX = rect.width() / 2 - textWidth / 2; auto posY = rect.height() / 2 - fm.height() / 2; - m_progressLabel->setPosition( { posX, posY } ); + m_progressLabel->setPosition( posX, posY ); m_progressLabel->setFixedWidth( textWidth ); } diff --git a/examples/iotdashboard/UpAndDownButton.cpp b/examples/iotdashboard/RoundButton.cpp similarity index 72% rename from examples/iotdashboard/UpAndDownButton.cpp rename to examples/iotdashboard/RoundButton.cpp index a360b1d0..b5c71173 100644 --- a/examples/iotdashboard/UpAndDownButton.cpp +++ b/examples/iotdashboard/RoundButton.cpp @@ -3,11 +3,9 @@ * This file may be used under the terms of the 3-clause BSD License *****************************************************************************/ -#include "UpAndDownButton.h" +#include "RoundButton.h" -#include #include -#include #include #include @@ -39,15 +37,3 @@ RoundButton::RoundButton( QskAspect::Placement placement, QQuickItem* parent ) graphic = QskGraphic::fromImage( image ); setGraphic( graphic ); } - -UpAndDownButton::UpAndDownButton( QQuickItem* parent ) - : QskLinearBox( Qt::Vertical, parent ) -{ - setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed ); - setSpacing( 0 ); - - new RoundButton( QskAspect::Top, this ); - new RoundButton( QskAspect::Bottom, this ); -} - -#include "moc_UpAndDownButton.cpp" diff --git a/examples/iotdashboard/UpAndDownButton.h b/examples/iotdashboard/RoundButton.h similarity index 66% rename from examples/iotdashboard/UpAndDownButton.h rename to examples/iotdashboard/RoundButton.h index 37625779..5064b055 100644 --- a/examples/iotdashboard/UpAndDownButton.h +++ b/examples/iotdashboard/RoundButton.h @@ -5,7 +5,6 @@ #pragma once -#include #include class RoundButton : QskPushButton @@ -16,13 +15,5 @@ class RoundButton : QskPushButton QSK_SUBCONTROLS( Panel ) QSK_STATES( Top ) - RoundButton( QskAspect::Placement placement, QQuickItem* parent ); -}; - -class UpAndDownButton : public QskLinearBox -{ - Q_OBJECT - - public: - UpAndDownButton( QQuickItem* parent ); + RoundButton( QskAspect::Placement, QQuickItem* parent ); }; diff --git a/examples/iotdashboard/RoundedIcon.cpp b/examples/iotdashboard/RoundedIcon.cpp index a9c0457d..b619d11b 100644 --- a/examples/iotdashboard/RoundedIcon.cpp +++ b/examples/iotdashboard/RoundedIcon.cpp @@ -22,6 +22,7 @@ RoundedIcon::RoundedIcon( const QString& iconName, bool isBright, bool isSmall, { setPanel( true ); setPolishOnResize( true ); + setSubcontrolProxy( QskBox::Panel, Panel ); if( isSmall ) { @@ -37,7 +38,7 @@ RoundedIcon::RoundedIcon( const QString& iconName, bool isBright, bool isSmall, setSkinState( Bright ); } - QString fileName = ":/images/" + iconName + ".png"; + const QString fileName( ":/images/" + iconName + ".png" ); if( QFile::exists( fileName ) ) { @@ -47,21 +48,16 @@ RoundedIcon::RoundedIcon( const QString& iconName, bool isBright, bool isSmall, } } -QskAspect::Subcontrol RoundedIcon::substitutedSubcontrol( QskAspect::Subcontrol subControl ) const -{ - if( subControl == QskBox::Panel ) - return Panel; - - return subControl; -} - void RoundedIcon::updateLayout() { if( m_graphicLabel ) { - const qreal size = metric( Icon | QskAspect::Size ); - m_graphicLabel->setSize( {size, size} ); - m_graphicLabel->setPosition( { ( width() - m_graphicLabel->width() ) / 2, ( height() - m_graphicLabel->height() ) / 2 } ); + const auto size = metric( Icon | QskAspect::Size ); + + QRectF r( 0.0, 0.0, size, size ); + r.moveCenter( rect().center() ); + + m_graphicLabel->setGeometry( r ); } } diff --git a/examples/iotdashboard/RoundedIcon.h b/examples/iotdashboard/RoundedIcon.h index 3cc0edf1..ca3091e8 100644 --- a/examples/iotdashboard/RoundedIcon.h +++ b/examples/iotdashboard/RoundedIcon.h @@ -22,9 +22,6 @@ class RoundedIcon : public QskBox QQuickItem* parent = nullptr ); protected: - QskAspect::Subcontrol substitutedSubcontrol( - QskAspect::Subcontrol ) const override; - void updateLayout() override; virtual QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; diff --git a/examples/iotdashboard/Skin.cpp b/examples/iotdashboard/Skin.cpp index f2a14d01..74654d11 100644 --- a/examples/iotdashboard/Skin.cpp +++ b/examples/iotdashboard/Skin.cpp @@ -13,11 +13,13 @@ #include "MainContent.h" #include "MenuBar.h" #include "PieChartPainted.h" +#include "RoundedIcon.h" #include "TopBar.h" -#include "UpAndDownButton.h" -#include "Usage.h" +#include "RoundButton.h" +#include "UsageBox.h" #include "UsageDiagram.h" +#include #include #include #include @@ -121,8 +123,8 @@ void Skin::initHints( const Palette& palette ) // content in boxes (indoor temperature, humidity etc.): - ed.setFontRole( UsageSpacer::Text, QskSkin::SmallFont ); - ed.setColor( UsageSpacer::Text, "#dddddd" ); + ed.setFontRole( UsageBox::Separator, QskSkin::SmallFont ); + ed.setColor( UsageBox::Separator, "#dddddd" ); ed.setPadding( BoxWithButtons::Panel, 8 ); @@ -133,10 +135,10 @@ void Skin::initHints( const Palette& palette ) ed.setMetric( RoundedIcon::Panel | RoundedIcon::Small | QskAspect::Size, 60 ); ed.setMetric( RoundedIcon::Icon | QskAspect::Size, 36 ); - ed.setFontRole( ButtonValueLabel::Text, QskSkin::HugeFont ); - ed.setColor( ButtonValueLabel::Text, "#929cb2" ); + ed.setFontRole( BoxWithButtons::ValueText, QskSkin::HugeFont ); + ed.setColor( BoxWithButtons::ValueText, "#929cb2" ); - ed.setPadding( TitleAndValueBox::Panel, {0, 10, 0, 0} ); + ed.setPadding( BoxWithButtons::ValuePanel, {0, 10, 0, 0} ); ed.setStrutSize( RoundButton::Panel, {27, 38} ); ed.setBoxShape( RoundButton::Panel, {0, 0, 30, 30} ); @@ -170,8 +172,8 @@ void Skin::initHints( const Palette& palette ) // light intensity: ed.setGradient( LightDisplay::ColdPart, { Qt::Horizontal, "#a7b0ff", "#6776ff" } ); ed.setGradient( LightDisplay::WarmPart, { Qt::Horizontal, "#feeeb7", "#ff3122" } ); - ed.setFontRole( LightIntensityValueLabel::Text, QskSkin::LargeFont ); - ed.setColor( LightIntensityValueLabel::Text, "#929cb2" ); + ed.setFontRole( LightDisplay::ValueText, QskSkin::LargeFont ); + ed.setColor( LightDisplay::ValueText, "#929cb2" ); // palette dependent skin hints: diff --git a/examples/iotdashboard/TopBar.cpp b/examples/iotdashboard/TopBar.cpp index b6044407..be4d71dc 100644 --- a/examples/iotdashboard/TopBar.cpp +++ b/examples/iotdashboard/TopBar.cpp @@ -63,17 +63,16 @@ TopBarItem::TopBarItem( int index, const QString& name, const QskGradient& gradi QColor textColor = color( subcontrol | QskAspect::TextColor ); new PieChartPainted( textColor, gradient, progress, value, pieChartAndDisplay ); - auto* display = new QskLinearBox( Qt::Vertical, pieChartAndDisplay ); + auto display = new QskLinearBox( Qt::Vertical, pieChartAndDisplay ); display->setSpacing( 0 ); display->addSpacer( 0, 1 ); - auto* displayValue = new QskTextLabel( QString::number( value ), display ); + auto displayValue = new QskTextLabel( QString::number( value ), display ); displayValue->setFontRole( QskSkin::MediumFont ); - auto* displayUnit = new QskTextLabel( "kwH", display ); + auto displayUnit = new QskTextLabel( "kwH", display ); displayUnit->setFontRole( QskSkin::SmallFont ); display->addSpacer( 0, 1 ); - } TopBar::TopBar( QQuickItem* parent ) @@ -86,20 +85,22 @@ TopBar::TopBar( QQuickItem* parent ) setAutoAddChildren( true ); setSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Fixed ); - QStringList itemStrings = { "Living Room", "Bedroom", "Bathroom", "Kitchen" }; - int progressValues[] = {25, 45, 15, 86}; - int values[] = {175, 205, 115, 289}; + const QStringList itemStrings = { "Living Room", "Bedroom", "Bathroom", "Kitchen" }; + const int progressValues[] = {25, 45, 15, 86}; + const int values[] = {175, 205, 115, 289}; for( int i = 0; i < itemStrings.count(); i++ ) { - QskAspect::Subcontrol subcontrol = subcontrolForIndex( i ); - QskGradient gradient = gradientHint( subcontrol ); + const auto subcontrol = subcontrolForIndex( i ); + const auto gradient = gradientHint( subcontrol ); - auto* item = new TopBarItem( i, itemStrings.at( i ), gradient, progressValues[i], values[i], this ); - m_entries.append( item ); + auto item = new TopBarItem( i, itemStrings.at( i ), + gradient, progressValues[i], values[i], this ); + + m_entries += item; } - auto* timeControl = new QskLinearBox( Qt::Vertical, this ); + auto timeControl = new QskLinearBox( Qt::Vertical, this ); new TimeTitleLabel( "Current time", timeControl ); auto now = QTime::currentTime(); diff --git a/examples/iotdashboard/TopBar.h b/examples/iotdashboard/TopBar.h index 81e76661..1f595c1c 100644 --- a/examples/iotdashboard/TopBar.h +++ b/examples/iotdashboard/TopBar.h @@ -59,7 +59,7 @@ class TopBar : public QskLinearBox public: QSK_SUBCONTROLS( Panel ) - TopBar( QQuickItem* parent ); + TopBar( QQuickItem* parent = nullptr ); private: QList< TopBarItem* > m_entries; diff --git a/examples/iotdashboard/Usage.h b/examples/iotdashboard/Usage.h deleted file mode 100644 index f6ab3fe6..00000000 --- a/examples/iotdashboard/Usage.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2021 Edelhirsch Software GmbH - * This file may be used under the terms of the 3-clause BSD License - *****************************************************************************/ - -#pragma once - -#include "Box.h" -#include - -class UsageSpacer : public QskTextLabel -{ - Q_OBJECT - - public: - QSK_SUBCONTROLS( Text ) - - UsageSpacer( QQuickItem* parent = nullptr ) - : QskTextLabel( "_____", parent ) - { - setSubcontrolProxy( QskTextLabel::Text, Text ); - } -}; - -class Usage : public Box -{ - public: - Usage( QQuickItem* parent ); -}; diff --git a/examples/iotdashboard/Usage.cpp b/examples/iotdashboard/UsageBox.cpp similarity index 72% rename from examples/iotdashboard/Usage.cpp rename to examples/iotdashboard/UsageBox.cpp index 8f53188e..60d18930 100644 --- a/examples/iotdashboard/Usage.cpp +++ b/examples/iotdashboard/UsageBox.cpp @@ -3,14 +3,28 @@ * This file may be used under the terms of the 3-clause BSD License *****************************************************************************/ -#include "Usage.h" +#include "UsageBox.h" #include "Skin.h" #include -QSK_SUBCONTROL( UsageSpacer, Text ) +QSK_SUBCONTROL( UsageBox, Separator ) -Usage::Usage( QQuickItem* parent ) +namespace +{ + class SeparatorLabel : public QskTextLabel + { + public: + + SeparatorLabel( QQuickItem* parent = nullptr ) + : QskTextLabel( "_____", parent ) + { + setSubcontrolProxy( QskTextLabel::Text, UsageBox::Separator ); + } + }; +} + +UsageBox::UsageBox( QQuickItem* parent ) : Box( "Usage", parent ) { auto* content = new QskLinearBox( Qt::Vertical, this ); @@ -18,23 +32,27 @@ Usage::Usage( QQuickItem* parent ) auto* today = new QskLinearBox( Qt::Horizontal, content ); auto* todayText = new QskTextLabel( "Usage today", today ); todayText->setFontRole( QskSkin::SmallFont ); - new UsageSpacer( today ); + + new SeparatorLabel( today ); + auto* todayValue = new QskTextLabel( "0,5 kwH", today ); todayValue->setFontRole( QskSkin::SmallFont ); auto* month = new QskLinearBox( Qt::Horizontal, content ); auto* monthText = new QskTextLabel( "Usage this month", month ); monthText->setFontRole( QskSkin::SmallFont ); - new UsageSpacer( month ); + + new SeparatorLabel( month ); + auto* monthValue = new QskTextLabel( "66 kwH", month ); monthValue->setFontRole( QskSkin::SmallFont ); auto* total = new QskLinearBox( Qt::Horizontal, content ); auto* totalText = new QskTextLabel( "Total working hours", total ); totalText->setFontRole( QskSkin::SmallFont ); - new UsageSpacer( total ); + + new SeparatorLabel( total ); + auto* totalValue = new QskTextLabel( "125 hrs", total ); totalValue->setFontRole( QskSkin::SmallFont ); } - -#include "moc_Usage.cpp" diff --git a/examples/iotdashboard/UsageBox.h b/examples/iotdashboard/UsageBox.h new file mode 100644 index 00000000..5feb19cb --- /dev/null +++ b/examples/iotdashboard/UsageBox.h @@ -0,0 +1,16 @@ +/****************************************************************************** + * Copyright (C) 2021 Edelhirsch Software GmbH + * This file may be used under the terms of the 3-clause BSD License + *****************************************************************************/ + +#pragma once + +#include "Box.h" + +class UsageBox : public Box +{ + public: + QSK_SUBCONTROLS( Separator ) + + UsageBox( QQuickItem* parent = nullptr ); +}; diff --git a/examples/iotdashboard/UsageDiagram.cpp b/examples/iotdashboard/UsageDiagram.cpp index 69b6a6da..f51de198 100644 --- a/examples/iotdashboard/UsageDiagram.cpp +++ b/examples/iotdashboard/UsageDiagram.cpp @@ -135,7 +135,7 @@ void UsageDiagram::updateLayout() auto weekdaysHeight = m_weekdays->preferredSize().height(); m_diagram->setHeight( m_diagram->height() - weekdaysHeight ); const qreal captionX = width() - m_captionBox->width(); - m_captionBox->setPosition( {captionX, 0} ); + m_captionBox->setPosition( captionX, 0 ); } #include "moc_UsageDiagram.cpp" diff --git a/examples/iotdashboard/UsageDiagram.h b/examples/iotdashboard/UsageDiagram.h index 4fbe6692..1e48ae5e 100644 --- a/examples/iotdashboard/UsageDiagram.h +++ b/examples/iotdashboard/UsageDiagram.h @@ -92,7 +92,7 @@ class UsageDiagram : public Box public: QSK_SUBCONTROLS( Panel ) - UsageDiagram( QQuickItem* parent ); + UsageDiagram( QQuickItem* parent = nullptr ); protected: void updateLayout() override; diff --git a/examples/iotdashboard/iotdashboard.pro b/examples/iotdashboard/iotdashboard.pro index 575a1d76..5ec94ff3 100644 --- a/examples/iotdashboard/iotdashboard.pro +++ b/examples/iotdashboard/iotdashboard.pro @@ -16,11 +16,11 @@ SOURCES += \ RoundedIcon.cpp \ Skin.cpp \ TopBar.cpp \ - UpAndDownButton.cpp \ - Usage.cpp \ - main.cpp \ + RoundButton.cpp \ + UsageBox.cpp \ + UsageDiagram.cpp \ MainWindow.cpp \ - UsageDiagram.cpp + main.cpp \ SOURCES += \ nodes/DiagramDataNode.cpp \ @@ -43,8 +43,8 @@ HEADERS += \ RoundedIcon.h \ Skin.h \ TopBar.h \ - UpAndDownButton.h \ - Usage.h \ + RoundButton.h \ + UsageBox.h \ UsageDiagram.h HEADERS += \