add AnimationEffect::set() and ::cancel()
This will allow to sue the AnimationEffect class for (temorarily) persistent changes like required by the translucency effect REVIEW: 109211
This commit is contained in:
parent
9aef5b85a0
commit
39499de9cc
5 changed files with 62 additions and 11 deletions
|
@ -30,11 +30,11 @@ AniData::AniData()
|
|||
attribute = AnimationEffect::Opacity;
|
||||
windowType = (NET::WindowTypeMask)0;
|
||||
duration = time = meta = startTime = 0;
|
||||
waitAtSource = false;
|
||||
waitAtSource = keepAtTarget = false;
|
||||
}
|
||||
|
||||
AniData::AniData(AnimationEffect::Attribute a, int meta, int ms, const FPx2 &to,
|
||||
QEasingCurve curve, int delay, const FPx2 &from, bool waitAtSource )
|
||||
QEasingCurve curve, int delay, const FPx2 &from, bool waitAtSource, bool keepAtTarget )
|
||||
{
|
||||
attribute = a;
|
||||
this->from = from;
|
||||
|
@ -44,6 +44,7 @@ AniData::AniData(AnimationEffect::Attribute a, int meta, int ms, const FPx2 &to,
|
|||
time = 0;
|
||||
this->meta = meta;
|
||||
this->waitAtSource = waitAtSource;
|
||||
this->keepAtTarget = keepAtTarget;
|
||||
startTime = AnimationEffect::clock() + delay;
|
||||
}
|
||||
|
||||
|
@ -58,6 +59,8 @@ AniData::AniData(const AniData &other)
|
|||
customCurve = other.customCurve;
|
||||
windowType = other.windowType;
|
||||
meta = other.meta;
|
||||
waitAtSource = other.waitAtSource;
|
||||
keepAtTarget = other.keepAtTarget;
|
||||
startTime = other.startTime;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class AniData {
|
|||
public:
|
||||
AniData();
|
||||
AniData(AnimationEffect::Attribute a, int meta, int ms, const FPx2 &to,
|
||||
QEasingCurve curve, int delay, const FPx2 &from, bool waitAtSource );
|
||||
QEasingCurve curve, int delay, const FPx2 &from, bool waitAtSource, bool keepAtTarget = false);
|
||||
AniData(const AniData &other);
|
||||
explicit AniData(const QString &str);
|
||||
inline void addTime(int t) { time += t; }
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
uint meta;
|
||||
qint64 startTime;
|
||||
NET::WindowTypeMask windowType;
|
||||
bool waitAtSource;
|
||||
bool waitAtSource, keepAtTarget;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -74,7 +74,7 @@ bool AnimationEffect::isActive() const
|
|||
#define RELATIVE_XY(_FIELD_) const bool relative[2] = { static_cast<bool>(metaData(Relative##_FIELD_##X, meta)), \
|
||||
static_cast<bool>(metaData(Relative##_FIELD_##Y, meta)) }
|
||||
|
||||
void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve, int delay, FPx2 from )
|
||||
quint64 AnimationEffect::p_animate( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve, int delay, FPx2 from, bool keepAtTarget )
|
||||
{
|
||||
const bool waitAtSource = from.isValid();
|
||||
if (a < NonFloatBase) {
|
||||
|
@ -179,7 +179,8 @@ void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms,
|
|||
AniMap::iterator it = d->m_animations.find(w);
|
||||
if (it == d->m_animations.end())
|
||||
it = d->m_animations.insert(w, QPair<QList<AniData>, QRect>(QList<AniData>(), QRect()));
|
||||
it->first.append(AniData(a, meta, ms, to, curve, delay, from, waitAtSource));
|
||||
it->first.append(AniData(a, meta, ms, to, curve, delay, from, waitAtSource, keepAtTarget));
|
||||
quint64 ret_id = quint64(&it->first.last());
|
||||
it->second = QRect();
|
||||
|
||||
d->m_animationsTouched = true;
|
||||
|
@ -192,6 +193,29 @@ void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms,
|
|||
else {
|
||||
triggerRepaint();
|
||||
}
|
||||
return ret_id;
|
||||
}
|
||||
|
||||
bool AnimationEffect::cancel(quint64 animationId)
|
||||
{
|
||||
Q_D(AnimationEffect);
|
||||
for (AniMap::iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end(); entry != mapEnd; ++entry) {
|
||||
for (QList<AniData>::iterator anim = entry->first.begin(), animEnd = entry->first.end(); anim != animEnd; ++anim) {
|
||||
if (quint64(&(*anim)) == animationId) {
|
||||
entry->first.erase(anim); // remove the animation
|
||||
if (entry->first.isEmpty()) { // no other animations on the window, release it.
|
||||
const int i = d->m_zombies.indexOf(entry.key());
|
||||
if ( i > -1 ) {
|
||||
d->m_zombies.removeAt( i );
|
||||
entry.key()->unrefWindow();
|
||||
}
|
||||
d->m_animations.erase(entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
||||
|
@ -221,7 +245,7 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
|||
anim->addTime(time);
|
||||
}
|
||||
|
||||
if (anim->time < anim->duration) {
|
||||
if (anim->time < anim->duration || anim->keepAtTarget) {
|
||||
// if (anim->attribute != Brightness && anim->attribute != Saturation && anim->attribute != Opacity)
|
||||
// transformed = true;
|
||||
d->m_animated = true;
|
||||
|
@ -540,14 +564,18 @@ float AnimationEffect::interpolated( const AniData &a, int i ) const
|
|||
{
|
||||
if (a.startTime > clock())
|
||||
return a.from[i];
|
||||
return a.from[i] + a.curve.valueForProgress( ((float)a.time)/a.duration )*(a.to[i] - a.from[i]);
|
||||
if (a.time < a.duration)
|
||||
return a.from[i] + a.curve.valueForProgress( ((float)a.time)/a.duration )*(a.to[i] - a.from[i]);
|
||||
return a.to[i]; // we're done and "waiting" at the target value
|
||||
}
|
||||
|
||||
float AnimationEffect::progress( const AniData &a ) const
|
||||
{
|
||||
if (a.startTime > clock())
|
||||
return 0.0;
|
||||
return a.curve.valueForProgress( ((float)a.time)/a.duration );
|
||||
if (a.time < a.duration)
|
||||
return a.curve.valueForProgress( ((float)a.time)/a.duration );
|
||||
return 1.0; // we're done and "waiting" at the target value
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -155,13 +155,32 @@ protected:
|
|||
* @param shape - How the animation progresses, eg. Linear progresses constantly while Exponential start slow and becomes very fast in the end
|
||||
* @param delay - When the animation will start compared to "now" (the window will remain at the "from" position until then)
|
||||
* @param from - the starting value, the default is invalid, ie. the attribute for the window is not transformed in the beginning
|
||||
* @return an ID that you can use to cancel a running animation
|
||||
*/
|
||||
void animate( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve = QEasingCurve(), int delay = 0, FPx2 from = FPx2() );
|
||||
quint64 animate( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve = QEasingCurve(), int delay = 0, FPx2 from = FPx2() )
|
||||
{ return p_animate(w, a, meta, ms, to, curve, delay, from, false); }
|
||||
|
||||
/**
|
||||
* Equal to ::animate() with one important difference:
|
||||
* The target value for the attribute is kept until you ::cancel() this animation
|
||||
* @return an ID that you need to use to cancel this manipulation
|
||||
*/
|
||||
quint64 set( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve = QEasingCurve(), int delay = 0, FPx2 from = FPx2() )
|
||||
{ return p_animate(w, a, meta, ms, to, curve, delay, from, true); }
|
||||
|
||||
/**
|
||||
* Called whenever an animation end, passes the transformed @class EffectWindow @enum Attribute and originally supplied @param meta
|
||||
* You can reimplement it to keep a constant transformation for the window (ie. keep it a this opacity or position) or to start another animation
|
||||
*/
|
||||
virtual void animationEnded( EffectWindow *, Attribute, uint meta ) {Q_UNUSED(meta);}
|
||||
|
||||
/**
|
||||
* Cancel a running animation. @return true if an animation for @p animationId was found (and canceled)
|
||||
* NOTICE that there is NO animated reset of the original value. You'll have to provide that with a second animation
|
||||
* NOTICE as well that this will eventually release a Deleted window.
|
||||
* If you intend to run another animation on the (Deleted) window, you have to do that before cancelling the old animation (to keep the window around)
|
||||
*/
|
||||
bool cancel(quint64 animationId);
|
||||
/**
|
||||
* Called if the transformed @enum Attribute is Generic. You should reimplement it if you transform this "Attribute".
|
||||
* You could use the meta information to eg. support more than one additional animations
|
||||
|
@ -170,6 +189,7 @@ protected:
|
|||
{Q_UNUSED(w); Q_UNUSED(data); Q_UNUSED(progress); Q_UNUSED(meta);}
|
||||
|
||||
private:
|
||||
quint64 p_animate( EffectWindow *w, Attribute a, uint meta, int ms, FPx2 to, QEasingCurve curve, int delay, FPx2 from, bool keepAtTarget );
|
||||
QRect clipRect(const QRect &windowRect, const AniData&) const;
|
||||
void clipWindow(const EffectWindow *, const AniData &, WindowQuadList &) const;
|
||||
float interpolated( const AniData&, int i = 0 ) const;
|
||||
|
|
|
@ -170,7 +170,7 @@ X-KDE-Library=kwin4_effect_cooleffect
|
|||
|
||||
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
|
||||
#define KWIN_EFFECT_API_VERSION_MAJOR 0
|
||||
#define KWIN_EFFECT_API_VERSION_MINOR 220
|
||||
#define KWIN_EFFECT_API_VERSION_MINOR 221
|
||||
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
|
||||
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
|
||||
|
||||
|
|
Loading…
Reference in a new issue