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