1 #ifndef oxygentransitionwidget_h
2 #define oxygentransitionwidget_h
3 //////////////////////////////////////////////////////////////////////////////
4 // oxygentransitionwidget.h
5 // stores event filters and maps widgets to transitions for transitions
6 // -------------------
7 //
8 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
9 //
10 // SPDX-License-Identifier: MIT
11 //////////////////////////////////////////////////////////////////////////////
12 
13 #include "oxygenanimation.h"
14 #include "oxygen.h"
15 
16 #include <QWidget>
17 
18 #include <cmath>
19 
20 namespace Oxygen
21 {
22 
23     //* temporary widget used to perform smooth transition between one widget state and another
24     class TransitionWidget: public QWidget
25     {
26 
27         Q_OBJECT
28 
29         //* declare opacity property
30         Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
31 
32         public:
33 
34         //* shortcut to painter
35         using Pointer = WeakPointer<TransitionWidget>;
36 
37         //* constructor
38         TransitionWidget( QWidget* parent, int duration );
39 
40         //*@name flags
41         //@{
42         enum Flag
43         {
44             None = 0,
45             GrabFromWindow = 1<<0,
46             Transparent = 1<<1,
47             PaintOnWidget = 1<<2
48         };
49 
Q_DECLARE_FLAGS(Flags,Flag)50         Q_DECLARE_FLAGS(Flags, Flag)
51 
52         void setFlags( Flags value )
53         { _flags = value; }
54 
55         void setFlag( Flag flag, bool value = true )
56         {
57             if( value ) _flags |= flag;
58             else _flags &= (~flag);
59         }
60 
testFlag(Flag flag)61         bool testFlag( Flag flag ) const
62         { return _flags.testFlag( flag ); }
63 
64         //@}
65 
66         //* duration
setDuration(int duration)67         void setDuration( int duration )
68         {
69             if( _animation )
70             { _animation.data()->setDuration( duration ); }
71         }
72 
73         //* duration
duration(void)74         int duration( void ) const
75         { return ( _animation ) ? _animation.data()->duration() : 0; }
76 
77         //* steps
setSteps(int value)78         static void setSteps( int value )
79         { _steps = value; }
80 
81         //*@name opacity
82         //@{
83 
opacity(void)84         qreal opacity( void ) const
85         { return _opacity; }
86 
setOpacity(qreal value)87         void setOpacity( qreal value )
88         {
89             value = digitize( value );
90             if( _opacity == value ) return;
91             _opacity = value;
92             update();
93         }
94 
95         //@}
96 
97         //@name pixmaps handling
98         //@{
99 
100         //* start
resetStartPixmap(void)101         void resetStartPixmap( void )
102         { setStartPixmap( QPixmap() ); }
103 
104         //* start
setStartPixmap(QPixmap pixmap)105         void setStartPixmap( QPixmap pixmap )
106         { _startPixmap = pixmap; }
107 
108         //* start
startPixmap(void)109         const QPixmap& startPixmap( void ) const
110         { return _startPixmap; }
111 
112         //* end
resetEndPixmap(void)113         void resetEndPixmap( void )
114         { setEndPixmap( QPixmap() ); }
115 
116         //* end
setEndPixmap(QPixmap pixmap)117         void setEndPixmap( QPixmap pixmap )
118         {
119             _endPixmap = pixmap;
120             _currentPixmap = pixmap;
121         }
122 
123         //* start
endPixmap(void)124         const QPixmap& endPixmap( void ) const
125         { return _endPixmap; }
126 
127         //* current
currentPixmap(void)128         const QPixmap& currentPixmap( void ) const
129         { return _currentPixmap; }
130 
131         //@}
132 
133         //* grap pixmap
134         QPixmap grab( QWidget* = 0, QRect = QRect() );
135 
136         //* true if animated
isAnimated(void)137         bool isAnimated( void ) const
138         { return _animation.data()->isRunning(); }
139 
140         //* end animation
endAnimation(void)141         void endAnimation( void )
142         { if( _animation.data()->isRunning() ) _animation.data()->stop(); }
143 
144         //* animate transition
animate(void)145         void animate( void )
146         {
147             if( _animation.data()->isRunning() ) _animation.data()->stop();
148             _animation.data()->start();
149         }
150 
151         //* true if paint is enabled
152         static bool paintEnabled( void );
153 
154         protected:
155 
156         //* generic event filter
157         bool event( QEvent* ) override;
158 
159         //* paint event
160         void paintEvent( QPaintEvent* ) override;
161 
162         private:
163 
164         //* grab widget background
165         /**
166         Background is not rendered properly using QWidget::render.
167         Use home-made grabber instead. This is directly inspired from bespin.
168         SPDX-FileCopyrightText: 2007 Thomas Luebking <thomas.luebking@web.de>
169         */
170         void grabBackground( QPixmap&, QWidget*, QRect& ) const;
171 
172         //* grab widget
173         void grabWidget( QPixmap&, QWidget*, QRect& ) const;
174 
175         //* fade pixmap
176         void fade( const QPixmap& source, QPixmap& target, qreal opacity, const QRect& ) const;
177 
178         //* apply step
digitize(const qreal & value)179         qreal digitize( const qreal& value ) const
180         {
181             if( _steps > 0 ) return std::floor( value*_steps )/_steps;
182             else return value;
183         }
184 
185         //* Flags
186         Flags _flags = None;
187 
188         //* paint enabled
189         static bool _paintEnabled;
190 
191         //* internal transition animation
192         Animation::Pointer _animation;
193 
194         //* animation starting pixmap
195         QPixmap _startPixmap;
196 
197         //* animation starting pixmap
198         QPixmap _localStartPixmap;
199 
200         //* animation starting pixmap
201         QPixmap _endPixmap;
202 
203         //* current pixmap
204         QPixmap _currentPixmap;
205 
206         //* current state opacity
207         qreal _opacity = 0;
208 
209         //* steps
210         static int _steps;
211 
212     };
213 
214 }
215 
216 #endif
217