introducing series/sample for subcontrols being related to multiple

instances
This commit is contained in:
Uwe Rathmann 2021-12-28 16:14:30 +01:00
parent 9fff09144a
commit aca538a89d
5 changed files with 74 additions and 60 deletions

View File

@ -308,13 +308,13 @@ void QskMenu::setSelectedIndex( int index )
QRectF QskMenu::cellRect( int index ) const
{
return effectiveSkinlet()->subControlCell(
return effectiveSkinlet()->sampleRect(
this, contentsRect(), QskMenu::Cell, index );
}
int QskMenu::indexAtPosition( const QPointF& pos ) const
{
return effectiveSkinlet()->subControlCellIndexAt(
return effectiveSkinlet()->sampleIndexAt(
this, contentsRect(), QskMenu::Cell, pos );
}

View File

@ -15,7 +15,7 @@
#include <qfontmetrics.h>
template< class T >
static inline QVariant qskValueAt( const QskMenu* menu, int index )
static inline QVariant qskSampleAt( const QskMenu* menu, int index )
{
const auto item = menu->itemAt( index );
@ -35,6 +35,13 @@ static inline QVariant qskValueAt( const QskMenu* menu, int index )
return QVariant();
}
template< class T >
static inline T qskValueAt( const QskMenu* menu, int index )
{
const auto sample = qskSampleAt< T >( menu, index );
return sample.template value< T >();
}
class QskMenuSkinlet::PrivateData
{
public:
@ -126,10 +133,10 @@ class QskMenuSkinlet::PrivateData
qreal maxW = 0.0;
for ( int i = 0; i < menu->count(); i++ )
{
const auto value = skinlet->valueAt( menu, QskMenu::Graphic, i );
if ( value.canConvert< QskGraphic >() )
const auto sample = skinlet->sampleAt( menu, QskMenu::Graphic, i );
if ( sample.canConvert< QskGraphic >() )
{
const auto graphic = value.value< QskGraphic >();
const auto graphic = sample.value< QskGraphic >();
if ( !graphic.isNull() )
{
const auto w = graphic.widthForHeight( h );
@ -152,10 +159,10 @@ class QskMenuSkinlet::PrivateData
for ( int i = 0; i < menu->count(); i++ )
{
const auto value = skinlet->valueAt( menu, QskMenu::Text, i );
if ( value.canConvert< QString >() )
const auto sample = skinlet->sampleAt( menu, QskMenu::Text, i );
if ( sample.canConvert< QString >() )
{
const auto text = value.value< QString >();
const auto text = sample.value< QString >();
if( !text.isEmpty() )
{
const auto w = qskHorizontalAdvance( fm, text );
@ -234,7 +241,7 @@ QRectF QskMenuSkinlet::subControlRect(
return Inherited::subControlRect( skinnable, contentsRect, subControl );
}
QRectF QskMenuSkinlet::subControlCell(
QRectF QskMenuSkinlet::sampleRect(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl, int index ) const
{
@ -252,7 +259,7 @@ QRectF QskMenuSkinlet::subControlCell(
if ( subControl == QskMenu::Graphic || subControl == QskMenu::Text )
{
const auto r = subControlCell( menu, contentsRect, Q::Cell, index );
const auto r = sampleRect( menu, contentsRect, Q::Cell, index );
const auto graphicWidth = m_data->graphicWidth( menu );
if ( subControl == QskMenu::Graphic )
@ -276,19 +283,19 @@ QRectF QskMenuSkinlet::subControlCell(
}
}
return Inherited::subControlCell(
return Inherited::sampleRect(
skinnable, contentsRect, subControl, index );
}
int QskMenuSkinlet::subControlCellIndexAt(
int QskMenuSkinlet::sampleIndexAt(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl, const QPointF& pos ) const
{
const PrivateData::CacheGuard guard( m_data.get() );
return Inherited::subControlCellIndexAt( skinnable, contentsRect, subControl, pos );
return Inherited::sampleIndexAt( skinnable, contentsRect, subControl, pos );
}
int QskMenuSkinlet::subControlCellCount(
int QskMenuSkinlet::sampleCount(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const
{
using Q = QskMenu;
@ -299,15 +306,15 @@ int QskMenuSkinlet::subControlCellCount(
return menu->count();
}
return Inherited::subControlCellCount( skinnable, subControl );
return Inherited::sampleCount( skinnable, subControl );
}
QskAspect::States QskMenuSkinlet::subControlCellStates(
QskAspect::States QskMenuSkinlet::sampleStates(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const
{
using Q = QskMenu;
auto states = Inherited::subControlCellStates( skinnable, subControl, index );
auto states = Inherited::sampleStates( skinnable, subControl, index );
if ( subControl == Q::Cell || subControl == Q::Graphic || subControl == Q::Text )
{
@ -319,7 +326,7 @@ QskAspect::States QskMenuSkinlet::subControlCellStates(
return states;
}
QVariant QskMenuSkinlet::valueAt( const QskSkinnable* skinnable,
QVariant QskMenuSkinlet::sampleAt( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index ) const
{
using Q = QskMenu;
@ -327,12 +334,12 @@ QVariant QskMenuSkinlet::valueAt( const QskSkinnable* skinnable,
const auto menu = static_cast< const QskMenu* >( skinnable );
if ( subControl == Q::Graphic )
return qskValueAt< QskGraphic >( menu, index );
return qskSampleAt< QskGraphic >( menu, index );
if ( subControl == Q::Text )
return qskValueAt< QString >( menu, index );
return qskSampleAt< QString >( menu, index );
return Inherited::valueAt( skinnable, subControl, index );
return Inherited::sampleAt( skinnable, subControl, index );
}
QSGNode* QskMenuSkinlet::updateContentsNode(
@ -392,14 +399,14 @@ QSGNode* QskMenuSkinlet::updateMenuNode(
return contentsNode;
}
QSGNode* QskMenuSkinlet::updateSeriesSubNode( const QskSkinnable* skinnable,
QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
{
using Q = QskMenu;
auto menu = static_cast< const QskMenu* >( skinnable );
const auto rect = subControlCell( menu, menu->contentsRect(), subControl, index );
const auto rect = sampleRect( menu, menu->contentsRect(), subControl, index );
if ( subControl == Q::Cell )
{
@ -408,24 +415,28 @@ QSGNode* QskMenuSkinlet::updateSeriesSubNode( const QskSkinnable* skinnable,
if ( subControl == Q::Graphic )
{
const auto v = qskValueAt< QskGraphic >( menu, index );
const auto graphic = qskValueAt< QskGraphic >( menu, index );
if ( graphic.isNull() )
return nullptr;
const auto alignment = menu->alignmentHint( subControl, Qt::AlignCenter );
const auto filter = menu->effectiveGraphicFilter( subControl );
return QskSkinlet::updateGraphicNode(
menu, node, v.value< QskGraphic >(), filter, rect, alignment );
menu, node, graphic, filter, rect, alignment );
}
if ( subControl == Q::Text )
{
const auto v = qskValueAt< QString >( menu, index );
const auto text = qskValueAt< QString >( menu, index );
if ( text.isEmpty() )
return nullptr;
const auto alignment = menu->alignmentHint(
subControl, Qt::AlignVCenter | Qt::AlignLeft );
return QskSkinlet::updateTextNode( menu, node, rect, alignment,
v.value< QString>(), menu->textOptions(), QskMenu::Text );
text, menu->textOptions(), QskMenu::Text );
}
return nullptr;
@ -440,7 +451,7 @@ QSizeF QskMenuSkinlet::sizeHint( const QskSkinnable* skinnable,
const PrivateData::CacheGuard guard( m_data.get() );
const auto count = subControlCellCount( skinnable, QskMenu::Cell );
const auto count = sampleCount( skinnable, QskMenu::Cell );
qreal w = 0.0;
qreal h = 0.0;

View File

@ -24,18 +24,18 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
QRectF subControlRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol ) const override;
QRectF subControlCell( const QskSkinnable*,
int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
QRectF sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const override;
int subControlCellIndexAt( const QskSkinnable*,
int sampleIndexAt( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override;
int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
QskAspect::States subControlCellStates( const QskSkinnable*,
QskAspect::States sampleStates( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const override;
QVariant valueAt( const QskSkinnable*,
QVariant sampleAt( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const override;
QSizeF sizeHint( const QskSkinnable*,
@ -45,7 +45,7 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const override;
QSGNode* updateMenuNode( const QskSkinnable*, QSGNode* ) const;
QSGNode* updateSeriesSubNode( const QskSkinnable*,
QSGNode* updateSampleNode( const QskSkinnable*,
QskAspect::Subcontrol, int index, QSGNode* ) const override;
private:

View File

@ -564,20 +564,17 @@ QSGNode* QskSkinlet::updateGraphicNode(
return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect, mirrored );
}
int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable,
int QskSkinlet::sampleIndexAt( const QskSkinnable* skinnable,
const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const
{
/*
slow default implementation to be overloaded when
having many cells
*/
// slow default implementation to be overloaded when having many cells
const auto cellCount = subControlCellCount( skinnable, subControl );
const auto count = sampleCount( skinnable, subControl );
for ( int i = 0; i < cellCount; i++ )
for ( int i = 0; i < count; i++ )
{
const auto cellRect = subControlCell( skinnable, rect, subControl, i );
if ( cellRect.contains( pos ) )
const auto r = sampleRect( skinnable, rect, subControl, i );
if ( r.contains( pos ) )
return i;
}
@ -590,19 +587,19 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable,
auto node = rootNode ? rootNode->firstChild() : nullptr;
QSGNode* lastNode = nullptr;
const auto count = subControlCellCount( skinnable, subControl );
const auto count = sampleCount( skinnable, subControl );
for( int i = 0; i < count; i++ )
{
QSGNode* newNode = nullptr;
{
const auto newStates = subControlCellStates( skinnable, subControl, i );
const auto newStates = sampleStates( skinnable, subControl, i );
QskSkinStateChanger stateChanger( skinnable );
stateChanger.setStates( newStates );
newNode = updateSeriesSubNode( skinnable, subControl, i, node );
newNode = updateSampleNode( skinnable, subControl, i, node );
}
if ( newNode )
@ -631,21 +628,21 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable,
return rootNode;
}
QSGNode* QskSkinlet::updateSeriesSubNode( const QskSkinnable*,
QSGNode* QskSkinlet::updateSampleNode( const QskSkinnable*,
QskAspect::Subcontrol, int index, QSGNode* ) const
{
Q_UNUSED( index )
return nullptr;
}
QskAspect::States QskSkinlet::subControlCellStates(
QskAspect::States QskSkinlet::sampleStates(
const QskSkinnable* skinnable, QskAspect::Subcontrol, int index ) const
{
Q_UNUSED( index )
return skinnable->skinStates();
}
QVariant QskSkinlet::valueAt( const QskSkinnable*,
QVariant QskSkinlet::sampleAt( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const
{
Q_UNUSED( index )

View File

@ -42,18 +42,22 @@ class QSK_EXPORT QskSkinlet
virtual QRectF subControlRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol ) const;
virtual QRectF subControlCell( const QskSkinnable*,
/*
When having more than one instance for the
same QskAspect::Subcontrol it is called a sample
*/
virtual QRectF sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const;
virtual int subControlCellIndexAt( const QskSkinnable*,
virtual int sampleIndexAt( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const;
virtual int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const;
virtual int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const;
virtual QskAspect::States subControlCellStates( const QskSkinnable*,
virtual QskAspect::States sampleStates( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const;
virtual QVariant valueAt( const QskSkinnable*,
virtual QVariant sampleAt( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const;
const QVector< quint8 >& nodeRoles() const;
@ -61,6 +65,8 @@ class QSK_EXPORT QskSkinlet
void setOwnedBySkinnable( bool on );
bool isOwnedBySkinnable() const;
// Helper functions for creating nodes
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
const QRectF&, QskAspect::Subcontrol );
@ -136,7 +142,7 @@ class QSK_EXPORT QskSkinlet
QSGNode* updateSeriesNode( const QskSkinnable*,
QskAspect::Subcontrol, QSGNode* ) const;
virtual QSGNode* updateSeriesSubNode( const QskSkinnable*,
virtual QSGNode* updateSampleNode( const QskSkinnable*,
QskAspect::Subcontrol, int index, QSGNode* ) const;
void replaceChildNode( quint8 nodeRole, QSGNode* parentNode,
@ -168,17 +174,17 @@ inline QSizeF QskSkinlet::sizeHint(
return QSizeF();
}
inline QRectF QskSkinlet::subControlCell( const QskSkinnable*,
inline QRectF QskSkinlet::sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const
{
Q_UNUSED( index )
return QRectF();
}
inline int QskSkinlet::subControlCellCount(
inline int QskSkinlet::sampleCount(
const QskSkinnable*, QskAspect::Subcontrol ) const
{
return 1;
return 0;
}
#endif