1 #ifndef oxygenwidgetstateengine_h 2 #define oxygenwidgetstateengine_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 24 #include "../oxygenanimationdata.h" 25 #include "../oxygenstyleoptions.h" 26 #include "oxygenanimationengine.h" 27 #include "oxygenbaseengine.h" 28 #include "oxygendatamap.h" 29 #include "oxygenwidgetstatedata.h" 30 31 #include "../config.h" 32 33 #include <gtk/gtk.h> 34 #include <iostream> 35 36 namespace Oxygen 37 { 38 //! forward declaration 39 class Animations; 40 41 //! associates widgets with some type of data 42 class WidgetStateEngine: public BaseEngine, public AnimationEngine 43 { 44 45 public: 46 47 //! constructor WidgetStateEngine(Animations * widget)48 WidgetStateEngine( Animations* widget ): 49 BaseEngine( widget ) 50 {} 51 52 //! destructor ~WidgetStateEngine(void)53 virtual ~WidgetStateEngine( void ) 54 {} 55 56 //! unregister widget unregisterWidget(GtkWidget * widget)57 virtual void unregisterWidget( GtkWidget* widget ) 58 { 59 unregisterWidget( widget, _hoverData ); 60 unregisterWidget( widget, _focusData ); 61 } 62 63 //! enabled state setEnabled(bool value)64 virtual bool setEnabled( bool value ) 65 { 66 67 if( !BaseEngine::setEnabled( value ) ) return false; 68 69 // hover data map 70 for( DataMap<WidgetStateData>::Map::iterator iter = _hoverData.map().begin(); iter != _hoverData.map().end(); iter++ ) 71 { 72 iter->second.setEnabled( value ); 73 if( enabled() && !widgetIsBlackListed( iter->first ) ) iter->second.connect( iter->first ); 74 else iter->second.disconnect( iter->first ); 75 } 76 77 // focus data map 78 for( DataMap<WidgetStateData>::Map::iterator iter = _focusData.map().begin(); iter != _focusData.map().end(); iter++ ) 79 { 80 iter->second.setEnabled( value ); 81 if( enabled() && !widgetIsBlackListed( iter->first ) ) iter->second.connect( iter->first ); 82 else iter->second.disconnect( iter->first ); 83 } 84 85 return true; 86 } 87 88 //! transition duration setDuration(int value)89 virtual bool setDuration( int value ) 90 { 91 92 if( !AnimationEngine::setDuration( value ) ) return false; 93 94 // hover data map 95 for( DataMap<WidgetStateData>::Map::iterator iter = _hoverData.map().begin(); iter != _hoverData.map().end(); iter++ ) 96 { iter->second.setDuration( value ); } 97 98 // focus data map 99 for( DataMap<WidgetStateData>::Map::iterator iter = _focusData.map().begin(); iter != _focusData.map().end(); iter++ ) 100 { iter->second.setDuration( value ); } 101 102 return true; 103 104 } 105 106 //!@name accessors 107 //@{ 108 109 //! true if widget is included contains(GtkWidget * widget,AnimationMode mode)110 virtual bool contains( GtkWidget* widget, AnimationMode mode ) 111 { 112 switch( mode ) 113 { 114 case AnimationHover: return _hoverData.contains( widget ); 115 case AnimationFocus: return _focusData.contains( widget ); 116 default: return false; 117 } 118 } 119 120 //! retrieve animation data matching a given widget for provided options 121 /*! note: for convenience, this method also calls ::registerWidget and ::updateState */ 122 virtual AnimationData get( GtkWidget* widget, const StyleOptions& options, AnimationModes modes = AnimationHover|AnimationFocus, AnimationMode precedence = AnimationHover ) 123 { return get( widget, Gtk::gdk_rectangle(), options, modes, precedence ); } 124 125 //! retrieve animation data matching a given widget for provided options 126 /*! note: for convenience, this method also calls ::registerWidget and ::updateState */ 127 virtual AnimationData get( GtkWidget* widget, const GdkRectangle& rect, const StyleOptions& options, AnimationModes modes = AnimationHover|AnimationFocus, AnimationMode precedence = AnimationHover ) 128 { 129 130 // check widget 131 if( !( enabled() && widget ) ) return AnimationData(); 132 133 // register 134 registerWidget( widget, modes, options ); 135 136 // stores WidgetStateData locally for speedup 137 WidgetStateData* hoverData( (modes&AnimationHover) ? &_hoverData.value( widget ):0L ); 138 WidgetStateData* focusData( (modes&AnimationFocus) ? &_focusData.value( widget ):0L ); 139 140 // update state 141 if( hoverData ) hoverData->updateState( (options&Hover) && !(options&Disabled), rect ); 142 if( focusData ) focusData->updateState( (options&Focus) && !(options&Disabled), rect ); 143 144 // assume hover takes precedence over focus 145 switch( precedence ) 146 { 147 default: 148 case AnimationHover: 149 if( hoverData && hoverData->isAnimated() ) return AnimationData( hoverData->opacity(), AnimationHover ); 150 else if( focusData && focusData->isAnimated() ) return AnimationData( focusData->opacity(), AnimationFocus ); 151 else return AnimationData(); 152 153 case AnimationFocus: 154 if( focusData && focusData->isAnimated() ) return AnimationData( focusData->opacity(), AnimationFocus ); 155 else if( hoverData && hoverData->isAnimated() ) return AnimationData( hoverData->opacity(), AnimationHover ); 156 else return AnimationData(); 157 158 } 159 160 } 161 162 //@} 163 164 protected: 165 166 //! register widget 167 using BaseEngine::registerWidget; 168 virtual bool registerWidget( GtkWidget*, AnimationModes, const StyleOptions& = StyleOptions() ); 169 170 //! register widget in given map 171 bool registerWidget( GtkWidget*, DataMap<WidgetStateData>&, const bool& = false ) const; 172 173 //! register widget in given map unregisterWidget(GtkWidget * widget,DataMap<WidgetStateData> & data)174 void unregisterWidget( GtkWidget* widget, DataMap<WidgetStateData>& data ) const 175 { 176 if( !data.contains( widget ) ) return; 177 data.value( widget ).disconnect( widget ); 178 data.erase( widget ); 179 } 180 181 private: 182 183 //!@name maps 184 //@{ 185 DataMap<WidgetStateData> _hoverData; 186 DataMap<WidgetStateData> _focusData; 187 //@} 188 189 }; 190 191 } 192 193 #endif 194