2009-02-06 18:53:16 +00:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
|
|
|
|
|
|
|
|
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 "cubeslide.h"
|
|
|
|
|
|
|
|
#include <kwinconfig.h>
|
|
|
|
#include <kconfiggroup.h>
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2010-12-18 09:18:54 +00:00
|
|
|
#include <kwinglutils.h>
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
KWIN_EFFECT(cubeslide, CubeSlideEffect)
|
|
|
|
KWIN_EFFECT_SUPPORTED(cubeslide, CubeSlideEffect::supported())
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
CubeSlideEffect::CubeSlideEffect()
|
2011-01-30 14:34:42 +00:00
|
|
|
: windowMoving(false)
|
|
|
|
, desktopChangedWhileMoving(false)
|
|
|
|
, progressRestriction(0.0f)
|
|
|
|
{
|
2011-02-25 19:41:10 +00:00
|
|
|
connect(effects, SIGNAL(desktopChanged(int, int)), this, SLOT(slotDesktopChanged(int, int)));
|
2011-01-30 14:34:42 +00:00
|
|
|
reconfigure(ReconfigureAll);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
CubeSlideEffect::~CubeSlideEffect()
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
bool CubeSlideEffect::supported()
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
2009-02-06 18:53:16 +00:00
|
|
|
return effects->compositingType() == OpenGLCompositing;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::reconfigure(ReconfigureFlags)
|
|
|
|
{
|
|
|
|
KConfigGroup conf = effects->effectConfig("CubeSlide");
|
|
|
|
rotationDuration = animationTime(conf, "RotationDuration", 500);
|
|
|
|
timeLine.setCurveShape(TimeLine::EaseInOutCurve);
|
|
|
|
timeLine.setDuration(rotationDuration);
|
|
|
|
dontSlidePanels = conf.readEntry("DontSlidePanels", true);
|
|
|
|
dontSlideStickyWindows = conf.readEntry("DontSlideStickyWindows", false);
|
|
|
|
usePagerLayout = conf.readEntry("UsePagerLayout", true);
|
|
|
|
useWindowMoving = conf.readEntry("UseWindowMoving", false);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty()) {
|
2009-02-06 18:53:16 +00:00
|
|
|
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
2011-01-30 14:34:42 +00:00
|
|
|
timeLine.addTime(time);
|
|
|
|
if (windowMoving && timeLine.progress() > progressRestriction)
|
|
|
|
timeLine.setProgress(progressRestriction);
|
|
|
|
if (dontSlidePanels)
|
2009-02-06 18:53:16 +00:00
|
|
|
panels.clear();
|
2009-10-14 07:22:11 +00:00
|
|
|
stickyWindows.clear();
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->prePaintScreen(data, time);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty()) {
|
2010-12-18 09:18:54 +00:00
|
|
|
#ifdef KWIN_HAVE_OPENGLES
|
2011-01-30 14:34:42 +00:00
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
paintSlideCube(mask, region, data);
|
|
|
|
glCullFace(GL_BACK);
|
|
|
|
paintSlideCube(mask, region, data);
|
|
|
|
glDisable(GL_CULL_FACE);
|
2010-12-18 09:18:54 +00:00
|
|
|
#else
|
2011-01-30 14:34:42 +00:00
|
|
|
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glCullFace(GL_FRONT);
|
2009-02-06 18:53:16 +00:00
|
|
|
glPushMatrix();
|
2011-01-30 14:34:42 +00:00
|
|
|
paintSlideCube(mask, region, data);
|
2009-02-06 18:53:16 +00:00
|
|
|
glPopMatrix();
|
2011-01-30 14:34:42 +00:00
|
|
|
glCullFace(GL_BACK);
|
2009-02-06 18:53:16 +00:00
|
|
|
glPushMatrix();
|
2011-01-30 14:34:42 +00:00
|
|
|
paintSlideCube(mask, region, data);
|
2009-02-06 18:53:16 +00:00
|
|
|
glPopMatrix();
|
2011-01-30 14:34:42 +00:00
|
|
|
glDisable(GL_CULL_FACE);
|
2009-02-06 18:53:16 +00:00
|
|
|
glPopAttrib();
|
2010-12-18 09:18:54 +00:00
|
|
|
#endif
|
2011-01-30 14:34:42 +00:00
|
|
|
if (dontSlidePanels) {
|
|
|
|
foreach (EffectWindow * w, panels) {
|
|
|
|
WindowPaintData wData(w);
|
|
|
|
effects->paintWindow(w, 0, QRegion(w->x(), w->y(), w->width(), w->height()), wData);
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (EffectWindow * w, stickyWindows) {
|
|
|
|
WindowPaintData wData(w);
|
|
|
|
effects->paintWindow(w, 0, QRegion(w->x(), w->y(), w->width(), w->height()), wData);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
effects->paintScreen(mask, region, data);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
void CubeSlideEffect::paintSlideCube(int mask, QRegion region, ScreenPaintData& data)
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
2009-02-06 18:53:16 +00:00
|
|
|
// slide cube only paints to desktops at a time
|
|
|
|
// first the horizontal rotations followed by vertical rotations
|
2011-01-30 14:34:42 +00:00
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), effects->currentDesktop());
|
|
|
|
float point = rect.width() / 2 * tan(45.0f * M_PI / 180.0f);
|
2009-02-06 18:53:16 +00:00
|
|
|
cube_painting = true;
|
|
|
|
painting_desktop = front_desktop;
|
|
|
|
|
|
|
|
ScreenPaintData firstFaceData = data;
|
|
|
|
ScreenPaintData secondFaceData = data;
|
|
|
|
RotationData firstFaceRot = RotationData();
|
|
|
|
RotationData secondFaceRot = RotationData();
|
|
|
|
RotationDirection direction = slideRotations.head();
|
|
|
|
int secondDesktop;
|
2011-01-30 14:34:42 +00:00
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
firstFaceRot.axis = RotationData::YAxis;
|
|
|
|
secondFaceRot.axis = RotationData::YAxis;
|
|
|
|
if (usePagerLayout)
|
|
|
|
secondDesktop = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
secondDesktop = front_desktop - 1;
|
|
|
|
if (secondDesktop == 0)
|
|
|
|
secondDesktop = effects->numberOfDesktops();
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
firstFaceRot.angle = 90.0f * timeLine.value();
|
|
|
|
secondFaceRot.angle = -90.0f * (1.0f - timeLine.value());
|
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
firstFaceRot.axis = RotationData::YAxis;
|
|
|
|
secondFaceRot.axis = RotationData::YAxis;
|
|
|
|
if (usePagerLayout)
|
|
|
|
secondDesktop = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
secondDesktop = front_desktop + 1;
|
|
|
|
if (secondDesktop > effects->numberOfDesktops())
|
|
|
|
secondDesktop = 1;
|
|
|
|
}
|
|
|
|
firstFaceRot.angle = -90.0f * timeLine.value();
|
|
|
|
secondFaceRot.angle = 90.0f * (1.0f - timeLine.value());
|
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
firstFaceRot.axis = RotationData::XAxis;
|
|
|
|
secondFaceRot.axis = RotationData::XAxis;
|
|
|
|
secondDesktop = effects->desktopAbove(front_desktop, true);
|
|
|
|
firstFaceRot.angle = -90.0f * timeLine.value();
|
|
|
|
secondFaceRot.angle = 90.0f * (1.0f - timeLine.value());
|
|
|
|
point = rect.height() / 2 * tan(45.0f * M_PI / 180.0f);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
firstFaceRot.axis = RotationData::XAxis;
|
|
|
|
secondFaceRot.axis = RotationData::XAxis;
|
|
|
|
secondDesktop = effects->desktopBelow(front_desktop, true);
|
|
|
|
firstFaceRot.angle = 90.0f * timeLine.value();
|
|
|
|
secondFaceRot.angle = -90.0f * (1.0f - timeLine.value());
|
|
|
|
point = rect.height() / 2 * tan(45.0f * M_PI / 180.0f);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// totally impossible
|
|
|
|
return;
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
// front desktop
|
2011-01-30 14:34:42 +00:00
|
|
|
firstFaceRot.xRotationPoint = rect.width() / 2;
|
|
|
|
firstFaceRot.yRotationPoint = rect.height() / 2;
|
2009-02-06 18:53:16 +00:00
|
|
|
firstFaceRot.zRotationPoint = -point;
|
|
|
|
firstFaceData.rotation = &firstFaceRot;
|
2009-02-18 19:14:47 +00:00
|
|
|
other_desktop = secondDesktop;
|
|
|
|
firstDesktop = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->paintScreen(mask, region, firstFaceData);
|
2009-02-06 18:53:16 +00:00
|
|
|
// second desktop
|
2009-02-18 19:14:47 +00:00
|
|
|
other_desktop = painting_desktop;
|
2009-02-06 18:53:16 +00:00
|
|
|
painting_desktop = secondDesktop;
|
2009-02-18 19:14:47 +00:00
|
|
|
firstDesktop = false;
|
2011-01-30 14:34:42 +00:00
|
|
|
secondFaceRot.xRotationPoint = rect.width() / 2;
|
|
|
|
secondFaceRot.yRotationPoint = rect.height() / 2;
|
2009-02-06 18:53:16 +00:00
|
|
|
secondFaceRot.zRotationPoint = -point;
|
|
|
|
secondFaceData.rotation = &secondFaceRot;
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->paintScreen(mask, region, secondFaceData);
|
2009-02-06 18:53:16 +00:00
|
|
|
cube_painting = false;
|
|
|
|
painting_desktop = effects->currentDesktop();
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty() && cube_painting) {
|
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
|
|
|
if (dontSlidePanels && w->isDock()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
panels.insert(w);
|
|
|
|
}
|
|
|
|
if (!w->isManaged()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
stickyWindows.insert(w);
|
|
|
|
} else if (dontSlideStickyWindows && !w->isDock() &&
|
|
|
|
!w->isDesktop() && w->isOnAllDesktops()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
stickyWindows.insert(w);
|
|
|
|
}
|
|
|
|
if (w->isOnDesktop(painting_desktop)) {
|
|
|
|
if (w->x() < rect.x()) {
|
|
|
|
data.quads = data.quads.splitAtX(-w->x());
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->x() + w->width() > rect.x() + rect.width()) {
|
|
|
|
data.quads = data.quads.splitAtX(rect.width() - w->x());
|
2009-10-14 07:22:11 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->y() < rect.y()) {
|
|
|
|
data.quads = data.quads.splitAtY(-w->y());
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->y() + w->height() > rect.y() + rect.height()) {
|
|
|
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else if (w->isOnDesktop(other_desktop)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
RotationDirection direction = slideRotations.head();
|
|
|
|
bool enable = false;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->x() < rect.x() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
|
|
|
data.quads = data.quads.splitAtX(-w->x());
|
2009-02-18 19:14:47 +00:00
|
|
|
enable = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
|
|
|
data.quads = data.quads.splitAtX(rect.width() - w->x());
|
2009-02-18 19:14:47 +00:00
|
|
|
enable = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (w->y() < rect.y() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
|
|
|
data.quads = data.quads.splitAtY(-w->y());
|
2009-02-18 19:14:47 +00:00
|
|
|
enable = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
|
|
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
2009-02-18 19:14:47 +00:00
|
|
|
enable = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (enable) {
|
2009-02-18 19:14:47 +00:00
|
|
|
data.setTransformed();
|
|
|
|
data.setTranslucent();
|
2011-01-30 14:34:42 +00:00
|
|
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else
|
|
|
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else
|
|
|
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->prePaintWindow(w, data, time);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty() && cube_painting) {
|
|
|
|
if (dontSlidePanels && w->isDock())
|
2009-02-06 18:53:16 +00:00
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (stickyWindows.contains(w))
|
2009-02-06 18:53:16 +00:00
|
|
|
return;
|
2009-02-18 19:14:47 +00:00
|
|
|
|
|
|
|
// filter out quads overlapping the edges
|
2011-01-30 14:34:42 +00:00
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
|
|
|
if (w->isOnDesktop(painting_desktop)) {
|
|
|
|
if (w->x() < rect.x()) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() > -w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width()) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() <= rect.width() - w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() < rect.y()) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() > -w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height()) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() <= rect.height() - w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-18 19:14:47 +00:00
|
|
|
// paint windows overlapping edges from other desktop
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->isOnDesktop(other_desktop) && (mask & PAINT_WINDOW_TRANSFORMED)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
RotationDirection direction = slideRotations.head();
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w->x() < rect.x() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
|
|
|
data.xTranslate = rect.width();
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() <= -w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
|
|
|
data.xTranslate = -rect.width();
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() > rect.width() - w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() < rect.y() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
|
|
|
data.yTranslate = rect.height();
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() <= -w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
2009-02-18 19:14:47 +00:00
|
|
|
WindowQuadList new_quads;
|
|
|
|
data.yTranslate = -rect.height();
|
2011-01-30 14:34:42 +00:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() > rect.height() - w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 19:14:47 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (firstDesktop)
|
2009-02-18 19:14:47 +00:00
|
|
|
data.opacity *= timeLine.value();
|
|
|
|
else
|
2011-01-30 14:34:42 +00:00
|
|
|
data.opacity *= (1.0 - timeLine.value());
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->paintWindow(w, mask, region, data);
|
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
|
|
|
void CubeSlideEffect::postPaintScreen()
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
2009-02-06 18:53:16 +00:00
|
|
|
effects->postPaintScreen();
|
2011-01-30 14:34:42 +00:00
|
|
|
if (!slideRotations.empty()) {
|
|
|
|
if (timeLine.value() == 1.0) {
|
2009-02-06 18:53:16 +00:00
|
|
|
RotationDirection direction = slideRotations.dequeue();
|
2011-01-30 14:34:42 +00:00
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
if (usePagerLayout)
|
|
|
|
front_desktop = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
front_desktop--;
|
|
|
|
if (front_desktop == 0)
|
|
|
|
front_desktop = effects->numberOfDesktops();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
if (usePagerLayout)
|
|
|
|
front_desktop = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
front_desktop++;
|
|
|
|
if (front_desktop > effects->numberOfDesktops())
|
|
|
|
front_desktop = 1;
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
front_desktop = effects->desktopAbove(front_desktop, true);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
front_desktop = effects->desktopBelow(front_desktop, true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
timeLine.setProgress(0.0);
|
|
|
|
if (slideRotations.count() == 1)
|
|
|
|
timeLine.setCurveShape(TimeLine::EaseOutCurve);
|
2009-02-19 09:31:58 +00:00
|
|
|
else
|
2011-01-30 14:34:42 +00:00
|
|
|
timeLine.setCurveShape(TimeLine::LinearCurve);
|
|
|
|
if (slideRotations.empty()) {
|
|
|
|
foreach (EffectWindow * w, panels)
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(false));
|
|
|
|
foreach (EffectWindow * w, stickyWindows)
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(false));
|
2010-06-13 07:36:40 +00:00
|
|
|
stickyWindows.clear();
|
|
|
|
panels.clear();
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->setActiveFullScreenEffect(0);
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->addRepaintFull();
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-02-25 19:41:10 +00:00
|
|
|
void CubeSlideEffect::slotDesktopChanged(int old, int current)
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
|
|
|
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
|
2009-02-06 18:53:16 +00:00
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (old > effects->numberOfDesktops()) {
|
2009-06-14 20:31:08 +00:00
|
|
|
// number of desktops has been reduced -> no animation
|
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (windowMoving) {
|
2010-01-10 15:51:02 +00:00
|
|
|
desktopChangedWhileMoving = true;
|
|
|
|
progressRestriction = 1.0 - progressRestriction;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
bool activate = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (!slideRotations.empty()) {
|
2009-02-06 18:53:16 +00:00
|
|
|
// last slide still in progress
|
|
|
|
activate = false;
|
|
|
|
RotationDirection direction = slideRotations.dequeue();
|
|
|
|
slideRotations.clear();
|
2011-01-30 14:34:42 +00:00
|
|
|
slideRotations.enqueue(direction);
|
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
if (usePagerLayout)
|
|
|
|
old = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
old = front_desktop - 1;
|
|
|
|
if (old == 0)
|
|
|
|
old = effects->numberOfDesktops();
|
2009-02-17 12:47:18 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
if (usePagerLayout)
|
|
|
|
old = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
old = front_desktop + 1;
|
|
|
|
if (old > effects->numberOfDesktops())
|
|
|
|
old = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
old = effects->desktopAbove(front_desktop, true);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
old = effects->desktopBelow(front_desktop, true);
|
|
|
|
break;
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (usePagerLayout) {
|
2009-05-04 13:24:55 +00:00
|
|
|
// calculate distance in respect to pager
|
2011-01-30 14:34:42 +00:00
|
|
|
QPoint diff = effects->desktopGridCoords(effects->currentDesktop()) - effects->desktopGridCoords(old);
|
|
|
|
if (qAbs(diff.x()) > effects->desktopGridWidth() / 2) {
|
|
|
|
int sign = -1 * (diff.x() / qAbs(diff.x()));
|
|
|
|
diff.setX(sign *(effects->desktopGridWidth() - qAbs(diff.x())));
|
|
|
|
}
|
|
|
|
if (diff.x() > 0) {
|
|
|
|
for (int i = 0; i < diff.x(); i++) {
|
|
|
|
slideRotations.enqueue(Right);
|
2009-05-04 13:24:55 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
} else if (diff.x() < 0) {
|
|
|
|
diff.setX(-diff.x());
|
|
|
|
for (int i = 0; i < diff.x(); i++) {
|
|
|
|
slideRotations.enqueue(Left);
|
2009-05-04 13:24:55 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (qAbs(diff.y()) > effects->desktopGridHeight() / 2) {
|
|
|
|
int sign = -1 * (diff.y() / qAbs(diff.y()));
|
|
|
|
diff.setY(sign *(effects->desktopGridHeight() - qAbs(diff.y())));
|
|
|
|
}
|
|
|
|
if (diff.y() > 0) {
|
|
|
|
for (int i = 0; i < diff.y(); i++) {
|
|
|
|
slideRotations.enqueue(Downwards);
|
2009-05-04 13:24:55 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
if (diff.y() < 0) {
|
|
|
|
diff.setY(-diff.y());
|
|
|
|
for (int i = 0; i < diff.y(); i++) {
|
|
|
|
slideRotations.enqueue(Upwards);
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
} else {
|
2009-05-04 13:24:55 +00:00
|
|
|
// ignore pager layout
|
2011-02-25 19:41:10 +00:00
|
|
|
int left = old - current;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (left < 0)
|
2009-05-04 13:24:55 +00:00
|
|
|
left = effects->numberOfDesktops() + left;
|
2011-02-25 19:41:10 +00:00
|
|
|
int right = current - old;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (right < 0)
|
2009-05-04 13:24:55 +00:00
|
|
|
right = effects->numberOfDesktops() + right;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (left < right) {
|
|
|
|
for (int i = 0; i < left; i++) {
|
|
|
|
slideRotations.enqueue(Left);
|
2009-05-04 13:24:55 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
} else {
|
|
|
|
for (int i = 0; i < right; i++) {
|
|
|
|
slideRotations.enqueue(Right);
|
2009-02-06 18:53:16 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
|
|
|
timeLine.setDuration((float)rotationDuration / (float)slideRotations.count());
|
|
|
|
if (activate) {
|
|
|
|
if (slideRotations.count() == 1)
|
|
|
|
timeLine.setCurveShape(TimeLine::EaseInOutCurve);
|
2009-02-19 09:31:58 +00:00
|
|
|
else
|
2011-01-30 14:34:42 +00:00
|
|
|
timeLine.setCurveShape(TimeLine::EaseInCurve);
|
|
|
|
effects->setActiveFullScreenEffect(this);
|
|
|
|
timeLine.setProgress(0.0);
|
2009-02-06 18:53:16 +00:00
|
|
|
front_desktop = old;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2009-02-06 18:53:16 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::windowUserMovedResized(EffectWindow* c, bool first, bool last)
|
|
|
|
{
|
|
|
|
if (!useWindowMoving)
|
2010-01-10 15:51:02 +00:00
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
if ((first && last) || c->isUserResize())
|
2010-01-10 15:51:02 +00:00
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (last) {
|
|
|
|
if (!desktopChangedWhileMoving) {
|
|
|
|
if (slideRotations.isEmpty())
|
2010-01-10 15:51:02 +00:00
|
|
|
return;
|
|
|
|
const RotationDirection direction = slideRotations.dequeue();
|
2011-01-30 14:34:42 +00:00
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
slideRotations.enqueue(Right);
|
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
slideRotations.enqueue(Left);
|
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
slideRotations.enqueue(Downwards);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
slideRotations.enqueue(Upwards);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break; // impossible
|
2010-01-10 15:51:02 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
timeLine.setProgress(1.0 - timeLine.progress());
|
|
|
|
}
|
2010-01-10 15:51:02 +00:00
|
|
|
desktopChangedWhileMoving = false;
|
|
|
|
windowMoving = false;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
return;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2010-01-10 15:51:02 +00:00
|
|
|
const QPoint cursor = effects->cursorPos();
|
2011-01-30 14:34:42 +00:00
|
|
|
const int horizontal = displayWidth() * 0.1;
|
|
|
|
const int vertical = displayHeight() * 0.1;
|
|
|
|
const QRect leftRect(0, displayHeight() * 0.1, horizontal, displayHeight() * 0.8);
|
|
|
|
const QRect rightRect(displayWidth() - horizontal, displayHeight() * 0.1, horizontal, displayHeight() * 0.8);
|
|
|
|
const QRect topRect(horizontal, 0, displayWidth() * 0.8, vertical);
|
|
|
|
const QRect bottomRect(horizontal, displayHeight() - vertical, displayWidth() - horizontal * 2, vertical);
|
|
|
|
if (leftRect.contains(cursor)) {
|
|
|
|
if (effects->desktopToLeft(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(horizontal - cursor.x()) / (float)horizontal, Left);
|
|
|
|
} else if (rightRect.contains(cursor)) {
|
|
|
|
if (effects->desktopToRight(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(cursor.x() - displayWidth() + horizontal) / (float)horizontal, Right);
|
|
|
|
} else if (topRect.contains(cursor)) {
|
|
|
|
if (effects->desktopAbove(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(vertical - cursor.y()) / (float)vertical, Upwards);
|
|
|
|
} else if (bottomRect.contains(cursor)) {
|
|
|
|
if (effects->desktopBelow(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(cursor.y() - displayHeight() + vertical) / (float)vertical, Downwards);
|
|
|
|
} else {
|
2010-01-10 15:51:02 +00:00
|
|
|
// not in one of the areas
|
|
|
|
windowMoving = false;
|
|
|
|
desktopChangedWhileMoving = false;
|
2011-01-30 14:34:42 +00:00
|
|
|
timeLine.setProgress(0.0);
|
|
|
|
if (!slideRotations.isEmpty())
|
2010-01-10 15:51:02 +00:00
|
|
|
slideRotations.clear();
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->setActiveFullScreenEffect(0);
|
2010-01-10 15:51:02 +00:00
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2010-01-10 15:51:02 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
void CubeSlideEffect::windowMovingChanged(float progress, RotationDirection direction)
|
|
|
|
{
|
|
|
|
if (desktopChangedWhileMoving)
|
2010-01-10 15:51:02 +00:00
|
|
|
progressRestriction = 1.0 - progress;
|
|
|
|
else
|
|
|
|
progressRestriction = progress;
|
|
|
|
front_desktop = effects->currentDesktop();
|
2011-01-30 14:34:42 +00:00
|
|
|
if (slideRotations.isEmpty()) {
|
|
|
|
slideRotations.enqueue(direction);
|
|
|
|
timeLine.setCurveShape(TimeLine::EaseInOutCurve);
|
2010-01-10 15:51:02 +00:00
|
|
|
windowMoving = true;
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->setActiveFullScreenEffect(this);
|
2010-01-10 15:51:02 +00:00
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2010-01-10 15:51:02 +00:00
|
|
|
|
2009-02-06 18:53:16 +00:00
|
|
|
} // namespace
|