Browse Source

A few widgets are now working somewhat

tags/r14.0.0
Timothy Pearson 7 years ago
parent
commit
0bf8ed2645
18 changed files with 4332 additions and 1124 deletions
  1. +12
    -3
      tdegtk/Makefile.am
  2. +0
    -1062
      tdegtk/tdegtk-draw.c
  3. +1273
    -0
      tdegtk/tdegtk-draw.cpp
  4. +100
    -0
      tdegtk/tdegtk-hooks.cpp
  5. +63
    -0
      tdegtk/tdegtk-hooks.h
  6. +89
    -0
      tdegtk/tdegtk-signals.cpp
  7. +64
    -0
      tdegtk/tdegtk-signals.h
  8. +0
    -51
      tdegtk/tdegtk-theme.c
  9. +788
    -0
      tdegtk/tdegtk-theme.cpp
  10. +23
    -2
      tdegtk/tdegtk-types.h
  11. +1064
    -0
      tdegtk/tdegtk-utils.cpp
  12. +428
    -0
      tdegtk/tdegtk-utils.h
  13. +231
    -0
      tdegtk/tdegtk-widgetlookup.cpp
  14. +92
    -0
      tdegtk/tdegtk-widgetlookup.h
  15. +9
    -5
      tdegtk/tqtcairopainter.cpp
  16. +3
    -1
      tdegtk/tqtcairopainter.h
  17. +3
    -0
      tests/compare
  18. +90
    -0
      tests/test-painter.cpp

+ 12
- 3
tdegtk/Makefile.am View File

@@ -7,6 +7,10 @@ source_h = \
$(srcdir)/tdegtk-draw.h \
$(srcdir)/tdegtk-engine.h \
$(srcdir)/tdegtk-support.h \
$(srcdir)/tdegtk-hooks.h \
$(srcdir)/tdegtk-signals.h \
$(srcdir)/tdegtk-widgetlookup.h \
$(srcdir)/tdegtk-utils.h \
$(srcdir)/tdegtk-types.h

source_c = \
@@ -14,10 +18,14 @@ source_c = \
$(srcdir)/gtkroundedbox.c \
$(srcdir)/raico-blur.c \
$(srcdir)/tdegtk-cairo-support.c \
$(srcdir)/tdegtk-draw.c \
$(srcdir)/tdegtk-draw.cpp \
$(srcdir)/tdegtk-engine.c \
$(srcdir)/tdegtk-support.c \
$(srcdir)/tdegtk-theme.c
$(srcdir)/tdegtk-hooks.cpp \
$(srcdir)/tdegtk-signals.cpp \
$(srcdir)/tdegtk-widgetlookup.cpp \
$(srcdir)/tdegtk-utils.cpp \
$(srcdir)/tdegtk-theme.cpp

enginedir = $(libdir)/gtk-3.0/$(GTK_VERSION)/theming-engines
engine_LTLIBRARIES = libtdegtk.la
@@ -25,8 +33,9 @@ engine_LTLIBRARIES = libtdegtk.la
libtdegtk_la_SOURCES = $(source_h) $(source_c)

libtdegtk_la_CFLAGS = $(TDEGTK_CFLAGS)
libtdegtk_la_CXXFLAGS = $(TDEGTK_CXXFLAGS) -I/usr/include/tqt -I/usr/include/tqt3 -I/opt/trinity/include $(TDEGTK_CFLAGS)

libtdegtk_la_LIBADD = $(TDEGTK_LIBADD)
libtdegtk_la_LIBADD = $(TDEGTK_LIBADD) libtqtcairo.la -ltqt -ltqt-mt -L/opt/trinity/lib -ltdecore

libtdegtk_la_LDFLAGS = $(TDEGTK_LDFLAGS)



+ 0
- 1062
tdegtk/tdegtk-draw.c
File diff suppressed because it is too large
View File


+ 1273
- 0
tdegtk/tdegtk-draw.cpp
File diff suppressed because it is too large
View File


+ 100
- 0
tdegtk/tdegtk-hooks.cpp View File

@@ -0,0 +1,100 @@
/*
* 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-hooks.h"
#include "../config.h"

#include <cassert>
#include <iostream>

#if TDEGTK_DEBUG
static int counter( 0 );
#endif

//__________________________________________________________________
bool Hook::connect( const std::string& signal, GType typeId, GSignalEmissionHook hookFunction, gpointer data )
{
// make sure that signal is not already connected
assert( _signalId == 0 && _hookId == 0 );

// check type id
if( !g_type_class_peek( typeId ) )
{

#if TDEGTK_DEBUG
std::cerr << "Oxygen::Hook::connect - typeId " << g_type_name(typeId) << " not yet installed" << std::endl;
#endif

g_type_class_ref( typeId );

}

// store signal id
_signalId = g_signal_lookup( signal.c_str(), typeId );
if( !_signalId )
{

#if TDEGTK_DEBUG
std::cerr << "Oxygen::Hook::connect - signal " << signal << " not installed." << std::endl;
#endif

return false;

}

// store attributes and create connection
_hookId = g_signal_add_emission_hook(
_signalId,
(GQuark)0L,
hookFunction,
data, 0L);

#if TDEGTK_DEBUG
++counter;
std::cerr << "Oxygen::Hook::connect - hook: " << _hookId << " counter: " << counter << std::endl;
#endif

return true;

}

//____________________________________________________________________
void Hook::disconnect( void )
{

// disconnect signal
if( _signalId > 0 && _hookId > 0 )
{

#if TDEGTK_DEBUG
--counter;
std::cerr << "Oxygen::Hook::disconnect - hook: " << _hookId << " counter: " << counter << std::endl;
#endif

g_signal_remove_emission_hook( _signalId, _hookId );

}

_signalId = 0;
_hookId = 0;

}


+ 63
- 0
tdegtk/tdegtk-hooks.h View File

@@ -0,0 +1,63 @@
#ifndef tdegtk_hooks_h
#define tdegtk_hooks_h
/*
* 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 <gtk/gtk.h>
#include <string>


//! handles gtk signal hooks
class Hook
{
public:

//! constructor
Hook( void ):
_signalId(0),
_hookId(0)
{}

//! destructor
virtual ~Hook( void )
{}



//! connect
bool connect( const std::string&, GType, GSignalEmissionHook, gpointer );

bool connect( const std::string& signal, GSignalEmissionHook hook, gpointer data )
{ return connect( signal, GTK_TYPE_WIDGET, hook, data ); }

//! disconnect
void disconnect( void );

private:

//! signal id
guint _signalId;
gulong _hookId;

};

#endif


+ 89
- 0
tdegtk/tdegtk-signals.cpp View File

@@ -0,0 +1,89 @@

/*
* 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 "../config.h"

#include <iostream>


#if OXYGEN_DEBUG
static int counter( 0 );
#endif

//____________________________________________________________________
bool Signal::connect( GObject* object, const std::string& signal, GCallback callback, gpointer data, bool after )
{
// make sure that signal is not already connected
assert( _object == 0L && _id == 0 );

// check object
if( !object ) return false;

// first try lookup signal
if( !g_signal_lookup( signal.c_str(), G_OBJECT_TYPE(object) ) )
{

#if OXYGEN_DEBUG
std::cerr << "Oxygen::Signal::connect - signal " << signal << " not installed on widget " << object << std::endl;
#endif

return false;

}

// store attributes and create connection
_object = object;
if(after) _id = g_signal_connect_after( object, signal.c_str(), callback, data );
else _id = g_signal_connect( object, signal.c_str(), callback, data );

#if OXYGEN_DEBUG
++counter;
std::cerr << "Oxygen::Signal::connect - _id: " << _id << " counter: " << counter << std::endl;
#endif

return true;

}

//____________________________________________________________________
void Signal::disconnect( void )
{

// disconnect signal
if( _object && _id > 0 )
{

#if OXYGEN_DEBUG
--counter;
std::cerr << "Oxygen::Signal::disconnect - _id: " << _id << " counter: " << counter << std::endl;
#endif

g_signal_handler_disconnect( _object, _id );

}

// reset members
_object = 0L;
_id = 0;

}


+ 64
- 0
tdegtk/tdegtk-signals.h View File

@@ -0,0 +1,64 @@
#ifndef tdegtk_signal_h
#define tdegtk_signal_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 <cassert>
#include <string>

//! handles gtk signal connections
class Signal
{
public:

//! constructor
Signal( void ):
_id(0),
_object(0L)
{}

//! destructor
virtual ~Signal( void )
{}

//! true if connected
bool isConnected( void ) const
{ return _id > 0 && _object; }

//! connect
bool connect( GObject*, const std::string&, GCallback, gpointer, bool after=false );

//! disconnect
void disconnect( void );

private:

//! signal id
guint _id;

//! connected object
GObject* _object;

};

#endif


+ 0
- 51
tdegtk/tdegtk-theme.c View File

@@ -1,51 +0,0 @@
/* The TdeGtk Theming Engine for Gtk+.
* Copyright (C) 2011 Canonical Ltd
*
* 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.
*
* Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
*
*/

#include <gmodule.h>
#include <gtk/gtk.h>

#include "tdegtk-engine.h"

G_MODULE_EXPORT void theme_init (GTypeModule *module);

G_MODULE_EXPORT void theme_exit (void);

G_MODULE_EXPORT GtkThemingEngine* create_engine (void);

G_MODULE_EXPORT void
theme_init (GTypeModule *module)
{
tdegtk_engine_register_types (module);
}

G_MODULE_EXPORT void
theme_exit (void)
{
}

G_MODULE_EXPORT GtkThemingEngine*
create_engine (void)
{
return GTK_THEMING_ENGINE (g_object_new (TDEGTK_TYPE_ENGINE,
"name", "tdegtk",
NULL));
}

+ 788
- 0
tdegtk/tdegtk-theme.cpp View File

@@ -0,0 +1,788 @@
/* The TdeGtk Theming Engine for Gtk+.
* Copyright (C) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
*
* 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.
*
*/

#define TDEGTK_THEME_THEME_DIRECTORY_NAME "tdegtk"
#define TDEGTK_THEME_CONTROL_FILE_NAME "gtk.css"
#define RC_CACHE_VERSION TQString("1")
#define DEBUG_PRINT(x) if (gtk3TQtDebug) printf(x"\n\r");
#define DEBUG_PRINT_ARGS(x,y) if (gtk3TQtDebug) printf(x"\n\r",y);

bool gtk3TQtEnable = false;
int gtk3TQtDebug = false;
bool tde_showIconsOnPushButtons = false;

void initTDESettings();
void writeGtkThemeControlFile(int forceRecreate);

extern "C" {
#include <gmodule.h>
#include <gtk/gtk.h>
#include "tdegtk-engine.h"
G_MODULE_EXPORT void theme_init(GTypeModule *module);
G_MODULE_EXPORT void theme_exit(void);
G_MODULE_EXPORT GtkThemingEngine* create_engine(void);
G_MODULE_EXPORT void theme_init(GTypeModule *module) {
tdegtk_engine_register_types(module);
}
G_MODULE_EXPORT void theme_exit(void) {
//
}
}

#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utility>
#include <vector>
#include <fstream>
#include <sstream>

#include <tqpainter.h>
#include <tqapplication.h>
#include <tqdir.h>
#include <tqfile.h>
#include <tqstyle.h>
#include <tqslider.h>
#include <tqscrollbar.h>
#include <tqregexp.h>
#include <tqfont.h>

#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kglobalsettings.h>

#include <gdk/gdkx.h>

#include "tdegtk-widgetlookup.h"

extern WidgetLookup m_widgetLookup;

typedef std::pair<std::string, unsigned int> SizePair;
typedef std::vector<SizePair> SizeMap;
SizeMap icon_sizes;

G_MODULE_EXPORT GtkThemingEngine* create_engine(void) {
gtk3TQtEnable = true;

gtk3TQtDebug = (getenv("GTK3_TQT_ENGINE_DEBUG") != NULL) ? 1 : 0;
DEBUG_PRINT("Creating KApplication")

int argc = 1;
char** argv;
// Supply it with fake data to keep KApplication happy
argv = (char**) malloc(sizeof(char*));
argv[0] = (char*) malloc(sizeof(char) * 21);
strncpy(argv[0], "gtk3-tqt-application", 21);

KAboutData aboutData("gtk3-tqt-engine", I18N_NOOP("gtk3-tqt-engine"), "v0.1",
"GTK3 TQt theme engine", KAboutData::License_GPL,
"(c) 2012, Timothy Pearson",
"", 0 /* TODO: Website */, "kb9vqf@pearsoncomputing.net");
KCmdLineArgs::init(argc, const_cast<char**>(argv), &aboutData);

KApplication::disableAutoDcopRegistration();
new KApplication(gdk_x11_get_default_xdisplay(), true, 0, 0, true);

initTDESettings();

// initialize icon sizes
icon_sizes.push_back(std::make_pair("panel-menu", 16));
icon_sizes.push_back(std::make_pair("panel", 32));
icon_sizes.push_back(std::make_pair("gtk-small-toolbar", 22));
icon_sizes.push_back(std::make_pair("gtk-large-toolbar", 22));
icon_sizes.push_back(std::make_pair("gtk-dnd", 48));
icon_sizes.push_back(std::make_pair("gtk-button", 16));
icon_sizes.push_back(std::make_pair("gtk-menu", 16));
icon_sizes.push_back(std::make_pair("gtk-dialog", 32));
icon_sizes.push_back(std::make_pair("", 16));

writeGtkThemeControlFile(false);

// Initialize hooks
m_widgetLookup.initializeHooks();

return GTK_THEMING_ENGINE (g_object_new (TDEGTK_TYPE_ENGINE, "name", "tdegtk", NULL));
}

// =========================================================================================================
//
// TQt3/GTK Theme Control Functions
//
// =========================================================================================================

TQStringList tdeSearchPaths;
TQString iconTheme;
TQStringList iconThemeDirs;
TQColor alternateBackgroundColour;
int showIconsOnButtons;
int toolbarStyle;

TQString tdeConfigValue(const TQString& section, const TQString& name, const TQString& def) {
KConfig currentConfig;
currentConfig.setGroup(section);
return currentConfig.readEntry(name, def);
}

bool tdeBoolConfigValue(const TQString& section, const TQString& name, bool def) {
KConfig currentConfig;
currentConfig.setGroup(section);
return currentConfig.readBoolEntry(name, def);
}

TQString tdeFindDir(const TQString& suffix, const TQString& file1, const TQString& file2) {
for ( TQStringList::Iterator it = tdeSearchPaths.begin(); it != tdeSearchPaths.end(); ++it )
{
if ((TQFile::exists((*it) + suffix + file1)) || (TQFile::exists((*it) + suffix + file2)))
return (*it) + suffix;
}
return TQString();
}

TQString runCommand(const TQString& command) {
FILE* p = popen(command.latin1(), "r");
if ((p == NULL) || (p < 0))
return TQString();
TQString ret;
while (!feof(p))
{
char buffer[256];
int n = fread(buffer, 1, 255, p);
buffer[n] = '\0';
ret += buffer;
}
pclose(p);
return ret.stripWhiteSpace();
}

void initTDESettings() {
tdeSearchPaths.clear();
TQString tdeHome = getenv("TDEHOME");
TQString tdeDirs = getenv("TDEDIRS");
TQString tdeDir = getenv("TDEDIR");
if (!tdeHome.isEmpty()) {
tdeSearchPaths.append(tdeHome);
}
tdeSearchPaths.append(runCommand("tde-config --localprefix"));
if (!tdeDirs.isEmpty()) {
tdeSearchPaths += TQStringList::split(':', tdeDirs);
}
if (!tdeDir.isEmpty()) {
tdeSearchPaths.append(tdeDir);
}
tdeSearchPaths.append(runCommand("tde-config --prefix"));
iconTheme = tdeConfigValue("Icons", "Theme", "crystalsvg");
tde_showIconsOnPushButtons = tdeBoolConfigValue("KDE", "ShowIconsOnPushButtons", false);

TQStringList back = TQStringList::split(',', tdeConfigValue("General", "alternateBackground", "238,246,255"));
alternateBackgroundColour.setRgb(back[0].toInt(), back[1].toInt(), back[2].toInt());

showIconsOnButtons = (tdeConfigValue("KDE", "ShowIconsOnPushButtons", "true").lower() == "true");

TQString tmp = tdeConfigValue("Toolbar style", "IconText", "true").lower();
if (tmp == "icononly") {
toolbarStyle = 0;
}
else if (tmp == "icontextright") {
toolbarStyle = 3;
}
else if (tmp == "textonly") {
toolbarStyle = 1;
}
else if (tmp == "icontextbottom") {
toolbarStyle = 2;
}
else {
// Should never happen, but just in case we fallback to TDE's default "icononly"
toolbarStyle = 0;
}
}

void gtk3_tqt_load_resource_string(const char* css_string) {
GtkCssProvider *provider;

provider = gtk_css_provider_new();
gtk_css_provider_load_from_data(provider, css_string, -1, NULL);
GdkDisplay *display = gdk_display_get_default();
GdkScreen *screen = gdk_display_get_default_screen(display);
gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref(provider);

DEBUG_PRINT_ARGS("gtk3_tqt_load_resource_string(%s)", css_string)
}

void gtk3_tqt_reload_theme_definition_file(const char* filename) {
GtkCssProvider *provider;
GError *error;

provider = gtk_css_provider_new();
GdkDisplay *display = gdk_display_get_default();
GdkScreen *screen = gdk_display_get_default_screen(display);
gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref(provider);
if (!gtk_css_provider_load_from_path(provider, filename, &error)) {
g_printerr("%s: error parsing %s: %s\n", G_STRFUNC, filename, error->message);
g_clear_error(&error);
}
}

TQString tdeFontToGTKFontString(TQFont font) {
TQString fontDescriptor = "font: ";
fontDescriptor.append(font.family());
if (font.bold()) {
fontDescriptor.append(" bold");
}
if (font.italic()) {
fontDescriptor.append(" italic");
}
if (font.pointSizeFloat() != -1) {
fontDescriptor.append(TQString(" %1").arg(font.pointSizeFloat()));
}
else {
fontDescriptor.append(TQString(" %1px").arg(font.pixelSize()));
}

return fontDescriptor;
}

// Thanks Martin Dvorak of metatheme
TQString parse_rc_string(const TQString& defs, const TQString& pattern, bool widgetClass = true) {
static int dynamic_counter = 0;
++dynamic_counter;

return pattern + " {\n\t" + defs + ";\n}\n\n";
}

GtkIconSet* generateIconSet(const std::string& gtkIconName, const std::string& tdeIconName, TQStringList pathList) {
if (tdeIconName == "NONE") {
return 0L;
}
bool empty = true;
// create iconSet
GtkIconSet* iconSet = gtk_icon_set_new();

// loop over iconSizes
for (SizeMap::const_iterator sizeIter = icon_sizes.begin(); sizeIter != icon_sizes.end(); ++sizeIter) {
// generate full icon name
std::ostringstream iconFileStream;
iconFileStream << sizeIter->second << "x" << sizeIter->second << "/" << tdeIconName;

// loop over provided path to see if at least one icon is found
for (TQStringList::const_iterator pathIter = pathList.begin(); pathIter != pathList.end(); ++pathIter) {
std::string filename((*pathIter + '/' + iconFileStream.str()).latin1());
if (!std::ifstream(filename.c_str())) {
continue;
}

empty = false;
GtkIconSource* iconSource(gtk_icon_source_new());
// set name
gtk_icon_source_set_filename(iconSource, filename.c_str());

// set direction and state wildcarded
gtk_icon_source_set_direction_wildcarded(iconSource, TRUE);
gtk_icon_source_set_state_wildcarded(iconSource, TRUE);

// set size
if (sizeIter->first.empty()) {
gtk_icon_source_set_size_wildcarded(iconSource, TRUE);
}
else {
GtkIconSize size = gtk_icon_size_from_name(sizeIter->first.c_str());
if (size != GTK_ICON_SIZE_INVALID) {
gtk_icon_source_set_size_wildcarded(iconSource, FALSE);
gtk_icon_source_set_size(iconSource, size);
}
}

// add source to iconSet
gtk_icon_set_add_source(iconSet, iconSource);
break;
}
}

// if nothing found, return;
if (empty) {
gtk_icon_set_unref(iconSet);
return 0L;
}
else {
return iconSet;
}

}

void doIconMapping(const char* gtkName, const char * tdeName, GtkIconFactory* factory, TQStringList tdeIconThemeDirs) {
GtkIconSet* iconSet = generateIconSet(gtkName, tdeName, tdeIconThemeDirs);
if (iconSet) {
gtk_icon_factory_add(factory, gtkName, iconSet);
gtk_icon_set_unref(iconSet);
}
}

TQString colorString(TQColor color) {
TQString ret = "rgb(";
ret += TQString::number(color.red()) + ", ";
ret += TQString::number(color.green()) + ", ";
ret += TQString::number(color.blue()) + ")";
return ret;
}

void setColour(TQString name, TQString state, TQColor color) {
state = ":" + state;
if (state == ":normal") {
state = "";
}
gtk3_tqt_load_resource_string(parse_rc_string(name + ": " + colorString(color), "*" + state).latin1());
}

static TQStringList iconInheritsDirs(const TQString& icondir) {
TQFile index;
index.setName(icondir + "index.theme");
if( !index.open( IO_ReadOnly )) {
index.setName(icondir + "index.desktop");
if( !index.open( IO_ReadOnly ))
return TQStringList();
}
char buf[1024];
TQRegExp reg( "^\\s*Inherits=([^\\n]*)" );
for(;;) {
if( index.readLine(buf, 1023) <= 0 ) {
break;
}
if( reg.search(buf, 0) >= 0 ) {
return TQStringList::split(",", reg.cap(1));
}
}
return TQStringList();
}

void addIconThemeDir(const TQString& theme) {
// Try to find this theme's directory
TQString icondir = tdeFindDir("/share/icons/" + theme + "/", "index.theme", "index.desktop");
if(icondir.isEmpty()) {
return;
}
if (iconThemeDirs.contains(icondir)) {
return;
}

// Add this theme to the list
iconThemeDirs.append(icondir);

// Do it again for any parent themes
TQStringList parents = iconInheritsDirs(icondir);
for ( TQStringList::Iterator it=parents.begin() ; it!=parents.end(); ++it) {
addIconThemeDir((*it).stripWhiteSpace());
}
}

void writeGtkThemeControlFile(int forceRecreate) {
if (!gtk3TQtEnable) {
return;
}
DEBUG_PRINT("writeGtkThemeControlFile()")
// Set colors
// Normal
setColour("color", "normal", tqApp->palette().active().text());
setColour("background-color", "normal", tqApp->palette().active().background());
// setColour("text", "normal", tqApp->palette().active().text());
// setColour("base", "normal", tqApp->palette().active().base());

// Active (on)
setColour("color", "active", tqApp->palette().active().text());
setColour("background-color", "active", tqApp->palette().active().background());
// setColour("text", "active", tqApp->palette().active().text());
// setColour("base", "active", tqApp->palette().active().base());

// Mouseover
setColour("color", "prelight", tqApp->palette().active().text()); // menu items - change?
setColour("background-color", "prelight", tqApp->palette().active().highlight());
// setColour("text", "prelight", tqApp->palette().active().text());
// setColour("base", "prelight", tqApp->palette().active().base());

// Selected
setColour("color", "selected", tqApp->palette().active().highlightedText());
setColour("background-color", "selected", tqApp->palette().active().highlight());
// setColour("text", "selected", tqApp->palette().active().highlightedText());
// setColour("base", "selected", tqApp->palette().active().highlight());

// Disabled
setColour("color", "insensitive", tqApp->palette().disabled().text());
setColour("background-color", "insensitive", tqApp->palette().disabled().background());
// setColour("text", "insensitive", tqApp->palette().disabled().text());
// setColour("base", "insensitive", tqApp->palette().disabled().background());

// Set up global application settings
GtkSettings* gtksettings = gtk_settings_get_default();
GtkSettingsValue svalue;
if (gtksettings) {
g_object_set(gtksettings, "gtk-alternative-button-order", TRUE, NULL);
g_object_set(gtksettings, "gtk-button-images", tde_showIconsOnPushButtons, NULL);
g_object_set(gtksettings, "gtk-menu-popup-delay", tqApp->style().styleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay), NULL);
// Handle toolbar text display
if (toolbarStyle == 3) {
// This is broken by GTK bug #68700
g_object_set(gtksettings, "gtk-toolbar-style", GTK_TOOLBAR_BOTH_HORIZ, NULL);
}
else if (toolbarStyle == 2) {
g_object_set(gtksettings, "gtk-toolbar-style", GTK_TOOLBAR_BOTH, NULL);
}
else if (toolbarStyle == 1) {
g_object_set(gtksettings, "gtk-toolbar-style", GTK_TOOLBAR_TEXT, NULL);
}
else {
g_object_set(gtksettings, "gtk-toolbar-style", GTK_TOOLBAR_ICONS, NULL);
}
}

// This function takes quite a long time to execute, and is run at the start of every app.
// In order to speed it up, we can store the results in a file, along with the name of icon
// theme and style. This file can then be regenerated when the icon theme or style change.

TQDir curDir;
TQString themeFilePath = TQDir::homeDirPath();
curDir.setPath(themeFilePath);
if (!curDir.exists()) {
curDir.mkdir(themeFilePath);
}
themeFilePath = themeFilePath + "/.themes/";
curDir.setPath(themeFilePath);
if (!curDir.exists()) {
curDir.mkdir(themeFilePath);
}
themeFilePath = themeFilePath + TQString(TDEGTK_THEME_THEME_DIRECTORY_NAME) + "/";
curDir.setPath(themeFilePath);
if (!curDir.exists()) {
curDir.mkdir(themeFilePath);
}
themeFilePath = themeFilePath + "gtk-3.0/";
curDir.setPath(themeFilePath);
if (!curDir.exists()) {
curDir.mkdir(themeFilePath);
}

themeFilePath = themeFilePath + TDEGTK_THEME_CONTROL_FILE_NAME;
TQFile themeFile(themeFilePath);
TQTextStream stream;
if (!forceRecreate && themeFile.exists())
{
themeFile.open(IO_ReadOnly);
stream.setDevice(TQT_TQIODEVICE(&themeFile));
if (stream.readLine() == "/* " + iconTheme + ", " + tqApp->style().name() + ", " + RC_CACHE_VERSION + " */")
{
// This cache matches the current icon theme and style
gtk3_tqt_reload_theme_definition_file(themeFilePath.latin1());
return;
}
stream.unsetDevice();
themeFile.close();
}
themeFile.open(IO_WriteOnly | IO_Truncate);
stream.setDevice(TQT_TQIODEVICE(&themeFile));
stream << "/* " << iconTheme << ", " << tqApp->style().name() << ", " << RC_CACHE_VERSION << " */\n\n";
stream << "/* This file was generated by the Gtk TQt Theme Engine */\n";
stream << "/* It will be recreated when you change your TDE icon theme or widget style */\n\n";

stream << "\n";
stream << "* {\n\tengine:tdegtk;\n}\n";
stream << "\n";
TQScrollBar sbar(NULL);
sbar.setOrientation(TQt::Horizontal);
sbar.setValue(1);
sbar.resize(200,25);
// The following code determines how many buttons are on a scrollbar
// It works by looking at each pixel of the scrollbar's area not taken up by the groove,
// and asking the style which subcontrol is at that location.
TQRect rect = tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, &sbar, TQStyle::SC_ScrollBarGroove);
bool back1 = false;
bool forward1 = false;
bool back2 = false;
bool forward2 = false;
TQStyle::SubControl sc = TQStyle::SC_None;
for (TQPoint pos(0,7) ; pos.x()<rect.x() ; pos.setX(pos.x()+1))
{
TQStyle::SubControl sc2 = tqApp->style().querySubControl(TQStyle::CC_ScrollBar, &sbar, pos);
if (sc != sc2)
{
if (sc2 == TQStyle::SC_ScrollBarAddLine) forward1 = true;
if (sc2 == TQStyle::SC_ScrollBarSubLine) back1 = true;
sc = sc2;
}
}
sc = TQStyle::SC_None;
for (TQPoint pos(rect.x()+rect.width(),7) ; pos.x()<200 ; pos.setX(pos.x()+1))
{
TQStyle::SubControl sc2 = tqApp->style().querySubControl(TQStyle::CC_ScrollBar, &sbar, pos);
if (sc != sc2)
{
if (sc2 == TQStyle::SC_ScrollBarAddLine) forward2 = true;
if (sc2 == TQStyle::SC_ScrollBarSubLine) back2 = true;
sc = sc2;
}
}

bool combobox_appears_as_list = (!(tqApp->style().styleHint(TQStyle::SH_ComboBox_Popup) || tqApp->style().styleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle));
stream << parse_rc_string(TQString("-GtkComboBox-appears-as-list: %1px").arg(combobox_appears_as_list), "*");

stream << parse_rc_string(TQString("-GtkScrollbar-has-backward-stepper: ") + (back1 ? "1" : "0"), "*");
stream << parse_rc_string(TQString("-GtkScrollbar-has-forward-stepper: ") + (forward2 ? "1" : "0"), "*");
stream << parse_rc_string(TQString("-GtkScrollbar-has-secondary-forward-stepper: ") + (forward1 ? "1" : "0"), "*");
stream << parse_rc_string(TQString("-GtkScrollbar-has-secondary-backward-stepper: ") + (back2 ? "1" : "0"), "*");

stream << parse_rc_string("-GtkScrollbar-stepper-size: " + TQString::number(tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, &sbar, TQStyle::SC_ScrollBarSubLine).width() - 1), "*");

stream << parse_rc_string("-GtkScrollbar-min-slider-length: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ScrollBarSliderMin)), "*");
stream << parse_rc_string("-GtkScrollbar-slider-width: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ScrollBarExtent)-2), "*");

stream << parse_rc_string("-GtkButton-child-displacement-x: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ButtonShiftHorizontal)), "*");
stream << parse_rc_string("-GtkButton-child-displacement-y: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ButtonShiftVertical)), "*");
stream << parse_rc_string("-GtkButton-default-border: 0 0 0 0", "*");
stream << parse_rc_string("-GtkButton-default-outside-border: 0 0 0 0", "*");
#ifdef USE_NATIVE_GTK_BUTTON_DRAWING
stream << parse_rc_string("-GtkButton-inner-border: 2 2 2 2", "*");
#else
if (tde_showIconsOnPushButtons) {
stream << parse_rc_string("-GtkButton-inner-border: 10 10 2 2", "*"); // Allow space for the icon on either side of the text
}
else {
stream << parse_rc_string("-GtkButton-inner-border: 2 2 2 2", "*");
}
#endif

stream << parse_rc_string("-GtkButtonBox-child_min_height: 0", "*");
stream << parse_rc_string("-GtkButtonBox-child_internal_pad_x: 0", "*");
stream << parse_rc_string("-GtkButtonBox-child_internal_pad_y: 0", "*");

TQSlider slider(NULL); // To keep BlueCurve happy
stream << parse_rc_string("-GtkScale-slider-length: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_SliderLength, &slider)), "*");

stream << parse_rc_string("-GtkRange-arrow-scaling: 1.0", "GtkScrollbar");

stream << parse_rc_string("-xthickness: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_DefaultFrameWidth)), "*.GtkMenu");
stream << parse_rc_string("-ythickness: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_DefaultFrameWidth)), "*.GtkMenu");
stream << parse_rc_string("-xthickness: 5", "*.GtkMenu.Gtk*MenuItem");
stream << parse_rc_string("-xthickness: 3", "*.GtkNotebook");
stream << parse_rc_string("-ythickness: 3", "*.GtkNotebook");
stream << parse_rc_string("-ythickness: 1", "*.GtkButton");
stream << parse_rc_string("-color: " + colorString(TQColor(0,0,0)), "gtk-tooltips.GtkLabel", false);

stream << parse_rc_string("-xthickness: 1", "*.GtkButton.*");
stream << parse_rc_string("-ythickness: 1", "*.GtkButton.*");

// stream << parse_rc_string("GtkTreeView::allow-rules = 0", "*");
// stream << parse_rc_string("GtkTreeView::tree-line-width = 1", "*");
// stream << parse_rc_string("GtkTreeView::vertical-separator = 30", "*");
// //stream << parse_rc_string("GtkTreeView::odd-row-color = { 0.0, 0.0, 0.0 }", "*");

stream << parse_rc_string("-GtkButton-inner-border: 0 0 0 0", "*GtkToolbar*GtkButton*");
stream << parse_rc_string("-GtkButton-inner-border: 0 0 0 0", "*GtkToolbar*GtkToggleButton*");
stream << parse_rc_string("-GtkButton-inner-border: 0 0 0 0", "*GtkNotebook*GtkButton*");
stream << parse_rc_string("-GtkButton-inner-border: 0 0 0 0", "*GtkNotebook*GtkToggleButton*");

// TQt calls them tab boxes, GTK calls them notebooks (!??!?) Either way they are a pain...
//stream << parse_rc_string("-GtkNotebook-tab-overlap: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_TabBarTabOverlap)), "*");
stream << parse_rc_string("-GtkNotebook-tab-overlap: 0", "*"); // Overlap is handled in the style engine itself
stream << parse_rc_string("-GtkNotebook-tab-curvature: 0", "*");

// This sets both the radio button and check box sizes
stream << parse_rc_string("-GtkCheckButton-indicator-size: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_IndicatorHeight)), "*");

// FIXME
// GtkCellRendererToggle indicator-size must be set as follows, however GTK3 does not provide any means to change the default size!
// See upstream GTK bug #687076
//stream << parse_rc_string("-GtkCellRendererToggle-indicator-size: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_IndicatorHeight)), "*");

// FIXME
// There must be a way to set the selected tab offset (shift)
// If not, it may be neccessary to override the GTK text drawing routines for notebooks to insert the proper shift
//stream << parse_rc_string("-????: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_TabBarTabShiftHorizontal)), "*");

stream << parse_rc_string("-GtkButton-child-displacement-x: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ButtonShiftHorizontal)), "*");
stream << parse_rc_string("-GtkButton-child-displacement-y: " + TQString::number(tqApp->style().pixelMetric(TQStyle::PM_ButtonShiftVertical)), "*");

// Set up fonts
TQFont generalFont = KGlobalSettings::generalFont();
TQFont toolBarFont = KGlobalSettings::toolBarFont();
TQFont menuFont = KGlobalSettings::menuFont();
// TQFont windowTitleFont = KGlobalSettings::windowTitleFont();
// TQFont taskbarFont = KGlobalSettings::taskbarFont();
stream << parse_rc_string(tdeFontToGTKFontString(generalFont), "*");
stream << parse_rc_string(tdeFontToGTKFontString(toolBarFont), "*GtkToolbar*GtkButton*");
stream << parse_rc_string(tdeFontToGTKFontString(menuFont), "*.GtkMenu");

// Set up icons
// Build the list of icon theme directories.
// This function is recursive - it gets the directories of all the inherited themes as well
addIconThemeDir(iconTheme);

if (iconThemeDirs.isEmpty()) {
themeFile.close();
if (!forceRecreate) {
gtk3_tqt_reload_theme_definition_file(themeFilePath.latin1());
}
return;
}

GtkIconFactory* factory;
factory = gtk_icon_factory_new();

doIconMapping("gtk-about", "actions/about_kde.png", factory, iconThemeDirs);
doIconMapping("gtk-add", "actions/add.png", factory, iconThemeDirs);
doIconMapping("gtk-apply", "actions/apply.png", factory, iconThemeDirs);
doIconMapping("gtk-bold", "actions/text_bold.png", factory, iconThemeDirs);
doIconMapping("gtk-cancel", "actions/button_cancel.png", factory, iconThemeDirs);
doIconMapping("gtk-cdrom", "devices/cdrom_unmount.png", factory, iconThemeDirs);
doIconMapping("gtk-clear", "actions/editclear.png", factory, iconThemeDirs);
doIconMapping("gtk-close", "actions/fileclose.png", factory, iconThemeDirs);
doIconMapping("gtk-color-picker", "actions/colorpicker.png", factory, iconThemeDirs);
doIconMapping("gtk-copy", "actions/editcopy.png", factory, iconThemeDirs);
doIconMapping("gtk-convert", "actions/gtk-convert.png", factory, iconThemeDirs);
doIconMapping("gtk-connect", "actions/connect_creating.png", factory, iconThemeDirs);
doIconMapping("gtk-cut", "actions/editcut.png", factory, iconThemeDirs);
doIconMapping("gtk-delete", "actions/editdelete.png", factory, iconThemeDirs);
doIconMapping("gtk-dialog-authentication", "status/gtk-dialog-authentication", factory, iconThemeDirs);
doIconMapping("gtk-dialog-error", "actions/messagebox_critical.png", factory, iconThemeDirs);
doIconMapping("gtk-dialog-info", "actions/messagebox_info.png", factory, iconThemeDirs);
doIconMapping("gtk-dialog-question", "actions/help.png", factory, iconThemeDirs);
doIconMapping("gtk-dialog-warning", "actions/messagebox_warning.png", factory, iconThemeDirs);
doIconMapping("gtk-directory", "filesystems/folder.png", factory, iconThemeDirs);
doIconMapping("gtk-disconnect", "actions/connect_no.png", factory, iconThemeDirs);
doIconMapping("gtk-dnd", "mimetypes/empty.png", factory, iconThemeDirs);
doIconMapping("gtk-dnd-multiple", "mimetypes/kmultiple.png", factory, iconThemeDirs);
doIconMapping("gtk-edit", "actions/edit.png", factory, iconThemeDirs); //2.6
doIconMapping("gtk-execute", "actions/exec.png", factory, iconThemeDirs);
doIconMapping("gtk-file", "mimetypes/empty.png", factory, iconThemeDirs);
doIconMapping("gtk-find", "actions/find.png", factory, iconThemeDirs);
doIconMapping("gtk-find-and-replace", "actions/find.png", factory, iconThemeDirs); // Is there a TDE "find and replace" icon? FIXME
doIconMapping("gtk-floppy", "devices/3floppy_unmount.png", factory, iconThemeDirs);
doIconMapping("gtk-fullscreen", "actions/window-fullscreen.png", factory, iconThemeDirs);
doIconMapping("gtk-goto-bottom", "actions/bottom.png", factory, iconThemeDirs);
doIconMapping("gtk-goto-first", "actions/start.png", factory, iconThemeDirs);
doIconMapping("gtk-goto-last", "actions/finish.png", factory, iconThemeDirs);
doIconMapping("gtk-goto-top", "actions/top.png", factory, iconThemeDirs);
doIconMapping("gtk-go-back", "actions/back.png", factory, iconThemeDirs);
doIconMapping("gtk-go-down", "actions/down.png", factory, iconThemeDirs);
doIconMapping("gtk-go-forward", "actions/forward.png", factory, iconThemeDirs);
doIconMapping("gtk-go-up", "actions/up.png", factory, iconThemeDirs);
doIconMapping("gtk-harddisk", "devices/hdd_unmount.png", factory, iconThemeDirs);
doIconMapping("gtk-help", "apps/khelpcenter.png", factory, iconThemeDirs);
doIconMapping("gtk-home", "filesystems/folder_home.png", factory, iconThemeDirs);
doIconMapping("gtk-indent", "actions/indent.png", factory, iconThemeDirs);
doIconMapping("gtk-index", "actions/contents.png", factory, iconThemeDirs);
doIconMapping("gtk-info", "actions/messagebox_info.png", factory, iconThemeDirs);
doIconMapping("gtk-italic", "actions/text_italic.png", factory, iconThemeDirs);
doIconMapping("gtk-jump-to", "actions/goto.png", factory, iconThemeDirs);
doIconMapping("gtk-justify-center", "actions/text_center.png", factory, iconThemeDirs);
doIconMapping("gtk-justify-fill", "actions/text_block.png", factory, iconThemeDirs);
doIconMapping("gtk-justify-left", "actions/text_left.png", factory, iconThemeDirs);
doIconMapping("gtk-justify-right", "actions/text_right.png", factory, iconThemeDirs);
doIconMapping("gtk-leave-fullscreen", "actions/window-nofullscreen.png", factory, iconThemeDirs);
doIconMapping("gtk-media-forward", "player-fwd.png", factory, iconThemeDirs);
doIconMapping("gtk-media-next", "actions/player-end.png", factory, iconThemeDirs);
doIconMapping("gtk-media-pause", "actions/player-pause.png", factory, iconThemeDirs);
doIconMapping("gtk-media-previous", "actions/player-start.png", factory, iconThemeDirs);
doIconMapping("gtk-media-record", "actions/gtk-media-record.png", factory, iconThemeDirs); // FIXME
doIconMapping("gtk-media-rewind", "actions/player-rew.png", factory, iconThemeDirs);
doIconMapping("gtk-media-stop", "actions/player-stop.png", factory, iconThemeDirs);
doIconMapping("gtk-missing-image", "mimetypes/unknown.png", factory, iconThemeDirs);
doIconMapping("gtk-network", "filesystems/network.png", factory, iconThemeDirs);
doIconMapping("gtk-new", "actions/filenew.png", factory, iconThemeDirs);
doIconMapping("gtk-no", "actions/gtk-no.png", factory, iconThemeDirs);
doIconMapping("gtk-ok", "actions/button_ok.png", factory, iconThemeDirs);
doIconMapping("gtk-open", "actions/fileopen.png", factory, iconThemeDirs);
//doIconMapping("gtk-orientation-landscape", factory, iconThemeDirs); // FIXME
//doIconMapping("gtk-orientation-portrait", factory, iconThemeDirs); // FIXME
//doIconMapping("gtk-orientation-reverse-landscape", factory, iconThemeDirs); // FIXME
//doIconMapping("gtk-orientation-reverse-portrait"", factory, iconThemeDirs); // FIXME
doIconMapping("gtk-paste", "actions/editpaste.png", factory, iconThemeDirs);
doIconMapping("gtk-preferences", "actions/configure.png", factory, iconThemeDirs);
doIconMapping("gtk-print", "actions/fileprint.png", factory, iconThemeDirs);
doIconMapping("gtk-print-preview", "actions/filequickprint.png", factory, iconThemeDirs);
doIconMapping("gtk-properties", "actions/configure.png", factory, iconThemeDirs);
doIconMapping("gtk-quit", "actions/exit.png", factory, iconThemeDirs);
doIconMapping("gtk-redo", "actions/redo.png", factory, iconThemeDirs);
doIconMapping("gtk-refresh", "actions/reload.png", factory, iconThemeDirs);
doIconMapping("gtk-remove", "actions/remove.png", factory, iconThemeDirs);
doIconMapping("gtk-revert-to-saved", "actions/revert.png", factory, iconThemeDirs);
doIconMapping("gtk-save", "actions/filesave.png", factory, iconThemeDirs);
doIconMapping("gtk-save-as", "actions/filesaveas.png", factory, iconThemeDirs);
doIconMapping("gtk-select-all", "actions/gtk-select-all.png", factory, iconThemeDirs); // FIXME
doIconMapping("gtk-select-color", "actions/colorize.png", factory, iconThemeDirs);
doIconMapping("gtk-select-font", "mimetypes/font.png", factory, iconThemeDirs);
//doIconMapping("gtk-sort-ascending", "??", factory, iconThemeDirs); // FIXME
//doIconMapping("gtk-sort-descending", "??", factory, iconThemeDirs); // FIXME
doIconMapping("gtk-spell-check", "actions/spellcheck.png", factory, iconThemeDirs);
doIconMapping("gtk-stop", "actions/stop.png", factory, iconThemeDirs);
doIconMapping("gtk-strikethrough", "actions/text_strike.png", factory, iconThemeDirs);
doIconMapping("gtk-undelete", "actions/gtk-undelete.png", factory, iconThemeDirs); // FIXME
doIconMapping("gtk-underline", "actions/text_under.png", factory, iconThemeDirs);
doIconMapping("gtk-undo", "actions/undo.png", factory, iconThemeDirs);
doIconMapping("gtk-unindent", "actions/unindent.png", factory, iconThemeDirs);
doIconMapping("gtk-yes", "actions/button_ok.png", factory, iconThemeDirs); // Verify mapping here
doIconMapping("gtk-zoom-100", "actions/viewmag1.png", factory, iconThemeDirs);
doIconMapping("gtk-zoom-fit", "actions/viewmagfit.png", factory, iconThemeDirs);
doIconMapping("gtk-zoom-in", "actions/viewmag+.png", factory, iconThemeDirs);
doIconMapping("gtk-zoom-out", "actions/viewmag-.png", factory, iconThemeDirs);

// Other icons that really should have Trinity equivalents in tdelibs
doIconMapping("list-add", "actions/add.png", factory, iconThemeDirs);
doIconMapping("list-remove", "actions/remove.png", factory, iconThemeDirs);

gtk_icon_factory_add_default(factory);
themeFile.close();

if (!forceRecreate) {
gtk3_tqt_reload_theme_definition_file(themeFilePath.latin1());
}
}
// =========================================================================================================

+ 23
- 2
tdegtk/tdegtk-types.h View File

@@ -1,5 +1,5 @@
/* The TdeGtk Theming Engine for Gtk+.
* Copyright (C) 2011 Canonical Ltd
* Copyright (C) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,8 @@
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
* Portions of this file written by
* Andrea Cimitan <andrea.cimitan@canonical.com>
*
*/

@@ -61,6 +62,26 @@ typedef enum
TDEGTK_NUM_STYLES = 1
} TdeGtkStyles;

enum TQt3WidgetType {
TQT3WT_NONE,
TQT3WT_TQProgressBar,
TQT3WT_TQTabBar,
TQT3WT_TQRadioButton,
TQT3WT_TQCheckBox,
TQT3WT_TQPushButton,
TQT3WT_TQPopupMenu,
TQT3WT_TQComboBox,
TQT3WT_TQSlider,
TQT3WT_TQScrollBar,
TQT3WT_TQSpinBox,
TQT3WT_TQSpinWidget,
TQT3WT_TQTitleBar,
TQT3WT_TQMenuBar,
TQT3WT_TQToolBox,
TQT3WT_TQToolButton,
TQT3WT_GTKTreeViewCell,
};

typedef struct _TdeGtkStyleFunctions TdeGtkStyleFunctions;

struct _TdeGtkStyleFunctions


+ 1064
- 0
tdegtk/tdegtk-utils.cpp
File diff suppressed because it is too large
View File


+ 428
- 0
tdegtk/tdegtk-utils.h View File

@@ -0,0 +1,428 @@
#ifndef tdegtk_utils_h
#define tdegtk_utils_h
/*
* 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>
*
* GdkPixbuf modification code from Walmis
* <http://gnome-look.org/content/show.php?content=77783&forumpage=3>
*
* 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 "oxygenrgba.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include <cmath>
#include <string>

#if 0
//! GdkRectangle streamer
inline std::ostream& operator << (std::ostream& out, const GdkRectangle& rect )
{
out << "( " << rect.x << "," << rect.y << "," << rect.width << "," << rect.height << ")";
return out;
}

//! GtkBorder streamer
inline std::ostream& operator << (std::ostream& out, const GtkBorder& border )
{
out << "( " << border.left << "," << border.right << "," << border.top << "," << border.bottom << ")";
return out;
}

//! streamer for GtkWidgetPath
std::ostream& operator << ( std::ostream& out, const GtkWidgetPath* path );

//! GtkContainer streamer
inline std::ostream& operator << (std::ostream& out, GtkContainer* container)
{
GList* children=gtk_container_get_children(container);
for(GList* child=g_list_first(children); child; child=g_list_next(child))
{
out << G_OBJECT_TYPE_NAME(child->data) << " ";
}
g_list_free(children);
return out;
}
#endif

namespace Gtk
{

//! mouse button enumeration
enum MouseButton
{
NoButton = 0,
LeftButton = 1,
RightButton = 2,
MidButton = 3
};

//@!name gdk utilities
//@{

#if 0
//! returns OxygenRgba color from GdkColor
/*! TODO: remove as obsolete */
inline ColorUtils::Rgba gdk_get_color( const GdkColor& color )
{
return ColorUtils::Rgba(
double(color.red)/0xffff,
double(color.green)/0xffff,
double(color.blue)/0xffff );
}

//! returns OxygenRgba color from GdkColor
inline ColorUtils::Rgba gdk_get_color( const GdkRGBA& color )
{ return ColorUtils::Rgba( color.red, color.green, color.blue, color.alpha ); }
#endif

//! map widget origin to top level
/*!
x and y correspond to (0,0) maped to toplevel window;
w and h correspond to toplevel window frame size
*/
bool gdk_window_map_to_toplevel( GdkWindow*, gint*, gint*, gint*, gint*, bool frame = false );

//! map widget origin to top level
/*!
x and y correspond to (0,0) maped to toplevel window;
w and h correspond to toplevel window frame size
*/
bool gtk_widget_map_to_toplevel( GtkWidget*, gint*, gint*, gint*, gint*, bool frame = false );

//! map widget onto another (parent) widget
/*! second argument can be any parent in widget's ancestry tree */
bool gtk_widget_map_to_parent( GtkWidget*, GtkWidget*, gint*, gint*, gint*, gint* );

//! map window/widget origin to top level
inline bool gdk_map_to_toplevel( GdkWindow* window, GtkWidget* widget, gint* x, gint* y, gint* w, gint* h, bool frame = false )
{
if( window && GDK_IS_WINDOW( window ) ) return gdk_window_map_to_toplevel( window, x, y, w, h, frame );
else return gtk_widget_map_to_toplevel( widget, x, y, w, h, frame );
}

//! map window origin to top level
inline bool gdk_map_to_toplevel( GdkWindow* window, gint* x, gint* y, gint* w, gint* h, bool frame = false )
{ return gdk_window_map_to_toplevel( window, x, y, w, h, frame ); }

//! translate origin of child window into parent
/*! returns true on success */
bool gdk_window_translate_origin( GdkWindow*, GdkWindow*, gint*, gint* );

//! get top level windows dimension
void gdk_toplevel_get_size( GdkWindow*, gint*, gint* );

//! get top level windows dimension
void gdk_toplevel_get_frame_size( GdkWindow*, gint*, gint* );

//! get position relatve to toplevel
void gdk_window_get_toplevel_origin( GdkWindow*, gint*, gint* );

//! add alpha channel to pixbuf
GdkPixbuf* gdk_pixbuf_set_alpha( const GdkPixbuf*, double );

//! changes the gamma value of an image
bool gdk_pixbuf_to_gamma( GdkPixbuf* pixbuf, double value );

//! resize pixbuf
GdkPixbuf* gdk_pixbuf_resize( GdkPixbuf* src, int width, int height );

//! returns initialized GdkRectangle
inline GdkRectangle gdk_rectangle( int x = 0, int y = 0, int w = -1, int h = -1 )
{
GdkRectangle out = {x, y, w, h};
return out;
}

//! returns true if rectangle is valid
inline bool gdk_rectangle_is_valid( const GdkRectangle* rect )
{ return rect && rect->width > 0 && rect->height > 0; }

//! performs union of two rectangle, properly accounting for their validity
inline void gdk_rectangle_union( const GdkRectangle* first, const GdkRectangle* second, GdkRectangle* out )
{
if( !out ) return;
const bool firstIsValid( Gtk::gdk_rectangle_is_valid( first ) );
const bool secondIsValid( Gtk::gdk_rectangle_is_valid( second ) );
if( firstIsValid && secondIsValid ) ::gdk_rectangle_union( first, second, out );
else if( secondIsValid ) *out = *second;
else *out = *first;
}

//! returns true if given rectangle contains point
inline bool gdk_rectangle_contains( const GdkRectangle* rect, int x, int y )
{
return
rect &&
( rect->x <= x && (rect->x + rect->width) > x ) &&
( rect->y <= y && (rect->y + rect->height) > y );
}

//@}

//! get arrow orientation from angle
inline GtkArrowType gtk_arrow_get_type( const double& angle )
{
static const double delta( 0.001 );
if( std::abs( angle ) < delta ) return GTK_ARROW_UP;
else if( std::abs( angle - M_PI/2 ) < delta ) return GTK_ARROW_RIGHT;
else if( std::abs( angle - M_PI ) < delta ) return GTK_ARROW_DOWN;
else return GTK_ARROW_LEFT;
}

//! returns true if widget's layout is reversed
inline bool gtk_widget_layout_is_reversed( GtkWidget* widget )
{ return widget ? gtk_widget_get_direction( widget ) == GTK_TEXT_DIR_RTL : false; }

//! returns true if widget's layout is reversed
inline bool gtk_theming_engine_layout_is_reversed( GtkThemingEngine* engine )
{ return engine ? gtk_theming_engine_get_direction( engine ) == GTK_TEXT_DIR_RTL : false; }

//! set all buttons in the container to state NORMAL
void gtk_container_adjust_buttons_state( GtkContainer*, gpointer=0L );

//! returns widget allocation
inline GtkAllocation gtk_widget_get_allocation( GtkWidget* widget )
{
GtkAllocation allocation = { 0, 0, -1, -1 };
::gtk_widget_get_allocation( widget, &allocation );
return allocation;
}

//! returns true if given path as given type
bool gtk_widget_path_has_type( const GtkWidgetPath*, GType );

//! returns true if widget is a groupbox (a la Qt)
inline bool gtk_widget_is_groupbox( GtkWidget* widget )
{
return
GTK_IS_FRAME( widget ) &&
gtk_frame_get_label_widget( GTK_FRAME( widget ) ) &&
gtk_frame_get_shadow_type( GTK_FRAME( widget ) ) == GTK_SHADOW_OUT;
}

//! returns true if widget (or one of its parent) has a custom background
bool gtk_widget_has_custom_background( GtkWidget*, GtkStateType = GTK_STATE_NORMAL );

//! returns true if is an Gnome applet
bool gtk_widget_is_applet( GtkWidget* );

//! print some widget information
void gtk_widget_print_tree( GtkWidget* );

//! returns true if widget supports rgba
bool gtk_widget_has_rgba( GtkWidget* );

//! returns true if default screen is composited
bool gdk_default_screen_is_composited( void );

//! returns true if window supports rgba
bool gdk_window_has_rgba( GdkWindow* );

//! true if visual supports rgba
bool gdk_visual_has_rgba( GdkVisual* );

//! returns true if window is a base window
bool gdk_window_is_base( GdkWindow* );

//! returns true if window is a base window that do not need painting
bool gdk_window_nobackground( GdkWindow* );

//! true if object match a given type
bool g_object_is_a( const GObject*, const std::string& );

//! trigger area update using GdkRectangle
inline void gtk_widget_queue_draw( GtkWidget* widget, const GdkRectangle* rect = 0L )
{
if( !gdk_rectangle_is_valid( rect ) ) ::gtk_widget_queue_draw( widget );
else ::gtk_widget_queue_draw_area( widget, rect->x, rect->y, rect->width, rect->height );
}

//!@name check parent type
//@{

//! returns widget path as a string
std::string gtk_widget_path( GtkWidget* );

//! return parent of given type if any
GtkWidget* gtk_widget_find_parent( GtkWidget*, GType );

//! return parent of given type
inline GtkWidget* gtk_widget_find_parent( GtkWidget* widget, const std::string& typeName )
{
const GType tmp( g_type_from_name( typeName.c_str() ) );
return tmp ? gtk_widget_find_parent( widget, tmp ): 0L;
}

//! return parent "group box" if any.
GtkWidget* gtk_parent_groupbox( GtkWidget* widget );

//! return parent button if any.
inline GtkWidget* gtk_parent_button( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_BUTTON ); }

//! return parent menu if any
inline GtkWidget* gtk_parent_menubar( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_MENU_BAR ); }

//! return parent menu if any
inline GtkWidget* gtk_parent_menu( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_MENU ); }

//! return parent treeview if any.
inline GtkWidget* gtk_parent_tree_view( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_TREE_VIEW ); }

//! return parent combobox if any.
inline GtkWidget* gtk_parent_combobox( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_COMBO_BOX ); }

//! return parent combobox if any.
inline GtkWidget* gtk_parent_combobox_entry( GtkWidget* widget )
{
GtkWidget* parent( gtk_parent_combobox( widget ) );
return ( parent && gtk_combo_box_get_has_entry( GTK_COMBO_BOX( parent ) ) ) ? parent:0L;
}

//! return parent scrolled window if any.
inline GtkWidget* gtk_parent_scrolled_window( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_SCROLLED_WINDOW ); }

//! return parent statusbar if any.
inline GtkWidget* gtk_parent_statusbar( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_STATUSBAR ); }

//! return parent combobox if any.
inline GtkWidget* gtk_parent_notebook( GtkWidget* widget )
{ return gtk_widget_find_parent( widget, GTK_TYPE_NOTEBOOK ); }

//! returns true if potentialParent is (maybe indirect) parent of widget
bool gtk_widget_is_parent( GtkWidget*, GtkWidget* potentialParent );

//! returns true if one of the parent widgets has a sunken shadow
bool gtk_parent_is_shadow_in( GtkWidget* );

//@}

//! true if a widget (orientable) is horizontal
inline bool gtk_widget_is_horizontal( GtkWidget* widget )
{
if( !GTK_IS_ORIENTABLE( widget ) ) return true;
return gtk_orientable_get_orientation( GTK_ORIENTABLE( widget ) ) == GTK_ORIENTATION_HORIZONTAL;
}


//! true if a widget (orientable) is vertical
inline bool gtk_widget_is_vertical( GtkWidget* widget )
{
if( !GTK_IS_ORIENTABLE( widget ) ) return false;
return gtk_orientable_get_orientation( GTK_ORIENTABLE( widget ) ) == GTK_ORIENTATION_VERTICAL;
}

//! true if scrolled window must be forced to have a sunken frame
bool gtk_scrolled_window_force_sunken( GtkWidget* );

//!@name button utilities
//@{

//! true for 'flat' buttons (e.g. toolbuttons)
bool gtk_button_is_flat( GtkWidget* );

//! true for treeview headers and affiliated
bool gtk_button_is_header( GtkWidget* );

//! true for buttons in path bars
bool gtk_button_is_in_path_bar( GtkWidget* widget );

//! true if widget is last in path bar
bool gtk_path_bar_button_is_last( GtkWidget* widget );

//! returns an image on button-container
GtkWidget* gtk_button_find_image( GtkWidget* );

//! returns an image on button-container
GtkWidget* gtk_button_find_label( GtkWidget* );

//@}

//!@name combobox utilities
//@{

//! returns true if combobox has frame
bool gtk_combobox_has_frame( GtkWidget* );

//! true if widget is the treeview of a combobox
bool gtk_combobox_is_tree_view( GtkWidget* );

//! true if widget is the treeview of a combobox
bool gtk_combobox_is_scrolled_window( GtkWidget* );

//! true if widget is the treeview of a combobox
bool gtk_combobox_is_viewport( GtkWidget* );

//! true if widget is the treeview of a combobox
bool gtk_combobox_is_frame( GtkWidget* );

//! true if combobox must appear as list
bool gtk_combobox_appears_as_list( GtkWidget* );

//@}

//!@name notebook utilities
//@{

//! returns true if position is in hovered tab
//* this should move to OxygenTabWidgetData
bool gtk_notebook_tab_contains( GtkWidget*, int tab, int x, int y );

//! returns tab matching position or -1 if none
int gtk_notebook_find_tab( GtkWidget*, int x, int y );

//! returns index of first visible tab
int gtk_notebook_find_first_tab( GtkWidget* );

//! returns true if widget is one of the notebook's tab labels
bool gtk_notebook_is_tab_label( GtkNotebook*, GtkWidget* );

//! returns tabbar rect in notebook
void gtk_notebook_get_tabbar_rect( GtkNotebook*, GdkRectangle* );

//! returns true if notebook has visible scrollbar arrows
/*! arrows are dimmed visible if at least one of the child tab_labels is unmapped */
bool gtk_notebook_has_visible_arrows( GtkNotebook* );

// make all the buttons on the tabs normal
bool gtk_notebook_update_close_buttons( GtkNotebook*);

//! returns true if widget is a notebook close button
bool gtk_notebook_is_close_button( GtkWidget* );

//@}

//! calculates viewport offsets (between view window and bin window
void gtk_viewport_get_position( GtkViewport*, gint*, gint* );

//! returns a widget which has response_id as response id for dialog
GtkWidget* gtk_dialog_find_button( GtkDialog*, gint );

}

#endif

+ 231
- 0
tdegtk/tdegtk-widgetlookup.cpp View File

@@ -0,0 +1,231 @@
/*
* 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;
}



+ 92
- 0
tdegtk/tdegtk-widgetlookup.h View File

@@ -0,0 +1,92 @@
#ifndef tdegtk_widgetlookup_h
#define tdegtk_widgetlookup_h
/*
* 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-hooks.h"
#include "tdegtk-signals.h"

#include <cairo/cairo.h>
#include <gtk/gtk.h>

#include <list>
#include <map>


//! uses the widget's "draw" signal to bind GtkWidget and cairo context
/*! this allows us to retrieve painted widgets from ThemingEngine rendering primitives */
class WidgetLookup
{

public:

//! constructor
explicit WidgetLookup( void );

//! destructor
virtual ~WidgetLookup( void );

//! initialize hooks
void initializeHooks( void );

//! find widget matching given context and type
GtkWidget* find( cairo_t*, const GtkWidgetPath* ) const;

//! find widget matching given context and type
GtkWidget* find( cairo_t*, GType ) const;

protected:

//! bind widget to context
void bind( GtkWidget*, cairo_t* );

//! unregister widget
void unregisterWidget( GtkWidget* );

//! hook connected to widget's "draw" signal
static gboolean drawHook( GSignalInvocationHint*, guint, const GValue*, gpointer );

//! destruction callback
static gboolean destroyNotifyEvent( GtkWidget*, gpointer );

private:

//! true if hooks are initialized
bool _hooksInitialized;

//! hook connected to widget's "draw" signal
Hook _drawHook;

//! store current context
cairo_t* _context;

//! store list of associated widgets, to keep track of destruction
typedef std::list<GtkWidget*> WidgetList;
WidgetList _widgets;

//! keep track of all registered widgets, and associated destroy callback
typedef std::map< GtkWidget*, Signal > WidgetMap;
WidgetMap _allWidgets;

};

#endif


+ 9
- 5
tdegtk/tqtcairopainter.cpp View File

@@ -327,16 +327,16 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {

if (!m_clipRegionEnabled) {
// Clipping disabled
cairo_set_source_surface(m_devicePainter, m_intermediateSurface, 0, 0);
cairo_set_source_surface(m_devicePainter, m_intermediateSurface, m_offsetX, m_offsetY);
cairo_set_operator(m_devicePainter, overlayMerge?CAIRO_OPERATOR_OVER:CAIRO_OPERATOR_SOURCE);
cairo_paint(m_devicePainter);
}
else {
// Clipping enabled
cairo_surface_t* maskSurface = TQImageToCairoSurface(m_clipRegion);
cairo_set_source_surface(m_devicePainter, m_intermediateSurface, 0, 0);
cairo_set_source_surface(m_devicePainter, m_intermediateSurface, m_offsetX, m_offsetY);
cairo_set_operator(m_devicePainter, overlayMerge?CAIRO_OPERATOR_OVER:CAIRO_OPERATOR_SOURCE);
cairo_mask_surface(m_devicePainter, maskSurface, 0, 0);
cairo_mask_surface(m_devicePainter, maskSurface, m_offsetX, m_offsetY);
cairo_surface_destroy(maskSurface);
}

@@ -1083,16 +1083,18 @@ void TQt3CairoPaintDevice::setCairoTransformations() {
Constructs TQt3CairoPaintDevice on an existing QPainter
*/

TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface, int width, int height, cairo_t *overridepainter )
TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface, int x, int y, int width, int height, cairo_t *overridepainter )
: TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice )
{
init();

m_offsetX = x;
m_offsetY = y;
if (width >= 0) {
m_width = width;
}
if (height >= 0) {
m_height = width;
m_height = height;
}
if (overridepainter) {
m_overridePainter = overridepainter;
@@ -1138,6 +1140,8 @@ TQt3CairoPaintDevice::~TQt3CairoPaintDevice()
void TQt3CairoPaintDevice::init() {
m_width = -1;
m_height = -1;
m_offsetX = 0;
m_offsetY = 0;

m_intermediateSurface = NULL;
m_painter = NULL;


+ 3
- 1
tdegtk/tqtcairopainter.h View File

@@ -40,7 +40,7 @@ typedef TQPtrStack<TQWMatrix> TQWMatrixStack;
class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
{
public:
TQt3CairoPaintDevice( cairo_surface_t *, int width = -1, int height = -1, cairo_t *overridepainter = NULL );
TQt3CairoPaintDevice( cairo_surface_t *, int x = 0, int y = 0, int width = -1, int height = -1, cairo_t *overridepainter = NULL );
~TQt3CairoPaintDevice();

protected:
@@ -75,6 +75,8 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
private:
mutable int m_width;
mutable int m_height;
mutable int m_offsetX;
mutable int m_offsetY;

cairo_surface_t *m_surface;
cairo_surface_t *m_intermediateSurface;


+ 3
- 0
tests/compare View File

@@ -0,0 +1,3 @@
#!/bin/bash

composite -compose subtract tqt3.png stroke.png diff.png

+ 90
- 0
tests/test-painter.cpp View File

@@ -257,6 +257,96 @@ void runTests(TQPaintDevice* pd) {
cg.setColor(TQColorGroup::Foreground, TQColor(0,0,0));
tqApp->style().drawPrimitive(TQStyle::PE_ExclusiveIndicator, &p, TQRect(400, 400, 16, 16), cg, TQStyle::Style_Down);

// Tab bar tab tests
{
int currentPage;
int numPages=3;
int tabIndex=2;

int x = 0;
int y = 300;
int width = 50;
int height = 20;

for (currentPage=0;currentPage<numPages;currentPage++) {
TQRect boundingRect(0, 0, width, height);

TQStringList objectTypes;
objectTypes.append(TQTABBAR_OBJECT_NAME_STRING);