From af1edc3d8809f35092c25eedfdb81af7c7a45e2a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 27 Mar 2010 21:23:13 +0100 Subject: [PATCH] GtkThemingEngine: Add vmethod to render frames with a gap. --- gtk/gtkthemingengine.c | 145 +++++++++++++++++++++++++++++++++++++++++ gtk/gtkthemingengine.h | 9 +++ 2 files changed, 154 insertions(+) diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index f824dfe54a..b95d6de6b6 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -103,6 +103,15 @@ static void gtk_theming_engine_render_slider (GtkThemingEngine *engine, gdouble width, gdouble height, GtkOrientation orientation); +static void gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine, + cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + GtkPositionType gap_side, + gdouble xy0_gap, + gdouble xy1_gap); G_DEFINE_TYPE (GtkThemingEngine, gtk_theming_engine, G_TYPE_OBJECT) @@ -144,6 +153,7 @@ gtk_theming_engine_class_init (GtkThemingEngineClass *klass) klass->render_layout = gtk_theming_engine_render_layout; klass->render_line = gtk_theming_engine_render_line; klass->render_slider = gtk_theming_engine_render_slider; + klass->render_frame_gap = gtk_theming_engine_render_frame_gap; g_type_class_add_private (object_class, sizeof (GtkThemingEnginePrivate)); } @@ -709,6 +719,51 @@ add_path_rounded_rectangle (cairo_t *cr, } } +static void +add_path_gap_side (cairo_t *cr, + GtkPositionType gap_side, + gdouble radius, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble xy0_gap, + gdouble xy1_gap) +{ + if (gap_side == GTK_POS_TOP) + { + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + xy0_gap, y); + + cairo_move_to (cr, x + xy1_gap, y); + cairo_line_to (cr, x + width, y); + } + else if (gap_side == GTK_POS_BOTTOM) + { + cairo_move_to (cr, x, y + height); + cairo_line_to (cr, x + xy0_gap, y + height); + + cairo_move_to (cr, x + xy1_gap, y + height); + cairo_line_to (cr, x + width, y + height); + } + else if (gap_side == GTK_POS_LEFT) + { + cairo_move_to (cr, x, y); + cairo_line_to (cr, x, y + xy0_gap); + + cairo_move_to (cr, x, y + xy1_gap); + cairo_line_to (cr, x, y + height); + } + else + { + cairo_move_to (cr, x + width, y); + cairo_line_to (cr, x + width, y + xy0_gap); + + cairo_move_to (cr, x + width, y + xy1_gap); + cairo_line_to (cr, x + width, y + height); + } +} + static void color_shade (const GdkColor *color, gdouble factor, @@ -1111,5 +1166,95 @@ gtk_theming_engine_render_slider (GtkThemingEngine *engine, } } +static void +gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine, + cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + GtkPositionType gap_side, + gdouble xy0_gap, + gdouble xy1_gap) +{ + GtkStateFlags flags; + GtkStateType state; + GdkColor *bg_color; + GdkColor lighter, darker; + guint sides; + + cairo_save (cr); + flags = gtk_theming_engine_get_state (engine); + + if (flags & GTK_STATE_FLAG_PRELIGHT) + state = GTK_STATE_PRELIGHT; + else if (flags & GTK_STATE_FLAG_INSENSITIVE) + state = GTK_STATE_INSENSITIVE; + else + state = GTK_STATE_NORMAL; + + cairo_set_line_width (cr, 1); + + gtk_theming_engine_get (engine, state, + "background-color", &bg_color, + NULL); + color_shade (bg_color, 0.7, &darker); + color_shade (bg_color, 1.3, &lighter); + + if (gap_side == GTK_POS_RIGHT) + sides = SIDE_BOTTOM; + else if (gap_side == GTK_POS_BOTTOM) + sides = SIDE_RIGHT; + else + sides = SIDE_BOTTOM | SIDE_RIGHT; + + if (gap_side == GTK_POS_RIGHT || + gap_side == GTK_POS_BOTTOM) + add_path_gap_side (cr, gap_side, 0, + x, y, width, height, + xy0_gap, xy1_gap); + + add_path_rounded_rectangle (cr, 0, sides, + x, y, width, height); + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_stroke (cr); + + if (gap_side == GTK_POS_RIGHT || + gap_side == GTK_POS_BOTTOM) + add_path_gap_side (cr, gap_side, 0, + x, y, width, height, + xy0_gap, xy1_gap); + + add_path_rounded_rectangle (cr, 0, sides, + x, y, width - 1, height - 1); + + gdk_cairo_set_source_color (cr, &darker); + cairo_stroke (cr); + + if (gap_side == GTK_POS_LEFT) + sides = SIDE_TOP; + else if (gap_side == GTK_POS_TOP) + sides = SIDE_LEFT; + else + sides = SIDE_TOP | SIDE_LEFT; + + if (gap_side == GTK_POS_TOP || + gap_side == GTK_POS_LEFT) + add_path_gap_side (cr, gap_side, 0, + x, y, width, height, + xy0_gap, xy1_gap); + + add_path_rounded_rectangle (cr, 0, sides, + x, y, width, height); + + gdk_cairo_set_source_color (cr, &lighter); + cairo_stroke (cr); + + cairo_restore (cr); + + gdk_color_free (bg_color); +} + #define __GTK_THEMING_ENGINE_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkthemingengine.h b/gtk/gtkthemingengine.h index dd02bc5557..d085637eab 100644 --- a/gtk/gtkthemingengine.h +++ b/gtk/gtkthemingengine.h @@ -67,6 +67,15 @@ struct GtkThemingEngineClass gdouble y, gdouble width, gdouble height); + void (* render_frame_gap) (GtkThemingEngine *engine, + cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + GtkPositionType gap_side, + gdouble xy0_gap, + gdouble xy1_gap); void (* render_check) (GtkThemingEngine *engine, cairo_t *cr, gdouble x,