#if defined( HAVE_CONFIG_H ) # include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_BONOBO #include #include #endif #include #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; }