added leveling sensor playground
This commit is contained in:
parent
0f452813ff
commit
87b304e0c5
|
@ -6,6 +6,7 @@ add_subdirectory(invoker)
|
|||
add_subdirectory(shadows)
|
||||
add_subdirectory(shapes)
|
||||
add_subdirectory(charts)
|
||||
add_subdirectory(levelingsensor)
|
||||
|
||||
if (BUILD_INPUTCONTEXT)
|
||||
add_subdirectory(inputpanel)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
############################################################################
|
||||
# QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
############################################################################
|
||||
|
||||
set(SOURCES
|
||||
SkinFactory.h SkinFactory.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
qsk_add_example(levelingsensor ${SOURCES})
|
|
@ -0,0 +1,125 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QskTextLabel.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace
|
||||
{
|
||||
class DashboardDial : public Dial
|
||||
{
|
||||
public:
|
||||
DashboardDial( const QString& title, QQuickItem* parent = nullptr )
|
||||
: Dial( parent )
|
||||
{
|
||||
setPolishOnResize( true );
|
||||
m_label = new QskTextLabel( title, this );
|
||||
}
|
||||
|
||||
protected:
|
||||
void updateLayout() override
|
||||
{
|
||||
const auto r = layoutRect();
|
||||
|
||||
const auto hint = m_label->sizeConstraint();
|
||||
|
||||
const qreal y = r.y() + 0.6 * r.height() - 0.5 * hint.height();
|
||||
const qreal x = r.center().x() - 0.5 * hint.width();
|
||||
|
||||
m_label->setGeometry( x, y, hint.width(), hint.height() );
|
||||
}
|
||||
|
||||
private:
|
||||
QskTextLabel* m_label;
|
||||
};
|
||||
|
||||
class RevCounter : public DashboardDial
|
||||
{
|
||||
public:
|
||||
RevCounter( QQuickItem* parent = nullptr )
|
||||
: DashboardDial( "x 1000 min^-1", parent )
|
||||
{
|
||||
setMinimum( 145 );
|
||||
setMaximum( 305 );
|
||||
setValue( 200 );
|
||||
|
||||
constexpr int labelsCount = 8;
|
||||
|
||||
QVector< QString > labels;
|
||||
labels.reserve( labelsCount );
|
||||
|
||||
for ( int i = 0; i < labelsCount; i++ )
|
||||
labels += QString::number( i );
|
||||
|
||||
setTickLabels( labels );
|
||||
}
|
||||
};
|
||||
|
||||
class SpeedoMeter : public DashboardDial
|
||||
{
|
||||
public:
|
||||
SpeedoMeter( QQuickItem* parent = nullptr )
|
||||
: DashboardDial( "km/h", parent )
|
||||
{
|
||||
setMinimum( -215 );
|
||||
setMaximum( 35 );
|
||||
setValue( -90 );
|
||||
|
||||
constexpr int labelsCount = 17;
|
||||
|
||||
QVector< QString > labels;
|
||||
labels.reserve( labelsCount );
|
||||
|
||||
for ( int i = 0; i < labelsCount; i++ )
|
||||
labels.append( QString::number( i * 10 ) );
|
||||
|
||||
setTickLabels( labels );
|
||||
}
|
||||
|
||||
void updateValue()
|
||||
{
|
||||
setValue( value() + std::rand() % 3 - 0.95 );
|
||||
}
|
||||
};
|
||||
|
||||
class FuelGauge : public DashboardDial
|
||||
{
|
||||
public:
|
||||
FuelGauge( QQuickItem* parent = nullptr )
|
||||
: DashboardDial( "fuel", parent )
|
||||
{
|
||||
setMinimum( 195 );
|
||||
setMaximum( 345 );
|
||||
setValue( 330 );
|
||||
|
||||
setTickLabels( { "0", "", "1/2", "", "1/1" } );
|
||||
}
|
||||
|
||||
void updateValue()
|
||||
{
|
||||
setValue( 0.99997 * value() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Dashboard::Dashboard( QQuickItem* parent )
|
||||
: QskLinearBox( Qt::Horizontal, parent )
|
||||
{
|
||||
(void ) new RevCounter( this );
|
||||
auto speedometer = new SpeedoMeter( this );
|
||||
auto fuelGauge = new FuelGauge( this );
|
||||
|
||||
setMargins( 10 );
|
||||
setSpacing( 10 );
|
||||
|
||||
auto timer = new QTimer( this );
|
||||
|
||||
connect( timer, &QTimer::timeout, speedometer, &SpeedoMeter::updateValue );
|
||||
connect( timer, &QTimer::timeout, fuelGauge, &FuelGauge::updateValue );
|
||||
|
||||
timer->setInterval( 16 );
|
||||
timer->start();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskWindow.h>
|
||||
|
||||
class QQuickItem;
|
||||
|
||||
class MainWindow : public QskWindow
|
||||
{
|
||||
public:
|
||||
MainWindow();
|
||||
};
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkinFactory.h"
|
||||
|
||||
#include <QskBoxBorderColors.h>
|
||||
#include <QskGradient.h>
|
||||
#include <QskGradientStop.h>
|
||||
#include <QskPlatform.h>
|
||||
#include <QskRgbValue.h>
|
||||
#include <QskSkin.h>
|
||||
#include <QskSkinHintTableEditor.h>
|
||||
#include <QskTextLabel.h>
|
||||
|
||||
#include <LevelingSensor/QskLevelingSensor.h>
|
||||
#include <LevelingSensor/QskLevelingSensorSkinlet.h>
|
||||
|
||||
#include <QskSlider.h>
|
||||
#include <QskSliderSkinlet.h>
|
||||
|
||||
#include <QskTextLabel.h>
|
||||
#include <QskTextLabelSkinlet.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
class Skin : public QskSkin
|
||||
{
|
||||
template< typename T >
|
||||
void style( QskSkinHintTableEditor& editor );
|
||||
|
||||
template< typename Skinnable, typename Skinlet >
|
||||
void declareSkinlet( )
|
||||
{
|
||||
QskSkin::declareSkinlet< Skinnable, Skinlet >();
|
||||
}
|
||||
|
||||
template< typename Skinnable, typename Skinlet >
|
||||
void declareSkinlet( QskSkinHintTableEditor& editor )
|
||||
{
|
||||
QskSkin::declareSkinlet< Skinnable, Skinlet >();
|
||||
style< Skinnable >( editor );
|
||||
}
|
||||
|
||||
template<>
|
||||
void style< QskSlider >( QskSkinHintTableEditor& editor )
|
||||
{
|
||||
using A = QskAspect;
|
||||
using Q = QskSlider;
|
||||
|
||||
const qreal extent = 40;
|
||||
|
||||
// Panel
|
||||
|
||||
for ( auto variation : { A::Horizontal, A::Vertical } )
|
||||
{
|
||||
const auto aspect = Q::Panel | variation;
|
||||
|
||||
editor.setMetric( aspect | A::Size, extent );
|
||||
editor.setBoxBorderMetrics( aspect, 0 );
|
||||
editor.setBoxShape( aspect, 0 );
|
||||
editor.setGradient( aspect, QskGradient() );
|
||||
}
|
||||
|
||||
// Groove, Fill
|
||||
|
||||
for ( auto variation : { A::Horizontal, A::Vertical } )
|
||||
{
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
const auto aspect = subControl | variation;
|
||||
|
||||
editor.setMetric( aspect | A::Size, 0.3 * extent );
|
||||
|
||||
editor.setBoxBorderMetrics( aspect, 0 );
|
||||
editor.setBoxShape( aspect, 0.1 * extent );
|
||||
}
|
||||
|
||||
editor.setGradient( Q::Groove | variation, Qt::lightGray );
|
||||
editor.setGradient( Q::Fill | variation, Qt::darkGray );
|
||||
}
|
||||
|
||||
// Handle
|
||||
|
||||
for ( auto variation : { A::Horizontal, A::Vertical } )
|
||||
{
|
||||
const auto aspect = Q::Handle | variation;
|
||||
editor.setColor( aspect, Qt::black );
|
||||
|
||||
editor.setBoxShape( aspect, 20.0, Qt::RelativeSize );
|
||||
|
||||
const qreal sz = 0.75 * extent;
|
||||
editor.setStrutSize( aspect, sz, sz );
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void style< QskLevelingSensor >( QskSkinHintTableEditor& ed )
|
||||
{
|
||||
using Q = QskLevelingSensor;
|
||||
|
||||
static constexpr auto r1 = 0.9;
|
||||
static constexpr auto r2 = 1.0;
|
||||
|
||||
QskGradient gradient{ {
|
||||
{ 0.5, Qt::lightGray },
|
||||
{ 0.5, Qt::lightGray },
|
||||
{ 0.5, Qt::darkGray },
|
||||
{ 1.0, Qt::darkGray },
|
||||
} };
|
||||
gradient.setLinearDirection( Qt::Vertical );
|
||||
|
||||
ed.setColor( Q::Background, "dimgray" );
|
||||
|
||||
ed.setStrutSize( Q::OuterDisk, { r2, r2 } );
|
||||
ed.setColor( Q::OuterDisk, Qt::white );
|
||||
|
||||
ed.setGradient( Q::Horizon, gradient );
|
||||
ed.setStrutSize( Q::Horizon, { r1, r1 } );
|
||||
|
||||
ed.setColor( Q::TickmarksX, Qt::black );
|
||||
ed.setStrutSize( Q::TickmarksX, { r1, 0.2 } ); // w %, h %
|
||||
ed.setHint( Q::TickmarksX, QVector3D{ 0.50, 0.75, 1.0 } ); // %
|
||||
|
||||
ed.setStrutSize( Q::TickmarksXLabels, { r1, 0.15 } ); // w %, h %
|
||||
ed.setAlignment( Q::TickmarksXLabels, Qt::AlignTop | Qt::AlignHCenter );
|
||||
|
||||
ed.setColor( Q::TickmarksY, Qt::black );
|
||||
ed.setStrutSize( Q::TickmarksY, { 0.1, r1 } ); // w %, h %
|
||||
ed.setHint( Q::TickmarksY, QVector3D{ 0.50, 0.75, 1.00 } ); // %
|
||||
|
||||
ed.setStrutSize( Q::TickmarksYLabels, { 0.15, r1 } ); // w %, h %
|
||||
ed.setAlignment( Q::TickmarksYLabels, Qt::AlignCenter );
|
||||
|
||||
ed.setColor( Q::TickmarksZ, "silver" );
|
||||
ed.setStrutSize( Q::TickmarksZ, { 0.90, 0.95 } );
|
||||
ed.setHint( Q::TickmarksZ, QVector3D{ 0.50, 0.75, 1.00 } ); // %
|
||||
|
||||
ed.setStrutSize( Q::TickmarksZLabels, { 0.9, 0.0 } ); // r1 %, r2 %
|
||||
ed.setAlignment( Q::TickmarksZLabels, Qt::AlignCenter );
|
||||
}
|
||||
|
||||
public:
|
||||
Skin()
|
||||
{
|
||||
QskSkinHintTableEditor editor( &hintTable() );
|
||||
declareSkinlet< QskSlider, QskSliderSkinlet >( editor );
|
||||
declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
|
||||
declareSkinlet< QskLevelingSensor, QskLevelingSensorSkinlet >( editor );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
QStringList SkinFactory::skinNames() const
|
||||
{
|
||||
return { "Skin" };
|
||||
}
|
||||
|
||||
QskSkin* SkinFactory::createSkin( const QString& skinName )
|
||||
{
|
||||
if ( skinName == "Skin" )
|
||||
return new Skin();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#include "moc_SkinFactory.cpp"
|
|
@ -0,0 +1,17 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskSkinFactory.h>
|
||||
|
||||
class SkinFactory : public QskSkinFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QStringList skinNames() const override;
|
||||
QskSkin* createSkin( const QString& ) override;
|
||||
};
|
|
@ -0,0 +1,159 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkinFactory.h"
|
||||
|
||||
#include <SkinnyShortcut.h>
|
||||
|
||||
#include <QskObjectCounter.h>
|
||||
#include <QskSkinManager.h>
|
||||
#include <QskWindow.h>
|
||||
|
||||
#include <LevelingSensor/QskLevelingSensor.h>
|
||||
#include <QskIntervalF.h>
|
||||
#include <QskLinearBox.h>
|
||||
#include <QskSlider.h>
|
||||
#include <QskTextLabel.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQuickWindow>
|
||||
|
||||
namespace
|
||||
{
|
||||
void updateTickmarks( const Qt::Axis axis, const QskIntervalF& intervalA,
|
||||
const QskIntervalF& intervalB, QskLevelingSensor* const sensor )
|
||||
{
|
||||
QskScaleTickmarks tickmarks;
|
||||
QVector< qreal > major;
|
||||
QVector< qreal > medium;
|
||||
QVector< qreal > minor;
|
||||
|
||||
for ( const auto& interval : { intervalA, intervalB } )
|
||||
{
|
||||
for ( int deg = ( int ) interval.lowerBound(); deg < ( int ) interval.upperBound();
|
||||
++deg )
|
||||
{
|
||||
if ( deg % 45 == 0 )
|
||||
{
|
||||
major << deg;
|
||||
}
|
||||
if ( deg % 45 != 0 && deg % 5 == 0 )
|
||||
{
|
||||
medium << deg;
|
||||
}
|
||||
if ( deg % 45 != 0 && deg % 5 != 0 )
|
||||
{
|
||||
minor << deg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tickmarks.setMajorTicks( major );
|
||||
tickmarks.setMediumTicks( medium );
|
||||
tickmarks.setMinorTicks( minor );
|
||||
sensor->setTickmarks( axis, tickmarks );
|
||||
}
|
||||
|
||||
void updateTickmarksLabels( const Qt::Axis axis, const QskIntervalF& intervalA,
|
||||
const QskIntervalF& intervalB, int step, QskLevelingSensor* const sensor )
|
||||
{
|
||||
QskLevelingSensor::TickmarksLabels labels;
|
||||
for ( const auto& interval : { intervalA, intervalB } )
|
||||
{
|
||||
for ( int deg = ( ( int ) interval.lowerBound() / step ) * step;
|
||||
deg < ( int ) interval.upperBound(); deg += step )
|
||||
{
|
||||
labels << QskLevelingSensor::TickmarksLabels::value_type{ ( float ) deg,
|
||||
QString( deg > 0 ? "+" : "" ) + QString::number( deg ) };
|
||||
}
|
||||
}
|
||||
sensor->setTickmarksLabels( axis, labels );
|
||||
}
|
||||
|
||||
Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis, QskLevelingSensor* const sensor, int min, int max, std::function<QskIntervalF(qreal)> intervalA, std::function<QskIntervalF(qreal)> intervalB, QQuickItem* const parent = nullptr )
|
||||
{
|
||||
auto* const slider = new QskSlider( Qt::Horizontal, parent );
|
||||
slider->setMinimum( min );
|
||||
slider->setMaximum( max );
|
||||
|
||||
QObject::connect(slider, &QskSlider::valueChanged, sensor, [ = ]( const qreal degree ) {
|
||||
updateTickmarks( axis, intervalA(degree), intervalB(degree), sensor );
|
||||
updateTickmarksLabels( axis, intervalA( degree ), intervalB( degree ), 10, sensor );
|
||||
} );
|
||||
|
||||
return slider;
|
||||
}
|
||||
|
||||
Q_REQUIRED_RESULT QskSlider* makeRotationSlider(
|
||||
const Qt::Axis axis, QskLevelingSensor* const sensor, QQuickItem* const parent = nullptr )
|
||||
{
|
||||
auto* const slider = new QskSlider( Qt::Horizontal, parent );
|
||||
slider->setMinimum( -360 );
|
||||
slider->setMaximum( +360 );
|
||||
|
||||
QObject::connect( sensor, &QskLevelingSensor::rotationChanged, slider,
|
||||
[ slider, axis ]( const QVector3D& degree ) { slider->setValue( degree[ axis ] ); } );
|
||||
|
||||
QObject::connect( slider, &QskSlider::valueChanged, sensor,
|
||||
[ sensor, axis ]( const qreal degree ) { sensor->setRotation( axis, degree ); } );
|
||||
|
||||
return slider;
|
||||
}
|
||||
|
||||
class Window : public QskWindow
|
||||
{
|
||||
public:
|
||||
Window()
|
||||
{
|
||||
auto* const root = new QskLinearBox( Qt::Horizontal, contentItem() );
|
||||
auto* const left = new QskLinearBox( Qt::Vertical, root );
|
||||
auto* const right = new QskLinearBox( Qt::Vertical, root );
|
||||
auto* const sensor = new QskLevelingSensor( left );
|
||||
|
||||
auto linearIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};};
|
||||
auto linearIntervalB = [](const qreal degree)->QskIntervalF{ return {}; };
|
||||
|
||||
auto radialIntervalA = [](const qreal degree)->QskIntervalF{ return {-degree, +degree};};
|
||||
auto radialIntervalB = [](const qreal degree)->QskIntervalF{ return {180-degree, 180+degree};};
|
||||
|
||||
( void ) new QskTextLabel( "Tickmarks X", right );
|
||||
auto* const sliderTickmarksX = makeTickmarksSlider( Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
||||
( void ) new QskTextLabel( "Tickmarks Y", right );
|
||||
auto* const sliderTickmarksY = makeTickmarksSlider( Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
||||
( void ) new QskTextLabel( "Tickmarks Z", right );
|
||||
auto* const sliderTickmarksZ = makeTickmarksSlider( Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right );
|
||||
|
||||
( void ) new QskTextLabel( "Rotation X", right );
|
||||
( void ) makeRotationSlider( Qt::XAxis, sensor, right );
|
||||
( void ) new QskTextLabel( "Rotation Y", right );
|
||||
( void ) makeRotationSlider( Qt::YAxis, sensor, right );
|
||||
( void ) new QskTextLabel( "Rotation Z", right );
|
||||
( void ) makeRotationSlider( Qt::ZAxis, sensor, right );
|
||||
|
||||
sliderTickmarksX->setValue(15);
|
||||
sliderTickmarksY->setValue(15);
|
||||
sliderTickmarksZ->setValue(30);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
#ifdef ITEM_STATISTICS
|
||||
QskObjectCounter counter( true );
|
||||
#endif
|
||||
|
||||
qskSkinManager->setPluginPaths( QStringList() ); // no skin plugins
|
||||
qskSkinManager->registerFactory( QStringLiteral( "sample" ), new SkinFactory() );
|
||||
|
||||
QGuiApplication app( argc, argv );
|
||||
|
||||
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
||||
|
||||
Window window;
|
||||
window.showMaximized();
|
||||
|
||||
return app.exec();
|
||||
}
|
Loading…
Reference in New Issue