smooth state transitions for listbox row selections
This commit is contained in:
parent
ac4f190733
commit
3eb62bb692
@ -76,15 +76,10 @@ class QskListView::PrivateData
|
||||
inline void startTransitions( QskListView* listView, int row,
|
||||
QskAspect::States oldStates, QskAspect::States newStates )
|
||||
{
|
||||
/*
|
||||
working implementation can be found in
|
||||
https://github.com/uwerat/qskinny/tree/features/listview
|
||||
*/
|
||||
using Q = QskListView;
|
||||
|
||||
Q_UNUSED( listView );
|
||||
Q_UNUSED( row );
|
||||
Q_UNUSED( oldStates );
|
||||
Q_UNUSED( newStates );
|
||||
listView->startHintTransitions(
|
||||
{ Q::Cell, Q::Text }, oldStates, newStates, row );
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -204,7 +204,7 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
||||
for ( int row = listViewNode->rowMin(); row <= listViewNode->rowMax(); row++ )
|
||||
{
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ) );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ), row );
|
||||
|
||||
const auto rect = sampleRect( listView, listView->contentsRect(), Q::Cell, row );
|
||||
|
||||
@ -391,7 +391,7 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||
using namespace QskSGNode;
|
||||
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ) );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ), row );
|
||||
|
||||
QSGNode* newNode = nullptr;
|
||||
|
||||
|
@ -15,7 +15,7 @@ class QskSkinStateChanger
|
||||
QskSkinStateChanger( const QskSkinnable* );
|
||||
~QskSkinStateChanger();
|
||||
|
||||
void setStates( QskAspect::States );
|
||||
void setStates( QskAspect::States, int sampleIndex = -1 );
|
||||
void resetStates();
|
||||
|
||||
private:
|
||||
@ -34,16 +34,15 @@ inline QskSkinStateChanger::~QskSkinStateChanger()
|
||||
resetStates();
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::setStates( QskAspect::States states )
|
||||
inline void QskSkinStateChanger::setStates(
|
||||
QskAspect::States states, int sampleIndex )
|
||||
{
|
||||
if ( states != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( states );
|
||||
m_skinnable->replaceSkinStates( states, sampleIndex );
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::resetStates()
|
||||
{
|
||||
if ( m_oldStates != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( m_oldStates );
|
||||
m_skinnable->replaceSkinStates( m_oldStates, -1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -282,8 +282,6 @@ class QskSkinlet::PrivateData
|
||||
QskSkin* skin;
|
||||
QVector< quint8 > nodeRoles;
|
||||
|
||||
int animatorIndex = -1;
|
||||
|
||||
bool ownedBySkinnable : 1;
|
||||
};
|
||||
|
||||
@ -311,21 +309,6 @@ bool QskSkinlet::isOwnedBySkinnable() const
|
||||
return m_data->ownedBySkinnable;
|
||||
}
|
||||
|
||||
void QskSkinlet::setAnimatorIndex( int index )
|
||||
{
|
||||
m_data->animatorIndex = index;
|
||||
}
|
||||
|
||||
void QskSkinlet::resetAnimatorIndex()
|
||||
{
|
||||
m_data->animatorIndex = -1;
|
||||
}
|
||||
|
||||
int QskSkinlet::animatorIndex() const
|
||||
{
|
||||
return m_data->animatorIndex;
|
||||
}
|
||||
|
||||
void QskSkinlet::setNodeRoles( const QVector< quint8 >& nodeRoles )
|
||||
{
|
||||
m_data->nodeRoles = nodeRoles;
|
||||
@ -796,26 +779,7 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable,
|
||||
const auto newStates = sampleStates( skinnable, subControl, i );
|
||||
|
||||
QskSkinStateChanger stateChanger( skinnable );
|
||||
stateChanger.setStates( newStates );
|
||||
|
||||
class IndexChanger
|
||||
{
|
||||
public:
|
||||
inline IndexChanger( const QskSkinlet* skinlet, int index )
|
||||
: m_skinlet( const_cast< QskSkinlet* >( skinlet ) )
|
||||
{
|
||||
m_skinlet->setAnimatorIndex( index );
|
||||
}
|
||||
|
||||
inline ~IndexChanger()
|
||||
{
|
||||
m_skinlet->resetAnimatorIndex();
|
||||
}
|
||||
private:
|
||||
QskSkinlet* m_skinlet;
|
||||
};
|
||||
|
||||
IndexChanger indexChanger( this, i );
|
||||
stateChanger.setStates( newStates, i );
|
||||
|
||||
newNode = updateSampleNode( skinnable, subControl, i, node );
|
||||
}
|
||||
|
@ -71,10 +71,6 @@ class QSK_EXPORT QskSkinlet
|
||||
void setOwnedBySkinnable( bool on );
|
||||
bool isOwnedBySkinnable() const;
|
||||
|
||||
void setAnimatorIndex( int );
|
||||
void resetAnimatorIndex();
|
||||
int animatorIndex() const;
|
||||
|
||||
// Helper functions for creating nodes
|
||||
|
||||
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
|
||||
|
@ -248,6 +248,8 @@ class QskSkinnable::PrivateData
|
||||
QskSkinHintTable hintTable;
|
||||
QskHintAnimatorTable animators;
|
||||
|
||||
int sampleIndex = -1; // for the ugly QskSkinStateChanger hack
|
||||
|
||||
typedef std::map< QskAspect::Subcontrol, QskAspect::Subcontrol > ProxyMap;
|
||||
ProxyMap* subcontrolProxies = nullptr;
|
||||
|
||||
@ -993,11 +995,11 @@ QVariant QskSkinnable::animatedHint(
|
||||
|
||||
if ( !m_data->animators.isEmpty() )
|
||||
{
|
||||
const int index = effectiveSkinlet()->animatorIndex();
|
||||
const auto a = qskAnimatorAspect( aspect );
|
||||
|
||||
v = m_data->animators.currentValue( aspect, index );
|
||||
if ( !v.isValid() && index >= 0 )
|
||||
v = m_data->animators.currentValue( aspect, -1 );
|
||||
v = m_data->animators.currentValue( a, m_data->sampleIndex );
|
||||
if ( !v.isValid() && m_data->sampleIndex >= 0 )
|
||||
v = m_data->animators.currentValue( a, -1 );
|
||||
}
|
||||
|
||||
if ( status && v.isValid() )
|
||||
@ -1309,7 +1311,7 @@ void QskSkinnable::startHintTransition( QskAspect aspect, int index,
|
||||
aspect = qskAnimatorAspect( aspect );
|
||||
|
||||
#if DEBUG_ANIMATOR
|
||||
qDebug() << aspect << animationHint.duration;
|
||||
qDebug() << aspect << index << animationHint.duration;
|
||||
#endif
|
||||
|
||||
auto animator = m_data->animators.animator( aspect, index );
|
||||
@ -1328,9 +1330,20 @@ void QskSkinnable::setSkinStateFlag( QskAspect::State stateFlag, bool on )
|
||||
setSkinStates( newState );
|
||||
}
|
||||
|
||||
void QskSkinnable::replaceSkinStates( QskAspect::States newStates )
|
||||
void QskSkinnable::replaceSkinStates(
|
||||
QskAspect::States newStates, int sampleIndex )
|
||||
{
|
||||
/*
|
||||
Hack time: we might need different hints for a specific instance
|
||||
of a subcontrol ( f.e the selected row in a list box ), what is not
|
||||
supported by QskAspect.
|
||||
|
||||
As a workaround we use QskSkinStateChanger, that sets/restores this state/index
|
||||
while retrieving the skin hints.
|
||||
*/
|
||||
|
||||
m_data->skinStates = newStates;
|
||||
m_data->sampleIndex = sampleIndex; // needed to find specific animators
|
||||
}
|
||||
|
||||
void QskSkinnable::addSkinStates( QskAspect::States states )
|
||||
|
@ -39,6 +39,7 @@ class QskGraphic;
|
||||
class QskSkin;
|
||||
class QskSkinlet;
|
||||
class QskSkinHintTable;
|
||||
class QskSkinStateChanger;
|
||||
|
||||
class QSK_EXPORT QskSkinHintStatus
|
||||
{
|
||||
@ -149,8 +150,6 @@ class QSK_EXPORT QskSkinnable
|
||||
void addSkinStates( QskAspect::States );
|
||||
void clearSkinStates( QskAspect::States );
|
||||
|
||||
void replaceSkinStates( QskAspect::States );
|
||||
|
||||
bool hasSkinState( QskAspect::State ) const;
|
||||
QskAspect::States skinStates() const;
|
||||
|
||||
@ -281,6 +280,9 @@ class QSK_EXPORT QskSkinnable
|
||||
QVariant interpolatedHint( QskAspect, QskSkinHintStatus* ) const;
|
||||
const QVariant& storedHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
|
||||
|
||||
friend class QskSkinStateChanger;
|
||||
void replaceSkinStates( QskAspect::States, int sampleIndex = -1 );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user