using subControl proxies + other improvements

This commit is contained in:
Uwe Rathmann 2021-08-04 18:55:18 +02:00
parent 56211d9816
commit 9cb938b5e7
27 changed files with 372 additions and 446 deletions

View File

@ -4,19 +4,33 @@
*****************************************************************************/
#include "BoxWithButtons.h"
#include "RoundButton.h"
#include "RoundedIcon.h"
#include "Skin.h"
#include "UpAndDownButton.h"
#include <QskTextLabel.h>
#include <QskLinearBox.h>
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"

View File

@ -6,67 +6,12 @@
#pragma once
#include "Box.h"
#include "RoundedIcon.h"
#include <QskBoxShapeMetrics.h>
#include <QskTextLabel.h>
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 )
{
}
};

View File

@ -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();

View File

@ -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;

View File

@ -10,104 +10,168 @@
#include <QskRgbValue.h>
#include <QskSetup.h>
#include <QskTextLabel.h>
#include <QskQuick.h>
#include <QGuiApplication>
#include <QQuickWindow>
#include <QQuickPaintedItem>
#include <QPainter>
#include <QRadialGradient>
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"

View File

@ -5,102 +5,22 @@
#pragma once
#include "Box.h"
#include <QskLinearBox.h>
#include <QskTextLabel.h>
#include <QQuickPaintedItem>
#include <QRadialGradient>
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;
};

View File

@ -12,7 +12,7 @@
#include "MyDevices.h"
#include "PieChart.h"
#include "TopBar.h"
#include "Usage.h"
#include "UsageBox.h"
#include <QskBoxBorderColors.h>
#include <QskBoxBorderMetrics.h>
@ -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 );
}

View File

@ -4,22 +4,21 @@
*****************************************************************************/
#include "MainWindow.h"
#include "MainContent.h"
#include "MenuBar.h"
#include <QskLinearBox.h>
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"

View File

@ -7,19 +7,10 @@
#include <QskWindow.h>
class MainContent;
class MenuBar;
class QskLinearBox;
class MainWindow : public QskWindow
{
Q_OBJECT
public:
MainWindow();
private:
QskLinearBox* m_mainLayout;
MenuBar* m_menuBar;
MainContent* m_mainContent;
};

View File

@ -11,7 +11,7 @@
#include <QskSkin.h>
#include <QskTextLabel.h>
#include <QtGui/QImage>
#include <QImage>
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 );

View File

@ -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

View File

@ -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:

View File

@ -10,5 +10,5 @@
class MyDevices : public Box
{
public:
MyDevices( QQuickItem* parent );
MyDevices( QQuickItem* parent = nullptr );
};

View File

@ -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 );
}

View File

@ -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 <QskBoxShapeMetrics.h>
#include <QskGraphic.h>
#include <QskGraphicIO.h>
#include <QskPushButton.h>
#include <QImage>
@ -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"

View File

@ -5,7 +5,6 @@
#pragma once
#include <QskLinearBox.h>
#include <QskPushButton.h>
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 );
};

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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 <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskFunctions.h>
@ -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:

View File

@ -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();

View File

@ -59,7 +59,7 @@ class TopBar : public QskLinearBox
public:
QSK_SUBCONTROLS( Panel )
TopBar( QQuickItem* parent );
TopBar( QQuickItem* parent = nullptr );
private:
QList< TopBarItem* > m_entries;

View File

@ -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 <QskTextLabel.h>
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 );
};

View File

@ -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 <QskTextLabel.h>
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"

View File

@ -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 );
};

View File

@ -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"

View File

@ -92,7 +92,7 @@ class UsageDiagram : public Box
public:
QSK_SUBCONTROLS( Panel )
UsageDiagram( QQuickItem* parent );
UsageDiagram( QQuickItem* parent = nullptr );
protected:
void updateLayout() override;

View File

@ -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 += \