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

0001 #ifndef oxygenmenubardata_imp_h
0002 #define oxygenmenubardata_imp_h
0003 
0004 //////////////////////////////////////////////////////////////////////////////
0005 // oxygenmenubardata_imp.h
0006 // implements menubar data templatized methods
0007 // -------------------
0008 //
0009 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0010 //
0011 // SPDX-License-Identifier: MIT
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 namespace Oxygen
0015 {
0016 //________________________________________________________________________
0017 template<typename T>
0018 void MenuBarDataV1::enterEvent(const QObject *object)
0019 {
0020     const T *local = qobject_cast<const T *>(object);
0021     if (!local)
0022         return;
0023 
0024     // if the current action is still active, one does nothing
0025     if (local->activeAction() == currentAction().data())
0026         return;
0027 
0028     if (currentAnimation().data()->isRunning())
0029         currentAnimation().data()->stop();
0030     clearCurrentAction();
0031     clearCurrentRect();
0032 }
0033 
0034 //________________________________________________________________________
0035 template<typename T>
0036 void MenuBarDataV1::leaveEvent(const QObject *object)
0037 {
0038     const T *local = qobject_cast<const T *>(object);
0039     if (!local)
0040         return;
0041 
0042     // if the current action is still active, one does nothing
0043     if (local->activeAction() == currentAction().data())
0044         return;
0045 
0046     if (currentAnimation().data()->isRunning())
0047         currentAnimation().data()->stop();
0048     if (previousAnimation().data()->isRunning())
0049         previousAnimation().data()->stop();
0050     if (currentAction()) {
0051         setPreviousRect(currentRect());
0052         clearCurrentAction();
0053         clearCurrentRect();
0054         previousAnimation().data()->start();
0055     }
0056 
0057     // trigger update
0058     setDirty();
0059 }
0060 
0061 //________________________________________________________________________
0062 template<typename T>
0063 void MenuBarDataV1::mouseMoveEvent(const QObject *object)
0064 {
0065     const T *local = qobject_cast<const T *>(object);
0066     if (!local)
0067         return;
0068 
0069     // check action
0070     if (local->activeAction() == currentAction().data())
0071         return;
0072 
0073     bool hasCurrentAction(currentAction());
0074 
0075     // check current action
0076     if (currentAction()) {
0077         if (currentAnimation().data()->isRunning())
0078             currentAnimation().data()->stop();
0079         if (previousAnimation().data()->isRunning()) {
0080             previousAnimation().data()->setCurrentTime(0);
0081             previousAnimation().data()->stop();
0082         }
0083 
0084         // only start fadeout effect if there is no new selected action
0085         // if( !activeActionValid )
0086         if (!local->activeAction()) {
0087             setPreviousRect(currentRect());
0088             previousAnimation().data()->start();
0089         }
0090 
0091         clearCurrentAction();
0092         clearCurrentRect();
0093     }
0094 
0095     // check if local current actions is valid
0096     bool activeActionValid(local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator());
0097     if (activeActionValid) {
0098         if (currentAnimation().data()->isRunning())
0099             currentAnimation().data()->stop();
0100 
0101         setCurrentAction(local->activeAction());
0102         setCurrentRect(local->actionGeometry(currentAction().data()));
0103         if (!hasCurrentAction) {
0104             currentAnimation().data()->start();
0105         }
0106     }
0107 }
0108 
0109 //________________________________________________________________________
0110 template<typename T>
0111 void MenuBarDataV1::mousePressEvent(const QObject *object)
0112 {
0113     const T *local = qobject_cast<const T *>(object);
0114     if (!local)
0115         return;
0116 
0117     // check action
0118     if (local->activeAction() == currentAction().data())
0119         return;
0120 
0121     // check current action
0122     bool activeActionValid(local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator());
0123     if (currentAction() && !activeActionValid) {
0124         if (currentAnimation().data()->isRunning())
0125             currentAnimation().data()->stop();
0126         if (previousAnimation().data()->isRunning())
0127             previousAnimation().data()->stop();
0128 
0129         setPreviousRect(currentRect());
0130         previousAnimation().data()->start();
0131 
0132         clearCurrentAction();
0133         clearCurrentRect();
0134     }
0135 }
0136 
0137 //________________________________________________________________________
0138 template<typename T>
0139 void MenuBarDataV2::enterEvent(const QObject *object)
0140 {
0141     // cast widget
0142     const T *local = qobject_cast<const T *>(object);
0143     if (!local)
0144         return;
0145 
0146     if (_timer.isActive())
0147         _timer.stop();
0148 
0149     // if the current action is still active, one does nothing
0150     if (currentAction() && local->activeAction() == currentAction().data())
0151         return;
0152 
0153     if (animation().data()->isRunning())
0154         animation().data()->stop();
0155     if (progressAnimation().data()->isRunning())
0156         progressAnimation().data()->stop();
0157     clearPreviousRect();
0158     clearAnimatedRect();
0159 
0160     if (local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator()) {
0161         setCurrentAction(local->activeAction());
0162         setCurrentRect(local->actionGeometry(currentAction().data()));
0163         animation().data()->setDirection(Animation::Forward);
0164         animation().data()->start();
0165 
0166     } else {
0167         clearCurrentAction();
0168         clearCurrentRect();
0169     }
0170 
0171     return;
0172 }
0173 
0174 //________________________________________________________________________
0175 template<typename T>
0176 void MenuBarDataV2::leaveEvent(const QObject *object)
0177 {
0178     const T *local = qobject_cast<const T *>(object);
0179     if (!local)
0180         return;
0181 
0182     // if the current action is still active, one does nothing
0183     if (local->activeAction() && local->activeAction() == currentAction().data()) {
0184         return;
0185     }
0186 
0187     if (progressAnimation().data()->isRunning())
0188         progressAnimation().data()->stop();
0189     if (animation().data()->isRunning())
0190         animation().data()->stop();
0191     clearAnimatedRect();
0192     clearPreviousRect();
0193     if (currentAction()) {
0194         clearCurrentAction();
0195         animation().data()->setDirection(Animation::Backward);
0196         animation().data()->start();
0197     }
0198 
0199     // trigger update
0200     setDirty();
0201 
0202     return;
0203 }
0204 
0205 //________________________________________________________________________
0206 template<typename T>
0207 void MenuBarDataV2::mouseMoveEvent(const QObject *object)
0208 {
0209     const T *local = qobject_cast<const T *>(object);
0210     if (!local)
0211         return;
0212     if (local->activeAction() == currentAction().data())
0213         return;
0214 
0215     // check if current position match another action
0216     if (local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator()) {
0217         if (_timer.isActive())
0218             _timer.stop();
0219 
0220         QAction *activeAction(local->activeAction());
0221 
0222         // update previous rect if the current action is valid
0223         QRect activeRect(local->actionGeometry(activeAction));
0224         if (currentAction()) {
0225             if (!progressAnimation().data()->isRunning()) {
0226                 setPreviousRect(currentRect());
0227 
0228             } else if (progress() < 1 && currentRect().isValid() && previousRect().isValid()) {
0229                 // re-calculate previous rect so that animatedRect
0230                 // is unchanged after currentRect is updated
0231                 // this prevents from having jumps in the animation
0232                 qreal ratio = progress() / (1.0 - progress());
0233                 _previousRect.adjust(ratio * (currentRect().left() - activeRect.left()),
0234                                      ratio * (currentRect().top() - activeRect.top()),
0235                                      ratio * (currentRect().right() - activeRect.right()),
0236                                      ratio * (currentRect().bottom() - activeRect.bottom()));
0237             }
0238 
0239             // update current action
0240             setCurrentAction(activeAction);
0241             setCurrentRect(activeRect);
0242             if (animation().data()->isRunning())
0243                 animation().data()->stop();
0244             if (!progressAnimation().data()->isRunning())
0245                 progressAnimation().data()->start();
0246 
0247         } else {
0248             // update current action
0249             setCurrentAction(activeAction);
0250             setCurrentRect(activeRect);
0251             if (!_entered) {
0252                 _entered = true;
0253                 if (animation().data()->isRunning())
0254                     animation().data()->stop();
0255                 if (!progressAnimation().data()->isRunning())
0256                     progressAnimation().data()->start();
0257 
0258             } else {
0259                 setPreviousRect(activeRect);
0260                 clearAnimatedRect();
0261                 if (progressAnimation().data()->isRunning())
0262                     progressAnimation().data()->stop();
0263                 animation().data()->setDirection(Animation::Forward);
0264                 if (!animation().data()->isRunning())
0265                     animation().data()->start();
0266             }
0267         }
0268 
0269     } else if (currentAction()) {
0270         _timer.start(150, this);
0271     }
0272 
0273     return;
0274 }
0275 }
0276 
0277 #endif