diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 80927d0cbe..8c15e16633 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -14,6 +14,7 @@ demos_base = \ combobox.c \ css_accordion.c \ css_basics.c \ + css_blendmodes.c \ css_multiplebgs.c \ css_pixbufs.c \ css_shadows.c \ diff --git a/demos/gtk-demo/blendmodes.ui b/demos/gtk-demo/blendmodes.ui new file mode 100644 index 0000000000..9badf330dc --- /dev/null +++ b/demos/gtk-demo/blendmodes.ui @@ -0,0 +1,391 @@ + + + + + False + CSS Blend Modes + 400 + 300 + + + True + False + 12 + 12 + 12 + + + True + False + Blend mode: + 0 + + + + 0 + 0 + + + + + True + True + True + in + 150 + + + 0 + 1 + + + + + True + False + center + True + stack + + + 1 + 0 + + + + + True + False + True + True + False + False + crossfade + + + True + False + center + center + False + True + 12 + 12 + + + True + False + Duck + + + 0 + 0 + + + + + True + False + Background + + + 1 + 0 + + + + + True + False + + + + 0 + 1 + + + + + True + False + + + + 1 + 1 + + + + + True + False + +Blended picture + + + 0 + 2 + 2 + + + + + True + False + center + + + + 0 + 3 + 2 + + + + + page0 + Ducky + + + + + True + False + center + center + False + True + 12 + 12 + + + True + False + Red + + + 0 + 0 + + + + + True + False + Blue + + + 1 + 0 + + + + + True + False + + + + 0 + 1 + + + + + True + False + + + + 1 + 1 + + + + + True + False + +Blended picture + + + 0 + 2 + 2 + + + + + True + False + center + + + + 0 + 3 + 2 + + + + + page1 + Blends + + + + + True + False + center + center + True + True + 6 + 12 + + + True + False + + + + 0 + 1 + + + + + True + False + + + + 1 + 1 + + + + + True + False + + + + 0 + 3 + + + + + True + False + center + + + + 1 + 3 + + + + + True + False + Cyan + 0 + + + + 0 + 0 + + + + + True + False + Magenta + 0 + + + + 1 + 0 + + + + + True + False + Yellow + 0 + + + + 0 + 2 + + + + + True + False + Blended picture + 0 + + + + + + 1 + 2 + + + + + page2 + CMYK + + + + + 1 + 1 + + + + + + + + + diff --git a/demos/gtk-demo/blends.png b/demos/gtk-demo/blends.png new file mode 100644 index 0000000000..afc6c4abc1 Binary files /dev/null and b/demos/gtk-demo/blends.png differ diff --git a/demos/gtk-demo/cmy.jpg b/demos/gtk-demo/cmy.jpg new file mode 100644 index 0000000000..f44d0966da Binary files /dev/null and b/demos/gtk-demo/cmy.jpg differ 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 + +#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; +} diff --git a/demos/gtk-demo/css_blendmodes.css b/demos/gtk-demo/css_blendmodes.css new file mode 100644 index 0000000000..b212e50760 --- /dev/null +++ b/demos/gtk-demo/css_blendmodes.css @@ -0,0 +1,51 @@ +/* + * First page. + */ +image.duck { + background-image: url('resource://css_blendmodes/ducky.png'); + background-size: cover; + min-width: 200px; + min-height: 200px; +} + +image.gradient { + background-image: linear-gradient(to right, red 0%, green 50%, blue 100%); + min-width: 200px; + min-height: 200px; +} + +/* + * Second page. + */ +image.red { + background: url('resource://css_blendmodes/blends.png') top center; + min-width: 200px; + min-height: 200px; +} + +image.blue { + background: url('resource://css_blendmodes/blends.png') bottom center; + min-width: 200px; + min-height: 200px; +} + +/* + * Third page. + */ +image.cyan { + background: url('resource://css_blendmodes/cmy.jpg') top center; + min-width: 200px; + min-height: 200px; +} + +image.magenta { + background: url('resource://css_blendmodes/cmy.jpg') center center; + min-width: 200px; + min-height: 200px; +} + +image.yellow { + background: url('resource://css_blendmodes/cmy.jpg') bottom center; + min-width: 200px; + min-height: 200px; +} diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 4b30c67c4b..f0c7201f3c 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -20,6 +20,13 @@ css_basics.css reset.css + + css_blendmodes.css + blendmodes.ui + blends.png + ducky.png + cmy.jpg + css_multiplebgs.css brick.png @@ -130,6 +137,7 @@ combobox.c css_accordion.c css_basics.c + css_blendmodes.c css_multiplebgs.c css_pixbufs.c css_shadows.c diff --git a/demos/gtk-demo/ducky.png b/demos/gtk-demo/ducky.png new file mode 100644 index 0000000000..f1cbd35250 Binary files /dev/null and b/demos/gtk-demo/ducky.png differ