diff options
author | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2016-07-01 19:39:04 -0300 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-07-03 17:24:47 -0400 |
commit | 1d93cc2b0b88bcc02f8a15d80b8a75d61d0cb24a (patch) | |
tree | f796bfe224909a03cf6bbac49ba261646f8f0de9 /demos/gtk-demo/css_blendmodes.c | |
parent | 27fea1c4fc7e178fd435a4bb0c5d5c836d72ed09 (diff) | |
download | gtk+-1d93cc2b0b88bcc02f8a15d80b8a75d61d0cb24a.tar.gz |
demo: add a demo for blend modes
After introducing the CSS blend mode enum values and including
the background-blend-mode CSS property, it is very important to
actually provide an example of the new feature.
This patch adds a new demo to gtk3-demo which shows how the
background-blend-mode CSS property works.
https://bugzilla.gnome.org/show_bug.cgi?id=768305
Diffstat (limited to 'demos/gtk-demo/css_blendmodes.c')
-rw-r--r-- | demos/gtk-demo/css_blendmodes.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/demos/gtk-demo/css_blendmodes.c b/demos/gtk-demo/css_blendmodes.c new file mode 100644 index 0000000000..4c4e6730a8 --- /dev/null +++ b/demos/gtk-demo/css_blendmodes.c @@ -0,0 +1,178 @@ +/* Theming/CSS Blend Modes + * + * You can blend multiple backgrounds using the CSS blend modes available. + */ + +#include <gtk/gtk.h> + +#define WID(x) ((GtkWidget*) gtk_builder_get_object (builder, x)) + +/* + * These are the available blend modes. + */ +struct { + gchar *name; + gchar *id; +} blend_modes[] = +{ + { "Color", "color" }, + { "Color (burn)", "color-burn" }, + { "Color (dodge)", "color-dodge" }, + { "Darken", "darken" }, + { "Difference", "difference" }, + { "Exclusion", "exclusion" }, + { "Hard Light", "hard-light" }, + { "Hue", "hue" }, + { "Lighten", "lighten" }, + { "Luminosity", "luminosity" }, + { "Multiply", "multiply" }, + { "Normal", "normal" }, + { "Overlay", "overlay" }, + { "Saturate", "saturate" }, + { "Screen", "screen" }, + { "Soft Light", "soft-light" }, + { NULL } +}; + +/* + * The CSS class to be applied in the blended image. Notice that the first %s + * is replaced by the content of css_blendmodes.css and the second %s is + * replaced by the blend mode. + */ +static const gchar *CSS_TEMPLATE = +"%s\n" +"\n" +"image.blend0 {\n" +" background-image: url('resource://css_blendmodes/ducky.png'),\n" +" linear-gradient(to right, red 0%, green 50%, blue 100%);\n" +" background-size: cover;\n" +" background-blend-mode: %s;\n" +" min-width: 200px;\n" +" min-height: 200px;\n" +"}\n" +"\n" +"image.blend1 {\n" +" background: url('resource://css_blendmodes/blends.png') top center,\n" +" url('resource://css_blendmodes/blends.png') bottom center;\n" +" background-blend-mode: %s;\n" +" min-width: 200px;\n" +" min-height: 200px;\n" +"}\n" +"\n" +"image.blend2 {\n" +" background: url('resource://css_blendmodes/cmy.jpg') top center,\n" +" url('resource://css_blendmodes/cmy.jpg') center center,\n" +" url('resource://css_blendmodes/cmy.jpg') bottom center;\n" +" background-blend-mode: %s;\n" +" min-width: 200px;\n" +" min-height: 200px;\n" +"}\n"; + +static void +update_css_for_blend_mode (GtkCssProvider *provider, + const gchar *blend_mode) +{ + GBytes *bytes; + gchar *css; + + bytes = g_resources_lookup_data ("/css_blendmodes/css_blendmodes.css", 0, NULL); + + css = g_strdup_printf (CSS_TEMPLATE, + (gchar*) g_bytes_get_data (bytes, NULL), + blend_mode, + blend_mode, + blend_mode); + + gtk_css_provider_load_from_data (provider, css, -1, NULL); + + g_bytes_unref (bytes); + g_free (css); +} + +static void +row_activated (GtkListBox *listbox, + GtkListBoxRow *row, + GtkCssProvider *provider) +{ + const gchar *blend_mode; + + blend_mode = blend_modes[gtk_list_box_row_get_index (row)].id; + + update_css_for_blend_mode (provider, blend_mode); +} + +static void +setup_listbox (GtkBuilder *builder, + GtkStyleProvider *provider) +{ + GtkWidget *normal_row; + GtkWidget *listbox; + gint i; + + normal_row = NULL; + listbox = gtk_list_box_new (); + gtk_container_add (GTK_CONTAINER (WID ("scrolledwindow")), listbox); + + g_signal_connect (listbox, "row-activated", G_CALLBACK (row_activated), provider); + + /* Add a row for each blend mode available */ + for (i = 0; blend_modes[i].name != NULL; i++) + { + GtkWidget *label; + GtkWidget *row; + + row = gtk_list_box_row_new (); + label = g_object_new (GTK_TYPE_LABEL, + "label", blend_modes[i].name, + "xalign", 0.0, + NULL); + + gtk_container_add (GTK_CONTAINER (row), label); + + gtk_container_add (GTK_CONTAINER (listbox), row); + + /* The first selected row is "normal" */ + if (g_strcmp0 (blend_modes[i].id, "normal") == 0) + normal_row = row; + } + + /* Select the "normal" row */ + gtk_list_box_select_row (GTK_LIST_BOX (listbox), GTK_LIST_BOX_ROW (normal_row)); + g_signal_emit_by_name (G_OBJECT (normal_row), "activate"); + + gtk_widget_grab_focus (normal_row); +} + +GtkWidget * +do_css_blendmodes (GtkWidget *do_widget) +{ + static GtkWidget *window = NULL; + + if (!window) + { + GtkStyleProvider *provider; + GtkBuilder *builder; + + builder = gtk_builder_new_from_resource ("/css_blendmodes/blendmodes.ui"); + + window = WID ("window"); + gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); + + /* Setup the CSS provider for window */ + provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ()); + + gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), + provider, + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + setup_listbox (builder, provider); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show_all (window); + else + gtk_widget_destroy (window); + + return window; +} |