QskSkinlet improved for subControls with multible instances
This commit is contained in:
parent
2201c80d09
commit
f1a324b216
@ -162,7 +162,7 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
||||
if ( rowSelected >= rowMin && rowSelected <= rowMax )
|
||||
{
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.addStates( QskListView::Selected );
|
||||
stateChanger.setStates( listView->skinStates() | QskListView::Selected );
|
||||
|
||||
const QColor color = listView->color( QskListView::Cell );
|
||||
|
||||
@ -436,12 +436,12 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||
{
|
||||
using namespace QskSGNode;
|
||||
|
||||
QskAspect::States rowStates;
|
||||
auto rowStates = listView->skinStates();
|
||||
if ( row == listView->selectedRow() )
|
||||
rowStates |= QskListView::Selected;
|
||||
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.addStates( rowStates );
|
||||
stateChanger.setStates( rowStates );
|
||||
|
||||
QSGNode* newNode = nullptr;
|
||||
|
||||
|
@ -308,13 +308,13 @@ void QskMenu::setSelectedIndex( int index )
|
||||
|
||||
QRectF QskMenu::cellRect( int index ) const
|
||||
{
|
||||
return effectiveSkinlet()->itemRect(
|
||||
return effectiveSkinlet()->subControlCell(
|
||||
this, contentsRect(), QskMenu::Cell, index );
|
||||
}
|
||||
|
||||
int QskMenu::indexAtPosition( const QPointF& pos ) const
|
||||
{
|
||||
return effectiveSkinlet()->itemIndexAt(
|
||||
return effectiveSkinlet()->subControlCellIndexAt(
|
||||
this, contentsRect(), QskMenu::Cell, pos );
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ static qreal qskMaxTextWidth( const QskMenu* menu )
|
||||
for ( int i = 0; i < menu->count(); i++ )
|
||||
{
|
||||
const auto value = menu->itemAt( i );
|
||||
|
||||
|
||||
const auto text = qskValueAt< QString >( menu, i );
|
||||
if( !text.isEmpty() )
|
||||
{
|
||||
@ -131,6 +131,10 @@ static QSGNode* qskUpdateTextNode( const QskMenu* menu,
|
||||
|
||||
static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode )
|
||||
{
|
||||
using Q = QskMenu;
|
||||
|
||||
const auto skinlet = menu->effectiveSkinlet();
|
||||
|
||||
auto node = rootNode ? rootNode->firstChild() : nullptr;
|
||||
QSGNode* lastNode = nullptr;
|
||||
|
||||
@ -140,11 +144,11 @@ static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode
|
||||
|
||||
{
|
||||
QskSkinStateChanger stateChanger( menu );
|
||||
if ( menu->currentIndex() == i )
|
||||
stateChanger.addStates( QskMenu::Selected );
|
||||
stateChanger.setStates(
|
||||
skinlet->subControlCellStates( menu, Q::Cell, i ) );
|
||||
|
||||
newNode = QskSkinlet::updateBoxNode(
|
||||
menu, node, menu->cellRect( i ), QskMenu::Cell );
|
||||
menu, node, menu->cellRect( i ), Q::Cell );
|
||||
}
|
||||
|
||||
if ( newNode )
|
||||
@ -196,15 +200,21 @@ static void qskUpdateItemNode(
|
||||
|
||||
static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode )
|
||||
{
|
||||
const auto spacing = menu->spacingHint( QskMenu::Cell );
|
||||
using Q = QskMenu;
|
||||
|
||||
const auto skinlet = menu->effectiveSkinlet();
|
||||
|
||||
const auto spacing = menu->spacingHint( Q::Cell );
|
||||
const auto graphicWidth = qskGraphicWidth( menu );
|
||||
const auto contentsRect = menu->contentsRect();
|
||||
|
||||
if ( rootNode == nullptr )
|
||||
rootNode = new QSGNode();
|
||||
|
||||
QSGNode* node = nullptr;
|
||||
|
||||
for( int i = 0; i < menu->count(); i++ )
|
||||
const auto count = skinlet->subControlCellCount( menu, Q::Cell );
|
||||
for( int i = 0; i < count; i++ )
|
||||
{
|
||||
if ( node == nullptr )
|
||||
node = rootNode->firstChild();
|
||||
@ -219,10 +229,11 @@ static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode )
|
||||
|
||||
{
|
||||
QskSkinStateChanger stateChanger( menu );
|
||||
if ( menu->currentIndex() == i )
|
||||
stateChanger.addStates( QskMenu::Selected );
|
||||
stateChanger.setStates(
|
||||
skinlet->subControlCellStates( menu, Q::Cell, i ) );
|
||||
|
||||
const auto cellRect = menu->cellRect( i );
|
||||
const auto cellRect = skinlet->subControlCell(
|
||||
menu, contentsRect, Q::Cell, i );
|
||||
|
||||
auto graphicRect = cellRect;
|
||||
graphicRect.setWidth( graphicWidth );
|
||||
@ -268,10 +279,11 @@ QRectF QskMenuSkinlet::subControlRect(
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QRectF QskMenuSkinlet::itemRect(
|
||||
QRectF QskMenuSkinlet::subControlCell(
|
||||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol subControl, int index ) const
|
||||
{
|
||||
// QskMenu::Text, QskMenu::Graphic ???
|
||||
if ( subControl == QskMenu::Cell )
|
||||
{
|
||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
||||
@ -285,43 +297,37 @@ QRectF QskMenuSkinlet::itemRect(
|
||||
return QRectF( r.x(), r.y() + index * h, r.width(), h );
|
||||
}
|
||||
|
||||
return Inherited::itemRect(
|
||||
return Inherited::subControlCell(
|
||||
skinnable, contentsRect, subControl, index );
|
||||
}
|
||||
|
||||
int QskMenuSkinlet::itemIndexAt( const QskSkinnable* skinnable,
|
||||
const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const
|
||||
int QskMenuSkinlet::subControlCellCount(
|
||||
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
// QskMenu::Text, QskMenu::Graphic ???
|
||||
if ( subControl == QskMenu::Cell )
|
||||
{
|
||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
||||
|
||||
const auto panelRect = menu->subControlContentsRect( QskMenu::Panel );
|
||||
if ( !panelRect.contains( pos ) )
|
||||
return -1;
|
||||
|
||||
/*
|
||||
A menu never has many items and we can simply iterate
|
||||
without being concerned about performance issues
|
||||
*/
|
||||
|
||||
const auto h = qskCellHeight( menu );
|
||||
|
||||
auto r = panelRect;
|
||||
r.setHeight( h );
|
||||
|
||||
for ( int i = 0; i < menu->count(); i++ )
|
||||
{
|
||||
if ( r.contains( pos ) )
|
||||
return i;
|
||||
|
||||
r.moveTop( r.bottom() );
|
||||
}
|
||||
|
||||
return -1;
|
||||
return menu->count();
|
||||
}
|
||||
|
||||
return Inherited::itemIndexAt( skinnable, rect, subControl, pos );
|
||||
return Inherited::subControlCellCount( skinnable, subControl );
|
||||
}
|
||||
|
||||
QskAspect::States QskMenuSkinlet::subControlCellStates(
|
||||
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const
|
||||
{
|
||||
auto states = Inherited::subControlCellStates( skinnable, subControl, index );
|
||||
|
||||
// QskMenu::Text, QskMenu::Graphic ???
|
||||
if ( subControl == QskMenu::Cell )
|
||||
{
|
||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
||||
if ( menu->currentIndex() == index )
|
||||
states |= QskMenu::Selected;
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
QSGNode* QskMenuSkinlet::updateContentsNode(
|
||||
|
@ -23,11 +23,13 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QRectF itemRect( const QskSkinnable*,
|
||||
QRectF subControlCell( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const override;
|
||||
|
||||
int itemIndexAt( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override;
|
||||
int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QskAspect::States subControlCellStates( const QskSkinnable*,
|
||||
QskAspect::Subcontrol, int index ) const override;
|
||||
|
||||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
@ -12,25 +12,20 @@
|
||||
class QskSkinStateChanger
|
||||
{
|
||||
public:
|
||||
QskSkinStateChanger( const QskSkinnable*,
|
||||
QskAspect::States = QskAspect::States() );
|
||||
|
||||
QskSkinStateChanger( const QskSkinnable* );
|
||||
~QskSkinStateChanger();
|
||||
|
||||
void addStates( QskAspect::States );
|
||||
void clearStates( QskAspect::States );
|
||||
void setStates( QskAspect::States );
|
||||
|
||||
private:
|
||||
QskSkinnable* m_skinnable;
|
||||
const QskAspect::States m_oldStates;
|
||||
};
|
||||
|
||||
inline QskSkinStateChanger::QskSkinStateChanger(
|
||||
const QskSkinnable* skinnable, QskAspect::States states )
|
||||
inline QskSkinStateChanger::QskSkinStateChanger( const QskSkinnable* skinnable )
|
||||
: m_skinnable( const_cast< QskSkinnable* >( skinnable ) )
|
||||
, m_oldStates( skinnable->skinStates() )
|
||||
{
|
||||
addStates( states );
|
||||
}
|
||||
|
||||
inline QskSkinStateChanger::~QskSkinStateChanger()
|
||||
@ -39,20 +34,10 @@ inline QskSkinStateChanger::~QskSkinStateChanger()
|
||||
m_skinnable->replaceSkinStates( m_oldStates );
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::addStates( QskAspect::States states )
|
||||
inline void QskSkinStateChanger::setStates( QskAspect::States states )
|
||||
{
|
||||
const auto newStates = m_oldStates | states;
|
||||
|
||||
if ( newStates != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( newStates );
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::clearStates( QskAspect::States states )
|
||||
{
|
||||
const auto newStates = m_oldStates & ~states;
|
||||
|
||||
if ( newStates != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( newStates );
|
||||
if ( states != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( states );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -581,19 +581,31 @@ QSizeF QskSkinlet::hintWithoutConstraint(
|
||||
return h;
|
||||
}
|
||||
|
||||
int QskSkinlet::itemIndexAt( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const
|
||||
int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable,
|
||||
const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const
|
||||
{
|
||||
/*
|
||||
slow default implementation to be overloaded when
|
||||
having many cells
|
||||
*/
|
||||
|
||||
const auto cellCount = subControlCellCount( skinnable, subControl );
|
||||
|
||||
for ( int i = 0; i < cellCount; i++ )
|
||||
{
|
||||
const auto cellRect = subControlCell( skinnable, rect, subControl, i );
|
||||
if ( cellRect.contains( pos ) )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QRectF QskSkinlet::itemRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const
|
||||
QskAspect::States QskSkinlet::subControlCellStates(
|
||||
const QskSkinnable* skinnable, QskAspect::Subcontrol, int index ) const
|
||||
{
|
||||
// When a subControl is for a unknown number of item, f.e. in a menu
|
||||
|
||||
Q_UNUSED( index )
|
||||
return QRectF();
|
||||
return skinnable->skinStates();
|
||||
}
|
||||
|
||||
#include "moc_QskSkinlet.cpp"
|
||||
|
@ -42,12 +42,17 @@ class QSK_EXPORT QskSkinlet
|
||||
virtual QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol ) const;
|
||||
|
||||
virtual QRectF itemRect( const QskSkinnable*,
|
||||
virtual QRectF subControlCell( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const;
|
||||
|
||||
virtual int itemIndexAt( const QskSkinnable*,
|
||||
virtual int subControlCellIndexAt( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const;
|
||||
|
||||
virtual int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const;
|
||||
|
||||
virtual QskAspect::States subControlCellStates( const QskSkinnable*,
|
||||
QskAspect::Subcontrol, int index ) const;
|
||||
|
||||
const QVector< quint8 >& nodeRoles() const;
|
||||
|
||||
void setOwnedBySkinnable( bool on );
|
||||
@ -154,4 +159,17 @@ inline QSizeF QskSkinlet::sizeHint(
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
inline QRectF QskSkinlet::subControlCell( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const
|
||||
{
|
||||
Q_UNUSED( index )
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
inline int QskSkinlet::subControlCellCount(
|
||||
const QskSkinnable*, QskAspect::Subcontrol ) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user