1 #ifndef oxygentoolbarstatedata_h 2 #define oxygentoolbarstatedata_h 3 /* 4 * this file is part of the oxygen gtk engine 5 * Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or(at your option ) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 20 * MA 02110-1301, USA. 21 */ 22 23 #include "../oxygenanimationdata.h" 24 #include "../oxygenanimationmodes.h" 25 #include "../oxygengtkutils.h" 26 #include "oxygenfollowmousedata.h" 27 #include "oxygensignal.h" 28 #include "oxygentimeline.h" 29 #include "oxygentimer.h" 30 31 #include <map> 32 #include <gtk/gtk.h> 33 34 namespace Oxygen 35 { 36 class ToolBarStateData: public FollowMouseData 37 { 38 39 public: 40 41 //! constructor ToolBarStateData(void)42 ToolBarStateData( void ): 43 _target( 0L ), 44 _dirtyRect( Gtk::gdk_rectangle() ) 45 {} 46 47 //! destructor ~ToolBarStateData(void)48 virtual ~ToolBarStateData( void ) 49 { disconnect( _target ); } 50 51 //! setup connections 52 using FollowMouseData::connect; 53 virtual void connect( GtkWidget* ); 54 55 //! disconnect 56 using FollowMouseData::disconnect; 57 virtual void disconnect( GtkWidget* ); 58 59 //! register child 60 void registerChild( GtkWidget*, bool = true ); 61 62 //!@name modifiers 63 //@{ 64 65 //! enable state setEnabled(bool value)66 void setEnabled( bool value ) 67 { 68 FollowMouseData::setEnabled( value ); 69 70 _current._timeLine.setEnabled( value ); 71 _previous._timeLine.setEnabled( value ); 72 73 if( !value ) 74 { 75 _current.clear(); 76 _previous.clear(); 77 } 78 79 } 80 81 //! duration setDuration(int value)82 void setDuration( int value ) 83 { 84 _current._timeLine.setDuration( value ); 85 _previous._timeLine.setDuration( value ); 86 } 87 88 //@} 89 90 //!@name accessors 91 //@{ 92 93 //! true if animated isAnimated(void)94 bool isAnimated( void ) const 95 { return isAnimated( AnimationCurrent ) || isAnimated( AnimationPrevious ); } 96 97 //! true if given animation type is animated isAnimated(const WidgetType & type)98 bool isAnimated( const WidgetType& type ) const 99 { return data( type )._timeLine.isRunning(); } 100 101 //! widget matching type widget(const WidgetType & type)102 GtkWidget* widget( const WidgetType& type ) const 103 { return data( type )._widget; } 104 105 //! rect for given animation type rectangle(const WidgetType & type)106 const GdkRectangle& rectangle( const WidgetType& type ) const 107 { return data( type )._rect; } 108 109 //! animation data animationData(const WidgetType & type)110 AnimationData animationData( const WidgetType& type ) const 111 { 112 const Data& data( this->data( type ) ); 113 return data._timeLine.isRunning() ? 114 AnimationData( data._timeLine.value(), AnimationHover ): 115 AnimationData(); 116 } 117 118 //! true when fade out animation is locked (delayed) isLocked(void)119 bool isLocked( void ) const 120 { return _timer.isRunning(); } 121 122 //@} 123 124 protected: 125 126 //! disconnect child 127 void unregisterChild( GtkWidget* ); 128 129 //! update state for given widget 130 bool updateState( GtkWidget*, bool state, bool delayed ); 131 132 //! return dirty rect (for update) 133 GdkRectangle dirtyRect( void ); 134 135 //! animations data 136 class Data 137 { 138 139 public: 140 141 //! constructor Data(void)142 explicit Data( void ): 143 _widget( 0L ), 144 _rect( Gtk::gdk_rectangle() ) 145 {} 146 147 //! update data copy(const Data & other)148 void copy( const Data& other ) 149 { 150 _widget = other._widget; 151 _rect = other._rect; 152 } 153 154 //! update data update(GtkWidget * widget,const GdkRectangle & rect)155 void update( GtkWidget* widget, const GdkRectangle& rect ) 156 { 157 _widget = widget; 158 _rect = rect; 159 } 160 161 //! true if valid isValid(void)162 bool isValid( void ) const 163 { return _widget && Gtk::gdk_rectangle_is_valid( &_rect ); } 164 165 //! clear clear(void)166 void clear( void ) 167 { 168 if( _timeLine.isRunning() ) _timeLine.stop(); 169 _widget = 0L; 170 _rect = Gtk::gdk_rectangle(); 171 } 172 173 //! timeline 174 TimeLine _timeLine; 175 176 //! widget 177 GtkWidget* _widget; 178 179 //! rectangle 180 GdkRectangle _rect; 181 182 }; 183 184 //! get data for given animation type data(const WidgetType & type)185 Data& data( const WidgetType& type ) 186 { 187 switch( type ) 188 { 189 default: 190 case AnimationCurrent: return _current; 191 case AnimationPrevious: return _previous; 192 } 193 } 194 195 //! get data for given animation type data(const WidgetType & type)196 const Data& data( const WidgetType& type ) const 197 { 198 switch( type ) 199 { 200 default: 201 case AnimationCurrent: return _current; 202 case AnimationPrevious: return _previous; 203 } 204 } 205 206 //!@name callbacks 207 //@{ 208 209 //! child is destroyed 210 static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer ); 211 212 //! child entered 213 static gboolean childEnterNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer); 214 215 //! child left 216 static gboolean childLeaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer); 217 218 //! mouse leave events 219 static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer); 220 221 //! update widget for fade-in/fade-out animation 222 static gboolean delayedUpdate( gpointer ); 223 224 //! update widget for follow-mouse animation 225 static gboolean followMouseUpdate( gpointer ); 226 227 //! start delayed fade-out animation 228 static gboolean delayedAnimate( gpointer ); 229 230 //@} 231 232 private: 233 234 //! target 235 GtkWidget* _target; 236 237 //! signals 238 Signal _leaveId; 239 240 //!@name animation data 241 //@{ 242 243 //! additional dirty rect 244 GdkRectangle _dirtyRect; 245 246 //! previous button animation data 247 Data _previous; 248 249 //! current button animation data 250 Data _current; 251 252 //@} 253 254 //!@name hover data 255 /*! need to keep track of enter/leave events in toolbar items */ 256 class HoverData 257 { 258 259 public: 260 261 //! constructor HoverData(void)262 explicit HoverData( void ) 263 {} 264 265 //! destructor ~HoverData(void)266 virtual ~HoverData( void ) 267 {} 268 269 //! disconnect disconnect(void)270 virtual void disconnect( void ) 271 { 272 _destroyId.disconnect(); 273 _enterId.disconnect(); 274 _leaveId.disconnect(); 275 } 276 277 //!@name callback ids 278 //@{ 279 Signal _destroyId; 280 Signal _enterId; 281 Signal _leaveId; 282 //@} 283 284 }; 285 286 typedef std::map<GtkWidget*, HoverData> HoverDataMap; 287 HoverDataMap _hoverData; 288 289 //! delayed animation timeOut 290 static const int _timeOut; 291 292 //! timer of delayed animation 293 Timer _timer; 294 295 }; 296 297 } 298 299 #endif 300