1 #ifndef oxygenmenubarstatedata_h 2 #define oxygenmenubarstatedata_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 * Copyright (c) 2010 Ruslan Kabatsayev <b7.10110111@gmail.com> 7 * 8 * MenuBarState prelight effect is based on 9 * Redmond95 - a cairo based GTK+ engine 10 * Copyright (C) 2001 Red Hat, Inc. <@redhat.com> 11 * Copyright (C) 2006 Andrew Johnson <acjgenius@earthlink.net> 12 * Copyright (C) 2006-2007 Benjamin Berg <benjamin@sipsolutions.net> 13 * 14 * This library is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU Lesser General Public 16 * License as published by the Free Software Foundation; either 17 * version 2 of the License, or(at your option ) any later version. 18 * 19 * This library is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * Lesser General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public 25 * License along with this library; if not, write to the Free 26 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 27 * MA 02110-1301, USA. 28 */ 29 30 #include "../oxygenanimationdata.h" 31 #include "../oxygenanimationmodes.h" 32 #include "../oxygengtkutils.h" 33 #include "oxygenfollowmousedata.h" 34 #include "oxygensignal.h" 35 #include "oxygentimeline.h" 36 37 #include <gtk/gtk.h> 38 39 #include <map> 40 41 namespace Oxygen 42 { 43 class MenuBarStateData: public FollowMouseData 44 { 45 46 public: 47 48 //! constructor MenuBarStateData(void)49 MenuBarStateData( void ): 50 _target( 0L ), 51 _animationsEnabled( true ), 52 _dirtyRect( Gtk::gdk_rectangle() ) 53 {} 54 55 //! destructor ~MenuBarStateData(void)56 virtual ~MenuBarStateData( void ) 57 { disconnect( _target ); } 58 59 //! setup connections 60 using FollowMouseData::connect; 61 virtual void connect( GtkWidget* ); 62 63 //! disconnect 64 using FollowMouseData::disconnect; 65 virtual void disconnect( GtkWidget* ); 66 67 //! enable state setAnimationsEnabled(bool value)68 void setAnimationsEnabled( bool value ) 69 { 70 71 // base class 72 FollowMouseData::setEnabled( value ); 73 74 _animationsEnabled = value; 75 _current._timeLine.setEnabled( value ); 76 _previous._timeLine.setEnabled( value ); 77 78 if( !value ) 79 { 80 _current.clear(); 81 _previous.clear(); 82 } 83 84 } 85 86 //! duration setDuration(int value)87 void setDuration( int value ) 88 { 89 _current._timeLine.setDuration( value ); 90 _previous._timeLine.setDuration( value ); 91 } 92 93 //!@name accessors 94 //@{ 95 96 //! true if animated isAnimated(void)97 bool isAnimated( void ) const 98 { return isAnimated( AnimationCurrent ) || isAnimated( AnimationPrevious ); } 99 100 //! true if given animation type is animated isAnimated(const WidgetType & type)101 bool isAnimated( const WidgetType& type ) const 102 { return data( type )._timeLine.isRunning(); } 103 104 //! widget for current animation type widget(const WidgetType & type)105 GtkWidget* widget( const WidgetType& type ) const 106 { return data( type )._widget; } 107 108 //! rect for given animation type rectangle(const WidgetType & type)109 const GdkRectangle& rectangle( const WidgetType& type ) const 110 { return data( type )._rect; } 111 112 //! animation data animationData(const WidgetType & type)113 AnimationData animationData( const WidgetType& type ) const 114 { 115 const Data& data( this->data( type ) ); 116 return data._timeLine.isRunning() ? 117 AnimationData( data._timeLine.value(), AnimationHover ): 118 AnimationData(); 119 } 120 121 //@} 122 123 protected: 124 125 //! register child 126 void registerChild( GtkWidget* ); 127 128 //! disconnect child 129 void unregisterChild( GtkWidget* ); 130 131 //! update items 132 void updateItems( GdkEventType ); 133 134 //! update state for given widget 135 bool updateState( GtkWidget*, const GdkRectangle&, bool ); 136 137 //! true if menu item is active (pressed down) 138 bool menuItemIsActive( GtkWidget* ) const; 139 140 //! return dirty rect (for update) 141 GdkRectangle dirtyRect( void ); 142 143 //@} 144 145 //! animations data 146 class Data 147 { 148 149 public: 150 151 //! constructor Data(void)152 explicit Data( void ): 153 _widget( 0L ), 154 _rect( Gtk::gdk_rectangle() ) 155 {} 156 157 //! update data copy(const Data & other)158 void copy( const Data& other ) 159 { 160 _widget = other._widget; 161 _rect = other._rect; 162 } 163 164 //! update data update(GtkWidget * widget,const GdkRectangle & rect)165 void update( GtkWidget* widget, const GdkRectangle& rect ) 166 { 167 _widget = widget; 168 _rect = rect; 169 } 170 171 //! true if valid isValid(void)172 bool isValid( void ) const 173 { return _widget && Gtk::gdk_rectangle_is_valid( &_rect ); } 174 175 //! clear clear(void)176 void clear( void ) 177 { 178 if( _timeLine.isRunning() ) _timeLine.stop(); 179 _widget = 0L; 180 _rect = Gtk::gdk_rectangle(); 181 } 182 183 //! timeline 184 TimeLine _timeLine; 185 186 //! widget 187 GtkWidget* _widget; 188 189 //! rectangle 190 GdkRectangle _rect; 191 192 }; 193 194 //! get data for given animation type data(const WidgetType & type)195 Data& data( const WidgetType& type ) 196 { 197 switch( type ) 198 { 199 default: 200 case AnimationCurrent: return _current; 201 case AnimationPrevious: return _previous; 202 } 203 } 204 205 //! get data for given animation type data(const WidgetType & type)206 const Data& data( const WidgetType& type ) const 207 { 208 switch( type ) 209 { 210 default: 211 case AnimationCurrent: return _current; 212 case AnimationPrevious: return _previous; 213 } 214 } 215 216 //!@name callbacks 217 //@{ 218 219 //! child is destroyed 220 static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer ); 221 222 //! mouse motion events 223 static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer); 224 225 //! mouse leave events 226 static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer); 227 228 //! update widget for fade-in/fade-out animation 229 static gboolean delayedUpdate( gpointer ); 230 231 //! update widget for follow-mouse animation 232 static gboolean followMouseUpdate( gpointer ); 233 234 //@} 235 236 private: 237 238 //! target 239 GtkWidget* _target; 240 241 //!@name signals 242 //@{ 243 Signal _motionId; 244 Signal _leaveId; 245 //@} 246 247 //!@name animation data 248 //@{ 249 250 //! true if menubar item mouse-over is animated 251 bool _animationsEnabled; 252 253 //! additional dirty rect 254 GdkRectangle _dirtyRect; 255 256 Data _previous; 257 Data _current; 258 259 //@} 260 261 //! map children to destroy signal 262 typedef std::map<GtkWidget*, Signal> ChildrenMap; 263 ChildrenMap _children; 264 265 }; 266 267 } 268 269 #endif 270