effects/animationeffect: clean up the code a bit
This commit is contained in:
parent
8ca94eed44
commit
f10a93ce1c
1 changed files with 272 additions and 289 deletions
|
@ -229,6 +229,7 @@ quint64 AnimationEffect::p_animate(EffectWindow *w, Attribute a, uint meta, int
|
||||||
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
||||||
it = d->m_animations.emplace(std::make_pair(w, std::pair<std::vector<AniData>, QRect>{})).first;
|
it = d->m_animations.emplace(std::make_pair(w, std::pair<std::vector<AniData>, QRect>{})).first;
|
||||||
}
|
}
|
||||||
|
auto &[animations, rect] = it->second;
|
||||||
|
|
||||||
std::shared_ptr<FullScreenEffectLock> fullscreen;
|
std::shared_ptr<FullScreenEffectLock> fullscreen;
|
||||||
if (fullScreenEffect) {
|
if (fullScreenEffect) {
|
||||||
|
@ -243,7 +244,7 @@ quint64 AnimationEffect::p_animate(EffectWindow *w, Attribute a, uint meta, int
|
||||||
CrossFadeEffect::redirect(w);
|
CrossFadeEffect::redirect(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second.first.push_back(AniData(
|
animations.push_back(AniData(
|
||||||
a, // Attribute
|
a, // Attribute
|
||||||
meta, // Metadata
|
meta, // Metadata
|
||||||
to, // Target
|
to, // Target
|
||||||
|
@ -255,7 +256,7 @@ quint64 AnimationEffect::p_animate(EffectWindow *w, Attribute a, uint meta, int
|
||||||
shader));
|
shader));
|
||||||
|
|
||||||
const quint64 ret_id = ++d->m_animCounter;
|
const quint64 ret_id = ++d->m_animCounter;
|
||||||
AniData &animation = it->second.first.back();
|
AniData &animation = animations.back();
|
||||||
animation.id = ret_id;
|
animation.id = ret_id;
|
||||||
|
|
||||||
animation.visibleRef = EffectWindowVisibleRef(w, EffectWindow::PAINT_DISABLED_BY_MINIMIZE | EffectWindow::PAINT_DISABLED_BY_DESKTOP | EffectWindow::PAINT_DISABLED);
|
animation.visibleRef = EffectWindowVisibleRef(w, EffectWindow::PAINT_DISABLED_BY_MINIMIZE | EffectWindow::PAINT_DISABLED_BY_DESKTOP | EffectWindow::PAINT_DISABLED);
|
||||||
|
@ -271,7 +272,7 @@ quint64 AnimationEffect::p_animate(EffectWindow *w, Attribute a, uint meta, int
|
||||||
animation.terminationFlags |= TerminateAtTarget;
|
animation.terminationFlags |= TerminateAtTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second.second = QRect();
|
rect = QRect();
|
||||||
|
|
||||||
d->m_animationsTouched = true;
|
d->m_animationsTouched = true;
|
||||||
|
|
||||||
|
@ -296,15 +297,14 @@ bool AnimationEffect::retarget(quint64 animationId, FPx2 newTarget, int newRemai
|
||||||
if (animationId == d->m_justEndedAnimation) {
|
if (animationId == d->m_justEndedAnimation) {
|
||||||
return false; // this is just ending, do not try to retarget it
|
return false; // this is just ending, do not try to retarget it
|
||||||
}
|
}
|
||||||
for (AniMap::iterator entry = d->m_animations.begin(),
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
mapEnd = d->m_animations.end();
|
auto &[animations, rect] = pair;
|
||||||
entry != mapEnd; ++entry) {
|
const auto anim = std::ranges::find_if(animations, [animationId](const auto &anim) {
|
||||||
for (auto anim = entry->second.first.begin(),
|
return anim.id == animationId;
|
||||||
animEnd = entry->second.first.end();
|
});
|
||||||
anim != animEnd; ++anim) {
|
if (anim != animations.end()) {
|
||||||
if (anim->id == animationId) {
|
|
||||||
anim->from.set(interpolated(*anim, 0), interpolated(*anim, 1));
|
anim->from.set(interpolated(*anim, 0), interpolated(*anim, 1));
|
||||||
validate(anim->attribute, anim->meta, nullptr, &newTarget, entry->first);
|
validate(anim->attribute, anim->meta, nullptr, &newTarget, window);
|
||||||
anim->to.set(newTarget[0], newTarget[1]);
|
anim->to.set(newTarget[0], newTarget[1]);
|
||||||
|
|
||||||
anim->timeLine.setDirection(TimeLine::Forward);
|
anim->timeLine.setDirection(TimeLine::Forward);
|
||||||
|
@ -312,13 +312,12 @@ bool AnimationEffect::retarget(quint64 animationId, FPx2 newTarget, int newRemai
|
||||||
anim->timeLine.reset();
|
anim->timeLine.reset();
|
||||||
|
|
||||||
if (anim->attribute == CrossFadePrevious) {
|
if (anim->attribute == CrossFadePrevious) {
|
||||||
CrossFadeEffect::redirect(entry->first);
|
CrossFadeEffect::redirect(window);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return false; // no animation found
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimationEffect::freezeInTime(quint64 animationId, qint64 frozenTime)
|
bool AnimationEffect::freezeInTime(quint64 animationId, qint64 frozenTime)
|
||||||
|
@ -328,13 +327,12 @@ bool AnimationEffect::freezeInTime(quint64 animationId, qint64 frozenTime)
|
||||||
if (animationId == d->m_justEndedAnimation) {
|
if (animationId == d->m_justEndedAnimation) {
|
||||||
return false; // this is just ending, do not try to retarget it
|
return false; // this is just ending, do not try to retarget it
|
||||||
}
|
}
|
||||||
for (AniMap::iterator entry = d->m_animations.begin(),
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
mapEnd = d->m_animations.end();
|
auto &[animations, rect] = pair;
|
||||||
entry != mapEnd; ++entry) {
|
const auto anim = std::ranges::find_if(animations, [animationId](const auto &anim) {
|
||||||
for (auto anim = entry->second.first.begin(),
|
return anim.id == animationId;
|
||||||
animEnd = entry->second.first.end();
|
});
|
||||||
anim != animEnd; ++anim) {
|
if (anim != animations.end()) {
|
||||||
if (anim->id == animationId) {
|
|
||||||
if (frozenTime >= 0) {
|
if (frozenTime >= 0) {
|
||||||
anim->timeLine.setElapsed(std::chrono::milliseconds(frozenTime));
|
anim->timeLine.setElapsed(std::chrono::milliseconds(frozenTime));
|
||||||
}
|
}
|
||||||
|
@ -342,8 +340,7 @@ bool AnimationEffect::freezeInTime(quint64 animationId, qint64 frozenTime)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return false; // no animation found
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimationEffect::redirect(quint64 animationId, Direction direction, TerminationFlags terminationFlags)
|
bool AnimationEffect::redirect(quint64 animationId, Direction direction, TerminationFlags terminationFlags)
|
||||||
|
@ -352,31 +349,24 @@ bool AnimationEffect::redirect(quint64 animationId, Direction direction, Termina
|
||||||
if (animationId == d->m_justEndedAnimation) {
|
if (animationId == d->m_justEndedAnimation) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
for (auto entryIt = d->m_animations.begin(); entryIt != d->m_animations.end(); ++entryIt) {
|
auto &[animations, rect] = pair;
|
||||||
auto animIt = std::find_if(entryIt->second.first.begin(), entryIt->second.first.end(),
|
const auto anim = std::ranges::find_if(animations, [animationId](const auto &anim) {
|
||||||
[animationId](AniData &anim) {
|
|
||||||
return anim.id == animationId;
|
return anim.id == animationId;
|
||||||
});
|
});
|
||||||
if (animIt == entryIt->second.first.end()) {
|
if (anim != animations.end()) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Backward:
|
case Backward:
|
||||||
animIt->timeLine.setDirection(TimeLine::Backward);
|
anim->timeLine.setDirection(TimeLine::Backward);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Forward:
|
case Forward:
|
||||||
animIt->timeLine.setDirection(TimeLine::Forward);
|
anim->timeLine.setDirection(TimeLine::Forward);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
anim->terminationFlags = terminationFlags & ~TerminateAtTarget;
|
||||||
animIt->terminationFlags = terminationFlags & ~TerminateAtTarget;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,22 +377,17 @@ bool AnimationEffect::complete(quint64 animationId)
|
||||||
if (animationId == d->m_justEndedAnimation) {
|
if (animationId == d->m_justEndedAnimation) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
for (auto entryIt = d->m_animations.begin(); entryIt != d->m_animations.end(); ++entryIt) {
|
auto &[animations, rect] = pair;
|
||||||
auto animIt = std::find_if(entryIt->second.first.begin(), entryIt->second.first.end(),
|
const auto anim = std::ranges::find_if(animations, [animationId](const auto &anim) {
|
||||||
[animationId](AniData &anim) {
|
|
||||||
return anim.id == animationId;
|
return anim.id == animationId;
|
||||||
});
|
});
|
||||||
if (animIt == entryIt->second.first.end()) {
|
if (anim != animations.end()) {
|
||||||
continue;
|
anim->timeLine.setElapsed(anim->timeLine.duration());
|
||||||
}
|
unredirect(window);
|
||||||
|
|
||||||
animIt->timeLine.setElapsed(animIt->timeLine.duration());
|
|
||||||
unredirect(entryIt->first);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,26 +397,28 @@ bool AnimationEffect::cancel(quint64 animationId)
|
||||||
if (animationId == d->m_justEndedAnimation) {
|
if (animationId == d->m_justEndedAnimation) {
|
||||||
return true; // this is just ending, do not try to cancel it but fake success
|
return true; // this is just ending, do not try to cancel it but fake success
|
||||||
}
|
}
|
||||||
for (AniMap::iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end(); entry != mapEnd; ++entry) {
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
for (auto anim = entry->second.first.begin(), animEnd = entry->second.first.end(); anim != animEnd; ++anim) {
|
auto &[animations, rect] = pair;
|
||||||
if (anim->id == animationId) {
|
const auto anim = std::ranges::find_if(animations, [animationId](const auto &anim) {
|
||||||
|
return anim.id == animationId;
|
||||||
|
});
|
||||||
|
if (anim != animations.end()) {
|
||||||
EffectWindowDeletedRef ref = std::move(anim->deletedRef); // delete window once we're done updating m_animations
|
EffectWindowDeletedRef ref = std::move(anim->deletedRef); // delete window once we're done updating m_animations
|
||||||
if (anim->shader && std::none_of(entry->second.first.begin(), entry->second.first.end(), [animationId](const auto &anim) {
|
if (anim->shader && std::ranges::none_of(animations, [animationId](const auto &anim) {
|
||||||
return anim.id != animationId && anim.shader;
|
return anim.id != animationId && anim.shader;
|
||||||
})) {
|
})) {
|
||||||
unredirect(entry->first);
|
unredirect(window);
|
||||||
}
|
}
|
||||||
entry->second.first.erase(anim); // remove the animation
|
animations.erase(anim);
|
||||||
if (entry->second.first.empty()) { // no other animations on the window, release it.
|
if (animations.empty()) { // no other animations on the window, release it.
|
||||||
disconnect(entry->first, &EffectWindow::windowExpandedGeometryChanged,
|
disconnect(window, &EffectWindow::windowExpandedGeometryChanged,
|
||||||
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
||||||
d->m_animations.erase(entry);
|
d->m_animations.erase(window);
|
||||||
}
|
}
|
||||||
d->m_animationsTouched = true; // could be called from animationEnded
|
d->m_animationsTouched = true; // could be called from animationEnded
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,18 +478,20 @@ void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
auto entry = d->m_animations.find(w);
|
auto entry = d->m_animations.find(w);
|
||||||
if (entry != d->m_animations.end()) {
|
if (entry != d->m_animations.end()) {
|
||||||
for (auto anim = entry->second.first.begin(); anim != entry->second.first.end(); ++anim) {
|
auto &[window, pair] = *entry;
|
||||||
if (anim->startTime > clock() && !anim->waitAtSource) {
|
auto &[list, rect] = pair;
|
||||||
|
for (auto &anim : list) {
|
||||||
|
if (anim.startTime > clock() && !anim.waitAtSource) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anim->frozenTime < 0) {
|
if (anim.frozenTime < 0) {
|
||||||
anim->timeLine.advance(presentTime);
|
anim.timeLine.advance(presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anim->attribute == Opacity || anim->attribute == CrossFadePrevious) {
|
if (anim.attribute == Opacity || anim.attribute == CrossFadePrevious) {
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
} else if (!(anim->attribute == Brightness || anim->attribute == Saturation)) {
|
} else if (!(anim.attribute == Brightness || anim.attribute == Saturation)) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,40 +513,43 @@ static inline float geometryCompensation(int flags, float v)
|
||||||
void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
auto entry = d->m_animations.find(w);
|
auto it = d->m_animations.find(w);
|
||||||
|
if (it == d->m_animations.end()) {
|
||||||
if (entry != d->m_animations.end()) {
|
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
|
||||||
for (auto anim = entry->second.first.begin(); anim != entry->second.first.end(); ++anim) {
|
return;
|
||||||
|
}
|
||||||
if (anim->startTime > clock() && !anim->waitAtSource) {
|
auto &[window, pair] = *it;
|
||||||
|
auto &[list, rect] = pair;
|
||||||
|
for (auto &anim : list) {
|
||||||
|
if (anim.startTime > clock() && !anim.waitAtSource) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (anim->attribute) {
|
switch (anim.attribute) {
|
||||||
case Opacity:
|
case Opacity:
|
||||||
data.multiplyOpacity(interpolated(*anim));
|
data.multiplyOpacity(interpolated(anim));
|
||||||
break;
|
break;
|
||||||
case Brightness:
|
case Brightness:
|
||||||
data.multiplyBrightness(interpolated(*anim));
|
data.multiplyBrightness(interpolated(anim));
|
||||||
break;
|
break;
|
||||||
case Saturation:
|
case Saturation:
|
||||||
data.multiplySaturation(interpolated(*anim));
|
data.multiplySaturation(interpolated(anim));
|
||||||
break;
|
break;
|
||||||
case Scale: {
|
case Scale: {
|
||||||
const QSizeF sz = w->frameGeometry().size();
|
const QSizeF sz = w->frameGeometry().size();
|
||||||
float f1(1.0), f2(0.0);
|
float f1(1.0), f2(0.0);
|
||||||
if (anim->from[0] >= 0.0 && anim->to[0] >= 0.0) { // scale x
|
if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) { // scale x
|
||||||
f1 = interpolated(*anim, 0);
|
f1 = interpolated(anim, 0);
|
||||||
f2 = geometryCompensation(anim->meta & AnimationEffect::Horizontal, f1);
|
f2 = geometryCompensation(anim.meta & AnimationEffect::Horizontal, f1);
|
||||||
data.translate(f2 * sz.width());
|
data.translate(f2 * sz.width());
|
||||||
data.setXScale(data.xScale() * f1);
|
data.setXScale(data.xScale() * f1);
|
||||||
}
|
}
|
||||||
if (anim->from[1] >= 0.0 && anim->to[1] >= 0.0) { // scale y
|
if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) { // scale y
|
||||||
if (!anim->isOneDimensional()) {
|
if (!anim.isOneDimensional()) {
|
||||||
f1 = interpolated(*anim, 1);
|
f1 = interpolated(anim, 1);
|
||||||
f2 = geometryCompensation(anim->meta & AnimationEffect::Vertical, f1);
|
f2 = geometryCompensation(anim.meta & AnimationEffect::Vertical, f1);
|
||||||
} else if (((anim->meta & AnimationEffect::Vertical) >> 1) != (anim->meta & AnimationEffect::Horizontal)) {
|
} else if (((anim.meta & AnimationEffect::Vertical) >> 1) != (anim.meta & AnimationEffect::Horizontal)) {
|
||||||
f2 = geometryCompensation(anim->meta & AnimationEffect::Vertical, f1);
|
f2 = geometryCompensation(anim.meta & AnimationEffect::Vertical, f1);
|
||||||
}
|
}
|
||||||
data.translate(0.0, f2 * sz.height());
|
data.translate(0.0, f2 * sz.height());
|
||||||
data.setYScale(data.yScale() * f1);
|
data.setYScale(data.yScale() * f1);
|
||||||
|
@ -565,52 +557,52 @@ void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const Render
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Clip:
|
case Clip:
|
||||||
region = clipRect(w->expandedGeometry().toAlignedRect(), *anim);
|
region = clipRect(w->expandedGeometry().toAlignedRect(), anim);
|
||||||
break;
|
break;
|
||||||
case Translation:
|
case Translation:
|
||||||
data += QPointF(interpolated(*anim, 0), interpolated(*anim, 1));
|
data += QPointF(interpolated(anim, 0), interpolated(anim, 1));
|
||||||
break;
|
break;
|
||||||
case Size: {
|
case Size: {
|
||||||
FPx2 dest = anim->from + progress(*anim) * (anim->to - anim->from);
|
FPx2 dest = anim.from + progress(anim) * (anim.to - anim.from);
|
||||||
const QSizeF sz = w->frameGeometry().size();
|
const QSizeF sz = w->frameGeometry().size();
|
||||||
float f;
|
float f;
|
||||||
if (anim->from[0] >= 0.0 && anim->to[0] >= 0.0) { // resize x
|
if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) { // resize x
|
||||||
f = dest[0] / sz.width();
|
f = dest[0] / sz.width();
|
||||||
data.translate(geometryCompensation(anim->meta & AnimationEffect::Horizontal, f) * sz.width());
|
data.translate(geometryCompensation(anim.meta & AnimationEffect::Horizontal, f) * sz.width());
|
||||||
data.setXScale(data.xScale() * f);
|
data.setXScale(data.xScale() * f);
|
||||||
}
|
}
|
||||||
if (anim->from[1] >= 0.0 && anim->to[1] >= 0.0) { // resize y
|
if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) { // resize y
|
||||||
f = dest[1] / sz.height();
|
f = dest[1] / sz.height();
|
||||||
data.translate(0.0, geometryCompensation(anim->meta & AnimationEffect::Vertical, f) * sz.height());
|
data.translate(0.0, geometryCompensation(anim.meta & AnimationEffect::Vertical, f) * sz.height());
|
||||||
data.setYScale(data.yScale() * f);
|
data.setYScale(data.yScale() * f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Position: {
|
case Position: {
|
||||||
const QRectF geo = w->frameGeometry();
|
const QRectF geo = w->frameGeometry();
|
||||||
const float prgrs = progress(*anim);
|
const float prgrs = progress(anim);
|
||||||
if (anim->from[0] >= 0.0 && anim->to[0] >= 0.0) {
|
if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) {
|
||||||
float dest = interpolated(*anim, 0);
|
float dest = interpolated(anim, 0);
|
||||||
const qreal x[2] = {xCoord(geo, metaData(SourceAnchor, anim->meta)),
|
const qreal x[2] = {xCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||||
xCoord(geo, metaData(TargetAnchor, anim->meta))};
|
xCoord(geo, metaData(TargetAnchor, anim.meta))};
|
||||||
data.translate(dest - (x[0] + prgrs * (x[1] - x[0])));
|
data.translate(dest - (x[0] + prgrs * (x[1] - x[0])));
|
||||||
}
|
}
|
||||||
if (anim->from[1] >= 0.0 && anim->to[1] >= 0.0) {
|
if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) {
|
||||||
float dest = interpolated(*anim, 1);
|
float dest = interpolated(anim, 1);
|
||||||
const qreal y[2] = {yCoord(geo, metaData(SourceAnchor, anim->meta)),
|
const qreal y[2] = {yCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||||
yCoord(geo, metaData(TargetAnchor, anim->meta))};
|
yCoord(geo, metaData(TargetAnchor, anim.meta))};
|
||||||
data.translate(0.0, dest - (y[0] + prgrs * (y[1] - y[0])));
|
data.translate(0.0, dest - (y[0] + prgrs * (y[1] - y[0])));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Rotation: {
|
case Rotation: {
|
||||||
data.setRotationAxis((Qt::Axis)metaData(Axis, anim->meta));
|
data.setRotationAxis((Qt::Axis)metaData(Axis, anim.meta));
|
||||||
const float prgrs = progress(*anim);
|
const float prgrs = progress(anim);
|
||||||
data.setRotationAngle(anim->from[0] + prgrs * (anim->to[0] - anim->from[0]));
|
data.setRotationAngle(anim.from[0] + prgrs * (anim.to[0] - anim.from[0]));
|
||||||
|
|
||||||
const QRect geo = w->rect().toRect();
|
const QRect geo = w->rect().toRect();
|
||||||
const uint sAnchor = metaData(SourceAnchor, anim->meta),
|
const uint sAnchor = metaData(SourceAnchor, anim.meta),
|
||||||
tAnchor = metaData(TargetAnchor, anim->meta);
|
tAnchor = metaData(TargetAnchor, anim.meta);
|
||||||
QPointF pt(xCoord(geo, sAnchor), yCoord(geo, sAnchor));
|
QPointF pt(xCoord(geo, sAnchor), yCoord(geo, sAnchor));
|
||||||
|
|
||||||
if (tAnchor != sAnchor) {
|
if (tAnchor != sAnchor) {
|
||||||
|
@ -621,32 +613,30 @@ void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const Render
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Generic:
|
case Generic:
|
||||||
genericAnimation(w, data, progress(*anim), anim->meta);
|
genericAnimation(w, data, progress(anim), anim.meta);
|
||||||
break;
|
break;
|
||||||
case CrossFadePrevious:
|
case CrossFadePrevious:
|
||||||
data.setCrossFadeProgress(progress(*anim));
|
data.setCrossFadeProgress(progress(anim));
|
||||||
break;
|
break;
|
||||||
case Shader:
|
case Shader:
|
||||||
if (anim->shader && anim->shader->isValid()) {
|
if (anim.shader && anim.shader->isValid()) {
|
||||||
ShaderBinder binder{anim->shader};
|
ShaderBinder binder{anim.shader};
|
||||||
anim->shader->setUniform("animationProgress", progress(*anim));
|
anim.shader->setUniform("animationProgress", progress(anim));
|
||||||
setShader(w, anim->shader);
|
setShader(w, anim.shader);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderUniform:
|
case ShaderUniform:
|
||||||
if (anim->shader && anim->shader->isValid()) {
|
if (anim.shader && anim.shader->isValid()) {
|
||||||
ShaderBinder binder{anim->shader};
|
ShaderBinder binder{anim.shader};
|
||||||
anim->shader->setUniform("animationProgress", progress(*anim));
|
anim.shader->setUniform("animationProgress", progress(anim));
|
||||||
anim->shader->setUniform(anim->meta, interpolated(*anim));
|
anim.shader->setUniform(anim.meta, interpolated(anim));
|
||||||
setShader(w, anim->shader);
|
setShader(w, anim.shader);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
|
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,15 +650,15 @@ void AnimationEffect::postPaintScreen()
|
||||||
for (auto entry = d->m_animations.begin(); entry != d->m_animations.end();) {
|
for (auto entry = d->m_animations.begin(); entry != d->m_animations.end();) {
|
||||||
bool invalidateLayerRect = false;
|
bool invalidateLayerRect = false;
|
||||||
size_t animCounter = 0;
|
size_t animCounter = 0;
|
||||||
|
EffectWindow *const window = entry->first;
|
||||||
for (auto anim = entry->second.first.begin(); anim != entry->second.first.end();) {
|
for (auto anim = entry->second.first.begin(); anim != entry->second.first.end();) {
|
||||||
if (anim->isActive() || (anim->startTime > clock() && !anim->waitAtSource)) {
|
if (anim->isActive() || (anim->startTime > clock() && !anim->waitAtSource)) {
|
||||||
++anim;
|
++anim;
|
||||||
++animCounter;
|
++animCounter;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
EffectWindow *window = entry->first;
|
|
||||||
d->m_justEndedAnimation = anim->id;
|
d->m_justEndedAnimation = anim->id;
|
||||||
if (anim->shader && std::none_of(entry->second.first.begin(), entry->second.first.end(), [anim](const auto &other) {
|
if (anim->shader && std::ranges::none_of(entry->second.first, [anim](const auto &other) {
|
||||||
return anim->id != other.id && other.shader;
|
return anim->id != other.id && other.shader;
|
||||||
})) {
|
})) {
|
||||||
unredirect(window);
|
unredirect(window);
|
||||||
|
@ -681,16 +671,12 @@ void AnimationEffect::postPaintScreen()
|
||||||
// so we've to restore the former states, ie. find our window list and animation
|
// so we've to restore the former states, ie. find our window list and animation
|
||||||
if (d->m_animationsTouched) {
|
if (d->m_animationsTouched) {
|
||||||
d->m_animationsTouched = false;
|
d->m_animationsTouched = false;
|
||||||
entry = d->m_animations.begin();
|
entry = std::ranges::find_if(d->m_animations, [window](const auto &pair) {
|
||||||
while (entry->first != window && entry != d->m_animations.end()) {
|
return pair.first == window;
|
||||||
++entry;
|
});
|
||||||
}
|
|
||||||
Q_ASSERT(entry != d->m_animations.end()); // usercode should not delete animations from animationEnded (not even possible atm.)
|
Q_ASSERT(entry != d->m_animations.end()); // usercode should not delete animations from animationEnded (not even possible atm.)
|
||||||
anim = entry->second.first.begin();
|
|
||||||
Q_ASSERT(animCounter < entry->second.first.size());
|
Q_ASSERT(animCounter < entry->second.first.size());
|
||||||
for (size_t i = 0; i < animCounter; ++i) {
|
anim = entry->second.first.begin() + animCounter;
|
||||||
++anim;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// If it's a closed window, keep it alive for a little bit longer until we're done
|
// If it's a closed window, keep it alive for a little bit longer until we're done
|
||||||
// updating m_animations. Otherwise our windowDeleted slot can access m_animations
|
// updating m_animations. Otherwise our windowDeleted slot can access m_animations
|
||||||
|
@ -702,13 +688,13 @@ void AnimationEffect::postPaintScreen()
|
||||||
invalidateLayerRect = damageDirty = true;
|
invalidateLayerRect = damageDirty = true;
|
||||||
}
|
}
|
||||||
if (entry->second.first.empty()) {
|
if (entry->second.first.empty()) {
|
||||||
disconnect(entry->first, &EffectWindow::windowExpandedGeometryChanged,
|
disconnect(window, &EffectWindow::windowExpandedGeometryChanged,
|
||||||
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
this, &AnimationEffect::_windowExpandedGeometryChanged);
|
||||||
effects->addRepaint(entry->second.second);
|
effects->addRepaint(entry->second.second);
|
||||||
entry = d->m_animations.erase(entry);
|
entry = d->m_animations.erase(entry);
|
||||||
} else {
|
} else {
|
||||||
if (invalidateLayerRect) {
|
if (invalidateLayerRect) {
|
||||||
*const_cast<QRect *>(&(entry->second.second)) = QRect(); // invalidate
|
entry->second.second = QRect(); // invalidate
|
||||||
}
|
}
|
||||||
++entry;
|
++entry;
|
||||||
}
|
}
|
||||||
|
@ -720,13 +706,14 @@ void AnimationEffect::postPaintScreen()
|
||||||
if (d->m_needSceneRepaint) {
|
if (d->m_needSceneRepaint) {
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
} else {
|
} else {
|
||||||
for (auto entry = d->m_animations.begin(); entry != d->m_animations.end(); ++entry) {
|
for (const auto &[window, pair] : d->m_animations) {
|
||||||
for (auto anim = entry->second.first.begin(); anim != entry->second.first.end(); ++anim) {
|
const auto &[data, rect] = pair;
|
||||||
if (anim->startTime > clock()) {
|
for (const auto &anim : data) {
|
||||||
|
if (anim.startTime > clock()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!anim->timeLine.done()) {
|
if (!anim.timeLine.done()) {
|
||||||
entry->first->addLayerRepaint(entry->second.second);
|
window->addLayerRepaint(rect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,16 +797,15 @@ void AnimationEffect::setMetaData(MetaType type, uint value, uint &meta)
|
||||||
void AnimationEffect::triggerRepaint()
|
void AnimationEffect::triggerRepaint()
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
for (AniMap::const_iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end(); entry != mapEnd; ++entry) {
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
*const_cast<QRect *>(&(entry->second.second)) = QRect();
|
pair.second = QRect();
|
||||||
}
|
}
|
||||||
updateLayerRepaints();
|
updateLayerRepaints();
|
||||||
if (d->m_needSceneRepaint) {
|
if (d->m_needSceneRepaint) {
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
} else {
|
} else {
|
||||||
AniMap::const_iterator it = d->m_animations.begin(), end = d->m_animations.end();
|
for (const auto &[window, pair] : d->m_animations) {
|
||||||
for (; it != end; ++it) {
|
window->addLayerRepaint(pair.second);
|
||||||
it->first->addLayerRepaint(it->second.second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -846,20 +832,20 @@ void AnimationEffect::updateLayerRepaints()
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
d->m_needSceneRepaint = false;
|
d->m_needSceneRepaint = false;
|
||||||
for (AniMap::const_iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end(); entry != mapEnd; ++entry) {
|
for (auto &[window, pair] : d->m_animations) {
|
||||||
if (!entry->second.second.isNull()) {
|
auto &[data, rect] = pair;
|
||||||
|
if (!rect.isNull()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float f[2] = {1.0, 1.0};
|
float f[2] = {1.0, 1.0};
|
||||||
float t[2] = {0.0, 0.0};
|
float t[2] = {0.0, 0.0};
|
||||||
bool createRegion = false;
|
bool createRegion = false;
|
||||||
QList<QRect> rects;
|
QList<QRect> rects;
|
||||||
QRect *layerRect = const_cast<QRect *>(&(entry->second.second));
|
for (auto &anim : data) {
|
||||||
for (auto anim = entry->second.first.begin(), animEnd = entry->second.first.end(); anim != animEnd; ++anim) {
|
if (anim.startTime > clock()) {
|
||||||
if (anim->startTime > clock()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (anim->attribute) {
|
switch (anim.attribute) {
|
||||||
case Opacity:
|
case Opacity:
|
||||||
case Brightness:
|
case Brightness:
|
||||||
case Saturation:
|
case Saturation:
|
||||||
|
@ -870,34 +856,35 @@ void AnimationEffect::updateLayerRepaints()
|
||||||
break;
|
break;
|
||||||
case Rotation:
|
case Rotation:
|
||||||
createRegion = false;
|
createRegion = false;
|
||||||
*layerRect = QRect(QPoint(0, 0), effects->virtualScreenSize());
|
rect = QRect(QPoint(0, 0), effects->virtualScreenSize());
|
||||||
goto region_creation; // sic! no need to do anything else
|
break; // sic! no need to do anything else
|
||||||
case Generic:
|
case Generic:
|
||||||
d->m_needSceneRepaint = true; // we don't know whether this will change visual stacking order
|
d->m_needSceneRepaint = true; // we don't know whether this will change visual stacking order
|
||||||
return; // sic! no need to do anything else
|
return; // sic! no need to do anything else
|
||||||
case Translation:
|
case Translation:
|
||||||
case Position: {
|
case Position: {
|
||||||
createRegion = true;
|
createRegion = true;
|
||||||
QRect r(entry->first->frameGeometry().toRect());
|
QRect r(window->frameGeometry().toRect());
|
||||||
int x[2] = {0, 0};
|
int x[2] = {0, 0};
|
||||||
int y[2] = {0, 0};
|
int y[2] = {0, 0};
|
||||||
if (anim->attribute == Translation) {
|
if (anim.attribute == Translation) {
|
||||||
x[0] = anim->from[0];
|
x[0] = anim.from[0];
|
||||||
x[1] = anim->to[0];
|
x[1] = anim.to[0];
|
||||||
y[0] = anim->from[1];
|
y[0] = anim.from[1];
|
||||||
y[1] = anim->to[1];
|
y[1] = anim.to[1];
|
||||||
} else {
|
} else {
|
||||||
if (anim->from[0] >= 0.0 && anim->to[0] >= 0.0) {
|
if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) {
|
||||||
x[0] = anim->from[0] - xCoord(r, metaData(SourceAnchor, anim->meta));
|
x[0] = anim.from[0] - xCoord(r, metaData(SourceAnchor, anim.meta));
|
||||||
x[1] = anim->to[0] - xCoord(r, metaData(TargetAnchor, anim->meta));
|
x[1] = anim.to[0] - xCoord(r, metaData(TargetAnchor, anim.meta));
|
||||||
}
|
}
|
||||||
if (anim->from[1] >= 0.0 && anim->to[1] >= 0.0) {
|
if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) {
|
||||||
y[0] = anim->from[1] - yCoord(r, metaData(SourceAnchor, anim->meta));
|
y[0] = anim.from[1] - yCoord(r, metaData(SourceAnchor, anim.meta));
|
||||||
y[1] = anim->to[1] - yCoord(r, metaData(TargetAnchor, anim->meta));
|
y[1] = anim.to[1] - yCoord(r, metaData(TargetAnchor, anim.meta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = entry->first->expandedGeometry().toRect();
|
r = window->expandedGeometry().toRect();
|
||||||
rects << r.translated(x[0], y[0]) << r.translated(x[1], y[1]);
|
rects.push_back(r.translated(x[0], y[0]));
|
||||||
|
rects.push_back(r.translated(x[1], y[1]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Clip:
|
case Clip:
|
||||||
|
@ -906,55 +893,52 @@ void AnimationEffect::updateLayerRepaints()
|
||||||
case Size:
|
case Size:
|
||||||
case Scale: {
|
case Scale: {
|
||||||
createRegion = true;
|
createRegion = true;
|
||||||
const QSize sz = entry->first->frameGeometry().size().toSize();
|
const QSize sz = window->frameGeometry().size().toSize();
|
||||||
float fx = std::max(fixOvershoot(anim->from[0], *anim, 1), fixOvershoot(anim->to[0], *anim, 2));
|
float fx = std::max(fixOvershoot(anim.from[0], anim, 1), fixOvershoot(anim.to[0], anim, 2));
|
||||||
// float fx = std::max(interpolated(*anim,0), anim->to[0]);
|
// float fx = std::max(interpolated(*anim,0), anim.to[0]);
|
||||||
if (fx >= 0.0) {
|
if (fx >= 0.0) {
|
||||||
if (anim->attribute == Size) {
|
if (anim.attribute == Size) {
|
||||||
fx /= sz.width();
|
fx /= sz.width();
|
||||||
}
|
}
|
||||||
f[0] *= fx;
|
f[0] *= fx;
|
||||||
t[0] += geometryCompensation(anim->meta & AnimationEffect::Horizontal, fx) * sz.width();
|
t[0] += geometryCompensation(anim.meta & AnimationEffect::Horizontal, fx) * sz.width();
|
||||||
}
|
}
|
||||||
// float fy = std::max(interpolated(*anim,1), anim->to[1]);
|
// float fy = std::max(interpolated(*anim,1), anim.to[1]);
|
||||||
float fy = std::max(fixOvershoot(anim->from[1], *anim, 1), fixOvershoot(anim->to[1], *anim, 2));
|
float fy = std::max(fixOvershoot(anim.from[1], anim, 1), fixOvershoot(anim.to[1], anim, 2));
|
||||||
if (fy >= 0.0) {
|
if (fy >= 0.0) {
|
||||||
if (anim->attribute == Size) {
|
if (anim.attribute == Size) {
|
||||||
fy /= sz.height();
|
fy /= sz.height();
|
||||||
}
|
}
|
||||||
if (!anim->isOneDimensional()) {
|
if (!anim.isOneDimensional()) {
|
||||||
f[1] *= fy;
|
f[1] *= fy;
|
||||||
t[1] += geometryCompensation(anim->meta & AnimationEffect::Vertical, fy) * sz.height();
|
t[1] += geometryCompensation(anim.meta & AnimationEffect::Vertical, fy) * sz.height();
|
||||||
} else if (((anim->meta & AnimationEffect::Vertical) >> 1) != (anim->meta & AnimationEffect::Horizontal)) {
|
} else if (((anim.meta & AnimationEffect::Vertical) >> 1) != (anim.meta & AnimationEffect::Horizontal)) {
|
||||||
f[1] *= fx;
|
f[1] *= fx;
|
||||||
t[1] += geometryCompensation(anim->meta & AnimationEffect::Vertical, fx) * sz.height();
|
t[1] += geometryCompensation(anim.meta & AnimationEffect::Vertical, fx) * sz.height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
region_creation:
|
|
||||||
if (createRegion) {
|
if (createRegion) {
|
||||||
const QRect geo = entry->first->expandedGeometry().toRect();
|
const QRect geo = window->expandedGeometry().toRect();
|
||||||
if (rects.isEmpty()) {
|
if (rects.empty()) {
|
||||||
rects << geo;
|
rects.push_back(geo);
|
||||||
}
|
}
|
||||||
QList<QRect>::const_iterator r, rEnd = rects.constEnd();
|
for (auto &r : rects) { // transform
|
||||||
for (r = rects.constBegin(); r != rEnd; ++r) { // transform
|
r.setSize(QSize(std::round(r.width() * f[0]), std::round(r.height() * f[1])));
|
||||||
const_cast<QRect *>(&(*r))->setSize(QSize(qRound(r->width() * f[0]), qRound(r->height() * f[1])));
|
r.translate(t[0], t[1]); // "const_cast" - don't do that at home, kids ;-)
|
||||||
const_cast<QRect *>(&(*r))->translate(t[0], t[1]); // "const_cast" - don't do that at home, kids ;-)
|
|
||||||
}
|
}
|
||||||
QRect rect = rects.at(0);
|
rect = rects.at(0);
|
||||||
if (rects.count() > 1) {
|
if (rects.count() > 1) {
|
||||||
for (r = rects.constBegin() + 1; r != rEnd; ++r) { // unite
|
for (const auto &r : rects | std::views::drop(1)) { // unite
|
||||||
rect |= *r;
|
rect |= r;
|
||||||
}
|
}
|
||||||
const int dx = 110 * (rect.width() - geo.width()) / 100 + 1 - rect.width() + geo.width();
|
const int dx = 110 * (rect.width() - geo.width()) / 100 + 1 - rect.width() + geo.width();
|
||||||
const int dy = 110 * (rect.height() - geo.height()) / 100 + 1 - rect.height() + geo.height();
|
const int dy = 110 * (rect.height() - geo.height()) / 100 + 1 - rect.height() + geo.height();
|
||||||
rect.adjust(-dx, -dy, dx, dy); // fix pot. overshoot
|
rect.adjust(-dx, -dy, dx, dy); // fix pot. overshoot
|
||||||
}
|
}
|
||||||
*layerRect = rect;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -962,12 +946,13 @@ void AnimationEffect::updateLayerRepaints()
|
||||||
void AnimationEffect::_windowExpandedGeometryChanged(KWin::EffectWindow *w)
|
void AnimationEffect::_windowExpandedGeometryChanged(KWin::EffectWindow *w)
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
AniMap::const_iterator entry = d->m_animations.find(w);
|
const auto entry = d->m_animations.find(w);
|
||||||
if (entry != d->m_animations.end()) {
|
if (entry != d->m_animations.end()) {
|
||||||
*const_cast<QRect *>(&(entry->second.second)) = QRect();
|
auto &[data, rect] = entry->second;
|
||||||
|
rect = QRect();
|
||||||
updateLayerRepaints();
|
updateLayerRepaints();
|
||||||
if (!entry->second.second.isNull()) { // actually got updated, ie. is in use - ensure it get's a repaint
|
if (!rect.isNull()) { // actually got updated, ie. is in use - ensure it get's a repaint
|
||||||
w->addLayerRepaint(entry->second.second);
|
w->addLayerRepaint(rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,11 +965,10 @@ void AnimationEffect::_windowClosed(EffectWindow *w)
|
||||||
if (it == d->m_animations.end()) {
|
if (it == d->m_animations.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto &[animations, rect] = it->second;
|
||||||
auto &animations = (*it).second.first;
|
for (auto &animation : animations) {
|
||||||
for (auto animationIt = animations.begin(); animationIt != animations.end(); ++animationIt) {
|
if (animation.keepAlive) {
|
||||||
if (animationIt->keepAlive) {
|
animation.deletedRef = EffectWindowDeletedRef(w);
|
||||||
animationIt->deletedRef = EffectWindowDeletedRef(w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -995,23 +979,22 @@ void AnimationEffect::_windowDeleted(EffectWindow *w)
|
||||||
d->m_animations.erase(w);
|
d->m_animations.erase(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AnimationEffect::debug(const QString & /*parameter*/) const
|
QString AnimationEffect::debug(const QString ¶meter) const
|
||||||
{
|
{
|
||||||
Q_D(const AnimationEffect);
|
Q_D(const AnimationEffect);
|
||||||
QString dbg;
|
QString dbg;
|
||||||
if (d->m_animations.empty()) {
|
if (d->m_animations.empty()) {
|
||||||
dbg = QStringLiteral("No window is animated");
|
dbg = QStringLiteral("No window is animated");
|
||||||
} else {
|
} else {
|
||||||
AniMap::const_iterator entry = d->m_animations.begin(), mapEnd = d->m_animations.end();
|
for (const auto &[window, pair] : d->m_animations) {
|
||||||
for (; entry != mapEnd; ++entry) {
|
const auto &[data, rect] = pair;
|
||||||
QString caption = entry->first->isDeleted() ? QStringLiteral("[Deleted]") : entry->first->caption();
|
QString caption = window->isDeleted() ? QStringLiteral("[Deleted]") : window->caption();
|
||||||
if (caption.isEmpty()) {
|
if (caption.isEmpty()) {
|
||||||
caption = QStringLiteral("[Untitled]");
|
caption = QStringLiteral("[Untitled]");
|
||||||
}
|
}
|
||||||
dbg += QLatin1String("Animating window: ") + caption + QLatin1Char('\n');
|
dbg += QLatin1String("Animating window: ") + caption + QLatin1Char('\n');
|
||||||
auto anim = entry->second.first.begin(), animEnd = entry->second.first.end();
|
for (const auto &anim : data) {
|
||||||
for (; anim != animEnd; ++anim) {
|
dbg += anim.debugInfo();
|
||||||
dbg += anim->debugInfo();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue