Add a new option to cube animation to trigger rotating the cube while moving a window towards the screen edge.

The cube starts to rotate before the desktop switches due to active desktop border change. This gives the impression that you drag the cube by moving the window. Of course option is only useful when switching desktop on screen edge is enabled and so this feature is disabled by default.

svn path=/trunk/KDE/kdebase/workspace/; revision=1072640
This commit is contained in:
Martin Gräßlin 2010-01-10 15:51:02 +00:00
parent 0e62916ccd
commit c3476f0345
4 changed files with 127 additions and 4 deletions

View file

@ -34,6 +34,9 @@ KWIN_EFFECT( cubeslide, CubeSlideEffect )
KWIN_EFFECT_SUPPORTED( cubeslide, CubeSlideEffect::supported() )
CubeSlideEffect::CubeSlideEffect()
: windowMoving( false )
, desktopChangedWhileMoving( false )
, progressRestriction( 0.0f )
{
reconfigure( ReconfigureAll );
}
@ -56,6 +59,7 @@ void CubeSlideEffect::reconfigure( ReconfigureFlags )
dontSlidePanels = conf.readEntry( "DontSlidePanels", true );
dontSlideStickyWindows = conf.readEntry( "DontSlideStickyWindows", false );
usePagerLayout = conf.readEntry( "UsePagerLayout", true );
useWindowMoving = conf.readEntry( "UseWindowMoving", false );
}
void CubeSlideEffect::prePaintScreen( ScreenPrePaintData& data, int time)
@ -64,6 +68,8 @@ void CubeSlideEffect::prePaintScreen( ScreenPrePaintData& data, int time)
{
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
timeLine.addTime( time );
if( windowMoving && timeLine.progress() > progressRestriction )
timeLine.setProgress( progressRestriction );
if( dontSlidePanels )
panels.clear();
stickyWindows.clear();
@ -463,6 +469,13 @@ void CubeSlideEffect::desktopChanged( int old )
// number of desktops has been reduced -> no animation
return;
}
if( windowMoving )
{
desktopChangedWhileMoving = true;
progressRestriction = 1.0 - progressRestriction;
effects->addRepaintFull();
return;
}
bool activate = true;
if( !slideRotations.empty() )
{
@ -584,4 +597,98 @@ void CubeSlideEffect::desktopChanged( int old )
}
}
void CubeSlideEffect::windowUserMovedResized( EffectWindow* c, bool first, bool last )
{
if( !useWindowMoving )
return;
if( (first && last) || c->isUserResize() )
return;
if( last )
{
if( !desktopChangedWhileMoving )
{
if( slideRotations.isEmpty() )
return;
const RotationDirection direction = slideRotations.dequeue();
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
}
timeLine.setProgress( 1.0 - timeLine.progress() );
}
desktopChangedWhileMoving = false;
windowMoving = false;
effects->addRepaintFull();
return;
}
const QPoint cursor = effects->cursorPos();
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
{
// not in one of the areas
windowMoving = false;
desktopChangedWhileMoving = false;
timeLine.setProgress( 0.0 );
if( !slideRotations.isEmpty() )
slideRotations.clear();
effects->setActiveFullScreenEffect( 0 );
effects->addRepaintFull();
}
}
void CubeSlideEffect::windowMovingChanged( float progress, RotationDirection direction )
{
if( desktopChangedWhileMoving )
progressRestriction = 1.0 - progress;
else
progressRestriction = progress;
front_desktop = effects->currentDesktop();
if( slideRotations.isEmpty() )
{
slideRotations.enqueue( direction );
timeLine.setCurveShape( TimeLine::EaseInOutCurve );
windowMoving = true;
effects->setActiveFullScreenEffect( this );
}
effects->addRepaintFull();
}
} // namespace

View file

@ -41,6 +41,7 @@ class CubeSlideEffect
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
virtual void desktopChanged( int old );
virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
static bool supported();
private:
@ -52,6 +53,7 @@ class CubeSlideEffect
Downwards
};
void paintSlideCube( int mask, QRegion region, ScreenPaintData& data );
void windowMovingChanged( float progress, RotationDirection direction );
bool cube_painting;
int front_desktop;
int painting_desktop;
@ -65,6 +67,10 @@ class CubeSlideEffect
bool dontSlideStickyWindows;
bool usePagerLayout;
int rotationDuration;
bool useWindowMoving;
bool windowMoving;
bool desktopChangedWhileMoving;
double progressRestriction;
};
}

View file

@ -46,6 +46,7 @@ CubeSlideEffectConfig::CubeSlideEffectConfig(QWidget* parent, const QVariantList
connect(m_ui->dontSlidePanelsBox, SIGNAL(stateChanged(int)), this, SLOT(changed()));
connect(m_ui->dontSlideStickyWindowsBox, SIGNAL(stateChanged(int)), this, SLOT(changed()));
connect(m_ui->usePagerBox, SIGNAL(stateChanged(int)), this, SLOT(changed()));
connect(m_ui->windowsMovingBox, SIGNAL(stateChanged(int)), SLOT(changed()));
load();
}
@ -65,7 +66,7 @@ void CubeSlideEffectConfig::load()
m_ui->dontSlidePanelsBox->setChecked( dontSlidePanels );
m_ui->dontSlideStickyWindowsBox->setChecked( dontSlideStickyWindows );
m_ui->usePagerBox->setChecked( usePager );
m_ui->windowsMovingBox->setChecked( conf.readEntry( "UseWindowMoving", false ) );
emit changed(false);
}
@ -78,6 +79,7 @@ void CubeSlideEffectConfig::save()
conf.writeEntry( "DontSlidePanels", m_ui->dontSlidePanelsBox->isChecked() );
conf.writeEntry( "DontSlideStickyWindows", m_ui->dontSlideStickyWindowsBox->isChecked() );
conf.writeEntry( "UsePagerLayout", m_ui->usePagerBox->isChecked() );
conf.writeEntry( "UseWindowMoving", m_ui->windowsMovingBox->isChecked() );
conf.sync();
@ -91,6 +93,7 @@ void CubeSlideEffectConfig::defaults()
m_ui->dontSlidePanelsBox->setChecked( true );
m_ui->dontSlideStickyWindowsBox->setChecked( false );
m_ui->usePagerBox->setChecked( true );
m_ui->windowsMovingBox->setChecked( false );
emit changed(true);
}

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>342</width>
<height>126</height>
<width>431</width>
<height>161</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -18,7 +18,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -86,6 +86,13 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="windowsMovingBox">
<property name="text">
<string>Start animation when moving windows towards screen edges</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>