8#include <qalgorithms.h>
10#include <qmetaobject.h>
15#include <unordered_map>
17static_assert(
sizeof(
QskAspect ) ==
sizeof( quint64 ),
18 "QskAspect::Aspect has to match quint64" );
20static void qskRegisterAspect()
22 qRegisterMetaType< QskAspect >();
24#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
25 QMetaType::registerEqualsComparator< QskAspect >();
29Q_CONSTRUCTOR_FUNCTION( qskRegisterAspect )
43 QVector< QByteArray > subControlNames;
44 unordered_map< const QMetaObject*, QVector< QskAspect::Subcontrol > > subControlTable;
45 unordered_map< const QMetaObject*, QVector< StateInfo > > stateTable;
49static quint8 qskPrimitiveCount = QMetaEnum::fromType< QskAspect::Primitive >().keyCount();
51quint8 QskAspect::primitiveCount()
53 return qskPrimitiveCount;
56void QskAspect::reservePrimitives( quint8 count )
60 constexpr quint8 maxCount = 1 << 5;
62 Q_ASSERT( count <= maxCount );
64 if ( count > maxCount )
66 qWarning() <<
"QskAspect: having more than"
67 << maxCount <<
"primitives is not supported.";
72 if ( count > qskPrimitiveCount )
73 qskPrimitiveCount = count;
76Q_GLOBAL_STATIC( AspectRegistry, qskAspectRegistry )
79 const QMetaObject* metaObject,
State state, const
char* name )
85 auto& stateTable = qskAspectRegistry->stateTable;
86 stateTable[ metaObject ] += info;
92 const QMetaObject* metaObject,
const char* name )
94 auto& names = qskAspectRegistry->subControlNames;
95 auto& hashTable = qskAspectRegistry->subControlTable;
98 "There are no free subcontrol aspects; please modify your"
99 " application to declare fewer aspects, or increase the mask size of"
100 " QskAspect::Subcontrol in QskAspect.h." );
113 const auto& names = qskAspectRegistry->subControlNames;
116 if ( index > 0 && index <= names.size() )
117 return names[ index - 1 ];
124 const auto& names = qskAspectRegistry->subControlNames;
126 if ( metaObject ==
nullptr )
144 const auto& hashTable = qskAspectRegistry->subControlTable;
146 auto it = hashTable.find( metaObject );
147 if ( it != hashTable.end() )
151 return QVector< Subcontrol >();
154#ifndef QT_NO_DEBUG_STREAM
156static QByteArray qskEnumString(
const char* name,
int value )
158 const auto& mo = QskAspect::staticMetaObject;
160 const QMetaEnum metaEnum = mo.enumerator( mo.indexOfEnumerator( name ) );
161 const char* key = metaEnum.valueToKey( value );
163 return key ? QByteArray( key ) : QString::number( value ).toLatin1();
166static QByteArray qskStateKey(
const QMetaObject* metaObject, quint16 state )
168 const auto& stateTable = qskAspectRegistry->stateTable;
170 for (
auto mo = metaObject; mo !=
nullptr; mo = mo->superClass() )
172 const auto it = stateTable.find( mo );
173 if ( it != stateTable.end() )
175 for (
const auto& info : it->second )
177 if ( info.state == state )
186static QByteArray qskStatesToString(
187 const QMetaObject* metaObject, QskAspect::States states )
194 if ( metaObject ==
nullptr )
196 const std::bitset< 16 > stateBits( states );
197 return stateBits.to_string().c_str();
202 QByteArray stateString;
206 for (
int i = 0; i < 16; i++ )
208 const uint mask = 1 << i;
217 const auto key = qskStateKey( metaObject, mask );
220 const std::bitset< 16 > stateBits( states );
221 stateString += stateBits.to_string().c_str();
233static inline QDebug qskDebugEnum(
234 QDebug debug,
const char* name,
int value )
236 qt_QMetaEnum_debugOperator( debug, value,
237 &QskAspect::staticMetaObject, name );
243 return qskDebugEnum( debug,
"Type", type );
248 return qskDebugEnum( debug,
"Primitive", primitive );
253 QDebugStateSaver saver( debug );
256 debug <<
"QskAspect::Subcontrol" <<
'(';
265 qskDebugEnum( debug,
"Variation", variation );
269QDebug operator<<( QDebug debug, QskAspect::States states )
271 qskDebugStates( debug,
nullptr, states );
275QDebug operator<<( QDebug debug,
QskAspect aspect )
277 qskDebugAspect( debug,
nullptr, aspect );
281void qskDebugStates( QDebug debug,
282 const QMetaObject* metaObject, QskAspect::States states )
284 QDebugStateSaver saver( debug );
290 debug <<
"QskAspect::States( " << qskStatesToString( metaObject, states ) <<
" )";
293void qskDebugAspect( QDebug debug,
const QMetaObject* metaObject,
QskAspect aspect )
295 QDebugStateSaver saver( debug );
301 debug <<
"QskAspect( ";
304 if ( subControlName.isEmpty() )
305 debug << QByteArrayLiteral(
"NoSubcontrol" );
307 debug << subControlName;
309 if ( aspect.section() != QskAspect::Body )
310 debug <<
", " << qskEnumString(
"Section", aspect.section() );
312 debug <<
", " << qskEnumString(
"Type", aspect.
type() );
317 debug <<
", " << qskEnumString(
"Primitive", aspect.
primitive() );
320 debug <<
", " << qskEnumString(
"Variation", aspect.
variation() );
323 debug <<
", " << qskStatesToString( metaObject, aspect.
states() );
334 QDebug debug( &tmp );
338 static QByteArray bytes[ 10 ];
339 static int counter = 0;
341 counter = ( counter + 1 ) % 10;
343 bytes[ counter ] = tmp.toUtf8();
344 return bytes[ counter ].constData();
349 if ( m_bits.states ==
NoState )
352 const auto n = qCountLeadingZeroBits(
static_cast< quint16
>( m_bits.states ) );
356#include "moc_QskAspect.cpp"
Lookup key for a QskSkinHintTable.
State topState() const noexcept
constexpr bool hasStates() const noexcept
constexpr bool isAnimator() const noexcept
const char * toPrintable() const
Variation
Some sort of variation.
static QVector< QByteArray > subControlNames(const QMetaObject *=nullptr)
constexpr Primitive primitive() const noexcept
constexpr Subcontrol subControl() const noexcept
constexpr Variation variation() const noexcept
constexpr Type type() const noexcept
constexpr States states() const noexcept
Primitive
Represents a specific element or attribute.
static QVector< Subcontrol > subControls(const QMetaObject *)
static QByteArray subControlName(Subcontrol)
Type
Represents the type of the Aspect.
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
static Subcontrol nextSubcontrol(const QMetaObject *, const char *)