[gtk+] demo: add a demo for blend modes



commit 1d93cc2b0b88bcc02f8a15d80b8a75d61d0cb24a
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Jul 1 19:39:04 2016 -0300

    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

 demos/gtk-demo/Makefile.am        |    1 +
 demos/gtk-demo/blendmodes.ui      |  391 +++++++++++++++++++++++++++++++++++++
 demos/gtk-demo/blends.png         |  Bin 0 -> 788 bytes
 demos/gtk-demo/cmy.jpg            |  Bin 0 -> 55825 bytes
 demos/gtk-demo/css_blendmodes.c   |  178 +++++++++++++++++
 demos/gtk-demo/css_blendmodes.css |   51 +++++
 demos/gtk-demo/demo.gresource.xml |    8 +
 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 80927d0..8c15e16 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 0000000..9badf33
--- /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
new file mode 100644
index 0000000..afc6c4a
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 0000000..f44d096
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 0000000..4c4e673
--- /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 0000000..b212e50
--- /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 4b30c67..f0c7201 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
new file mode 100644
index 0000000..f1cbd35
Binary files /dev/null and b/demos/gtk-demo/ducky.png differ


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]