You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gtk3-tqt-engine/tdegtk/tdegtk-draw.cpp

1267 lines
41 KiB

/* 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.
*
*/
#include <cairo.h>
#include <gtk/gtk.h>
#include <math.h>
#include <tqapplication.h>
#include <tqpainter.h>
#include <tqstyle.h>
#include <tqpopupmenu.h>
#include <kiconloader.h>
#include <kicontheme.h>
#include "tdegtk-cairo-support.h"
#include "tdegtk-draw.h"
#include "tdegtk-support.h"
#include "tdegtk-types.h"
#include "tdegtk-widgetlookup.h"
#include "tdegtk-utils.h"
#include "tdegtk-animations.h"
#include "tqtcairopainter.h"
#define DEBUG_FILL_BACKGROUND_WITH_COLOR(p,x,y,z) TQBrush brush2( TQColor(x,y,z), TQBrush::SolidPattern ); \
p.setBrush( brush2 ); \
p.setPen( TQt::NoPen ); \
p.drawRect( 0,0, 5000,5000 );
#define DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p,x) p.setBrush(x); \
p.setPen(TQt::NoPen); \
p.drawRect(0, 0, width, height);
#define DRAW_FILLED_RECTANGLE_OVER_SPECIFIC_AREA(p,b,x,y,w,h) p.setBrush(b); \
p.setPen(TQt::NoPen); \
p.drawRect(x, y, w, h);
WidgetLookup m_widgetLookup;
Animations m_animations;
// Keep this in sync with gtkToTQPaletteColorGroup() below
static TQColorGroup gtkToTQtColorGroup(GtkThemingEngine* engine, GtkStateFlags state) {
// GdkRGBA *background_color;
// GdkRGBA *foreground_color;
// gtk_theming_engine_get(engine, state, GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &background_color, NULL);
// gtk_theming_engine_get(engine, state, GTK_STYLE_PROPERTY_COLOR, &foreground_color, NULL);
// GTK_STATE_FLAG_ACTIVE
// GTK_STATE_FLAG_PRELIGHT
// GTK_STATE_FLAG_SELECTED
// GTK_STATE_FLAG_INSENSITIVE
// GTK_STATE_FLAG_INCONSISTENT
// GTK_STATE_FLAG_FOCUSED
TQColorGroup cg;
// if (state & GTK_STATE_FLAG_INCONSISTENT) {
// cg = tqApp->palette().inactive();
// }
/*else*/ if (state & GTK_STATE_FLAG_INSENSITIVE) {
cg = tqApp->palette().disabled();
}
else {
cg = tqApp->palette().active();
}
// cg.setColor(TQColorGroup::Background, TQColor((background_color->red*255.0),(background_color->green*255.0),(background_color->blue*255.0)));
// cg.setColor(TQColorGroup::Foreground, TQColor((foreground_color->red*255.0),(foreground_color->green*255.0),(foreground_color->blue*255.0)));
return cg;
}
// Keep this in sync with gtkToTQtColorGroup() above
static TQPalette::ColorGroup gtkToTQPaletteColorGroup(GtkThemingEngine* engine, GtkStateFlags state) {
TQPalette::ColorGroup cg = TQPalette::Active;
if (state & GTK_STATE_FLAG_INSENSITIVE) {
cg = TQPalette::Disabled;
}
else {
cg = TQPalette::Active;
}
return cg;
}
static TQStyle::SFlags gtkToTQtStyleFlags(GtkThemingEngine* engine, GtkStateFlags state, TQt3WidgetType wt) {
TQStyle::SFlags sflags = TQStyle::Style_Default;
gboolean active, inconsistent, mousedown, prelight, focused, disabled, in_menu;
in_menu = gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_MENUITEM);
prelight = (state & GTK_STATE_FLAG_PRELIGHT) != 0;
focused = (state & GTK_STATE_FLAG_FOCUSED) != 0;
disabled = (state & GTK_STATE_FLAG_INSENSITIVE) != 0;
inconsistent = (state & GTK_STATE_FLAG_INCONSISTENT) != 0;
mousedown = (state & GTK_STATE_FLAG_SELECTED) != 0;
active = (state & GTK_STATE_FLAG_ACTIVE) != 0;
if ((wt == TQT3WT_TQRadioButton) || (wt == TQT3WT_TQCheckBox) || (wt == TQT3WT_TQPushButton)) {
if (!inconsistent) {
if (active) {
sflags |= TQStyle::Style_On;
}
else {
sflags |= TQStyle::Style_Off;
}
}
if (mousedown) {
sflags |= TQStyle::Style_Down;
}
if (prelight) {
sflags |= TQStyle::Style_MouseOver;
}
if (focused) {
sflags |= TQStyle::Style_HasFocus;
}
if (!disabled) {
sflags |= TQStyle::Style_Enabled;
}
}
else if (wt == TQT3WT_GTKTreeViewCell) {
if (!inconsistent) {
if (active) {
sflags |= TQStyle::Style_On;
}
else {
sflags |= TQStyle::Style_Off;
}
}
if (prelight) {
sflags |= TQStyle::Style_MouseOver;
}
if (focused) {
sflags |= TQStyle::Style_HasFocus;
}
if (!disabled) {
sflags |= TQStyle::Style_Enabled;
}
}
else if (wt == TQT3WT_TQGroupBox) {
if (prelight) {
sflags |= TQStyle::Style_MouseOver;
}
if (focused) {
sflags |= TQStyle::Style_HasFocus;
}
if (!disabled) {
sflags |= TQStyle::Style_Enabled;
}
}
else if (wt == TQT3WT_TQMenuItem) {
if (prelight) {
sflags |= TQStyle::Style_MouseOver;
}
if (focused) {
sflags |= TQStyle::Style_HasFocus;
}
if (!disabled) {
sflags |= TQStyle::Style_Enabled;
}
}
else {
if (active) {
sflags |= TQStyle::Style_Down;
}
if (prelight) {
sflags |= TQStyle::Style_MouseOver;
}
if (focused) {
sflags |= TQStyle::Style_HasFocus;
}
if (!disabled) {
sflags |= TQStyle::Style_Enabled;
}
}
return sflags;
}
static TQColorGroup::ColorRole backgroundModeToColorRole(TQt::BackgroundMode mode) {
TQColorGroup::ColorRole ret = TQColorGroup::Background;
if (mode == TQt::PaletteForeground) {
ret = TQColorGroup::Foreground;
}
else if (mode == TQt::PaletteBackground) {
ret = TQColorGroup::Background;
}
else if (mode == TQt::PaletteButton) {
ret = TQColorGroup::Button;
}
else if (mode == TQt::PaletteLight) {
ret = TQColorGroup::Light;
}
else if (mode == TQt::PaletteMidlight) {
ret = TQColorGroup::Midlight;
}
else if (mode == TQt::PaletteDark) {
ret = TQColorGroup::Dark;
}
else if (mode == TQt::PaletteMid) {
ret = TQColorGroup::Mid;
}
else if (mode == TQt::PaletteText) {
ret = TQColorGroup::Text;
}
else if (mode == TQt::PaletteBrightText) {
ret = TQColorGroup::BrightText;
}
else if (mode == TQt::PaletteButtonText) {
ret = TQColorGroup::ButtonText;
}
else if (mode == TQt::PaletteBase) {
ret = TQColorGroup::Base;
}
else if (mode == TQt::PaletteShadow) {
ret = TQColorGroup::Shadow;
}
else if (mode == TQt::PaletteHighlight) {
ret = TQColorGroup::Highlight;
}
else if (mode == TQt::PaletteHighlightedText) {
ret = TQColorGroup::HighlightedText;
}
else if (mode == TQt::PaletteLink) {
ret = TQColorGroup::Link;
}
else if (mode == TQt::PaletteLinkVisited) {
ret = TQColorGroup::LinkVisited;
}
return ret;
}
/* draw a texture placed on the centroid */
static gboolean
draw_centroid_texture (GtkThemingEngine *engine,
cairo_t *cr,
gdouble x,
gdouble y,
gdouble width,
gdouble height)
{
GtkStateFlags state;
GValue value = { 0, };
cairo_pattern_t *texture = NULL;
cairo_surface_t *surface = NULL;
gboolean retval = FALSE;
state = gtk_theming_engine_get_state (engine);
gtk_theming_engine_get_property (engine, "-tdegtk-centroid-texture", state, &value);
if (!G_VALUE_HOLDS_BOXED (&value))
return FALSE;
texture = (cairo_pattern_t*)g_value_dup_boxed (&value);
g_value_unset (&value);
if (texture != NULL)
cairo_pattern_get_surface (texture, &surface);
if (surface != NULL)
{
cairo_save (cr);
cairo_set_source_surface (cr, surface, (gint) (x + width / 2 - cairo_image_surface_get_width (surface) / 2),
(gint) (y + height / 2 - cairo_image_surface_get_height (surface) / 2));
cairo_paint (cr);
cairo_restore (cr);
retval = TRUE;
}
if (texture != NULL)
cairo_pattern_destroy (texture);
return retval;
}
static void
tdegtk_draw_activity (DRAW_ARGS)
{
/* playground for effects */
tdegtk_cairo_draw_background (engine, cr,
x, y, width, height,
0, gtk_theming_engine_get_junction_sides (engine));
tdegtk_cairo_draw_frame (engine, cr,
x, y, width, height,
0, gtk_theming_engine_get_junction_sides (engine));
}
static void
tdegtk_draw_arrow (GtkThemingEngine *engine,
cairo_t *cr,
gdouble angle,
gdouble x,
gdouble y,
gdouble size)
{
TQRect boundingRect(0, 0, size, size);
TQt3CairoPaintDevice pd(NULL, x, y, size, size, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,128,0,255);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
GtkArrowType arrow_direction;
if ((angle <= ((G_PI/2)-(G_PI/4))) || (angle > ((3*(G_PI/2))+(G_PI/4)))) {
arrow_direction = GTK_ARROW_UP;
}
else if ((angle <= ((G_PI)-(G_PI/4))) && (angle > ((0)+(G_PI/4)))) {
arrow_direction = GTK_ARROW_RIGHT;
}
else if ((angle <= ((3*(G_PI/2))-(G_PI/4))) && (angle > ((G_PI/2)+(G_PI/4)))) {
arrow_direction = GTK_ARROW_DOWN;
}
else {
arrow_direction = GTK_ARROW_LEFT;
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_SCROLLBAR)) {
TQStringList objectTypes;
objectTypes.append(TQSCROLLBAR_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
ceData.orientation = ((arrow_direction == GTK_ARROW_UP) || (arrow_direction == GTK_ARROW_DOWN))?TQt::Vertical:TQt::Horizontal;
bool subline = ((arrow_direction == GTK_ARROW_DOWN) || (arrow_direction == GTK_ARROW_RIGHT))?false:true;
// Draw slider arrow buttons
TQRect scrollpagerect = tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, ceData, elementFlags, (subline)?TQStyle::SC_ScrollBarSubLine:TQStyle::SC_ScrollBarAddLine, gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
if (ceData.orientation == TQt::Vertical) {
scrollpagerect.setY(ceData.rect.y());
scrollpagerect.setHeight(ceData.rect.height());
}
else {
scrollpagerect.setX(ceData.rect.x());
scrollpagerect.setWidth(ceData.rect.width());
}
tqApp->style().drawPrimitive((subline)?TQStyle::PE_ScrollBarSubLine:TQStyle::PE_ScrollBarAddLine, &p, scrollpagerect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((ceData.orientation == TQt::Horizontal)?TQStyle::Style_Horizontal:TQStyle::Style_Default));
}
else {
// Draw arrow
TQStyle::PrimitiveElement pe;
if (arrow_direction == GTK_ARROW_UP) {
pe = TQStyle::PE_ArrowUp;
}
else if (arrow_direction == GTK_ARROW_DOWN) {
pe = TQStyle::PE_ArrowDown;
}
else if (arrow_direction == GTK_ARROW_LEFT) {
pe = TQStyle::PE_ArrowLeft;
}
else {
pe = TQStyle::PE_ArrowRight;
}
tqApp->style().drawPrimitive(pe, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
}
p.end();
return;
GdkRGBA color;
gdouble size_reduction = 2;
state = gtk_theming_engine_get_state (engine);
gtk_theming_engine_get_color (engine, state, &color);
cairo_save (cr);
/* use floor function to adjust doubles */
y = floor (y);
x = floor (x);
size = floor (size);
size -= size_reduction;
cairo_translate (cr, size_reduction / 2, size_reduction / 2);
cairo_translate (cr, x + (gint) (size / 2.0) + 0.5, y + (gint) (size / 2.0) + 0.5);
cairo_rotate (cr, angle - G_PI_2);
cairo_translate (cr, (gint) (size / 4.0), 0);
/* FIXME this + 1/- 1 is done to fix blurred diagonal lines.
* I know it's not nice at all, but it fix a visual bug */
cairo_move_to (cr, - (gint) (size / 2.0), - (gint) (size / 2.0));
cairo_rel_line_to (cr, (gint) (size / 2.0) + 1, (gint) (size / 2.0));
cairo_rel_line_to (cr, - (gint) (size / 2.0) - 1, (gint) (size / 2.0));
cairo_close_path (cr);
cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha * 0.75);
cairo_fill_preserve (cr);
gdk_cairo_set_source_rgba (cr, &color);
cairo_stroke (cr);
cairo_restore (cr);
}
static void
tdegtk_draw_cell_background (DRAW_ARGS,
GtkRegionFlags flags)
{
GtkJunctionSides junction;
guint hidden_side;
junction = (GtkJunctionSides)(GTK_JUNCTION_RIGHT | GTK_JUNCTION_LEFT);
hidden_side = SIDE_RIGHT | SIDE_LEFT;
if ((flags & GTK_REGION_FIRST) != 0)
{
junction = (GtkJunctionSides)(junction & ~(GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMLEFT));
hidden_side &= ~(SIDE_LEFT);
}
if ((flags & GTK_REGION_LAST) != 0)
{
junction = (GtkJunctionSides)(junction & ~(GTK_JUNCTION_CORNER_TOPRIGHT | GTK_JUNCTION_CORNER_BOTTOMRIGHT));
hidden_side &= ~(SIDE_RIGHT);
}
tdegtk_cairo_draw_background (engine, cr,
x, y, width, height,
hidden_side, junction);
}
static void
tdegtk_draw_cell_frame (DRAW_ARGS,
GtkRegionFlags flags)
{
GtkJunctionSides junction;
guint hidden_side;
junction = (GtkJunctionSides)(GTK_JUNCTION_RIGHT | GTK_JUNCTION_LEFT);
hidden_side = SIDE_RIGHT | SIDE_LEFT;
if ((flags & GTK_REGION_FIRST) != 0)
{
junction = (GtkJunctionSides)(junction & ~(GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMLEFT));
hidden_side &= ~(SIDE_LEFT);
}
if ((flags & GTK_REGION_LAST) != 0)
{
junction = (GtkJunctionSides)(junction & ~(GTK_JUNCTION_CORNER_TOPRIGHT | GTK_JUNCTION_CORNER_BOTTOMRIGHT));
hidden_side &= ~(SIDE_RIGHT);
}
tdegtk_cairo_draw_frame (engine, cr,
x, y, width, height,
hidden_side, junction);
}
static void
tdegtk_draw_check (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,0,0);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
const GtkWidgetPath* path(gtk_theming_engine_get_path(engine));
if (gtk_widget_path_is_type(path, GTK_TYPE_TREE_VIEW)) {
tqApp->style().drawPrimitive(TQStyle::PE_Indicator, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_GTKTreeViewCell));
}
else {
tqApp->style().drawPrimitive(TQStyle::PE_Indicator, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_TQCheckBox));
}
p.end();
}
static void
tdegtk_draw_common (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,0,255,255);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
//tqApp->style().drawPrimitive(TQStyle::PE_Indicator, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
p.end();
}
static void
tdegtk_draw_common_background (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,0,0,255);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_ENTRY)) {
TQStringList objectTypes;
objectTypes.append(TQLINEEDIT_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Base);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_SCROLLBAR)) {
TQStringList objectTypes;
objectTypes.append(TQSCROLLBAR_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
ceData.orientation = (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_VERTICAL))?TQt::Vertical:TQt::Horizontal;
// Draw frame
tqApp->style().drawPrimitive(TQStyle::PE_PanelLineEdit, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((ceData.orientation == TQt::Horizontal)?TQStyle::Style_Horizontal:TQStyle::Style_Default));
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_BUTTON)) {
TQStringList objectTypes;
objectTypes.append(TQBUTTON_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_TOOLTIP)) {
TQStringList objectTypes;
objectTypes.append(TQTIPLABEL_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
}
if ((gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_MENU)) || (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_MENUITEM))) {
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,128,255);
// FIXME
// Mouse movements in the popup menu should be tracked similarly to mouse movements in the tab bar
// Many TQt3 styles highlight inactive menu items on hover; not providing this visual feedback may cause users to briefly think their GTK application has frozen up
// // Register menu item with animation engine
// m_animations.menuItemEngine().registerWidget(widget);
//
// // Check tab properties
// int tabIndex = Gtk::gtk_notebook_find_tab(widget, x+width/2, y+height/2);
// m_animations.tabWidgetEngine().updateTabRect(widget, tabIndex, x, y, width, height);
// bool prelight = (tabIndex == m_animations.tabWidgetEngine().hoveredTab(widget));
// GtkMenuItem* menuitem = GTK_MENU_ITEM(widget);
// const int currentPage = gtk_notebook_get_current_page(notebook);
// const int numPages = gtk_notebook_get_n_pages(notebook);
// bool selectedTab = (tabIndex==currentPage);
TQStringList objectTypes;
objectTypes.append(TQPOPUPMENU_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
TQMenuItem tqt3MenuItem;
int maxAcceleratorTextWidth = 0;
int maxIconWidth = IconSize(KIcon::Small) + 4;
TQStyleOption menuOpt(&tqt3MenuItem, maxIconWidth, maxAcceleratorTextWidth);
// if (???) elementFlags = elementFlags | TQStyle::TQStyle::CEF_IsCheckable;
TQRect paintDeviceRect;
TQRect backgroundRect;
// Draw item
tqApp->style().drawControl(TQStyle::CE_PopupMenuItem, &p, ceData, elementFlags, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_TQMenuItem) | ((gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_MENUITEM))?TQStyle::Style_Active:TQStyle::Style_Default), menuOpt);
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_BACKGROUND)) {
TQStringList objectTypes;
objectTypes.append(TQWIDGET_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
}
p.end();
}
static void
tdegtk_draw_common_frame (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_SCROLLBAR)) {
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_BUTTON)) {
// Scrollbar buttons are drawn in the arrow handler
}
else {
TQStringList objectTypes;
objectTypes.append(TQSCROLLBAR_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
ceData.orientation = ((gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_VERTICAL))?TQt::Vertical:TQt::Horizontal);
// Draw background
// HACK
// PE_ScrollBarAddPage and PE_ScrollBarSubPage are separate in TQt3
// Apparently there is no such distinction in GTK3!
TQRect scrollpagerect = tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, ceData, elementFlags, TQStyle::SC_ScrollBarAddPage, gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((ceData.orientation == TQt::Horizontal)?TQStyle::Style_Horizontal:TQStyle::Style_Default));
if (ceData.orientation == TQt::Vertical) {
scrollpagerect.setY(ceData.rect.y());
scrollpagerect.setHeight(ceData.rect.height());
}
else {
scrollpagerect.setX(ceData.rect.x());
scrollpagerect.setWidth(ceData.rect.width());
}
tqApp->style().drawPrimitive(TQStyle::PE_ScrollBarAddPage, &p, scrollpagerect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
}
}
else {
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_BUTTON)) {
// Draw frame
tqApp->style().drawPrimitive(TQStyle::PE_ButtonBevel, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_TQPushButton));
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_ENTRY)) {
TQStringList objectTypes;
objectTypes.append(TQLINEEDIT_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw frame
tqApp->style().drawPrimitive(TQStyle::PE_PanelLineEdit, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
}
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_MENU)) {
TQStringList objectTypes;
objectTypes.append(TQPOPUPMENU_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
ceData.orientation = (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_VERTICAL))?TQt::Vertical:TQt::Horizontal;
// Draw frame
tqApp->style().drawPrimitive(TQStyle::PE_PanelPopup, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((ceData.orientation == TQt::Horizontal)?TQStyle::Style_Horizontal:TQStyle::Style_Default));
}
}
p.end();
}
static void
tdegtk_draw_expander (DRAW_ARGS)
{
GtkStateFlags state;
GdkRGBA color;
gint size;
gdouble angle = G_PI_2;
state = gtk_theming_engine_get_state (engine);
gtk_theming_engine_get_color (engine, state, &color);
cairo_save (cr);
/* use floor function to adjust doubles */
size = floor (MIN (width, height));
x += (gint) (width / 2) - size / 2;
y += (gint) (height / 2) - size / 2;
if ((state & GTK_STATE_FLAG_ACTIVE) == 0)
angle = 0;
cairo_translate (cr, x + size / 2.0 + 0.5, y + size / 2.0 + 0.5);
cairo_rotate (cr, angle);
cairo_translate (cr, size / 4.0, 0);
/* FIXME this + 1/- 1 is done to fix blurred diagonal lines.
* I know it's not nice at all, but it fix a visual bug */
cairo_move_to (cr, - size / 2.0, - size / 2.0);
cairo_rel_line_to (cr, size / 2.0 + 1, size / 2.0);
cairo_rel_line_to (cr, - size / 2.0 - 1, size / 2.0);
cairo_close_path (cr);
cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha * 0.75);
cairo_fill_preserve (cr);
gdk_cairo_set_source_rgba (cr, &color);
cairo_stroke (cr);
cairo_restore (cr);
}
static void
tdegtk_draw_extension (DRAW_ARGS,
GtkPositionType gap_side)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,255,0);
const GtkWidgetPath* path;
GtkStateFlags state;
GtkWidget* widget;
path = gtk_theming_engine_get_path(engine);
state = gtk_theming_engine_get_state(engine);
widget = m_widgetLookup.find(cr, path);
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_NOTEBOOK)) {
// Register tabbar with animation engine
m_animations.tabWidgetEngine().registerWidget(widget);
// Check tab properties
int tabIndex = Gtk::gtk_notebook_find_tab(widget, x+width/2, y+height/2);
m_animations.tabWidgetEngine().updateTabRect(widget, tabIndex, x, y, width, height);
bool prelight = (tabIndex == m_animations.tabWidgetEngine().hoveredTab(widget));
GtkNotebook* notebook = GTK_NOTEBOOK(widget);
// bool firstTab = (tabIndex == 0);
// bool lastTab = (tabIndex == gtk_notebook_get_n_pages(notebook)-1);
const int currentPage = gtk_notebook_get_current_page(notebook);
const int numPages = gtk_notebook_get_n_pages(notebook);
bool selectedTab = (tabIndex==currentPage);
TQStringList objectTypes;
objectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
TQTab tqt3Tab;
tqt3Tab.setIdentifier(tabIndex);
TQStyleOption tabOpt(&tqt3Tab, (prelight)?&tqt3Tab:(TQTab*)NULL);
elementFlags = elementFlags | TQStyle::CEF_HasParentWidget;
ceData.parentWidgetData.widgetObjectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
int tab_overlap = tqApp->style().pixelMetric(TQStyle::PM_TabBarTabOverlap);
int tab_to_frame_gap_height = 2;
ceData.tabBarData.tabCount = numPages;
ceData.tabBarData.identIndexMap[tqt3Tab.identifier()] = tabIndex;
TQRect paintDeviceRect;
TQRect backgroundRect;
switch (gap_side) {
default:
case GTK_POS_TOP:
ceData.tabBarData.shape = TQTabBar::RoundedBelow;
paintDeviceRect = TQRect(x-tab_overlap, y-tab_to_frame_gap_height, width+(tab_overlap*2), height+tab_to_frame_gap_height);
boundingRect = TQRect(0, 0, width+(tab_overlap*2)-tab_overlap, height+tab_to_frame_gap_height);
backgroundRect = TQRect(tab_overlap, 0, width, height+2);
break;
case GTK_POS_LEFT:
ceData.tabBarData.shape = TQTabBar::RoundedAbove;
// FIXME
// TQt3 does not know how to draw these
// For now, draw a single unconnected tab in this location
tabIndex = 0;
ceData.tabBarData.tabCount = 1;
tqt3Tab.setIdentifier(tabIndex);
ceData.tabBarData.identIndexMap[tqt3Tab.identifier()] = tabIndex;
paintDeviceRect = TQRect(x-tab_overlap, y, width+(tab_overlap*2), height);
boundingRect = TQRect(0, 0, width+(tab_overlap*2)-tab_overlap, height);
backgroundRect = TQRect(0, 0, width, height);
break;
case GTK_POS_BOTTOM:
ceData.tabBarData.shape = TQTabBar::RoundedAbove;
paintDeviceRect = TQRect(x-tab_overlap, y, width+(tab_overlap*2), height+tab_to_frame_gap_height);
boundingRect = TQRect(0, 0, width+(tab_overlap*2)-tab_overlap, height+tab_to_frame_gap_height);
backgroundRect = TQRect(tab_overlap, 0, width, height+2);
break;
case GTK_POS_RIGHT:
ceData.tabBarData.shape = TQTabBar::RoundedAbove;
// FIXME
// TQt3 does not know how to draw these
// For now, draw a single unconnected tab in this location
tabIndex = 0;
ceData.tabBarData.tabCount = 1;
tqt3Tab.setIdentifier(tabIndex);
ceData.tabBarData.identIndexMap[tqt3Tab.identifier()] = tabIndex;
paintDeviceRect = TQRect(x-tab_overlap, y, width+(tab_overlap*2), height);
boundingRect = TQRect(0, 0, width+(tab_overlap*2)-tab_overlap, height);
backgroundRect = TQRect(0, 0, width, height);
break;
}
cairo_save(cr);
cairo_reset_clip(cr);
TQt3CairoPaintDevice pd2(NULL, paintDeviceRect.x(), paintDeviceRect.y(), paintDeviceRect.width(), paintDeviceRect.height(), cr);
TQPainter p2(&pd2);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_SPECIFIC_AREA(p2, brush, backgroundRect.x(), backgroundRect.y(), backgroundRect.width(), backgroundRect.height())
// Draw tab
tqApp->style().drawControl(TQStyle::CE_TabBarTab, &p2, ceData, elementFlags, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((selectedTab)?TQStyle::Style_Selected:TQStyle::Style_Default) | ((prelight)?TQStyle::Style_MouseOver:TQStyle::Style_Default), tabOpt);
cairo_restore(cr);
}
p.end();
}
static void
tdegtk_draw_focus (DRAW_ARGS)
{
GtkStateFlags state;
state = gtk_theming_engine_get_state (engine);
return;
}
static void
tdegtk_draw_frame_gap (DRAW_ARGS,
GtkPositionType gap_side,
gdouble xy0_gap,
gdouble xy1_gap)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,128,0);
const GtkWidgetPath* path;
GtkStateFlags state;
GtkWidget* widget;
path = gtk_theming_engine_get_path(engine);
state = gtk_theming_engine_get_state(engine);
widget = m_widgetLookup.find(cr, path);
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_FRAME)) {
GtkFrame* frame = GTK_FRAME(widget);
GtkShadowType gtkShadowType = gtk_frame_get_shadow_type(frame);
TQStringList objectTypes;
objectTypes.append(TQGROUPBOX_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
int groupBoxLineWidth = 1;
int lineWidth = 0;
int midLineWidth = 0;
TQStyle::SFlags sflags = gtkToTQtStyleFlags(engine, state, TQT3WT_TQGroupBox);
if (gtkShadowType == GTK_SHADOW_NONE) {
lineWidth = 0;
midLineWidth = 0;
}
else if (gtkShadowType == GTK_SHADOW_IN) {
lineWidth = groupBoxLineWidth;
midLineWidth = 0;
sflags = sflags | TQStyle::Style_Sunken;
}
else if (gtkShadowType == GTK_SHADOW_OUT) {
lineWidth = groupBoxLineWidth;
midLineWidth = 0;
sflags = sflags | TQStyle::Style_Raised;
}
else if (gtkShadowType == GTK_SHADOW_ETCHED_IN) {
lineWidth = groupBoxLineWidth;
midLineWidth = groupBoxLineWidth;
sflags = sflags | TQStyle::Style_Sunken;
}
else if (gtkShadowType == GTK_SHADOW_ETCHED_OUT) {
lineWidth = groupBoxLineWidth;
midLineWidth = groupBoxLineWidth;
sflags = sflags | TQStyle::Style_Raised;
}
TQStyleOption opt(lineWidth, midLineWidth);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
// Draw group box
tqApp->style().drawPrimitive(TQStyle::PE_PanelGroupBox, &p, boundingRect, gtkToTQtColorGroup(engine, state), sflags, opt);
// Draw background behind groupbox label
DRAW_FILLED_RECTANGLE_OVER_SPECIFIC_AREA(p, brush, xy0_gap, x, (xy1_gap-xy0_gap), (height/2))
}
p.end();
}
static void
tdegtk_draw_grip (DRAW_ARGS)
{
GdkRGBA border_color;
GdkRGBA *inner_stroke_color;
GtkStateFlags state;
gint lx, ly;
state = gtk_theming_engine_get_state (engine);
gtk_theming_engine_get (engine, state,
"-tdegtk-inner-stroke-color", &inner_stroke_color,
NULL);
gtk_theming_engine_get_border_color (engine, state, &border_color);
for (ly = 0; ly < 4; ly++)
{
/* vertically, four rows of dots */
for (lx = 0; lx <= ly; lx++)
{
/* horizontally */
int ny = (3.5 - ly) * 3;
int nx = lx * 3;
gdk_cairo_set_source_rgba (cr, inner_stroke_color);
cairo_rectangle (cr, x + width - nx - 1, y + height - ny - 1, 2, 2);
cairo_fill (cr);
gdk_cairo_set_source_rgba (cr, &border_color);
cairo_rectangle (cr, x + width - nx - 1, y + height - ny - 1, 1, 1);
cairo_fill (cr);
}
}
gdk_rgba_free (inner_stroke_color);
}
static void
tdegtk_draw_handle (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,0,128,255);
p.end();
return;
gdouble line_width;
gint i, bar_y, num_bars, bar_spacing, bar_width, bar_height;
tdegtk_cairo_draw_background (engine, cr,
x, y, width, height,
0, gtk_theming_engine_get_junction_sides (engine));
if (draw_centroid_texture (engine, cr, x, y, width, height))
return;
tdegtk_get_line_width (engine, &line_width);
bar_y = 1;
num_bars = 3;
bar_spacing = 3;
bar_width = 3;
bar_height = num_bars * bar_spacing * line_width;
cairo_save (cr);
cairo_translate (cr, x + (gint) (width / 2), y + (gint) (height / 2));
if (height > width)
cairo_translate (cr, - bar_width / 2 - 0.5, - bar_height / 2 + 0.5);
else
{
cairo_translate (cr, - bar_height / 2 + 0.5, bar_width / 2 + 0.5);
cairo_rotate (cr, - G_PI / 2);
}
for (i = 0; i < num_bars; i++)
{
/* draw bars */
cairo_move_to (cr, 0, bar_y);
cairo_line_to (cr, bar_width, bar_y);
tdegtk_cairo_set_source_border (engine, cr, bar_width, 3);
cairo_stroke (cr);
cairo_move_to (cr, 0, bar_y + line_width);
cairo_line_to (cr, bar_width, bar_y + line_width);
tdegtk_cairo_set_source_inner_stroke (engine, cr, bar_width, line_width);
cairo_stroke (cr);
bar_y += bar_spacing;
}
cairo_restore (cr);
}
static void
tdegtk_draw_line (GtkThemingEngine *engine,
cairo_t *cr,
gdouble x0,
gdouble y0,
gdouble x1,
gdouble y1)
{
/* line endings */
if (y0 == y1)
{
y0 += 0.5;
y1 += 0.5;
x0 += 0.5;
x1 -= 0.5;
}
else if (x0 == x1)
{
x0 += 0.5;
x1 += 0.5;
y0 += 0.5;
y1 -= 0.5;
}
cairo_move_to (cr, x0, y0);
cairo_line_to (cr, x1, y1);
tdegtk_cairo_set_source_border (engine, cr, MAX (x1 - x0, 1), MAX (y1 - y0, 1));
cairo_stroke (cr);
}
static void
tdegtk_draw_notebook (DRAW_ARGS,
GtkPositionType gap_side,
gdouble xy0_gap,
gdouble xy1_gap)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,0,255,0);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
TQStringList objectTypes;
objectTypes.append(TQTABWIDGET_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
// Draw background
TQBrush brush = objectPalette.brush(gtkToTQPaletteColorGroup(engine, state), TQColorGroup::Background);
DRAW_FILLED_RECTANGLE_OVER_ENTIRE_AREA(p, brush)
// Draw tab frame
tqApp->style().drawPrimitive(TQStyle::PE_PanelTabWidget, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
p.end();
}
static void
tdegtk_draw_radio (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,0,0);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
const GtkWidgetPath* path(gtk_theming_engine_get_path(engine));
if (gtk_widget_path_is_type(path, GTK_TYPE_TREE_VIEW)) {
tqApp->style().drawPrimitive(TQStyle::PE_ExclusiveIndicator, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_GTKTreeViewCell));
}
else {
tqApp->style().drawPrimitive(TQStyle::PE_ExclusiveIndicator, &p, boundingRect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_TQRadioButton));
}
p.end();
}
static void
tdegtk_draw_separator (DRAW_ARGS)
{
gdouble line_width;
tdegtk_get_line_width (engine, &line_width);
if (line_width == 0)
return;
/* FIXME right code should be
* if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_VERTICAL))
* but doesn't work for separator tool item. */
if (width > height)
{
cairo_move_to (cr, x, y + (gint) (height / 2) + line_width / 2);
cairo_line_to (cr, x + width, y + (gint) (height / 2) + line_width / 2);
tdegtk_cairo_set_source_inner_stroke (engine, cr, width, line_width);
cairo_stroke (cr);
cairo_move_to (cr, x, y + (gint) (height / 2) - line_width / 2);
cairo_line_to (cr, x + width, y + (gint) (height / 2) - line_width / 2);
tdegtk_cairo_set_source_border (engine, cr, width, line_width);
cairo_stroke (cr);
}
else
{
cairo_move_to (cr, x + (gint) (width / 2) + line_width / 2, y);
cairo_line_to (cr, x + (gint) (width / 2) + line_width / 2, y + height);
tdegtk_cairo_set_source_inner_stroke (engine, cr, line_width, height);
cairo_stroke (cr);
cairo_move_to (cr, x + (gint) (width / 2) - line_width / 2, y);
cairo_line_to (cr, x + (gint) (width / 2) - line_width / 2, y + height);
tdegtk_cairo_set_source_border (engine, cr, line_width, height);
cairo_stroke (cr);
}
}
static void
tdegtk_draw_slider (DRAW_ARGS,
GtkOrientation orientation)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,255,0,255);
GtkStateFlags state;
state = gtk_theming_engine_get_state(engine);
if (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_SCROLLBAR)) {
TQStringList objectTypes;
objectTypes.append(TQSCROLLBAR_OBJECT_NAME_STRING);
TQPalette objectPalette = tqApp->palette(objectTypes);
TQStyleControlElementData ceData;
TQStyle::ControlElementFlags elementFlags;
ceData.widgetObjectTypes = objectTypes;
ceData.rect = boundingRect;
ceData.orientation = (gtk_theming_engine_has_class(engine, GTK_STYLE_CLASS_VERTICAL))?TQt::Vertical:TQt::Horizontal;
// Draw slider
TQRect scrollpagerect = tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, ceData, elementFlags, TQStyle::SC_ScrollBarSlider, gtkToTQtStyleFlags(engine, state, TQT3WT_NONE));
if (ceData.orientation == TQt::Vertical) {
scrollpagerect.setY(ceData.rect.y());
scrollpagerect.setHeight(ceData.rect.height());
}
else {
scrollpagerect.setX(ceData.rect.x());
scrollpagerect.setWidth(ceData.rect.width());
}
tqApp->style().drawPrimitive(TQStyle::PE_ScrollBarSlider, &p, scrollpagerect, gtkToTQtColorGroup(engine, state), gtkToTQtStyleFlags(engine, state, TQT3WT_NONE) | ((ceData.orientation == TQt::Horizontal)?TQStyle::Style_Horizontal:TQStyle::Style_Default));
}
p.end();
}
static void
tdegtk_draw_spinbutton_background (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,128,255,0);
p.end();
}
static void
tdegtk_draw_spinbutton_frame (DRAW_ARGS)
{
TQRect boundingRect(0, 0, width, height);
TQt3CairoPaintDevice pd(NULL, x, y, width, height, cr);
TQPainter p(&pd);
DEBUG_FILL_BACKGROUND_WITH_COLOR(p,128,255,128);
p.end();
}
void
tdegtk_register_style_default (TdeGtkStyleFunctions *functions)
{
g_assert (functions);
functions->draw_activity = tdegtk_draw_activity;
functions->draw_arrow = tdegtk_draw_arrow;
functions->draw_cell_background = tdegtk_draw_cell_background;
functions->draw_cell_frame = tdegtk_draw_cell_frame;
functions->draw_check = tdegtk_draw_check;
functions->draw_common = tdegtk_draw_common;
functions->draw_common_background = tdegtk_draw_common_background;
functions->draw_common_frame = tdegtk_draw_common_frame;
functions->draw_expander = tdegtk_draw_expander;
functions->draw_extension = tdegtk_draw_extension;
functions->draw_focus = tdegtk_draw_focus;
functions->draw_frame_gap = tdegtk_draw_frame_gap;
functions->draw_grip = tdegtk_draw_grip;
functions->draw_handle = tdegtk_draw_handle;
functions->draw_line = tdegtk_draw_line;
functions->draw_notebook = tdegtk_draw_notebook;
functions->draw_radio = tdegtk_draw_radio;
functions->draw_separator = tdegtk_draw_separator;
functions->draw_slider = tdegtk_draw_slider;
functions->draw_spinbutton_background = tdegtk_draw_spinbutton_background;
functions->draw_spinbutton_frame = tdegtk_draw_spinbutton_frame;
}