File indexing completed on 2024-05-12 17:05:48
0001 #ifndef oxygenmenubarstatedata_h 0002 #define oxygenmenubarstatedata_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 * SPDX-FileCopyrightText: 2010 Ruslan Kabatsayev <b7.10110111@gmail.com> 0007 * 0008 * MenuBarState prelight effect is based on 0009 * Redmond95 - a cairo based GTK+ engine 0010 * SPDX-FileCopyrightText: 2001 Red Hat Inc. <@redhat.com> 0011 * SPDX-FileCopyrightText: 2006 Andrew Johnson <acjgenius@earthlink.net> 0012 * SPDX-FileCopyrightText: 2006-2007 Benjamin Berg <benjamin@sipsolutions.net> 0013 * 0014 * SPDX-License-Identifier: LGPL-2.0-or-later 0015 */ 0016 0017 #include "../oxygenanimationdata.h" 0018 #include "../oxygenanimationmodes.h" 0019 #include "../oxygengtkutils.h" 0020 #include "oxygenfollowmousedata.h" 0021 #include "oxygensignal.h" 0022 #include "oxygentimeline.h" 0023 0024 #include <gtk/gtk.h> 0025 0026 #include <map> 0027 0028 namespace Oxygen 0029 { 0030 class MenuBarStateData: public FollowMouseData 0031 { 0032 0033 public: 0034 0035 //! constructor 0036 MenuBarStateData( void ): 0037 _target( 0L ), 0038 _animationsEnabled( true ), 0039 _dirtyRect( Gtk::gdk_rectangle() ) 0040 {} 0041 0042 //! destructor 0043 virtual ~MenuBarStateData( void ) 0044 { disconnect( _target ); } 0045 0046 //! setup connections 0047 using FollowMouseData::connect; 0048 virtual void connect( GtkWidget* ); 0049 0050 //! disconnect 0051 using FollowMouseData::disconnect; 0052 virtual void disconnect( GtkWidget* ); 0053 0054 //! enable state 0055 void setAnimationsEnabled( bool value ) 0056 { 0057 0058 // base class 0059 FollowMouseData::setEnabled( value ); 0060 0061 _animationsEnabled = value; 0062 _current._timeLine.setEnabled( value ); 0063 _previous._timeLine.setEnabled( value ); 0064 0065 if( !value ) 0066 { 0067 _current.clear(); 0068 _previous.clear(); 0069 } 0070 0071 } 0072 0073 //! duration 0074 void setDuration( int value ) 0075 { 0076 _current._timeLine.setDuration( value ); 0077 _previous._timeLine.setDuration( value ); 0078 } 0079 0080 //!@name accessors 0081 //@{ 0082 0083 //! true if animated 0084 bool isAnimated( void ) const 0085 { return isAnimated( AnimationCurrent ) || isAnimated( AnimationPrevious ); } 0086 0087 //! true if given animation type is animated 0088 bool isAnimated( const WidgetType& type ) const 0089 { return data( type )._timeLine.isRunning(); } 0090 0091 //! widget for current animation type 0092 GtkWidget* widget( const WidgetType& type ) const 0093 { return data( type )._widget; } 0094 0095 //! rect for given animation type 0096 const GdkRectangle& rectangle( const WidgetType& type ) const 0097 { return data( type )._rect; } 0098 0099 //! animation data 0100 AnimationData animationData( const WidgetType& type ) const 0101 { 0102 const Data& data( this->data( type ) ); 0103 return data._timeLine.isRunning() ? 0104 AnimationData( data._timeLine.value(), AnimationHover ): 0105 AnimationData(); 0106 } 0107 0108 //@} 0109 0110 protected: 0111 0112 //! register child 0113 void registerChild( GtkWidget* ); 0114 0115 //! disconnect child 0116 void unregisterChild( GtkWidget* ); 0117 0118 //! update items 0119 void updateItems( GdkEventType ); 0120 0121 //! update state for given widget 0122 bool updateState( GtkWidget*, const GdkRectangle&, bool ); 0123 0124 //! true if menu item is active (pressed down) 0125 bool menuItemIsActive( GtkWidget* ) const; 0126 0127 //! return dirty rect (for update) 0128 GdkRectangle dirtyRect( void ); 0129 0130 //@} 0131 0132 //! animations data 0133 class Data 0134 { 0135 0136 public: 0137 0138 //! constructor 0139 explicit Data( void ): 0140 _widget( 0L ), 0141 _rect( Gtk::gdk_rectangle() ) 0142 {} 0143 0144 //! update data 0145 void copy( const Data& other ) 0146 { 0147 _widget = other._widget; 0148 _rect = other._rect; 0149 } 0150 0151 //! update data 0152 void update( GtkWidget* widget, const GdkRectangle& rect ) 0153 { 0154 _widget = widget; 0155 _rect = rect; 0156 } 0157 0158 //! true if valid 0159 bool isValid( void ) const 0160 { return _widget && Gtk::gdk_rectangle_is_valid( &_rect ); } 0161 0162 //! clear 0163 void clear( void ) 0164 { 0165 if( _timeLine.isRunning() ) _timeLine.stop(); 0166 _widget = 0L; 0167 _rect = Gtk::gdk_rectangle(); 0168 } 0169 0170 //! timeline 0171 TimeLine _timeLine; 0172 0173 //! widget 0174 GtkWidget* _widget; 0175 0176 //! rectangle 0177 GdkRectangle _rect; 0178 0179 }; 0180 0181 //! get data for given animation type 0182 Data& data( const WidgetType& type ) 0183 { 0184 switch( type ) 0185 { 0186 default: 0187 case AnimationCurrent: return _current; 0188 case AnimationPrevious: return _previous; 0189 } 0190 } 0191 0192 //! get data for given animation type 0193 const Data& data( const WidgetType& type ) const 0194 { 0195 switch( type ) 0196 { 0197 default: 0198 case AnimationCurrent: return _current; 0199 case AnimationPrevious: return _previous; 0200 } 0201 } 0202 0203 //!@name callbacks 0204 //@{ 0205 0206 //! child is destroyed 0207 static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer ); 0208 0209 //! mouse motion events 0210 static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer); 0211 0212 //! mouse leave events 0213 static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer); 0214 0215 //! update widget for fade-in/fade-out animation 0216 static gboolean delayedUpdate( gpointer ); 0217 0218 //! update widget for follow-mouse animation 0219 static gboolean followMouseUpdate( gpointer ); 0220 0221 //@} 0222 0223 private: 0224 0225 //! target 0226 GtkWidget* _target; 0227 0228 //!@name signals 0229 //@{ 0230 Signal _motionId; 0231 Signal _leaveId; 0232 //@} 0233 0234 //!@name animation data 0235 //@{ 0236 0237 //! true if menubar item mouse-over is animated 0238 bool _animationsEnabled; 0239 0240 //! additional dirty rect 0241 GdkRectangle _dirtyRect; 0242 0243 Data _previous; 0244 Data _current; 0245 0246 //@} 0247 0248 //! map children to destroy signal 0249 typedef std::map<GtkWidget*, Signal> ChildrenMap; 0250 ChildrenMap _children; 0251 0252 }; 0253 0254 } 0255 0256 #endif