/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2009 Jorge Mata 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 . *********************************************************************/ #include "slidetabs.h" #include #include namespace KWin { KWIN_EFFECT(slidetabs, SlideTabsEffect) SlideTabsEffect::SlideTabsEffect() { reconfigure(ReconfigureAll); } void SlideTabsEffect::reconfigure(ReconfigureFlags) { KConfigGroup conf = EffectsHandler::effectConfig("SlideTabs"); switching = conf.readEntry("SlideSwitching", true); grouping = conf.readEntry("SlideGrouping", true); totalTime = conf.readEntry("SlideDuration", 500); } void SlideTabsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) { if (motionManager.isManaging(w)) { data.setTransformed(); w->enablePainting(EffectWindow::PAINT_DISABLED); timeLine.addTime(time); } effects->prePaintWindow(w, data, time); } void SlideTabsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) { if (motionManager.isManaging(w) && w == inMove) motionManager.apply(w, data); effects->paintWindow(w, mask, region, data); } void SlideTabsEffect::postPaintWindow(EffectWindow* w) { if (motionManager.isManaging(w)) { if (w == inMove) { QRect moving = calculateNextMove(); motionManager.moveWindow(w, moving); if (direction && timeLine.progress() >= 0.5) { moving = target; target = source; source = moving; direction = false; effects->setElevatedWindow(notMoving, false); effects->setElevatedWindow(w, true); } else if (timeLine.progress() >= 1.0) { effects->setElevatedWindow(notMoving, false); effects->setElevatedWindow(inMove, false); motionManager.unmanage(notMoving); motionManager.unmanage(inMove); notMoving = NULL; inMove = NULL; wasD = false; effects->addRepaintFull(); } } else if (w == notMoving && !direction && target != w->geometry() && !wasD) { target = w->geometry(); } w->addRepaintFull(); } effects->postPaintWindow(w); } void SlideTabsEffect::prePaintScreen(ScreenPrePaintData &data, int time) { if (motionManager.managingWindows()) { motionManager.calculate(time); data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; } effects->prePaintScreen(data, time); } void SlideTabsEffect::postPaintScreen() { if (motionManager.managingWindows()) effects->addRepaintFull(); effects->postPaintScreen(); } void SlideTabsEffect::clientGroupItemSwitched(EffectWindow* from, EffectWindow* to) { if (!switching) return; inMove = to; notMoving = from; source = notMoving->geometry(); QRect window = notMoving->geometry(); int leftSpace = window.x(), rightSpace = displayWidth() - (window.x() + window.width()), upSpace = window.y(), downSpace = displayHeight() - (window.y() + window.height()); if (leftSpace >= rightSpace && leftSpace >= upSpace && leftSpace >= downSpace) target = QRect(source.x() - (1.2 * source.width()), source.y(), source.width(), source.height()); else if (rightSpace >= leftSpace && rightSpace >= upSpace && rightSpace >= downSpace) target = QRect(source.x() + (1.2 * source.width()), source.y(), source.width(), source.height()); else if (upSpace >= leftSpace && upSpace >= rightSpace && upSpace >= downSpace) target = QRect(source.x(), source.y() - (1.2 * source.height()), source.width(), source.height()); else target = QRect(source.x(), source.y() + (1.2 * source.height()), source.width(), source.height()); timeLine.setCurveShape(TimeLine::LinearCurve); timeLine.setDuration(animationTime(totalTime)); timeLine.setProgress(0.0f); motionManager.manage(inMove); motionManager.manage(notMoving); distance = sqrt(((source.x() - target.x()) * (source.x() - target.x())) + ((source.y() - target.y()) * (source.y() - target.y()))); effects->setElevatedWindow(notMoving, true); direction = wasD = true; QRect moving = calculateNextMove(); motionManager.moveWindow(inMove, moving); } void SlideTabsEffect::clientGroupItemAdded(EffectWindow* from, EffectWindow* to) { if (!grouping || from->desktop() != to->desktop() || from->isMinimized() || to->isMinimized()) return; timeLine.setCurveShape(TimeLine::LinearCurve); timeLine.setDuration(animationTime(totalTime)); timeLine.setProgress(0.0f); inMove = from; notMoving = to; source = inMove->geometry(); target = notMoving->geometry(); distance = sqrt(((source.x() - target.x()) * (source.x() - target.x())) + ((source.y() - target.y()) * (source.y() - target.y()))); motionManager.manage(inMove); motionManager.manage(notMoving); QRect moving = calculateNextMove(); motionManager.moveWindow(inMove, moving); effects->setElevatedWindow(notMoving, true); direction = wasD = false; } QPoint SlideTabsEffect::calculatePointTarget(const QPoint &a, const QPoint &b) { double dy, dx, x, y, k; k = direction ? (2.0 * timeLine.progress()) : (wasD ? ((timeLine.progress() - 0.5) * 2) : timeLine.progress()); dx = fabs(a.x() - b.x()); dy = fabs(a.y() - b.y()); y = k * dy; x = k * dx; if (a.x() > b.x()) x = -x; if (a.y() > b.y()) y = -y; return QPoint(a.x() + x, a.y() + y); } QRect SlideTabsEffect::calculateNextMove() { QPoint topLeft, bottomRight; int mw = source.width(), mh = source.height(), tw = target.width(), th = target.height(); topLeft = calculatePointTarget(QPoint(source.x(), source.y()), QPoint(target.x(), target.y())); bottomRight = calculatePointTarget(QPoint(source.x() + mw, source.y() + mh), QPoint(target.x() + tw, target.y() + th)); return QRect(topLeft.x(), topLeft.y(), bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y()); } }