[prev in list] [next in list] [prev in thread] [next in thread]
List: kwin
Subject: Re: wobbly effect
From: cedric <cedric.borgese () gmail ! com>
Date: 2008-02-20 22:29:21
Message-ID: 200802202329.21555.cedric.borgese () gmail ! com
[Download RAW message or body]
and the patch...
["kwin.diff" (text/x-patch)]
Index: effects/CMakeLists.txt
===================================================================
--- effects/CMakeLists.txt (revision 777553)
+++ effects/CMakeLists.txt (working copy)
@@ -1,5 +1,5 @@
# Uncomment to have the test effects built
-#add_subdirectory( test )
+add_subdirectory( test )
# Adds effect plugin with given name. Sources are given after the name
Index: effects/test/demo_wobblywindows.cpp
===================================================================
--- effects/test/demo_wobblywindows.cpp (revision 0)
+++ effects/test/demo_wobblywindows.cpp (revision 0)
@@ -0,0 +1,1153 @@
+/*****************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2007
+
+You can Freely distribute this program under the GNU General Public
+License. See the file "COPYING" for the exact licensing terms.
+******************************************************************/
+
+
+#include "demo_wobblywindows.h"
+#include "demo_wobblywindows_constants.h"
+
+#include <kdebug.h>
+#include <kconfiggroup.h>
+#include <math.h>
+
+#define USE_ASSERT
+#ifdef USE_ASSERT
+#define ASSERT1 assert
+#else
+#define ASSERT1
+#endif
+
+//#define COMPUTE_STATS
+
+// if you enable it and run kwin in a terminal from the session it manages,
+// be sure to redirect the output of kwin in a file or
+// you'll propably get deadlocks.
+//#define VERBOSE_MODE
+
+#if defined COMPUTE_STATS and not defined VERBOSE_MODE
+# warning "You enable COMPUTE_STATS without VERBOSE_MODE, computed stats will not \
be printed." +#endif
+
+namespace KWin
+{
+
+KWIN_EFFECT(demo_wobblywindows, WobblyWindowsEffect)
+
+WobblyWindowsEffect::WobblyWindowsEffect()
+{
+ KConfigGroup conf = effects->effectConfig("Wobbly");
+
+ m_raideur = conf.readEntry("Raideur", RAIDEUR);
+ m_amortissement = conf.readEntry("Amortissement", AMORTISSEMENT);
+ m_move_factor = conf.readEntry("MoveFactor", MOVEFACTOR);
+
+ m_xTesselation = conf.readEntry("XTesselation", XTESSELATION);
+ m_yTesselation = conf.readEntry("YTesselation", YTESSELATION);
+
+ m_squareRootMasterAcceleration = conf.readEntry("SquareRootMasterAcceleration", \
SQUAREROOTMASTERACCELERATION); +
+ m_minVelocity = conf.readEntry("MinVelocity", MINVELOCITY);
+ m_maxVelocity = conf.readEntry("MaxVelocity", MAXVELOCITY);
+ m_stopVelocity = conf.readEntry("StopVelocity", STOPVELOCITY);
+ m_minAcceleration = conf.readEntry("MinAcceleration", MINACCELERATION);
+ m_maxAcceleration = conf.readEntry("MaxAcceleration", MAXACCELERATION);
+ m_stopAcceleration = conf.readEntry("StopAcceleration", STOPACCELERATION);
+
+ QString velFilter = conf.readEntry("VelocityFilter", VELOCITYFILTER);
+ if (velFilter == "NoFilter")
+ {
+ m_velocityFilter = NoFilter;
+ }
+ else if (velFilter == "FourRingLinearMean")
+ {
+ m_velocityFilter = FourRingLinearMean;
+ }
+ else if (velFilter == "MeanWithMean")
+ {
+ m_velocityFilter = MeanWithMean;
+ }
+ else if (velFilter == "MeanWithMedian")
+ {
+ m_velocityFilter = MeanWithMedian;
+ }
+ else
+ {
+ m_velocityFilter = FourRingLinearMean;
+ kDebug() << "Unknown config value for VelocityFilter : " << velFilter;
+ }
+
+
+ QString accFilter = conf.readEntry("AccelerationFilter", ACCELERATIONFILTER);
+ if (accFilter == "NoFilter")
+ {
+ m_accelerationFilter = NoFilter;
+ }
+ else if (accFilter == "FourRingLinearMean")
+ {
+ m_accelerationFilter = FourRingLinearMean;
+ }
+ else if (accFilter == "MeanWithMean")
+ {
+ m_accelerationFilter = MeanWithMean;
+ }
+ else if (accFilter == "MeanWithMedian")
+ {
+ m_accelerationFilter = MeanWithMedian;
+ }
+ else
+ {
+ m_accelerationFilter = NoFilter;
+ kDebug() << "Unknown config value for accelerationFilter : " << accFilter;
+ }
+
+#if defined VERBOSE_MODE
+ kDebug() << "Parameters :\n" <<
+ "grid(" << m_raideur << ", " << m_amortissement << ", " << m_move_factor << \
")\n" << + "velocity(" << m_minVelocity << ", " << m_maxVelocity << ", " << \
m_stopVelocity << ")\n" << + "acceleration(" << m_minAcceleration << ", " << \
m_maxAcceleration << ", " << m_stopAcceleration << ")\n" << + "tesselation(" \
<< m_xTesselation << ", " << m_yTesselation << ")"; +#endif
+}
+
+WobblyWindowsEffect::~WobblyWindowsEffect()
+{
+ if (windows.empty())
+ {
+ // we should be empty at this point...
+ // emit a warning and clean the list.
+ kDebug() << "Windows list not empty. Left items : " << windows.count();
+ QHash< const EffectWindow*, WindowWobblyInfos >::iterator i;
+ for (i = windows.begin(); i != windows.end(); ++i)
+ {
+ freeWobblyInfo(i.value());
+ }
+ }
+}
+void WobblyWindowsEffect::setVelocityThreshold(qreal m_minVelocity)
+{
+ this->m_minVelocity = m_minVelocity;
+}
+
+void WobblyWindowsEffect::setMoveFactor(qreal factor)
+{
+ m_move_factor = factor;
+}
+
+void WobblyWindowsEffect::setRaideur(qreal m_raideur)
+{
+ this->m_raideur = m_raideur;
+}
+
+void WobblyWindowsEffect::setVelocityFilter(GridFilter filter)
+{
+ m_velocityFilter = filter;
+}
+
+void WobblyWindowsEffect::setAccelerationFilter(GridFilter filter)
+{
+ m_accelerationFilter = filter;
+}
+
+WobblyWindowsEffect::GridFilter WobblyWindowsEffect::velocityFilter() const
+{
+ return m_velocityFilter;
+}
+
+WobblyWindowsEffect::GridFilter WobblyWindowsEffect::accelerationFilter() const
+{
+ return m_accelerationFilter;
+}
+
+void WobblyWindowsEffect::setAmortissement(qreal m_amortissement)
+{
+ this->m_amortissement = m_amortissement;
+}
+
+void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
+{
+ // We need to mark the screen windows as transformed. Otherwise the whole
+ // screen won't be repainted, resulting in artefacts.
+ // Could we just set a subset of the screen to be repainted ?
+ if (windows.count() != 0)
+ {
+ data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
+ }
+
+ // this set the QRect invalid.
+ m_updateRegion.setWidth(0);
+
+ effects->prePaintScreen(data, time);
+}
+const qreal maxTime = 10.0;
+void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, \
int time) +{
+ if (windows.contains(w))
+ {
+ data.setTransformed();
+ data.quads = data.quads.makeRegularGrid(m_xTesselation, m_yTesselation);
+ bool stop = false;
+ qreal updateTime = time;
+
+ WindowWobblyInfos& wwi = windows[w];
+ if (wwi.onConstrain)
+ {
+ wwi.mDestination.x = cursorPos().x();
+ wwi.mDestination.y = cursorPos().y();
+ }
+
+ while (!stop && (updateTime > maxTime))
+ {
+#if defined VERBOSE_MODE
+ kDebug() << "loop time " << updateTime << " / " << time;
+#endif
+ stop = !updateWindowWobblyDatas(w, maxTime);
+ updateTime -= maxTime;
+ }
+ if (!stop && updateTime > 0)
+ {
+ updateWindowWobblyDatas(w, updateTime);
+ }
+ }
+
+ effects->prePaintWindow(w, data, time);
+}
+
+void WobblyWindowsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, \
WindowPaintData& data) +{
+ if(windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ int tx = w->geometry().x();
+ int ty = w->geometry().y();
+ for (int i = 0; i < data.quads.count(); ++i)
+ {
+ for(int j = 0; j < 4; ++j)
+ {
+ WindowVertex& v = data.quads[i][j];
+ Pair oldPos = {tx + v.x(), ty + v.y()};
+ Pair newPos = computeBezierPoint(wwi, oldPos);
+ v.move(newPos.x - tx, newPos.y - ty);
+ }
+ }
+ }
+
+ // Call the next effect.
+ effects->paintWindow(w, mask, region, data);
+}
+
+void WobblyWindowsEffect::postPaintScreen()
+{
+ if (!windows.isEmpty())
+ {
+ effects->addRepaint(m_updateRegion);
+ // Repaint the workspace so that everything would be repainted next time
+ //effects->addRepaintFull();
+ }
+
+ // Call the next effect.
+ effects->postPaintScreen();
+}
+
+void WobblyWindowsEffect::windowUserMovedResized(EffectWindow* w, bool first, bool \
last) +{
+ if (first && !w->isSpecialWindow())
+ {
+ if (!windows.contains(w))
+ {
+ WindowWobblyInfos new_wwi;
+ initWobblyInfo(new_wwi, w->geometry());
+ windows[w] = new_wwi;
+ }
+
+ WindowWobblyInfos& wwi = windows[w];
+ wwi.onConstrain = true;
+ const QRectF& rect = w->geometry();
+
+ qreal x_increment = rect.width() / (wwi.width-1.0);
+ qreal y_increment = rect.height() / (wwi.height-1.0);
+
+ Pair picked = {cursorPos().x(), cursorPos().y()};
+ wwi.mDestination = picked;
+ int indx = (picked.x - rect.x()) / x_increment;
+ int indy = (picked.y - rect.y()) / y_increment;
+ wwi.mPickedPointIndex = indy*wwi.width + indx;
+ if (wwi.mPickedPointIndex < 0)
+ {
+ kDebug() << "Picked index == " << wwi.mPickedPointIndex << " with (" << \
cursorPos().x() << "," << cursorPos().y() << ")"; + wwi.mPickedPointIndex \
= 0; + }
+ else if (static_cast<unsigned int>(wwi.mPickedPointIndex) > wwi.count - 1)
+ {
+ kDebug() << "Picked index == " << wwi.mPickedPointIndex << " with (" << \
cursorPos().x() << "," << cursorPos().y() << ")"; + wwi.mPickedPointIndex \
= wwi.count - 1; + }
+#if defined VERBOSE_MODE
+ kDebug() << "Original Picked point -- x : " << picked.x << " - y : " << \
picked.y; +#endif
+ wwi.mPickedPointTranslation.x = wwi.position[wwi.mPickedPointIndex].x - \
picked.x; + wwi.mPickedPointTranslation.y = \
wwi.position[wwi.mPickedPointIndex].y - picked.y; + }
+ else if (last)
+ {
+ if (windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ wwi.onConstrain = false;
+ }
+ }
+}
+
+void WobblyWindowsEffect::windowClosed(EffectWindow* w)
+{
+ if(windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ freeWobblyInfo(wwi);
+ windows.remove(w);
+ }
+}
+
+void WobblyWindowsEffect::initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) \
const +{
+ wwi.count = 4*4;
+ wwi.width = 4;
+ wwi.height = 4;
+
+ wwi.bezierWidth = m_xTesselation;
+ wwi.bezierHeight = m_yTesselation;
+ wwi.bezierCount = m_xTesselation * m_yTesselation;
+
+ wwi.origin = new Pair[wwi.count];
+ wwi.position = new Pair[wwi.count];
+ wwi.velocity = new Pair[wwi.count];
+ wwi.acceleration = new Pair[wwi.count];
+ wwi.buffer = new Pair[wwi.count];
+ wwi.bezierSurface = new Pair[wwi.bezierCount];
+
+ wwi.onConstrain = true;
+
+ qreal x = geometry.x(), y = geometry.y();
+ qreal width = geometry.width(), height = geometry.height();
+
+ Pair initValue = {x, y};
+ static const Pair nullPair = {0.0, 0.0};
+
+ qreal x_increment = width / (wwi.width-1.0);
+ qreal y_increment = height / (wwi.height-1.0);
+
+ for (unsigned int j=0; j<4; ++j)
+ {
+ for (unsigned int i=0; i<4; ++i)
+ {
+ unsigned int idx = j*4 + i;
+ wwi.origin[idx] = initValue;
+ wwi.position[idx] = initValue;
+ wwi.velocity[idx] = nullPair;
+ if (i != 4-2) // x grid count - 2, i.e. not the last point
+ {
+ initValue.x += x_increment;
+ }
+ else
+ {
+ initValue.x = width + x;
+ }
+ initValue.x = initValue.x;
+ }
+ initValue.x = x;
+ initValue.x = initValue.x;
+ if (j != 4-2) // y grid count - 2, i.e. not the last point
+ {
+ initValue.y += y_increment;
+ }
+ else
+ {
+ initValue.y = height + y;
+ }
+ initValue.y = initValue.y;
+ }
+}
+
+void WobblyWindowsEffect::freeWobblyInfo(WindowWobblyInfos& wwi) const
+{
+ delete wwi.origin;
+ delete wwi.position;
+ delete wwi.velocity;
+ delete wwi.acceleration;
+ delete wwi.buffer;
+
+ delete wwi.bezierSurface;
+}
+
+WobblyWindowsEffect::Pair WobblyWindowsEffect::computeBezierPoint(const \
WindowWobblyInfos& wwi, Pair point) const +{
+ // compute the input value
+ Pair topleft = wwi.origin[0];
+ Pair bottomright = wwi.origin[wwi.count-1];
+
+ ASSERT1(point.x >= topleft.x);
+ ASSERT1(point.y >= topleft.y);
+ ASSERT1(point.x <= bottomright.x);
+ ASSERT1(point.y <= bottomright.y);
+
+ qreal tx = (point.x - topleft.x) / (bottomright.x - topleft.x);
+ qreal ty = (point.y - topleft.y) / (bottomright.y - topleft.y);
+
+ ASSERT1(tx >= 0);
+ ASSERT1(tx <= 1);
+ ASSERT1(ty >= 0);
+ ASSERT1(ty <= 1);
+
+ // compute polinomial coeff
+
+ qreal px[4];
+ px[0] = (1-tx)*(1-tx)*(1-tx);
+ px[1] = 3*(1-tx)*(1-tx)*tx;
+ px[2] = 3*(1-tx)*tx*tx;
+ px[3] = tx*tx*tx;
+
+ qreal py[4];
+ py[0] = (1-ty)*(1-ty)*(1-ty);
+ py[1] = 3*(1-ty)*(1-ty)*ty;
+ py[2] = 3*(1-ty)*ty*ty;
+ py[3] = ty*ty*ty;
+
+ Pair res = {0.0, 0.0};
+
+ for (unsigned int j = 0; j < 4; ++j)
+ {
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ // this assume the grid is 4*4
+ res.x += px[i] * py[j] * wwi.position[i + j * wwi.width].x;
+ res.y += px[i] * py[j] * wwi.position[i + j * wwi.width].y;
+ }
+ }
+
+ return res;
+}
+namespace
+{
+
+static inline void fixVectorBounds(WobblyWindowsEffect::Pair& vec, qreal min, qreal \
max) +{
+ if (fabs(vec.x) < min)
+ {
+ vec.x = 0.0;
+ }
+ else if (fabs(vec.x) > max)
+ {
+ if (vec.x > 0.0)
+ {
+ vec.x = max;
+ }
+ else
+ {
+ vec.x = -max;
+ }
+ }
+
+ if (fabs(vec.y) < min)
+ {
+ vec.y = 0.0;
+ }
+ else if (fabs(vec.y) > max)
+ {
+ if (vec.y > 0.0)
+ {
+ vec.y = max;
+ }
+ else
+ {
+ vec.y = -max;
+ }
+ }
+}
+
+static inline void computeVectorBounds(WobblyWindowsEffect::Pair& vec, \
WobblyWindowsEffect::Pair& bound) +{
+ if (fabs(vec.x) < bound.x)
+ {
+ bound.x = fabs(vec.x);
+ }
+ else if (fabs(vec.x) > bound.y)
+ {
+ bound.y = fabs(vec.x);
+ }
+ if (fabs(vec.y) < bound.x)
+ {
+ bound.x = fabs(vec.y);
+ }
+ else if (fabs(vec.y) > bound.y)
+ {
+ bound.y = fabs(vec.y);
+ }
+}
+
+} // close the anonymous namespace
+
+bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow* w, qreal time)
+{
+ const QRectF& rect = w->geometry();
+ WindowWobblyInfos& wwi = windows[w];
+
+ qreal x_length = rect.width() / (wwi.width-1.0);
+ qreal y_length = rect.height() / (wwi.height-1.0);
+
+ Pair picked = wwi.mDestination;
+
+ Pair pickedTranslation = wwi.mPickedPointTranslation;
+ picked.x += pickedTranslation.x;
+ picked.y += pickedTranslation.y;
+ Pair on_grid_picked = wwi.position[wwi.mPickedPointIndex];
+ Pair move = {picked.x - on_grid_picked.x, picked.y - on_grid_picked.y};
+
+#if defined VERBOSE_MODE
+ kDebug() << "Picked point -- x : " << picked.x << " - y : " << picked.y;
+ kDebug() << "On grid point -- x : " << on_grid_picked.x << " - y : " << \
on_grid_picked.y; + kDebug() << "Move -- x : " << move.x << " - y : " << move.y;
+
+ kDebug() << "time " << time;
+#endif
+
+ Pair origine = {rect.x(), rect.y()};
+
+#if defined VERBOSE_MODE
+ kDebug() << "increment x " << x_length << " // y" << y_length;
+#endif
+
+ for (unsigned int j=0; j<wwi.height; ++j)
+ {
+ for (unsigned int i=0; i<wwi.width; ++i)
+ {
+ wwi.origin[wwi.width*j + i] = origine;
+ if (i != wwi.width-2)
+ {
+ origine.x += x_length;
+ }
+ else
+ {
+ origine.x = rect.width() + rect.x();
+ }
+ }
+ origine.x = rect.x();
+ if (j != wwi.height-2)
+ {
+ origine.y += y_length;
+ }
+ else
+ {
+ origine.y = rect.height() + rect.y();
+ }
+ }
+
+
+ Pair acc = {move.x*m_raideur, move.y*m_raideur};
+ if (m_squareRootMasterAcceleration)
+ {
+ if (acc.x < 0.0)
+ {
+ acc.x = -sqrt(-acc.x);
+ }
+ else
+ {
+ acc.x = sqrt(acc.x);
+ }
+
+ if (acc.y < 0.0)
+ {
+ acc.y = -sqrt(-acc.y);
+ }
+ else
+ {
+ acc.y = sqrt(acc.y);
+ }
+ }
+
+#if defined VERBOSE_MODE
+ kDebug() << "Master acceleration -- x : " << acc.x << " - y : " << acc.y;
+#endif
+
+ unsigned int fixedIndex = wwi.mPickedPointIndex;
+ Pair neibourgs[4];
+ Pair acceleration;
+
+ qreal acc_sum = 0.0;
+ qreal vel_sum = 0.0;
+
+ // compute acceleration, velocity and position for each point
+
+ // for corners
+
+ // top-left
+
+ // acceleration is acc
+ if (fixedIndex == 0)
+ {
+ wwi.acceleration[0] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[0];
+ neibourgs[0] = wwi.position[1];
+ neibourgs[1] = wwi.position[wwi.width];
+
+ acceleration.x = ((neibourgs[0].x - pos.x) - x_length)*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur; + acceleration.y = ((neibourgs[1].y - \
pos.y) - y_length)*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 2;
+ acceleration.y /= 2;
+
+ wwi.acceleration[0] = acceleration;
+ }
+
+ // top-right
+
+ // acceleration is acc
+ if (fixedIndex == wwi.width-1)
+ {
+ wwi.acceleration[wwi.width-1] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[wwi.width-1];
+ neibourgs[0] = wwi.position[wwi.width-2];
+ neibourgs[1] = wwi.position[2*wwi.width-1];
+
+ acceleration.x = (x_length - (pos.x - neibourgs[0].x))*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur; + acceleration.y = ((neibourgs[1].y - \
pos.y) - y_length)*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 2;
+ acceleration.y /= 2;
+
+ wwi.acceleration[wwi.width-1] = acceleration;
+ }
+
+ // bottom-left
+
+ // acceleration is acc
+ if (fixedIndex == wwi.width*(wwi.height-1))
+ {
+ wwi.acceleration[wwi.width*(wwi.height-1)] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[wwi.width*(wwi.height-1)];
+ neibourgs[0] = wwi.position[wwi.width*(wwi.height-1)+1];
+ neibourgs[1] = wwi.position[wwi.width*(wwi.height-2)];
+
+ acceleration.x = ((neibourgs[0].x - pos.x) - x_length)*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur; + acceleration.y = (y_length - (pos.y - \
neibourgs[1].y))*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 2;
+ acceleration.y /= 2;
+
+ wwi.acceleration[wwi.width*(wwi.height-1)] = acceleration;
+ }
+
+ // bottom-right
+
+ // acceleration is acc
+ if (fixedIndex == wwi.count-1)
+ {
+ wwi.acceleration[wwi.count-1] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[wwi.count-1];
+ neibourgs[0] = wwi.position[wwi.count-2];
+ neibourgs[1] = wwi.position[wwi.width*(wwi.height-1)-1];
+
+ acceleration.x = (x_length - (pos.x - neibourgs[0].x))*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur; + acceleration.y = (y_length - (pos.y - \
neibourgs[1].y))*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 2;
+ acceleration.y /= 2;
+
+ wwi.acceleration[wwi.count-1] = acceleration;
+ }
+
+
+ // for borders
+
+ // top border
+ for (unsigned int i=1; i<wwi.width-1; ++i)
+ {
+ // acceleration is acc
+ if (fixedIndex == i)
+ {
+ wwi.acceleration[i] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[i];
+ neibourgs[0] = wwi.position[i-1];
+ neibourgs[1] = wwi.position[i+1];
+ neibourgs[2] = wwi.position[i+wwi.width];
+
+ acceleration.x = (x_length - (pos.x - neibourgs[0].x))*m_raideur + \
((neibourgs[1].x - pos.x) - x_length)*m_raideur + (neibourgs[2].x - pos.x)*m_raideur; \
+ acceleration.y = ((neibourgs[2].y - pos.y) - y_length)*m_raideur + \
(neibourgs[0].y - pos.y)*m_raideur + (neibourgs[1].y - pos.y)*m_raideur; +
+ acceleration.x /= 3;
+ acceleration.y /= 3;
+
+ wwi.acceleration[i] = acceleration;
+ }
+ }
+
+ // bottom border
+ for (unsigned int i=wwi.width*(wwi.height-1)+1; i<wwi.count-1; ++i)
+ {
+ // acceleration is acc
+ if (fixedIndex == i)
+ {
+ wwi.acceleration[i] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[i];
+ neibourgs[0] = wwi.position[i-1];
+ neibourgs[1] = wwi.position[i+1];
+ neibourgs[2] = wwi.position[i-wwi.width];
+
+ acceleration.x = (x_length - (pos.x - neibourgs[0].x))*m_raideur + \
((neibourgs[1].x - pos.x) - x_length)*m_raideur + (neibourgs[2].x - pos.x)*m_raideur; \
+ acceleration.y = (y_length - (pos.y - neibourgs[2].y))*m_raideur + \
(neibourgs[0].y - pos.y)*m_raideur + (neibourgs[1].y - pos.y)*m_raideur; +
+ acceleration.x /= 3;
+ acceleration.y /= 3;
+
+ wwi.acceleration[i] = acceleration;
+ }
+ }
+
+ // left border
+ for (unsigned int i=wwi.width; i<wwi.width*(wwi.height-1); i+=wwi.width)
+ {
+ // acceleration is acc
+ if (fixedIndex == i)
+ {
+ wwi.acceleration[i] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[i];
+ neibourgs[0] = wwi.position[i+1];
+ neibourgs[1] = wwi.position[i-wwi.width];
+ neibourgs[2] = wwi.position[i+wwi.width];
+
+ acceleration.x = ((neibourgs[0].x - pos.x) - x_length)*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur + (neibourgs[2].x - pos.x)*m_raideur; + \
acceleration.y = (y_length - (pos.y - neibourgs[1].y))*m_raideur + ((neibourgs[2].y - \
pos.y) - y_length)*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 3;
+ acceleration.y /= 3;
+
+ wwi.acceleration[i] = acceleration;
+ }
+ }
+
+ // right border
+ for (unsigned int i=2*wwi.width-1; i<wwi.count-1; i+=wwi.width)
+ {
+ // acceleration is acc
+ if (fixedIndex == i)
+ {
+ wwi.acceleration[i] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[i];
+ neibourgs[0] = wwi.position[i-1];
+ neibourgs[1] = wwi.position[i-wwi.width];
+ neibourgs[2] = wwi.position[i+wwi.width];
+
+ acceleration.x = (x_length - (pos.x - neibourgs[0].x))*m_raideur + \
(neibourgs[1].x - pos.x)*m_raideur + (neibourgs[2].x - pos.x)*m_raideur; + \
acceleration.y = (y_length - (pos.y - neibourgs[1].y))*m_raideur + ((neibourgs[2].y - \
pos.y) - y_length)*m_raideur + (neibourgs[0].y - pos.y)*m_raideur; +
+ acceleration.x /= 3;
+ acceleration.y /= 3;
+
+ wwi.acceleration[i] = acceleration;
+ }
+ }
+
+ // 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;
+
+ // acceleration is acc
+ if (fixedIndex == index)
+ {
+ wwi.acceleration[index] = acc;
+ }
+ else
+ {
+ Pair& pos = wwi.position[index];
+ neibourgs[0] = wwi.position[index-1];
+ neibourgs[1] = wwi.position[index+1];
+ neibourgs[2] = wwi.position[index-wwi.width];
+ neibourgs[3] = wwi.position[index+wwi.width];
+
+ acceleration.x = ((neibourgs[0].x - pos.x) - x_length)*m_raideur +
+ (x_length - (pos.x - neibourgs[1].x))*m_raideur +
+ (neibourgs[2].x - pos.x)*m_raideur +
+ (neibourgs[3].x - pos.x)*m_raideur;
+ acceleration.y = (y_length - (pos.y - neibourgs[2].y))*m_raideur +
+ ((neibourgs[3].y - pos.y) - y_length)*m_raideur +
+ (neibourgs[0].y - pos.y)*m_raideur +
+ (neibourgs[1].y - pos.y)*m_raideur;
+
+ acceleration.x /= 4;
+ acceleration.y /= 4;
+
+ wwi.acceleration[index] = acceleration;
+ }
+ }
+ }
+
+ switch (m_accelerationFilter)
+ {
+ case NoFilter:
+ break;
+
+ case FourRingLinearMean:
+ fourRingLinearMean(&wwi.acceleration, wwi);
+ break;
+
+ case MeanWithMean:
+ meanWithMean(&wwi.acceleration, wwi);
+ break;
+
+ case MeanWithMedian:
+ meanWithMedian(&wwi.acceleration, wwi);
+ break;
+
+ default:
+ ASSERT1(false);
+ }
+
+#if defined COMPUTE_STATS
+ Pair accBound = {maxAcceleration, minAcceleration};
+ Pair velBound = {maxVelocity, minVelocity};
+#endif
+
+ // compute the new velocity of each vertex.
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ Pair acc = wwi.acceleration[i];
+ fixVectorBounds(acc, m_minAcceleration, m_maxAcceleration);
+
+#if defined COMPUTE_STATS
+ computeVectorBounds(acc, accBound);
+#endif
+
+ Pair& vel = wwi.velocity[i];
+ vel.x = acc.x*time + vel.x*m_amortissement;
+ vel.y = acc.y*time + vel.y*m_amortissement;
+
+ acc_sum += fabs(acc.x) + fabs(acc.y);
+ }
+
+
+ switch (m_velocityFilter)
+ {
+ case NoFilter:
+ break;
+
+ case FourRingLinearMean:
+ fourRingLinearMean(&wwi.velocity, wwi);
+ break;
+
+ case MeanWithMean:
+ meanWithMean(&wwi.velocity, wwi);
+ break;
+
+ case MeanWithMedian:
+ meanWithMedian(&wwi.velocity, wwi);
+ break;
+
+ default:
+ ASSERT1(false);
+ }
+
+ Pair topLeftCorner = {-10000.0, -10000.0};
+ Pair bottomRightCorner = {10000.0, 10000.0};
+
+ // compute the new pos of each vertex.
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ Pair& pos = wwi.position[i];
+ Pair& vel = wwi.velocity[i];
+
+ fixVectorBounds(vel, m_minVelocity, m_maxVelocity);
+#if defined COMPUTE_STATS
+ computeVectorBounds(vel, velBound);
+#endif
+
+ pos.x += vel.x*time*m_move_factor;
+ pos.y += vel.y*time*m_move_factor;
+
+ if (pos.x < topLeftCorner.x)
+ {
+ topLeftCorner.x = pos.x;
+ }
+ if (pos.x > bottomRightCorner.x)
+ {
+ bottomRightCorner.x = pos.x;
+ }
+ if (pos.y < topLeftCorner.y)
+ {
+ topLeftCorner.y = pos.y;
+ }
+ if (pos.y > bottomRightCorner.y)
+ {
+ bottomRightCorner.y = pos.y;
+ }
+
+ vel_sum += fabs(vel.x) + fabs(vel.y);
+
+#if defined VERBOSE_MODE
+ if (fixedIndex == i)
+ {
+ kDebug() << "Fixed item ** vel : " << vel.x << "," << vel.y << " ** move \
: " << vel.x*time << "," << vel.y*time; + }
+#endif
+ }
+
+#if defined VERBOSE_MODE
+# if defined COMPUTE_STATS
+ kDebug() << "Acceleration bounds (" << accBound.x << ", " << accBound.y << \
")"; + kDebug() << "Velocity bounds (" << velBound.x << ", " << velBound.y << \
")"; +# endif
+ kDebug() << "sum_acc : " << acc_sum << " *** sum_vel :" << vel_sum;
+#endif
+
+ if (!wwi.onConstrain && acc_sum < m_stopAcceleration && vel_sum < \
m_stopVelocity) + {
+ freeWobblyInfo(wwi);
+ windows.remove(w);
+ return false;
+ }
+
+ QRect windowRect(topLeftCorner.x, topLeftCorner.y,
+ bottomRightCorner.x - topLeftCorner.x, bottomRightCorner.y - \
topLeftCorner.y); + if (m_updateRegion.isValid())
+ {
+ m_updateRegion = m_updateRegion.united(windowRect);
+ }
+ else
+ {
+ m_updateRegion = windowRect;
+ }
+
+ return true;
+}
+
+void WobblyWindowsEffect::fourRingLinearMean(Pair** datas_pointer, \
WindowWobblyInfos& wwi) +{
+ Pair* datas = *datas_pointer;
+ Pair neibourgs[4];
+
+ // for corners
+
+ // top-left
+ {
+ Pair& res = wwi.buffer[0];
+ Pair vit = datas[0];
+ neibourgs[0] = datas[1];
+ neibourgs[1] = datas[wwi.width];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.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];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.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)];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.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];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.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];
+
+ 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 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];
+
+ 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; + }
+
+ // 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];
+
+ 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; + }
+
+ // 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];
+
+ 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 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];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + neibourgs[2].x + \
neibourgs[3].x + 4.0*vit.x) / 8.0; + res.y = (neibourgs[0].y + \
neibourgs[1].y + neibourgs[2].y + neibourgs[3].y + 4.0*vit.y) / 8.0; + }
+ }
+
+ Pair* tmp = datas;
+ *datas_pointer = wwi.buffer;
+ wwi.buffer = tmp;
+}
+
+void WobblyWindowsEffect::meanWithMean(Pair** datas_pointer, WindowWobblyInfos& wwi)
+{
+ Pair* datas = *datas_pointer;
+
+ Pair mean = {0.0, 0.0};
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ mean.x += datas[i].x;
+ mean.y += datas[i].y;
+ }
+
+ mean.x /= wwi.count;
+ mean.y /= wwi.count;
+
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ wwi.buffer[i].x = (datas[i].x + mean.x) / 2.0;
+ wwi.buffer[i].y = (datas[i].y + mean.y) / 2.0;
+ }
+
+ Pair* tmp = datas;
+ *datas_pointer = wwi.buffer;
+ wwi.buffer = tmp;
+}
+
+void WobblyWindowsEffect::meanWithMedian(Pair** datas_pointer, WindowWobblyInfos& \
wwi) +{
+ Pair* datas = *datas_pointer;
+
+ qreal xmin = datas[0].x, ymin = datas[0].y;
+ qreal xmax = datas[0].x, ymax = datas[0].y;
+ for (unsigned int i = 1; i < wwi.count; ++i)
+ {
+ if (datas[i].x < xmin)
+ {
+ xmin = datas[i].x;
+ }
+ if (datas[i].x > xmax)
+ {
+ xmax = datas[i].x;
+ }
+
+ if (datas[i].y < ymin)
+ {
+ ymin = datas[i].y;
+ }
+ if (datas[i].y > ymax)
+ {
+ ymax = datas[i].y;
+ }
+ }
+
+ Pair median = {(xmin + xmax)/2.0, (ymin + ymax)/2.0};
+
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ wwi.buffer[i].x = (datas[i].x + median.x) / 2.0;
+ wwi.buffer[i].y = (datas[i].y + median.y) / 2.0;
+ }
+
+ Pair* tmp = datas;
+ *datas_pointer = wwi.buffer;
+ wwi.buffer = tmp;
+}
+
+
+} // namespace
+
Index: effects/test/wobbly_config.ui
===================================================================
--- effects/test/wobbly_config.ui (revision 0)
+++ effects/test/wobbly_config.ui (revision 0)
@@ -0,0 +1,642 @@
+<ui version="4.0" >
+ <class>KWin::WobblyWindowsEffectConfigForm</class>
+ <widget class="QWidget" name="KWin::WobblyWindowsEffectConfigForm" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>553</width>
+ <height>383</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>WobblyWindows</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Grid Parameters</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Maximum" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Grid Minimal Tesselation</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Horizontal Nodes :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="spHNodes" >
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="value" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Vertical Nodes :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="spVNodes" >
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="value" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item rowspan="2" row="0" column="1" >
+ <widget class="QGroupBox" name="groupBox_4" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Grid Parameters</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Raideur :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QDoubleSpinBox" name="spRaideur" >
+ <property name="maximum" >
+ <double>2.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.020000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.500000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QSlider" name="slRaideur" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>25</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Amortissement :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QDoubleSpinBox" name="spAmortissement" >
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.940000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3" >
+ <widget class="QSlider" name="slAmortissement" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>94</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3" >
+ <widget class="Line" name="line_4" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Move Factor :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="2" >
+ <widget class="QDoubleSpinBox" name="spMovFactor" >
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="3" >
+ <widget class="QSlider" name="slMovFactor" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>1</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QGroupBox" name="groupBox_5" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Maximum" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Grid Filter</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QComboBox" name="cbGridFilter" >
+ <item>
+ <property name="text" >
+ <string>Velocity</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Acceleration</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="rbNone" >
+ <property name="text" >
+ <string>None</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="rbRingMean" >
+ <property name="text" >
+ <string>Ring Mean</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="rbMeanMean" >
+ <property name="text" >
+ <string>Mean With Mean</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="rbMeanMedian" >
+ <property name="text" >
+ <string>Mean With Median</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2" >
+ <attribute name="title" >
+ <string>Thresholds</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Velocity</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Min Velocity</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="2" colspan="2" >
+ <widget class="QDoubleSpinBox" name="spMinVel" >
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.500000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4" >
+ <widget class="QSlider" name="slMinVel" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>50</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4" >
+ <widget class="Line" name="line_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Max Velocity</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="3" >
+ <widget class="QDoubleSpinBox" name="spMaxVel" >
+ <property name="maximum" >
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value" >
+ <double>500.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4" >
+ <widget class="QSlider" name="slMaxVel" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>50</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="4" >
+ <widget class="Line" name="line_3" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="text" >
+ <string>Velocity Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="3" >
+ <widget class="QDoubleSpinBox" name="spStopVel" >
+ <property name="maximum" >
+ <double>10.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value" >
+ <double>3.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="4" >
+ <widget class="QSlider" name="slStopVel" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>30</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="title" >
+ <string>Acceleration</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_8" >
+ <property name="text" >
+ <string>Min Acceleration</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QDoubleSpinBox" name="spMinAcc" >
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.100000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4" >
+ <widget class="QSlider" name="slMinAcc" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>10</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4" >
+ <widget class="Line" name="line_5" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QLabel" name="label_9" >
+ <property name="text" >
+ <string>Max Acceleration</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="3" >
+ <widget class="QDoubleSpinBox" name="spMaxAcc" >
+ <property name="maximum" >
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value" >
+ <double>500.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4" >
+ <widget class="QSlider" name="slMaxAcc" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>50</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="4" >
+ <widget class="Line" name="line_6" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2" >
+ <widget class="QLabel" name="label_11" >
+ <property name="text" >
+ <string>Acceleration Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="3" >
+ <widget class="QDoubleSpinBox" name="spStopAcc" >
+ <property name="maximum" >
+ <double>10.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value" >
+ <double>8.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="4" >
+ <widget class="QSlider" name="slStopAcc" >
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>80</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Index: effects/test/wobbly_config.cpp
===================================================================
--- effects/test/wobbly_config.cpp (revision 0)
+++ effects/test/wobbly_config.cpp (revision 0)
@@ -0,0 +1,503 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2007
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#include "wobbly_config.h"
+#include "demo_wobblywindows_constants.h"
+
+#include <kwineffects.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <KActionCollection>
+#include <kaction.h>
+#include <KGlobalAccel>
+#include <kconfiggroup.h>
+
+#include <QGridLayout>
+#ifndef KDE_USE_FINAL
+K_PLUGIN_FACTORY_DECLARATION(TestEffectFactory)
+#endif
+
+namespace KWin
+{
+
+WobblyEffectConfig::WobblyEffectConfig(QWidget* parent, const QVariantList& args) :
+KCModule(TestEffectFactory::componentData(), parent, args)
+{
+ m_ui.setupUi(this);
+
+ connect(m_ui.spRaideur, SIGNAL(valueChanged(double)), this, \
SLOT(slotSpRaideur(double))); + connect(m_ui.slRaideur, SIGNAL(sliderMoved(int)), \
this, SLOT(slotSlRaideur(int))); + connect(m_ui.spAmortissement, \
SIGNAL(valueChanged(double)), this, SLOT(slotSpAmortissement(double))); + \
connect(m_ui.slAmortissement, SIGNAL(sliderMoved(int)), this, \
SLOT(slotSlAmortissement(int))); + connect(m_ui.spMovFactor, \
SIGNAL(valueChanged(double)), this, SLOT(slotSpMovFactor(double))); + \
connect(m_ui.slMovFactor, SIGNAL(sliderMoved(int)), this, \
SLOT(slotSlMovFactor(int))); +
+ 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.rbMeanMean, SIGNAL(toggled(bool)), \
this, SLOT(slotRbMeanMean(bool))); + connect(m_ui.rbMeanMedian, \
SIGNAL(toggled(bool)), this, SLOT(slotRbMeanMedian(bool))); +
+ connect(m_ui.spMinVel, SIGNAL(valueChanged(double)), this, \
SLOT(slotSpMinVel(double))); + connect(m_ui.slMinVel, SIGNAL(sliderMoved(int)), \
this, SLOT(slotSlMinVel(int))); + connect(m_ui.spMaxVel, \
SIGNAL(valueChanged(double)), this, SLOT(slotSpMaxVel(double))); + \
connect(m_ui.slMaxVel, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMaxVel(int))); + \
connect(m_ui.spStopVel, SIGNAL(valueChanged(double)), this, \
SLOT(slotSpStopVel(double))); + connect(m_ui.slStopVel, SIGNAL(sliderMoved(int)), \
this, SLOT(slotSlStopVel(int))); + connect(m_ui.spMinAcc, \
SIGNAL(valueChanged(double)), this, SLOT(slotSpMinAcc(double))); + \
connect(m_ui.slMinAcc, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMinAcc(int))); + \
connect(m_ui.spMaxAcc, SIGNAL(valueChanged(double)), this, \
SLOT(slotSpMaxAcc(double))); + connect(m_ui.slMaxAcc, SIGNAL(sliderMoved(int)), \
this, SLOT(slotSlMaxAcc(int))); + connect(m_ui.spStopAcc, \
SIGNAL(valueChanged(double)), this, SLOT(slotSpStopAcc(double))); + \
connect(m_ui.slStopAcc, SIGNAL(sliderMoved(int)), this, SLOT(slotSlStopAcc(int))); +
+ load();
+}
+
+WobblyEffectConfig::~WobblyEffectConfig()
+{
+}
+
+void WobblyEffectConfig::load()
+{
+ KCModule::load();
+
+ KConfigGroup conf = EffectsHandler::effectConfig("Wobbly");
+ qreal raideur = conf.readEntry("Raideur", RAIDEUR);
+ qreal amortissement = conf.readEntry("Amortissement", AMORTISSEMENT);
+ qreal move_factor = conf.readEntry("MoveFactor", MOVEFACTOR);
+
+ m_ui.spRaideur->setValue(raideur);
+ m_ui.slRaideur->setSliderPosition(raideur*50);
+
+ m_ui.spAmortissement->setValue(amortissement);
+ m_ui.slAmortissement->setSliderPosition(amortissement*100);
+
+ m_ui.spMovFactor->setValue(move_factor);
+ m_ui.slMovFactor->setValue(move_factor*100);
+
+ int xTesselation = conf.readEntry("XTesselation", XTESSELATION);
+ int yTesselation = conf.readEntry("YTesselation", YTESSELATION);
+
+ m_ui.spHNodes->setValue(xTesselation);
+ m_ui.spVNodes->setValue(yTesselation);
+
+ //squareRootMasterAcceleration = conf.readEntry("SquareRootMasterAcceleration", \
false); +
+ QString velFilter = conf.readEntry("VelocityFilter", VELOCITYFILTER);
+ if (velFilter == "NoFilter")
+ {
+ velocityFilter = NoFilter;
+ }
+ else if (velFilter == "FourRingLinearMean")
+ {
+ velocityFilter = FourRingLinearMean;
+ }
+ else if (velFilter == "MeanWithMean")
+ {
+ velocityFilter = MeanWithMean;
+ }
+ else if (velFilter == "MeanWithMedian")
+ {
+ velocityFilter = MeanWithMedian;
+ }
+ else
+ {
+ velocityFilter = FourRingLinearMean;
+ kDebug() << "Unknown config value for VelocityFilter : " << velFilter;
+ }
+
+
+ QString accFilter = conf.readEntry("AccelerationFilter", ACCELERATIONFILTER);
+ if (accFilter == "NoFilter")
+ {
+ accelerationFilter = NoFilter;
+ }
+ else if (accFilter == "FourRingLinearMean")
+ {
+ accelerationFilter = FourRingLinearMean;
+ }
+ else if (accFilter == "MeanWithMean")
+ {
+ accelerationFilter = MeanWithMean;
+ }
+ else if (accFilter == "MeanWithMedian")
+ {
+ accelerationFilter = MeanWithMedian;
+ }
+ else
+ {
+ accelerationFilter = NoFilter;
+ kDebug() << "Unknown config value for accelerationFilter : " << accFilter;
+ }
+
+ qreal minVel = conf.readEntry("MinVelocity", MINVELOCITY);
+ qreal maxVel = conf.readEntry("MaxVelocity", MAXVELOCITY);
+ qreal stopVel = conf.readEntry("StopVelocity", STOPVELOCITY);
+ qreal minAcc = conf.readEntry("MinAcceleration", MINACCELERATION);
+ qreal maxAcc = conf.readEntry("MaxAcceleration", MAXACCELERATION);
+ qreal stopAcc = conf.readEntry("StopAcceleration", STOPACCELERATION);
+
+ m_ui.spMinVel->setValue(minVel);
+ m_ui.slMinVel->setSliderPosition(minVel*100);
+ m_ui.spMaxVel->setValue(maxVel);
+ m_ui.slMaxVel->setSliderPosition(maxVel/10);
+ m_ui.spStopVel->setValue(stopVel);
+ m_ui.slStopVel->setSliderPosition(stopVel*10);
+ m_ui.spMinAcc->setValue(minAcc);
+ m_ui.slMinAcc->setSliderPosition(minAcc*100);
+ m_ui.spMaxAcc->setValue(maxAcc);
+ m_ui.slMaxAcc->setSliderPosition(maxAcc/10);
+ m_ui.spStopAcc->setValue(stopAcc);
+ m_ui.slStopAcc->setSliderPosition(stopAcc*10);
+
+ emit changed(false);
+}
+
+void WobblyEffectConfig::save()
+{
+ KConfigGroup conf = EffectsHandler::effectConfig("Wobbly");
+
+ conf.writeEntry("Raideur", m_ui.spRaideur->value());
+ conf.writeEntry("Amortissement", m_ui.spAmortissement->value());
+ conf.writeEntry("MoveFactor", m_ui.spMovFactor->value());
+
+ conf.writeEntry("XTesselation", m_ui.spHNodes->value());
+ conf.writeEntry("YTesselation", m_ui.spVNodes->value());
+
+ switch (velocityFilter)
+ {
+ case NoFilter:
+ conf.writeEntry("VelocityFilter", "NoFilter");
+ break;
+
+ case FourRingLinearMean:
+ conf.writeEntry("VelocityFilter", "FourRingLinearMean");
+ break;
+
+ case MeanWithMean:
+ conf.writeEntry("VelocityFilter", "MeanWithMean");
+ break;
+
+ case MeanWithMedian:
+ conf.writeEntry("VelocityFilter", "MeanWithMedian");
+ break;
+ }
+
+ switch (accelerationFilter)
+ {
+ case NoFilter:
+ conf.writeEntry("AccelerationFilter", "NoFilter");
+ break;
+
+ case FourRingLinearMean:
+ conf.writeEntry("AccelerationFilter", "FourRingLinearMean");
+ break;
+
+ case MeanWithMean:
+ conf.writeEntry("AccelerationFilter", "MeanWithMean");
+ break;
+
+ case MeanWithMedian:
+ conf.writeEntry("AccelerationFilter", "MeanWithMedian");
+ break;
+ }
+
+ conf.writeEntry("MinVelocity", m_ui.spMinVel->value());
+ conf.writeEntry("MaxVelocity", m_ui.spMaxVel->value());
+ conf.writeEntry("StopVelocity", m_ui.spStopVel->value());
+ conf.writeEntry("MinAcceleration", m_ui.spMinAcc->value());
+ conf.writeEntry("MaxAcceleration", m_ui.spMaxAcc->value());
+ conf.writeEntry("StopAcceleration", m_ui.spStopAcc->value());
+
+ conf.sync();
+
+ emit changed(false);
+ EffectsHandler::sendReloadMessage("demo_wobblywindows");
+}
+
+void WobblyEffectConfig::defaults()
+{
+ m_ui.spRaideur->setValue(RAIDEUR);
+ m_ui.slRaideur->setSliderPosition(RAIDEUR*50);
+
+ m_ui.spAmortissement->setValue(AMORTISSEMENT);
+ m_ui.slAmortissement->setSliderPosition(AMORTISSEMENT*100);
+
+ m_ui.spMovFactor->setValue(MOVEFACTOR);
+ m_ui.slMovFactor->setValue(MOVEFACTOR*100);
+
+ m_ui.spHNodes->setValue(XTESSELATION);
+ m_ui.spVNodes->setValue(YTESSELATION);
+
+ velocityFilter = FourRingLinearMean;
+ accelerationFilter = NoFilter;
+ slotGridParameterSelected(m_ui.cbGridFilter->currentIndex());
+
+ m_ui.spMinVel->setValue(MINVELOCITY);
+ m_ui.slMinVel->setSliderPosition(MINVELOCITY*100);
+
+ m_ui.spMaxVel->setValue(MAXVELOCITY);
+ m_ui.slMaxVel->setSliderPosition(MAXVELOCITY/10);
+
+ m_ui.spStopVel->setValue(STOPVELOCITY);
+ m_ui.slStopVel->setSliderPosition(STOPVELOCITY*10);
+
+ m_ui.spMinAcc->setValue(MINACCELERATION);
+ m_ui.slMinAcc->setSliderPosition(MINACCELERATION*100);
+
+ m_ui.spMaxAcc->setValue(MAXACCELERATION);
+ m_ui.slMaxAcc->setSliderPosition(MAXACCELERATION/10);
+
+ m_ui.spStopAcc->setValue(STOPACCELERATION);
+ m_ui.slStopAcc->setSliderPosition(STOPACCELERATION*10);
+
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpRaideur(double value)
+{
+ m_ui.slRaideur->setSliderPosition(value*50);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlRaideur(int value)
+{
+ m_ui.spRaideur->setValue(value/50.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpAmortissement(double value)
+{
+ m_ui.slAmortissement->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlAmortissement(int value)
+{
+ m_ui.spAmortissement->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpMovFactor(double value)
+{
+ m_ui.slMovFactor->setValue(value*100);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlMovFactor(int value)
+{
+ m_ui.spMovFactor->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+// filters
+
+void WobblyEffectConfig::slotRbNone(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = NoFilter;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = NoFilter;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotRbRingMean(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = FourRingLinearMean;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = FourRingLinearMean;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotRbMeanMean(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = MeanWithMean;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = MeanWithMean;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotRbMeanMedian(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = MeanWithMedian;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = MeanWithMedian;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotGridParameterSelected(int index)
+{
+ if (index == 0) // velocity
+ {
+ switch (velocityFilter)
+ {
+ case NoFilter:
+ m_ui.rbNone->setChecked(true);
+ break;
+
+ case FourRingLinearMean:
+ m_ui.rbRingMean->setChecked(true);
+ break;
+
+ case MeanWithMean:
+ m_ui.rbMeanMean->setChecked(true);
+ break;
+
+ case MeanWithMedian:
+ m_ui.rbMeanMedian->setChecked(true);
+ break;
+ }
+ }
+ else if (index == 1) // acceleration
+ {
+ switch (accelerationFilter)
+ {
+ case NoFilter:
+ m_ui.rbNone->setChecked(true);
+ break;
+
+ case FourRingLinearMean:
+ m_ui.rbRingMean->setChecked(true);
+ break;
+
+ case MeanWithMean:
+ m_ui.rbMeanMean->setChecked(true);
+ break;
+
+ case MeanWithMedian:
+ m_ui.rbMeanMedian->setChecked(true);
+ break;
+ }
+ }
+ emit changed(true);
+}
+
+// thresholds
+
+void WobblyEffectConfig::slotSpMinVel(double value)
+{
+ m_ui.slMinVel->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlMinVel(int value)
+{
+ m_ui.spMinVel->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpMaxVel(double value)
+{
+ m_ui.slMaxVel->setSliderPosition(value/10);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlMaxVel(int value)
+{
+ m_ui.spMaxVel->setValue(value*10.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpStopVel(double value)
+{
+ m_ui.slStopVel->setSliderPosition(value*10);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlStopVel(int value)
+{
+ m_ui.spStopVel->setValue(value/10.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpMinAcc(double value)
+{
+ m_ui.slMinAcc->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlMinAcc(int value)
+{
+ m_ui.spMinAcc->setValue(value/100.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpMaxAcc(double value)
+{
+ m_ui.slMaxAcc->setSliderPosition(value/10);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlMaxAcc(int value)
+{
+ m_ui.spMaxAcc->setValue(value*10.0);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSpStopAcc(double value)
+{
+ m_ui.slStopAcc->setSliderPosition(value*10);
+ emit changed(true);
+}
+
+void WobblyEffectConfig::slotSlStopAcc(int value)
+{
+ m_ui.spStopAcc->setValue(value/10.0);
+ emit changed(true);
+}
+
+
+} // namespace
+
+#include "wobbly_config.moc"
Index: effects/test/CMakeLists.txt
===================================================================
--- effects/test/CMakeLists.txt (revision 777553)
+++ effects/test/CMakeLists.txt (working copy)
@@ -6,8 +6,18 @@
endmacro(KWIN4_ADD_EFFECT)
macro(KWIN4_ADD_EFFECT_CONFIG name)
- kde4_add_plugin(kcm_kwin4_effect_${name} ${ARGN})
- target_link_libraries(kcm_kwin4_effect_${name} kwineffects ${KDE4_KDEUI_LIBS})
+ set(kwin4_effect_ui ) #empty
+ set(kwin4_effect_src ) #empty
+ foreach(file ${ARGN})
+ if(file MATCHES \\.ui)
+ set(kwin4_effect_ui ${kwin4_effect_ui} ${file})
+ else(file MATCHES \\.ui)
+ set(kwin4_effect_src ${kwin4_effect_src} ${file})
+ endif(file MATCHES \\.ui)
+ endforeach(file)
+ kde4_add_ui_files(kwin4_effect_src ${kwin4_effect_ui})
+ kde4_add_plugin(kcm_kwin4_effect_${name} ${kwin4_effect_src})
+ target_link_libraries(kcm_kwin4_effect_${name} kwineffects ${KDE4_KIO_LIBS} \
${KDE4_KDEUI_LIBS})
install(TARGETS kcm_kwin4_effect_${name} DESTINATION ${PLUGIN_INSTALL_DIR})
endmacro(KWIN4_ADD_EFFECT_CONFIG)
@@ -42,6 +52,7 @@
demo_liquid.cpp
demo_showpicture.cpp
demo_wavywindows.cpp
+ demo_wobblywindows.cpp
test_fbo.cpp
)
@@ -49,6 +60,7 @@
demo_liquid.desktop
demo_showpicture.desktop
demo_wavywindows.desktop
+ demo_wobblywindows.desktop
test_fbo.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
@@ -56,8 +68,19 @@
data/liquid.frag
data/liquid.vert
DESTINATION ${DATA_INSTALL_DIR}/kwin )
+
+ SET(kwin4_effect_tests_config_sources ${kwin4_effect_tests_config_sources}
+ wobbly_config.ui
+ wobbly_config.cpp
+ config_test.cpp
+ )
+
+ install( FILES
+ wobbly_config.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
+
endif(OPENGL_FOUND)
# add the plugin
KWIN4_ADD_EFFECT(tests ${kwin4_effect_tests_sources})
-
+KWIN4_ADD_EFFECT_CONFIG(tests ${kwin4_effect_tests_config_sources})
Index: effects/test/demo_wobblywindows.desktop
===================================================================
--- effects/test/demo_wobblywindows.desktop (revision 0)
+++ effects/test/demo_wobblywindows.desktop (revision 0)
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Demo Wobbly Windows
+Icon=kwin-effect-wavywindows
+
+Type=Service
+ServiceTypes=KWin/Effect
+X-KDE-PluginInfo-Author=
+X-KDE-PluginInfo-Email=
+X-KDE-PluginInfo-Name=kwin4_effect_demo_wobblywindows
+X-KDE-PluginInfo-Version=0.1.0
+X-KDE-PluginInfo-Category=Demos
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+X-KDE-Library=kwin4_effect_tests
Index: effects/test/config_test.cpp
===================================================================
--- effects/test/config_test.cpp (revision 0)
+++ effects/test/config_test.cpp (revision 0)
@@ -0,0 +1,50 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#include <kwinconfig.h>
+
+#ifdef KWIN_HAVE_OPENGL_COMPOSITING
+#include "wobbly_config.h"
+#endif
+
+#include <kwineffects.h>
+
+#include <KPluginLoader>
+#ifndef KDE_USE_FINAL
+K_PLUGIN_FACTORY_DECLARATION(TestEffectFactory)
+#endif
+
+#define NON_GL_PLUGINS
+
+#define GL_PLUGINS \
+ registerPlugin<KWin::WobblyEffectConfig>("demo_wobblywindows"); \
+
+#ifdef KWIN_HAVE_OPENGL_COMPOSITING
+K_PLUGIN_FACTORY_DEFINITION(TestEffectFactory,
+ NON_GL_PLUGINS
+ GL_PLUGINS
+ )
+#else
+K_PLUGIN_FACTORY_DEFINITION(TestEffectFactory,
+ NON_GL_PLUGINS
+ )
+#endif
+K_EXPORT_PLUGIN(TestEffectFactory("kwin"))
Index: effects/test/wobbly_config.desktop
===================================================================
--- effects/test/wobbly_config.desktop (revision 0)
+++ effects/test/wobbly_config.desktop (revision 0)
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=KCModule
+
+X-KDE-Library=kcm_kwin4_effect_tests
+X-KDE-ParentComponents=kwin4_effect_demo_wobblywindows
+X-KDE-PluginKeyword=demo_wobblywindows
+
+Name=demo_wobblywindows
+
Index: effects/test/demo_wobblywindows_constants.h
===================================================================
--- effects/test/demo_wobblywindows_constants.h (revision 0)
+++ effects/test/demo_wobblywindows_constants.h (revision 0)
@@ -0,0 +1,21 @@
+
+#include <QtGlobal>
+
+static const qreal RAIDEUR = 0.5;
+static const qreal AMORTISSEMENT = 0.93;
+static const qreal MOVEFACTOR = 0.01;
+
+static const int XTESSELATION = 20;
+static const int YTESSELATION = 20;
+
+static const bool SQUAREROOTMASTERACCELERATION = false;
+
+static const qreal MINVELOCITY = 0.5;
+static const qreal MAXVELOCITY = 1000.0;
+static const qreal STOPVELOCITY = 5.0;
+static const qreal MINACCELERATION = 0.1;
+static const qreal MAXACCELERATION = 1000.0;
+static const qreal STOPACCELERATION = 10.0;
+
+static const char* VELOCITYFILTER = "FourRingLinearMean";
+static const char* ACCELERATIONFILTER = "NoFilter";
Index: effects/test/demo_wobblywindows.h
===================================================================
--- effects/test/demo_wobblywindows.h (revision 0)
+++ effects/test/demo_wobblywindows.h (revision 0)
@@ -0,0 +1,129 @@
+/*****************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2007
+
+You can Freely distribute this program under the GNU General Public
+License. See the file "COPYING" for the exact licensing terms.
+******************************************************************/
+
+#ifndef DEMO_WOBBLYWINDOWS_H
+#define DEMO_WOBBLYWINDOWS_H
+
+// Include with base class for effects.
+#include <kwineffects.h>
+
+namespace KWin
+{
+
+/**
+ * Demo effect which wobble windows
+ **/
+class WobblyWindowsEffect : public Effect
+{
+ public:
+
+ enum GridFilter
+ {
+ NoFilter,
+ FourRingLinearMean,
+ MeanWithMean,
+ MeanWithMedian
+ };
+
+
+ WobblyWindowsEffect();
+ virtual ~WobblyWindowsEffect();
+
+ virtual void prePaintScreen( ScreenPrePaintData& data, int time );
+ virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int \
time ); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, \
WindowPaintData& data ); + virtual void postPaintScreen();
+ virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last \
); + virtual void windowClosed( EffectWindow* c );
+
+ // Wobbly model parameters
+ void setRaideur(qreal raideur);
+ void setAmortissement(qreal amortissement);
+ void setVelocityThreshold(qreal velocityThreshold);
+ void setMoveFactor(qreal factor);
+
+ void setVelocityFilter(GridFilter filter);
+ void setAccelerationFilter(GridFilter filter);
+ GridFilter velocityFilter() const;
+ GridFilter accelerationFilter() const;
+
+ struct Pair
+ {
+ qreal x;
+ qreal y;
+ };
+
+ private:
+
+ bool updateWindowWobblyDatas(EffectWindow* w, qreal time);
+
+ struct WindowWobblyInfos
+ {
+ Pair* origin;
+ Pair* position;
+ Pair* velocity;
+ Pair* acceleration;
+ Pair* buffer;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int count;
+
+ int mPickedPointIndex;
+ Pair mPickedPointTranslation;
+ Pair mDestination;
+
+ Pair* bezierSurface;
+ unsigned int bezierWidth;
+ unsigned int bezierHeight;
+ unsigned int bezierCount;
+
+ bool onConstrain;
+ };
+
+ QHash< const EffectWindow*, WindowWobblyInfos > windows;
+
+ QRect m_updateRegion;
+
+ qreal m_raideur;
+ qreal m_amortissement;
+ qreal m_move_factor;
+
+ // the default tesselation for windows
+ // use qreal instead of int as I really often need
+ // these values as real to do divisions.
+ qreal m_xTesselation;
+ qreal m_yTesselation;
+
+ bool m_squareRootMasterAcceleration;
+
+ GridFilter m_velocityFilter;
+ GridFilter m_accelerationFilter;
+
+ qreal m_minVelocity;
+ qreal m_maxVelocity;
+ qreal m_stopVelocity;
+ qreal m_minAcceleration;
+ qreal m_maxAcceleration;
+ qreal m_stopAcceleration;
+
+ void initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) const;
+ void freeWobblyInfo(WindowWobblyInfos& wwi) const;
+
+ WobblyWindowsEffect::Pair computeBezierPoint(const WindowWobblyInfos& wwi, \
Pair point) const; +
+ static void fourRingLinearMean(Pair** datas, WindowWobblyInfos& wwi);
+ static void meanWithMean(Pair** datas, WindowWobblyInfos& wwi);
+ static void meanWithMedian(Pair** datas, WindowWobblyInfos& wwi);
+};
+
+} // namespace
+
+#endif // DEMO_WOBBLYWINDOWS_H
Index: effects/test/wobbly_config.h
===================================================================
--- effects/test/wobbly_config.h (revision 0)
+++ effects/test/wobbly_config.h (revision 0)
@@ -0,0 +1,93 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2007
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#ifndef KWIN_WOBBLY_CONFIG_H
+#define KWIN_WOBBLY_CONFIG_H
+
+#define KDE3_SUPPORT
+#include <kcmodule.h>
+#undef KDE3_SUPPORT
+
+#include "ui_wobbly_config.h"
+
+class KActionCollection;
+
+namespace KWin
+{
+
+class WobblyEffectConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ explicit WobblyEffectConfig(QWidget* parent = 0, const QVariantList& args = \
QVariantList()); + ~WobblyEffectConfig();
+
+public slots:
+ virtual void save();
+ virtual void load();
+ virtual void defaults();
+
+private:
+ enum GridFilter
+ {
+ NoFilter,
+ FourRingLinearMean,
+ MeanWithMean,
+ MeanWithMedian
+ };
+
+private slots:
+
+ void slotSpRaideur(double);
+ void slotSlRaideur(int);
+ void slotSpAmortissement(double);
+ void slotSlAmortissement(int);
+ void slotSpMovFactor(double);
+ void slotSlMovFactor(int);
+
+ void slotGridParameterSelected(int);
+ void slotRbNone(bool);
+ void slotRbRingMean(bool);
+ void slotRbMeanMean(bool);
+ void slotRbMeanMedian(bool);
+
+ void slotSpMinVel(double);
+ void slotSlMinVel(int);
+ void slotSpMaxVel(double);
+ void slotSlMaxVel(int);
+ void slotSpStopVel(double);
+ void slotSlStopVel(int);
+ void slotSpMinAcc(double);
+ void slotSlMinAcc(int);
+ void slotSpMaxAcc(double);
+ void slotSlMaxAcc(int);
+ void slotSpStopAcc(double);
+ void slotSlStopAcc(int);
+
+private:
+ Ui::WobblyWindowsEffectConfigForm m_ui;
+
+ GridFilter velocityFilter;
+ GridFilter accelerationFilter;
+};
+
+} // namespace
+
+#endif
Index: lib/kwineffects.cpp
===================================================================
--- lib/kwineffects.cpp (revision 777553)
+++ lib/kwineffects.cpp (working copy)
@@ -613,6 +613,52 @@
return ret;
}
+WindowQuadList WindowQuadList::makeRegularGrid( int xSubdivisions, int ySubdivisions \
) const + {
+ if( empty())
+ return *this;
+ // find the bounding rectangle
+ double left = first().left();
+ double right = first().right();
+ double top = first().top();
+ double bottom = first().bottom();
+ foreach( WindowQuad quad, *this )
+ {
+#ifndef NDEBUG
+ if( quad.isTransformed())
+ kFatal( 1212 ) << "Splitting quads is allowed only in pre-paint calls!" \
; +#endif
+ left = qMin( left, quad.left());
+ right = qMax( right, quad.right());
+ top = qMin( top, quad.top());
+ bottom = qMax( bottom, quad.bottom());
+ }
+
+ double xincrement = (right - left) / xSubdivisions;
+ double yincrement = (bottom - top) / ySubdivisions;
+ WindowQuadList ret;
+ for( double y = top;
+ y < bottom;
+ y += yincrement )
+ {
+ for( double x = left;
+ x < right;
+ x += xincrement)
+ {
+ foreach( WindowQuad quad, *this )
+ {
+ if( QRectF( QPointF( quad.left(), quad.top()), QPointF( \
quad.right(), quad.bottom())) + .intersects( QRectF( x, y, \
xincrement, yincrement ))) + {
+ ret.append( quad.makeSubQuad( qMax( x, quad.left()), qMax( y, \
quad.top()), + qMin( quad.right(), x + xincrement ), qMin( \
quad.bottom(), y + yincrement ))); + }
+ }
+ }
+ }
+ return ret;
+ }
+
void WindowQuadList::makeArrays( float** vertices, float** texcoords ) const
{
*vertices = new float[ count() * 4 * 2 ];
Index: lib/kwineffects.h
===================================================================
--- lib/kwineffects.h (revision 777553)
+++ lib/kwineffects.h (working copy)
@@ -738,6 +738,7 @@
WindowQuadList splitAtX( double x ) const;
WindowQuadList splitAtY( double y ) const;
WindowQuadList makeGrid( int maxquadsize ) const;
+ WindowQuadList makeRegularGrid( int xSubdivisions, int ySubdivisions ) \
const; WindowQuadList select( WindowQuadType type ) const;
WindowQuadList filterOut( WindowQuadType type ) const;
bool smoothNeeded() const;
_______________________________________________
Kwin mailing list
Kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic