diff --git a/examples/examples.pro b/examples/examples.pro index 98635a05..e691a3f0 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -7,6 +7,7 @@ SUBDIRS += \ qvgviewer \ desktop \ dialogbuttons \ + hmi-demo \ layouts \ listbox \ messagebox \ diff --git a/examples/hmi-demo/DefaultSkin.cpp b/examples/hmi-demo/DefaultSkin.cpp new file mode 100644 index 00000000..7bcd83ba --- /dev/null +++ b/examples/hmi-demo/DefaultSkin.cpp @@ -0,0 +1,135 @@ +#include "DefaultSkin.h" + +#include "SoundControl.h" + +#include +#include +#include +#include +#include +#include + +#include + +class DefaultSkin::Transition : public QskSkinTransition +{ +protected: + virtual void updateSkin( QskSkin*, QskSkin* newSkin ) override final + { + DefaultSkin* skin = static_cast< DefaultSkin* >( newSkin ); + skin->resetColors(); + } +}; + +class Palette { +public: + + Palette( DefaultSkin::Scheme scheme = DefaultSkin::Daylight ) + { + if ( scheme == DefaultSkin::Daylight ) + { + // colorful: + color1.setNamedColor( "#011627" ); // Maastricht blue + color2.setNamedColor( "#FF0022" ); // ruddy + color3.setNamedColor( "#41EAD4" ); // Turquoise + color4.setNamedColor( "#FDFFFC" ); // baby powder + color5.setNamedColor( "#B91372" ); // red violet + } + else + { + // greenish: + color4.setNamedColor( "#FAF3DD" ); // Beige + color2.setNamedColor( "#C8D5B9" ); // Pale Silver + color3.setNamedColor( "#8FC0A9" ); // Eton Blue + color1.setNamedColor( "#68B0AB" ); // Green Sheen + color5.setNamedColor( "#4A7C59" ); // Amazon + } + } + + QColor color1; + QColor color2; + QColor color3; + QColor color4; + QColor color5; + +}; + +namespace { + +static inline QFont qskFont( int pointSize ) +{ + QFont font( "Roboto" ); + font.setPointSize( pointSize / qskDpiScaled( 1.0 ) ); + return font; +} + +} + +DefaultSkin::DefaultSkin( const QString &name, QObject *parent ) + : QskSkin( parent ), + m_name( name ), + m_palette( new Palette ), + m_scheme( Daylight ) +{ + setObjectName( "DefaultSkin" ); + initHints(); +} + +void DefaultSkin::initHints() +{ + setFont( QskSkin::DefaultFont, qskFont( 13 ) ); + setFont( QskSkin::LargeFont, qskFont( 20 ) ); + + setColor( QskTextLabel::Text, m_palette->color4 ); + + setColor( FilledRectangle::Panel, m_palette->color3 ); + + setColor( QskPushButton::Panel, m_palette->color1 ); + setColor( QskPushButton::Text, m_palette->color3 ); + setColor( QskPushButton::Panel | QskPushButton::Pressed, m_palette->color2 ); + setMetric( QskPushButton::Text | QskAspect::Size, 20 ); + setSkinHint( QskPushButton::Text | QskAspect::FontRole, int( QskSkin::LargeFont ) ); + setSkinHint( QskPushButton::Text | QskAspect::Alignment, Qt::AlignCenter ); + + setMetric( QskSlider::Panel | QskAspect::Size, 5 ); + setColor( QskSlider::Groove, m_palette->color4 ); + setColor( QskSlider::Fill, m_palette->color4.darker( 200 ) ); + setMetric( QskSlider::Handle | QskAspect::Size, 18 ); + setMetric( QskSlider::Handle | QskAspect::Radius, 9 ); + setColor( QskSlider::Handle, m_palette->color5 ); + + setColor( BalanceFadeBox::Panel, m_palette->color5 ); + setMetric( BalanceFadeBox::Panel | QskAspect::Radius, 15 ); + + // animator for daylight/night scheme transitions + setAnimation( QskAspect::Color, QskAnimationHint( 1000, QEasingCurve::InQuad ) ); +} + +void DefaultSkin::toggleScheme() +{ + if ( m_scheme == Daylight ) + m_scheme = Nighttime; + else + m_scheme = Daylight; + + Transition transition; + + transition.setSourceSkin( this ); + transition.setTargetSkin( this ); + transition.setMask( QskSkinTransition::Color ); + transition.setAnimation( animation( QskAspect::Color ) ); + + transition.process(); +} + +void DefaultSkin::resetColors() +{ + delete m_palette; + m_palette = new Palette( m_scheme ); + initHints(); +} + +DefaultSkin::~DefaultSkin() +{ + delete m_palette; +} diff --git a/examples/hmi-demo/DefaultSkin.h b/examples/hmi-demo/DefaultSkin.h new file mode 100644 index 00000000..7d817a0e --- /dev/null +++ b/examples/hmi-demo/DefaultSkin.h @@ -0,0 +1,32 @@ +#ifndef DEFAULTSKIN_H +#define DEFAULTSKIN_H + +#include + +class Palette; + +class DefaultSkin : public QskSkin +{ +public: + DefaultSkin( const QString& name, QObject* parent = nullptr ); + virtual ~DefaultSkin(); + + void toggleScheme(); + void resetColors(); + + enum Scheme { + Daylight, + Nighttime + }; + +private: + class Transition; + + void initHints(); + + QString m_name; + Palette* m_palette; + Scheme m_scheme; +}; + +#endif // DEFAULTSKIN_H diff --git a/examples/hmi-demo/MainWindow.cpp b/examples/hmi-demo/MainWindow.cpp new file mode 100644 index 00000000..141291e5 --- /dev/null +++ b/examples/hmi-demo/MainWindow.cpp @@ -0,0 +1,102 @@ +#include "MainWindow.h" +#include "RadioControl.h" +#include "SoundControl.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace { + void addIcon( QskLayout* layout, const QString& fileName ) + { + QImage buildIcon( fileName ); + QskGraphic graphic = QskGraphic::fromImage( buildIcon ); + QskGraphicLabel* buildLabel = new QskGraphicLabel( layout ); + buildLabel->setFixedSize( 76, 36 ); + buildLabel->setMargins( QMarginsF( 20, 7, 20, 7 ) ); + buildLabel->setGraphic( graphic ); + } +} + +MainWindow::MainWindow() : QskWindow() + , m_backgroundImage( new QskGraphicLabel( contentItem() ) ) + , m_layout( new QskLinearBox( Qt::Vertical, contentItem() ) ) +{ + setPreferredSize( QSize( 1024, 576 ) ); + setAutoLayoutChildren( true ); + + // later: +// QFont font( "Roboto" ); +// font.setPointSize( 20 ); +// setFont( QskSkin::DefaultFont, 20 ); + + QImage image( ":/images/background.jpg" ); + QskGraphic graphic = QskGraphic::fromImage( image ); + m_backgroundImage->setGraphic( graphic ); + + m_layout->setAutoAddChildren( true ); + + addHeaderBar(); + addMainContent(); + addBottomBar(); +} + +void MainWindow::addHeaderBar() +{ + QskPushButton* headerBar = new QskPushButton( m_layout ); + headerBar->setEnabled( false ); + headerBar->setPosition( QPointF( 0, 0 ) ); + headerBar->setOpacity( 0.5 ); + headerBar->setBackgroundColor( Qt::black ); + headerBar->setFixedHeight( 50 ); + headerBar->setFlat( true ); + headerBar->setAutoLayoutChildren( true ); + + QskLinearBox* headerLayout = new QskLinearBox( headerBar ); + headerLayout->setMargins( QMarginsF( 20, 0, 20, 0 ) ); + + addIcon( headerLayout, ":/images/ic_pan_tool_white_48dp_2x.png" ); + addIcon( headerLayout, ":/images/ic_star_rate_white_18dp_2x.png" ); + addIcon( headerLayout, ":/images/ic_airplanemode_active_white_18dp_2x.png" ); + + QDate currentDate = QDate::currentDate(); + QskTextLabel* dateLabel = new QskTextLabel( currentDate.toString(), headerLayout ); + dateLabel->setColor( QskTextLabel::Text, Qt::white ); + + addIcon( headerLayout, ":/images/ic_face_white_48px.svg" ); + addIcon( headerLayout, ":/images/ic_extension_white_48dp_2x.png" ); + addIcon( headerLayout, ":/images/ic_build_white_24dp_2x.png" ); +} + +void MainWindow::addMainContent() +{ +// RadioControl* radioControl = new RadioControl( m_layout ); +// m_layout->setRetainSizeWhenHidden( radioControl, true ); +// radioControl->setVisible( false ); + + SoundControl* soundControl = new SoundControl( m_layout ); +} + +void MainWindow::addBottomBar() +{ + QskPushButton* bottomBar = new QskPushButton( m_layout ); + bottomBar->setEnabled( false ); + bottomBar->setPosition( QPointF( 0, 0 ) ); + bottomBar->setOpacity( 0.5 ); + bottomBar->setBackgroundColor( Qt::black ); + bottomBar->setFixedHeight( 50 ); + bottomBar->setFlat( true ); + + QskLinearBox* bottomLayout = new QskLinearBox( bottomBar ); + bottomLayout->setMargins( QMarginsF( 20, 0, 20, 0 ) ); + + addIcon( bottomLayout, ":/images/ic_pan_tool_white_48dp_2x.png" ); + addIcon( bottomLayout, ":/images/ic_star_rate_white_18dp_2x.png" ); + addIcon( bottomLayout, ":/images/ic_airplanemode_active_white_18dp_2x.png" ); +} diff --git a/examples/hmi-demo/MainWindow.h b/examples/hmi-demo/MainWindow.h new file mode 100644 index 00000000..f6272ca4 --- /dev/null +++ b/examples/hmi-demo/MainWindow.h @@ -0,0 +1,24 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +class QskGraphicLabel; +class QskLinearBox; + +class MainWindow : public QskWindow +{ +public: + MainWindow(); + +private: + void addHeaderBar(); + void addMainContent(); + void addBottomBar(); + + QskGraphicLabel* m_backgroundImage; + QskLinearBox* m_layout; +}; + +#endif // MAINWINDOW_H diff --git a/examples/hmi-demo/OtherSkin.cpp b/examples/hmi-demo/OtherSkin.cpp new file mode 100644 index 00000000..9adf0ae9 --- /dev/null +++ b/examples/hmi-demo/OtherSkin.cpp @@ -0,0 +1,84 @@ +#include "OtherSkin.h" + +#include "SoundControl.h" + +#include +#include +#include +#include +#include + +#include + +class Palette { +public: + + Palette() + { + // grey-blue-yellow: + color1.setNamedColor( "#363636" ); // Jet + color2.setNamedColor( "#242F40" ); // Yankees blue + color3.setNamedColor( "#CCA43B" ); // Satin sheet gold + color4.setNamedColor( "#E5E5E5" ); // Platinum + color5.setNamedColor( "#FFFFFF" ); // white + } + + QColor color1; + QColor color2; + QColor color3; + QColor color4; + QColor color5; + +}; + +namespace { + +static inline QFont qskFont( int pointSize ) +{ + QFont font( "Roboto" ); + font.setPointSize( pointSize / qskDpiScaled( 1.0 ) ); + return font; +} + +} + +OtherSkin::OtherSkin( const QString &name, QObject *parent ) + : QskSkin( parent ), + m_name( name ), + m_palette( new Palette ) +{ + setObjectName( "OtherSkin" ); + initHints(); +} + +void OtherSkin::initHints() +{ + setFont( QskSkin::DefaultFont, qskFont( 13 ) ); + setFont( QskSkin::LargeFont, qskFont( 20 ) ); + + setColor( QskTextLabel::Text, m_palette->color4 ); + + setColor( FilledRectangle::Panel, m_palette->color3 ); + + setColor( QskPushButton::Panel, m_palette->color1 ); + setColor( QskPushButton::Text, m_palette->color3 ); + setMetric( QskPushButton::Text | QskAspect::Size, 20 ); + setSkinHint( QskPushButton::Text | QskAspect::FontRole, int( QskSkin::LargeFont ) ); + setSkinHint( QskPushButton::Text | QskAspect::Alignment, Qt::AlignCenter ); + + setMetric( QskSlider::Panel | QskAspect::Size, 5 ); + setColor( QskSlider::Groove, m_palette->color4 ); + setColor( QskSlider::Fill, m_palette->color4.darker( 200 ) ); + setMetric( QskSlider::Handle | QskAspect::Size, 18 ); + setMetric( QskSlider::Handle | QskAspect::Radius, 9 ); + setColor( QskSlider::Handle, m_palette->color5 ); + + setColor( BalanceFadeBox::Panel, m_palette->color5 ); + setMetric( BalanceFadeBox::Panel | QskAspect::Radius, 15 ); + +} + +OtherSkin::~OtherSkin() +{ + delete m_palette; +} diff --git a/examples/hmi-demo/OtherSkin.h b/examples/hmi-demo/OtherSkin.h new file mode 100644 index 00000000..d5546db8 --- /dev/null +++ b/examples/hmi-demo/OtherSkin.h @@ -0,0 +1,21 @@ +#ifndef OTHERSKIN_H +#define OTHERSKIN_H + +#include + +class Palette; + +class OtherSkin : public QskSkin +{ +public: + OtherSkin( const QString& name, QObject* parent = nullptr ); + virtual ~OtherSkin(); + +private: + void initHints(); + + QString m_name; + Palette* m_palette; +}; + +#endif // OTHERSKIN_H diff --git a/examples/hmi-demo/README.images b/examples/hmi-demo/README.images new file mode 100644 index 00000000..4c20831c --- /dev/null +++ b/examples/hmi-demo/README.images @@ -0,0 +1,4 @@ +* background image: http://7-themes.com/collections/green-wallpapers/4440155/ , license unknown +* car image: https://openclipart.org/detail/234440/white-blank-racing-car-top-view , unlimited commercial use +* arrow images: https://www.flaticon.com/free-icon/right-arrow_108522 etc. made by Butterflytronics from www.flaticon.com +* icons: https://www.flaticon.com/packs/material-design, made by Material Design from www.flaticon.com diff --git a/examples/hmi-demo/RadioControl.cpp b/examples/hmi-demo/RadioControl.cpp new file mode 100644 index 00000000..0d69a1f9 --- /dev/null +++ b/examples/hmi-demo/RadioControl.cpp @@ -0,0 +1,66 @@ +#include "RadioControl.h" + +#include +#include +#include +#include +#include +#include +#include + +RadioControl::RadioControl( QQuickItem* parent ) : QskControl( parent ) + , m_currentBand( "FM" ) +{ + setMargins( QMarginsF( 40, 30, 40, 30 ) ); + setAutoLayoutChildren( true ); + + QskLinearBox* outterLayout = new QskLinearBox( Qt::Vertical, this ); + outterLayout->setAutoAddChildren( true ); + + QskTabBar* favoritesBar = new QskTabBar( outterLayout ); + favoritesBar->addTab( "AM" ); + favoritesBar->addTab( "FM" ); + favoritesBar->addTab( "DAB" ); + + outterLayout->addSpacer( 80 ); + outterLayout->setMargins( QMarginsF( 150, 0, 150, 0 ) ); + outterLayout->setAlignment( 2, Qt::AlignHCenter ); + + QskPushButton* frequencyButton = new QskPushButton( outterLayout ); + frequencyButton->setAutoLayoutChildren( true ); + frequencyButton->setFlat( true ); + frequencyButton->setBackgroundColor( QColor( 183, 210, 255 ) ); + frequencyButton->setEnabled( false ); + frequencyButton->setFixedWidth( 400 ); + + QskLinearBox* frequencyLayout = new QskLinearBox( Qt::Horizontal, frequencyButton ); + frequencyLayout->setAutoAddChildren( true ); + frequencyLayout->setMargins( QMarginsF( 150, 20, 150, 20 ) ); + + QskTextLabel* bandLabel = new QskTextLabel( m_currentBand, frequencyLayout ); + QskTextLabel* frequencyLabel = new QskTextLabel( "87.50", frequencyLayout ); + QskTextLabel* hzLabel = new QskTextLabel( "MHz", frequencyLayout ); + + QskLinearBox* tuneLayout = new QskLinearBox( Qt::Horizontal, outterLayout ); + tuneLayout->setAutoLayoutChildren( true ); + + QskPushButton* prevTuneButton = new QskPushButton( tuneLayout ); + QImage prevTuneImage( ":/images/ic_skip_previous_white_18dp_2x.png" ); + QskGraphic prevTuneGraphic = QskGraphic::fromImage( prevTuneImage ); + prevTuneButton->setGraphic( prevTuneGraphic ); + + QskPushButton* prevSearchButton = new QskPushButton( tuneLayout ); + QImage prevSearchImage( ":/images/ic_fast_rewind_white_18dp_2x.png" ); + QskGraphic prevSearchGraphic = QskGraphic::fromImage( prevSearchImage ); + prevSearchButton->setGraphic( prevSearchGraphic ); + + QskPushButton* nextSearchButton = new QskPushButton( tuneLayout ); + QImage nextSearchImage( ":/images/ic_fast_forward_white_18dp_2x.png" ); + QskGraphic nextSearchGraphic = QskGraphic::fromImage( nextSearchImage ); + nextSearchButton->setGraphic( nextSearchGraphic ); + + QskPushButton* nextTuneButton = new QskPushButton( tuneLayout ); + QImage nextTuneImage( ":/images/ic_skip_next_white_18dp_1x.png" ); + QskGraphic nextTuneGraphic = QskGraphic::fromImage( nextTuneImage ); + nextTuneButton->setGraphic( nextTuneGraphic ); +} diff --git a/examples/hmi-demo/RadioControl.h b/examples/hmi-demo/RadioControl.h new file mode 100644 index 00000000..3e355ef9 --- /dev/null +++ b/examples/hmi-demo/RadioControl.h @@ -0,0 +1,17 @@ +#ifndef RADIOCONTROL_H +#define RADIOCONTROL_H + +#include + +class QskLinearBox; + +class RadioControl : public QskControl +{ +public: + RadioControl( QQuickItem *parent = nullptr ); + +private: + QString m_currentBand; +}; + +#endif // RADIOCONTROL_H diff --git a/examples/hmi-demo/SoundControl.cpp b/examples/hmi-demo/SoundControl.cpp new file mode 100644 index 00000000..ed25c95e --- /dev/null +++ b/examples/hmi-demo/SoundControl.cpp @@ -0,0 +1,291 @@ +#include "SoundControl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +QSK_SUBCONTROL( FilledRectangle, Panel ) + +QskAspect::Subcontrol FilledRectangle::effectiveSubcontrol( + QskAspect::Subcontrol subControl ) const +{ + if ( subControl == QskPushButton::Panel ) + return FilledRectangle::Panel; + + return subControl; +} + +QSK_SUBCONTROL( BalanceFadeBox, Panel ) + +QskAspect::Subcontrol BalanceFadeBox::effectiveSubcontrol( + QskAspect::Subcontrol subControl ) const +{ + if ( subControl == QskPushButton::Panel ) + return BalanceFadeBox::Panel; + + return subControl; +} + +class StackedControl : public QskControl { +public: + StackedControl( QQuickItem* parent = nullptr ) : QskControl( parent ), + m_offset( 0.0, 0.0 ) + { + } + + QPointF offset() const + { + return m_offset; + } + + void setOffset( const QPointF& offset ) + { + m_offset = offset; + } + +protected: + virtual void updateLayout() override final + { + const QRectF cr = contentsRect(); + + for ( int a = 0; a < children().count(); a++ ) + { + QskControl* control = static_cast< QskControl* >( children().at( a ) ); + + qreal xCenter = ( cr.width() + margins().top() + margins().bottom() ) / 2; + qreal yCenter = ( cr.height() + margins().left() + margins().right() ) / 2; + + if ( control->objectName() == "verticalBar" ) + { + control->setPosition( QPointF( xCenter, margins().top() ) ); + control->setSize( QSizeF( 3, cr.height() ) ); + control->setZ( 1 ); + } + else if ( control->objectName() == "horizontalBar" ) + { + control->setPosition( QPointF( margins().left(), yCenter ) ); + control->setSize( QSizeF( cr.width(), 3 ) ); + control->setZ( 1 ); + } + else if ( control->objectName() == "box" ) + { + qreal size = 30; + control->setPosition( QPointF( xCenter - ( size / 2 ) + 1 + m_offset.x(), + yCenter - ( size / 2 ) + 1 + m_offset.y() ) ); + control->setSize( QSizeF( size, size ) ); + control->setZ( 2 ); + } + else + { + control->setPosition( cr.topLeft() ); + control->setSize( cr.size() ); + } + } + } + +private: + QPointF m_offset; +}; + +SoundControl::SoundControl( QQuickItem *parent ) : QskControl( parent ) +{ + setMargins( QMarginsF( 40, 20, 40, 20 ) ); + setAutoLayoutChildren( true ); + + QskGridBox* outterLayout = new QskGridBox( this ); + outterLayout->setVerticalSpacing( 40 ); + outterLayout->setHorizontalSpacing( 60 ); + outterLayout->setColumnStretchFactor( 0, 1 ); + outterLayout->setColumnStretchFactor( 1, 2 ); + + QskLinearBox* toneBox = new QskLinearBox( Qt::Horizontal, outterLayout ); + toneBox->setSpacing( 20 ); + toneBox->setAutoAddChildren( true ); + toneBox->setAutoLayoutChildren( true ); + toneBox->addSpacer( 0, 1 ); + FilledRectangle* toneRectangle = new FilledRectangle( toneBox ); + QskTextLabel* toneLabel = new QskTextLabel( "Tone", toneBox ); + toneLabel->setAlignment( Qt::AlignLeft ); + toneRectangle->setFixedHeight( + QFontMetricsF( toneLabel->effectiveFont( QskTextLabel::Text ) ).height() ); + toneBox->addSpacer( 0, 1 ); + outterLayout->addItem( toneBox, 0, 0 ); + + + QskLinearBox* balanceBox = new QskLinearBox( Qt::Horizontal, outterLayout ); + balanceBox->setSpacing( 20 ); + balanceBox->setAutoAddChildren( true ); + balanceBox->setAutoLayoutChildren( true ); + balanceBox->addSpacer( 0, 1 ); + FilledRectangle* balanceRectangle = new FilledRectangle( balanceBox ); + QskTextLabel* balanceLabel = new QskTextLabel( "Balance / Fade", balanceBox ); + balanceLabel->setAlignment( Qt::AlignLeft ); + balanceRectangle->setFixedHeight( + QFontMetricsF( balanceLabel->effectiveFont( QskTextLabel::Text ) ).height() ); + balanceBox->addSpacer( 0, 1 ); + outterLayout->addItem( balanceBox, 0, 1 ); + + + QskGridBox* toneGridBox = new QskGridBox( outterLayout ); + QskTextLabel* bassLabel = new QskTextLabel( "Bass", toneGridBox ); + toneGridBox->addItem( bassLabel, 0, 0 ); + QskTextLabel* trebleLabel = new QskTextLabel( "Treble", toneGridBox ); + toneGridBox->addItem( trebleLabel, 0, 1 ); + QskTextLabel* subLabel = new QskTextLabel( "Sub", toneGridBox ); + toneGridBox->addItem( subLabel, 0, 2 ); + + QskTextLabel* bassNumberLabel = new QskTextLabel( "0", toneGridBox ); + toneGridBox->addItem( bassNumberLabel, 1, 0 ); + QskTextLabel* trebleNumberLabel = new QskTextLabel( "0", toneGridBox ); + toneGridBox->addItem( trebleNumberLabel, 1, 1 ); + QskTextLabel* subNumberLabel = new QskTextLabel( "0", toneGridBox ); + toneGridBox->addItem( subNumberLabel, 1, 2 ); + + QskPushButton* bassPlusButton = new QskPushButton( "+", toneGridBox ); + bassPlusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( bassPlusButton, 2, 0 ); + toneGridBox->setAlignment( bassPlusButton, Qt::AlignCenter ); + QskPushButton* treblePlusButton = new QskPushButton( "+", toneGridBox ); + treblePlusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( treblePlusButton, 2, 1 ); + toneGridBox->setAlignment( treblePlusButton, Qt::AlignCenter ); + QskPushButton* subPlusButton = new QskPushButton( "+", toneGridBox ); + subPlusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( subPlusButton, 2, 2 ); + toneGridBox->setAlignment( subPlusButton, Qt::AlignCenter ); + + QskSlider* bassSlider = new QskSlider( Qt::Vertical, toneGridBox ); + bassSlider->setMinimum( 0 ); + bassSlider->setMaximum( 40 ); + bassSlider->setValue( 30 ); + toneGridBox->addItem( bassSlider, 3, 0 ); + toneGridBox->setAlignment( bassSlider, Qt::AlignCenter ); + QskSlider* trebleSlider = new QskSlider( Qt::Vertical, toneGridBox ); + trebleSlider->setMinimum( 0 ); + trebleSlider->setMaximum( 40 ); + trebleSlider->setValue( 11 ); + toneGridBox->addItem( trebleSlider, 3, 1 ); + toneGridBox->setAlignment( trebleSlider, Qt::AlignCenter ); + QskSlider* subSlider = new QskSlider( Qt::Vertical, toneGridBox ); + subSlider->setMinimum( 0 ); + subSlider->setMaximum( 40 ); + subSlider->setValue( 18 ); + toneGridBox->addItem( subSlider, 3, 2 ); + toneGridBox->setAlignment( subSlider, Qt::AlignCenter ); + + QskPushButton* bassMinusButton = new QskPushButton( "-", toneGridBox ); + bassMinusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( bassMinusButton, 4, 0 ); + toneGridBox->setAlignment( bassMinusButton, Qt::AlignCenter ); + QskPushButton* trebleMinusButton = new QskPushButton( "-", toneGridBox ); + trebleMinusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( trebleMinusButton, 4, 1 ); + toneGridBox->setAlignment( trebleMinusButton, Qt::AlignCenter ); + QskPushButton* subMinusButton = new QskPushButton( "-", toneGridBox ); + subMinusButton->setFixedSize( 35, 35 ); + toneGridBox->addItem( subMinusButton, 4, 2 ); + toneGridBox->setAlignment( subMinusButton, Qt::AlignCenter ); + + connect( bassPlusButton, &QskPushButton::pressed, [ bassSlider ]() { + bassSlider->setValue( bassSlider->value() + 1 ); + } ); + connect( treblePlusButton, &QskPushButton::pressed, [ trebleSlider ]() { + trebleSlider->setValue( trebleSlider->value() + 1 ); + } ); + connect( subPlusButton, &QskPushButton::pressed, [ subSlider ]() { + subSlider->setValue( subSlider->value() + 1 ); + } ); + connect( bassMinusButton, &QskPushButton::pressed, [ bassSlider ]() { + bassSlider->setValue( bassSlider->value() - 1 ); + } ); + connect( trebleMinusButton, &QskPushButton::pressed, [ trebleSlider ]() { + trebleSlider->setValue( trebleSlider->value() - 1 ); + } ); + connect( subMinusButton, &QskPushButton::pressed, [ subSlider ]() { + subSlider->setValue( subSlider->value() - 1 ); + } ); + + outterLayout->addItem( toneGridBox, 1, 0 ); + + + QskGridBox* carGridBox = new QskGridBox( outterLayout ); + carGridBox->setAutoLayoutChildren( true ); + + QskPushButton* upButton = new QskPushButton( carGridBox ); + upButton->setFixedSize( 100, 50 ); + QImage upImage( ":/images/up.svg" ); + QskGraphic upGraphic = QskGraphic::fromImage( upImage ); + upButton->setGraphic( upGraphic ); // ### try with setGraphicSource + carGridBox->addItem( upButton, 0, 0, 1, 3 ); + carGridBox->setAlignment( upButton, Qt::AlignCenter ); + + QskPushButton* leftButton = new QskPushButton( carGridBox ); + leftButton->setFixedSize( 50, 100 ); + QImage leftImage( ":/images/left.svg" ); + QskGraphic leftGraphic = QskGraphic::fromImage( leftImage ); + leftButton->setGraphic( leftGraphic ); + carGridBox->addItem( leftButton, 1, 0 ); + + StackedControl* carControl = new StackedControl( carGridBox ); + carControl->setSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Expanding ); + carControl->setPolishOnResize( true ); + carControl->setMargins( 10 ); + FilledRectangle* horizontalCarRectangle = new FilledRectangle( carControl ); + horizontalCarRectangle->setObjectName( "horizontalBar" ); + FilledRectangle* verticalCarRectangle = new FilledRectangle( carControl ); + verticalCarRectangle->setObjectName( "verticalBar" ); + BalanceFadeBox *box = new BalanceFadeBox( carControl ); + box->setObjectName( "box" ); + QImage carImage( ":/images/car.svg" ); + QskGraphic graphic = QskGraphic::fromImage( carImage ); + QskGraphicLabel* carLabel = new QskGraphicLabel( carControl ); + carLabel->setGraphic( graphic ); + carGridBox->addItem( carControl, 1, 1 ); + + QskPushButton* rightButton = new QskPushButton( carGridBox ); + rightButton->setFixedSize( 50, 100 ); + QImage rightImage( ":/images/right.svg" ); + QskGraphic rightGraphic = QskGraphic::fromImage( rightImage ); + rightButton->setGraphic( rightGraphic ); + carGridBox->addItem( rightButton, 1, 2 ); + carGridBox->setAlignment( rightButton, Qt::AlignRight ); + + QskPushButton* downButton = new QskPushButton( carGridBox ); + downButton->setFixedSize( 100, 50 ); + QImage downImage( ":/images/down.svg" ); + QskGraphic downGraphic = QskGraphic::fromImage( downImage ); + downButton->setGraphic( downGraphic ); + carGridBox->addItem( downButton, 2, 0, 1, 3 ); + carGridBox->setAlignment( downButton, Qt::AlignCenter ); + + connect( upButton, &QskPushButton::pressed, [ carControl ]() { + carControl->setOffset( QPointF( carControl->offset().x(), + carControl->offset().y() - 5.0 ) ); + carControl->polish(); + } ); + connect( leftButton, &QskPushButton::pressed, [ carControl ]() { + carControl->setOffset( QPointF( carControl->offset().x() - 5.0, + carControl->offset().y() ) ); + carControl->polish(); + } ); + connect( rightButton, &QskPushButton::pressed, [ carControl ]() { + carControl->setOffset( QPointF( carControl->offset().x() + 5.0, + carControl->offset().y() ) ); + carControl->polish(); + } ); + connect( downButton, &QskPushButton::pressed, [ carControl ]() { + carControl->setOffset( QPointF( carControl->offset().x(), + carControl->offset().y() + 5.0 ) ); + carControl->polish(); + } ); + + outterLayout->addItem( carGridBox, 1, 1 ); +} diff --git a/examples/hmi-demo/SoundControl.h b/examples/hmi-demo/SoundControl.h new file mode 100644 index 00000000..2ac431a7 --- /dev/null +++ b/examples/hmi-demo/SoundControl.h @@ -0,0 +1,44 @@ +#ifndef SOUNDCONTROL_H +#define SOUNDCONTROL_H + +#include +#include +#include + +class QskGridBox; + +class FilledRectangle : public QskPushButton // ### move to some main control file +{ +public: + QSK_SUBCONTROLS( Panel ) + + FilledRectangle( QQuickItem* parent ) : QskPushButton( parent ) + { + setFlat( true ); + setFixedWidth( 80 ); // ### style + } + + virtual QskAspect::Subcontrol effectiveSubcontrol( + QskAspect::Subcontrol subControl ) const override final; +}; + +class BalanceFadeBox : public QskPushButton +{ +public: + QSK_SUBCONTROLS( Panel ) + + BalanceFadeBox( QQuickItem* parent ) : QskPushButton( parent ) + { + } + + virtual QskAspect::Subcontrol effectiveSubcontrol( + QskAspect::Subcontrol subControl ) const override final; +}; + +class SoundControl : public QskControl +{ +public: + SoundControl( QQuickItem *parent = nullptr ); +}; + +#endif // SOUNDCONTROL_H diff --git a/examples/hmi-demo/hmi-demo.pro b/examples/hmi-demo/hmi-demo.pro new file mode 100644 index 00000000..894828a7 --- /dev/null +++ b/examples/hmi-demo/hmi-demo.pro @@ -0,0 +1,20 @@ +include( $${PWD}/../examples.pri ) + +TARGET = hmi-demo + +RESOURCES = images.qrc + +HEADERS += \ + MainWindow.h \ + RadioControl.h \ + SoundControl.h \ + DefaultSkin.h \ + OtherSkin.h + +SOURCES += \ + main.cpp \ + MainWindow.cpp \ + RadioControl.cpp \ + SoundControl.cpp \ + DefaultSkin.cpp \ + OtherSkin.cpp diff --git a/examples/hmi-demo/images.qrc b/examples/hmi-demo/images.qrc new file mode 100644 index 00000000..4b72d97e --- /dev/null +++ b/examples/hmi-demo/images.qrc @@ -0,0 +1,22 @@ + + + + images/background.jpg + images/car.svg + images/down.svg + images/ic_airplanemode_active_white_18dp_2x.png + images/ic_build_white_24dp_2x.png + images/ic_extension_white_48dp_2x.png + images/ic_face_white_48px.svg + images/ic_fast_forward_white_18dp_2x.png + images/ic_fast_rewind_white_18dp_2x.png + images/ic_pan_tool_white_48dp_2x.png + images/ic_skip_next_white_18dp_1x.png + images/ic_skip_previous_white_18dp_2x.png + images/ic_star_rate_white_18dp_2x.png + images/left.svg + images/right.svg + images/up.svg + + + diff --git a/examples/hmi-demo/images/background-original.jpg b/examples/hmi-demo/images/background-original.jpg new file mode 100644 index 00000000..80014c73 Binary files /dev/null and b/examples/hmi-demo/images/background-original.jpg differ diff --git a/examples/hmi-demo/images/background.jpg b/examples/hmi-demo/images/background.jpg new file mode 100644 index 00000000..3ce90504 Binary files /dev/null and b/examples/hmi-demo/images/background.jpg differ diff --git a/examples/hmi-demo/images/car.svg b/examples/hmi-demo/images/car.svg new file mode 100644 index 00000000..4beb2aab --- /dev/null +++ b/examples/hmi-demo/images/car.svg @@ -0,0 +1,410 @@ + + + + + + Red Car - Top View + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Red Car - Top View + 2010-05-19T15:02:12 + I was thinking of Trophy ( http://trophy.sourceforge.net/index.php?body=screenshots ) when remixing this one :) + https://openclipart.org/detail/61201/red-racing-car-top-view-by-qubodup + + + qubodup + + + + + car + game + game sprite + racing + racing car + red + red car + simple + simple car + sprite + transport + transportation + travel + video game + video game art + video game sprite + + + + + + + + + + + diff --git a/examples/hmi-demo/images/down.svg b/examples/hmi-demo/images/down.svg new file mode 100644 index 00000000..0acfad0c --- /dev/null +++ b/examples/hmi-demo/images/down.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/hmi-demo/images/ic_airplanemode_active_white_18dp_2x.png b/examples/hmi-demo/images/ic_airplanemode_active_white_18dp_2x.png new file mode 100644 index 00000000..4f8165f1 Binary files /dev/null and b/examples/hmi-demo/images/ic_airplanemode_active_white_18dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_build_white_24dp_2x.png b/examples/hmi-demo/images/ic_build_white_24dp_2x.png new file mode 100644 index 00000000..db384dee Binary files /dev/null and b/examples/hmi-demo/images/ic_build_white_24dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_extension_white_48dp_2x.png b/examples/hmi-demo/images/ic_extension_white_48dp_2x.png new file mode 100644 index 00000000..d740716b Binary files /dev/null and b/examples/hmi-demo/images/ic_extension_white_48dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_face_white_48px.svg b/examples/hmi-demo/images/ic_face_white_48px.svg new file mode 100644 index 00000000..50834f60 --- /dev/null +++ b/examples/hmi-demo/images/ic_face_white_48px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/examples/hmi-demo/images/ic_fast_forward_white_18dp_2x.png b/examples/hmi-demo/images/ic_fast_forward_white_18dp_2x.png new file mode 100644 index 00000000..cf15f0c7 Binary files /dev/null and b/examples/hmi-demo/images/ic_fast_forward_white_18dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_fast_rewind_white_18dp_2x.png b/examples/hmi-demo/images/ic_fast_rewind_white_18dp_2x.png new file mode 100644 index 00000000..3d754e27 Binary files /dev/null and b/examples/hmi-demo/images/ic_fast_rewind_white_18dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_pan_tool_white_48dp_2x.png b/examples/hmi-demo/images/ic_pan_tool_white_48dp_2x.png new file mode 100644 index 00000000..e872653d Binary files /dev/null and b/examples/hmi-demo/images/ic_pan_tool_white_48dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_skip_next_white_18dp_1x.png b/examples/hmi-demo/images/ic_skip_next_white_18dp_1x.png new file mode 100644 index 00000000..26434a02 Binary files /dev/null and b/examples/hmi-demo/images/ic_skip_next_white_18dp_1x.png differ diff --git a/examples/hmi-demo/images/ic_skip_previous_white_18dp_2x.png b/examples/hmi-demo/images/ic_skip_previous_white_18dp_2x.png new file mode 100644 index 00000000..23faeeb0 Binary files /dev/null and b/examples/hmi-demo/images/ic_skip_previous_white_18dp_2x.png differ diff --git a/examples/hmi-demo/images/ic_star_rate_white_18dp_2x.png b/examples/hmi-demo/images/ic_star_rate_white_18dp_2x.png new file mode 100644 index 00000000..a182ef21 Binary files /dev/null and b/examples/hmi-demo/images/ic_star_rate_white_18dp_2x.png differ diff --git a/examples/hmi-demo/images/left.svg b/examples/hmi-demo/images/left.svg new file mode 100644 index 00000000..016fdd2c --- /dev/null +++ b/examples/hmi-demo/images/left.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/hmi-demo/images/right.svg b/examples/hmi-demo/images/right.svg new file mode 100644 index 00000000..f88ab81a --- /dev/null +++ b/examples/hmi-demo/images/right.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/hmi-demo/images/up.svg b/examples/hmi-demo/images/up.svg new file mode 100644 index 00000000..52619ba8 --- /dev/null +++ b/examples/hmi-demo/images/up.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/hmi-demo/main.cpp b/examples/hmi-demo/main.cpp new file mode 100644 index 00000000..49b997c0 --- /dev/null +++ b/examples/hmi-demo/main.cpp @@ -0,0 +1,69 @@ +#include "MainWindow.h" +#include "DefaultSkin.h" +#include "OtherSkin.h" + +#include +#include +#include + +#include + +#include + +namespace { + +class SkinFactory : public QskSkinFactory +{ + Q_OBJECT + +public: + SkinFactory() : QskSkinFactory() + { + } + + virtual QStringList skinNames() const override final + { + return { "DefaultSkin", "OtherSkin" }; + } + + virtual QskSkin* createSkin( const QString& skinName ) override + { + if ( skinName == "DefaultSkin" ) + return new DefaultSkin( skinName ); + + if ( skinName == "OtherSkin" ) + return new OtherSkin( skinName ); + + return nullptr; + } + +public Q_SLOTS: + void toggleScheme() + { + DefaultSkin* skin = static_cast< DefaultSkin* >( qskSetup->skin() ); + if ( skin ) + skin->toggleScheme(); + } +}; + +} + +int main( int argc, char **argv ) +{ + QGuiApplication app( argc, argv ); + + SkinFactory skinFactory; + Qsk::registerSkinFactory( "SampleSkinFactory", &skinFactory ); + QskSetup::instance()->setSkin( "DefaultSkin" ); + + SkinnyShortcut::enable( SkinnyShortcut::DebugBackground | SkinnyShortcut::Quit | SkinnyShortcut::RotateSkin ); + + QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_T ), &skinFactory, + SLOT( toggleScheme() ), false ); + + MainWindow mainWindow; + mainWindow.show(); + return app.exec(); +} + +#include "main.moc"