You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
6.8 KiB
232 lines
6.8 KiB
12 years ago
|
/*
|
||
|
* this file was largely taken from the oxygen gtk engine
|
||
|
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||
|
* Copyright (c) 2010 Ruslan Kabatsayev <b7.10110111@gmail.com>
|
||
|
*
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
|