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