1
//////////////////////////////////////////////////////////////////////////////
2
// oxygentransitionwidget.cpp
3
// stores event filters and maps widgets to transitions for transitions
6
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
9
// of this software and associated documentation files (the "Software"), to
10
// deal in the Software without restriction, including without limitation the
11
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
// sell copies of the Software, and to permit persons to whom the Software is
13
// furnished to do so, subject to the following conditions:
15
// The above copyright notice and this permission notice shall be included in
16
// all copies or substantial portions of the Software.
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25
//////////////////////////////////////////////////////////////////////////////
27
#include "oxygentransitionwidget.h"
28
#include "oxygentransitionwidget.moc"
31
#include <QtGui/QPainter>
32
#include <QtGui/QPaintEvent>
33
#include <QtGui/QStyleOption>
34
#include <QtCore/QCoreApplication>
35
#include <QtCore/QTextStream>
40
//________________________________________________
41
bool TransitionWidget::_paintEnabled = true;
42
bool TransitionWidget::paintEnabled( void )
43
{ return _paintEnabled; }
45
int TransitionWidget::_steps = 0;
47
//________________________________________________
48
TransitionWidget::TransitionWidget( QWidget* parent, int duration ):
51
_animation( new Animation( duration, this ) ),
56
setAttribute(Qt::WA_NoSystemBackground );
57
setAutoFillBackground( false );
60
_animation.data()->setStartValue( 0 );
61
_animation.data()->setEndValue( 1.0 );
62
_animation.data()->setTargetObject( this );
63
_animation.data()->setPropertyName( "opacity" );
66
connect( _animation.data(), SIGNAL( finished( void ) ), SIGNAL( finished( void ) ) );
70
//________________________________________________
71
QPixmap TransitionWidget::grab( QWidget* widget, QRect rect )
75
if( !rect.isValid() ) rect = widget->rect();
76
if( !rect.isValid() ) return QPixmap();
79
QPixmap out( rect.size() );
80
out.fill( Qt::transparent );
81
_paintEnabled = false;
83
if( testFlag( GrabFromWindow ) )
86
rect = rect.translated( widget->mapTo( widget->window(), widget->rect().topLeft() ) );
87
widget = widget->window();
88
out = QPixmap::grabWidget( widget, rect );
92
if( !testFlag( Transparent ) ) { grabBackground( out, widget, rect ); }
93
grabWidget( out, widget, rect );
103
//________________________________________________
104
void TransitionWidget::paintEvent( QPaintEvent* event )
107
// fully transparent case
108
if( opacity() >= 1.0 && endPixmap().isNull() ) return;
109
if( !_paintEnabled ) return;
112
QRect rect = event->rect();
113
if( !rect.isValid() ) rect = this->rect();
116
const bool paintOnWidget( testFlag( PaintOnWidget ) && !testFlag( Transparent ) );
120
if( _currentPixmap.isNull() || _currentPixmap.size() != size() )
121
{ _currentPixmap = QPixmap( size() ); }
126
_currentPixmap.fill( Qt::transparent );
128
// copy local pixmap to current
133
// draw end pixmap first, provided that opacity is small enough
134
if( opacity() >= 0.004 && !_endPixmap.isNull() )
137
// faded endPixmap if parent target is transparent and opacity is
138
if( opacity() <= 0.996 && testFlag( Transparent ) )
141
fade( _endPixmap, _currentPixmap, opacity(), rect );
142
p.begin( &_currentPixmap );
143
p.setClipRect( event->rect() );
147
if( paintOnWidget ) p.begin( this );
148
else p.begin( &_currentPixmap );
149
p.setClipRect( event->rect() );
150
p.drawPixmap( QPoint(), _endPixmap );
156
if( paintOnWidget ) p.begin( this );
157
else p.begin( &_currentPixmap );
158
p.setClipRect( event->rect() );
162
// draw fading start pixmap
163
if( opacity() <= 0.996 && !_startPixmap.isNull() )
165
if( opacity() >= 0.004 )
168
fade( _startPixmap, _localStartPixmap, 1.0-opacity(), rect );
169
p.drawPixmap( QPoint(), _localStartPixmap );
171
} else p.drawPixmap( QPoint(), _startPixmap );
178
// copy current pixmap on widget
182
p.setClipRect( event->rect() );
183
p.drawPixmap( QPoint(0,0), _currentPixmap );
188
//________________________________________________
189
void TransitionWidget::grabBackground( QPixmap& pixmap, QWidget* widget, QRect& rect ) const
191
if( !widget ) return;
194
if( widget->autoFillBackground() )
195
{ widgets.push_back( widget ); }
199
// get highest level parent
200
for( parent = widget->parentWidget(); parent; parent = parent->parentWidget() )
203
if( !( parent->isVisible() && parent->rect().isValid() ) ) continue;
206
widgets.push_back( parent );
209
if( parent->isTopLevel() || parent->autoFillBackground() ) break;
213
if( !parent ) parent = widget;
217
p.setClipRect( rect );
218
const QBrush backgroundBrush = parent->palette().brush( parent->backgroundRole());
219
if( backgroundBrush.style() == Qt::TexturePattern)
222
p.drawTiledPixmap( rect, backgroundBrush.texture(), widget->mapTo( parent, rect.topLeft() ) );
226
p.fillRect( pixmap.rect(), backgroundBrush );
230
if( parent->isTopLevel() && parent->testAttribute(Qt::WA_StyledBackground))
233
option.initFrom(parent);
235
option.rect.translate( widget->mapTo( parent, rect.topLeft() ) );
236
p.translate(-option.rect.topLeft());
237
parent->style()->drawPrimitive ( QStyle::PE_Widget, &option, &p, parent );
242
// draw all widgets in parent list
244
QPaintEvent event(rect);
245
for( int i = widgets.size() - 1; i>=0; i-- )
247
QWidget* w = widgets.at(i);
248
QPainter::setRedirected( w, &pixmap, widget->mapTo(w, rect.topLeft() ) );
249
event = QPaintEvent(QRect( QPoint(), rect.size()));
250
QCoreApplication::sendEvent(w, &event);
251
QPainter::restoreRedirected(w);
256
//________________________________________________
257
void TransitionWidget::grabWidget( QPixmap& pixmap, QWidget* widget, QRect& rect ) const
258
{ widget->render( &pixmap, pixmap.rect().topLeft(), rect, QWidget::DrawChildren ); }
260
//________________________________________________
261
void TransitionWidget::fade( const QPixmap& source, QPixmap& target, qreal opacity, const QRect& rect ) const
264
if( target.isNull() || target.size() != size() )
265
{ target = QPixmap( size() ); }
268
target.fill( Qt::transparent );
271
if( opacity*255 < 1 ) return;
273
QPainter p( &target );
274
p.setClipRect( rect );
277
p.drawPixmap( QPoint(0,0), source );
279
// opacity mask (0.996 corresponds to 254/255)
280
if( opacity <= 0.996 )
282
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
283
QColor color( Qt::black );
284
color.setAlphaF( opacity );
285
p.fillRect(rect, color );