File indexing completed on 2024-05-19 05:35:20

0001 #ifndef oxygenmenubar_data_h
0002 #define oxygenmenubar_data_h
0003 
0004 //////////////////////////////////////////////////////////////////////////////
0005 // oxygenmenubardata.h
0006 // data container for QMenuBar animations
0007 // -------------------
0008 //
0009 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0010 //
0011 // SPDX-License-Identifier: MIT
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 #include "oxygen.h"
0015 #include "oxygenanimationdata.h"
0016 
0017 #include <QBasicTimer>
0018 #include <QMenuBar>
0019 
0020 namespace Oxygen
0021 {
0022 //* widget index
0023 enum WidgetIndex { Current, Previous };
0024 
0025 //* menubar data
0026 class MenuBarData : public AnimationData
0027 {
0028     Q_OBJECT
0029 
0030 public:
0031     //* constructor
0032     MenuBarData(QObject *parent, QWidget *target);
0033 
0034 protected:
0035     bool _isMenu = false;
0036     int _motions = -1;
0037 };
0038 
0039 //* menubar data
0040 class MenuBarDataV1 : public MenuBarData
0041 {
0042     Q_OBJECT
0043 
0044     //* declare opacity property
0045     Q_PROPERTY(qreal currentOpacity READ currentOpacity WRITE setCurrentOpacity)
0046     Q_PROPERTY(qreal previousOpacity READ previousOpacity WRITE setPreviousOpacity)
0047 
0048 public:
0049     //* constructor
0050     MenuBarDataV1(QObject *parent, QWidget *target, int duration);
0051 
0052     //* event filter
0053     bool eventFilter(QObject *, QEvent *) override;
0054 
0055     //* animations
0056     const Animation::Pointer &currentAnimation(void) const
0057     {
0058         return _current._animation;
0059     }
0060 
0061     //* animations
0062     const Animation::Pointer &previousAnimation(void) const
0063     {
0064         return _previous._animation;
0065     }
0066 
0067     //* return animation matching given point
0068     Animation::Pointer animation(const QPoint &point) const
0069     {
0070         if (currentRect().contains(point))
0071             return currentAnimation();
0072         else if (previousRect().contains(point))
0073             return previousAnimation();
0074         else
0075             return Animation::Pointer();
0076     }
0077 
0078     //* return animation matching given point
0079     qreal opacity(const QPoint &point) const
0080     {
0081         if (currentRect().contains(point))
0082             return currentOpacity();
0083         else if (previousRect().contains(point))
0084             return previousOpacity();
0085         else
0086             return OpacityInvalid;
0087     }
0088 
0089     // return rect matching QPoint
0090     QRect currentRect(const QPoint &point) const
0091     {
0092         if (currentRect().contains(point))
0093             return currentRect();
0094         else if (previousRect().contains(point))
0095             return previousRect();
0096         else
0097             return QRect();
0098     }
0099 
0100     //* animation associated to given Widget index
0101     const Animation::Pointer &animation(WidgetIndex index) const
0102     {
0103         return index == Current ? currentAnimation() : previousAnimation();
0104     }
0105 
0106     //* opacity associated to given Widget index
0107     qreal opacity(WidgetIndex index) const
0108     {
0109         return index == Current ? currentOpacity() : previousOpacity();
0110     }
0111 
0112     //* opacity associated to given Widget index
0113     const QRect &currentRect(WidgetIndex index) const
0114     {
0115         return index == Current ? currentRect() : previousRect();
0116     }
0117 
0118     //* duration
0119     void setDuration(int duration) override
0120     {
0121         currentAnimation().data()->setDuration(duration);
0122         previousAnimation().data()->setDuration(duration);
0123     }
0124 
0125     //* current opacity
0126     qreal currentOpacity(void) const
0127     {
0128         return _current._opacity;
0129     }
0130 
0131     //* current opacity
0132     void setCurrentOpacity(qreal value)
0133     {
0134         value = digitize(value);
0135         if (_current._opacity == value)
0136             return;
0137         _current._opacity = value;
0138         setDirty();
0139     }
0140 
0141     //* current rect
0142     const QRect &currentRect(void) const
0143     {
0144         return _current._rect;
0145     }
0146 
0147     //* previous opacity
0148     qreal previousOpacity(void) const
0149     {
0150         return _previous._opacity;
0151     }
0152 
0153     //* previous opacity
0154     void setPreviousOpacity(qreal value)
0155     {
0156         value = digitize(value);
0157         if (_previous._opacity == value)
0158             return;
0159         _previous._opacity = value;
0160         setDirty();
0161     }
0162 
0163     //* previous rect
0164     const QRect &previousRect(void) const
0165     {
0166         return _previous._rect;
0167     }
0168 
0169 protected:
0170     //*@name current action handling
0171     //@{
0172 
0173     //* guarded action pointer
0174     using ActionPointer = WeakPointer<QAction>;
0175 
0176     //* current action
0177     virtual const ActionPointer &currentAction(void) const
0178     {
0179         return _currentAction;
0180     }
0181 
0182     //* current action
0183     virtual void setCurrentAction(QAction *action)
0184     {
0185         _currentAction = ActionPointer(action);
0186     }
0187 
0188     //* current action
0189     virtual void clearCurrentAction(void)
0190     {
0191         _currentAction = ActionPointer();
0192     }
0193 
0194     //@}
0195 
0196     //*@name rect handling
0197     //@{
0198 
0199     //* current rect
0200     virtual void setCurrentRect(const QRect &rect)
0201     {
0202         _current._rect = rect;
0203     }
0204 
0205     //* current rect
0206     virtual void clearCurrentRect(void)
0207     {
0208         _current._rect = QRect();
0209     }
0210 
0211     //* previous rect
0212     virtual void setPreviousRect(const QRect &rect)
0213     {
0214         _previous._rect = rect;
0215     }
0216 
0217     //* previous rect
0218     virtual void clearPreviousRect(void)
0219     {
0220         _previous._rect = QRect();
0221     }
0222 
0223     //@}
0224 
0225     // leave event
0226     template<typename T>
0227     inline void enterEvent(const QObject *object);
0228 
0229     // leave event
0230     template<typename T>
0231     inline void leaveEvent(const QObject *object);
0232 
0233     //* mouse move event
0234     template<typename T>
0235     inline void mouseMoveEvent(const QObject *object);
0236 
0237     //* mouse move event
0238     template<typename T>
0239     inline void mousePressEvent(const QObject *object);
0240 
0241     //* menubar enterEvent
0242     virtual void enterEvent(const QObject *object)
0243     {
0244         enterEvent<QMenuBar>(object);
0245     }
0246 
0247     //* menubar enterEvent
0248     virtual void leaveEvent(const QObject *object)
0249     {
0250         leaveEvent<QMenuBar>(object);
0251     }
0252 
0253     //* menubar mouseMoveEvent
0254     virtual void mouseMoveEvent(const QObject *object)
0255     {
0256         mouseMoveEvent<QMenuBar>(object);
0257     }
0258 
0259     //* menubar mousePressEvent
0260     virtual void mousePressEvent(const QObject *object)
0261     {
0262         mousePressEvent<QMenuBar>(object);
0263     }
0264 
0265 private:
0266     //* container for needed animation data
0267     class Data
0268     {
0269     public:
0270         //* default constructor
0271         Data(void)
0272             : _opacity(0)
0273         {
0274         }
0275 
0276         Animation::Pointer _animation;
0277         qreal _opacity;
0278         QRect _rect;
0279     };
0280 
0281     //* current tab animation data (for hover enter animations)
0282     Data _current;
0283 
0284     //* previous tab animations data (for hover leave animations)
0285     Data _previous;
0286 
0287     //* current action
0288     ActionPointer _currentAction;
0289 };
0290 
0291 //* menubar data
0292 class MenuBarDataV2 : public MenuBarData
0293 {
0294     Q_OBJECT
0295     Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
0296     Q_PROPERTY(qreal progress READ progress WRITE setProgress)
0297 
0298 public:
0299     //* constructor
0300     MenuBarDataV2(QObject *parent, QWidget *target, int duration);
0301 
0302     //* event filter
0303     bool eventFilter(QObject *, QEvent *) override;
0304 
0305     //* return animation associated to action at given position, if any
0306     virtual const Animation::Pointer &animation(void) const
0307     {
0308         return _animation;
0309     }
0310 
0311     //* return animation associated to action at given position, if any
0312     virtual const Animation::Pointer &progressAnimation(void) const
0313     {
0314         return _progressAnimation;
0315     }
0316 
0317     //* duration
0318     void setDuration(int duration) override
0319     {
0320         animation().data()->setDuration(duration);
0321     }
0322 
0323     //* duration
0324     virtual void setFollowMouseDuration(int duration)
0325     {
0326         progressAnimation().data()->setDuration(duration);
0327     }
0328 
0329     //* return 'hover' rect position when widget is animated
0330     virtual const QRect &animatedRect(void) const
0331     {
0332         return _animatedRect;
0333     }
0334 
0335     //* current rect
0336     virtual const QRect &currentRect(void) const
0337     {
0338         return _currentRect;
0339     }
0340 
0341     //* timer
0342     const QBasicTimer &timer(void) const
0343     {
0344         return _timer;
0345     }
0346 
0347     //* animation opacity
0348     virtual qreal opacity(void) const
0349     {
0350         return _opacity;
0351     }
0352 
0353     //* animation opacity
0354     virtual void setOpacity(qreal value)
0355     {
0356         value = digitize(value);
0357         if (_opacity == value)
0358             return;
0359         _opacity = value;
0360         setDirty();
0361     }
0362 
0363     //* animation progress
0364     virtual qreal progress(void) const
0365     {
0366         return _progress;
0367     }
0368 
0369     //* animation progress
0370     virtual void setProgress(qreal value)
0371     {
0372         value = digitize(value);
0373         if (_progress == value)
0374             return;
0375         _progress = value;
0376         updateAnimatedRect();
0377     }
0378 
0379 protected:
0380     virtual void setEntered(bool value)
0381     {
0382         _entered = value;
0383     }
0384 
0385     //* animated rect
0386     virtual void clearAnimatedRect(void)
0387     {
0388         _animatedRect = QRect();
0389     }
0390 
0391     //* updated animated rect
0392     virtual void updateAnimatedRect(void);
0393 
0394     //* timer event
0395     void timerEvent(QTimerEvent *) override;
0396 
0397     //*@name current action handling
0398     //@{
0399 
0400     //* guarded action pointer
0401     using ActionPointer = WeakPointer<QAction>;
0402 
0403     //* current action
0404     virtual const ActionPointer &currentAction(void) const
0405     {
0406         return _currentAction;
0407     }
0408 
0409     //* current action
0410     virtual void setCurrentAction(QAction *action)
0411     {
0412         _currentAction = ActionPointer(action);
0413     }
0414 
0415     //* current action
0416     virtual void clearCurrentAction(void)
0417     {
0418         _currentAction = ActionPointer();
0419     }
0420 
0421     //@}
0422 
0423     //*@name rect handling
0424     //@{
0425 
0426     //* current rect
0427     virtual void setCurrentRect(const QRect &rect)
0428     {
0429         _currentRect = rect;
0430     }
0431 
0432     //* current rect
0433     virtual void clearCurrentRect(void)
0434     {
0435         _currentRect = QRect();
0436     }
0437 
0438     //* previous rect
0439     virtual const QRect &previousRect(void) const
0440     {
0441         return _previousRect;
0442     }
0443 
0444     //* previous rect
0445     virtual void setPreviousRect(const QRect &rect)
0446     {
0447         _previousRect = rect;
0448     }
0449 
0450     //* previous rect
0451     virtual void clearPreviousRect(void)
0452     {
0453         _previousRect = QRect();
0454     }
0455 
0456     //@}
0457 
0458     // leave event
0459     template<typename T>
0460     inline void enterEvent(const QObject *object);
0461 
0462     // leave event
0463     template<typename T>
0464     inline void leaveEvent(const QObject *object);
0465 
0466     //* mouse move event
0467     template<typename T>
0468     inline void mouseMoveEvent(const QObject *object);
0469 
0470     //* menubar enterEvent
0471     virtual void enterEvent(const QObject *object)
0472     {
0473         enterEvent<QMenuBar>(object);
0474     }
0475 
0476     //* menubar enterEvent
0477     virtual void leaveEvent(const QObject *object)
0478     {
0479         leaveEvent<QMenuBar>(object);
0480     }
0481 
0482     //* menubar mouseMoveEvent
0483     virtual void mouseMoveEvent(const QObject *object)
0484     {
0485         mouseMoveEvent<QMenuBar>(object);
0486     }
0487 
0488 private:
0489     //* fade animation
0490     Animation::Pointer _animation;
0491 
0492     //* progress animation
0493     Animation::Pointer _progressAnimation;
0494 
0495     //* opacity
0496     qreal _opacity = 0;
0497 
0498     //* opacity
0499     qreal _progress = 0;
0500 
0501     //* timer
0502     /** this allows to add some delay before starting leaveEvent animation */
0503     QBasicTimer _timer;
0504 
0505     //* current action
0506     ActionPointer _currentAction;
0507 
0508     // current rect
0509     QRect _currentRect;
0510 
0511     // previous rect
0512     QRect _previousRect;
0513 
0514     // animated rect
0515     QRect _animatedRect;
0516 
0517     //* true if toolbar was entered at least once (this prevents some initialization glitches)
0518     bool _entered = false;
0519 };
0520 }
0521 
0522 #include "oxygenmenubardata_imp.h"
0523 #endif