1 #ifndef oxygenmenubar_data_h
2 #define oxygenmenubar_data_h
3 
4 //////////////////////////////////////////////////////////////////////////////
5 // oxygenmenubardata.h
6 // data container for QMenuBar animations
7 // -------------------
8 //
9 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
10 //
11 // SPDX-License-Identifier: MIT
12 //////////////////////////////////////////////////////////////////////////////
13 
14 #include "oxygenanimationdata.h"
15 #include "oxygen.h"
16 
17 #include <QMenuBar>
18 #include <QBasicTimer>
19 
20 namespace Oxygen
21 {
22 
23     //* widget index
24     enum WidgetIndex
25     {
26         Current,
27         Previous
28     };
29 
30     //* menubar data
31     class MenuBarData: public AnimationData
32     {
33 
34         Q_OBJECT
35 
36         public:
37 
38         //* constructor
39         MenuBarData( QObject* parent, QWidget* target );
40 
41         protected:
42 
43         bool _isMenu = false;
44         int _motions = -1;
45 
46     };
47 
48     //* menubar data
49     class MenuBarDataV1: public MenuBarData
50     {
51 
52         Q_OBJECT
53 
54         //* declare opacity property
55         Q_PROPERTY( qreal currentOpacity READ currentOpacity WRITE setCurrentOpacity )
56         Q_PROPERTY( qreal previousOpacity READ previousOpacity WRITE setPreviousOpacity )
57 
58         public:
59 
60         //* constructor
61         MenuBarDataV1( QObject* parent, QWidget* target, int duration );
62 
63         //* event filter
64         bool eventFilter( QObject*, QEvent* ) override;
65 
66         //* animations
currentAnimation(void)67         const Animation::Pointer& currentAnimation( void ) const
68         { return _current._animation; }
69 
70         //* animations
previousAnimation(void)71         const Animation::Pointer& previousAnimation( void ) const
72         { return _previous._animation; }
73 
74         //* return animation matching given point
animation(const QPoint & point)75         Animation::Pointer animation( const QPoint& point ) const
76         {
77             if( currentRect().contains( point ) ) return currentAnimation();
78             else if( previousRect().contains( point ) ) return previousAnimation();
79             else return Animation::Pointer();
80         }
81 
82         //* return animation matching given point
opacity(const QPoint & point)83         qreal opacity( const QPoint& point ) const
84         {
85             if( currentRect().contains( point ) ) return currentOpacity();
86             else if( previousRect().contains( point ) ) return previousOpacity();
87             else return OpacityInvalid;
88         }
89 
90         // return rect matching QPoint
currentRect(const QPoint & point)91         QRect currentRect( const QPoint& point ) const
92         {
93             if( currentRect().contains( point ) ) return currentRect();
94             else if( previousRect().contains( point ) ) return previousRect();
95             else return QRect();
96         }
97 
98         //* animation associated to given Widget index
animation(WidgetIndex index)99         const Animation::Pointer& animation( WidgetIndex index ) const
100         { return index == Current ? currentAnimation():previousAnimation(); }
101 
102         //* opacity associated to given Widget index
opacity(WidgetIndex index)103         qreal opacity( WidgetIndex index ) const
104         { return index == Current ? currentOpacity():previousOpacity(); }
105 
106         //* opacity associated to given Widget index
currentRect(WidgetIndex index)107         const QRect& currentRect( WidgetIndex index ) const
108         { return index == Current ? currentRect():previousRect(); }
109 
110         //* duration
setDuration(int duration)111         void setDuration( int duration ) override
112         {
113             currentAnimation().data()->setDuration( duration );
114             previousAnimation().data()->setDuration( duration );
115         }
116 
117         //* current opacity
currentOpacity(void)118         qreal currentOpacity( void ) const
119         { return _current._opacity; }
120 
121         //* current opacity
setCurrentOpacity(qreal value)122         void setCurrentOpacity( qreal value )
123         {
124             value = digitize( value );
125             if( _current._opacity == value ) return;
126             _current._opacity = value;
127             setDirty();
128         }
129 
130         //* current rect
currentRect(void)131         const QRect& currentRect( void ) const
132         { return _current._rect; }
133 
134         //* previous opacity
previousOpacity(void)135         qreal previousOpacity( void ) const
136         { return _previous._opacity; }
137 
138         //* previous opacity
setPreviousOpacity(qreal value)139         void setPreviousOpacity( qreal value )
140         {
141             value = digitize( value );
142             if( _previous._opacity == value ) return;
143             _previous._opacity = value;
144             setDirty();
145         }
146 
147         //* previous rect
previousRect(void)148         const QRect& previousRect( void ) const
149         { return _previous._rect; }
150 
151         protected:
152 
153         //*@name current action handling
154         //@{
155 
156         //* guarded action pointer
157         using ActionPointer = WeakPointer<QAction>;
158 
159         //* current action
currentAction(void)160         virtual const ActionPointer& currentAction( void ) const
161         { return _currentAction; }
162 
163         //* current action
setCurrentAction(QAction * action)164         virtual void setCurrentAction( QAction* action )
165         { _currentAction = ActionPointer( action ); }
166 
167         //* current action
clearCurrentAction(void)168         virtual void clearCurrentAction( void )
169         { _currentAction = ActionPointer(); }
170 
171         //@}
172 
173         //*@name rect handling
174         //@{
175 
176         //* current rect
setCurrentRect(const QRect & rect)177         virtual void setCurrentRect( const QRect& rect )
178         { _current._rect = rect; }
179 
180         //* current rect
clearCurrentRect(void)181         virtual void clearCurrentRect( void )
182         { _current._rect = QRect(); }
183 
184         //* previous rect
setPreviousRect(const QRect & rect)185         virtual void setPreviousRect( const QRect& rect )
186         { _previous._rect = rect; }
187 
188         //* previous rect
clearPreviousRect(void)189         virtual void clearPreviousRect( void )
190         { _previous._rect = QRect(); }
191 
192         //@}
193 
194         // leave event
195         template< typename T > inline void enterEvent( const QObject* object );
196 
197         // leave event
198         template< typename T > inline void leaveEvent( const QObject* object );
199 
200         //* mouse move event
201         template< typename T > inline void mouseMoveEvent( const QObject* object );
202 
203         //* mouse move event
204         template< typename T > inline void mousePressEvent( const QObject* object );
205 
206         //* menubar enterEvent
enterEvent(const QObject * object)207         virtual void enterEvent( const QObject* object )
208         { enterEvent<QMenuBar>( object ); }
209 
210         //* menubar enterEvent
leaveEvent(const QObject * object)211         virtual void leaveEvent( const QObject* object )
212         { leaveEvent<QMenuBar>( object ); }
213 
214         //* menubar mouseMoveEvent
mouseMoveEvent(const QObject * object)215         virtual void mouseMoveEvent( const QObject* object )
216         { mouseMoveEvent<QMenuBar>( object ); }
217 
218         //* menubar mousePressEvent
mousePressEvent(const QObject * object)219         virtual void mousePressEvent( const QObject* object )
220         { mousePressEvent<QMenuBar>( object ); }
221 
222         private:
223 
224         //* container for needed animation data
225         class Data
226         {
227             public:
228 
229             //* default constructor
Data(void)230             Data( void ):
231                 _opacity(0)
232                 {}
233 
234             Animation::Pointer _animation;
235             qreal _opacity;
236             QRect _rect;
237         };
238 
239         //* current tab animation data (for hover enter animations)
240         Data _current;
241 
242         //* previous tab animations data (for hover leave animations)
243         Data _previous;
244 
245         //* current action
246         ActionPointer _currentAction;
247 
248     };
249 
250 
251     //* menubar data
252     class MenuBarDataV2: public MenuBarData
253     {
254 
255         Q_OBJECT
256         Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
257         Q_PROPERTY( qreal progress READ progress  WRITE setProgress )
258 
259         public:
260 
261         //* constructor
262         MenuBarDataV2( QObject* parent, QWidget* target, int duration );
263 
264         //* event filter
265         bool eventFilter( QObject*, QEvent* ) override;
266 
267         //* return animation associated to action at given position, if any
animation(void)268         virtual const Animation::Pointer& animation( void ) const
269         { return _animation; }
270 
271         //* return animation associated to action at given position, if any
progressAnimation(void)272         virtual const Animation::Pointer& progressAnimation( void ) const
273         { return _progressAnimation; }
274 
275         //* duration
setDuration(int duration)276         void setDuration( int duration ) override
277         { animation().data()->setDuration( duration ); }
278 
279         //* duration
setFollowMouseDuration(int duration)280         virtual void setFollowMouseDuration( int duration )
281         { progressAnimation().data()->setDuration( duration ); }
282 
283         //* return 'hover' rect position when widget is animated
animatedRect(void)284         virtual const QRect& animatedRect( void ) const
285         { return _animatedRect; }
286 
287         //* current rect
currentRect(void)288         virtual const QRect& currentRect( void ) const
289         { return _currentRect; }
290 
291         //* timer
timer(void)292         const QBasicTimer& timer( void ) const
293         { return _timer; }
294 
295         //* animation opacity
opacity(void)296         virtual qreal opacity( void ) const
297         { return _opacity; }
298 
299         //* animation opacity
setOpacity(qreal value)300         virtual void setOpacity( qreal value )
301         {
302             value = digitize( value );
303             if( _opacity == value ) return;
304             _opacity = value;
305             setDirty();
306         }
307 
308         //* animation progress
progress(void)309         virtual qreal progress( void ) const
310         { return _progress; }
311 
312         //* animation progress
setProgress(qreal value)313         virtual void setProgress( qreal value )
314         {
315             value = digitize( value );
316             if( _progress == value ) return;
317             _progress = value;
318             updateAnimatedRect();
319         }
320 
321         protected:
322 
setEntered(bool value)323         virtual void setEntered( bool value )
324         { _entered = value; }
325 
326         //* animated rect
clearAnimatedRect(void)327         virtual void clearAnimatedRect( void )
328         { _animatedRect = QRect(); }
329 
330         //* updated animated rect
331         virtual void updateAnimatedRect( void );
332 
333         //* timer event
334         void timerEvent( QTimerEvent* ) override;
335 
336         //*@name current action handling
337         //@{
338 
339         //* guarded action pointer
340         using ActionPointer = WeakPointer<QAction>;
341 
342         //* current action
currentAction(void)343         virtual const ActionPointer& currentAction( void ) const
344         { return _currentAction; }
345 
346         //* current action
setCurrentAction(QAction * action)347         virtual void setCurrentAction( QAction* action )
348         { _currentAction = ActionPointer( action ); }
349 
350         //* current action
clearCurrentAction(void)351         virtual void clearCurrentAction( void )
352         { _currentAction = ActionPointer(); }
353 
354         //@}
355 
356         //*@name rect handling
357         //@{
358 
359         //* current rect
setCurrentRect(const QRect & rect)360         virtual void setCurrentRect( const QRect& rect )
361         { _currentRect = rect; }
362 
363         //* current rect
clearCurrentRect(void)364         virtual void clearCurrentRect( void )
365         { _currentRect = QRect(); }
366 
367         //* previous rect
previousRect(void)368         virtual const QRect& previousRect( void ) const
369         { return _previousRect; }
370 
371         //* previous rect
setPreviousRect(const QRect & rect)372         virtual void setPreviousRect( const QRect& rect )
373         { _previousRect = rect; }
374 
375         //* previous rect
clearPreviousRect(void)376         virtual void clearPreviousRect( void )
377         { _previousRect = QRect(); }
378 
379         //@}
380 
381         // leave event
382         template< typename T > inline void enterEvent( const QObject* object );
383 
384         // leave event
385         template< typename T > inline void leaveEvent( const QObject* object );
386 
387         //* mouse move event
388         template< typename T > inline void mouseMoveEvent( const QObject* object );
389 
390         //* menubar enterEvent
enterEvent(const QObject * object)391         virtual void enterEvent( const QObject* object )
392         { enterEvent<QMenuBar>( object ); }
393 
394         //* menubar enterEvent
leaveEvent(const QObject * object)395         virtual void leaveEvent( const QObject* object )
396         { leaveEvent<QMenuBar>( object ); }
397 
398         //* menubar mouseMoveEvent
mouseMoveEvent(const QObject * object)399         virtual void mouseMoveEvent( const QObject* object )
400         { mouseMoveEvent<QMenuBar>( object ); }
401 
402         private:
403 
404         //* fade animation
405         Animation::Pointer _animation;
406 
407         //* progress animation
408         Animation::Pointer _progressAnimation;
409 
410         //* opacity
411         qreal _opacity = 0;
412 
413         //* opacity
414         qreal _progress = 0;
415 
416         //* timer
417         /** this allows to add some delay before starting leaveEvent animation */
418         QBasicTimer _timer;
419 
420         //* current action
421         ActionPointer _currentAction;
422 
423         // current rect
424         QRect _currentRect;
425 
426         // previous rect
427         QRect _previousRect;
428 
429         // animated rect
430         QRect _animatedRect;
431 
432         //* true if toolbar was entered at least once (this prevents some initialization glitches)
433         bool _entered = false;
434 
435     };
436 }
437 
438 #include "oxygenmenubardata_imp.h"
439 #endif
440