qskinny/examples/mycontrols/main.cpp

269 lines
8.0 KiB
C++
Raw Normal View History

2019-02-26 20:52:02 +00:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
2023-04-06 07:23:37 +00:00
* SPDX-License-Identifier: BSD-3-Clause
2019-02-26 20:52:02 +00:00
*****************************************************************************/
#include "MySkin.h"
#include "MyToggleButton.h"
#include <SkinnyShapeProvider.h>
#include <SkinnyShortcut.h>
#include <QskWindow.h>
#include <QskObjectCounter.h>
#include <QskFocusIndicator.h>
#include <QskBox.h>
#include <QskLinearBox.h>
#include <QskSkinManager.h>
2022-03-24 10:17:03 +00:00
#include <QskAnimationHint.h>
2019-02-26 20:52:02 +00:00
#include <QskSkinTransition.h>
#include <QskSetup.h>
#include <QskSkin.h>
2023-11-05 17:29:56 +00:00
#include <QskSkinlet.h>
#include <QskSGNode.h>
#include <QskGraduationMetrics.h>
2023-11-05 17:29:56 +00:00
#include <QskTickmarksNode.h>
#include <QskScaleTickmarks.h>
#include <QskTextLabel.h>
2023-11-05 19:31:57 +00:00
#include <QskAnimator.h>
#include <QskGraduationMetrics.h>
2019-02-26 20:52:02 +00:00
#include <QGuiApplication>
2023-11-05 19:43:02 +00:00
#include <qmath.h>
2019-02-26 20:52:02 +00:00
/*
This example is intended to show how to:
- implement custom controls
- set up skins, customizing these controls
For demonstration purposes we limit the set of controls
being used:
- QskPushButton
- QskBox
- QskFocusIndicator
- MyToggleButton
*/
class ContentBox : public QskBox
{
public:
ContentBox( QQuickItem* parent = nullptr )
: QskBox( parent )
{
setAutoLayoutChildren( true );
auto layout = new QskLinearBox( Qt::Horizontal, 2, this );
layout->setMargins( 10 );
2019-02-26 21:13:43 +00:00
layout->setSpacing( 20 );
2019-02-26 20:52:02 +00:00
layout->setDefaultAlignment( Qt::AlignCenter );
layout->setExtraSpacingAt( Qt::BottomEdge );
2021-12-27 17:47:46 +00:00
const QskSizePolicy sizePolicy(
QskSizePolicy::MinimumExpanding, QskSizePolicy::MinimumExpanding );
2019-02-26 20:52:02 +00:00
{
auto button = new MyToggleButton( layout );
2021-12-27 17:47:46 +00:00
button->setSizePolicy( sizePolicy );
button->setText( false, "Off" );
button->setText( true, "On" );
2019-02-26 20:52:02 +00:00
}
{
auto button = new MyToggleButton( layout );
2021-12-27 17:47:46 +00:00
button->setSizePolicy( sizePolicy );
button->setIcon( false, "image://shapes/Diamond/Khaki" );
button->setIcon( true, "image://shapes/Ring/Khaki" );
2019-02-26 20:52:02 +00:00
}
}
};
2023-11-05 17:29:56 +00:00
struct Tickmarks final : public QskControl
2019-02-26 20:52:02 +00:00
{
public:
2023-11-07 19:42:57 +00:00
QSK_SUBCONTROLS(Ticks)
2023-11-05 17:29:56 +00:00
using QskControl::QskControl;
};
2023-11-07 19:42:57 +00:00
QSK_SUBCONTROL(Tickmarks, Ticks)
2023-11-05 17:29:56 +00:00
class TickmarksSkinlet final : public QskSkinlet
{
Q_GADGET
public:
enum NodeRoles
{
TickmarksRole
};
2019-02-26 20:52:02 +00:00
2023-11-05 17:29:56 +00:00
Q_INVOKABLE TickmarksSkinlet(QskSkin* skin = nullptr) : QskSkinlet(skin)
{
setNodeRoles( { TickmarksRole } );
}
2019-02-26 20:52:02 +00:00
2023-11-05 17:29:56 +00:00
QSGNode* updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const override
{
const auto* const q = static_cast< const Tickmarks* >( skinnable );
2019-02-26 20:52:02 +00:00
2023-11-05 17:29:56 +00:00
if(nodeRole == TickmarksRole)
{
auto* const tickmarksNode = QskSGNode::ensureNode<QskTickmarksNode>(node);
const auto rect = q->contentsRect();
QskScaleTickmarks tickmarks;
QVector<qreal> major, medium, minor;
for ( int i = -100; i <= +100; ++i )
{
if(i % 50 == 0) major << i;
else if(i % 10 == 0) medium << i;
else minor << i;
}
tickmarks.setMajorTicks(major);
tickmarks.setMediumTicks(medium);
tickmarks.setMinorTicks(minor);
const auto metric = q->graduationMetricsHint(Tickmarks::Ticks);
2023-11-05 17:29:56 +00:00
tickmarksNode->update(
2023-11-07 19:42:57 +00:00
Qt::darkGray, rect, { -100, +100 }, tickmarks, 1, Qt::Horizontal, Qt::AlignBottom, metric );
2023-11-05 17:29:56 +00:00
return tickmarksNode;
}
2019-02-26 20:52:02 +00:00
2023-11-05 17:29:56 +00:00
return nullptr;
}
};
2019-02-26 20:52:02 +00:00
2023-11-05 17:29:56 +00:00
class Window : public QskWindow
{
public:
Window()
{
auto* const layout = new QskLinearBox(Qt::Vertical, contentItem());
{
(void) new QskTextLabel("Default", layout);
auto* const tickmarks = new Tickmarks(layout);
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
}
{
(void) new QskTextLabel("Custom", layout);
auto* const tickmarks = new Tickmarks(layout);
tickmarks->setGraduationMetricsHint(Tickmarks::Ticks, { 0.2, 0.5, 1.0 } );
2023-11-05 17:29:56 +00:00
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
}
2023-11-05 19:31:57 +00:00
{
(void) new QskTextLabel("Custom (Major only)", layout);
auto* const tickmarks = new Tickmarks(layout);
tickmarks->setGraduationMetricsHint(Tickmarks::Ticks, { 0.0, 0.0, 1.0 } );
2023-11-05 19:31:57 +00:00
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
}
{
(void) new QskTextLabel("Custom (Major + Minor only)", layout);
auto* const tickmarks = new Tickmarks(layout);
tickmarks->setGraduationMetricsHint(Tickmarks::Ticks, { 0.2, 0.0, 1.0 } );
2023-11-05 19:31:57 +00:00
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
}
{
(void) new QskTextLabel("Custom (Animated)", layout);
auto* const tickmarks = new Tickmarks(layout);
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
class Animator final : public QskAnimator
{
public:
explicit Animator(Tickmarks& tickmarks) : tickmarks(tickmarks)
{
setAutoRepeat(true);
setDuration(2000);
}
void advance( qreal value ) override
{
const QskGraduationMetrics metrics {
2023-11-07 19:42:57 +00:00
( 0.1 + 0.1 * qFastSin( value * 2 * M_PI ) ),
( 0.25 + 0.25 * qFastSin( value * 2 * M_PI ) ),
( 0.5 + 0.5 * qFastSin( value * 2 * M_PI ) )
};
tickmarks.setGraduationMetricsHint(Tickmarks::Ticks, metrics);
2023-11-05 19:31:57 +00:00
}
Tickmarks& tickmarks;
};
auto* const animator = new Animator(*tickmarks);
animator->setWindow(this);
animator->start();
}
2019-02-26 20:52:02 +00:00
}
private:
void setAlternativeSkin( bool on )
{
auto oldSkin = qskSetup->skin();
if ( oldSkin->parent() == qskSetup )
oldSkin->setParent( nullptr ); // otherwise setSkin deletes it
2021-12-27 17:47:46 +00:00
auto newSkin = qskSetup->setSkin( alternativeSkin( on ) );
2019-02-26 20:52:02 +00:00
QskSkinTransition transition;
transition.setSourceSkin( oldSkin );
transition.setTargetSkin( newSkin );
2019-02-28 07:20:02 +00:00
transition.setAnimation( QskAnimationHint( 600, QEasingCurve::Linear ) );
2019-02-26 20:52:02 +00:00
transition.process();
if ( oldSkin->parent() == nullptr )
delete oldSkin;
}
2021-12-27 17:47:46 +00:00
QString alternativeSkin( bool on ) const
{
const auto skinNames = qskSkinManager->skinNames();
return skinNames[ on ];
}
2019-02-26 20:52:02 +00:00
};
int main( int argc, char* argv[] )
{
#ifdef ITEM_STATISTICS
QskObjectCounter counter( true );
#endif
QGuiApplication app( argc, argv );
SkinnyShortcut::enable( SkinnyShortcut::DebugBackground |
SkinnyShortcut::DebugStatistics | SkinnyShortcut::Quit );
Qsk::addGraphicProvider( "shapes", new SkinnyShapeProvider() );
qskSkinManager->setPluginPaths( QStringList() ); // no plugins
qskSkinManager->unregisterFactories(); // get rid of the factories of the support lib
2019-02-26 20:52:02 +00:00
qskSkinManager->registerFactory(
QStringLiteral( "MySkinFactory" ), new MySkinFactory() );
2021-02-09 07:13:20 +00:00
qskSetup->setItemUpdateFlag( QskQuickItem::PreferRasterForTextures, true );
2019-02-26 20:52:02 +00:00
Window window;
window.resize( 480, 360 );
window.show();
return app.exec();
}
2023-11-05 17:29:56 +00:00
#include "main.moc"