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 | |
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')
-rw-r--r-- | demos/gtk-demo/Makefile.am | 1 | ||||
-rw-r--r-- | demos/gtk-demo/blendmodes.ui | 391 | ||||
-rw-r--r-- | demos/gtk-demo/blends.png | bin | 0 -> 788 bytes | |||
-rw-r--r-- | demos/gtk-demo/cmy.jpg | bin | 0 -> 55825 bytes | |||
-rw-r--r-- | demos/gtk-demo/css_blendmodes.c | 178 | ||||
-rw-r--r-- | demos/gtk-demo/css_blendmodes.css | 51 | ||||
-rw-r--r-- | demos/gtk-demo/demo.gresource.xml | 8 | ||||
-rw-r--r-- | demos/gtk-demo/ducky.png | bin | 0 -> 248546 bytes |
8 files changed, 629 insertions, 0 deletions
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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.20"/> + <object class="GtkWindow" id="window"> + <property name="can_focus">False</property> + <property name="title">CSS Blend Modes</property> + <property name="default_width">400</property> + <property name="default_height">300</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="row_spacing">12</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Blend mode:</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="vexpand">True</property> + <property name="shadow_type">in</property> + <property name="min_content_width">150</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkStackSwitcher"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="hexpand">True</property> + <property name="stack">stack</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkStack" id="stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="hhomogeneous">False</property> + <property name="vhomogeneous">False</property> + <property name="transition_type">crossfade</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="hexpand">False</property> + <property name="vexpand">True</property> + <property name="row_spacing">12</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Duck</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Background</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="duck"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="gradient"/> + </style> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"> +Blended picture</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <style> + <class name="blend0"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + <property name="width">2</property> + </packing> + </child> + </object> + <packing> + <property name="name">page0</property> + <property name="title" translatable="yes">Ducky</property> + </packing> + </child> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="hexpand">False</property> + <property name="vexpand">True</property> + <property name="row_spacing">12</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Red</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Blue</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="red"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="blue"/> + </style> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"> +Blended picture</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <style> + <class name="blend1"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + <property name="width">2</property> + </packing> + </child> + </object> + <packing> + <property name="name">page1</property> + <property name="title" translatable="yes">Blends</property> + </packing> + </child> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="cyan"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="magenta"/> + </style> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="yellow"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <style> + <class name="blend2"/> + </style> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Cyan</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Magenta</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Yellow</property> + <property name="xalign">0</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Blended picture</property> + <property name="xalign">0</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + </object> + <packing> + <property name="name">page2</property> + <property name="title" translatable="yes">CMYK</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + </object> + </child> + <child type="titlebar"> + <placeholder/> + </child> + </object> +</interface> diff --git a/demos/gtk-demo/blends.png b/demos/gtk-demo/blends.png Binary files differnew file mode 100644 index 0000000000..afc6c4abc1 --- /dev/null +++ b/demos/gtk-demo/blends.png diff --git a/demos/gtk-demo/cmy.jpg b/demos/gtk-demo/cmy.jpg Binary files differnew file mode 100644 index 0000000000..f44d0966da --- /dev/null +++ b/demos/gtk-demo/cmy.jpg 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; +} 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 @@ <file>css_basics.css</file> <file>reset.css</file> </gresource> + <gresource prefix="/css_blendmodes"> + <file>css_blendmodes.css</file> + <file>blendmodes.ui</file> + <file>blends.png</file> + <file>ducky.png</file> + <file>cmy.jpg</file> + </gresource> <gresource prefix="/css_multiplebgs"> <file>css_multiplebgs.css</file> <file>brick.png</file> @@ -130,6 +137,7 @@ <file>combobox.c</file> <file>css_accordion.c</file> <file>css_basics.c</file> + <file>css_blendmodes.c</file> <file>css_multiplebgs.c</file> <file>css_pixbufs.c</file> <file>css_shadows.c</file> diff --git a/demos/gtk-demo/ducky.png b/demos/gtk-demo/ducky.png Binary files differnew file mode 100644 index 0000000000..f1cbd35250 --- /dev/null +++ b/demos/gtk-demo/ducky.png |