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