Add auto-deletion functionality into LayoutAnimator which can be used to delete the item when its removal animation finishes. Emit a signal when the state of an item in the animator changes. Avoid repeatedly setting an item's geometry with the NoEffect effect. Added a DeadState into which items transition after their removal animation finishes or if they have not been added to the animator. When inserting an item with a fade in effect set the opacity to 0 if the item is a widget.
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=706933
This commit is contained in:
parent
b329ddb69a
commit
37b993d8ff
@ -46,10 +46,15 @@ public:
|
||||
|
||||
QHash<LayoutItem*,ItemGeometry> geometries;
|
||||
QHash<LayoutItem*,LayoutAnimator::State> states;
|
||||
|
||||
QPointer<QTimeLine> timeLine;
|
||||
|
||||
qreal lastValue;
|
||||
bool autoDeleteOnRemoval;
|
||||
|
||||
Private()
|
||||
: lastValue(0)
|
||||
, autoDeleteOnRemoval(false)
|
||||
{
|
||||
}
|
||||
|
||||
qreal delta(qreal currentValue) const
|
||||
{
|
||||
@ -73,6 +78,18 @@ public:
|
||||
|
||||
return newGeometry;
|
||||
}
|
||||
|
||||
void prepareItemForState( LayoutItem *item , LayoutAnimator::State state ) {
|
||||
|
||||
// opacity setting for widgets
|
||||
if ( state == InsertedState && effects[state] == LayoutAnimator::FadeInMoveEffect ) {
|
||||
Widget *widget = dynamic_cast<Widget*>(item->graphicsItem());
|
||||
|
||||
if ( widget ) {
|
||||
widget->setOpacity(0); // item is invisible immediately after insertion
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LayoutAnimator::LayoutAnimator(QObject* parent)
|
||||
@ -87,6 +104,39 @@ LayoutAnimator::~LayoutAnimator()
|
||||
delete d;
|
||||
}
|
||||
|
||||
void LayoutAnimator::setAutoDeleteOnRemoval(bool autoDelete)
|
||||
{
|
||||
if ( d->autoDeleteOnRemoval == autoDelete )
|
||||
return;
|
||||
|
||||
d->autoDeleteOnRemoval = autoDelete;
|
||||
|
||||
if ( autoDelete ) {
|
||||
connect( this , SIGNAL(stateChanged(LayoutItem*,State,State)) , this ,
|
||||
SLOT(itemAutoDeleter(LayoutItem*,State,State)) );
|
||||
} else {
|
||||
disconnect( this , SIGNAL(stateChanged(LayoutItem*,State,State)) , this ,
|
||||
SLOT(itemAutoDeleter(LayoutItem*,State,State)) );
|
||||
}
|
||||
}
|
||||
bool LayoutAnimator::autoDeleteOnRemoval() const
|
||||
{
|
||||
return d->autoDeleteOnRemoval;
|
||||
}
|
||||
void LayoutAnimator::itemAutoDeleter(LayoutItem *item , State oldState , State newState)
|
||||
{
|
||||
if ( oldState == RemovedState && newState == DeadState ) {
|
||||
|
||||
if ( item->graphicsItem() ) {
|
||||
item->graphicsItem()->scene()->removeItem( item->graphicsItem() );
|
||||
|
||||
if ( dynamic_cast<QGraphicsItem*>(item) != dynamic_cast<QGraphicsItem*>(item->graphicsItem()) )
|
||||
delete item->graphicsItem();
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
void LayoutAnimator::setEffect( State action , int effect )
|
||||
{
|
||||
d->effects[action] = effect;
|
||||
@ -96,13 +146,22 @@ int LayoutAnimator::effect(State action) const
|
||||
return d->effects[action];
|
||||
}
|
||||
|
||||
void LayoutAnimator::setCurrentState( LayoutItem* item , State action )
|
||||
void LayoutAnimator::setCurrentState( LayoutItem* item , State state )
|
||||
{
|
||||
d->states[item] = action;
|
||||
State oldState = d->states[item];
|
||||
|
||||
d->states[item] = state;
|
||||
d->prepareItemForState(item,state);
|
||||
|
||||
emit stateChanged(item,oldState,state);
|
||||
}
|
||||
LayoutAnimator::State LayoutAnimator::state( LayoutItem* item ) const
|
||||
{
|
||||
return d->states[item];
|
||||
if ( !d->states.contains(item) ) {
|
||||
return DeadState;
|
||||
} else {
|
||||
return d->states[item];
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutAnimator::setTimeLine(QTimeLine* timeLine)
|
||||
@ -121,6 +180,12 @@ void LayoutAnimator::setTimeLine(QTimeLine* timeLine)
|
||||
connect( d->timeLine , SIGNAL(finished()) , this ,
|
||||
SLOT(animationCompleted()) );
|
||||
}
|
||||
void LayoutAnimator::animationCompleted()
|
||||
{
|
||||
foreach( LayoutItem* item , d->states.keys() ) {
|
||||
animationFinished(item);
|
||||
}
|
||||
}
|
||||
QTimeLine* LayoutAnimator::timeLine() const
|
||||
{
|
||||
return d->timeLine;
|
||||
@ -153,12 +218,23 @@ void LayoutAnimator::moveEffectUpdateItem( qreal value , LayoutItem* item , Effe
|
||||
else if ( widget && effect == FadeOutMoveEffect )
|
||||
widget->setOpacity( qMax(0.0,widget->opacity()-d->delta(value)) );
|
||||
|
||||
item->setGeometry( d->interpolateGeometry(item,value) );
|
||||
|
||||
if ( effect == FadeInMoveEffect ) {
|
||||
const QRectF finalGeometry = d->geometries[item].endGeometry;
|
||||
|
||||
if ( item->geometry() != finalGeometry )
|
||||
item->setGeometry( finalGeometry );
|
||||
}
|
||||
else
|
||||
item->setGeometry( d->interpolateGeometry(item,value) );
|
||||
}
|
||||
|
||||
void LayoutAnimator::noEffectUpdateItem( qreal , LayoutItem* item )
|
||||
{
|
||||
item->setGeometry( d->geometries[item].endGeometry );
|
||||
const QRectF finalGeometry = d->geometries[item].endGeometry;
|
||||
|
||||
if ( item->geometry() != finalGeometry )
|
||||
item->setGeometry( finalGeometry );
|
||||
}
|
||||
|
||||
void LayoutAnimator::fadeEffectUpdateItem( qreal value , LayoutItem* item )
|
||||
@ -184,17 +260,19 @@ void LayoutAnimator::fadeEffectUpdateItem( qreal value , LayoutItem* item )
|
||||
|
||||
void LayoutAnimator::animationFinished(LayoutItem* item)
|
||||
{
|
||||
switch (d->states[item])
|
||||
switch ( state(item) )
|
||||
{
|
||||
case InsertedState:
|
||||
d->states[item] = NormalState;
|
||||
setCurrentState(item,StandardState);
|
||||
break;
|
||||
case RemovedState:
|
||||
d->states.remove(item);
|
||||
d->geometries.remove(item);
|
||||
|
||||
emit stateChanged( item , RemovedState , DeadState );
|
||||
break;
|
||||
case NormalState:
|
||||
// do nothing
|
||||
case StandardState:
|
||||
d->geometries[item].startGeometry = d->geometries[item].endGeometry;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
|
@ -44,7 +44,7 @@ class LayoutItem;
|
||||
*
|
||||
* animator->setTimeLine(timeLine);
|
||||
* animator->setEffect( LayoutAnimator::InsertedState , LayoutAnimator::FadeInMoveEffect );
|
||||
* animator->setEffect( LayoutAnimator::NormalState , LayoutAnimator::MoveEffect );
|
||||
* animator->setEffect( LayoutAnimator::StandardState , LayoutAnimator::MoveEffect );
|
||||
* animator->setEffect( LayoutAnimator::RemovedState , LayoutAnimator::FadeOutMoveEffect );
|
||||
* myLayout->setAnimator(animator);
|
||||
*
|
||||
@ -69,7 +69,7 @@ public:
|
||||
/**
|
||||
* State for an item which has recently been added to a layout.
|
||||
* When the animation completes, the item's state will change to
|
||||
* NormalState
|
||||
* StandardState
|
||||
*/
|
||||
InsertedState,
|
||||
/**
|
||||
@ -77,13 +77,24 @@ public:
|
||||
* Items will remain in this state until it is explicitly changed
|
||||
* via setCurrentState()
|
||||
*/
|
||||
NormalState,
|
||||
StandardState,
|
||||
/**
|
||||
* State for an item which is being removed from a layout.
|
||||
* State for an item which is currently being removed from a layout.
|
||||
* When the animation completes, the item will be removed from the
|
||||
* animator and its state will be undefined.
|
||||
*/
|
||||
RemovedState
|
||||
RemovedState,
|
||||
/**
|
||||
* State for an item whoose geometry is not managed by the animator.
|
||||
*
|
||||
* All LayoutItems are initially in this state and are moved into a
|
||||
* different state ( usually InsertedState ) by calling
|
||||
* setCurrentState( item , state )
|
||||
*
|
||||
* An item transitions into this state when the animation completes
|
||||
* whilst the item is in RemovedState
|
||||
*/
|
||||
DeadState
|
||||
};
|
||||
|
||||
/**
|
||||
@ -146,7 +157,8 @@ public:
|
||||
/**
|
||||
* Sets the new geometry for a layout item.
|
||||
* The item will animate from its current geometry to @p geometry, using
|
||||
* the effect specified in setEffect()
|
||||
* the effect specified in setEffect() for the state currently associated
|
||||
* with @p item
|
||||
*/
|
||||
virtual void setGeometry( LayoutItem* item , const QRectF& geometry );
|
||||
|
||||
@ -159,12 +171,29 @@ public:
|
||||
/** Returns the QTimeLine used by this animator. */
|
||||
QTimeLine* timeLine() const;
|
||||
|
||||
/**
|
||||
* Convenience feature which causes LayoutItems and their associated
|
||||
* QGraphicsItems to be automatically deleted when their removal
|
||||
* animation finishes.
|
||||
*
|
||||
* The default is false.
|
||||
*/
|
||||
void setAutoDeleteOnRemoval(bool autoDelete);
|
||||
/** See setAutoDeleteOnRemoval() */
|
||||
bool autoDeleteOnRemoval() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/** This signal is emitted when the state of an item in the animator changes. */
|
||||
void stateChanged( LayoutItem *item , State oldState , State newState );
|
||||
|
||||
protected:
|
||||
virtual void updateItem( qreal value , LayoutItem* item );
|
||||
|
||||
private slots:
|
||||
void valueChanged(qreal value);
|
||||
|
||||
void animationCompleted();
|
||||
void itemAutoDeleter( LayoutItem *item , State oldState , State newState );
|
||||
|
||||
private:
|
||||
void moveEffectUpdateItem(qreal value,LayoutItem* item,Effect effect);
|
||||
void noEffectUpdateItem(qreal value,LayoutItem* item);
|
||||
|
Loading…
Reference in New Issue
Block a user