add QskTickmarksMetrics

This commit is contained in:
Rick Vogel 2023-11-05 18:29:56 +01:00
parent d968b20199
commit e6a91ad19d
8 changed files with 204 additions and 26 deletions

View File

@ -19,6 +19,12 @@
#include <QskSkinTransition.h> #include <QskSkinTransition.h>
#include <QskSetup.h> #include <QskSetup.h>
#include <QskSkin.h> #include <QskSkin.h>
#include <QskSkinlet.h>
#include <QskSGNode.h>
#include <QskTickmarksMetrics.h>
#include <QskTickmarksNode.h>
#include <QskScaleTickmarks.h>
#include <QskTextLabel.h>
#include <QGuiApplication> #include <QGuiApplication>
@ -72,31 +78,82 @@ class ContentBox : public QskBox
} }
}; };
struct Tickmarks final : public QskControl
{
public:
using QskControl::QskControl;
QskTickmarksMetrics metrics;
};
class TickmarksSkinlet final : public QskSkinlet
{
Q_GADGET
public:
enum NodeRoles
{
TickmarksRole
};
Q_INVOKABLE TickmarksSkinlet(QskSkin* skin = nullptr) : QskSkinlet(skin)
{
setNodeRoles( { TickmarksRole } );
}
QSGNode* updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const override
{
const auto* const q = static_cast< const Tickmarks* >( skinnable );
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);
tickmarksNode->update(
Qt::darkGray, rect, { -100, +100 }, tickmarks, 1, Qt::Horizontal, Qt::AlignBottom, q->metrics );
return tickmarksNode;
}
return nullptr;
}
};
class Window : public QskWindow class Window : public QskWindow
{ {
public: public:
Window() Window()
{ {
auto button = new MyToggleButton(); auto* const layout = new QskLinearBox(Qt::Vertical, contentItem());
{
button->setText( false, alternativeSkin( false ) ); (void) new QskTextLabel("Default", layout);
button->setText( true, alternativeSkin( true ) ); auto* const tickmarks = new Tickmarks(layout);
button->setLayoutAlignmentHint( Qt::AlignRight ); auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
auto box = new QskLinearBox( Qt::Vertical ); skinlet->setOwnedBySkinnable(true);
}
box->setMargins( 20 ); {
box->addItem( button ); (void) new QskTextLabel("Custom", layout);
box->addSpacer( 10 ); auto* const tickmarks = new Tickmarks(layout);
box->addItem( new ContentBox() ); tickmarks->metrics[QskScaleTickmarks::MajorTick] = 1.0;
tickmarks->metrics[QskScaleTickmarks::MediumTick] = 0.5;
connect( button, &MyToggleButton::toggled, tickmarks->metrics[QskScaleTickmarks::MinorTick] = 0.2;
this, &Window::setAlternativeSkin ); auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
setAlternativeSkin( button->isChecked() ); skinlet->setOwnedBySkinnable(true);
}
addItem( box );
addItem( new QskFocusIndicator() );
} }
private: private:
@ -154,3 +211,5 @@ int main( int argc, char* argv[] )
return app.exec(); return app.exec();
} }
#include "main.moc"

View File

@ -123,6 +123,7 @@ list(APPEND HEADERS
nodes/QskTextRenderer.h nodes/QskTextRenderer.h
nodes/QskTextureRenderer.h nodes/QskTextureRenderer.h
nodes/QskTickmarksNode.h nodes/QskTickmarksNode.h
nodes/QskTickmarksMetrics.h
nodes/QskVertex.h nodes/QskVertex.h
) )
@ -154,6 +155,7 @@ list(APPEND SOURCES
nodes/QskTextRenderer.cpp nodes/QskTextRenderer.cpp
nodes/QskTextureRenderer.cpp nodes/QskTextureRenderer.cpp
nodes/QskTickmarksNode.cpp nodes/QskTickmarksNode.cpp
nodes/QskTickmarksMetrics.cpp
nodes/QskVertex.cpp nodes/QskVertex.cpp
) )

View File

@ -58,7 +58,7 @@ inline QMarginsF qskMargins( const QRectF& rect, const QRectF& innerRect )
rect.bottom() - innerRect.bottom() ); rect.bottom() - innerRect.bottom() );
} }
inline bool qskFuzzyCompare( qreal value1, qreal value2 ) inline constexpr bool qskFuzzyCompare( qreal value1, qreal value2 )
{ {
if ( qFuzzyIsNull( value1 ) ) if ( qFuzzyIsNull( value1 ) )
return qFuzzyIsNull( value2 ); return qFuzzyIsNull( value2 );

View File

@ -7,6 +7,7 @@
#include "QskScaleTickmarks.h" #include "QskScaleTickmarks.h"
#include "QskSkinlet.h" #include "QskSkinlet.h"
#include "QskSGNode.h" #include "QskSGNode.h"
#include "QskTickmarksMetrics.h"
#include "QskTickmarksNode.h" #include "QskTickmarksNode.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskTextColors.h" #include "QskTextColors.h"
@ -230,7 +231,7 @@ QSGNode* QskScaleRenderer::updateTicksNode(
ticksNode->update( m_data->tickColor, rect, m_data->boundaries, ticksNode->update( m_data->tickColor, rect, m_data->boundaries,
m_data->tickmarks, tickWidth, m_data->orientation, m_data->tickmarks, tickWidth, m_data->orientation,
m_data->alignment ); m_data->alignment, {});
return ticksNode; return ticksNode;
} }

View File

@ -0,0 +1 @@
#include "QskTickmarksMetrics.h"

View File

@ -0,0 +1,113 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_TICKMARKS_METRICS_H
#define QSK_TICKMARKS_METRICS_H
#include "QskFunctions.h"
#include <qmetatype.h>
class QSK_EXPORT QskTickmarksMetrics
{
Q_GADGET
Q_PROPERTY( qreal majorRatio READ majorRatio WRITE setMajorRatio)
Q_PROPERTY( qreal mediumRatio READ mediumRatio WRITE setMediumRatio)
Q_PROPERTY( qreal minorRatio READ minorRatio WRITE setMinorRatio)
public:
constexpr QskTickmarksMetrics() noexcept = default;
constexpr QskTickmarksMetrics( qreal minorRatio, qreal mediumRatio, qreal majorRatio ) noexcept;
constexpr QskTickmarksMetrics(const QskTickmarksMetrics&) noexcept = default;
constexpr QskTickmarksMetrics( QskTickmarksMetrics&& ) noexcept = default;
constexpr QskTickmarksMetrics& operator=(const QskTickmarksMetrics&) noexcept = default;
constexpr QskTickmarksMetrics& operator=(QskTickmarksMetrics&&) noexcept = default;
constexpr Q_REQUIRED_RESULT bool operator==(const QskTickmarksMetrics& rhs) const noexcept;
constexpr Q_REQUIRED_RESULT bool operator!=(const QskTickmarksMetrics& rhs) const noexcept;
constexpr Q_REQUIRED_RESULT qreal majorRatio() const noexcept;
constexpr Q_REQUIRED_RESULT qreal mediumRatio() const noexcept;
constexpr Q_REQUIRED_RESULT qreal minorRatio() const noexcept;
constexpr void setMajorRatio( qreal ratio ) noexcept;
constexpr void setMediumRatio( qreal ratio ) noexcept;
constexpr void setMinorRatio( qreal ratio ) noexcept;
constexpr Q_REQUIRED_RESULT qreal operator[](int index) const noexcept;
constexpr Q_REQUIRED_RESULT qreal& operator[](int index) noexcept;
private:
union
{
struct
{
qreal m_minorRatio;
qreal m_mediumRatio;
qreal m_majorRatio;
};
qreal size[3] = { 0.7, 0.85, 1.0 };
};
};
inline constexpr QskTickmarksMetrics::QskTickmarksMetrics(qreal minorRatio, qreal mediumRatio, qreal majorRatio) noexcept
: m_minorRatio(minorRatio), m_mediumRatio(mediumRatio), m_majorRatio(majorRatio)
{
}
inline constexpr qreal QskTickmarksMetrics::majorRatio() const noexcept
{
return m_majorRatio;
}
inline constexpr qreal QskTickmarksMetrics::mediumRatio() const noexcept
{
return m_mediumRatio;
}
inline constexpr qreal QskTickmarksMetrics::minorRatio() const noexcept
{
return m_minorRatio;
}
inline constexpr void QskTickmarksMetrics::setMajorRatio( qreal ratio ) noexcept
{
m_majorRatio = qBound( 0.0, ratio, 1.0 );
}
inline constexpr void QskTickmarksMetrics::setMediumRatio( qreal ratio ) noexcept
{
m_mediumRatio = qBound( 0.0, ratio, 1.0 );
}
inline constexpr void QskTickmarksMetrics::setMinorRatio( qreal ratio ) noexcept
{
m_minorRatio = qBound( 0.0, ratio, 1.0 );
}
inline constexpr bool QskTickmarksMetrics::operator==(const QskTickmarksMetrics& rhs) const noexcept
{
return qskFuzzyCompare(m_minorRatio, rhs.m_minorRatio) &&
qskFuzzyCompare(m_mediumRatio, rhs.m_mediumRatio) &&
qskFuzzyCompare(m_majorRatio, rhs.m_majorRatio);
}
inline constexpr bool QskTickmarksMetrics::operator!=(const QskTickmarksMetrics& rhs) const noexcept
{
return !(*this == rhs);
}
inline constexpr qreal QskTickmarksMetrics::operator[](int index) const noexcept
{
return size[index % 3];
}
inline constexpr qreal& QskTickmarksMetrics::operator[](int index) noexcept
{
return size[index % 3];
}
#endif

View File

@ -1,5 +1,6 @@
#include "QskTickmarksNode.h" #include "QskTickmarksNode.h"
#include "QskScaleTickmarks.h" #include "QskScaleTickmarks.h"
#include "QskTickmarksMetrics.h"
#include <QSGFlatColorMaterial> #include <QSGFlatColorMaterial>
#include <QSGGeometryNode> #include <QSGGeometryNode>
@ -53,7 +54,7 @@ QskTickmarksNode::~QskTickmarksNode()
void QskTickmarksNode::update( void QskTickmarksNode::update(
const QColor& color, const QRectF& rect, const QColor& color, const QRectF& rect,
const QskIntervalF& boundaries, const QskScaleTickmarks& tickmarks, const QskIntervalF& boundaries, const QskScaleTickmarks& tickmarks,
int lineWidth, Qt::Orientation orientation, Qt::Alignment alignment ) int lineWidth, Qt::Orientation orientation, Qt::Alignment alignment, const QskTickmarksMetrics& metrics )
{ {
Q_D( QskTickmarksNode ); Q_D( QskTickmarksNode );
@ -88,7 +89,7 @@ void QskTickmarksNode::update(
if ( orientation == Qt::Horizontal ) if ( orientation == Qt::Horizontal )
{ {
const qreal ratio = rect.width() / range; const qreal ratio = rect.width() / range;
const float len = rect.height() * qskTickFactor( tickType ); const float len = rect.height() * metrics[tickType];
for( const auto tick : ticks ) for( const auto tick : ticks )
{ {
@ -121,7 +122,7 @@ void QskTickmarksNode::update(
else else
{ {
const qreal ratio = rect.height() / range; const qreal ratio = rect.height() / range;
const float len = rect.width() * qskTickFactor( tickType ); const float len = rect.width() * metrics[tickType];
for( const auto tick : ticks ) for( const auto tick : ticks )
{ {

View File

@ -17,6 +17,7 @@ class QskIntervalF;
class QskScaleTickmarks; class QskScaleTickmarks;
class QskTickmarksNodePrivate; class QskTickmarksNodePrivate;
class QskTickmarksMetrics;
class QSK_EXPORT QskTickmarksNode : public QSGGeometryNode class QSK_EXPORT QskTickmarksNode : public QSGGeometryNode
{ {
@ -26,7 +27,7 @@ class QSK_EXPORT QskTickmarksNode : public QSGGeometryNode
void update(const QColor&, const QRectF&, const QskIntervalF&, void update(const QColor&, const QRectF&, const QskIntervalF&,
const QskScaleTickmarks&, int tickLineWidth, Qt::Orientation, const QskScaleTickmarks&, int tickLineWidth, Qt::Orientation,
Qt::Alignment ); Qt::Alignment, const QskTickmarksMetrics& metrics );
private: private:
Q_DECLARE_PRIVATE( QskTickmarksNode ) Q_DECLARE_PRIVATE( QskTickmarksNode )