File indexing completed on 2024-05-12 05:34:36

0001 #ifndef oxygentoolbarstatedata_h
0002 #define oxygentoolbarstatedata_h
0003 /*
0004 * this file is part of the oxygen gtk engine
0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006 *
0007 * SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "../oxygenanimationdata.h"
0011 #include "../oxygenanimationmodes.h"
0012 #include "../oxygengtkutils.h"
0013 #include "oxygenfollowmousedata.h"
0014 #include "oxygensignal.h"
0015 #include "oxygentimeline.h"
0016 #include "oxygentimer.h"
0017 
0018 #include <map>
0019 #include <gtk/gtk.h>
0020 
0021 namespace Oxygen
0022 {
0023     class ToolBarStateData: public FollowMouseData
0024     {
0025 
0026         public:
0027 
0028         //! constructor
0029         ToolBarStateData( void ):
0030             _target( 0L ),
0031             _dirtyRect( Gtk::gdk_rectangle() )
0032         {}
0033 
0034         //! destructor
0035         virtual ~ToolBarStateData( void )
0036         { disconnect( _target ); }
0037 
0038         //! setup connections
0039         using FollowMouseData::connect;
0040         virtual void connect( GtkWidget* );
0041 
0042         //! disconnect
0043         using FollowMouseData::disconnect;
0044         virtual void disconnect( GtkWidget* );
0045 
0046         //! register child
0047         void registerChild( GtkWidget*, bool = true );
0048 
0049         //!@name modifiers
0050         //@{
0051 
0052         //! enable state
0053         void setEnabled( bool value )
0054         {
0055             FollowMouseData::setEnabled( value );
0056 
0057             _current._timeLine.setEnabled( value );
0058             _previous._timeLine.setEnabled( value );
0059 
0060             if( !value )
0061             {
0062                 _current.clear();
0063                 _previous.clear();
0064             }
0065 
0066         }
0067 
0068         //! duration
0069         void setDuration( int value )
0070         {
0071             _current._timeLine.setDuration( value );
0072             _previous._timeLine.setDuration( value );
0073         }
0074 
0075         //@}
0076 
0077         //!@name accessors
0078         //@{
0079 
0080         //! true if animated
0081         bool isAnimated( void ) const
0082         { return isAnimated( AnimationCurrent ) || isAnimated( AnimationPrevious ); }
0083 
0084         //! true if given animation type is animated
0085         bool isAnimated( const WidgetType& type ) const
0086         { return data( type )._timeLine.isRunning(); }
0087 
0088         //! widget matching type
0089         GtkWidget* widget( const WidgetType& type ) const
0090         { return data( type )._widget; }
0091 
0092         //! rect for given animation type
0093         const GdkRectangle& rectangle( const WidgetType& type ) const
0094         { return data( type )._rect; }
0095 
0096         //! animation data
0097         AnimationData animationData( const WidgetType& type ) const
0098         {
0099             const Data& data( this->data( type ) );
0100             return data._timeLine.isRunning() ?
0101                 AnimationData( data._timeLine.value(), AnimationHover ):
0102                 AnimationData();
0103         }
0104 
0105         //! true when fade out animation is locked (delayed)
0106         bool isLocked( void ) const
0107         { return _timer.isRunning(); }
0108 
0109         //@}
0110 
0111         protected:
0112 
0113         //! disconnect child
0114         void unregisterChild( GtkWidget* );
0115 
0116         //! update state for given widget
0117         bool updateState( GtkWidget*, bool state, bool delayed );
0118 
0119         //! return dirty rect (for update)
0120         GdkRectangle dirtyRect( void );
0121 
0122         //! animations data
0123         class Data
0124         {
0125 
0126             public:
0127 
0128             //! constructor
0129             explicit Data( void ):
0130                 _widget( 0L ),
0131                 _rect( Gtk::gdk_rectangle() )
0132             {}
0133 
0134             //! update data
0135             void copy( const Data& other )
0136             {
0137                 _widget = other._widget;
0138                 _rect = other._rect;
0139             }
0140 
0141             //! update data
0142             void update( GtkWidget* widget, const GdkRectangle& rect )
0143             {
0144                 _widget = widget;
0145                 _rect = rect;
0146             }
0147 
0148             //! true if valid
0149             bool isValid( void ) const
0150             { return _widget && Gtk::gdk_rectangle_is_valid( &_rect ); }
0151 
0152             //! clear
0153             void clear( void )
0154             {
0155                 if( _timeLine.isRunning() ) _timeLine.stop();
0156                 _widget = 0L;
0157                 _rect = Gtk::gdk_rectangle();
0158             }
0159 
0160             //! timeline
0161             TimeLine _timeLine;
0162 
0163             //! widget
0164             GtkWidget* _widget;
0165 
0166             //! rectangle
0167             GdkRectangle _rect;
0168 
0169         };
0170 
0171         //! get data for given animation type
0172         Data& data( const WidgetType& type )
0173         {
0174             switch( type )
0175             {
0176                 default:
0177                 case AnimationCurrent: return _current;
0178                 case AnimationPrevious: return _previous;
0179             }
0180         }
0181 
0182         //! get data for given animation type
0183         const Data& data( const WidgetType& type ) const
0184         {
0185             switch( type )
0186             {
0187                 default:
0188                 case AnimationCurrent: return _current;
0189                 case AnimationPrevious: return _previous;
0190             }
0191         }
0192 
0193         //!@name callbacks
0194         //@{
0195 
0196         //! child is destroyed
0197         static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer );
0198 
0199         //! child entered
0200         static gboolean childEnterNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer);
0201 
0202         //! child left
0203         static gboolean childLeaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer);
0204 
0205         //! mouse leave events
0206         static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer);
0207 
0208         //! update widget for fade-in/fade-out animation
0209         static gboolean delayedUpdate( gpointer );
0210 
0211         //! update widget for follow-mouse animation
0212         static gboolean followMouseUpdate( gpointer );
0213 
0214         //! start delayed fade-out animation
0215         static gboolean delayedAnimate( gpointer );
0216 
0217         //@}
0218 
0219         private:
0220 
0221         //! target
0222         GtkWidget* _target;
0223 
0224         //! signals
0225         Signal _leaveId;
0226 
0227         //!@name animation data
0228         //@{
0229 
0230         //! additional dirty rect
0231         GdkRectangle _dirtyRect;
0232 
0233         //! previous button animation data
0234         Data _previous;
0235 
0236         //! current button animation data
0237         Data _current;
0238 
0239         //@}
0240 
0241         //!@name hover data
0242         /*! need to keep track of enter/leave events in toolbar items */
0243         class HoverData
0244         {
0245 
0246             public:
0247 
0248             //! constructor
0249             explicit HoverData( void )
0250             {}
0251 
0252             //! destructor
0253             virtual ~HoverData( void )
0254             {}
0255 
0256             //! disconnect
0257             virtual void disconnect( void )
0258             {
0259                 _destroyId.disconnect();
0260                 _enterId.disconnect();
0261                 _leaveId.disconnect();
0262             }
0263 
0264             //!@name callback ids
0265             //@{
0266             Signal _destroyId;
0267             Signal _enterId;
0268             Signal _leaveId;
0269             //@}
0270 
0271         };
0272 
0273         typedef std::map<GtkWidget*, HoverData> HoverDataMap;
0274         HoverDataMap _hoverData;
0275 
0276         //! delayed animation timeOut
0277         static const int _timeOut;
0278 
0279         //! timer of delayed animation
0280         Timer _timer;
0281 
0282     };
0283 
0284 }
0285 
0286 #endif