1 #ifndef oxygendatamap_h 2 #define oxygendatamap_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 <cassert> 24 #include <map> 25 #include <gtk/gtk.h> 26 27 namespace Oxygen 28 { 29 30 //! generic class to map data to widgets 31 /* 32 Note: I'm not sure about memory management. At some point one might need to allocate the registered 33 data on the heap rather than on the stack, to be able to safely pass the data pointer around via callbacks. 34 The current implementation should make that possible without external code change, provided that the map 35 content is properly deleted (as opposed to erased) in destructor and 'unregister' method. 36 */ 37 template <typename T> 38 class DataMap 39 { 40 41 public: 42 43 //! constructor DataMap(void)44 DataMap( void ): 45 _lastWidget( 0L ), 46 _lastData( 0L ) 47 {} 48 ~DataMap()49 virtual ~DataMap(){} 50 51 //! insert new widget registerWidget(GtkWidget * widget)52 inline T& registerWidget( GtkWidget* widget ) 53 { 54 T& data( _map.insert( std::make_pair( widget, T() ) ).first->second ); 55 _lastWidget = widget; 56 _lastData = &data; 57 return data; 58 } 59 60 //! true if widget is in list contains(GtkWidget * widget)61 virtual bool contains( GtkWidget* widget ) 62 { 63 64 // check against last widget 65 if( widget == _lastWidget ) return true; 66 67 // find in map, returns false if not found 68 typename Map::iterator iter = _map.find( widget ); 69 if( iter == _map.end() ) return false; 70 71 // store as last widget/last data, to speed up lookup. 72 _lastWidget = widget; 73 _lastData = &iter->second; 74 return true; 75 76 } 77 78 //! return value value(GtkWidget * widget)79 virtual T& value( GtkWidget* widget ) 80 { 81 82 // check against last widget 83 if( widget == _lastWidget ) return *_lastData; 84 85 // find in map, abort if not found 86 typename Map::iterator iter( _map.find( widget ) ); 87 assert( iter != _map.end() ); 88 89 // store as last widget/last data, to speed up lookup. 90 _lastWidget = widget; 91 _lastData = &iter->second; 92 return iter->second; 93 94 } 95 96 //! erase erase(GtkWidget * widget)97 virtual void erase( GtkWidget* widget ) 98 { 99 100 // clear last widget and data, if match 101 if( _lastWidget == widget ) 102 { 103 _lastWidget = 0L; 104 _lastData = 0L; 105 } 106 107 // erase from map 108 _map.erase( widget ); 109 110 } 111 112 //! connect all widgets in map connectAll(void)113 void connectAll( void ) 114 { 115 for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ ) 116 { iter->second.connect( iter->first ); } 117 } 118 119 120 //! connect all widgets in map disconnectAll(void)121 void disconnectAll( void ) 122 { 123 for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ ) 124 { iter->second.disconnect( iter->first ); } 125 } 126 127 //! erase clear(void)128 virtual void clear( void ) 129 { 130 131 _lastWidget = 0L; 132 _lastData = 0L; 133 _map.clear(); 134 135 } 136 137 //! retrieve internal map 138 typedef std::map<GtkWidget*, T> Map; map(void)139 Map& map( void ) 140 { return _map; } 141 142 //! retrieve internal map map(void)143 const Map& map( void ) const 144 { return _map; } 145 146 protected: 147 148 //! copy constructor is private DataMap(const DataMap &)149 DataMap( const DataMap& ) 150 { assert( false ); } 151 152 //! assignment operator 153 DataMap& operator = ( const DataMap& ) 154 { 155 assert( false ); 156 return *this; 157 } 158 159 private: 160 161 //! pointer to last inquired widget 162 GtkWidget* _lastWidget; 163 164 //! pointer to last retrieved data 165 T* _lastData; 166 167 //! internal map between widget and data 168 Map _map; 169 170 }; 171 172 } 173 174 #endif 175