Merge branch 'master' into qskspinbox

This commit is contained in:
uwerat 2023-02-17 13:22:39 +01:00 committed by GitHub
commit 6071ce74d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 350 additions and 337 deletions

View File

@ -163,38 +163,38 @@
*/ */
/*! /*!
\enum QskAspect::Placement \enum QskAspect::Variation
\brief Represents an orientation or relative position \brief Some sort of variation
The placement bits can be used to have different definitions for The variation bits can be used to have different definitions for
a skinnable depending on its position or orientation. F.e a tab bar a skinnable depending on its position, orientation or emphasis. F.e a tab bar
looks slightly different depending on its position. looks slightly different depending on its position.
\note flags indicating an orientation can't be used together \note flags indicating an orientation can't be used together
with the flags for the position with the flags for the position
\sa QskSkinnable::effectivePlacement() \sa QskSkinnable::effectiveVariation()
\var QskAspect::Placement QskAspect::NoPlacement \var QskAspect::Variation QskAspect::NoVariation
No specific placement bits No specific variation bits
\var QskAspect::Placement QskAspect::Vertical \var QskAspect::Variation QskAspect::Vertical
Indicates a vertical orientation Indicates a vertical orientation
\var QskAspect::Placement QskAspect::Horizontal \var QskAspect::Variation QskAspect::Horizontal
Indicates a horizontal orientation Indicates a horizontal orientation
\var QskAspect::Placement QskAspect::Top \var QskAspect::Variation QskAspect::Top
Indicates a top position Indicates a top position
\var QskAspect::Placement QskAspect::Left \var QskAspect::Variation QskAspect::Left
Indicates a left position Indicates a left position
\var QskAspect::Placement QskAspect::Right \var QskAspect::Variation QskAspect::Right
Indicates a right position Indicates a right position
\var QskAspect::Placement QskAspect::Bottom \var QskAspect::Variation QskAspect::Bottom
Indicates a bottom position Indicates a bottom position
*/ */
@ -288,10 +288,10 @@
*/ */
/*! /*!
\fn QskAspect::QskAspect( Placement ) \fn QskAspect::QskAspect( Variation )
Constructs an aspect with the placement bits being initialized Constructs an aspect with the variation bits being initialized
\param placement Initial placement \param variation Initial variation
*/ */
/*! /*!
@ -351,9 +351,9 @@
*/ */
/*! /*!
\fn QskAspect::operator|( Placement ) const \fn QskAspect::operator|( Variation ) const
Sets the placement bits Sets the variation bits
*/ */
/*! /*!
@ -378,7 +378,7 @@
/*! /*!
\fn QskAspect::trunk \fn QskAspect::trunk
\return A copy of the aspect without the runtime bits ( state, placement ) bits \return A copy of the aspect without the runtime bits ( state, variation ) bits
*/ */
/*! /*!
@ -443,17 +443,17 @@
*/ */
/*! /*!
\fn QskAspect::placement \fn QskAspect::variation
\return Placement bits \return Variation bits
\sa setPlacement() \sa setVariation()
*/ */
/*! /*!
\fn QskAspect::setPlacement \fn QskAspect::setVariation
Sets the placement bits Sets the variation bits
\sa placement() \sa variation()
*/ */
/*! /*!

View File

@ -182,14 +182,14 @@
\sa setSkinHint(), effectiveSkinHint() \sa setSkinHint(), effectiveSkinHint()
*/ */
/*! \fn QskSkinnable::effectivePlacement /*! \fn QskSkinnable::effectiveVariation
The placements bits are added to an unresolved aspect when The variation bits are added to an unresolved aspect when
inserting or looking up values in the hint table. inserting or looking up values in the hint table.
\return The default implementation returns QskAspect::NoPlacement; \return The default implementation returns QskAspect::NoVariation;
\sa QskAspect::Placement, effectiveSkinHint() \sa QskAspect::Variation, effectiveSkinHint()
*/ */
/*! \fn QskSkinnable::hintStatus /*! \fn QskSkinnable::hintStatus

View File

@ -72,7 +72,7 @@ static void addTestRectangle( QskLinearBox* parent )
box->setBorderWidth( 10, 20, 40, 20 ); box->setBorderWidth( 10, 20, 40, 20 );
QskBoxShapeMetrics shape( 50, Qt::RelativeSize ); QskBoxShapeMetrics shape( 50, Qt::RelativeSize );
shape.setScalingMode( QskBoxShapeMetrics::Elliptic ); shape.setScalingMode( QskBoxShapeMetrics::Proportional );
shape.setRadius( Qt::BottomRightCorner, 30 ); shape.setRadius( Qt::BottomRightCorner, 30 );
shape.setRadius( Qt::TopRightCorner, 70 ); shape.setRadius( Qt::TopRightCorner, 70 );

View File

@ -19,7 +19,6 @@ Qsk.PushButton
shape shape
{ {
sizeMode: Qt.RelativeSize sizeMode: Qt.RelativeSize
aspectRatioMode: Qt.KeepAspectRatio
radius: 10 radius: 10
} }

View File

@ -129,7 +129,7 @@ Qsk.Window
shape shape
{ {
sizeMode: Qt.RelativeSize sizeMode: Qt.RelativeSize
aspectRatioMode: Qt.IgnoreAspectRatio scalingMode: Qsk.BoxShapeMetrics.SymmetricByMaximum
radius: 100 radius: 100
} }
} }

View File

@ -28,10 +28,10 @@ namespace
setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed ); setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
setSpacing( 0 ); setSpacing( 0 );
auto* const topButton = new RoundButton( QskAspect::Top, this ); auto* const topButton = new RoundButton( Qt::TopEdge, this );
connect( topButton, &QskPushButton::clicked, this, &UpAndDownBox::increase ); connect( topButton, &QskPushButton::clicked, this, &UpAndDownBox::increase );
auto* const bottomButton = new RoundButton( QskAspect::Bottom, this ); auto* const bottomButton = new RoundButton( Qt::BottomEdge, this );
connect( bottomButton, &QskPushButton::clicked, this, &UpAndDownBox::decrease ); connect( bottomButton, &QskPushButton::clicked, this, &UpAndDownBox::decrease );
} }

View File

@ -4,23 +4,19 @@
*****************************************************************************/ *****************************************************************************/
#include "RoundButton.h" #include "RoundButton.h"
#include <QskGraphic.h> #include <QskGraphic.h>
#include <QskPushButton.h>
#include <QImage>
QSK_SUBCONTROL( RoundButton, Panel ) QSK_SUBCONTROL( RoundButton, Panel )
QSK_STATE( RoundButton, Top, ( QskAspect::FirstUserState << 1 ) ) QSK_STATE( RoundButton, Top, ( QskAspect::FirstUserState << 1 ) )
RoundButton::RoundButton( QskAspect::Placement placement, QQuickItem* parent ) RoundButton::RoundButton( Qt::Edge edge, QQuickItem* parent )
: QskPushButton( parent ) : QskPushButton( parent )
{ {
setSubcontrolProxy( QskPushButton::Panel, RoundButton::Panel ); setSubcontrolProxy( QskPushButton::Panel, RoundButton::Panel );
setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Expanding ); setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Expanding );
if( placement == QskAspect::Top ) if( edge == Qt::TopEdge )
{ {
setSkinStateFlag( Top ); setSkinStateFlag( Top );
setGraphicSource( "up" ); setGraphicSource( "up" );

View File

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <QskPushButton.h> #include <QskPushButton.h>
#include <Qt>
class RoundButton : public QskPushButton class RoundButton : public QskPushButton
{ {
@ -15,5 +16,5 @@ class RoundButton : public QskPushButton
QSK_SUBCONTROLS( Panel ) QSK_SUBCONTROLS( Panel )
QSK_STATES( Top ) QSK_STATES( Top )
RoundButton( QskAspect::Placement, QQuickItem* parent ); RoundButton( Qt::Edge, QQuickItem* parent );
}; };

View File

@ -30,9 +30,9 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
// Panel // Panel
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Panel | placement; const auto aspect = Panel | variation;
ed.setMetric( aspect | A::Size, h ); ed.setMetric( aspect | A::Size, h );
ed.setBoxShape( aspect, 4 ); ed.setBoxShape( aspect, 4 );
@ -40,7 +40,7 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
ed.setBoxBorderColors( aspect, DimGray ); ed.setBoxBorderColors( aspect, DimGray );
ed.setGradient( aspect, Silver ); ed.setGradient( aspect, Silver );
if ( placement == A::Horizontal ) if ( variation == A::Horizontal )
ed.setPadding( aspect, QskMargins( paddingW, 0 ) ); ed.setPadding( aspect, QskMargins( paddingW, 0 ) );
else else
ed.setPadding( aspect, QskMargins( 0, paddingW ) ); ed.setPadding( aspect, QskMargins( 0, paddingW ) );
@ -48,9 +48,9 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
// Groove // Groove
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Groove | placement; const auto aspect = Groove | variation;
ed.setMetric( aspect | A::Size, 4 ); ed.setMetric( aspect | A::Size, 4 );
ed.setBoxBorderMetrics( aspect, 0 ); ed.setBoxBorderMetrics( aspect, 0 );
@ -60,24 +60,24 @@ OtherSlider::OtherSlider( QQuickItem* parentItem )
} }
// no Fill // no Fill
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Fill | placement; const auto aspect = Fill | variation;
ed.setMetric( aspect | A::Size, 0 ); ed.setMetric( aspect | A::Size, 0 );
} }
// Handle // Handle
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Handle | placement; const auto aspect = Handle | variation;
ed.setBoxBorderMetrics( aspect, 1 ); ed.setBoxBorderMetrics( aspect, 1 );
ed.setBoxShape( aspect, 4 ); ed.setBoxShape( aspect, 4 );
const qreal m = 0.5 * std::ceil( 0.5 * ( w - h ) ) + 1; const qreal m = 0.5 * std::ceil( 0.5 * ( w - h ) ) + 1;
if ( placement == A::Horizontal ) if ( variation == A::Horizontal )
ed.setMargin( aspect, QskMargins( -m, 0 ) ); ed.setMargin( aspect, QskMargins( -m, 0 ) );
else else
ed.setMargin( aspect, QskMargins( 0, -m ) ); ed.setMargin( aspect, QskMargins( 0, -m ) );

View File

@ -23,6 +23,23 @@
namespace namespace
{ {
class InputValidator : public QDoubleValidator
{
public:
InputValidator( QObject* parent = nullptr )
: QDoubleValidator( parent )
{
setRange( -9.99, 9.99 );
setDecimals( 2 );
setNotation( QDoubleValidator::StandardNotation );
auto locale = this->locale();
locale.setNumberOptions( QLocale::RejectGroupSeparator );
setLocale( locale );
}
};
class NumberInput : public QskLinearBox class NumberInput : public QskLinearBox
{ {
Q_OBJECT Q_OBJECT
@ -34,7 +51,7 @@ namespace
new QskTextLabel( label, this ); new QskTextLabel( label, this );
m_input = new QskTextInput( this ); m_input = new QskTextInput( this );
m_input->setValidator( new QDoubleValidator( -9.99, 9.99, 2, m_input ) ); m_input->setValidator( new InputValidator( m_input ) );
m_input->setText( QString::number( value ) ); m_input->setText( QString::number( value ) );
const QFontMetricsF fm( m_input->font() ); const QFontMetricsF fm( m_input->font() );

View File

@ -528,9 +528,9 @@ void Editor::setupSeparator()
using A = QskAspect; using A = QskAspect;
using Q = QskSeparator; using Q = QskSeparator;
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Q::Panel | placement; const auto aspect = Q::Panel | variation;
setMetric( aspect | A::Size, 4_dp ); setMetric( aspect | A::Size, 4_dp );
setBoxShape( Q::Panel, 0 ); setBoxShape( Q::Panel, 0 );
@ -815,13 +815,13 @@ void Editor::setupTabButton()
setColor( Q::Text | Q::Checked, m_pal.primary ); setColor( Q::Text | Q::Checked, m_pal.primary );
setColor( Q::Text | Q::Hovered, m_pal.primary ); setColor( Q::Text | Q::Hovered, m_pal.primary );
for ( const auto placement : { A::Left, A::Right, A::Top, A::Bottom } ) for ( const auto variation : { A::Left, A::Right, A::Top, A::Bottom } )
{ {
const auto aspect = Q::Panel | placement; const auto aspect = Q::Panel | variation;
Qt::Edge edge; Qt::Edge edge;
switch( placement ) switch( variation )
{ {
case A::Left: case A::Left:
edge = Qt::RightEdge; edge = Qt::RightEdge;

View File

@ -598,8 +598,7 @@ void Editor::setupPushButton()
setFlagHint( Q::Text | Q::Disabled | A::Style, Qsk::Sunken ); setFlagHint( Q::Text | Q::Disabled | A::Style, Qsk::Sunken );
setAlignment( Q::Text | A::Vertical, Qt::AlignCenter ); setAlignment( Q::Text, Qt::AlignCenter );
setAlignment( Q::Text | A::Horizontal, Qt::AlignLeft | Qt::AlignVCenter );
setColor( Q::Text, m_pal.themeForeground ); setColor( Q::Text, m_pal.themeForeground );
setColor( Q::Text | Q::Disabled, m_pal.darker200 ); setColor( Q::Text | Q::Disabled, m_pal.darker200 );
@ -625,33 +624,33 @@ void Editor::setupTabButton()
setStrutSize( Q::Panel, 30, 16 ); setStrutSize( Q::Panel, 30, 16 );
for ( auto placement : { A::Top, A::Bottom } ) for ( auto variation : { A::Top, A::Bottom } )
{ {
setVGradient( Q::Panel | placement, m_pal.lighter125, m_pal.lighter110 ); setVGradient( Q::Panel | variation, m_pal.lighter125, m_pal.lighter110 );
for ( const auto state : { Q::Checked | A::NoState, Q::Checked | Q::Pressed } ) for ( const auto state : { Q::Checked | A::NoState, Q::Checked | Q::Pressed } )
{ {
setGradient( Q::Panel | placement | state, m_pal.lighter125 ); setGradient( Q::Panel | variation | state, m_pal.lighter125 );
setColor( Q::Text | placement | state, m_pal.themeForeground ); setColor( Q::Text | variation | state, m_pal.themeForeground );
} }
} }
for ( auto placement : { A::Left, A::Right } ) for ( auto variation : { A::Left, A::Right } )
{ {
setGradient( Q::Panel | placement, m_pal.lighter125 ); setGradient( Q::Panel | variation, m_pal.lighter125 );
for ( const auto state : { Q::Checked | A::NoState, Q::Checked | Q::Pressed } ) for ( const auto state : { Q::Checked | A::NoState, Q::Checked | Q::Pressed } )
{ {
setGradient( Q::Panel | placement | state, m_pal.highlighted ); setGradient( Q::Panel | variation | state, m_pal.highlighted );
setColor( Q::Text | placement | state, m_pal.highlightedText ); setColor( Q::Text | variation | state, m_pal.highlightedText );
} }
} }
setBoxBorderColors( Q::Panel, m_pal.darker200 ); setBoxBorderColors( Q::Panel, m_pal.darker200 );
for ( auto placement : { A::Left, A::Right, A::Top, A::Bottom } ) for ( auto variation : { A::Left, A::Right, A::Top, A::Bottom } )
{ {
const auto aspect = Q::Panel | placement; const auto aspect = Q::Panel | variation;
QskMargins margins0, margins1, padding; QskMargins margins0, margins1, padding;
QskBoxBorderMetrics border( 1 ); QskBoxBorderMetrics border( 1 );
@ -659,7 +658,7 @@ void Editor::setupTabButton()
const int indent = 4; const int indent = 4;
if ( placement == A::Top ) if ( variation == A::Top )
{ {
margins0 = QskMargins( -1, indent, -1, -1 ); margins0 = QskMargins( -1, indent, -1, -1 );
margins1 = QskMargins( -1, 0, -1, -2 ); margins1 = QskMargins( -1, 0, -1, -2 );
@ -669,7 +668,7 @@ void Editor::setupTabButton()
shape.setRadius( Qt::BottomLeftCorner, 0 ); shape.setRadius( Qt::BottomLeftCorner, 0 );
shape.setRadius( Qt::BottomRightCorner, 0 ); shape.setRadius( Qt::BottomRightCorner, 0 );
} }
else if ( placement == A::Bottom ) else if ( variation == A::Bottom )
{ {
margins0 = QskMargins( -1, -1, -1, indent ); margins0 = QskMargins( -1, -1, -1, indent );
margins1 = QskMargins( -1, -2, -1, 0 ); margins1 = QskMargins( -1, -2, -1, 0 );
@ -679,7 +678,7 @@ void Editor::setupTabButton()
shape.setRadius( Qt::TopLeftCorner, 0 ); shape.setRadius( Qt::TopLeftCorner, 0 );
shape.setRadius( Qt::TopRightCorner, 0 ); shape.setRadius( Qt::TopRightCorner, 0 );
} }
else if ( placement == A::Left ) else if ( variation == A::Left )
{ {
margins0 = QskMargins( indent, -1, -1, -1 ); margins0 = QskMargins( indent, -1, -1, -1 );
margins1 = QskMargins( 0, -1, -2, 0 ); margins1 = QskMargins( 0, -1, -2, 0 );
@ -689,7 +688,7 @@ void Editor::setupTabButton()
shape.setRadius( Qt::TopRightCorner, 0 ); shape.setRadius( Qt::TopRightCorner, 0 );
shape.setRadius( Qt::BottomRightCorner, 0 ); shape.setRadius( Qt::BottomRightCorner, 0 );
} }
else if ( placement == A::Right ) else if ( variation == A::Right )
{ {
margins0 = QskMargins( -1, -1, indent, -1 ); margins0 = QskMargins( -1, -1, indent, -1 );
margins1 = QskMargins( -2, -1, 0, 0 ); margins1 = QskMargins( -2, -1, 0, 0 );
@ -732,9 +731,9 @@ void Editor::setupSlider()
// Panel // Panel
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Q::Panel | placement; const auto aspect = Q::Panel | variation;
setMetric( aspect | A::Size, extent ); setMetric( aspect | A::Size, extent );
setBoxBorderMetrics( aspect, 0 ); setBoxBorderMetrics( aspect, 0 );
@ -747,11 +746,11 @@ void Editor::setupSlider()
// Groove, Fill // Groove, Fill
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
for ( auto subControl : { Q::Groove, Q::Fill } ) for ( auto subControl : { Q::Groove, Q::Fill } )
{ {
const auto aspect = subControl | placement; const auto aspect = subControl | variation;
setMetric( aspect | A::Size, 0.3 * extent ); setMetric( aspect | A::Size, 0.3 * extent );
setPadding( aspect, 0 ); setPadding( aspect, 0 );
@ -760,15 +759,15 @@ void Editor::setupSlider()
setBoxShape( aspect, 0.1 * extent ); setBoxShape( aspect, 0.1 * extent );
} }
setGradient( Q::Groove | placement, m_pal.darker200 ); setGradient( Q::Groove | variation, m_pal.darker200 );
setGradient( Q::Fill | placement, QskGradient() ); // no filling setGradient( Q::Fill | variation, QskGradient() ); // no filling
} }
// Handle // Handle
for ( auto placement : { A::Horizontal, A::Vertical } ) for ( auto variation : { A::Horizontal, A::Vertical } )
{ {
const auto aspect = Q::Handle | placement; const auto aspect = Q::Handle | variation;
setButton( aspect, Raised, 1 ); setButton( aspect, Raised, 1 );
setBoxShape( aspect, 20.0, Qt::RelativeSize ); setBoxShape( aspect, 20.0, Qt::RelativeSize );

View File

@ -260,9 +260,9 @@ QDebug operator<<( QDebug debug, QskAspect::Subcontrol subControl )
return debug; return debug;
} }
QDebug operator<<( QDebug debug, QskAspect::Placement placement ) QDebug operator<<( QDebug debug, QskAspect::Variation variation )
{ {
qskDebugEnum( debug, "Placement", placement ); qskDebugEnum( debug, "Variation", variation );
return debug; return debug;
} }
@ -334,8 +334,8 @@ void qskDebugAspect( QDebug debug, const QMetaObject* metaObject, QskAspect aspe
} }
} }
if ( aspect.placement() != QskAspect::NoPlacement ) if ( aspect.variation() != QskAspect::NoVariation )
debug << ", " << qskEnumString( "Placement", aspect.placement() ); debug << ", " << qskEnumString( "Variation", aspect.variation() );
if ( aspect.hasStates() ) if ( aspect.hasStates() )
debug << ", " << qskStatesToString( metaObject, aspect.states() ); debug << ", " << qskStatesToString( metaObject, aspect.states() );

View File

@ -32,11 +32,13 @@ class QSK_EXPORT QskAspect
Body = 0, Body = 0,
Header, Header,
Footer Footer,
Floating
}; };
Q_ENUM( Section ) Q_ENUM( Section )
static constexpr uint FirstUserSection = Section::Footer + 1; static constexpr uint FirstUserSection = Section::Floating + 1;
static constexpr uint LastSection = ( 1 << 4 ) - 1; static constexpr uint LastSection = ( 1 << 4 ) - 1;
enum Primitive : quint8 enum Primitive : quint8
@ -69,9 +71,9 @@ class QSK_EXPORT QskAspect
}; };
Q_ENUM( Primitive ) Q_ENUM( Primitive )
enum Placement : quint8 enum Variation : quint8
{ {
NoPlacement = 0, NoVariation = 0,
Vertical = Qt::Vertical, Vertical = Qt::Vertical,
Horizontal = Qt::Horizontal, Horizontal = Qt::Horizontal,
@ -79,9 +81,14 @@ class QSK_EXPORT QskAspect
Top = 1, Top = 1,
Left = 2, Left = 2,
Right = 3, Right = 3,
Bottom = 4 Bottom = 4,
Tiny = 1,
Small = 2,
Large = 3,
Huge = 4
}; };
Q_ENUM( Placement ) Q_ENUM( Variation )
enum Subcontrol : quint16 enum Subcontrol : quint16
{ {
@ -111,7 +118,7 @@ class QSK_EXPORT QskAspect
constexpr QskAspect( Subcontrol ) noexcept; constexpr QskAspect( Subcontrol ) noexcept;
constexpr QskAspect( Section ) noexcept; constexpr QskAspect( Section ) noexcept;
constexpr QskAspect( Type ) noexcept; constexpr QskAspect( Type ) noexcept;
constexpr QskAspect( Placement ) noexcept; constexpr QskAspect( Variation ) noexcept;
constexpr QskAspect( const QskAspect& ) noexcept = default; constexpr QskAspect( const QskAspect& ) noexcept = default;
constexpr QskAspect( QskAspect&& ) noexcept = default; constexpr QskAspect( QskAspect&& ) noexcept = default;
@ -127,7 +134,7 @@ class QSK_EXPORT QskAspect
constexpr QskAspect operator|( Section ) const noexcept; constexpr QskAspect operator|( Section ) const noexcept;
constexpr QskAspect operator|( Type ) const noexcept; constexpr QskAspect operator|( Type ) const noexcept;
constexpr QskAspect operator|( Primitive ) const noexcept; constexpr QskAspect operator|( Primitive ) const noexcept;
constexpr QskAspect operator|( Placement ) const noexcept; constexpr QskAspect operator|( Variation ) const noexcept;
constexpr QskAspect operator|( State ) const noexcept; constexpr QskAspect operator|( State ) const noexcept;
QskAspect& operator|=( State ) noexcept; QskAspect& operator|=( State ) noexcept;
@ -164,8 +171,8 @@ class QSK_EXPORT QskAspect
constexpr bool isColor() const noexcept; constexpr bool isColor() const noexcept;
constexpr bool isFlag() const noexcept; constexpr bool isFlag() const noexcept;
constexpr Placement placement() const noexcept; constexpr Variation variation() const noexcept;
void setPlacement( Placement ) noexcept; void setVariation( Variation ) noexcept;
constexpr States states() const noexcept; constexpr States states() const noexcept;
constexpr bool hasStates() const noexcept; constexpr bool hasStates() const noexcept;
@ -198,10 +205,10 @@ class QSK_EXPORT QskAspect
static void reservePrimitives( quint8 count ); static void reservePrimitives( quint8 count );
private: private:
constexpr QskAspect( Subcontrol, Section, Type, Placement ) noexcept; constexpr QskAspect( Subcontrol, Section, Type, Variation ) noexcept;
constexpr QskAspect( uint subControl, uint section, uint type, bool isAnimator, constexpr QskAspect( uint subControl, uint section, uint type, bool isAnimator,
uint primitive, uint placement, uint states ) noexcept; uint primitive, uint variation, uint states ) noexcept;
struct Bits struct Bits
{ {
@ -212,7 +219,7 @@ class QSK_EXPORT QskAspect
uint isAnimator : 1; uint isAnimator : 1;
uint primitive : 5; uint primitive : 5;
uint placement : 3; uint variation : 3;
uint reserved1 : 4; uint reserved1 : 4;
uint states : 16; uint states : 16;
@ -243,39 +250,39 @@ constexpr inline QskAspect::State operator>>( QskAspect::State a, const int b )
} }
inline constexpr QskAspect::QskAspect() noexcept inline constexpr QskAspect::QskAspect() noexcept
: QskAspect( NoSubcontrol, Body, Flag, NoPlacement ) : QskAspect( NoSubcontrol, Body, Flag, NoVariation )
{ {
} }
inline constexpr QskAspect::QskAspect( Subcontrol subControl ) noexcept inline constexpr QskAspect::QskAspect( Subcontrol subControl ) noexcept
: QskAspect( subControl, Body, Flag, NoPlacement ) : QskAspect( subControl, Body, Flag, NoVariation )
{ {
} }
inline constexpr QskAspect::QskAspect( Section section ) noexcept inline constexpr QskAspect::QskAspect( Section section ) noexcept
: QskAspect( NoSubcontrol, section, Flag, NoPlacement ) : QskAspect( NoSubcontrol, section, Flag, NoVariation )
{ {
} }
inline constexpr QskAspect::QskAspect( Type type ) noexcept inline constexpr QskAspect::QskAspect( Type type ) noexcept
: QskAspect( NoSubcontrol, Body, type, NoPlacement ) : QskAspect( NoSubcontrol, Body, type, NoVariation )
{ {
} }
inline constexpr QskAspect::QskAspect( Placement placement ) noexcept inline constexpr QskAspect::QskAspect( Variation variation ) noexcept
: QskAspect( NoSubcontrol, Body, Flag, placement ) : QskAspect( NoSubcontrol, Body, Flag, variation )
{ {
} }
inline constexpr QskAspect::QskAspect( inline constexpr QskAspect::QskAspect(
Subcontrol subControl, Section section, Type type, Placement placement ) noexcept Subcontrol subControl, Section section, Type type, Variation variation ) noexcept
: QskAspect( subControl, section, type, false, 0, placement, NoState ) : QskAspect( subControl, section, type, false, 0, variation, NoState )
{ {
} }
inline constexpr QskAspect::QskAspect( uint subControl, uint section, uint type, bool isAnimator, inline constexpr QskAspect::QskAspect( uint subControl, uint section, uint type,
uint primitive, uint placement, uint states ) noexcept bool isAnimator, uint primitive, uint variation, uint states ) noexcept
: m_bits { subControl, section, type, isAnimator, primitive, placement, 0, states, 0 } : m_bits { subControl, section, type, isAnimator, primitive, variation, 0, states, 0 }
{ {
} }
@ -297,37 +304,37 @@ inline bool QskAspect::operator<( const QskAspect& other ) const noexcept
inline constexpr QskAspect QskAspect::operator|( Subcontrol subControl ) const noexcept inline constexpr QskAspect QskAspect::operator|( Subcontrol subControl ) const noexcept
{ {
return QskAspect( subControl, m_bits.section, m_bits.type, return QskAspect( subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, m_bits.states ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, m_bits.states );
} }
inline constexpr QskAspect QskAspect::operator|( Section section ) const noexcept inline constexpr QskAspect QskAspect::operator|( Section section ) const noexcept
{ {
return QskAspect( m_bits.subControl, section, m_bits.type, return QskAspect( m_bits.subControl, section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, m_bits.states ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, m_bits.states );
} }
inline constexpr QskAspect QskAspect::operator|( Type type ) const noexcept inline constexpr QskAspect QskAspect::operator|( Type type ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, type, return QskAspect( m_bits.subControl, m_bits.section, type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, m_bits.states ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, m_bits.states );
} }
inline constexpr QskAspect QskAspect::operator|( Primitive primitive ) const noexcept inline constexpr QskAspect QskAspect::operator|( Primitive primitive ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, primitive, m_bits.placement, m_bits.states ); m_bits.isAnimator, primitive, m_bits.variation, m_bits.states );
} }
inline constexpr QskAspect QskAspect::operator|( Placement placement ) const noexcept inline constexpr QskAspect QskAspect::operator|( Variation variation ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, placement, m_bits.states ); m_bits.isAnimator, m_bits.primitive, variation, m_bits.states );
} }
inline constexpr QskAspect QskAspect::operator|( State state ) const noexcept inline constexpr QskAspect QskAspect::operator|( State state ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, m_bits.states | state ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, m_bits.states | state );
} }
inline QskAspect& QskAspect::operator|=( State state ) noexcept inline QskAspect& QskAspect::operator|=( State state ) noexcept
@ -339,7 +346,7 @@ inline QskAspect& QskAspect::operator|=( State state ) noexcept
inline constexpr QskAspect QskAspect::operator&( State state ) const noexcept inline constexpr QskAspect QskAspect::operator&( State state ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, m_bits.isAnimator, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, m_bits.isAnimator,
m_bits.primitive, m_bits.placement, m_bits.states & state ); m_bits.primitive, m_bits.variation, m_bits.states & state );
} }
inline QskAspect& QskAspect::operator&=( State state ) noexcept inline QskAspect& QskAspect::operator&=( State state ) noexcept
@ -351,7 +358,7 @@ inline QskAspect& QskAspect::operator&=( State state ) noexcept
inline constexpr QskAspect QskAspect::operator|( States states ) const noexcept inline constexpr QskAspect QskAspect::operator|( States states ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, m_bits.isAnimator, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, m_bits.isAnimator,
m_bits.primitive, m_bits.placement, m_bits.states | states ); m_bits.primitive, m_bits.variation, m_bits.states | states );
} }
inline QskAspect& QskAspect::operator|=( States states ) noexcept inline QskAspect& QskAspect::operator|=( States states ) noexcept
@ -363,7 +370,7 @@ inline QskAspect& QskAspect::operator|=( States states ) noexcept
inline constexpr QskAspect QskAspect::operator&( States states ) const noexcept inline constexpr QskAspect QskAspect::operator&( States states ) const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, m_bits.states & states ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, m_bits.states & states );
} }
inline QskAspect& QskAspect::operator&=( States states ) noexcept inline QskAspect& QskAspect::operator&=( States states ) noexcept
@ -375,12 +382,12 @@ inline QskAspect& QskAspect::operator&=( States states ) noexcept
inline constexpr QskAspect QskAspect::stateless() const noexcept inline constexpr QskAspect QskAspect::stateless() const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, m_bits.section, m_bits.type,
m_bits.isAnimator, m_bits.primitive, m_bits.placement, 0 ); m_bits.isAnimator, m_bits.primitive, m_bits.variation, 0 );
} }
inline constexpr QskAspect QskAspect::trunk() const noexcept inline constexpr QskAspect QskAspect::trunk() const noexcept
{ {
return QskAspect( m_bits.subControl, m_bits.section, m_bits.type, return QskAspect( m_bits.subControl, 0, m_bits.type,
m_bits.isAnimator, m_bits.primitive, 0, 0 ); m_bits.isAnimator, m_bits.primitive, 0, 0 );
} }
@ -518,14 +525,14 @@ inline void QskAspect::clearPrimitive() noexcept
m_bits.primitive = NoPrimitive; m_bits.primitive = NoPrimitive;
} }
inline constexpr QskAspect::Placement QskAspect::placement() const noexcept inline constexpr QskAspect::Variation QskAspect::variation() const noexcept
{ {
return static_cast< Placement >( m_bits.placement ); return static_cast< Variation >( m_bits.variation );
} }
inline void QskAspect::setPlacement( Placement placement ) noexcept inline void QskAspect::setVariation( Variation variation ) noexcept
{ {
m_bits.placement = placement; m_bits.variation = variation;
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
@ -559,9 +566,9 @@ inline constexpr QskAspect operator|(
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
QskAspect::Placement placement, const QskAspect& aspect ) noexcept QskAspect::Variation variation, const QskAspect& aspect ) noexcept
{ {
return aspect | placement; return aspect | variation;
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
@ -601,15 +608,15 @@ inline constexpr QskAspect operator|(
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
QskAspect::Type type, QskAspect::Placement placement ) noexcept QskAspect::Type type, QskAspect::Variation variation ) noexcept
{ {
return QskAspect( type ) | placement; return QskAspect( type ) | variation;
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
QskAspect::Placement placement, QskAspect::Type type ) noexcept QskAspect::Variation variation, QskAspect::Type type ) noexcept
{ {
return type | placement; return type | variation;
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
@ -637,15 +644,15 @@ inline constexpr QskAspect operator|(
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
QskAspect::Subcontrol subControl, QskAspect::Placement placement ) noexcept QskAspect::Subcontrol subControl, QskAspect::Variation variation ) noexcept
{ {
return QskAspect( subControl ) | placement; return QskAspect( subControl ) | variation;
} }
inline constexpr QskAspect operator|( inline constexpr QskAspect operator|(
QskAspect::Placement placement, QskAspect::Subcontrol subControl ) noexcept QskAspect::Variation variation, QskAspect::Subcontrol subControl ) noexcept
{ {
return subControl | placement; return subControl | variation;
} }
namespace std namespace std
@ -672,7 +679,7 @@ QSK_EXPORT QDebug operator<<( QDebug, QskAspect );
QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Type ); QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Type );
QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Subcontrol ); QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Subcontrol );
QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Primitive ); QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Primitive );
QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Placement ); QSK_EXPORT QDebug operator<<( QDebug, QskAspect::Variation );
QSK_EXPORT QDebug operator<<( QDebug, QskAspect::States ); QSK_EXPORT QDebug operator<<( QDebug, QskAspect::States );
QSK_EXPORT void qskDebugStates( QDebug, const QMetaObject*, QskAspect::States ); QSK_EXPORT void qskDebugStates( QDebug, const QMetaObject*, QskAspect::States );

View File

@ -108,23 +108,32 @@ QskBoxShapeMetrics QskBoxShapeMetrics::toAbsolute( const QSizeF& size ) const no
const qreal rx = qskAbsoluted( size.width(), radius.width() ); const qreal rx = qskAbsoluted( size.width(), radius.width() );
const qreal ry = qskAbsoluted( size.height(), radius.height() ); const qreal ry = qskAbsoluted( size.height(), radius.height() );
if ( m_scalingMode == Circular ) switch ( m_scalingMode )
{ {
radius.rheight() = radius.rwidth() = std::min( rx, ry ); case Symmetric:
}
else
{
const auto ratio = radius.height() / radius.width();
if ( ratio >= 1.0 )
{ {
radius.rwidth() = ry / ratio; radius.rheight() = radius.rwidth() = std::min( rx, ry );
radius.rheight() = ry; break;
} }
else case SymmetricByMaximum:
{ {
radius.rwidth() = rx; radius.rheight() = radius.rwidth() = std::max( rx, ry );
radius.rheight() = rx * ratio; break;
}
default:
{
const auto ratio = radius.height() / radius.width();
if ( ratio >= 1.0 )
{
radius.rwidth() = ry / ratio;
radius.rheight() = ry;
}
else
{
radius.rwidth() = rx;
radius.rheight() = rx * ratio;
}
} }
} }
} }

View File

@ -29,11 +29,35 @@ class QSK_EXPORT QskBoxShapeMetrics
Q_PROPERTY( ScalingMode scalingMode READ scalingMode WRITE setScalingMode ) Q_PROPERTY( ScalingMode scalingMode READ scalingMode WRITE setScalingMode )
public: public:
/*
How to scale, when translating to Qt::AbsoluteSize
Symmetric/SymmetricByMaximum sets the aspect ratio between x/y radii
to 1:1, while Proportional preserves the aspect ratio of the relative radii.
Symmetric or Proportional shrink the larger radius, while SymmetricByMaximum
expands the smaller radius to achieve the desired aspect ratio.
The effect of the scaling on the implemented box rendering is:
- SymmetricByMaximum in combination with a relative radius of 100
results in an ellipse.
- Rectangles with rounded corners can be achieved by Symmetric in combination
with a relative radius < 100.
Note, that the scaling is affected by the aspect ratio of the relative radii and
the one of the absolute size.
The default setting is Symmetric.
*/
enum ScalingMode enum ScalingMode
{ {
// How to scale, when translating to Qt::AbsoluteSize Symmetric,
Circular, SymmetricByMaximum,
Elliptic
Proportional
}; };
Q_ENUM( ScalingMode ); Q_ENUM( ScalingMode );
@ -121,13 +145,13 @@ class QSK_EXPORT QskBoxShapeMetrics
QSizeF m_radii[ 4 ]; QSizeF m_radii[ 4 ];
Qt::SizeMode m_sizeMode : 2; Qt::SizeMode m_sizeMode : 2;
ScalingMode m_scalingMode : 1; ScalingMode m_scalingMode : 2;
}; };
inline constexpr QskBoxShapeMetrics::QskBoxShapeMetrics() noexcept inline constexpr QskBoxShapeMetrics::QskBoxShapeMetrics() noexcept
: m_radii{ { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } } : m_radii{ { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } }
, m_sizeMode( Qt::AbsoluteSize ) , m_sizeMode( Qt::AbsoluteSize )
, m_scalingMode( Circular ) , m_scalingMode( Symmetric )
{ {
} }
@ -142,7 +166,7 @@ inline constexpr QskBoxShapeMetrics::QskBoxShapeMetrics(
: m_radii{ { radiusX, radiusY }, { radiusX, radiusY }, : m_radii{ { radiusX, radiusY }, { radiusX, radiusY },
{ radiusX, radiusY }, { radiusX, radiusY } } { radiusX, radiusY }, { radiusX, radiusY } }
, m_sizeMode( sizeMode ) , m_sizeMode( sizeMode )
, m_scalingMode( Circular ) , m_scalingMode( Symmetric )
{ {
} }
@ -151,7 +175,7 @@ inline constexpr QskBoxShapeMetrics::QskBoxShapeMetrics( qreal topLeft, qreal to
: m_radii{ { topLeft, topLeft }, { topRight, topRight }, : m_radii{ { topLeft, topLeft }, { topRight, topRight },
{ bottomLeft, bottomLeft }, { bottomRight, bottomRight } } { bottomLeft, bottomLeft }, { bottomRight, bottomRight } }
, m_sizeMode( sizeMode ) , m_sizeMode( sizeMode )
, m_scalingMode( Circular ) , m_scalingMode( Symmetric )
{ {
} }

View File

@ -162,9 +162,9 @@ int QskPageIndicator::indexAtPosition( const QPointF& pos ) const
this, contentsRect(), QskPageIndicator::Bullet, pos ); this, contentsRect(), QskPageIndicator::Bullet, pos );
} }
QskAspect::Placement QskPageIndicator::effectivePlacement() const QskAspect::Variation QskPageIndicator::effectiveVariation() const
{ {
return static_cast< QskAspect::Placement >( m_data->orientation ); return static_cast< QskAspect::Variation >( m_data->orientation );
} }
void QskPageIndicator::mousePressEvent( QMouseEvent* event ) void QskPageIndicator::mousePressEvent( QMouseEvent* event )

View File

@ -42,7 +42,7 @@ class QSK_EXPORT QskPageIndicator : public QskControl
QRectF bulletRect( int index ) const; QRectF bulletRect( int index ) const;
int indexAtPosition( const QPointF& ) const; int indexAtPosition( const QPointF& ) const;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
Q_SIGNALS: Q_SIGNALS:
void countChanged( int ); void countChanged( int );

View File

@ -154,10 +154,10 @@ void QskProgressBar::setIndeterminate( bool on )
Q_EMIT indeterminateChanged( on ); Q_EMIT indeterminateChanged( on );
} }
QskAspect::Placement QskProgressBar::effectivePlacement() const QskAspect::Variation QskProgressBar::effectiveVariation() const
{ {
// so you can define different hints depending on the orientation // so you can define different hints depending on the orientation
return static_cast< QskAspect::Placement >( m_data->orientation ); return static_cast< QskAspect::Variation >( m_data->orientation );
} }
void QskProgressBar::setBarGradient( const QskGradient& gradient ) void QskProgressBar::setBarGradient( const QskGradient& gradient )

View File

@ -49,7 +49,7 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
bool isIndeterminate() const; bool isIndeterminate() const;
void setIndeterminate( bool on = true ); void setIndeterminate( bool on = true );
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
void setBarGradient( const QskGradient& ); void setBarGradient( const QskGradient& );
void resetBarGradient(); void resetBarGradient();

View File

@ -14,8 +14,6 @@
#include "QskSkinlet.h" #include "QskSkinlet.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include <qfontmetrics.h>
QSK_SUBCONTROL( QskPushButton, Panel ) QSK_SUBCONTROL( QskPushButton, Panel )
QSK_SUBCONTROL( QskPushButton, Ripple ) QSK_SUBCONTROL( QskPushButton, Ripple )
QSK_SUBCONTROL( QskPushButton, Text ) QSK_SUBCONTROL( QskPushButton, Text )
@ -227,29 +225,9 @@ void QskPushButton::updateResources()
m_data->ensureGraphic( this ); m_data->ensureGraphic( this );
} }
QskAspect::Placement QskPushButton::effectivePlacement() const QskAspect::Variation QskPushButton::effectiveVariation() const
{ {
if ( hasGraphic() && !text().isEmpty() ) return Inherited::effectiveVariation();
{
// for the moment we only support the direction. TODO ...
auto aspect = Panel | QskAspect::Direction;
aspect.setPlacement( QskAspect::Vertical ); // to avoid recursions TODO ...
const auto dir = flagHint( aspect, Qsk::LeftToRight );
switch( dir )
{
case Qsk::LeftToRight:
case Qsk::RightToLeft:
return QskAspect::Horizontal;
case Qsk::TopToBottom:
case Qsk::BottomToTop:
return QskAspect::Vertical;
}
}
return Inherited::effectivePlacement();
} }
QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const

View File

@ -73,7 +73,7 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
QFont font() const; QFont font() const;
QRectF layoutRectForSize( const QSizeF& ) const override; QRectF layoutRectForSize( const QSizeF& ) const override;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
public Q_SLOTS: public Q_SLOTS:
void setText( const QString& ); void setText( const QString& );

View File

@ -5,6 +5,7 @@
#include "QskPushButtonSkinlet.h" #include "QskPushButtonSkinlet.h"
#include "QskPushButton.h" #include "QskPushButton.h"
#include "QskTextOptions.h"
#include "QskAnimationHint.h" #include "QskAnimationHint.h"
#include "QskGraphic.h" #include "QskGraphic.h"
@ -38,8 +39,16 @@ namespace
QskPushButton::Text, button->text(), QskPushButton::Text, button->text(),
QskPushButton::Graphic, button->graphic().defaultSize() ); QskPushButton::Graphic, button->graphic().defaultSize() );
const auto alignment = button->alignmentHint( QskPushButton::Panel, Qt::AlignCenter ); const auto textOptions = button->textOptions();
setFixedContent( QskPushButton::Text, Qt::Horizontal, alignment );
if ( ( textOptions.elideMode() == Qt::ElideNone )
&& ( textOptions.wrapMode() == QskTextOptions::NoWrap ) )
{
const auto alignment = button->alignmentHint(
QskPushButton::Panel, Qt::AlignCenter );
setFixedContent( QskPushButton::Text, Qt::Horizontal, alignment );
}
} }
}; };
} }

View File

@ -159,9 +159,9 @@ QVariantList QskSegmentedBar::optionAt( int index ) const
return list; return list;
} }
QskAspect::Placement QskSegmentedBar::effectivePlacement() const QskAspect::Variation QskSegmentedBar::effectiveVariation() const
{ {
return static_cast< QskAspect::Placement >( m_data->orientation ); return static_cast< QskAspect::Variation >( m_data->orientation );
} }
void QskSegmentedBar::mousePressEvent( QMouseEvent* event ) void QskSegmentedBar::mousePressEvent( QMouseEvent* event )

View File

@ -63,7 +63,7 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
int indexAtPosition( const QPointF& ) const; int indexAtPosition( const QPointF& ) const;
QRectF focusIndicatorRect() const override final; QRectF focusIndicatorRect() const override final;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
public Q_SLOTS: public Q_SLOTS:
void setSelectedIndex( int index ); void setSelectedIndex( int index );

View File

@ -70,9 +70,9 @@ qreal QskSeparator::extent() const
return metric( Panel | QskAspect::Size ); return metric( Panel | QskAspect::Size );
} }
QskAspect::Placement QskSeparator::effectivePlacement() const QskAspect::Variation QskSeparator::effectiveVariation() const
{ {
return static_cast< QskAspect::Placement >( m_orientation ); return static_cast< QskAspect::Variation >( m_orientation );
} }
#include "moc_QskSeparator.cpp" #include "moc_QskSeparator.cpp"

View File

@ -35,7 +35,7 @@ class QSK_EXPORT QskSeparator : public QskControl
void resetExtent(); void resetExtent();
qreal extent() const; qreal extent() const;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
Q_SIGNALS: Q_SIGNALS:
void orientationChanged( Qt::Orientation ); void orientationChanged( Qt::Orientation );

View File

@ -47,11 +47,11 @@ inline const QVariant* qskResolvedHint( QskAspect aspect,
} }
#endif #endif
if ( aspect.placement() ) if ( aspect.variation() )
{ {
// clear the placement bits and restart // clear the variation bits and restart
aspect = a; aspect = a;
aspect.setPlacement( QskAspect::NoPlacement ); aspect.setVariation( QskAspect::NoVariation );
continue; continue;
} }
@ -254,56 +254,73 @@ bool QskSkinHintTable::isResolutionMatching(
if ( aspect1.trunk() != aspect2.trunk() ) if ( aspect1.trunk() != aspect2.trunk() )
return false; return false;
const auto a1 = aspect1; auto a1 = aspect1;
const auto a2 = aspect2; auto a2 = aspect2;
Q_FOREVER Q_FOREVER
{ {
const auto s1 = aspect1.topState(); const auto state1 = aspect1.topState();
const auto s2 = aspect2.topState(); const auto state2 = aspect2.topState();
if ( s1 > s2 ) if ( state1 > state2 )
{ {
if ( hasHint( aspect1 ) ) if ( hasHint( aspect1 ) )
return false; return false;
aspect1.clearState( s1 ); aspect1.clearState( state1 );
continue;
} }
else if ( s2 > s1 )
if ( state2 > state1 )
{ {
if ( hasHint( aspect2 ) ) if ( hasHint( aspect2 ) )
return false; return false;
aspect2.clearState( s2 ); aspect2.clearState( state2 );
continue;
}
if ( aspect1 == aspect2 )
{
if ( hasHint( aspect1 ) )
return true;
if ( state1 == 0 )
{
if ( aspect1.variation() == QskAspect::NoVariation )
{
if ( aspect1.section() == QskAspect::Body )
return true;
// clear the section bits and restart with the initial state
a1.setSection( QskAspect::Body );
a2.setSection( QskAspect::Body );
aspect1 = a1;
aspect2 = a2;
}
else
{
// clear the variation bits and restart with the initial state
aspect1 = a1;
aspect1.setVariation( QskAspect::NoVariation );
aspect2 = a2;
aspect2.setVariation( QskAspect::NoVariation );
}
continue;
}
} }
else else
{ {
if ( aspect1 == aspect2 ) if ( hasHint( aspect1 ) || hasHint( aspect2 ) )
{ return false;
if ( hasHint( aspect1 ) )
return true;
if ( s1 == 0 )
{
if ( aspect1.placement() == QskAspect::NoPlacement )
return true;
// clear the placement bits and restart with the initial state
aspect1 = a1;
aspect1.setPlacement( QskAspect::NoPlacement );
aspect2 = a2;
aspect2.setPlacement( QskAspect::NoPlacement );
}
}
else
{
if ( hasHint( aspect1 ) || hasHint( aspect2 ) )
return false;
}
aspect1.clearState( s1 );
aspect2.clearState( s2 );
} }
aspect1.clearState( state1 );
aspect2.clearState( state2 );
} }
} }

View File

@ -347,7 +347,7 @@ void WindowAnimator::addHints( const QskControl* control,
if ( !isControlAffected( control, subControls, aspect ) ) if ( !isControlAffected( control, subControls, aspect ) )
continue; continue;
aspect.setPlacement( control->effectivePlacement() ); aspect.setVariation( control->effectiveVariation() );
aspect.setStates( control->skinStates() ); aspect.setStates( control->skinStates() );
if ( localTable.resolvedHint( aspect ) ) if ( localTable.resolvedHint( aspect ) )
@ -365,8 +365,8 @@ void WindowAnimator::addHints( const QskControl* control,
{ {
if ( QskVariantAnimator::maybeInterpolate( *v1, *v2 ) ) if ( QskVariantAnimator::maybeInterpolate( *v1, *v2 ) )
{ {
if ( r1.placement() == r2.placement() ) if ( r1.variation() == r2.variation() )
aspect.setPlacement( r2.placement() ); aspect.setVariation( r2.variation() );
if ( r1.states() == r2.states() ) if ( r1.states() == r2.states() )
aspect.setStates( r2.states() ); aspect.setStates( r2.states() );
@ -377,7 +377,7 @@ void WindowAnimator::addHints( const QskControl* control,
} }
else if ( v1 ) else if ( v1 )
{ {
aspect.setPlacement( r1.placement() ); aspect.setVariation( r1.variation() );
aspect.setStates( r1.states() ); aspect.setStates( r1.states() );
storeAnimator( control, aspect, *v1, QVariant(), animatorHint ); storeAnimator( control, aspect, *v1, QVariant(), animatorHint );
@ -385,7 +385,7 @@ void WindowAnimator::addHints( const QskControl* control,
} }
else if ( v2 ) else if ( v2 )
{ {
aspect.setPlacement( r1.placement() ); aspect.setVariation( r1.variation() );
aspect.setStates( r1.states() ); aspect.setStates( r1.states() );
storeAnimator( control, aspect, QVariant(), *v2, animatorHint ); storeAnimator( control, aspect, QVariant(), *v2, animatorHint );

View File

@ -725,7 +725,7 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter(
QskAspect aspect( effectiveSubcontrol( subControl ) | QskAspect::GraphicRole ); QskAspect aspect( effectiveSubcontrol( subControl ) | QskAspect::GraphicRole );
aspect.setSection( section() ); aspect.setSection( section() );
aspect.setPlacement( effectivePlacement() ); aspect.setVariation( effectiveVariation() );
QskSkinHintStatus status; QskSkinHintStatus status;
@ -735,7 +735,7 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter(
aspect.setSubcontrol( status.aspect.subControl() ); aspect.setSubcontrol( status.aspect.subControl() );
aspect.setSection( QskAspect::Body ); aspect.setSection( QskAspect::Body );
aspect.setPlacement( QskAspect::NoPlacement ); aspect.setVariation( QskAspect::NoVariation );
const auto v = animatedHint( aspect, nullptr ); const auto v = animatedHint( aspect, nullptr );
@ -877,8 +877,8 @@ QVariant QskSkinnable::effectiveSkinHint(
if ( aspect.section() == QskAspect::Body ) if ( aspect.section() == QskAspect::Body )
aspect.setSection( section() ); aspect.setSection( section() );
if ( aspect.placement() == QskAspect::NoPlacement ) if ( aspect.variation() == QskAspect::NoVariation )
aspect.setPlacement( effectivePlacement() ); aspect.setVariation( effectiveVariation() );
if ( !aspect.hasStates() ) if ( !aspect.hasStates() )
aspect.setStates( skinStates() ); aspect.setStates( skinStates() );
@ -980,11 +980,11 @@ QVariant QskSkinnable::interpolatedHint(
continue; continue;
} }
if ( aspect.placement() ) if ( aspect.variation() )
{ {
// clear the placement bits and restart // clear the variation bits and restart
aspect = a; aspect = a;
aspect.setPlacement( QskAspect::NoPlacement ); aspect.setVariation( QskAspect::NoVariation );
continue; continue;
} }
@ -1257,7 +1257,7 @@ void QskSkinnable::startHintTransition( QskAspect aspect, int index,
aspect.clearStates(); aspect.clearStates();
aspect.setSection( QskAspect::Body ); aspect.setSection( QskAspect::Body );
aspect.setPlacement( QskAspect::NoPlacement ); aspect.setVariation( QskAspect::NoVariation );
aspect.setAnimator( false ); aspect.setAnimator( false );
#if DEBUG_ANIMATOR #if DEBUG_ANIMATOR
@ -1345,7 +1345,7 @@ bool QskSkinnable::startHintTransitions(
bool started = false; // at least one transition has been started bool started = false; // at least one transition has been started
QskAspect aspect; QskAspect aspect;
aspect.setPlacement( effectivePlacement() ); aspect.setVariation( effectiveVariation() );
aspect.setSection( section() ); aspect.setSection( section() );
const auto skin = effectiveSkin(); const auto skin = effectiveSkin();
@ -1426,9 +1426,9 @@ QskSkin* QskSkinnable::effectiveSkin() const
return skin ? skin : qskSetup->skin(); return skin ? skin : qskSetup->skin();
} }
QskAspect::Placement QskSkinnable::effectivePlacement() const QskAspect::Variation QskSkinnable::effectiveVariation() const
{ {
return QskAspect::NoPlacement; return QskAspect::NoVariation;
} }
QskAspect::Section QskSkinnable::section() const QskAspect::Section QskSkinnable::section() const

View File

@ -101,7 +101,7 @@ class QSK_EXPORT QskSkinnable
QskAspect::States, QskSkinHintStatus* status = nullptr ) const; QskAspect::States, QskSkinHintStatus* status = nullptr ) const;
QVariant effectiveSkinHint( QskAspect, QskSkinHintStatus* = nullptr ) const; QVariant effectiveSkinHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
virtual QskAspect::Placement effectivePlacement() const; virtual QskAspect::Variation effectiveVariation() const;
virtual QskAspect::Section section() const; virtual QskAspect::Section section() const;

View File

@ -87,9 +87,9 @@ Qt::Orientation QskSlider::orientation() const
return m_data->orientation; return m_data->orientation;
} }
QskAspect::Placement QskSlider::effectivePlacement() const QskAspect::Variation QskSlider::effectiveVariation() const
{ {
return static_cast< QskAspect::Placement >( m_data->orientation ); return static_cast< QskAspect::Variation >( m_data->orientation );
} }
void QskSlider::setTracking( bool on ) void QskSlider::setTracking( bool on )

View File

@ -41,7 +41,7 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
qreal handlePosition() const; // [0,0, 1.0] qreal handlePosition() const; // [0,0, 1.0]
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
Q_SIGNALS: Q_SIGNALS:
void pressedChanged( bool ); void pressedChanged( bool );

View File

@ -72,13 +72,9 @@ void QskSwitchButton::setInverted( bool on )
} }
} }
QskAspect::Placement QskSwitchButton::effectivePlacement() const QskAspect::Variation QskSwitchButton::effectiveVariation() const
{ {
/* return static_cast< QskAspect::Variation >( m_data->orientation );
So you can define different hints depending on the orientation,
but what about the layoutDirection ???
*/
return static_cast< QskAspect::Placement >( m_data->orientation );
} }
#include "moc_QskSwitchButton.cpp" #include "moc_QskSwitchButton.cpp"

View File

@ -32,7 +32,7 @@ class QSK_EXPORT QskSwitchButton : public QskAbstractButton
bool isInverted() const; bool isInverted() const;
void setInverted( bool ); void setInverted( bool );
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
Q_SIGNALS: Q_SIGNALS:
void orientationChanged( Qt::Orientation ); void orientationChanged( Qt::Orientation );

View File

@ -688,7 +688,7 @@ QskAspect::Subcontrol QskTabBar::substitutedSubcontrol(
return Inherited::substitutedSubcontrol( subControl ); return Inherited::substitutedSubcontrol( subControl );
} }
QskAspect::Placement QskTabBar::effectivePlacement() const QskAspect::Variation QskTabBar::effectiveVariation() const
{ {
switch ( edge() ) switch ( edge() )
{ {
@ -705,7 +705,7 @@ QskAspect::Placement QskTabBar::effectivePlacement() const
return QskAspect::Bottom; return QskAspect::Bottom;
} }
return QskAspect::NoPlacement; return QskAspect::NoVariation;
} }
#include "moc_QskTabBar.cpp" #include "moc_QskTabBar.cpp"

View File

@ -89,7 +89,7 @@ class QSK_EXPORT QskTabBar : public QskBox
int indexOf( const QskTabButton* ) const; int indexOf( const QskTabButton* ) const;
Q_INVOKABLE int indexOf( QskTabButton* ) const; Q_INVOKABLE int indexOf( QskTabButton* ) const;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
public Q_SLOTS: public Q_SLOTS:
void setCurrentIndex( int index ); void setCurrentIndex( int index );

View File

@ -98,12 +98,12 @@ QRectF QskTabButton::layoutRectForSize( const QSizeF& size ) const
return subControlContentsRect( size, Panel ); return subControlContentsRect( size, Panel );
} }
QskAspect::Placement QskTabButton::effectivePlacement() const QskAspect::Variation QskTabButton::effectiveVariation() const
{ {
if ( m_data->tabBar ) if ( m_data->tabBar )
return m_data->tabBar->effectivePlacement(); return m_data->tabBar->effectiveVariation();
return QskAspect::NoPlacement; return QskAspect::NoVariation;
} }
const QskTabBar* QskTabButton::tabBar() const const QskTabBar* QskTabButton::tabBar() const

View File

@ -41,7 +41,7 @@ class QSK_EXPORT QskTabButton : public QskAbstractButton
QRectF layoutRectForSize( const QSizeF& ) const override; QRectF layoutRectForSize( const QSizeF& ) const override;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
const QskTabBar* tabBar() const; const QskTabBar* tabBar() const;
QskTabBar* tabBar(); QskTabBar* tabBar();

View File

@ -206,9 +206,9 @@ int QskTabView::count() const
return m_data->tabBar->count(); return m_data->tabBar->count();
} }
QskAspect::Placement QskTabView::effectivePlacement() const QskAspect::Variation QskTabView::effectiveVariation() const
{ {
return m_data->tabBar->effectivePlacement(); return m_data->tabBar->effectiveVariation();
} }
QSizeF QskTabView::layoutSizeHint( QSizeF QskTabView::layoutSizeHint(

View File

@ -73,7 +73,7 @@ class QSK_EXPORT QskTabView : public QskControl
QRectF tabRect() const; QRectF tabRect() const;
QskAspect::Placement effectivePlacement() const override; QskAspect::Variation effectiveVariation() const override;
public Q_SLOTS: public Q_SLOTS:
void setCurrentIndex( int index ); void setCurrentIndex( int index );

View File

@ -283,65 +283,31 @@ static inline void qskCreateFill(
} }
} }
} }
else if ( m_metrics.stepSymmetries )
{
auto line = lines;
if ( isHorizontal )
{
int stepCount = qMax( cn[TopLeftCorner].stepCount, cn[BottomLeftCorner].stepCount );
for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it )
map.setVLine( TopLeftCorner, BottomLeftCorner, it.cos(), it.sin(), line++ );
stepCount = qMax( cn[TopRightCorner].stepCount, cn[BottomRightCorner].stepCount );
for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it )
map.setVLine( TopRightCorner, BottomRightCorner, it.cos(), it.sin(), line++ );
}
else
{
int stepCount = qMax( cn[TopLeftCorner].stepCount, cn[TopRightCorner].stepCount );
for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it )
map.setHLine( TopLeftCorner, TopRightCorner, it.cos(), it.sin(), line++ );
stepCount = qMax( cn[BottomLeftCorner].stepCount, cn[BottomRightCorner].stepCount );
for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it )
map.setHLine( BottomLeftCorner, BottomRightCorner, it.cos(), it.sin(), line++ );
}
}
else else
{ {
/*
This fallback code creates the same points. The cases above are
simply micro oprimization reducing the loops or calculations
to get there.
*/
auto line = lines; auto line = lines;
int stepCount;
if ( isHorizontal ) if ( isHorizontal )
{ {
int stepCount = qMax( cn[TopLeftCorner].stepCount, cn[BottomLeftCorner].stepCount ); stepCount = m_metrics.innerStepCount( TopLeftCorner, BottomLeftCorner );
for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it ) for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it )
map.setLine( TopLeftCorner, BottomLeftCorner, it.cos(), it.sin(), line++ ); map.setLine( TopLeftCorner, BottomLeftCorner, it.cos(), it.sin(), line++ );
stepCount = qMax( cn[TopRightCorner].stepCount, cn[BottomRightCorner].stepCount ); stepCount = m_metrics.innerStepCount( TopRightCorner, BottomRightCorner );
for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it ) for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it )
map.setLine( TopRightCorner, BottomRightCorner, it.cos(), it.sin(), line++ ); map.setLine( TopRightCorner, BottomRightCorner, it.cos(), it.sin(), line++ );
} }
else else
{ {
int stepCount = qMax( cn[TopLeftCorner].stepCount, cn[TopRightCorner].stepCount ); stepCount = m_metrics.innerStepCount( TopLeftCorner, TopRightCorner );
for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it ) for ( ArcIterator it( stepCount, false ); !it.isDone(); ++it )
map.setLine( TopLeftCorner, TopRightCorner, it.cos(), it.sin(), line++ ); map.setLine( TopLeftCorner, TopRightCorner, it.cos(), it.sin(), line++ );
stepCount = qMax( cn[BottomLeftCorner].stepCount, cn[BottomRightCorner].stepCount ); stepCount = m_metrics.innerStepCount( BottomLeftCorner, BottomRightCorner );
for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it ) for ( ArcIterator it( stepCount, true ); !it.isDone(); ++it )
map.setLine( BottomLeftCorner, BottomRightCorner, it.cos(), it.sin(), line++ ); map.setLine( BottomLeftCorner, BottomRightCorner, it.cos(), it.sin(), line++ );
@ -820,23 +786,15 @@ int QskBoxBasicStroker::fillCount() const
if ( m_metrics.isInsideRounded ) if ( m_metrics.isInsideRounded )
{ {
const auto c = m_metrics.corners;
if ( m_metrics.preferredOrientation == Qt::Horizontal ) if ( m_metrics.preferredOrientation == Qt::Horizontal )
{ {
n += qMax( c[ Qt::TopLeftCorner ].innerStepCount(), n += m_metrics.innerStepCount( Qt::TopLeftCorner, Qt::BottomLeftCorner );
c[ Qt::BottomLeftCorner ].innerStepCount() ); n += m_metrics.innerStepCount( Qt::TopRightCorner, Qt::BottomRightCorner );
n += qMax( c[ Qt::TopRightCorner ].innerStepCount(),
c[ Qt::BottomRightCorner ].innerStepCount() );
} }
else else
{ {
n += qMax( c[ Qt::TopLeftCorner ].innerStepCount(), n += m_metrics.innerStepCount( Qt::TopLeftCorner, Qt::TopRightCorner );
c[ Qt::TopRightCorner ].innerStepCount() ); n += m_metrics.innerStepCount( Qt::BottomLeftCorner, Qt::BottomRightCorner );
n += qMax( c[ Qt::BottomLeftCorner ].innerStepCount(),
c[ Qt::BottomRightCorner ].innerStepCount() );
} }
} }

View File

@ -9,6 +9,15 @@
#include "QskBoxColorMap.h" #include "QskBoxColorMap.h"
#include "QskBoxMetrics.h" #include "QskBoxMetrics.h"
static inline bool qskCanUseHVFiller(
const Qt::Orientations orientations, const QskLinearDirection& dir )
{
if ( !dir.isTilted() )
return orientations & ( dir.isVertical() ? Qt::Vertical : Qt::Horizontal );
return false;
}
namespace namespace
{ {
using namespace QskVertex; using namespace QskVertex;
@ -770,7 +779,7 @@ int QskBoxGradientStroker::lineCount() const
if ( m_metrics.isInsideRounded ) if ( m_metrics.isInsideRounded )
{ {
if ( m_metrics.stepSymmetries && !m_dir.isTilted() ) if ( qskCanUseHVFiller( m_metrics.stepSymmetries, m_dir ) )
{ {
const QskBoxBasicStroker stroker( m_metrics, QskBoxBorderColors(), m_gradient ); const QskBoxBasicStroker stroker( m_metrics, QskBoxBorderColors(), m_gradient );
n += stroker.fillCount(); n += stroker.fillCount();
@ -804,7 +813,7 @@ void QskBoxGradientStroker::setLines( int lineCount, QskVertex::ColoredLine* lin
if ( m_metrics.isInsideRounded ) if ( m_metrics.isInsideRounded )
{ {
if ( m_metrics.stepSymmetries && !m_dir.isTilted() ) if ( qskCanUseHVFiller( m_metrics.stepSymmetries, m_dir ) )
{ {
FillerHV filler( m_metrics ); FillerHV filler( m_metrics );
effectiveCount = filler.setLines( m_gradient, lines ); effectiveCount = filler.setLines( m_gradient, lines );

View File

@ -173,15 +173,6 @@ QskBoxMetrics::QskBoxMetrics( const QRectF& rect,
} }
} }
if ( stepSymmetries == Qt::Horizontal )
{
preferredOrientation = Qt::Horizontal;
}
else if ( stepSymmetries == Qt::Vertical )
{
preferredOrientation = Qt::Vertical;
}
else
{ {
const auto tl = corners[ Qt::TopLeftCorner ].innerStepCount(); const auto tl = corners[ Qt::TopLeftCorner ].innerStepCount();
const auto tr = corners[ Qt::TopRightCorner ].innerStepCount(); const auto tr = corners[ Qt::TopRightCorner ].innerStepCount();

View File

@ -7,6 +7,7 @@
#define QSK_BOX_METRICS_H #define QSK_BOX_METRICS_H
#include <qrect.h> #include <qrect.h>
#include <qglobal.h>
#include <qnamespace.h> #include <qnamespace.h>
class QskBoxShapeMetrics; class QskBoxShapeMetrics;
@ -24,6 +25,12 @@ class QskBoxMetrics
int outerStepCount() const; int outerStepCount() const;
int innerStepCount() const; int innerStepCount() const;
int innerStepCount( int corner1, int corner2 ) const
{
return qMax( corners[ corner1 ].innerStepCount(),
corners[ corner2 ].innerStepCount() );
}
struct Corner struct Corner
{ {
inline qreal xInner( qreal cos ) const inline qreal xInner( qreal cos ) const
@ -82,10 +89,7 @@ class QskBoxMetrics
*/ */
Qt::Orientations stepSymmetries; Qt::Orientations stepSymmetries;
/* // the direction that needs less contour lines is preferred.
In case stepSymmetries indicates both directions the direction
that needs less steps is preferred.
*/
Qt::Orientation preferredOrientation; Qt::Orientation preferredOrientation;
}; };

View File

@ -193,8 +193,7 @@ void QskBox::renderBox( const QRectF& rect,
const int fillCount = fillStroker.lineCount(); const int fillCount = fillStroker.lineCount();
const int borderCount = borderStroker.borderCount(); const int borderCount = borderStroker.borderCount();
const int extraLine = ( fillCount && borderCount ) ? 1 : 0;
const int extraLine = ( fillCount && borderCount && !metrics.isOutsideRounded ) ? 1 : 0;
auto lines = qskAllocateColoredLines( auto lines = qskAllocateColoredLines(
geometry, fillCount + borderCount + extraLine ); geometry, fillCount + borderCount + extraLine );