From 4962167864921ff372dc4d01d197b892cc37f473 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 6 Dec 2011 00:23:18 +0100 Subject: [PATCH] gtk-demo: Add test of transparent GdkWindows This shows a semi-transparent shadow from a GtkOverlay window --- demos/gtk-demo/Makefile.am | 1 + demos/gtk-demo/transparent.c | 248 +++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 demos/gtk-demo/transparent.c diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 2dac9ece8..e15a8c66e 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -43,6 +43,7 @@ demos = \ textview.c \ textscroll.c \ toolpalette.c \ + transparent.c \ tree_store.c \ ui_manager.c diff --git a/demos/gtk-demo/transparent.c b/demos/gtk-demo/transparent.c new file mode 100644 index 000000000..d1b2cb4f9 --- /dev/null +++ b/demos/gtk-demo/transparent.c @@ -0,0 +1,248 @@ +/* Transparent + * + * Use transparent background on GdkWindows to create a shadow effect on a GtkOverlay widget. + */ + +#include + +#define SHADOW_OFFSET_X 7 +#define SHADOW_OFFSET_Y 7 +#define SHADOW_RADIUS 5 + +static void +draw_shadow_box (cairo_t *cr, + GdkRectangle rect, + double radius, + double transparency) +{ + cairo_pattern_t *pattern; + double x0, x1, x2, x3; + double y0, y1, y2, y3; + + x0 = rect.x; + x1 = rect.x + radius; + x2 = rect.x + rect.width - radius; + x3 = rect.x + rect.width; + + y0 = rect.y; + y1 = rect.y + radius; + y2 = rect.y + rect.height - radius; + y3 = rect.y + rect.height; + + /* Fill non-border part */ + cairo_set_source_rgba (cr, 0, 0, 0, transparency); + cairo_rectangle (cr, + x1, y1, x2 - x1, y2 - y1); + cairo_fill (cr); + + /* Upper border */ + + pattern = cairo_pattern_create_linear (0, y0, 0, y1); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, transparency); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x1, y0, + x2 - x1, y1 - y0); + cairo_fill (cr); + + /* Bottom border */ + + pattern = cairo_pattern_create_linear (0, y2, 0, y3); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x1, y2, + x2 - x1, y3 - y2); + cairo_fill (cr); + + /* Left border */ + + pattern = cairo_pattern_create_linear (x0, 0, x1, 0); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, transparency); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x0, y1, + x1 - x0, y2 - y1); + cairo_fill (cr); + + /* Right border */ + + pattern = cairo_pattern_create_linear (x2, 0, x3, 0); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x2, y1, + x3 - x2, y2 - y1); + cairo_fill (cr); + + /* NW corner */ + + pattern = cairo_pattern_create_radial (x1, y1, 0, + x1, y1, radius); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x0, y0, + x1 - x0, y1 - y0); + cairo_fill (cr); + + /* NE corner */ + + pattern = cairo_pattern_create_radial (x2, y1, 0, + x2, y1, radius); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x2, y0, + x3 - x2, y1 - y0); + cairo_fill (cr); + + /* SW corner */ + + pattern = cairo_pattern_create_radial (x1, y2, 0, + x1, y2, radius); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x0, y2, + x1 - x0, y3 - y2); + cairo_fill (cr); + + /* SE corner */ + + pattern = cairo_pattern_create_radial (x2, y2, 0, + x2, y2, radius); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0, 0, transparency); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0, 0, 0.0); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, + x2, y2, + x3 - x2, y3 - y2); + cairo_fill (cr); +} + +static gboolean +draw_callback (GtkWidget *widget, + cairo_t *cr, + gpointer data) +{ + GdkRectangle rect; + + gtk_widget_get_allocation (widget, &rect); + rect.x += SHADOW_OFFSET_X; + rect.y += SHADOW_OFFSET_Y; + rect.width -= SHADOW_OFFSET_X; + rect.height -= SHADOW_OFFSET_Y; + + draw_shadow_box (cr, + rect, SHADOW_RADIUS, 0.4); + + return FALSE; +} + +GtkWidget * +do_transparent (GtkWidget *do_widget) +{ + static GtkWidget *window = NULL; + + if (!window) + { + GtkWidget *view; + GtkWidget *sw; + GtkWidget *overlay; + GtkWidget *align; + GtkWidget *entry; + GdkRGBA transparent = {0.1, 0, 0, 0}; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_default_size (GTK_WINDOW (window), + 450, 450); + + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + gtk_window_set_title (GTK_WINDOW (window), "Transparent"); + gtk_container_set_border_width (GTK_CONTAINER (window), 0); + + view = gtk_text_view_new (); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (sw), view); + + overlay = gtk_overlay_new (); + gtk_container_add (GTK_CONTAINER (overlay), sw); + gtk_container_add (GTK_CONTAINER (window), overlay); + + gtk_widget_override_background_color (overlay, 0, &transparent); + + align = gtk_alignment_new (0.0, 0.0, 0.0, 0.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (align), + 0, SHADOW_OFFSET_Y, 0, SHADOW_OFFSET_X); + g_signal_connect (align, "draw", G_CALLBACK (draw_callback), NULL); + + entry = gtk_entry_new (); + gtk_container_add (GTK_CONTAINER (align), entry); + + gtk_overlay_add_overlay (GTK_OVERLAY (overlay), align); + gtk_widget_set_halign (align, GTK_ALIGN_CENTER); + gtk_widget_set_valign (align, GTK_ALIGN_START); + + gtk_widget_show_all (overlay); + } + + if (!gtk_widget_get_visible (window)) + { + gtk_widget_show (window); + } + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} -- 2.43.2