parent
0bf8ed2645
commit
a66a6bbf0a
@ -0,0 +1,436 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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-animations.h"
|
||||
#include "tdegtk-utils.h"
|
||||
#include "../config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
//_________________________________________
|
||||
Animations::Animations( void ):
|
||||
_innerShadowsEnabled( true ),
|
||||
_hooksInitialized( false )
|
||||
{
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr << "Oxygen::Animations::Animations" << std::endl;
|
||||
#endif
|
||||
|
||||
// create engines
|
||||
#if 0
|
||||
registerEngine( _backgroundHintEngine = new BackgroundHintEngine( this ) );
|
||||
registerEngine( _comboBoxEngine = new ComboBoxEngine( this ) );
|
||||
registerEngine( _comboBoxEntryEngine = new ComboBoxEntryEngine( this ) );
|
||||
registerEngine( _dialogEngine = new DialogEngine( this ) );
|
||||
registerEngine( _groupBoxEngine = new GroupBoxEngine( this ) );
|
||||
registerEngine( _groupBoxLabelEngine = new GroupBoxLabelEngine( this ) );
|
||||
registerEngine( _hoverEngine = new HoverEngine( this ) );
|
||||
registerEngine( _mainWindowEngine = new MainWindowEngine( this ) );
|
||||
registerEngine( _menuItemEngine = new MenuItemEngine( this ) );
|
||||
registerEngine( _panedEngine = new PanedEngine( this ) );
|
||||
registerEngine( _scrollBarEngine = new ScrollBarEngine( this ) );
|
||||
registerEngine( _scrolledWindowEngine = new ScrolledWindowEngine( this ) );
|
||||
registerEngine( _innerShadowEngine = new InnerShadowEngine( this ) );
|
||||
#endif
|
||||
registerEngine( _tabWidgetEngine = new TabWidgetEngine( this ) );
|
||||
#if 0
|
||||
registerEngine( _treeViewEngine = new TreeViewEngine( this ) );
|
||||
registerEngine( _widgetSizeEngine = new WidgetSizeEngine( this ) );
|
||||
|
||||
// animations specific engines
|
||||
registerEngine( _widgetStateEngine = new WidgetStateEngine( this ) );
|
||||
registerEngine( _arrowStateEngine = new ArrowStateEngine( this ) );
|
||||
registerEngine( _scrollBarStateEngine = new ScrollBarStateEngine( this ) );
|
||||
registerEngine( _tabWidgetStateEngine = new TabWidgetStateEngine( this ) );
|
||||
registerEngine( _treeViewStateEngine = new TreeViewStateEngine( this ) );
|
||||
registerEngine( _menuBarStateEngine = new MenuBarStateEngine( this ) );
|
||||
registerEngine( _menuStateEngine = new MenuStateEngine( this ) );
|
||||
registerEngine( _toolBarStateEngine = new ToolBarStateEngine( this ) );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
Animations::~Animations( void )
|
||||
{
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr << "Oxygen::Animations::~Animations" << std::endl;
|
||||
#endif
|
||||
|
||||
// delete all engines
|
||||
for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
|
||||
{ delete *iter; }
|
||||
|
||||
// disconnect all signals from map
|
||||
for( WidgetMap::iterator iter = _allWidgets.begin(); iter != _allWidgets.end(); iter++ )
|
||||
{ iter->second.disconnect(); }
|
||||
|
||||
// clear hooks
|
||||
_backgroundHintHook.disconnect();
|
||||
_sizeAllocationHook.disconnect();
|
||||
_realizationHook.disconnect();
|
||||
_innerShadowHook.disconnect();
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
//_________________________________________
|
||||
void Animations::initialize( const QtSettings& settings )
|
||||
{
|
||||
|
||||
const bool animationsEnabled( settings.animationsEnabled() );
|
||||
|
||||
// pass animations configuration to engines
|
||||
widgetStateEngine().setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
|
||||
widgetStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
|
||||
arrowStateEngine().setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
|
||||
arrowStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
|
||||
scrollBarStateEngine().setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
|
||||
scrollBarStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
|
||||
tabWidgetStateEngine().setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
|
||||
tabWidgetStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
|
||||
treeViewStateEngine().setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
|
||||
treeViewStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
|
||||
menuBarStateEngine().setAnimationsEnabled( animationsEnabled && (settings.menuBarAnimationType() != None) );
|
||||
menuBarStateEngine().setFollowMouse( settings.menuBarAnimationType() == FollowMouse );
|
||||
menuBarStateEngine().setDuration( settings.menuBarAnimationsDuration() );
|
||||
menuBarStateEngine().setFollowMouseAnimationsDuration( settings.menuBarFollowMouseAnimationsDuration() );
|
||||
|
||||
menuStateEngine().setEnabled( animationsEnabled && (settings.menuAnimationType() != None) );
|
||||
menuStateEngine().setFollowMouse( settings.menuAnimationType() == FollowMouse );
|
||||
menuStateEngine().setDuration( settings.menuAnimationsDuration() );
|
||||
menuStateEngine().setFollowMouseAnimationsDuration( settings.menuFollowMouseAnimationsDuration() );
|
||||
|
||||
// for now, only Fade animations mode is supported for toolbar animations
|
||||
toolBarStateEngine().setEnabled( animationsEnabled && (settings.toolBarAnimationType() != None) );
|
||||
toolBarStateEngine().setFollowMouse( settings.toolBarAnimationType() == FollowMouse );
|
||||
toolBarStateEngine().setDuration( settings.genericAnimationsDuration() );
|
||||
toolBarStateEngine().setFollowMouseAnimationsDuration( settings.toolBarAnimationsDuration() );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
void Animations::initializeHooks( void )
|
||||
{
|
||||
if( _hooksInitialized ) return;
|
||||
|
||||
#if 0
|
||||
_backgroundHintHook.connect( "realize", (GSignalEmissionHook)backgroundHintHook, this );
|
||||
|
||||
#if ENABLE_INNER_SHADOWS_HACK
|
||||
if(!getenv("OXYGEN_DISABLE_INNER_SHADOWS_HACK"))
|
||||
{ _innerShadowHook.connect( "realize", (GSignalEmissionHook)innerShadowHook, this ); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
_sizeAllocationHook.connect( "size-allocate", (GSignalEmissionHook)sizeAllocationHook, this );
|
||||
_realizationHook.connect( "realize", (GSignalEmissionHook)realizationHook, this );
|
||||
|
||||
_hooksInitialized = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
bool Animations::registerWidget( GtkWidget* widget )
|
||||
{
|
||||
|
||||
if( _allWidgets.find( widget ) != _allWidgets.end() ) return false;
|
||||
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr << "Oxygen::Animations::registerWidget - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Signal destroyId;
|
||||
destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( destroyNotifyEvent ), this );
|
||||
_allWidgets.insert( std::make_pair( widget, destroyId ) );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
void Animations::unregisterWidget( GtkWidget* widget )
|
||||
{
|
||||
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr << "Oxygen::Animations::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 map
|
||||
_allWidgets.erase( widget );
|
||||
|
||||
// erase from all maps
|
||||
for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
|
||||
{ (*iter)->unregisterWidget( widget ); }
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
void Animations::setEnabled( bool value )
|
||||
{
|
||||
|
||||
for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
|
||||
{ (*iter)->setEnabled( value ); }
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean Animations::destroyNotifyEvent( GtkWidget* widget, gpointer data )
|
||||
{
|
||||
static_cast<Animations*>(data)->unregisterWidget( widget );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean Animations::sizeAllocationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
|
||||
{
|
||||
|
||||
// get widget from params
|
||||
GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );
|
||||
|
||||
// check type
|
||||
if( !GTK_IS_WIDGET( widget ) ) return FALSE;
|
||||
|
||||
// comboboxes
|
||||
/*
|
||||
need to force the wrap-width property to 0,
|
||||
otherwise the "appears-as-list" flag is not respected, which additionally breaks the widget rendering.
|
||||
This has to be done soon enoug to avoid crash with latest gtk3 versions
|
||||
*/
|
||||
if(
|
||||
GTK_IS_COMBO_BOX( widget ) &&
|
||||
Gtk::gtk_combobox_appears_as_list( widget ) &&
|
||||
!gtk_combo_box_get_has_entry( GTK_COMBO_BOX( widget ) ) )
|
||||
{
|
||||
gtk_combo_box_set_wrap_width( GTK_COMBO_BOX( widget ), 0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION( 3, 5, 0 )
|
||||
/*
|
||||
HACK: Somehow, style_updated method for GtkRange widgets is not called anymore
|
||||
as soon as we (oxygen-gtk) install our hooks. This prevents some settings to be
|
||||
properly initialized, such as the slider length, or the arrows for scrollbars.
|
||||
Therefore we explicitly call the styleUpdated function ourselves.
|
||||
*/
|
||||
if( GTK_IS_RANGE( widget ) )
|
||||
{
|
||||
// get class
|
||||
GtkWidgetClass* widgetClass = GTK_WIDGET_GET_CLASS( widget );
|
||||
if( widgetClass && widgetClass->style_updated )
|
||||
{ (*widgetClass->style_updated)(widget); }
|
||||
}
|
||||
#endif
|
||||
|
||||
// groupbox labels
|
||||
#if ENABLE_GROUPBOX_HACK
|
||||
if( static_cast<Animations*>( data )->groupBoxLabelEngine().contains( widget ) )
|
||||
{
|
||||
static_cast<Animations*>( data )->groupBoxLabelEngine().adjustSize( widget );
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_COMBOBOX_LIST_RESIZE
|
||||
// comboboxes
|
||||
if( !GTK_IS_WINDOW( widget ) ) return TRUE;
|
||||
|
||||
GtkWindow* window( GTK_WINDOW( widget ) );
|
||||
if( gtk_window_get_type_hint( window ) != GDK_WINDOW_TYPE_HINT_COMBO ) return TRUE;
|
||||
|
||||
Animations& animations( *static_cast<Animations*>(data) );
|
||||
GtkWidget* combobox = animations.comboBoxEngine().find( widget );
|
||||
if( !combobox ) combobox = animations.comboBoxEntryEngine().find( widget );
|
||||
if( !combobox ) return true;
|
||||
|
||||
int w, h;
|
||||
gtk_window_get_size( window, &w, &h );
|
||||
|
||||
gint sourceX, sourceY;
|
||||
gint targetX, targetY;
|
||||
gtk_window_get_position( window, &sourceX, &sourceY );
|
||||
gdk_window_get_origin( gtk_widget_get_window( combobox ), &targetX, &targetY );
|
||||
|
||||
// store allocations
|
||||
const GtkAllocation comboAllocation( Gtk::gtk_widget_get_allocation( combobox ) );
|
||||
const GtkAllocation widgetAllocation( Gtk::gtk_widget_get_allocation( widget ) );
|
||||
|
||||
const bool widthChanged( widgetAllocation.width != comboAllocation.width - 6 );
|
||||
const bool positionChanged( sourceX != targetX + comboAllocation.x + 3 );
|
||||
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr
|
||||
<< "Animations::comboBoxHook -"
|
||||
<< " widget: " << widget
|
||||
<< " widthChanged: " << widthChanged
|
||||
<< " positionChanged: " << positionChanged
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
int uglyShadowWidth=!Gtk::gdk_default_screen_is_composited();
|
||||
|
||||
// perform move-resize
|
||||
if( widthChanged && positionChanged )
|
||||
{
|
||||
|
||||
gdk_window_move_resize(
|
||||
gtk_widget_get_window( widget ),
|
||||
targetX + comboAllocation.x + 3 - uglyShadowWidth, sourceY,
|
||||
comboAllocation.width - 6 + 2*uglyShadowWidth, widgetAllocation.height );
|
||||
|
||||
} else if( widthChanged ) {
|
||||
|
||||
gdk_window_resize(
|
||||
gtk_widget_get_window( widget ),
|
||||
comboAllocation.width - 6 + 2*uglyShadowWidth, widgetAllocation.height );
|
||||
|
||||
} else if( positionChanged ) {
|
||||
|
||||
gdk_window_move(
|
||||
gtk_widget_get_window( widget ),
|
||||
targetX + comboAllocation.x + 3 - uglyShadowWidth, sourceY );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
//____________________________________________________________________________________________
|
||||
gboolean Animations::backgroundHintHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
|
||||
{
|
||||
// get widget from params
|
||||
GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );
|
||||
|
||||
// check type
|
||||
if( !GTK_IS_WIDGET( widget ) ) return FALSE;
|
||||
if( !GTK_IS_WINDOW( widget ) ) return TRUE;
|
||||
|
||||
Animations& animations( *static_cast<Animations*>(data) );
|
||||
animations.backgroundHintEngine().registerWidget( widget );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean Animations::innerShadowHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
|
||||
{
|
||||
|
||||
// get widget from params
|
||||
GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );
|
||||
|
||||
// check type
|
||||
if( !GTK_IS_WIDGET( widget ) ) return FALSE;
|
||||
|
||||
// check enabled state
|
||||
Animations& animations( *static_cast<Animations*>(data) );
|
||||
if( !animations.innerShadowsEnabled() ) return TRUE;
|
||||
|
||||
// blacklist
|
||||
if( Gtk::g_object_is_a( G_OBJECT( widget ), "SwtFixed" ) ) return TRUE;
|
||||
if( Gtk::g_object_is_a( G_OBJECT( widget ), "GtkPizza" ) ) return TRUE;
|
||||
if( Gtk::g_object_is_a( G_OBJECT( widget ), "MessageList") ) return TRUE;
|
||||
|
||||
GtkWidget* parent(gtk_widget_get_parent(widget));
|
||||
if( !GTK_IS_SCROLLED_WINDOW( parent ) ) return TRUE;
|
||||
|
||||
GtkWidget* child(gtk_bin_get_child(GTK_BIN(parent)));
|
||||
if(child!=widget) return TRUE;
|
||||
|
||||
#if OXYGEN_DEBUG
|
||||
std::cerr
|
||||
<< "Oxygen::Animations::innerShadowHook -"
|
||||
<< " widget: " << widget << " (" << G_OBJECT_TYPE_NAME(widget) << ")"
|
||||
<< " parent: " << parent << " (" << G_OBJECT_TYPE_NAME(parent) << ")"
|
||||
<< " widget path: " << Gtk::gtk_widget_path( widget )
|
||||
<< " isTreeView: " << (GTK_IS_TREE_VIEW(widget)?"true":"false")
|
||||
<< " isTextView: " << (GTK_IS_TEXT_VIEW(widget)?"true":"false")
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
animations.innerShadowEngine().registerWidget( parent );
|
||||
animations.innerShadowEngine().registerChild( parent, widget );
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean Animations::realizationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
|
||||
{
|
||||
|
||||
// get widget from params
|
||||
GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );
|
||||
|
||||
// check type
|
||||
if( !GTK_IS_WIDGET( widget ) ) return FALSE;
|
||||
|
||||
if( GTK_IS_NOTEBOOK( widget ) )
|
||||
{ gtk_notebook_set_show_border( GTK_NOTEBOOK(widget), FALSE ); }
|
||||
|
||||
#if ENABLE_GROUPBOX_HACK
|
||||
if( GTK_IS_LABEL( widget ) && GTK_IS_FRAME( gtk_widget_get_parent( widget ) ) )
|
||||
{
|
||||
|
||||
GtkFrame *frame( GTK_FRAME( gtk_widget_get_parent( widget ) ) );
|
||||
if( widget == gtk_frame_get_label_widget( frame ) && !Gtk::gtk_widget_find_parent( widget, "GtkPizza" ) )
|
||||
{
|
||||
#if OXYGEN_DEBUG
|
||||
std::cout
|
||||
<< "Oxygen::Animations::realizationHook -"
|
||||
<< " widget: " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")"
|
||||
<< " parent: " << frame << " (" << G_OBJECT_TYPE_NAME( frame ) << ")"
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
// modify alignment
|
||||
gtk_frame_set_label_align( frame, 0.5, 0.0 );
|
||||
gtk_frame_set_shadow_type( frame, GTK_SHADOW_OUT );
|
||||
|
||||
// register to engine
|
||||
static_cast<Animations*>( data )->groupBoxLabelEngine().registerWidget( widget );
|
||||
static_cast<Animations*>( data )->groupBoxLabelEngine().adjustSize( widget );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
@ -0,0 +1,337 @@
|
||||
#ifndef tdegtk_animations_h
|
||||
#define tdegtk_animations_h
|
||||
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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-arrowstateengine.h"
|
||||
// #include "tdegtk-backgroundhintengine.h"
|
||||
#include "tdegtk-baseengine.h"
|
||||
// #include "tdegtk-comboboxengine.h"
|
||||
// #include "tdegtk-comboboxentryengine.h"
|
||||
// #include "tdegtk-dialogengine.h"
|
||||
// #include "tdegtk-groupboxengine.h"
|
||||
// #include "tdegtk-groupboxlabelengine.h"
|
||||
#include "tdegtk-hooks.h"
|
||||
// #include "tdegtk-hoverengine.h"
|
||||
// #include "tdegtk-mainwindowengine.h"
|
||||
// #include "tdegtk-menubarstateengine.h"
|
||||
// #include "tdegtk-menuitemengine.h"
|
||||
// #include "tdegtk-menustateengine.h"
|
||||
// #include "tdegtk-panedengine.h"
|
||||
// #include "tdegtk-scrollbarengine.h"
|
||||
// #include "tdegtk-scrollbarstateengine.h"
|
||||
// #include "tdegtk-scrolledwindowengine.h"
|
||||
// #include "tdegtk-innershadowengine.h"
|
||||
#include "tdegtk-signals.h"
|
||||
#include "tdegtk-tabwidgetengine.h"
|
||||
// #include "tdegtk-tabwidgetstateengine.h"
|
||||
// #include "tdegtk-toolbarstateengine.h"
|
||||
// #include "tdegtk-treeviewengine.h"
|
||||
// #include "tdegtk-treeviewstateengine.h"
|
||||
// #include "tdegtk-widgetsizeengine.h"
|
||||
// #include "tdegtk-widgetstateengine.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//! keeps track of all animation engines
|
||||
class Animations
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
Animations( void );
|
||||
|
||||
//! destructor
|
||||
virtual ~Animations( void );
|
||||
|
||||
//! initialize settings
|
||||
// void initialize( const QtSettings& );
|
||||
|
||||
//! initialize hooks
|
||||
void initializeHooks( void );
|
||||
|
||||
//! unregister widget
|
||||
bool registerWidget( GtkWidget* );
|
||||
|
||||
//! unregister widget
|
||||
void unregisterWidget( GtkWidget* );
|
||||
|
||||
//! enabled state
|
||||
void setEnabled( bool value );
|
||||
|
||||
#if 0
|
||||
//! inner shadow enabled state
|
||||
void setInnerShadowsEnabled( bool value )
|
||||
{ _innerShadowsEnabled = value; }
|
||||
|
||||
//! inner shadow enabled state
|
||||
bool innerShadowsEnabled( void ) const
|
||||
{ return _innerShadowsEnabled; }
|
||||
|
||||
//! combobox engine
|
||||
ComboBoxEngine& comboBoxEngine( void ) const
|
||||
{ return *_comboBoxEngine; }
|
||||
|
||||
//! comboboxentry engine
|
||||
ComboBoxEntryEngine& comboBoxEntryEngine( void ) const
|
||||
{ return *_comboBoxEntryEngine; }
|
||||
|
||||
//! dialog engine
|
||||
DialogEngine& dialogEngine( void ) const
|
||||
{ return *_dialogEngine; }
|
||||
|
||||
//! groupbox engine
|
||||
GroupBoxEngine& groupBoxEngine( void ) const
|
||||
{ return *_groupBoxEngine; }
|
||||
|
||||
//! background hint
|
||||
BackgroundHintEngine& backgroundHintEngine( void ) const
|
||||
{ return *_backgroundHintEngine; }
|
||||
|
||||
//! main window engine
|
||||
MainWindowEngine& mainWindowEngine( void ) const
|
||||
{ return *_mainWindowEngine; }
|
||||
|
||||
//! menu item engine
|
||||
MenuItemEngine& menuItemEngine( void ) const
|
||||
{ return *_menuItemEngine; }
|
||||
|
||||
//! hover engine
|
||||
HoverEngine& hoverEngine( void ) const
|
||||
{ return *_hoverEngine; }
|
||||
|
||||
//! paned (splitter) engine
|
||||
PanedEngine& panedEngine( void ) const
|
||||
{ return *_panedEngine; }
|
||||
|
||||
//! scrollbar engine
|
||||
ScrollBarEngine& scrollBarEngine( void ) const
|
||||
{ return *_scrollBarEngine; }
|
||||
|
||||
//! scrolled window engine
|
||||
ScrolledWindowEngine& scrolledWindowEngine( void ) const
|
||||
{ return *_scrolledWindowEngine; }
|
||||
|
||||
//! inner shadow engine
|
||||
InnerShadowEngine& innerShadowEngine( void ) const
|
||||
{ return *_innerShadowEngine; }
|
||||
#endif
|
||||
|
||||
//! tab widget engine
|
||||
TabWidgetEngine& tabWidgetEngine( void ) const
|
||||
{ return *_tabWidgetEngine; }
|
||||
|
||||
#if 0
|
||||
//! tree view engine
|
||||
TreeViewEngine& treeViewEngine( void ) const
|
||||
{ return *_treeViewEngine; }
|
||||
|
||||
//! window size engine
|
||||
WidgetSizeEngine& widgetSizeEngine( void ) const
|
||||
{ return *_widgetSizeEngine; }
|
||||
|
||||
//!@name animations specific engines
|
||||
//@{
|
||||
|
||||
//! widget mouse-over and focus animations engine
|
||||
WidgetStateEngine& widgetStateEngine( void ) const
|
||||
{ return *_widgetStateEngine; }
|
||||
|
||||
//! arrow mouse-over animations engine
|
||||
ArrowStateEngine& arrowStateEngine( void ) const
|
||||
{ return *_arrowStateEngine; }
|
||||
|
||||
//! scrollbar arrow mouse-over animations engine
|
||||
ScrollBarStateEngine& scrollBarStateEngine( void ) const
|
||||
{ return *_scrollBarStateEngine; }
|
||||
|
||||
//! notebook tabs mouse-over animations engine
|
||||
TabWidgetStateEngine& tabWidgetStateEngine( void ) const
|
||||
{ return *_tabWidgetStateEngine; }
|
||||
|
||||
//! tree view mouse-over animation engine
|
||||
TreeViewStateEngine& treeViewStateEngine( void ) const
|
||||
{ return *_treeViewStateEngine; }
|
||||
|
||||
//! menubar mouse-over animation engine
|
||||
MenuBarStateEngine& menuBarStateEngine( void ) const
|
||||
{ return *_menuBarStateEngine; }
|
||||
|
||||
//! menu mouse-over animation engine
|
||||
MenuStateEngine& menuStateEngine( void ) const
|
||||
{ return *_menuStateEngine; }
|
||||
|
||||
//! toolbar mouse-over animation engine
|
||||
ToolBarStateEngine& toolBarStateEngine( void ) const
|
||||
{ return *_toolBarStateEngine; }
|
||||
#endif
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
//! register new engine
|
||||
void registerEngine( BaseEngine* engine )
|
||||
{ _engines.push_back( engine ); }
|
||||
|
||||
#if 0
|
||||
//! groupbox engine
|
||||
GroupBoxLabelEngine& groupBoxLabelEngine( void ) const
|
||||
{ return *_groupBoxLabelEngine; }
|
||||
#endif
|
||||
|
||||
//! destruction callback
|
||||
static gboolean destroyNotifyEvent( GtkWidget*, gpointer );
|
||||
|
||||
//! combobox list size adjustment hook
|
||||
static gboolean sizeAllocationHook( GSignalInvocationHint*, guint, const GValue*, gpointer );
|
||||
|
||||
#if 0
|
||||
//! background hint setting hook
|
||||
static gboolean backgroundHintHook( GSignalInvocationHint*, guint, const GValue*, gpointer );
|
||||
|
||||
//! inner shadow composited mode enabling hook
|
||||
static gboolean innerShadowHook( GSignalInvocationHint*, guint, const GValue*, gpointer );
|
||||
#endif
|
||||
|
||||
//! widget realize hook
|
||||
static gboolean realizationHook( GSignalInvocationHint*, guint, const GValue*, gpointer );
|
||||
|
||||
private:
|
||||
|
||||
//! inner shadow enabled state
|
||||
bool _innerShadowsEnabled;
|
||||
|
||||
//! list of engines
|
||||
BaseEngine::List _engines;
|
||||
|
||||
#if 0
|
||||
//! background hint engine
|
||||
BackgroundHintEngine* _backgroundHintEngine;
|
||||
|
||||
//! combobox engine
|
||||
ComboBoxEngine* _comboBoxEngine;
|
||||
|
||||
//! combobox entry engine
|
||||
ComboBoxEntryEngine* _comboBoxEntryEngine;
|
||||
|
||||
//! dialog engine
|
||||
DialogEngine* _dialogEngine;
|
||||
|
||||
//! groupbox engine
|
||||
GroupBoxEngine* _groupBoxEngine;
|
||||
|
||||
//! groupbox engine
|
||||
GroupBoxLabelEngine* _groupBoxLabelEngine;
|
||||
|
||||
//! hover engine
|
||||
HoverEngine* _hoverEngine;
|
||||
|
||||
//! main window engine
|
||||
MainWindowEngine* _mainWindowEngine;
|
||||
|
||||
//! menu item engine
|
||||
MenuItemEngine* _menuItemEngine;
|
||||
|
||||
//! paned engine
|
||||
PanedEngine* _panedEngine;
|
||||
|
||||
//! scrollbar engine
|
||||
ScrollBarEngine* _scrollBarEngine;
|
||||
|
||||
//! scrolled window engine
|
||||
ScrolledWindowEngine* _scrolledWindowEngine;
|
||||
|
||||
//! inner shadow engine
|
||||
InnerShadowEngine* _innerShadowEngine;
|
||||
#endif
|
||||
|
||||
//! tab widget engine
|
||||
TabWidgetEngine* _tabWidgetEngine;
|
||||
|
||||
#if 0
|
||||
//! tree view engine
|
||||
TreeViewEngine* _treeViewEngine;
|
||||
|
||||
//! widget size engine
|
||||
WidgetSizeEngine* _widgetSizeEngine;
|
||||
|
||||
//!@name Animation specific engines
|
||||
//@{
|
||||
|
||||
//! widget mouse-over and focus animations engine
|
||||
WidgetStateEngine* _widgetStateEngine;
|
||||
|
||||
//! arrow mouse-over animations engine
|
||||
ArrowStateEngine* _arrowStateEngine;
|
||||
|
||||
//! scrollbar arrow mouse-over animations engine
|
||||
ScrollBarStateEngine* _scrollBarStateEngine;
|
||||
|
||||
//! notebook tabs mouse-over animations engine
|
||||
TabWidgetStateEngine* _tabWidgetStateEngine;
|
||||
|
||||
//! tree view mouse-over animation engine
|
||||
TreeViewStateEngine* _treeViewStateEngine;
|
||||
|
||||
//! menubar mouse-over animation engine
|
||||
MenuBarStateEngine* _menuBarStateEngine;
|
||||
|
||||
//! menu mouse-over animation engine
|
||||
MenuStateEngine* _menuStateEngine;
|
||||
|
||||
//! toolbar mouse-over animation engine
|
||||
ToolBarStateEngine* _toolBarStateEngine;
|
||||
#endif
|
||||
|
||||
//@}
|
||||
|
||||
//!@name hooks
|
||||
//@{
|
||||
|
||||
//! true when hooks are initialized
|
||||
bool _hooksInitialized;
|
||||
|
||||
//! realization hook
|
||||
Hook _realizationHook;
|
||||
|
||||
//! size allocation hook
|
||||
Hook _sizeAllocationHook;
|
||||
|
||||
//! background hint hook
|
||||
Hook _backgroundHintHook;
|
||||
|
||||
//! inner shadows hook
|
||||
Hook _innerShadowHook;
|
||||
|
||||
//@}
|
||||
|
||||
//! keep track of all registered widgets, and associated destroy callback
|
||||
typedef std::map< GtkWidget*, Signal > WidgetMap;
|
||||
WidgetMap _allWidgets;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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-baseengine.h"
|
||||
#include "tdegtk-animations.h"
|
||||
|
||||
|
||||
//______________________________________________________
|
||||
bool BaseEngine::registerWidget( GtkWidget* widget )
|
||||
{ return parent().registerWidget( widget ); }
|
@ -0,0 +1,83 @@
|
||||
#ifndef tdegtk_baseengine_h
|
||||
#define tdegtk_baseengine_h
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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 <gtk/gtk.h>
|
||||
#include <vector>
|
||||
|
||||
//! forward declaration
|
||||
class Animations;
|
||||
|
||||
//! base class for all engines
|
||||
/*! engines map pointers to GtkWidget to some data, needed for animations */
|
||||
class BaseEngine
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
BaseEngine( Animations* parent ):
|
||||
_parent( parent ),
|
||||
_enabled( true )
|
||||
{}
|
||||
|
||||
virtual ~BaseEngine()
|
||||
{}
|
||||
|
||||
//! register widget
|
||||
virtual bool registerWidget( GtkWidget* widget );
|
||||
|
||||
//! unregister widget
|
||||
virtual void unregisterWidget( GtkWidget* ) = 0;
|
||||
|
||||
//! engine list
|
||||
typedef std::vector< BaseEngine* > List;
|
||||
|
||||
//! enable state
|
||||
/*! returns true if changed */
|
||||
virtual bool setEnabled( bool value )
|
||||
{
|
||||
if( _enabled == value ) return false;
|
||||
_enabled = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! enable state
|
||||
bool enabled( void ) const
|
||||
{ return _enabled; }
|
||||
|
||||
protected:
|
||||
|
||||
//! returns parent
|
||||
virtual Animations& parent( void ) const
|
||||
{ return *_parent; }
|
||||
|
||||
private:
|
||||
|
||||
//! parent
|
||||
Animations* _parent;
|
||||
|
||||
//! enable flag
|
||||
bool _enabled;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,170 @@
|
||||
#ifndef oxygendatamap_h
|
||||
#define oxygendatamap_h
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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 <cassert>
|
||||
#include <map>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//! generic class to map data to widgets
|
||||
/*
|
||||
Note: I'm not sure about memory management. At some point one might need to allocate the registered
|
||||
data on the heap rather than on the stack, to be able to safely pass the data pointer around via callbacks.
|
||||
The current implementation should make that possible without external code change, provided that the map
|
||||
content is properly deleted (as opposed to erased) in destructor and 'unregister' method.
|
||||
*/
|
||||
template <typename T>
|
||||
class DataMap
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
DataMap( void ):
|
||||
_lastWidget( 0L ),
|
||||
_lastData( 0L )
|
||||
{}
|
||||
|
||||
virtual ~DataMap(){}
|
||||
|
||||
//! insert new widget
|
||||
inline T& registerWidget( GtkWidget* widget )
|
||||
{
|
||||
T& data( _map.insert( std::make_pair( widget, T() ) ).first->second );
|
||||
_lastWidget = widget;
|
||||
_lastData = &data;
|
||||
return data;
|
||||
}
|
||||
|
||||
//! true if widget is in list
|
||||
virtual bool contains( GtkWidget* widget )
|
||||
{
|
||||
|
||||
// check against last widget
|
||||
if( widget == _lastWidget ) return true;
|
||||
|
||||
// find in map, returns false if not found
|
||||
typename Map::iterator iter = _map.find( widget );
|
||||
if( iter == _map.end() ) return false;
|
||||
|
||||
// store as last widget/last data, to speed up lookup.
|
||||
_lastWidget = widget;
|
||||
_lastData = &iter->second;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//! return value
|
||||
virtual T& value( GtkWidget* widget )
|
||||
{
|
||||
|
||||
// check against last widget
|
||||
if( widget == _lastWidget ) return *_lastData;
|
||||
|
||||
// find in map, abort if not found
|
||||
typename Map::iterator iter( _map.find( widget ) );
|
||||
assert( iter != _map.end() );
|
||||
|
||||
// store as last widget/last data, to speed up lookup.
|
||||
_lastWidget = widget;
|
||||
_lastData = &iter->second;
|
||||
return iter->second;
|
||||
|
||||
}
|
||||
|
||||
//! erase
|
||||
virtual void erase( GtkWidget* widget )
|
||||
{
|
||||
|
||||
// clear last widget and data, if match
|
||||
if( _lastWidget == widget )
|
||||
{
|
||||
_lastWidget = 0L;
|
||||
_lastData = 0L;
|
||||
}
|
||||
|
||||
// erase from map
|
||||
_map.erase( widget );
|
||||
|
||||
}
|
||||
|
||||
//! connect all widgets in map
|
||||
void connectAll( void )
|
||||
{
|
||||
for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ )
|
||||
{ iter->second.connect( iter->first ); }
|
||||
}
|
||||
|
||||
|
||||
//! connect all widgets in map
|
||||
void disconnectAll( void )
|
||||
{
|
||||
for( typename Map::iterator iter = _map.begin(); iter != _map.end(); iter++ )
|
||||
{ iter->second.disconnect( iter->first ); }
|
||||
}
|
||||
|
||||
//! erase
|
||||
virtual void clear( void )
|
||||
{
|
||||
|
||||
_lastWidget = 0L;
|
||||
_lastData = 0L;
|
||||
_map.clear();
|
||||
|
||||
}
|
||||
|
||||
//! retrieve internal map
|
||||
typedef std::map<GtkWidget*, T> Map;
|
||||
Map& map( void )
|
||||
{ return _map; }
|
||||
|
||||
//! retrieve internal map
|
||||
const Map& map( void ) const
|
||||
{ return _map; }
|
||||
|
||||
protected:
|
||||
|
||||
//! copy constructor is private
|
||||
DataMap( const DataMap& )
|
||||
{ assert( false ); }
|
||||
|
||||
//! assignment operator
|
||||
DataMap& operator = ( const DataMap& )
|
||||
{
|
||||
assert( false );
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! pointer to last inquired widget
|
||||
GtkWidget* _lastWidget;
|
||||
|
||||
//! pointer to last retrieved data
|
||||
T* _lastData;
|
||||
|
||||
//! internal map between widget and data
|
||||
Map _map;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,112 @@
|
||||
#ifndef tdegtk_genericengine_h
|
||||
#define tdegtk_genericengine_h
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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-baseengine.h"
|
||||
#include "tdegtk-datamap.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//! forward declaration
|
||||
class Animations;
|
||||
|
||||
//! associates widgets with some type of data
|
||||
template< typename T>
|
||||
class GenericEngine: public BaseEngine
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
GenericEngine( Animations* widget ):
|
||||
BaseEngine( widget )
|
||||
{}
|
||||
|
||||
//! destructor
|
||||
virtual ~GenericEngine( void )
|
||||
{}
|
||||
|
||||
//! register widget
|
||||
virtual bool registerWidget( GtkWidget* widget )
|
||||
{
|
||||
if( _data.contains( widget ) ) return false;
|
||||
if( enabled() )
|
||||
{
|
||||
|
||||
T& data( _data.registerWidget( widget ) );
|
||||
data.connect( widget );
|
||||
|
||||
} else _data.registerWidget( widget );
|
||||
|
||||
BaseEngine::registerWidget( widget );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//! unregister widget
|
||||
virtual void unregisterWidget( GtkWidget* widget )
|
||||
{
|
||||
if( !_data.contains( widget ) ) return;
|
||||
_data.value( widget ).disconnect( widget );
|
||||
_data.erase( widget );
|
||||
}
|
||||
|
||||
//! enabled state
|
||||
/*! returns true if changed */
|
||||
inline virtual bool setEnabled( bool value );
|
||||
|
||||
//! true if widget is included
|
||||
virtual bool contains( GtkWidget* widget )
|
||||
{ return _data.contains( widget ); }
|
||||
|
||||
protected:
|
||||
|
||||
//! return refence to data
|
||||
virtual DataMap<T>& data( void )
|
||||
{ return _data; }
|
||||
|
||||
//! return refence to data
|
||||
virtual const DataMap<T>& data( void ) const
|
||||
{ return _data; }
|
||||
|
||||
private:
|
||||
|
||||
//! map widgets to data
|
||||
DataMap<T> _data;
|
||||
|
||||
};
|
||||
|
||||
//________________________________________________________________________
|
||||
template< typename T> bool GenericEngine<T>::setEnabled( bool value )
|
||||
{
|
||||
if( enabled() == value ) return false;
|
||||
|
||||
BaseEngine::setEnabled( value );
|
||||
if( enabled() ) _data.connectAll();
|
||||
else _data.disconnectAll();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* the tabwidget data code is largely inspired from the gtk redmond engine
|
||||
*
|
||||
* 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-tabwidgetdata.h"
|
||||
#include "tdegtk-utils.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::connect( GtkWidget* widget )
|
||||
{
|
||||
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::connect - " << widget << std::endl;
|
||||
#endif
|
||||
|
||||
_target = widget;
|
||||
_motionId.connect( G_OBJECT(widget), "motion-notify-event", G_CALLBACK( motionNotifyEvent ), this );
|
||||
_leaveId.connect( G_OBJECT(widget), "leave-notify-event", G_CALLBACK( leaveNotifyEvent ), this );
|
||||
_pageAddedId.connect( G_OBJECT(widget), "page-added", G_CALLBACK( pageAddedEvent ), this );
|
||||
|
||||
updateRegisteredChildren( widget );
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::disconnect( GtkWidget* widget )
|
||||
{
|
||||
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::disconnect - " << widget << std::endl;
|
||||
#endif
|
||||
|
||||
_target = 0L;
|
||||
_motionId.disconnect();
|
||||
_leaveId.disconnect();
|
||||
_pageAddedId.disconnect();
|
||||
|
||||
// disconnect all children
|
||||
for( ChildDataMap::iterator iter = _childrenData.begin(); iter != _childrenData.end(); ++iter )
|
||||
{ iter->second.disconnect(); }
|
||||
_childrenData.clear();
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::updateHoveredTab( GtkWidget* widget )
|
||||
{
|
||||
|
||||
if( !widget ) widget = _target;
|
||||
if( !widget ) return;
|
||||
|
||||
// get pointer position
|
||||
int xPointer(0), yPointer(0);
|
||||
|
||||
GdkDeviceManager* manager( gdk_display_get_device_manager( gtk_widget_get_display( widget ) ) );
|
||||
GdkDevice* pointer( gdk_device_manager_get_client_pointer( manager ) );
|
||||
if( !pointer ) return;
|
||||
|
||||
gdk_window_get_device_position( gtk_widget_get_window( widget ), pointer, &xPointer, &yPointer, 0L );
|
||||
|
||||
|
||||
// loop over tabs and check matching
|
||||
for( unsigned int i = (unsigned int)Gtk::gtk_notebook_find_first_tab( widget ); i < _tabRects.size(); i++ )
|
||||
{
|
||||
if( Gtk::gdk_rectangle_contains( &_tabRects[i], xPointer, yPointer ) )
|
||||
{ setHoveredTab( widget, i ); return; }
|
||||
}
|
||||
|
||||
// reset hovered tab
|
||||
setHoveredTab( widget, -1 );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::updateTabRect( GtkWidget* widget, int index, const GdkRectangle& r )
|
||||
{
|
||||
// make sure the vector has the right size
|
||||
if( !GTK_IS_NOTEBOOK( widget ) ) return;
|
||||
GtkNotebook* notebook = GTK_NOTEBOOK( widget );
|
||||
_tabRects.resize( gtk_notebook_get_n_pages( notebook ), defaultRect() );
|
||||
|
||||
// check index against number of tabs
|
||||
if( index < 0 || index >= (int)_tabRects.size() )
|
||||
{ return; }
|
||||
|
||||
// store rectangle
|
||||
_tabRects[index]=r;
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::setDirty( bool value )
|
||||
{
|
||||
if( _dirty == value ) return;
|
||||
_dirty = value;
|
||||
if( _dirty && _target )
|
||||
{
|
||||
|
||||
// we should only update the tabbar rect here
|
||||
GdkRectangle updateRect;
|
||||
Gtk::gtk_notebook_get_tabbar_rect( GTK_NOTEBOOK( _target ), &updateRect );
|
||||
Gtk::gtk_widget_queue_draw( _target, &updateRect );
|
||||
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::setDirty - update: " << updateRect << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
bool TabWidgetData::isInTab( int x, int y ) const
|
||||
{
|
||||
|
||||
// loop over tab rectangles and check.
|
||||
for( RectangleList::const_iterator iter = _tabRects.begin(); iter != _tabRects.end(); ++iter )
|
||||
{ if( Gtk::gdk_rectangle_contains( &(*iter), x, y ) ) return true; }
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::setHoveredTab( GtkWidget* widget, int index )
|
||||
{
|
||||
|
||||
if( _hoveredTab == index ) return;
|
||||
|
||||
_hoveredTab = index;
|
||||
|
||||
GdkRectangle updateRect( Gtk::gdk_rectangle() );
|
||||
for( RectangleList::const_iterator iter = _tabRects.begin(); iter != _tabRects.end(); ++iter )
|
||||
{ gdk_rectangle_union( &(*iter), &updateRect, &updateRect ); }
|
||||
|
||||
gtk_widget_queue_draw_area( widget, updateRect.x-4, updateRect.y-4, updateRect.width+8, updateRect.height+8 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
gboolean TabWidgetData::motionNotifyEvent(GtkWidget* widget, GdkEventMotion*, gpointer data )
|
||||
{
|
||||
|
||||
static_cast<TabWidgetData*>( data )->updateHoveredTab( widget );
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
gboolean TabWidgetData::leaveNotifyEvent( GtkWidget* widget, GdkEventCrossing*, gpointer data )
|
||||
{
|
||||
// reset hovered tab
|
||||
static_cast<TabWidgetData*>( data )->setHoveredTab( widget, -1 );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::pageAddedEvent( GtkNotebook* parent, GtkWidget* child, guint, gpointer data)
|
||||
{
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::pageAddedEvent - " << child << std::endl;
|
||||
#endif
|
||||
static_cast<TabWidgetData*>(data)->updateRegisteredChildren( GTK_WIDGET( parent ) );
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::updateRegisteredChildren( GtkWidget* widget )
|
||||
{
|
||||
|
||||
if( !widget ) widget = _target;
|
||||
if( !widget ) return;
|
||||
|
||||
// cast to notebook and check against number of pages
|
||||
if( GTK_IS_NOTEBOOK( widget ) )
|
||||
{
|
||||
GtkNotebook* notebook( GTK_NOTEBOOK( widget ) );
|
||||
for( int i = 0; i < gtk_notebook_get_n_pages( notebook ); ++i )
|
||||
{
|
||||
|
||||
// retrieve page and tab label
|
||||
GtkWidget* page( gtk_notebook_get_nth_page( notebook, i ) );
|
||||
registerChild( gtk_notebook_get_tab_label( notebook, page ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::registerChild( GtkWidget* widget )
|
||||
{
|
||||
|
||||
// do nothing if child is invalid (might happen: not checked at calling stage)
|
||||
if( !widget ) return;
|
||||
|
||||
// make sure widget is not already in map
|
||||
if( _childrenData.find( widget ) == _childrenData.end() )
|
||||
{
|
||||
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::registerChild - " << widget << std::endl;
|
||||
#endif
|
||||
|
||||
// allocate new ChildData
|
||||
ChildData data;
|
||||
data._destroyId.connect( G_OBJECT(widget), "destroy", G_CALLBACK( childDestroyNotifyEvent ), this );
|
||||
data._enterId.connect( G_OBJECT(widget), "enter-notify-event", G_CALLBACK( childCrossingNotifyEvent ), this );
|
||||
data._leaveId.connect( G_OBJECT(widget), "leave-notify-event", G_CALLBACK( childCrossingNotifyEvent ), this );
|
||||
|
||||
if( GTK_IS_CONTAINER( widget ) )
|
||||
{ data._addId.connect( G_OBJECT(widget), "add", G_CALLBACK( childAddedEvent ), this ); }
|
||||
|
||||
// and insert in map
|
||||
_childrenData.insert( std::make_pair( widget, data ) );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
also insert widget's children, recursively.
|
||||
that should take care of buttons in tabs and other fancy stuff that applications mght do
|
||||
*/
|
||||
if( GTK_IS_CONTAINER( widget ) )
|
||||
{
|
||||
|
||||
GList *children( gtk_container_get_children( GTK_CONTAINER(widget) ) );
|
||||
for( GList* child = g_list_first(children); child; child = g_list_next(child) )
|
||||
{ registerChild( GTK_WIDGET( child->data ) ); }
|
||||
|
||||
if( children ) g_list_free( children );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________________________
|
||||
void TabWidgetData::unregisterChild( GtkWidget* widget )
|
||||
{
|
||||
|
||||
ChildDataMap::iterator iter( _childrenData.find( widget ) );
|
||||
if( iter == _childrenData.end() ) return;
|
||||
|
||||
#if TDEGTK_DEBUG
|
||||
std::cerr << "TDEGTK::TabWidgetData::unregisterChild - " << widget << std::endl;
|
||||
#endif
|
||||
|
||||
iter->second.disconnect();
|
||||
_childrenData.erase( iter );
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean TabWidgetData::childDestroyNotifyEvent( GtkWidget* widget, gpointer data )
|
||||
{
|
||||
static_cast<TabWidgetData*>(data)->unregisterChild( widget );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
void TabWidgetData::childAddedEvent( GtkContainer* parent, GtkWidget*, gpointer data )
|
||||
{
|
||||
static_cast<TabWidgetData*>(data)->updateRegisteredChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
gboolean TabWidgetData::childCrossingNotifyEvent( GtkWidget* widget, GdkEventCrossing*, gpointer data )
|
||||
{
|
||||
|
||||
// retrieve widget's parent and check type
|
||||
static_cast<TabWidgetData*>(data)->updateHoveredTab();
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________________
|
||||
void TabWidgetData::ChildData::disconnect( void )
|
||||
{
|
||||
|
||||
_destroyId.disconnect();
|
||||
_enterId.disconnect();
|
||||
_leaveId.disconnect();
|
||||
_addId.disconnect();
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,189 @@
|
||||
#ifndef tdegtk_tabwidgetdata_h
|
||||
#define tdegtk_widgetdata_h
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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-signals.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//! detects and stores tab widget hovered tab
|
||||
class TabWidgetData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
TabWidgetData( void ):
|
||||
_target(0L),
|
||||
_hoveredTab(-1),
|
||||
_dragInProgress( false ),
|
||||
_dirty( false )
|
||||
{}
|
||||
|
||||
//! destructor
|
||||
virtual ~TabWidgetData( void )
|
||||
{ disconnect( _target ); }
|
||||
|
||||
//! setup connections
|
||||
void connect( GtkWidget* );
|
||||
|
||||
//! disconnect
|
||||
void disconnect( GtkWidget* );
|
||||
|
||||
//!@name modifiers
|
||||
//@{
|
||||
|
||||
//! update tab rectangle
|
||||
/* this is used to decide when a tab is hovered or not */
|
||||
void updateTabRect( GtkWidget*, int, const GdkRectangle& );
|
||||
|
||||
//! update hovered tab
|
||||
void updateHoveredTab( GtkWidget* = 0L );
|
||||
|
||||
//! true when drag is in progress
|
||||
void setDragInProgress( bool value )
|
||||
{ _dragInProgress = value; }
|
||||
|
||||
//! toggle dirty state
|
||||
void toggleDirty( void )
|
||||
{ setDirty( !isDirty() ); }
|
||||
|
||||
//! mark as dirty
|
||||
void setDirty( bool );
|
||||
|
||||
//@}
|
||||
|
||||
//@name accessors
|
||||
//@{
|
||||
|
||||
//! true if hovered
|
||||
int hoveredTab( void ) const
|
||||
{ return _hoveredTab; }
|
||||
|
||||
//! true when drag is in progress
|
||||
bool dragInProgress( void ) const
|
||||
{ return _dragInProgress; }
|
||||
|
||||
//! true if is dirty
|
||||
bool isDirty( void ) const
|
||||
{ return _dirty; }
|
||||
|
||||
//! returns true if provided point is in one tab of the widget
|
||||
bool isInTab( int x, int y ) const;
|
||||
|
||||
//@]
|
||||
|
||||
protected:
|
||||
|
||||
//! set current tab
|
||||
void setHoveredTab( GtkWidget*, int );
|
||||
|
||||
//! child registration
|
||||
//@{
|
||||
|
||||
void updateRegisteredChildren( GtkWidget* = 0L );
|
||||
void registerChild( GtkWidget* );
|
||||
void unregisterChild( GtkWidget* );
|
||||
|
||||
//@}
|
||||
|
||||
//!@name static callbacks
|
||||
//@{
|
||||
static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer );
|
||||
static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
|
||||
static void pageAddedEvent( GtkNotebook*, GtkWidget*, guint, gpointer );
|
||||
static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer );
|
||||
static gboolean childCrossingNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
|
||||
static void childAddedEvent( GtkContainer*, GtkWidget*, gpointer );
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//! default tabRect size
|
||||
GdkRectangle defaultRect( void ) const
|
||||
{
|
||||
GdkRectangle out = {0, 0, -1, -1};
|
||||
return out;
|
||||
}
|
||||
|
||||
//! target widget
|
||||
GtkWidget* _target;
|
||||
|
||||
//!@name callbacks IDs
|
||||
//@{
|
||||
Signal _motionId;
|
||||
Signal _leaveId;
|
||||
Signal _pageAddedId;
|
||||
//@}
|
||||
|
||||
//! index of currently hovered tab
|
||||
int _hoveredTab;
|
||||
|
||||
//! true when there is a drag in progress
|
||||
bool _dragInProgress;
|
||||
|
||||
//! true when tabbar is dirty
|
||||
/*! a repaint is triggered of the full tabbar when set to true.
|
||||
This forces the tabbar base to be redrawn event if the selected tab
|
||||
has not been primarily damaged */
|
||||
bool _dirty;
|
||||
|
||||
//! store rectangles matching tabs
|
||||
typedef std::vector<GdkRectangle> RectangleList;
|
||||
RectangleList _tabRects;
|
||||
|
||||
//! child data
|
||||
/*!
|
||||
one must keep track of the tab widgets children enter/leave event
|
||||
to properly update tab hover because some tabs have embedded children.
|
||||
This is notably the case for gimp, nautilus (in tabbed mode), etc.
|
||||
*/
|
||||
class ChildData
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
ChildData( void )
|
||||
{}
|
||||
|
||||
//! destructor
|
||||
virtual ~ChildData( void )
|
||||
{}
|
||||
|
||||
//! disconnect all signals
|
||||
void disconnect( void );
|
||||
|
||||
Signal _destroyId;
|
||||
Signal _addId;
|
||||
Signal _enterId;
|
||||
Signal _leaveId;
|
||||
};
|
||||
|
||||
//! map registered children and corresponding data
|
||||
typedef std::map<GtkWidget*, ChildData> ChildDataMap;
|
||||
ChildDataMap _childrenData;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,109 @@
|
||||
#ifndef tdegtk_tabwidgetengine_h
|
||||
#define tdegtk_tabwidgetengine_h
|
||||
/*
|
||||
* this file was largely taken from the oxygen gtk engine
|
||||
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
|
||||
*
|
||||
* 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-genericengine.h"
|
||||
#include "tdegtk-datamap.h"
|
||||
#include "tdegtk-tabwidgetdata.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//! forward declaration
|
||||
class Animations;
|
||||
|
||||
//! stores data associated to editable tabwidgetes
|
||||
/*!
|
||||
ensures that the text entry and the button of editable tabwidgetes
|
||||
gets hovered and focus flags at the same time
|
||||
*/
|
||||
class TabWidgetEngine: public GenericEngine<TabWidgetData>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
TabWidgetEngine( Animations* widget ):
|
||||
GenericEngine<TabWidgetData>( widget )
|
||||
{}
|
||||
|
||||
//! destructor
|
||||
virtual ~TabWidgetEngine( void )
|
||||
{}
|
||||
|
||||
//!@name modifiers
|
||||
//@{
|
||||
|
||||
//! returns hovered tab, if any
|
||||
void updateTabRect( GtkWidget* widget, int index, int x, int y, int w, int h )
|
||||
{
|
||||
GdkRectangle local = { x, y, w, h };
|
||||
return data().value( widget ).updateTabRect( widget, index, local );
|
||||
}
|
||||
|
||||
//! returns hovered tab, if any
|
||||
void updateTabRect( GtkWidget* widget, int index, const GdkRectangle& r )
|
||||
{ return data().value( widget ).updateTabRect( widget, index, r ); }
|
||||
|
||||
//! returns hovered tab, if any
|
||||
void updateHoveredTab( GtkWidget* widget )
|
||||
{ return data().value( widget ).updateHoveredTab( widget ); }
|
||||
|
||||
//! true when drag is in progress
|
||||
void setDragInProgress( GtkWidget* widget, bool value )
|
||||
{ data().value( widget ).setDragInProgress( value ); }
|
||||
|
||||
//! toggle dirty state
|
||||
void toggleDirty( GtkWidget* widget )
|
||||
{ data().value( widget ).toggleDirty(); }
|
||||
|
||||
//! true when tabbar is dirty
|
||||
void setDirty( GtkWidget* widget, bool value )
|
||||
{ data().value( widget ).setDirty( value ); }
|
||||
|
||||
//@}
|
||||
|
||||
//!@name accessors
|
||||
//@{
|
||||
|
||||
//! returns hovered tab, if any
|
||||
int hoveredTab( GtkWidget* widget )
|
||||
{ return data().value( widget ).hoveredTab(); }
|
||||
|
||||
//! returns true if provided point is in one tab of the widget
|
||||
bool isInTab( GtkWidget* widget, int x, int y )
|
||||
{ return data().value( widget ).isInTab( x, y ); }
|
||||
|
||||
//! true when drag is in progress
|
||||
bool dragInProgress( GtkWidget* widget )
|
||||
{ return data().value( widget ).dragInProgress(); }
|
||||
|
||||
//! true when tabbar is dirty
|
||||
bool isDirty( GtkWidget* widget )
|
||||
{ return data().value( widget ).isDirty(); }
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in new issue