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.
gtk-qt-engine/src/qt_theme_draw.c

2087 lines
57 KiB

#include <math.h>
#include <string.h>
#include <gtk/gtkprogressbar.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <glib.h>
#ifdef HAVE_BONOBO
#include <libbonobo.h>
#include <libbonoboui.h>
#endif
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "qt_style.h"
#include "qt_rc_style.h"
#include "qt_qt_wrapper.h"
#define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
#define DETAILHAS(xx) ((detail) && (strstr(detail, xx)))
#define PARENT(xx) ((parent) && (!strcmp(xx, gtk_widget_get_name(parent))))
#ifndef max
#define max(x,y) ((x)>=(y)?(x):(y))
#endif
#ifndef min
#define min(x,y) ((x)<=(y)?(x):(y))
#endif
extern gboolean tde_showIconsOnPushButtons;
static GdkPixbuf * (*stockRenderIcon)() = NULL;
// static void * (*stockDrawString)() = NULL;
static void qtengine_style_init (QtEngineStyle *style);
static void qtengine_style_class_init (QtEngineStyleClass *klass);
static GtkNotebook *notebook = NULL;
static int nb_num_pages = 0;
static GtkStyleClass *parent_class = NULL;
static PangoLayout*
get_insensitive_layout (GdkDrawable *drawable,
PangoLayout *layout);
static GtkShadowType
get_shadow_type (GtkStyle* style, const char *detail, GtkShadowType requested)
{
GtkShadowType retval = GTK_SHADOW_NONE;
if (requested != GTK_SHADOW_NONE) {
retval = GTK_SHADOW_ETCHED_IN;
}
if (DETAIL ("dockitem") || DETAIL ("handlebox_bin") || DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down")) {
retval = GTK_SHADOW_NONE;
} else if (DETAIL ("button") || DETAIL ("togglebutton") || DETAIL ("notebook") || DETAIL ("optionmenu")) {
retval = requested;
} else if (DETAIL ("menu")) {
retval = GTK_SHADOW_ETCHED_IN;
}
return retval;
}
static void sanitize_size(GdkWindow* window, gint* width, gint* height)
{
if ((*width == -1) && (*height == -1))
gdk_window_get_size (window, width, height);
else if (*width == -1)
gdk_window_get_size (window, width, NULL);
else if (*height == -1)
gdk_window_get_size (window, NULL, height);
}
static GdkPixbuf *
draw_icon (GtkStyle *style,
const GtkIconSource *source,
GtkTextDirection direction,
GtkStateType state,
GtkIconSize size,
GtkWidget *widget,
const gchar *detail)
{
gboolean paint_icon = TRUE;
if (gtkQtDebug)
printf("ICON Widget: %s Detail: %s\n",gtk_widget_get_name(widget),detail);
GtkWidget* parent;
parent = gtk_widget_get_parent(widget);
int level = 1;
while (parent) {
if (gtkQtDebug)
printf("ICON Parent: %s\n",gtk_widget_get_name(parent));
if (strcmp("GtkButton", gtk_widget_get_name(parent)) == 0) {
if (level == 3) {
#ifdef USE_NATIVE_GTK_BUTTON_DRAWING
paint_icon = tde_showIconsOnPushButtons;
#else
paint_icon = FALSE;
#endif
}
}
parent = gtk_widget_get_parent(parent);
level++;
}
if (paint_icon) {
return stockRenderIcon(style, source, direction, state, size, widget, detail);
}
else {
// FIXME
return NULL;
}
}
static void
draw_hline(GtkStyle* style,
GdkWindow* window,
GtkStateType state_type,
GdkRectangle* area,
GtkWidget* widget,
const gchar* detail,
gint x1,
gint x2,
gint y)
{
if (gtkQtDebug) {
printf("HLINE (%d,%p,%d) Widget: %s Detail: %s\n",x1,y1,y,gtk_widget_get_name(widget),detail);
}
if (DETAIL("vscale")) {
return;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawHLine(window,style,state_type,y,x1,x2);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
static void
draw_vline(GtkStyle* style,
GdkWindow* window,
GtkStateType state_type,
GdkRectangle* area,
GtkWidget* widget,
const gchar* detail,
gint ySource,
gint yDest,
gint x)
{
if (gtkQtDebug) {
printf("VLINE (%d,%d,%d) Widget: %s Detail: %s\n",ySource ,yDest ,x,gtk_widget_get_name(widget),detail);
}
if (DETAIL("hscale")) {
return;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawVLine(window,style,state_type,x,ySource,yDest);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
static void
draw_shadow(GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
GdkGC *gc1 = NULL; /* Initialize to quiet GCC */
GdkGC *gc2 = NULL;
GdkGC *gc3 = NULL;
GdkGC *gc4 = NULL;
gint thickness_light;
gint thickness_dark;
gint i;
sanitize_size(window, &width, &height);
if (gtkQtDebug)
printf("Shadow (%d,%d,%d,%d) Widget: %s Detail: %s\n",x,y,width,height,gtk_widget_get_name(widget),detail);
if (DETAIL("menuitem"))
return;
if (DETAIL("menu"))
return;
if (DETAIL("entry"))
{
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawLineEdit(window,style,state_type,gtk_widget_is_focus(widget),x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("frame") || DETAIL("trough") || DETAIL("viewport"))
{
if (!GTK_IS_SCALE(widget))
{
/*printf("Frame (%d,%d) %dx%d %d %d\n", x,y,width,height,state_type, shadow_type);*/
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawFrame(window,style,state_type,shadow_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
}
/* The remainder of this function was borrowed from the "Metal" theme/
I don't really want to use Qt to draw these frames as there are too
many of them (it would slow down the theme engine even more).
TODO: Make them use the Qt color palette */
switch (shadow_type)
{
case GTK_SHADOW_NONE:
case GTK_SHADOW_IN:
case GTK_SHADOW_ETCHED_IN:
gc1 = style->light_gc[state_type];
gc2 = style->dark_gc[state_type];
gc3 = style->black_gc;
gc4 = style->bg_gc[state_type];
break;
case GTK_SHADOW_OUT:
case GTK_SHADOW_ETCHED_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
gc3 = style->black_gc;
gc4 = style->bg_gc[state_type];
break;
}
if (area)
{
gdk_gc_set_clip_rectangle (gc1, area);
gdk_gc_set_clip_rectangle (gc2, area);
gdk_gc_set_clip_rectangle (gc3, area);
gdk_gc_set_clip_rectangle (gc4, area);
}
switch (shadow_type)
{
case GTK_SHADOW_NONE:
break;
case GTK_SHADOW_IN:
gdk_draw_line (window, gc1,
x, y + height - 1, x + width - 1, y + height - 1);
gdk_draw_line (window, gc1,
x + width - 1, y, x + width - 1, y + height - 1);
gdk_draw_line (window, gc4,
x + 1, y + height - 2, x + width - 2, y + height - 2);
gdk_draw_line (window, gc4,
x + width - 2, y + 1, x + width - 2, y + height - 2);
gdk_draw_line (window, gc3,
x + 1, y + 1, x + width - 2, y + 1);
gdk_draw_line (window, gc3,
x + 1, y + 1, x + 1, y + height - 2);
gdk_draw_line (window, gc2,
x, y, x + width - 1, y);
gdk_draw_line (window, gc2,
x, y, x, y + height - 1);
break;
case GTK_SHADOW_OUT:
gdk_draw_line (window, gc1,
x + 1, y + height - 2, x + width - 2, y + height - 2);
gdk_draw_line (window, gc1,
x + width - 2, y + 1, x + width - 2, y + height - 2);
gdk_draw_line (window, gc2,
x, y, x + width - 1, y);
gdk_draw_line (window, gc2,
x, y, x, y + height - 1);
gdk_draw_line (window, gc4,
x + 1, y + 1, x + width - 2, y + 1);
gdk_draw_line (window, gc4,
x + 1, y + 1, x + 1, y + height - 2);
gdk_draw_line (window, gc3,
x, y + height - 1, x + width - 1, y + height - 1);
gdk_draw_line (window, gc3,
x + width - 1, y, x + width - 1, y + height - 1);
break;
case GTK_SHADOW_ETCHED_IN:
case GTK_SHADOW_ETCHED_OUT:
thickness_light = 1;
thickness_dark = 1;
for (i = 0; i < thickness_dark; i++)
{
gdk_draw_line (window, gc1,
x + i,
y + height - i - 1,
x + width - i - 1,
y + height - i - 1);
gdk_draw_line (window, gc1,
x + width - i - 1,
y + i,
x + width - i - 1,
y + height - i - 1);
gdk_draw_line (window, gc2,
x + i,
y + i,
x + width - i - 2,
y + i);
gdk_draw_line (window, gc2,
x + i,
y + i,
x + i,
y + height - i - 2);
}
for (i = 0; i < thickness_light; i++)
{
gdk_draw_line (window, gc1,
x + thickness_dark + i,
y + thickness_dark + i,
x + width - thickness_dark - i - 1,
y + thickness_dark + i);
gdk_draw_line (window, gc1,
x + thickness_dark + i,
y + thickness_dark + i,
x + thickness_dark + i,
y + height - thickness_dark - i - 1);
gdk_draw_line (window, gc2,
x + thickness_dark + i,
y + height - thickness_light - i - 1,
x + width - thickness_light - 1,
y + height - thickness_light - i - 1);
gdk_draw_line (window, gc2,
x + width - thickness_light - i - 1,
y + thickness_dark + i,
x + width - thickness_light - i - 1,
y + height - thickness_light - 1);
}
break;
}
if (area)
{
gdk_gc_set_clip_rectangle (gc1, NULL);
gdk_gc_set_clip_rectangle (gc2, NULL);
gdk_gc_set_clip_rectangle (gc3, NULL);
gdk_gc_set_clip_rectangle (gc4, NULL);
}
return;
}
static void
draw_polygon(GtkStyle* style,
GdkWindow* window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle* area,
GtkWidget* widget,
const gchar* detail,
GdkPoint* points,
gint npoints,
gint fill)
{
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif /* M_PI */
#ifndef M_PI_4
#define M_PI_4 0.78539816339744830962
#endif /* M_PI_4 */
static const gdouble pi_over_4 = M_PI_4;
static const gdouble pi_3_over_4 = M_PI_4 * 3;
GdkGC *gc1;
GdkGC *gc2;
GdkGC *gc3;
GdkGC *gc4;
gdouble angle;
gint xadjust;
gint yadjust;
gint i;
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
g_return_if_fail(points != NULL);
switch (shadow_type)
{
case GTK_SHADOW_IN:
gc1 = style->light_gc[state_type];
gc2 = style->dark_gc[state_type];
gc3 = style->light_gc[state_type];
gc4 = style->dark_gc[state_type];
break;
case GTK_SHADOW_ETCHED_IN:
gc1 = style->light_gc[state_type];
gc2 = style->dark_gc[state_type];
gc3 = style->dark_gc[state_type];
gc4 = style->light_gc[state_type];
break;
case GTK_SHADOW_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
gc3 = style->dark_gc[state_type];
gc4 = style->light_gc[state_type];
break;
case GTK_SHADOW_ETCHED_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
gc3 = style->light_gc[state_type];
gc4 = style->dark_gc[state_type];
break;
default:
return;
}
if (area)
{
gdk_gc_set_clip_rectangle(gc1, area);
gdk_gc_set_clip_rectangle(gc2, area);
gdk_gc_set_clip_rectangle(gc3, area);
gdk_gc_set_clip_rectangle(gc4, area);
}
if (fill)
gdk_draw_polygon(window, style->bg_gc[state_type], TRUE, points, npoints);
npoints--;
for (i = 0; i < npoints; i++)
{
if ((points[i].x == points[i + 1].x) &&
(points[i].y == points[i + 1].y))
{
angle = 0;
}
else
{
angle = atan2(points[i + 1].y - points[i].y,
points[i + 1].x - points[i].x);
}
if ((angle > -pi_3_over_4) && (angle < pi_over_4))
{
if (angle > -pi_over_4)
{
xadjust = 0;
yadjust = 1;
}
else
{
xadjust = 1;
yadjust = 0;
}
gdk_draw_line(window, gc1,
points[i].x - xadjust, points[i].y - yadjust,
points[i + 1].x - xadjust, points[i + 1].y - yadjust);
gdk_draw_line(window, gc3,
points[i].x, points[i].y,
points[i + 1].x, points[i + 1].y);
}
else
{
if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
{
xadjust = 0;
yadjust = 1;
}
else
{
xadjust = 1;
yadjust = 0;
}
gdk_draw_line(window, gc4,
points[i].x + xadjust, points[i].y + yadjust,
points[i + 1].x + xadjust, points[i + 1].y + yadjust);
gdk_draw_line(window, gc2,
points[i].x, points[i].y,
points[i + 1].x, points[i + 1].y);
}
}
if (area)
{
gdk_gc_set_clip_rectangle(gc1, NULL);
gdk_gc_set_clip_rectangle(gc2, NULL);
gdk_gc_set_clip_rectangle(gc3, NULL);
gdk_gc_set_clip_rectangle(gc4, NULL);
}
}
static void
draw_arrow(GtkStyle* style,
GdkWindow* window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle* area,
GtkWidget* widget,
const gchar *detail,
GtkArrowType arrow_type,
gint fill, gint x, gint y, gint width, gint height)
{
sanitize_size(window, &width, &height);
if (gtkQtDebug) {
printf("Arrow (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
if (DETAIL("hscrollbar") || DETAIL("vscrollbar")) {
return;
}
if (DETAIL("spinbutton")) {
return;
}
if (DETAIL("notebook"))
{
drawArrow(window, style, state_type, arrow_type, x, y, width, height);
return;
}
if (DETAIL("arrow"))
{
GdkPixbuf *gpix;
GtkWidget* parent;
if (gdk_window_is_viewable(gtk_widget_get_parent_window(widget)))
{
gpix = gdk_pixbuf_get_from_drawable(NULL, gtk_widget_get_parent_window(widget),NULL, x, y, 0, 0, width, height);
setFillPixmap(gpix);
g_object_unref(gpix);
}
parent = gtk_widget_get_parent(widget);
drawArrow(window,style, gtk_widget_get_state(parent), arrow_type, x, y, width, height);
return;
}
/* if (DETAIL("menuitem"))
{
GdkGC *gc1;
GdkGC *gc2;
GdkGC *gc3;
GdkGC *gc4;
gint half_width;
gint half_height;
gint ax, ay, aw, ah;
switch (shadow_type)
{
case GTK_SHADOW_IN:
gc1 = style->bg_gc[state_type];
gc2 = style->dark_gc[state_type];
gc3 = style->light_gc[state_type];
gc4 = style->black_gc;
break;
case GTK_SHADOW_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
gc3 = style->black_gc;
gc4 = style->bg_gc[state_type];
break;
case GTK_SHADOW_ETCHED_IN:
gc2 = style->light_gc[state_type];
gc1 = style->dark_gc[state_type];
gc3 = NULL;
gc4 = NULL;
break;
case GTK_SHADOW_ETCHED_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
gc3 = NULL;
gc4 = NULL;
break;
default:
return;
}
sanitize_size(window, &width, &height);
ax = x;
ay = y;
aw = width;
ah = height;
calculate_arrow_geometry (arrow_type, &ax, &ay, &aw, &ah);
half_width = width / 2;
half_height = height / 2;
if (area)
{
gdk_gc_set_clip_rectangle(gc1, area);
gdk_gc_set_clip_rectangle(gc2, area);
if ((gc3) && (gc4))
{
gdk_gc_set_clip_rectangle(gc3, area);
gdk_gc_set_clip_rectangle(gc4, area);
}
}
if (state_type == GTK_STATE_INSENSITIVE)
draw_black_arrow (window, style->white_gc, area, arrow_type, ax + 1, ay + 1, aw, ah);
draw_black_arrow (window, style->fg_gc[state_type], area, arrow_type, ax, ay, aw, ah);
if (area)
{
gdk_gc_set_clip_rectangle(gc1, NULL);
gdk_gc_set_clip_rectangle(gc2, NULL);
if (gc3)
{
gdk_gc_set_clip_rectangle(gc3, NULL);
gdk_gc_set_clip_rectangle(gc4, NULL);
}
}
}*/
else
{
GdkPixbuf *gpix;
if (gdk_window_is_viewable(gtk_widget_get_parent_window(widget)))
{
gpix = gdk_pixbuf_get_from_drawable(NULL, gtk_widget_get_parent_window(widget),NULL, x, y, 0, 0, width, height);
setFillPixmap(gpix);
g_object_unref(gpix);
}
drawArrow(window, style, state_type, arrow_type, x, y, width, height);
return;
}
}
static void
draw_diamond(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
}
// static void
// draw_string(GtkStyle *style,
// GdkWindow *window,
// GtkStateType state_type,
// GdkRectangle *area,
// GtkWidget *widget,
// const gchar *detail,
// gint x,
// gint y,
// const gchar *string)
// {
// if (gtkQtDebug)
// printf("STRING Widget: %s Detail: %s\n",gtk_widget_get_name(widget),detail);
// }
static void
draw_box(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
GList *child_list;
GtkWidget *child;
GtkNotebook *nb;
int nbpages;
sanitize_size(window, &width, &height);
if (gtkQtDebug) {
printf("Box (%d,%d,%d,%d) Widget: %s Detail: %s\n",x,y,width,height,gtk_widget_get_name(widget),detail);
}
if (GTK_IS_SCROLLBAR(widget))
{
if (DETAIL("trough"))
{
GtkAdjustment* adj = (GtkAdjustment*)gtk_range_get_adjustment(GTK_RANGE(widget));
int orientation = ((width>height) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
if (orientation == GTK_ORIENTATION_VERTICAL) {
drawScrollBar(window, style, state_type, orientation, adj, x+1, y, width, height);
}
else {
drawScrollBar(window, style, state_type, orientation, adj, x, y+1, width, height);
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (DETAIL("menuitem"))
{
/* Crude way of checking if it's a menu item, or a menubar item */
if (x != 0) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenuBarItem(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenuItem(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (DETAIL("menubar"))
{
if (openOfficeFix == 1) {
parent_class->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
}
else if (mozillaFix == 1) {
parent_class->draw_box (style, window, state_type, GTK_SHADOW_NONE, area, widget, detail, x, y, width, height);
}
else {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenubar(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (DETAIL("menu"))
{
if (openOfficeFix == 1) {
parent_class->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
}
else {
if ((x >= 0) && (y >= 0)) { /* Work around weirdness in firefox */
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenu(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
}
return;
}
if (GTK_IS_PROGRESS(widget) && DETAIL("trough"))
{
double fraction = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(widget));
GtkProgressBarOrientation orientation = gtk_progress_bar_get_orientation(GTK_PROGRESS_BAR(widget));
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawProgressBar(window,style,state_type,orientation,fraction,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (GTK_IS_PROGRESS(widget) && DETAIL("bar"))
{
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawProgressChunk(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (GTK_IS_SCALE(widget) && DETAIL("trough"))
{
GtkAdjustment* adj;
int inverted;
GValue *val = (GValue*)g_malloc( sizeof(GValue) );
if (gdk_window_is_viewable(gtk_widget_get_parent_window(widget))) {
GdkPixbuf *gpix;
gpix = gdk_pixbuf_get_from_drawable(NULL, gtk_widget_get_parent_window(widget),NULL, x, y, 0, 0, width, height);
setFillPixmap(gpix);
g_object_unref(gpix);
}
memset( val, 0, sizeof(GValue) );
g_value_init( val, G_TYPE_BOOLEAN );
g_object_get_property(G_OBJECT(widget), "inverted", val);
inverted = g_value_get_boolean(val);
g_value_unset(val);
g_free(val);
adj = gtk_range_get_adjustment((GtkRange *) widget);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSlider(window,style,state_type,adj,x,y,width,height, (GTK_RANGE(widget))->orientation, inverted);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("button"))
{
GtkWidget *parent;
int toolbutton = 0;
parent = gtk_widget_get_parent(widget);
if (parent && (GTK_IS_CLIST(parent) || GTK_IS_LIST(parent) || GTK_IS_TREE_VIEW(parent))) {
drawListHeader(window,style,state_type,x,y,width,height);
return;
}
/* this is a very very bad hack but there seems to be no way to find if a button is on a
* toolbar in gtk */
while (1) {
if (GTK_IS_WIDGET(parent)) {
#ifdef HAVE_BONOBO
if (GTK_IS_TOOLBAR(parent) || BONOBO_IS_UI_TOOLBAR(parent))
#else
if (GTK_IS_TOOLBAR(parent))
#endif
{
toolbutton = 1;
break;
}
}
else {
break;
}
parent = gtk_widget_get_parent(parent);
}
parent = gtk_widget_get_parent(widget);
if (toolbutton) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawToolButton(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else {
/* Baghira hack -- rounded buttons really ugly when they are small like
on a dropdown entry box -- eg. search/replace in gedit */
/* Draw square buttons only if number of children in the hbox is 2 and
* the first child is a entry view (GtkEntry)*/
int defaultButton = gtk_widget_has_focus(widget);
GtkWindow* toplevel;
if (isBaghira && GTK_IS_BOX(parent) && (g_list_length(GTK_BOX(parent)->children) == 2)) {
child_list = g_list_first((GTK_BOX(parent)->children));
child = (GtkWidget *)child_list->data;
if (GTK_IS_ENTRY(child)) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSquareButton(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
child_list = g_list_last((GTK_BOX(parent)->children));
child = ((GtkBoxChild *)child_list->data)->widget;
if (GTK_IS_ENTRY(child)) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSquareButton(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
}
toplevel = GTK_WINDOW(gtk_widget_get_toplevel(widget));
if (toplevel && toplevel->default_widget == widget) {
defaultButton = 1;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawButton(window,style,state_type,defaultButton,x,y,width,height,GTK_BUTTON(widget));
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (DETAIL("tab"))
{
if (GTK_IS_NOTEBOOK(widget))
{
nb = (GtkNotebook *)widget;
nbpages = g_list_length(nb->children);
/* THIS IS WHAT WORKS NOW --
Tabs and tabbarbase will be drawn properly according to the QT style
But the tabs won't be aligned according to QT. GTK+ does not have
an option for alignment of tabs. So if were to do this not only do we have to
calculate the x,y position of the tab ourselves, which is difficult in Qt unless
we are displaying the tab (can be done by subclassing TQTabBar/TQTabWidget)
but also have to position the tab bar label ourselves in gtk.
*/
/* Check if we have seen this notebook before */
if ((nb != notebook) || (nbpages != nb_num_pages))
{
notebook = nb;
nb_num_pages = nbpages;
initDrawTabNG(nbpages);
}
/* Now draw the tab -- tab position is also calculated in this function
checkout drawTabFrame() for drawing tabbarbase. */
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawTabNG(window,style,state_type,x, y, width/*-2*/, height, nb );
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawTab(window,style,state_type,x,y,width/*-2*/,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (DETAIL("optionmenu")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawComboBox(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("toolbar")) {
if (openOfficeFix == 1)
parent_class->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
else
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawToolbar(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("spinbutton_up")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSpinButton(window, style, state_type, 0, x, y, width, height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("spinbutton_down")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSpinButton(window, style, state_type, 1, x, y, width, height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
if (DETAIL("spinbutton")) {
return;
}
if (DETAIL("optionmenutab") || DETAIL("buttondefault")) {
return;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawFrame(window,style,state_type,shadow_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
static void
draw_flat_box(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
sanitize_size(window, &width, &height);
if (gtkQtDebug) {
printf("Flat Box (%d,%d,%d,%d) Widget: %s Detail: %s %d %d\n",x,y,width,height,gtk_widget_get_name(widget),detail, state_type, GTK_STATE_SELECTED);
}
if (DETAIL("tooltip")) {
GdkColor tooltipColor;
GdkGCValues gc_values;
GdkGCValuesMask gc_values_mask;
GdkGC* tooltipGc;
tooltipColor.red = 255*257;
tooltipColor.green = 255*257;
tooltipColor.blue = 220*257;
gdk_colormap_alloc_color(style->colormap, &tooltipColor, FALSE, TRUE);
gc_values_mask = GDK_GC_FOREGROUND;
gc_values.foreground = tooltipColor;
tooltipGc = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gdk_draw_rectangle(window, tooltipGc, TRUE, x, y, width, height);
gdk_draw_rectangle(window, style->black_gc, FALSE, x, y, width - 1, height - 1);
gtk_gc_release(tooltipGc);
}
if ((DETAILHAS("cell_even") || DETAILHAS("cell_odd")) && (state_type == GTK_STATE_SELECTED)) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawListViewItem(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else if (DETAIL("listitem")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawListViewItem(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else if (DETAILHAS("cell_even")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
gdk_draw_rectangle(window, style->base_gc[GTK_STATE_NORMAL], TRUE, x, y, width, height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else if (DETAILHAS("cell_odd")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
gdk_draw_rectangle(window, alternateBackgroundGc(style), TRUE, x, y, width, height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
}
static void
draw_check(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
if (gtkQtDebug) {
printf("Check (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
if (GTK_IS_MENU_ITEM(widget)) {
if (shadow_type == GTK_SHADOW_IN) {
if (gdk_window_is_viewable(gtk_widget_get_parent_window(widget))) {
GdkPixbuf *gpix;
gpix = gdk_pixbuf_get_from_drawable(NULL, gtk_widget_get_parent_window(widget), NULL, x, y, 0, 0, width, height);
setFillPixmap(gpix);
g_object_unref(gpix);
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenuCheck(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawCheckBox(window,style,state_type,(shadow_type==GTK_SHADOW_IN),x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
/* Thanks to Evan Lawrence */
static void
draw_option(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
if (gtkQtDebug) {
printf("Option (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
if (gdk_window_is_viewable(gtk_widget_get_parent_window(widget))) {
GdkPixbuf *gpix;
gpix = gdk_pixbuf_get_from_drawable(NULL, gtk_widget_get_parent_window(widget),NULL, x, y, 0, 0, width, height);
setFillPixmap(gpix);
g_object_unref(gpix);
}
if (GTK_IS_MENU_ITEM(widget))
{
if (shadow_type == GTK_SHADOW_IN) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawMenuCheck(window,style,state_type,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawRadioButton(window,style,state_type,(shadow_type==GTK_SHADOW_IN),x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
static void
draw_tab(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
if (gtkQtDebug) {
printf("Tab (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
gtk_paint_box(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
}
static void
draw_shadow_gap(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height,
GtkPositionType gap_side,
gint gap_x,
gint gap_width)
{
GdkGC *gc1 = NULL;
GdkGC *gc2 = NULL;
g_return_if_fail (window != NULL);
sanitize_size (window, &width, &height);
shadow_type = get_shadow_type (style, detail, shadow_type);
if (gtkQtDebug)
printf("Shadow_Gap (%d,%d,%d,%d) Widget: %s Detail: %s\n",x,y,width,height,gtk_widget_get_name(widget),detail);
switch (shadow_type) {
case GTK_SHADOW_NONE:
return;
case GTK_SHADOW_IN:
gc1 = style->dark_gc[state_type];
gc2 = style->light_gc[state_type];
break;
case GTK_SHADOW_OUT:
gc1 = style->light_gc[state_type];
gc2 = style->dark_gc[state_type];
break;
case GTK_SHADOW_ETCHED_IN:
case GTK_SHADOW_ETCHED_OUT:
gc1 = style->dark_gc[state_type];
gc2 = style->dark_gc[state_type];
}
if (area) {
gdk_gc_set_clip_rectangle (gc1, area);
gdk_gc_set_clip_rectangle (gc2, area);
}
switch (gap_side) {
case GTK_POS_TOP:
if (gap_x > 0) {
gdk_draw_line (window, gc1,
x, y,
x + gap_x, y);
}
if ((width - (gap_x + gap_width)) > 0) {
gdk_draw_line (window, gc1,
x + gap_x + gap_width - 1, y,
x + width - 1, y);
}
gdk_draw_line (window, gc1,
x, y,
x, y + height - 1);
gdk_draw_line (window, gc2,
x + width - 1, y,
x + width - 1, y + height - 1);
gdk_draw_line (window, gc2,
x, y + height - 1,
x + width - 1, y + height - 1);
break;
case GTK_POS_BOTTOM:
gdk_draw_line (window, gc1,
x, y,
x + width - 1, y);
gdk_draw_line (window, gc1,
x, y,
x, y + height - 1);
gdk_draw_line (window, gc2,
x + width - 1, y,
x + width - 1, y + height - 1);
if (gap_x > 0) {
gdk_draw_line (window, gc2,
x, y + height - 1,
x + gap_x, y + height - 1);
}
if ((width - (gap_x + gap_width)) > 0) {
gdk_draw_line (window, gc2,
x + gap_x + gap_width - 1, y + height - 1,
x + width - 1, y + height - 1);
}
break;
case GTK_POS_LEFT:
gdk_draw_line (window, gc1,
x, y,
x + width - 1, y);
if (gap_x > 0) {
gdk_draw_line (window, gc1,
x, y,
x, y + gap_x);
}
if ((height - (gap_x + gap_width)) > 0) {
gdk_draw_line (window, gc1,
x, y + gap_x + gap_width - 1,
x, y + height - 1);
}
gdk_draw_line (window, gc2,
x + width - 1, y,
x + width - 1, y + height - 1);
gdk_draw_line (window, gc2,
x, y + height - 1,
x + width - 1, y + height - 1);
break;
case GTK_POS_RIGHT:
gdk_draw_line (window, gc1,
x, y,
x + width - 1, y);
gdk_draw_line (window, gc1,
x, y,
x, y + height - 1);
if (gap_x > 0) {
gdk_draw_line (window, gc2,
x + width - 1, y,
x + width - 1, y + gap_x);
}
if ((height - (gap_x + gap_width)) > 0) {
gdk_draw_line (window, gc2,
x + width - 1, y + gap_x + gap_width - 1,
x + width - 1, y + height - 1);
}
gdk_draw_line (window, gc2,
x, y + height - 1,
x + width - 1, y + height - 1);
}
if (area) {
gdk_gc_set_clip_rectangle (gc1, NULL);
gdk_gc_set_clip_rectangle (gc2, NULL);
}
}
static void
draw_box_gap(GtkStyle* style,
GdkWindow* window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle* area,
GtkWidget* widget,
const gchar* detail,
gint x,
gint y,
gint width,
gint height,
GtkPositionType gap_side,
gint gap_x,
gint gap_width)
{
sanitize_size (window, &width, &height);
if (width<0 || height<0) return; /* Eclipse really can be this stupid! */
if (gtkQtDebug) {
printf("Box_gap (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
if (DETAIL("notebook")) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawTabFrame(window,style,state_type,x,y-2,width,height+2, gtk_notebook_get_tab_pos((GtkNotebook *)widget));
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
}
static void
draw_extension(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height,
GtkPositionType gap_side)
{
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
sanitize_size (window, &width, &height);
if (gtkQtDebug) {
printf("Extension (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
gtk_paint_box(style, window, state_type, shadow_type, area, widget, detail,
x, y, width, height);
}
static void
draw_focus (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
if (gtkQtDebug) {
printf("Focus Rect (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
GtkWidget* parent = gtk_widget_get_parent(widget);
if (GTK_IS_CHECK_BUTTON(widget) ||
GTK_IS_RADIO_BUTTON(widget) ||
(parent && (GTK_IS_CLIST(parent) || GTK_IS_LIST(parent) || GTK_IS_TREE_VIEW(parent))))
{
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawFocusRect(window, style, x, y, width, height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
static void
draw_slider(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height,
GtkOrientation orientation)
{
if (gtkQtDebug) {
printf("Slider (%d,%d,%d,%d) Widget: %s Detail: %s\n", x, y, width, height,gtk_widget_get_name(widget),detail);
}
if (DETAIL("slider")) {
GtkAdjustment* adj = gtk_range_get_adjustment(GTK_RANGE(widget));
int widgetX, widgetY;
GtkWidget* parent = widget;
while (gtk_widget_get_parent(parent) != NULL) {
parent = gtk_widget_get_parent(parent);
}
gtk_widget_translate_coordinates(widget, parent, 0, 0, &widgetX, &widgetY);
if (orientation == GTK_ORIENTATION_VERTICAL) {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawScrollBarSlider(window, style, state_type, orientation, adj, x, y, width, height, y-widgetY, widget->allocation.height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
else {
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawScrollBarSlider(window, style, state_type, orientation, adj, x, y, width, height, x-widgetX, widget->allocation.width);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
}
return;
}
}
static void
draw_handle(GtkStyle * style,
GdkWindow * window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height,
GtkOrientation orientation)
{
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
sanitize_size(window, &width, &height);
if (gtkQtDebug) {
printf("Handle (%d,%d,%d,%d) Widget: %s Detail: %s State Type: %d\n",x,y,width,height,gtk_widget_get_name(widget),detail, state_type);
}
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], area);
drawSplitter(window,style,state_type,orientation,x,y,width,height);
if (area) gdk_gc_set_clip_rectangle(style->bg_gc[state_type], NULL);
return;
}
static
void draw_layout (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
gboolean use_text,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
PangoLayout *layout)
{
gboolean paint_layout = TRUE;
GdkColor color;
GdkGC *gc;
getTextColor(&color, state_type);
if (gtkQtDebug)
printf("Layout (%d,%d) Widget: %s Detail: %s State Type: %d use_text: %d\n",x,y,gtk_widget_get_name(widget),detail, state_type, use_text);
#ifdef USE_NATIVE_GTK_BUTTON_DRAWING
#else
GtkWidget* parent;
parent = gtk_widget_get_parent(widget);
while (parent) {
if (gtkQtDebug)
printf("Layout Parent: %s\n",gtk_widget_get_name(parent));
if (strcmp("GtkButton", gtk_widget_get_name(parent)) == 0) {
paint_layout = FALSE;
}
parent = gtk_widget_get_parent(parent);
}
#endif
if (!paint_layout)
return;
if (DETAIL("accellabel") || DETAIL("label") || DETAIL("cellrenderertext"))
{
GtkWidget* parent = gtk_widget_get_parent(widget);
GtkWidget* parent1 = gtk_widget_get_parent(parent);
/* printf("parent's names are %s->%s->%s\n", gtk_widget_get_name(widget), gtk_widget_get_name(parent), gtk_widget_get_name(parent1)); */
/* In baghira -- even highlight the menu bar items */
if ((GTK_IS_MENU_ITEM(parent) && (!GTK_IS_MENU_BAR(parent1) || isBaghira || isPolyester)) || GTK_IS_TREE_VIEW(widget))
{
PangoAttrList *layoutattr;
const gchar *text;
gint text_bytelen = 0;
text = pango_layout_get_text (layout);
if (text != 0)
{
PangoAttribute *textcolorattr;
text_bytelen = strlen (text);
textcolorattr = pango_attr_foreground_new(color.red, color.green, color.blue);
textcolorattr->start_index = 0;
textcolorattr->end_index = text_bytelen;
layoutattr = pango_layout_get_attributes(layout);
if (layoutattr == NULL)
{
layoutattr = pango_attr_list_new();
pango_attr_list_insert(layoutattr, pango_attribute_copy(textcolorattr));
pango_layout_set_attributes(layout,layoutattr);
pango_attr_list_unref(layoutattr);
}
else
{
pango_attr_list_change(layoutattr, pango_attribute_copy(textcolorattr));
pango_layout_set_attributes(layout,layoutattr);
}
pango_attribute_destroy(textcolorattr);
}
}
/* printf("Drawing an label -- with state %d at %d %d\n", state_type, x, y); */
}
g_return_if_fail (window != NULL);
gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
if (area)
gdk_gc_set_clip_rectangle (gc, area);
if (state_type == GTK_STATE_INSENSITIVE)
{
PangoLayout *ins;
ins = get_insensitive_layout (window, layout);
gdk_draw_layout (window, gc, x, y, ins);
g_object_unref (ins);
}
else
{
gdk_draw_layout (window, gc, x, y, layout);
}
if (area)
gdk_gc_set_clip_rectangle (gc, NULL);
}
typedef struct _ByteRange ByteRange;
struct _ByteRange
{
guint start;
guint end;
};
static ByteRange*
range_new (guint start,
guint end)
{
ByteRange *br = g_new (ByteRange, 1);
br->start = start;
br->end = end;
return br;
}
static PangoLayout*
get_insensitive_layout (GdkDrawable *drawable,
PangoLayout *layout)
{
GSList *embossed_ranges = NULL;
GSList *stippled_ranges = NULL;
PangoLayoutIter *iter;
GSList *tmp_list = NULL;
PangoLayout *new_layout;
PangoAttrList *attrs;
GdkBitmap *stipple = NULL;
iter = pango_layout_get_iter (layout);
do
{
PangoLayoutRun *run;
PangoAttribute *attr;
gboolean need_stipple = FALSE;
ByteRange *br;
run = pango_layout_iter_get_run (iter);
if (run)
{
tmp_list = run->item->analysis.extra_attrs;
while (tmp_list != NULL)
{
attr = tmp_list->data;
switch (attr->klass->type)
{
case PANGO_ATTR_FOREGROUND:
case PANGO_ATTR_BACKGROUND:
need_stipple = TRUE;
break;
default:
break;
}
if (need_stipple)
break;
tmp_list = g_slist_next (tmp_list);
}
br = range_new (run->item->offset, run->item->offset + run->item->length);
if (need_stipple)
stippled_ranges = g_slist_prepend (stippled_ranges, br);
else
embossed_ranges = g_slist_prepend (embossed_ranges, br);
}
}
while (pango_layout_iter_next_run (iter));
pango_layout_iter_free (iter);
new_layout = pango_layout_copy (layout);
attrs = pango_layout_get_attributes (new_layout);
if (attrs == NULL)
{
/* Create attr list if there wasn't one */
attrs = pango_attr_list_new ();
pango_layout_set_attributes (new_layout, attrs);
pango_attr_list_unref (attrs);
}
tmp_list = embossed_ranges;
while (tmp_list != NULL)
{
PangoAttribute *attr;
ByteRange *br = tmp_list->data;
attr = gdk_pango_attr_embossed_new (TRUE);
attr->start_index = br->start;
attr->end_index = br->end;
pango_attr_list_change (attrs, attr);
g_free (br);
tmp_list = g_slist_next (tmp_list);
}
g_slist_free (embossed_ranges);
tmp_list = stippled_ranges;
while (tmp_list != NULL)
{
PangoAttribute *attr;
ByteRange *br = tmp_list->data;
if (stipple == NULL)
{
#define gray50_width 2
#define gray50_height 2
static const char gray50_bits[] = {
0x02, 0x01
};
stipple = gdk_bitmap_create_from_data (drawable,
gray50_bits, gray50_width,
gray50_height);
}
attr = gdk_pango_attr_stipple_new (stipple);
attr->start_index = br->start;
attr->end_index = br->end;
pango_attr_list_change (attrs, attr);
g_free (br);
tmp_list = g_slist_next (tmp_list);
}
g_slist_free (stippled_ranges);
if (stipple)
g_object_unref (stipple);
return new_layout;
}
GType qtengine_type_style = 0;
void
qtengine_style_register_type (GTypeModule *module)
{
static const GTypeInfo object_info =
{
sizeof (QtEngineStyleClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) qtengine_style_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (QtEngineStyle),
0, /* n_preallocs */
(GInstanceInitFunc) qtengine_style_init,
};
qtengine_type_style = g_type_module_register_type (module,
GTK_TYPE_STYLE,
"QtEngineStyle",
&object_info, 0);
}
static void
qtengine_style_init (QtEngineStyle *style)
{
}
/* Copied these functions from gtkstyle.c
Evil, evil GTK... why isn't this stuff exported? */
#define LIGHTNESS_MULT 1.3
#define DARKNESS_MULT 0.7
static void
rgb_to_hls (gdouble *r,
gdouble *g,
gdouble *b)
{
gdouble min;
gdouble max;
gdouble red;
gdouble green;
gdouble blue;
gdouble h, l, s;
gdouble delta;
red = *r;
green = *g;
blue = *b;
if (red > green)
{
if (red > blue)
max = red;
else
max = blue;
if (green < blue)
min = green;
else
min = blue;
}
else
{
if (green > blue)
max = green;
else
max = blue;
if (red < blue)
min = red;
else
min = blue;
}
l = (max + min) / 2;
s = 0;
h = 0;
if (max != min)
{
if (l <= 0.5)
s = (max - min) / (max + min);
else
s = (max - min) / (2 - max - min);
delta = max -min;
if (red == max)
h = (green - blue) / delta;
else if (green == max)
h = 2 + (blue - red) / delta;
else if (blue == max)
h = 4 + (red - green) / delta;
h *= 60;
if (h < 0.0)
h += 360;
}
*r = h;
*g = l;
*b = s;
}
static void
hls_to_rgb (gdouble *h,
gdouble *l,
gdouble *s)
{
gdouble hue;
gdouble lightness;
gdouble saturation;
gdouble m1, m2;
gdouble r, g, b;
lightness = *l;
saturation = *s;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
if (saturation == 0)
{
*h = lightness;
*l = lightness;
*s = lightness;
}
else
{
hue = *h + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
r = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
r = m2;
else if (hue < 240)
r = m1 + (m2 - m1) * (240 - hue) / 60;
else
r = m1;
hue = *h;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
g = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
g = m2;
else if (hue < 240)
g = m1 + (m2 - m1) * (240 - hue) / 60;
else
g = m1;
hue = *h - 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
b = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
b = m2;
else if (hue < 240)
b = m1 + (m2 - m1) * (240 - hue) / 60;
else
b = m1;
*h = r;
*l = g;
*s = b;
}
}
static void
gtk_style_shade (GdkColor *a,
GdkColor *b,
gdouble k)
{
gdouble red;
gdouble green;
gdouble blue;
red = (gdouble) a->red / 65535.0;
green = (gdouble) a->green / 65535.0;
blue = (gdouble) a->blue / 65535.0;
rgb_to_hls (&red, &green, &blue);
green *= k;
if (green > 1.0)
green = 1.0;
else if (green < 0.0)
green = 0.0;
blue *= k;
if (blue > 1.0)
blue = 1.0;
else if (blue < 0.0)
blue = 0.0;
hls_to_rgb (&red, &green, &blue);
b->red = red * 65535.0;
b->green = green * 65535.0;
b->blue = blue * 65535.0;
}
static void
gtk_style_real_realize (GtkStyle *style)
{
GdkGCValues gc_values;
GdkGCValuesMask gc_values_mask;
gint i;
for (i = 0; i < 5; i++)
{
gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
}
style->black.red = 0x0000;
style->black.green = 0x0000;
style->black.blue = 0x0000;
gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
style->white.red = 0xffff;
style->white.green = 0xffff;
style->white.blue = 0xffff;
gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
gc_values_mask = GDK_GC_FOREGROUND;
gc_values.foreground = style->black;
style->black_gc = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->white;
style->white_gc = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
for (i = 0; i < 5; i++)
{
if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->fg[i].red, style->fg[i].green, style->fg[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->bg[i].red, style->bg[i].green, style->bg[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->light[i].red, style->light[i].green, style->light[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->dark[i].red, style->dark[i].green, style->dark[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->mid[i].red, style->mid[i].green, style->mid[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->text[i].red, style->text[i].green, style->text[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->base[i].red, style->base[i].green, style->base[i].blue);
if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
g_warning ("unable to allocate color: ( %d %d %d )",
style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
gc_values.foreground = style->fg[i];
style->fg_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->bg[i];
style->bg_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->light[i];
style->light_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->dark[i];
style->dark_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->mid[i];
style->mid_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->text[i];
style->text_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->base[i];
style->base_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
gc_values.foreground = style->text_aa[i];
style->text_aa_gc[i] = (GdkGC*) gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
}
}
static void
realize (GtkStyle* style)
{
setColors(style);
gtk_style_real_realize(style);
}
static void
set_background (GtkStyle *style, GdkWindow *window, GtkStateType state_type)
{
GdkPixmap *pixmap;
gint parent_relative;
GdkPixmap* pix_test;
/* What kind of horrible person would store a pointer to a widget here... */
void* parent = 0;
gdk_window_get_user_data(window, &parent);
if (GTK_IS_MENU((GtkWidget*) parent))
{
pix_test = TQTENGINE_STYLE(style)->menuBackground;
}
else
pix_test = style->bg_pixmap[state_type];
if (pix_test)
{
if (pix_test == (GdkPixmap*) GDK_PARENT_RELATIVE)
{
pixmap = NULL;
parent_relative = TRUE;
}
else
{
pixmap = pix_test;
parent_relative = FALSE;
gdk_drawable_set_colormap(pixmap, style->colormap);
}
if (pixmap && !gdk_drawable_get_colormap (pixmap)) gdk_drawable_set_colormap (pixmap, gdk_drawable_get_colormap (window));
gdk_window_set_back_pixmap (window, pixmap, parent_relative);
}
else
gdk_window_set_background (window, &style->bg[state_type]);
}
static void
qtengine_style_class_init (QtEngineStyleClass *klass)
{
GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
stockRenderIcon = style_class->render_icon;
// stockDrawString = style_class->draw_string;
style_class->render_icon = draw_icon;
style_class->draw_hline = draw_hline;
style_class->draw_vline = draw_vline;
style_class->draw_shadow = draw_shadow;
style_class->draw_polygon = draw_polygon;
style_class->draw_arrow = draw_arrow;
style_class->draw_diamond = draw_diamond;
// style_class->draw_string = draw_string;
style_class->draw_box = draw_box;
style_class->draw_flat_box = draw_flat_box;
style_class->draw_check = draw_check;
style_class->draw_option = draw_option;
style_class->draw_tab = draw_tab;
style_class->draw_shadow_gap = draw_shadow_gap;
/* box around notebooks */
style_class->draw_box_gap = draw_box_gap;
/* the tab */
style_class->draw_extension = draw_extension;
style_class->draw_focus = draw_focus;
style_class->draw_handle = draw_handle;
style_class->draw_layout = draw_layout;
style_class->draw_slider = draw_slider;
style_class->realize = realize;
style_class->set_background = set_background;
}