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 <QskSetup.h>
#include <QskSkin.h>
#include <QskSkinlet.h>
#include <QskSGNode.h>
#include <QskTickmarksMetrics.h>
#include <QskTickmarksNode.h>
#include <QskScaleTickmarks.h>
#include <QskTextLabel.h>
#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
{
public:
Window()
{
auto button = new MyToggleButton();
button->setText( false, alternativeSkin( false ) );
button->setText( true, alternativeSkin( true ) );
button->setLayoutAlignmentHint( Qt::AlignRight );
auto box = new QskLinearBox( Qt::Vertical );
box->setMargins( 20 );
box->addItem( button );
box->addSpacer( 10 );
box->addItem( new ContentBox() );
connect( button, &MyToggleButton::toggled,
this, &Window::setAlternativeSkin );
setAlternativeSkin( button->isChecked() );
addItem( box );
addItem( new QskFocusIndicator() );
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->metrics[QskScaleTickmarks::MajorTick] = 1.0;
tickmarks->metrics[QskScaleTickmarks::MediumTick] = 0.5;
tickmarks->metrics[QskScaleTickmarks::MinorTick] = 0.2;
auto* const skinlet = new TickmarksSkinlet;
tickmarks->setSkinlet(skinlet);
skinlet->setOwnedBySkinnable(true);
}
}
private:
@ -154,3 +211,5 @@ int main( int argc, char* argv[] )
return app.exec();
}
#include "main.moc"

View File

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

View File

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

View File

@ -7,6 +7,7 @@
#include "QskScaleTickmarks.h"
#include "QskSkinlet.h"
#include "QskSGNode.h"
#include "QskTickmarksMetrics.h"
#include "QskTickmarksNode.h"
#include "QskTextOptions.h"
#include "QskTextColors.h"
@ -230,7 +231,7 @@ QSGNode* QskScaleRenderer::updateTicksNode(
ticksNode->update( m_data->tickColor, rect, m_data->boundaries,
m_data->tickmarks, tickWidth, m_data->orientation,
m_data->alignment );
m_data->alignment, {});
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 "QskScaleTickmarks.h"
#include "QskTickmarksMetrics.h"
#include <QSGFlatColorMaterial>
#include <QSGGeometryNode>
@ -53,7 +54,7 @@ QskTickmarksNode::~QskTickmarksNode()
void QskTickmarksNode::update(
const QColor& color, const QRectF& rect,
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 );
@ -88,7 +89,7 @@ void QskTickmarksNode::update(
if ( orientation == Qt::Horizontal )
{
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 )
{
@ -121,7 +122,7 @@ void QskTickmarksNode::update(
else
{
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 )
{

View File

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