code moved from QskArcRenderer to QskArcMetrics
This commit is contained in:
parent
c9063fd87e
commit
64db2d0117
|
@ -95,7 +95,6 @@ list(APPEND SOURCES
|
|||
|
||||
list(APPEND HEADERS
|
||||
nodes/QskArcNode.h
|
||||
nodes/QskArcRenderer.h
|
||||
nodes/QskBoxNode.h
|
||||
nodes/QskBoxClipNode.h
|
||||
nodes/QskBoxFillNode.h
|
||||
|
@ -125,7 +124,6 @@ list(APPEND HEADERS
|
|||
|
||||
list(APPEND SOURCES
|
||||
nodes/QskArcNode.cpp
|
||||
nodes/QskArcRenderer.cpp
|
||||
nodes/QskBoxNode.cpp
|
||||
nodes/QskBoxClipNode.cpp
|
||||
nodes/QskBoxFillNode.cpp
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "QskFunctions.h"
|
||||
|
||||
#include <qhashfunctions.h>
|
||||
#include <qpainterpath.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
static void qskRegisterArcMetrics()
|
||||
|
@ -25,6 +26,11 @@ static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio )
|
|||
return from + ( to - from ) * ratio;
|
||||
}
|
||||
|
||||
static inline qreal qskEffectiveThickness( qreal radius, qreal percentage )
|
||||
{
|
||||
return qMax( radius, 0.0 ) * qBound( 0.0, percentage, 100.0 ) / 100.0;
|
||||
}
|
||||
|
||||
void QskArcMetrics::setThickness( qreal thickness ) noexcept
|
||||
{
|
||||
m_thickness = thickness;
|
||||
|
@ -107,17 +113,83 @@ QskArcMetrics QskArcMetrics::toAbsolute( qreal radius ) const noexcept
|
|||
if ( m_sizeMode != Qt::RelativeSize )
|
||||
return *this;
|
||||
|
||||
QskArcMetrics m = *this;
|
||||
const qreal t = qskEffectiveThickness( radius, m_thickness );
|
||||
return QskArcMetrics( m_startAngle, m_spanAngle, t, Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
if ( radius < 0.0 )
|
||||
radius = 0.0;
|
||||
QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const
|
||||
{
|
||||
/*
|
||||
We might want to have no connecting line between inner and
|
||||
outer border. F.e. for 360° arcs. TODO ...
|
||||
*/
|
||||
const auto sz = qMin( ellipseRect.width(), ellipseRect.height() );
|
||||
|
||||
const auto ratio = qBound( 0.0, m.m_thickness, 100.0 ) / 100.0;
|
||||
qreal t = m_thickness;
|
||||
if ( m_sizeMode == Qt::RelativeSize )
|
||||
t = qskEffectiveThickness( 0.5 * sz, t );
|
||||
|
||||
m.m_thickness = radius * ratio;
|
||||
m.m_sizeMode = Qt::AbsoluteSize;
|
||||
if ( t <= 0.0 || qFuzzyIsNull( m_spanAngle ) )
|
||||
return QPainterPath();
|
||||
|
||||
return m;
|
||||
const auto tx = t * ellipseRect.width() / sz;
|
||||
const auto ty = t * ellipseRect.height() / sz;
|
||||
|
||||
const auto innerRect = ellipseRect.adjusted( tx, ty, -tx, -ty );
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
if ( innerRect.isEmpty() )
|
||||
{
|
||||
// a pie
|
||||
|
||||
path.arcMoveTo( ellipseRect, m_startAngle );
|
||||
path.arcTo( ellipseRect, m_startAngle, m_spanAngle );
|
||||
path.lineTo( ellipseRect.center() );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We need the end point of the inner arc to add the line that connects
|
||||
the inner/outer arcs. As QPainterPath does not offer such a method
|
||||
we insert a dummy arcMoveTo and grab the calculated position.
|
||||
*/
|
||||
path.arcMoveTo( innerRect, m_startAngle + m_spanAngle );
|
||||
const auto pos = path.currentPosition();
|
||||
|
||||
path.arcMoveTo( ellipseRect, m_startAngle ); // replaces the dummy arcMoveTo above
|
||||
path.arcTo( ellipseRect, m_startAngle, m_spanAngle );
|
||||
|
||||
path.lineTo( pos );
|
||||
path.arcTo( innerRect, m_startAngle + m_spanAngle, -m_spanAngle );
|
||||
}
|
||||
|
||||
path.closeSubpath();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
QRectF QskArcMetrics::boundingRect( const QRectF& ellipseRect ) const
|
||||
{
|
||||
if ( qFuzzyIsNull( m_spanAngle ) )
|
||||
return QRectF( ellipseRect.center(), QSizeF() );
|
||||
|
||||
if ( qAbs( m_spanAngle ) >= 360.0 )
|
||||
return ellipseRect;
|
||||
|
||||
return painterPath( ellipseRect ).controlPointRect();
|
||||
}
|
||||
|
||||
QSizeF QskArcMetrics::boundingSize( const QSizeF& ellipseSize ) const
|
||||
{
|
||||
if ( qFuzzyIsNull( m_spanAngle ) )
|
||||
return QSizeF();
|
||||
|
||||
if ( qAbs( m_spanAngle ) >= 360.0 )
|
||||
return ellipseSize;
|
||||
|
||||
const QRectF r( 0.0, 0.0, ellipseSize.width(), ellipseSize.height() );
|
||||
return painterPath( r ).controlPointRect().size();
|
||||
}
|
||||
|
||||
QskHashValue QskArcMetrics::hash( QskHashValue seed ) const noexcept
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <qmetatype.h>
|
||||
|
||||
class QVariant;
|
||||
class QPainterPath;
|
||||
|
||||
class QSK_EXPORT QskArcMetrics
|
||||
{
|
||||
|
@ -60,6 +61,11 @@ class QSK_EXPORT QskArcMetrics
|
|||
QskArcMetrics toAbsolute( qreal radiusX, qreal radiusY ) const noexcept;
|
||||
QskArcMetrics toAbsolute( qreal radius ) const noexcept;
|
||||
|
||||
QPainterPath painterPath( const QRectF& ellipseRect ) const;
|
||||
|
||||
QRectF boundingRect( const QRectF& ellipseRect ) const;
|
||||
QSizeF boundingSize( const QSizeF& ellipseSize ) const;
|
||||
|
||||
QskHashValue hash( QskHashValue seed = 0 ) const noexcept;
|
||||
|
||||
static QVariant interpolate( const QskArcMetrics&,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "QskArcNode.h"
|
||||
#include "QskArcRenderer.h"
|
||||
#include "QskArcMetrics.h"
|
||||
#include "QskMargins.h"
|
||||
#include "QskGradient.h"
|
||||
|
@ -96,7 +95,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
|||
return;
|
||||
}
|
||||
|
||||
const auto path = QskArcRenderer::arcPath( arcRect, metrics );
|
||||
const auto path = metrics.painterPath( arcRect );
|
||||
|
||||
if ( gradient.isVisible() && !metrics.isNull() )
|
||||
{
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskArcRenderer.h"
|
||||
#include "QskArcMetrics.h"
|
||||
|
||||
#include <qpainterpath.h>
|
||||
#include <qrect.h>
|
||||
|
||||
static inline QPainterPath qskArcPath(
|
||||
const QRectF& rect, const QskArcMetrics& metrics )
|
||||
{
|
||||
const auto sz = qMin( rect.width(), rect.height() );
|
||||
if ( sz <= 0.0 )
|
||||
return QPainterPath();
|
||||
|
||||
const auto m = metrics.toAbsolute( 0.5 * sz );
|
||||
|
||||
const auto tx = m.thickness() * rect.width() / sz;
|
||||
const auto ty = m.thickness() * rect.height() / sz;
|
||||
|
||||
const auto innerRect = rect.adjusted( tx, ty, -tx, -ty );
|
||||
|
||||
const auto angle = m.startAngle();
|
||||
const auto span = m.spanAngle();
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
/*
|
||||
We need the end point of the inner arc to add the line that connects
|
||||
the inner/outer arcs. As QPainterPath does not offer such a method
|
||||
we insert a dummy arcMoveTo and grab the calculated position.
|
||||
*/
|
||||
path.arcMoveTo( innerRect, angle + span );
|
||||
const auto pos = path.currentPosition();
|
||||
|
||||
path.arcMoveTo( rect, angle ); // replaces the dummy arcMoveTo above
|
||||
path.arcTo( rect, angle, span );
|
||||
|
||||
path.lineTo( pos );
|
||||
path.arcTo( innerRect, angle + span, -span );
|
||||
|
||||
path.closeSubpath();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static inline QRectF qskArcRect(
|
||||
const QRectF& rect, const QskArcMetrics& metrics )
|
||||
{
|
||||
return qskArcPath( rect, metrics ).controlPointRect();
|
||||
}
|
||||
|
||||
QPainterPath QskArcRenderer::arcPath(
|
||||
qreal radius, const QskArcMetrics& metrics )
|
||||
{
|
||||
const QRectF r( 0.0, 0.0, 2 * radius, 2 * radius );
|
||||
return qskArcPath( r, metrics );
|
||||
}
|
||||
|
||||
QPainterPath QskArcRenderer::arcPath(
|
||||
const QSizeF& diameters, const QskArcMetrics& metrics )
|
||||
{
|
||||
const QRectF r( 0.0, 0.0, diameters.width(), diameters.height() );
|
||||
return qskArcPath( r, metrics );
|
||||
}
|
||||
|
||||
QPainterPath QskArcRenderer::arcPath(
|
||||
const QRectF& rect, const QskArcMetrics& metrics )
|
||||
{
|
||||
return qskArcPath( rect, metrics );
|
||||
}
|
||||
|
||||
QRectF QskArcRenderer::arcRect( qreal radius, const QskArcMetrics& metrics )
|
||||
{
|
||||
const qreal d = 2.0 * radius;
|
||||
return qskArcRect( QRectF( 0.0, 0.0, d, d ), metrics );
|
||||
}
|
||||
|
||||
QRectF QskArcRenderer::arcRect( const QSizeF& diameters, const QskArcMetrics& metrics )
|
||||
{
|
||||
const QRectF r( 0.0, 0.0, diameters.width(), diameters.height() );
|
||||
return qskArcRect( r, metrics );
|
||||
}
|
||||
|
||||
QRectF QskArcRenderer::arcRect( const QRectF& rect, const QskArcMetrics& metrics )
|
||||
{
|
||||
return qskArcRect( rect, metrics );
|
||||
}
|
||||
|
||||
QSizeF QskArcRenderer::arcSize(
|
||||
const QSizeF& diameters, const QskArcMetrics& metrics )
|
||||
{
|
||||
if ( qFuzzyIsNull( metrics.spanAngle() ) )
|
||||
return QSizeF();
|
||||
|
||||
if ( qAbs( metrics.spanAngle() ) >= 360.0 )
|
||||
return diameters;
|
||||
|
||||
const QRectF r( 0.0, 0.0, diameters.width(), diameters.height() );
|
||||
return qskArcRect( r, metrics ).size();
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_ARC_RENDERER_H
|
||||
#define QSK_ARC_RENDERER_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
|
||||
class QskArcMetrics;
|
||||
|
||||
class QPainterPath;
|
||||
class QRectF;
|
||||
class QSizeF;
|
||||
|
||||
namespace QskArcRenderer
|
||||
{
|
||||
// radius
|
||||
QSK_EXPORT QPainterPath arcPath( qreal radius, const QskArcMetrics& );
|
||||
QSK_EXPORT QRectF arcRect( qreal radius, const QskArcMetrics& );
|
||||
|
||||
// diameter
|
||||
QSK_EXPORT QPainterPath arcPath( const QSizeF&, const QskArcMetrics& );
|
||||
QSK_EXPORT QSizeF arcSize( const QSizeF&, const QskArcMetrics& );
|
||||
QSK_EXPORT QRectF arcRect( const QSizeF&, const QskArcMetrics& );
|
||||
|
||||
// bounding rectangle
|
||||
QSK_EXPORT QPainterPath arcPath( const QRectF&, const QskArcMetrics& );
|
||||
QSK_EXPORT QRectF arcRect( const QRectF&, const QskArcMetrics& );
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue