Add a new filter for smoother move.

It may also help to keep the effect stable with more extreme values for the parameters.

svn path=/trunk/KDE/kdebase/workspace/; revision=799612
This commit is contained in:
Cédric Borgese 2008-04-21 23:25:03 +00:00
parent 89458622c7
commit e65a9e49ea
5 changed files with 230 additions and 11 deletions

View file

@ -68,6 +68,10 @@ WobblyWindowsEffect::WobblyWindowsEffect()
{
m_velocityFilter = FourRingLinearMean;
}
else if (velFilter == "HeightRingLinearMean")
{
m_velocityFilter = HeightRingLinearMean;
}
else if (velFilter == "MeanWithMean")
{
m_velocityFilter = MeanWithMean;
@ -92,6 +96,10 @@ WobblyWindowsEffect::WobblyWindowsEffect()
{
m_accelerationFilter = FourRingLinearMean;
}
else if (accFilter == "HeightRingLinearMean")
{
m_accelerationFilter = HeightRingLinearMean;
}
else if (accFilter == "MeanWithMean")
{
m_accelerationFilter = MeanWithMean;
@ -295,7 +303,7 @@ void WobblyWindowsEffect::windowUserMovedResized(EffectWindow* w, bool first, bo
if (windows.contains(w))
{
WindowWobblyInfos& wwi = windows[w];
wwi.status = Moving;
wwi.status = Free;
}
}
}
@ -886,6 +894,10 @@ bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow* w, qreal time)
fourRingLinearMean(&wwi.acceleration, wwi);
break;
case HeightRingLinearMean:
heightRingLinearMean(&wwi.acceleration, wwi);
break;
case MeanWithMean:
meanWithMean(&wwi.acceleration, wwi);
break;
@ -930,6 +942,10 @@ bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow* w, qreal time)
fourRingLinearMean(&wwi.velocity, wwi);
break;
case HeightRingLinearMean:
heightRingLinearMean(&wwi.velocity, wwi);
break;
case MeanWithMean:
meanWithMean(&wwi.velocity, wwi);
break;
@ -1217,6 +1233,155 @@ void WobblyWindowsEffect::meanWithMedian(Pair** datas_pointer, WindowWobblyInfos
wwi.buffer = tmp;
}
void WobblyWindowsEffect::heightRingLinearMean(Pair** datas_pointer, WindowWobblyInfos& wwi)
{
Pair* datas = *datas_pointer;
Pair neibourgs[8];
// for corners
// top-left
{
Pair& res = wwi.buffer[0];
Pair vit = datas[0];
neibourgs[0] = datas[1];
neibourgs[1] = datas[wwi.width];
neibourgs[2] = datas[wwi.width+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0*vit.x) / 6.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0*vit.y) / 6.0;
}
// top-right
{
Pair& res = wwi.buffer[wwi.width-1];
Pair vit = datas[wwi.width-1];
neibourgs[0] = datas[wwi.width-2];
neibourgs[1] = datas[2*wwi.width-1];
neibourgs[2] = datas[2*wwi.width-2];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0*vit.x) / 6.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0*vit.y) / 6.0;
}
// bottom-left
{
Pair& res = wwi.buffer[wwi.width*(wwi.height-1)];
Pair vit = datas[wwi.width*(wwi.height-1)];
neibourgs[0] = datas[wwi.width*(wwi.height-1)+1];
neibourgs[1] = datas[wwi.width*(wwi.height-2)];
neibourgs[2] = datas[wwi.width*(wwi.height-2)+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0*vit.x) / 6.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0*vit.y) / 6.0;
}
// bottom-right
{
Pair& res = wwi.buffer[wwi.count-1];
Pair vit = datas[wwi.count-1];
neibourgs[0] = datas[wwi.count-2];
neibourgs[1] = datas[wwi.width*(wwi.height-1)-1];
neibourgs[2] = datas[wwi.width*(wwi.height-1)-2];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + 3.0*vit.x) / 6.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + 3.0*vit.y) / 6.0;
}
// for borders
// top border
for (unsigned int i=1; i<wwi.width-1; ++i)
{
Pair& res = wwi.buffer[i];
Pair vit = datas[i];
neibourgs[0] = datas[i-1];
neibourgs[1] = datas[i+1];
neibourgs[2] = datas[i+wwi.width];
neibourgs[3] = datas[i+wwi.width-1];
neibourgs[4] = datas[i+wwi.width+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0*vit.x) / 10.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0*vit.y) / 10.0;
}
// bottom border
for (unsigned int i=wwi.width*(wwi.height-1)+1; i<wwi.count-1; ++i)
{
Pair& res = wwi.buffer[i];
Pair vit = datas[i];
neibourgs[0] = datas[i-1];
neibourgs[1] = datas[i+1];
neibourgs[2] = datas[i-wwi.width];
neibourgs[3] = datas[i-wwi.width-1];
neibourgs[4] = datas[i-wwi.width+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0*vit.x) / 10.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0*vit.y) / 10.0;
}
// left border
for (unsigned int i=wwi.width; i<wwi.width*(wwi.height-1); i+=wwi.width)
{
Pair& res = wwi.buffer[i];
Pair vit = datas[i];
neibourgs[0] = datas[i+1];
neibourgs[1] = datas[i-wwi.width];
neibourgs[2] = datas[i+wwi.width];
neibourgs[3] = datas[i-wwi.width+1];
neibourgs[4] = datas[i+wwi.width+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0*vit.x) / 10.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0*vit.y) / 10.0;
}
// right border
for (unsigned int i=2*wwi.width-1; i<wwi.count-1; i+=wwi.width)
{
Pair& res = wwi.buffer[i];
Pair vit = datas[i];
neibourgs[0] = datas[i-1];
neibourgs[1] = datas[i-wwi.width];
neibourgs[2] = datas[i+wwi.width];
neibourgs[3] = datas[i-wwi.width-1];
neibourgs[4] = datas[i+wwi.width-1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + 5.0*vit.x) / 10.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + 5.0*vit.y) / 10.0;
}
// for the inner points
for (unsigned int j=1; j<wwi.height-1; ++j)
{
for (unsigned int i=1; i<wwi.width-1; ++i)
{
unsigned int index = i+j*wwi.width;
Pair& res = wwi.buffer[index];
Pair& vit = datas[index];
neibourgs[0] = datas[index-1];
neibourgs[1] = datas[index+1];
neibourgs[2] = datas[index-wwi.width];
neibourgs[3] = datas[index+wwi.width];
neibourgs[4] = datas[index-wwi.width-1];
neibourgs[5] = datas[index-wwi.width+1];
neibourgs[6] = datas[index+wwi.width-1];
neibourgs[7] = datas[index+wwi.width+1];
res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + neibourgs[3].x + neibourgs[4].x + neibourgs[5].x + neibourgs[6].x + neibourgs[7].x + 8.0*vit.x) / 16.0;
res.y = (neibourgs[0].y + neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + neibourgs[4].y + neibourgs[5].y + neibourgs[6].y + neibourgs[7].y + 8.0*vit.y) / 16.0;
}
}
Pair* tmp = datas;
*datas_pointer = wwi.buffer;
wwi.buffer = tmp;
}
} // namespace KWin

View file

@ -28,6 +28,7 @@ class WobblyWindowsEffect : public Effect
{
NoFilter,
FourRingLinearMean,
HeightRingLinearMean,
MeanWithMean,
MeanWithMedian
};
@ -137,6 +138,7 @@ class WobblyWindowsEffect : public Effect
WobblyWindowsEffect::Pair computeBezierPoint(const WindowWobblyInfos& wwi, Pair point) const;
static void fourRingLinearMean(Pair** datas, WindowWobblyInfos& wwi);
static void heightRingLinearMean(Pair** datas, WindowWobblyInfos& wwi);
static void meanWithMean(Pair** datas, WindowWobblyInfos& wwi);
static void meanWithMedian(Pair** datas, WindowWobblyInfos& wwi);
};

View file

@ -53,7 +53,8 @@ KCModule(EffectFactory::componentData(), parent, args)
connect(m_ui.cbGridFilter, SIGNAL(activated(int)), this, SLOT(slotGridParameterSelected(int)));
connect(m_ui.rbNone, SIGNAL(toggled(bool)), this, SLOT(slotRbNone(bool)));
connect(m_ui.rbRingMean, SIGNAL(toggled(bool)), this, SLOT(slotRbRingMean(bool)));
connect(m_ui.rbFourRingMean, SIGNAL(toggled(bool)), this, SLOT(slotRbFourRingMean(bool)));
connect(m_ui.rbHeightRingMean, SIGNAL(toggled(bool)), this, SLOT(slotRbHeightRingMean(bool)));
connect(m_ui.rbMeanMean, SIGNAL(toggled(bool)), this, SLOT(slotRbMeanMean(bool)));
connect(m_ui.rbMeanMedian, SIGNAL(toggled(bool)), this, SLOT(slotRbMeanMedian(bool)));
@ -112,6 +113,10 @@ void WobblyWindowsEffectConfig::load()
{
velocityFilter = FourRingLinearMean;
}
else if (velFilter == "HeightRingLinearMean")
{
velocityFilter = HeightRingLinearMean;
}
else if (velFilter == "MeanWithMean")
{
velocityFilter = MeanWithMean;
@ -136,6 +141,10 @@ void WobblyWindowsEffectConfig::load()
{
accelerationFilter = FourRingLinearMean;
}
else if (accFilter == "HeightRingLinearMean")
{
accelerationFilter = HeightRingLinearMean;
}
else if (accFilter == "MeanWithMean")
{
accelerationFilter = MeanWithMean;
@ -194,6 +203,10 @@ void WobblyWindowsEffectConfig::save()
conf.writeEntry("VelocityFilter", "FourRingLinearMean");
break;
case HeightRingLinearMean:
conf.writeEntry("VelocityFilter", "HeightRingLinearMean");
break;
case MeanWithMean:
conf.writeEntry("VelocityFilter", "MeanWithMean");
break;
@ -213,6 +226,10 @@ void WobblyWindowsEffectConfig::save()
conf.writeEntry("AccelerationFilter", "FourRingLinearMean");
break;
case HeightRingLinearMean:
conf.writeEntry("AccelerationFilter", "HeightRingLinearMean");
break;
case MeanWithMean:
conf.writeEntry("AccelerationFilter", "MeanWithMean");
break;
@ -328,7 +345,7 @@ void WobblyWindowsEffectConfig::slotRbNone(bool toggled)
emit changed(true);
}
void WobblyWindowsEffectConfig::slotRbRingMean(bool toggled)
void WobblyWindowsEffectConfig::slotRbFourRingMean(bool toggled)
{
if (toggled)
{
@ -344,6 +361,24 @@ void WobblyWindowsEffectConfig::slotRbRingMean(bool toggled)
emit changed(true);
}
void WobblyWindowsEffectConfig::slotRbHeightRingMean(bool toggled)
{
if (toggled)
{
if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
{
velocityFilter = HeightRingLinearMean;
}
else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
{
accelerationFilter = HeightRingLinearMean;
}
}
emit changed(true);
}
void WobblyWindowsEffectConfig::slotRbMeanMean(bool toggled)
{
if (toggled)
@ -387,7 +422,11 @@ void WobblyWindowsEffectConfig::slotGridParameterSelected(int index)
break;
case FourRingLinearMean:
m_ui.rbRingMean->setChecked(true);
m_ui.rbFourRingMean->setChecked(true);
break;
case HeightRingLinearMean:
m_ui.rbHeightRingMean->setChecked(true);
break;
case MeanWithMean:
@ -408,7 +447,11 @@ void WobblyWindowsEffectConfig::slotGridParameterSelected(int index)
break;
case FourRingLinearMean:
m_ui.rbRingMean->setChecked(true);
m_ui.rbFourRingMean->setChecked(true);
break;
case HeightRingLinearMean:
m_ui.rbHeightRingMean->setChecked(true);
break;
case MeanWithMean:

View file

@ -49,6 +49,7 @@ private:
{
NoFilter,
FourRingLinearMean,
HeightRingLinearMean,
MeanWithMean,
MeanWithMedian
};
@ -64,7 +65,8 @@ private slots:
void slotGridParameterSelected(int);
void slotRbNone(bool);
void slotRbRingMean(bool);
void slotRbFourRingMean(bool);
void slotRbHeightRingMean(bool);
void slotRbMeanMean(bool);
void slotRbMeanMedian(bool);

View file

@ -6,7 +6,7 @@
<x>0</x>
<y>0</y>
<width>553</width>
<height>383</height>
<height>368</height>
</rect>
</property>
<property name="windowTitle" >
@ -23,8 +23,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>533</width>
<height>338</height>
<width>531</width>
<height>321</height>
</rect>
</property>
<attribute name="title" >
@ -284,15 +284,22 @@
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbRingMean" >
<widget class="QRadioButton" name="rbFourRingMean" >
<property name="text" >
<string>Ring Mean</string>
<string>Ring Mean (4 ways)</string>
</property>
<property name="checked" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbHeightRingMean" >
<property name="text" >
<string>Ring Mean (8 ways)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbMeanMean" >
<property name="text" >