remove QHash::operator[] from the motionmanager and sharpen the ::finish condiion

CCBUG: 252986
icc-effect-5.14.5
Thomas Lübking 2011-04-26 01:00:37 +02:00
parent 915d28d797
commit 48d8864090
1 changed files with 87 additions and 65 deletions

View File

@ -840,23 +840,24 @@ void WindowMotionManager::manage(EffectWindow *w)
smoothness = effects->animationTimeFactor() * 4.0;
}
m_managedWindows[ w ] = WindowMotion();
m_managedWindows[ w ].translation.setStrength(strength);
m_managedWindows[ w ].translation.setSmoothness(smoothness);
m_managedWindows[ w ].scale.setStrength(strength * 1.33);
m_managedWindows[ w ].scale.setSmoothness(smoothness / 2.0);
WindowMotion &motion = m_managedWindows[ w ];
motion.translation.setStrength(strength);
motion.translation.setSmoothness(smoothness);
motion.scale.setStrength(strength * 1.33);
motion.scale.setSmoothness(smoothness / 2.0);
m_managedWindows[ w ].translation.setValue(w->pos());
m_managedWindows[ w ].scale.setValue(QPointF(1.0, 1.0));
motion.translation.setValue(w->pos());
motion.scale.setValue(QPointF(1.0, 1.0));
}
void WindowMotionManager::unmanage(EffectWindow *w)
{
if (!m_managedWindows.contains(w))
return;
QPointF diffT = m_managedWindows[ w ].translation.distance();
QPointF diffS = m_managedWindows[ w ].scale.distance();
/// superflous, see below
// if (!m_managedWindows.contains(w))
// return;
/// this makes no sense?!
// QPointF diffT = m_managedWindows[ w ].translation.distance();
// QPointF diffS = m_managedWindows[ w ].scale.distance();
m_movingWindowsSet.remove(w);
m_managedWindows.remove(w);
@ -884,130 +885,151 @@ void WindowMotionManager::calculate(int time)
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.begin();
for (; it != m_managedWindows.end(); it++) {
WindowMotion *motion = &it.value();
bool stopped = false;
EffectWindow *window = it.key();
int stopped = 0;
// TODO: What happens when distance() == 0 but we are still moving fast?
// TODO: Motion needs to be calculated from the window's center
QPointF diffT = motion->translation.distance();
if (diffT != QPoint(0.0, 0.0)) {
Motion2D *trans = &motion->translation;
if (trans->distance().isNull())
++stopped;
else {
// Still moving
motion->translation.calculate(time);
diffT = motion->translation.distance();
if (qAbs(diffT.x()) < 0.5 && qAbs(motion->translation.velocity().x()) < 0.2 &&
qAbs(diffT.y()) < 0.5 && qAbs(motion->translation.velocity().y()) < 0.2) {
trans->calculate(time);
const short fx = trans->target().x() <= window->x() ? -1 : 1;
const short fy = trans->target().y() <= window->y() ? -1 : 1;
if (trans->distance().x()*fx/0.5 < 1.0 && trans->velocity().x()*fx/0.2 < 1.0 &&
trans->distance().y()*fy/0.5 < 1.0 && trans->velocity().y()*fy/0.2 < 1.0) {
// Hide tiny oscillations
motion->translation.finish();
diffT = QPoint(0.0, 0.0);
stopped = true;
++stopped;
}
}
QPointF diffS = motion->scale.distance();
if (diffS != QPoint(0.0, 0.0)) {
Motion2D *scale = &motion->scale;
if (scale->distance().isNull())
++stopped;
else {
// Still scaling
motion->scale.calculate(time);
diffS = motion->scale.distance();
if (qAbs(diffS.x()) < 0.001 && qAbs(motion->scale.velocity().x()) < 0.05 &&
qAbs(diffS.y()) < 0.001 && qAbs(motion->scale.velocity().y()) < 0.05) {
scale->calculate(time);
const short fx = scale->target().x() < 1.0 ? -1 : 1;
const short fy = scale->target().y() < 1.0 ? -1 : 1;
if (scale->distance().x()*fx/0.001 < 1.0 && scale->velocity().x()*fx/0.05 < 1.0 &&
scale->distance().y()*fy/0.001 < 1.0 && scale->velocity().y()*fy/0.05 < 1.0) {
// Hide tiny oscillations
motion->scale.finish();
diffS = QPoint(0.0, 0.0);
stopped = true;
++stopped;
}
}
// We just finished this window's motion
if (stopped && diffT == QPoint(0.0, 0.0) && diffS == QPoint(0.0, 0.0))
if (stopped == 2)
m_movingWindowsSet.remove(it.key());
}
}
void WindowMotionManager::reset()
{
if (!m_managedWindows.count())
return;
EffectWindowList windows = m_managedWindows.keys();
for (int i = 0; i < windows.size(); i++) {
EffectWindow *w = windows.at(i);
m_managedWindows[ w ].translation.setTarget(w->pos());
m_managedWindows[ w ].translation.finish();
m_managedWindows[ w ].scale.setTarget(QPointF(1.0, 1.0));
m_managedWindows[ w ].scale.finish();
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.begin();
for (; it != m_managedWindows.end(); it++) {
WindowMotion *motion = &it.value();
EffectWindow *window = it.key();
motion->translation.setTarget(window->pos());
motion->translation.finish();
motion->scale.setTarget(QPointF(1.0, 1.0));
motion->scale.finish();
}
}
void WindowMotionManager::reset(EffectWindow *w)
{
if (!m_managedWindows.contains(w))
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.find(w);
if (it == m_managedWindows.end())
return;
m_managedWindows[ w ].translation.setTarget(w->pos());
m_managedWindows[ w ].translation.finish();
m_managedWindows[ w ].scale.setTarget(QPointF(1.0, 1.0));
m_managedWindows[ w ].scale.finish();
WindowMotion *motion = &it.value();
motion->translation.setTarget(w->pos());
motion->translation.finish();
motion->scale.setTarget(QPointF(1.0, 1.0));
motion->scale.finish();
}
void WindowMotionManager::apply(EffectWindow *w, WindowPaintData &data)
{
if (!m_managedWindows.contains(w))
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.find(w);
if (it == m_managedWindows.end())
return;
// TODO: Take into account existing scale so that we can work with multiple managers (E.g. Present windows + grid)
data.xTranslate += m_managedWindows[ w ].translation.value().x() - w->x();
data.yTranslate += m_managedWindows[ w ].translation.value().y() - w->y();
data.xScale *= m_managedWindows[ w ].scale.value().x();
data.yScale *= m_managedWindows[ w ].scale.value().y();
WindowMotion *motion = &it.value();
data.xTranslate += motion->translation.value().x() - w->x();
data.yTranslate += motion->translation.value().y() - w->y();
data.xScale *= motion->scale.value().x();
data.yScale *= motion->scale.value().y();
}
void WindowMotionManager::moveWindow(EffectWindow *w, QPoint target, double scale, double yScale)
{
if (!m_managedWindows.contains(w))
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.find(w);
if (it == m_managedWindows.end())
abort(); // Notify the effect author that they did something wrong
WindowMotion *motion = &it.value();
if (yScale == 0.0)
yScale = scale;
QPointF scalePoint(scale, yScale);
if (m_managedWindows[ w ].translation.value() == target &&
m_managedWindows[ w ].scale.value() == scalePoint)
if (motion->translation.value() == target && motion->scale.value() == scalePoint)
return; // Window already at that position
m_managedWindows[ w ].translation.setTarget(target);
m_managedWindows[ w ].scale.setTarget(scalePoint);
motion->translation.setTarget(target);
motion->scale.setTarget(scalePoint);
m_movingWindowsSet << w;
}
QRectF WindowMotionManager::transformedGeometry(EffectWindow *w) const
{
QHash<EffectWindow*, WindowMotion>::const_iterator it = m_managedWindows.constFind(w);
if (it == m_managedWindows.end())
return w->geometry();
const WindowMotion *motion = &it.value();
QRectF geometry(w->geometry());
// TODO: Take into account existing scale so that we can work with multiple managers (E.g. Present windows + grid)
geometry.moveTo(m_managedWindows[ w ].translation.value());
geometry.setWidth(geometry.width() * m_managedWindows[ w ].scale.value().x());
geometry.setHeight(geometry.height() * m_managedWindows[ w ].scale.value().y());
geometry.moveTo(motion->translation.value());
geometry.setWidth(geometry.width() * motion->scale.value().x());
geometry.setHeight(geometry.height() * motion->scale.value().y());
return geometry;
}
void WindowMotionManager::setTransformedGeometry(EffectWindow *w, const QRectF &geometry)
{
m_managedWindows[ w ].translation.setValue(geometry.topLeft());
m_managedWindows[ w ].scale.setValue(QPointF(geometry.width() / qreal(w->width()),
geometry.height() / qreal(w->height())));
QHash<EffectWindow*, WindowMotion>::iterator it = m_managedWindows.find(w);
if (it == m_managedWindows.end())
return;
WindowMotion *motion = &it.value();
motion->translation.setValue(geometry.topLeft());
motion->scale.setValue(QPointF(geometry.width() / qreal(w->width()), geometry.height() / qreal(w->height())));
}
QRectF WindowMotionManager::targetGeometry(EffectWindow *w) const
{
QHash<EffectWindow*, WindowMotion>::const_iterator it = m_managedWindows.constFind(w);
if (it == m_managedWindows.end())
return w->geometry();
const WindowMotion *motion = &it.value();
QRectF geometry(w->geometry());
// TODO: Take into account existing scale so that we can work with multiple managers (E.g. Present windows + grid)
geometry.moveTo(m_managedWindows[ w ].translation.target());
geometry.setWidth(geometry.width() * m_managedWindows[ w ].scale.target().x());
geometry.setHeight(geometry.height() * m_managedWindows[ w ].scale.target().y());
geometry.moveTo(motion->translation.target());
geometry.setWidth(geometry.width() * motion->scale.target().x());
geometry.setHeight(geometry.height() * motion->scale.target().y());
return geometry;
}