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 )
|
if ( rowSelected >= rowMin && rowSelected <= rowMax )
|
||||||
{
|
{
|
||||||
QskSkinStateChanger stateChanger( listView );
|
QskSkinStateChanger stateChanger( listView );
|
||||||
stateChanger.addStates( QskListView::Selected );
|
stateChanger.setStates( listView->skinStates() | QskListView::Selected );
|
||||||
|
|
||||||
const QColor color = listView->color( QskListView::Cell );
|
const QColor color = listView->color( QskListView::Cell );
|
||||||
|
|
||||||
|
@ -436,12 +436,12 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||||
{
|
{
|
||||||
using namespace QskSGNode;
|
using namespace QskSGNode;
|
||||||
|
|
||||||
QskAspect::States rowStates;
|
auto rowStates = listView->skinStates();
|
||||||
if ( row == listView->selectedRow() )
|
if ( row == listView->selectedRow() )
|
||||||
rowStates |= QskListView::Selected;
|
rowStates |= QskListView::Selected;
|
||||||
|
|
||||||
QskSkinStateChanger stateChanger( listView );
|
QskSkinStateChanger stateChanger( listView );
|
||||||
stateChanger.addStates( rowStates );
|
stateChanger.setStates( rowStates );
|
||||||
|
|
||||||
QSGNode* newNode = nullptr;
|
QSGNode* newNode = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -308,13 +308,13 @@ void QskMenu::setSelectedIndex( int index )
|
||||||
|
|
||||||
QRectF QskMenu::cellRect( int index ) const
|
QRectF QskMenu::cellRect( int index ) const
|
||||||
{
|
{
|
||||||
return effectiveSkinlet()->itemRect(
|
return effectiveSkinlet()->subControlCell(
|
||||||
this, contentsRect(), QskMenu::Cell, index );
|
this, contentsRect(), QskMenu::Cell, index );
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskMenu::indexAtPosition( const QPointF& pos ) const
|
int QskMenu::indexAtPosition( const QPointF& pos ) const
|
||||||
{
|
{
|
||||||
return effectiveSkinlet()->itemIndexAt(
|
return effectiveSkinlet()->subControlCellIndexAt(
|
||||||
this, contentsRect(), QskMenu::Cell, pos );
|
this, contentsRect(), QskMenu::Cell, pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ static qreal qskMaxTextWidth( const QskMenu* menu )
|
||||||
for ( int i = 0; i < menu->count(); i++ )
|
for ( int i = 0; i < menu->count(); i++ )
|
||||||
{
|
{
|
||||||
const auto value = menu->itemAt( i );
|
const auto value = menu->itemAt( i );
|
||||||
|
|
||||||
const auto text = qskValueAt< QString >( menu, i );
|
const auto text = qskValueAt< QString >( menu, i );
|
||||||
if( !text.isEmpty() )
|
if( !text.isEmpty() )
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,10 @@ static QSGNode* qskUpdateTextNode( const QskMenu* menu,
|
||||||
|
|
||||||
static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode )
|
static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode )
|
||||||
{
|
{
|
||||||
|
using Q = QskMenu;
|
||||||
|
|
||||||
|
const auto skinlet = menu->effectiveSkinlet();
|
||||||
|
|
||||||
auto node = rootNode ? rootNode->firstChild() : nullptr;
|
auto node = rootNode ? rootNode->firstChild() : nullptr;
|
||||||
QSGNode* lastNode = nullptr;
|
QSGNode* lastNode = nullptr;
|
||||||
|
|
||||||
|
@ -140,11 +144,11 @@ static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode
|
||||||
|
|
||||||
{
|
{
|
||||||
QskSkinStateChanger stateChanger( menu );
|
QskSkinStateChanger stateChanger( menu );
|
||||||
if ( menu->currentIndex() == i )
|
stateChanger.setStates(
|
||||||
stateChanger.addStates( QskMenu::Selected );
|
skinlet->subControlCellStates( menu, Q::Cell, i ) );
|
||||||
|
|
||||||
newNode = QskSkinlet::updateBoxNode(
|
newNode = QskSkinlet::updateBoxNode(
|
||||||
menu, node, menu->cellRect( i ), QskMenu::Cell );
|
menu, node, menu->cellRect( i ), Q::Cell );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( newNode )
|
if ( newNode )
|
||||||
|
@ -196,15 +200,21 @@ static void qskUpdateItemNode(
|
||||||
|
|
||||||
static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode )
|
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 graphicWidth = qskGraphicWidth( menu );
|
||||||
|
const auto contentsRect = menu->contentsRect();
|
||||||
|
|
||||||
if ( rootNode == nullptr )
|
if ( rootNode == nullptr )
|
||||||
rootNode = new QSGNode();
|
rootNode = new QSGNode();
|
||||||
|
|
||||||
QSGNode* node = nullptr;
|
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 )
|
if ( node == nullptr )
|
||||||
node = rootNode->firstChild();
|
node = rootNode->firstChild();
|
||||||
|
@ -219,10 +229,11 @@ static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode )
|
||||||
|
|
||||||
{
|
{
|
||||||
QskSkinStateChanger stateChanger( menu );
|
QskSkinStateChanger stateChanger( menu );
|
||||||
if ( menu->currentIndex() == i )
|
stateChanger.setStates(
|
||||||
stateChanger.addStates( QskMenu::Selected );
|
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;
|
auto graphicRect = cellRect;
|
||||||
graphicRect.setWidth( graphicWidth );
|
graphicRect.setWidth( graphicWidth );
|
||||||
|
@ -268,10 +279,11 @@ QRectF QskMenuSkinlet::subControlRect(
|
||||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskMenuSkinlet::itemRect(
|
QRectF QskMenuSkinlet::subControlCell(
|
||||||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||||
QskAspect::Subcontrol subControl, int index ) const
|
QskAspect::Subcontrol subControl, int index ) const
|
||||||
{
|
{
|
||||||
|
// QskMenu::Text, QskMenu::Graphic ???
|
||||||
if ( subControl == QskMenu::Cell )
|
if ( subControl == QskMenu::Cell )
|
||||||
{
|
{
|
||||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
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 QRectF( r.x(), r.y() + index * h, r.width(), h );
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::itemRect(
|
return Inherited::subControlCell(
|
||||||
skinnable, contentsRect, subControl, index );
|
skinnable, contentsRect, subControl, index );
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskMenuSkinlet::itemIndexAt( const QskSkinnable* skinnable,
|
int QskMenuSkinlet::subControlCellCount(
|
||||||
const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const
|
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const
|
||||||
{
|
{
|
||||||
|
// QskMenu::Text, QskMenu::Graphic ???
|
||||||
if ( subControl == QskMenu::Cell )
|
if ( subControl == QskMenu::Cell )
|
||||||
{
|
{
|
||||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
const auto menu = static_cast< const QskMenu* >( skinnable );
|
||||||
|
return menu->count();
|
||||||
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 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(
|
QSGNode* QskMenuSkinlet::updateContentsNode(
|
||||||
|
|
|
@ -23,11 +23,13 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
|
||||||
QRectF subControlRect( const QskSkinnable*,
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
QRectF itemRect( const QskSkinnable*,
|
QRectF subControlCell( const QskSkinnable*,
|
||||||
const QRectF&, QskAspect::Subcontrol, int index ) const override;
|
const QRectF&, QskAspect::Subcontrol, int index ) const override;
|
||||||
|
|
||||||
int itemIndexAt( const QskSkinnable*,
|
int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
|
||||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override;
|
|
||||||
|
QskAspect::States subControlCellStates( const QskSkinnable*,
|
||||||
|
QskAspect::Subcontrol, int index ) const override;
|
||||||
|
|
||||||
QSizeF sizeHint( const QskSkinnable*,
|
QSizeF sizeHint( const QskSkinnable*,
|
||||||
Qt::SizeHint, const QSizeF& ) const override;
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
|
@ -12,25 +12,20 @@
|
||||||
class QskSkinStateChanger
|
class QskSkinStateChanger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QskSkinStateChanger( const QskSkinnable*,
|
QskSkinStateChanger( const QskSkinnable* );
|
||||||
QskAspect::States = QskAspect::States() );
|
|
||||||
|
|
||||||
~QskSkinStateChanger();
|
~QskSkinStateChanger();
|
||||||
|
|
||||||
void addStates( QskAspect::States );
|
void setStates( QskAspect::States );
|
||||||
void clearStates( QskAspect::States );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QskSkinnable* m_skinnable;
|
QskSkinnable* m_skinnable;
|
||||||
const QskAspect::States m_oldStates;
|
const QskAspect::States m_oldStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QskSkinStateChanger::QskSkinStateChanger(
|
inline QskSkinStateChanger::QskSkinStateChanger( const QskSkinnable* skinnable )
|
||||||
const QskSkinnable* skinnable, QskAspect::States states )
|
|
||||||
: m_skinnable( const_cast< QskSkinnable* >( skinnable ) )
|
: m_skinnable( const_cast< QskSkinnable* >( skinnable ) )
|
||||||
, m_oldStates( skinnable->skinStates() )
|
, m_oldStates( skinnable->skinStates() )
|
||||||
{
|
{
|
||||||
addStates( states );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QskSkinStateChanger::~QskSkinStateChanger()
|
inline QskSkinStateChanger::~QskSkinStateChanger()
|
||||||
|
@ -39,20 +34,10 @@ inline QskSkinStateChanger::~QskSkinStateChanger()
|
||||||
m_skinnable->replaceSkinStates( m_oldStates );
|
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 ( states != m_skinnable->skinStates() )
|
||||||
|
m_skinnable->replaceSkinStates( 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -581,19 +581,31 @@ QSizeF QskSkinlet::hintWithoutConstraint(
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskSkinlet::itemIndexAt( const QskSkinnable*,
|
int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable,
|
||||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskSkinlet::itemRect( const QskSkinnable*,
|
QskAspect::States QskSkinlet::subControlCellStates(
|
||||||
const QRectF&, QskAspect::Subcontrol, int index ) const
|
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 )
|
Q_UNUSED( index )
|
||||||
return QRectF();
|
return skinnable->skinStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskSkinlet.cpp"
|
#include "moc_QskSkinlet.cpp"
|
||||||
|
|
|
@ -42,12 +42,17 @@ class QSK_EXPORT QskSkinlet
|
||||||
virtual QRectF subControlRect( const QskSkinnable*,
|
virtual QRectF subControlRect( const QskSkinnable*,
|
||||||
const QRectF&, QskAspect::Subcontrol ) const;
|
const QRectF&, QskAspect::Subcontrol ) const;
|
||||||
|
|
||||||
virtual QRectF itemRect( const QskSkinnable*,
|
virtual QRectF subControlCell( const QskSkinnable*,
|
||||||
const QRectF&, QskAspect::Subcontrol, int index ) const;
|
const QRectF&, QskAspect::Subcontrol, int index ) const;
|
||||||
|
|
||||||
virtual int itemIndexAt( const QskSkinnable*,
|
virtual int subControlCellIndexAt( const QskSkinnable*,
|
||||||
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const;
|
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;
|
const QVector< quint8 >& nodeRoles() const;
|
||||||
|
|
||||||
void setOwnedBySkinnable( bool on );
|
void setOwnedBySkinnable( bool on );
|
||||||
|
@ -154,4 +159,17 @@ inline QSizeF QskSkinlet::sizeHint(
|
||||||
return QSizeF();
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue