File indexing completed on 2024-05-19 16:37:39
0001 #ifndef oxygendatamap_h 0002 #define oxygendatamap_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 * 0007 * SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include <cassert> 0011 #include <map> 0012 #include <gtk/gtk.h> 0013 0014 namespace Oxygen 0015 { 0016 0017 //! generic class to map data to widgets 0018 /* 0019 Note: I'm not sure about memory management. At some point one might need to allocate the registered 0020 data on the heap rather than on the stack, to be able to safely pass the data pointer around via callbacks. 0021 The current implementation should make that possible without external code change, provided that the map 0022 content is properly deleted (as opposed to erased) in destructor and 'unregister' method. 0023 */ 0024 template <typename T> 0025 class DataMap 0026 { 0027 0028 public: 0029 0030 //! constructor 0031 DataMap( void ): 0032 _lastWidget( 0L ), 0033 _lastData( 0L ) 0034 {} 0035 0036 virtual ~DataMap(){} 0037 0038 //! insert new widget 0039 inline T& registerWidget( GtkWidget* widget ) 0040 { 0041 T& data( _map.insert( std::make_pair( widget, T() ) ).first->second ); 0042 _lastWidget = widget; 0043 _lastData = &data; 0044 return data; 0045 } 0046 0047 //! true if widget is in list 0048 virtual bool contains( GtkWidget* widget ) 0049 { 0050 0051 // check against last widget 0052 if( widget == _lastWidget ) return true; 0053 0054 // find in map, returns false if not found 0055 typename Map::iterator iter = _map.find( widget ); 0056 if( iter == _map.end() ) return false; 0057 0058 // store as last widget/last data, to speed up lookup. 0059 _lastWidget = widget; 0060 _lastData = &iter->second; 0061 return true; 0062 0063 } 0064 0065 //! return value 0066 virtual T& value( GtkWidget* widget ) 0067 { 0068 0069 // check against last widget 0070 if( widget == _lastWidget ) return *_lastData; 0071 0072 // find in map, abort if not found 0073 typename Map::iterator iter( _map.find( widget ) ); 0074 assert( iter != _map.end() ); 0075 0076 // store as last widget/last data, to speed up lookup. 0077 _lastWidget = widget; 0078 _lastData = &iter->second; 0079 return iter->second; 0080 0081 } 0082 0083 //! erase 0084 virtual void erase( GtkWidget* widget ) 0085 { 0086 0087 // clear last widget and data, if match 0088 if( _lastWidget == widget ) 0089 { 0090 _lastWidget = 0L; 0091 _lastData = 0L; 0092 } 0093 0094 // erase from map 0095 _map.erase( widget ); 0096 0097 } 0098 0099 //! connect all widgets in map 0100 void connectAll( void ) 0101 { 0102 for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ ) 0103 { iter->second.connect( iter->first ); } 0104 } 0105 0106 0107 //! connect all widgets in map 0108 void disconnectAll( void ) 0109 { 0110 for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ ) 0111 { iter->second.disconnect( iter->first ); } 0112 } 0113 0114 //! erase 0115 virtual void clear( void ) 0116 { 0117 0118 _lastWidget = 0L; 0119 _lastData = 0L; 0120 _map.clear(); 0121 0122 } 0123 0124 //! retrieve internal map 0125 typedef std::map<GtkWidget*, T> Map; 0126 Map& map( void ) 0127 { return _map; } 0128 0129 //! retrieve internal map 0130 const Map& map( void ) const 0131 { return _map; } 0132 0133 protected: 0134 0135 //! copy constructor is private 0136 DataMap( const DataMap& ) 0137 { assert( false ); } 0138 0139 //! assignment operator 0140 DataMap& operator = ( const DataMap& ) 0141 { 0142 assert( false ); 0143 return *this; 0144 } 0145 0146 private: 0147 0148 //! pointer to last inquired widget 0149 GtkWidget* _lastWidget; 0150 0151 //! pointer to last retrieved data 0152 T* _lastData; 0153 0154 //! internal map between widget and data 0155 Map _map; 0156 0157 }; 0158 0159 } 0160 0161 #endif