1 #ifndef oxygenmenubardata_imp_h 2 #define oxygenmenubardata_imp_h 3 4 ////////////////////////////////////////////////////////////////////////////// 5 // oxygenmenubardata_imp.h 6 // implements menubar data templatized methods 7 // ------------------- 8 // 9 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr> 10 // 11 // SPDX-License-Identifier: MIT 12 ////////////////////////////////////////////////////////////////////////////// 13 14 namespace Oxygen 15 { 16 17 //________________________________________________________________________ enterEvent(const QObject * object)18 template< typename T > void MenuBarDataV1::enterEvent( const QObject* object ) 19 { 20 21 const T* local = qobject_cast<const T*>( object ); 22 if( !local ) return; 23 24 // if the current action is still active, one does nothing 25 if( local->activeAction() == currentAction().data() ) return; 26 27 if( currentAnimation().data()->isRunning() ) currentAnimation().data()->stop(); 28 clearCurrentAction(); 29 clearCurrentRect(); 30 31 } 32 33 //________________________________________________________________________ leaveEvent(const QObject * object)34 template< typename T > void MenuBarDataV1::leaveEvent( const QObject* object ) 35 { 36 37 const T* local = qobject_cast<const T*>( object ); 38 if( !local ) return; 39 40 // if the current action is still active, one does nothing 41 if( local->activeAction() == currentAction().data() ) return; 42 43 if( currentAnimation().data()->isRunning() ) currentAnimation().data()->stop(); 44 if( previousAnimation().data()->isRunning() ) previousAnimation().data()->stop(); 45 if( currentAction() ) 46 { 47 setPreviousRect( currentRect() ); 48 clearCurrentAction(); 49 clearCurrentRect(); 50 previousAnimation().data()->start(); 51 } 52 53 // trigger update 54 setDirty(); 55 56 } 57 58 //________________________________________________________________________ mouseMoveEvent(const QObject * object)59 template< typename T > void MenuBarDataV1::mouseMoveEvent( const QObject* object ) 60 { 61 62 const T* local = qobject_cast<const T*>( object ); 63 if( !local ) return; 64 65 // check action 66 if( local->activeAction() == currentAction().data() ) return; 67 68 bool hasCurrentAction( currentAction() ); 69 70 // check current action 71 if( currentAction() ) 72 { 73 if( currentAnimation().data()->isRunning() ) currentAnimation().data()->stop(); 74 if( previousAnimation().data()->isRunning() ) { 75 previousAnimation().data()->setCurrentTime(0); 76 previousAnimation().data()->stop(); 77 } 78 79 // only start fadeout effect if there is no new selected action 80 //if( !activeActionValid ) 81 if( !local->activeAction() ) 82 { 83 setPreviousRect( currentRect() ); 84 previousAnimation().data()->start(); 85 } 86 87 clearCurrentAction(); 88 clearCurrentRect(); 89 90 } 91 92 // check if local current actions is valid 93 bool activeActionValid( local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator() ); 94 if( activeActionValid ) 95 { 96 if( currentAnimation().data()->isRunning() ) currentAnimation().data()->stop(); 97 98 setCurrentAction( local->activeAction() ); 99 setCurrentRect( local->actionGeometry( currentAction().data() ) ); 100 if( !hasCurrentAction ) 101 { currentAnimation().data()->start(); } 102 103 } 104 105 } 106 107 //________________________________________________________________________ mousePressEvent(const QObject * object)108 template< typename T > void MenuBarDataV1::mousePressEvent( const QObject* object ) 109 { 110 111 const T* local = qobject_cast<const T*>( object ); 112 if( !local ) return; 113 114 // check action 115 if( local->activeAction() == currentAction().data() ) return; 116 117 // check current action 118 bool activeActionValid( local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator() ); 119 if( currentAction() && !activeActionValid ) 120 { 121 122 if( currentAnimation().data()->isRunning() ) currentAnimation().data()->stop(); 123 if( previousAnimation().data()->isRunning() ) previousAnimation().data()->stop(); 124 125 setPreviousRect( currentRect() ); 126 previousAnimation().data()->start(); 127 128 clearCurrentAction(); 129 clearCurrentRect(); 130 131 } 132 133 } 134 135 //________________________________________________________________________ enterEvent(const QObject * object)136 template< typename T > void MenuBarDataV2::enterEvent( const QObject* object ) 137 { 138 139 // cast widget 140 const T* local = qobject_cast<const T*>( object ); 141 if( !local ) return; 142 143 if( _timer.isActive() ) _timer.stop(); 144 145 // if the current action is still active, one does nothing 146 if( currentAction() && local->activeAction() == currentAction().data() ) return; 147 148 if( animation().data()->isRunning() ) animation().data()->stop(); 149 if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop(); 150 clearPreviousRect(); 151 clearAnimatedRect(); 152 153 if( local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator() ) 154 { 155 setCurrentAction( local->activeAction() ); 156 setCurrentRect( local->actionGeometry( currentAction().data() ) ); 157 animation().data()->setDirection( Animation::Forward ); 158 animation().data()->start(); 159 160 } else { 161 162 clearCurrentAction(); 163 clearCurrentRect(); 164 165 } 166 167 return; 168 } 169 170 //________________________________________________________________________ leaveEvent(const QObject * object)171 template< typename T > void MenuBarDataV2::leaveEvent( const QObject* object ) 172 { 173 174 const T* local = qobject_cast<const T*>( object ); 175 if( !local ) return; 176 177 // if the current action is still active, one does nothing 178 if( local->activeAction() && local->activeAction() == currentAction().data() ) 179 { return; } 180 181 if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop(); 182 if( animation().data()->isRunning() ) animation().data()->stop(); 183 clearAnimatedRect(); 184 clearPreviousRect(); 185 if( currentAction() ) 186 { 187 clearCurrentAction(); 188 animation().data()->setDirection( Animation::Backward ); 189 animation().data()->start(); 190 } 191 192 // trigger update 193 setDirty(); 194 195 return; 196 197 } 198 199 //________________________________________________________________________ mouseMoveEvent(const QObject * object)200 template< typename T > void MenuBarDataV2::mouseMoveEvent( const QObject* object ) 201 { 202 const T* local = qobject_cast<const T*>( object ); 203 if( !local ) return; 204 if( local->activeAction() == currentAction().data() ) return; 205 206 // check if current position match another action 207 if( local->activeAction() && local->activeAction()->isEnabled() && !local->activeAction()->isSeparator()) 208 { 209 210 if( _timer.isActive() ) _timer.stop(); 211 212 QAction* activeAction( local->activeAction() ); 213 214 // update previous rect if the current action is valid 215 QRect activeRect( local->actionGeometry( activeAction ) ); 216 if( currentAction() ) 217 { 218 if( !progressAnimation().data()->isRunning() ) 219 { 220 221 setPreviousRect( currentRect() ); 222 223 } else if( progress() < 1 && currentRect().isValid() && previousRect().isValid() ) { 224 225 // re-calculate previous rect so that animatedRect 226 // is unchanged after currentRect is updated 227 // this prevents from having jumps in the animation 228 qreal ratio = progress()/(1.0-progress()); 229 _previousRect.adjust( 230 ratio*( currentRect().left() - activeRect.left() ), 231 ratio*( currentRect().top() - activeRect.top() ), 232 ratio*( currentRect().right() - activeRect.right() ), 233 ratio*( currentRect().bottom() - activeRect.bottom() ) ); 234 235 } 236 237 // update current action 238 setCurrentAction( activeAction ); 239 setCurrentRect( activeRect ); 240 if( animation().data()->isRunning() ) animation().data()->stop(); 241 if( !progressAnimation().data()->isRunning() ) progressAnimation().data()->start(); 242 243 } else { 244 245 // update current action 246 setCurrentAction( activeAction ); 247 setCurrentRect( activeRect ); 248 if( !_entered ) 249 { 250 251 _entered = true; 252 if( animation().data()->isRunning() ) animation().data()->stop(); 253 if( !progressAnimation().data()->isRunning() ) progressAnimation().data()->start(); 254 255 } else { 256 257 setPreviousRect( activeRect ); 258 clearAnimatedRect(); 259 if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop(); 260 animation().data()->setDirection( Animation::Forward ); 261 if( !animation().data()->isRunning() ) animation().data()->start(); 262 } 263 264 } 265 266 } else if( currentAction() ) { 267 268 _timer.start( 150, this ); 269 270 } 271 272 return; 273 274 } 275 276 } 277 278 #endif 279