diff options
Diffstat (limited to 'tdegtk/tdegtk-widgetlookup.cpp')
-rw-r--r-- | tdegtk/tdegtk-widgetlookup.cpp | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/tdegtk/tdegtk-widgetlookup.cpp b/tdegtk/tdegtk-widgetlookup.cpp new file mode 100644 index 0000000..79ed0e9 --- /dev/null +++ b/tdegtk/tdegtk-widgetlookup.cpp @@ -0,0 +1,231 @@ +/* +* this file was largely taken from the oxygen gtk engine +* Copyright (c) 2010 Hugo Pereira Da Costa <[email protected]> +* Copyright (c) 2010 Ruslan Kabatsayev <[email protected]> +* +* Hook-setup code provided by Ruslan +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or( at your option ) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free +* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#include "tdegtk-widgetlookup.h" +#include "config.h" + +#include <iostream> +#include <cairo/cairo-gobject.h> + +// #define TDEGTK_DEBUG 1 + + //__________________________________________________________________ + WidgetLookup::WidgetLookup( void ): + _hooksInitialized( false ), + _context( 0L ) + {} + + + //_____________________________________________________ + WidgetLookup::~WidgetLookup( void ) + { + + // disconnect hooks + _drawHook.disconnect(); + + } + + //_____________________________________________________ + void WidgetLookup::initializeHooks( void ) + { + + #if TDEGTK_DEBUG + std::cerr << "Oxygen::WidgetLookup::initializeHooks" << std::endl; + #endif + + if( _hooksInitialized ) return; + + // install hook and test + if( !_drawHook.connect( "draw", (GSignalEmissionHook)drawHook, this ) ) return; + + // set initialization flag + _hooksInitialized = true; + + return; + + } + + //_____________________________________________________ + GtkWidget* WidgetLookup::find( cairo_t* context, const GtkWidgetPath* path ) const + { + + // check path + if( !path ) return 0L; + + // get length and check + const gint length( gtk_widget_path_length( path ) ); + if( length < 1 ) return 0L; + + // lookup last type + return find( context, gtk_widget_path_iter_get_object_type( path, length-1 ) ); + + } + + //_____________________________________________________ + GtkWidget* WidgetLookup::find( cairo_t* context, GType type ) const + { + // check context + if( context != _context ) + { + #if TDEGTK_DEBUG + std::cerr << "Oxygen::WidgetLookup::find - invalid context: " << context << std::endl; + #endif + return 0L; + } + + #if TDEGTK_DEBUG + std::cerr + << "Oxygen::WidgetLookup::find -" + << " context: " << context + << " type: " << g_type_name( type ) + << std::endl; + #endif + + // look for type in stored widgets + /* we loop backward, since last added widgets are more likely to be looked up */ + for( WidgetList::const_reverse_iterator iter = _widgets.rbegin(); iter != _widgets.rend(); ++iter ) + { + // compare types and return if matched + if( G_OBJECT_TYPE( *iter ) == type ) + { + #if TDEGTK_DEBUG + std::cerr + << "Oxygen::WidgetLookup::find -" + << " context: " << context + << " type: " << g_type_name( type ) + << " found: " << *iter + << std::endl; + #endif + return *iter; + } + } + + #if TDEGTK_DEBUG + std::cerr + << "Oxygen::WidgetLookup::find -" + << " context: " << context + << " type: " << g_type_name( type ) + << " - no match found" + << std::endl; + #endif + + return 0L; + + } + + //_____________________________________________________ + void WidgetLookup::bind( GtkWidget* widget, cairo_t* context ) + { + // check if context has changed and clear widgets if yes + if( context != _context ) + { + + #if TDEGTK_DEBUG + std::cerr + << "Oxygen::WidgetLookup::bind -" + << " context: " << _context + << " widgets: " << _widgets.size() + << std::endl; + #endif + + _context = context; + _widgets.clear(); + } + + _widgets.push_back( widget ); + + // add to all widgets map + if( _allWidgets.find( widget ) == _allWidgets.end() ) + { + Signal destroyId; + destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( destroyNotifyEvent ), this ); + _allWidgets.insert( std::make_pair( widget, destroyId ) ); + } + + } + + //____________________________________________________________________________________________ + void WidgetLookup::unregisterWidget( GtkWidget* widget ) + { + + #if TDEGTK_DEBUG + std::cerr << "Oxygen::WidgetLookup::unregisterWidget - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl; + #endif + + // find in map + WidgetMap::iterator iter( _allWidgets.find( widget ) ); + assert( iter != _allWidgets.end() ); + + // disconnect signal + iter->second.disconnect(); + + // erase from lists + _allWidgets.erase( widget ); + _widgets.remove( widget ); + + } + + //_____________________________________________________ + gboolean WidgetLookup::drawHook( GSignalInvocationHint*, guint numParams, const GValue* params, gpointer data ) + { + + // check number of parameters + if( numParams < 2 ) return FALSE; + + // get widget from params + GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) ); + + // check type + if( !GTK_IS_WIDGET( widget ) ) return FALSE; + + // check second parameter type. + if( !G_VALUE_HOLDS( params+1, CAIRO_GOBJECT_TYPE_CONTEXT ) ) + { return FALSE; } + + // retrieve context and cast + cairo_t* context( static_cast<cairo_t*>( g_value_get_boxed(params+1) ) ); + + #if TDEGTK_DEBUG + std::cerr + << "Oxygen::WidgetLookup::drawHook -" + << " widget: " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" + << " context: " << context + << std::endl; + #endif + + // bind widget and context + static_cast<WidgetLookup*>( data )->bind( widget, context ); + + return TRUE; + + } + + + //____________________________________________________________________________________________ + gboolean WidgetLookup::destroyNotifyEvent( GtkWidget* widget, gpointer data ) + { + static_cast<WidgetLookup*>(data)->unregisterWidget( widget ); + return FALSE; + } + + |