3 // Note: this file has been copied from the Qt source.
4 // Those classes are normally used internally in Qt
5 // but we need them for immitate the roll-over effect of QComboBox.
7 // A portion of code has been added. It's underlined by "THIS CODE WAS ADDED:".
9 // And some class definitions have been moved from this file to qeffects.h
10 // Theire old position is indicated by "REMOVED CLASS DEFINITION HERE (MOVED TO qeffects.h)"
12 /****************************************************************************
13 ** $Id: qt/qeffects.cpp 3.3.4 edited Dec 10 10:13 $
15 ** Implementation of QEffects functions
19 ** Copyright (C) 2000 Trolltech AS. All rights reserved.
21 ** This file is part of the widgets module of the Qt GUI Toolkit.
23 ** This file may be distributed under the terms of the Q Public License
24 ** as defined by Trolltech AS of Norway and appearing in the file
25 ** LICENSE.QPL included in the packaging of this file.
27 ** This file may be distributed and/or modified under the terms of the
28 ** GNU General Public License version 2 as published by the Free Software
29 ** Foundation and appearing in the file LICENSE.GPL included in the
30 ** packaging of this file.
32 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
33 ** licenses may use this file in accordance with the Qt Commercial License
34 ** Agreement provided with the Software.
36 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
37 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
39 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
40 ** information about Qt Commercial License Agreements.
41 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
42 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
44 ** Contact info@trolltech.com if any conditions of this licensing are
47 **********************************************************************/
49 #include "qapplication.h"
51 #include <QCloseEvent>
52 #include <QPaintEvent>
61 #include "qdatetime.h"
63 #include "q3scrollview.h"
65 /* REMOVED CLASS DEFINITION HERE (MOVED TO qeffects.h) */
67 static QAlphaWidget
* q_blend
= 0;
70 Constructs a QAlphaWidget.
72 QAlphaWidget::QAlphaWidget( QWidget
* w
, WFlags f
)
73 : QWidget( QApplication::desktop()->screen(QApplication::desktop()->screenNumber(w
)),
74 "qt internal alpha effect widget", f
)
80 pm
.setOptimization( QPixmap::BestOptim
);
81 setBackgroundMode( NoBackground
);
82 widget
= (QAccessWidget
*)w
;
89 void QAlphaWidget::paintEvent( QPaintEvent
* )
91 bitBlt( this, QPoint(0,0), &pm
);
95 Starts the alphablending animation.
96 The animation will take about \a time ms
98 void QAlphaWidget::run( int time
)
112 qApp
->installEventFilter( this );
114 widget
->setWState( WState_Visible
);
116 move( widget
->geometry().x(),widget
->geometry().y() );
117 resize( widget
->size().width(), widget
->size().height() );
119 front
= QImage( widget
->size(), 32 );
120 front
= QPixmap::grabWidget( widget
);
122 back
= QImage( widget
->size(), 32 );
123 back
= QPixmap::grabWindow( QApplication::desktop()->winId(),
124 widget
->geometry().x(), widget
->geometry().y(),
125 widget
->geometry().width(), widget
->geometry().height() );
127 if ( !back
.isNull() && checkTime
.elapsed() < duration
/ 2 ) {
133 connect( &anim
, SIGNAL(timeout()), this, SLOT(render()));
144 bool QAlphaWidget::eventFilter( QObject
* o
, QEvent
* e
)
146 switch ( e
->type() ) {
150 move( widget
->geometry().x(),widget
->geometry().y() );
157 case QEvent::MouseButtonPress
:
158 #ifndef QT_NO_SCROLLVIEW
159 if ( ::qt_cast
<Q3ScrollView
*>(o
) )
162 case QEvent::MouseButtonDblClick
:
167 case QEvent::KeyPress
:
169 QKeyEvent
*ke
= (QKeyEvent
*)e
;
170 if ( ke
->key() == Key_Escape
)
180 return QWidget::eventFilter( o
, e
);
186 void QAlphaWidget::closeEvent( QCloseEvent
*e
)
195 QWidget::closeEvent( e
);
199 Render alphablending for the time elapsed.
201 Show the blended widget and free all allocated source
202 if the blending is finished.
204 void QAlphaWidget::render()
206 int tempel
= checkTime
.elapsed();
207 if ( elapsed
>= tempel
)
213 alpha
= tempel
/ double(duration
);
216 if ( alpha
>= 1 || !showWidget
) {
218 qApp
->removeEventFilter( this );
227 widget
->setWState( WState_ForceHide
);
228 widget
->clearWState( WState_Visible
);
229 } else if ( duration
) {
230 BackgroundMode bgm
= widget
->backgroundMode();
231 QColor erc
= widget
->eraseColor();
232 const QPixmap
*erp
= widget
->erasePixmap();
234 widget
->clearWState( WState_Visible
);
235 widget
->setBackgroundMode( NoBackground
);
237 if ( bgm
!= FixedColor
&& bgm
!= FixedPixmap
) {
238 widget
->clearWState( WState_Visible
); // prevent update in setBackgroundMode
239 widget
->setBackgroundMode( bgm
);
240 widget
->setWState( WState_Visible
);
242 if ( erc
.isValid() ) {
243 widget
->setEraseColor( erc
);
245 widget
->setErasePixmap( *erp
);
248 widget
->clearWState( WState_Visible
);
256 widget
->clearWState( WState_ForceHide
);
264 Calculate an alphablended image.
266 void QAlphaWidget::alphaBlend()
268 const double ia
= 1-alpha
;
269 const int sw
= front
.width();
270 const int sh
= front
.height();
271 switch( front
.depth() ) {
274 Q_UINT32
** md
= (Q_UINT32
**)mixed
.jumpTable();
275 Q_UINT32
** bd
= (Q_UINT32
**)back
.jumpTable();
276 Q_UINT32
** fd
= (Q_UINT32
**)front
.jumpTable();
278 for (int sy
= 0; sy
< sh
; sy
++ ) {
279 Q_UINT32
* bl
= ((Q_UINT32
*)bd
[sy
]);
280 Q_UINT32
* fl
= ((Q_UINT32
*)fd
[sy
]);
281 for (int sx
= 0; sx
< sw
; sx
++ ) {
282 Q_UINT32 bp
= bl
[sx
];
283 Q_UINT32 fp
= fl
[sx
];
285 ((Q_UINT32
*)(md
[sy
]))[sx
] = qRgb(int (qRed(bp
)*ia
+ qRed(fp
)*alpha
),
286 int (qGreen(bp
)*ia
+ qGreen(fp
)*alpha
),
287 int (qBlue(bp
)*ia
+ qBlue(fp
)*alpha
) );
296 /* REMOVED CLASS DEFINITION HERE (MOVED TO qeffects.h) */
298 static QRollEffect
* q_roll
= 0;
301 Construct a QRollEffect widget.
303 QRollEffect::QRollEffect( QWidget
* w
, WFlags f
, DirFlags orient
)
304 : QWidget( QApplication::desktop()->screen(QApplication::desktop()->screenNumber(w
)),
305 "qt internal roll effect widget", f
), orientation(orient
)
307 #if 1 //ndef Q_WS_WIN
310 widget
= (QAccessWidget
*) w
;
313 setBackgroundMode( NoBackground
);
315 if ( widget
->testWState( WState_Resized
) ) {
316 totalWidth
= widget
->width();
317 totalHeight
= widget
->height();
319 totalWidth
= widget
->sizeHint().width();
320 totalHeight
= widget
->sizeHint().height();
323 currentHeight
= totalHeight
;
324 currentWidth
= totalWidth
;
326 if ( orientation
& (RightScroll
|LeftScroll
) )
328 if ( orientation
& (DownScroll
|UpScroll
) )
331 pm
.setOptimization( QPixmap::BestOptim
);
332 pm
= QPixmap::grabWidget( widget
);
338 void QRollEffect::paintEvent( QPaintEvent
* )
340 int x
= orientation
& RightScroll
? QMIN(0, currentWidth
- totalWidth
) : 0;
341 int y
= orientation
& DownScroll
? QMIN(0, currentHeight
- totalHeight
) : 0;
343 bitBlt( this, x
, y
, &pm
,
344 0, 0, pm
.width(), pm
.height(), CopyROP
, TRUE
);
350 bool QRollEffect::eventFilter( QObject
* o
, QEvent
* e
)
352 switch ( e
->type() ) {
356 move( widget
->geometry().x(),widget
->geometry().y() );
361 if ( o
!= widget
|| done
)
368 case QEvent::MouseButtonPress
:
369 #ifndef QT_NO_SCROLLVIEW
370 if ( ::qt_cast
<Q3ScrollView
*>(o
) )
373 case QEvent::MouseButtonDblClick
:
381 case QEvent::KeyPress
:
383 QKeyEvent
*ke
= (QKeyEvent
*)e
;
386 /* THIS CODE WAS ADDED: ************** */
387 if (ke
->key() == Qt::Key_Enter
) /*** Because we are simulating an Enter key press. */
388 break; /*** So we should not car about it and continue the animation. */
389 /************************************* */
392 if ( ke
->key() == Key_Escape
)
401 return QWidget::eventFilter( o
, e
);
407 void QRollEffect::closeEvent( QCloseEvent
*e
)
416 QWidget::closeEvent( e
);
422 The animation will take about \a time ms, or is
423 calculated if \a time is negative
425 void QRollEffect::run( int time
)
433 if ( duration
< 0 ) {
435 if ( orientation
& (RightScroll
|LeftScroll
) )
436 dist
+= totalWidth
- currentWidth
;
437 if ( orientation
& (DownScroll
|UpScroll
) )
438 dist
+= totalHeight
- currentHeight
;
439 duration
= QMIN( QMAX( dist
/3, 50 ), 120 );
442 connect( &anim
, SIGNAL(timeout()), this, SLOT(scroll()));
444 widget
->setWState( WState_Visible
);
446 move( widget
->geometry().x(),widget
->geometry().y() );
447 resize( QMIN( currentWidth
, totalWidth
), QMIN( currentHeight
, totalHeight
) );
452 qApp
->installEventFilter( this );
461 Roll according to the time elapsed.
463 void QRollEffect::scroll()
465 if ( !done
&& widget
) {
466 widget
->clearWState( WState_ForceHide
);
467 int tempel
= checkTime
.elapsed();
468 if ( elapsed
>= tempel
)
473 if ( currentWidth
!= totalWidth
) {
474 currentWidth
= totalWidth
* (elapsed
/duration
)
475 + ( 2 * totalWidth
* (elapsed
%duration
) + duration
)
477 // equiv. to int( (totalWidth*elapsed) / duration + 0.5 )
478 done
= (currentWidth
>= totalWidth
);
480 if ( currentHeight
!= totalHeight
) {
481 currentHeight
= totalHeight
* (elapsed
/duration
)
482 + ( 2 * totalHeight
* (elapsed
%duration
) + duration
)
484 // equiv. to int( (totalHeight*elapsed) / duration + 0.5 )
485 done
= (currentHeight
>= totalHeight
);
487 done
= ( currentHeight
>= totalHeight
) &&
488 ( currentWidth
>= totalWidth
);
492 int x
= widget
->geometry().x();
493 int y
= widget
->geometry().y();
495 if ( orientation
& RightScroll
|| orientation
& LeftScroll
)
496 w
= QMIN( currentWidth
, totalWidth
);
497 if ( orientation
& DownScroll
|| orientation
& UpScroll
)
498 h
= QMIN( currentHeight
, totalHeight
);
500 setUpdatesEnabled( FALSE
);
501 if ( orientation
& UpScroll
)
502 y
= widget
->geometry().y() + QMAX( 0, totalHeight
- currentHeight
);
503 if ( orientation
& LeftScroll
)
504 x
= widget
->geometry().x() + QMAX( 0, totalWidth
- currentWidth
);
505 if ( orientation
& UpScroll
|| orientation
& LeftScroll
)
509 setUpdatesEnabled( TRUE
);
514 qApp
->removeEventFilter( this );
522 widget
->setWState( WState_ForceHide
);
523 widget
->clearWState( WState_Visible
);
525 BackgroundMode bgm
= widget
->backgroundMode();
526 QColor erc
= widget
->eraseColor();
527 const QPixmap
*erp
= widget
->erasePixmap();
529 widget
->clearWState( WState_Visible
);
530 widget
->setBackgroundMode( NoBackground
);
532 if ( bgm
!= FixedColor
&& bgm
!= FixedPixmap
) {
533 widget
->clearWState( WState_Visible
); // prevent update in setBackgroundMode
534 widget
->setBackgroundMode( bgm
);
535 widget
->setWState( WState_Visible
);
537 if ( erc
.isValid() ) {
538 widget
->setEraseColor( erc
);
540 widget
->setErasePixmap( *erp
);
550 Delete this after timeout
553 #include "qeffects.moc"
556 Scroll widget \a w in \a time ms. \a orient may be 1 (vertical), 2
557 (horizontal) or 3 (diagonal).
559 void qScrollEffect( QWidget
* w
, QEffects::DirFlags orient
, int time
)
566 qApp
->sendPostedEvents( w
, QEvent::Move
);
567 qApp
->sendPostedEvents( w
, QEvent::Resize
);
569 uint flags
= Qt::WStyle_Customize
| Qt::WNoAutoErase
| Qt::WStyle_StaysOnTop
570 | (w
->isPopup() ? Qt::WType_Popup
: (Qt::WX11BypassWM
| Qt::WStyle_Tool
));
572 uint flags
= Qt::WStyle_Customize
| Qt::WType_Popup
| Qt::WX11BypassWM
| Qt::WNoAutoErase
| Qt::WStyle_StaysOnTop
;
575 // those can popups - they would steal the focus, but are disabled
576 q_roll
= new QRollEffect( w
, flags
, orient
);
581 Fade in widget \a w in \a time ms.
583 void qFadeEffect( QWidget
* w
, int time
)
590 qApp
->sendPostedEvents( w
, QEvent::Move
);
591 qApp
->sendPostedEvents( w
, QEvent::Resize
);
594 uint flags
= Qt::WStyle_Customize
| Qt::WNoAutoErase
| Qt::WStyle_StaysOnTop
595 | (w
->isPopup() ? Qt::WType_Popup
: (Qt::WX11BypassWM
| Qt::WStyle_Tool
));
597 uint flags
= Qt::WStyle_Customize
| Qt::WType_Popup
| Qt::WX11BypassWM
| Qt::WNoAutoErase
| Qt::WStyle_StaysOnTop
;
600 // those can popups - they would steal the focus, but are disabled
601 q_blend
= new QAlphaWidget( w
, flags
);
603 q_blend
->run( time
);
605 #endif //QT_NO_EFFECTS