[gnome-software] Allow widgets to use custom CSS in a generic way



commit f0f41b857e54db890765dbc67a185842de7301aa
Author: Richard Hughes <richard hughsie com>
Date:   Wed Apr 13 09:12:01 2016 +0100

    Allow widgets to use custom CSS in a generic way
    
    The custom CSS can either be set in the AppStream metadata, e.g.
    
      <component type="desktop">
        <id>inkscape.desktop</id>
        <metadata>
          <value key="GnomeSoftware::PopularTile-css">
    background: url('@datadir@/gnome-software/featured-inkscape.png');
    background-size: 100% 100%;
          </value>
        </metadata>
      </component>
    
    or this can be set in a plugin using gs_app_set_metadata().

 data/Makefile.am                     |    1 +
 data/org.gnome.Software-featured.xml |  166 ++++++++++++++++++++++++----------
 data/upgrade-bg.png                  |  Bin 0 -> 259630 bytes
 src/gs-app-tile.c                    |    6 ++
 src/gs-feature-tile.c                |   50 ++---------
 src/gs-popular-tile.c                |    7 ++
 src/gs-upgrade-banner.c              |   13 +++-
 src/gs-utils.c                       |   60 ++++++++++++
 src/gs-utils.h                       |    2 +
 src/plugins/gs-plugin-appstream.c    |    2 +-
 src/plugins/gs-plugin-dummy.c        |    3 +
 11 files changed, 216 insertions(+), 94 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index e5a45f1..5fe1bc1 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -14,6 +14,7 @@ org.gnome.Software.xml.gz: $(appstream_files)
 
 resourcesdir = $(datadir)/gnome-software
 dist_resources_DATA =                                  \
+       upgrade-bg.png                                  \
        featured-ardour.png                             \
        featured-ardour-bg.png                          \
        featured-blender.png                            \
diff --git a/data/org.gnome.Software-featured.xml b/data/org.gnome.Software-featured.xml
index 7fe9fe1..c974029 100644
--- a/data/org.gnome.Software-featured.xml
+++ b/data/org.gnome.Software-featured.xml
@@ -5,119 +5,191 @@
   <component type="desktop">
     <id>ardour2.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-ardour.png') 
30% 49% / 33% no-repeat, url('@datadir@/gnome-software/featured-ardour-bg.png') center center / 100% auto 
no-repeat, linear-gradient(to bottom, #373936, #60625e)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#333333</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #333333;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-ardour.png') 30% 49% / 33% no-repeat, 
url('@datadir@/gnome-software/featured-ardour-bg.png') center center / 100% auto no-repeat, 
linear-gradient(to bottom, #373936, #60625e);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>blender.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-blender.png') 
10% 40% / 50% auto no-repeat, -gtk-gradient (radial, center bottom, 0, center center, 1, from(#fcbf83), 
to(#c06105))</value>
-      <value key="GnomeSoftware::featured-stroke-color">#783d03</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #783d03;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-blender.png') 10% 40% / 50% auto no-repeat, -gtk-gradient 
(radial, center bottom, 0, center center, 1, from(#fcbf83), to(#c06105));
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>gnome-chess.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-chess.png') 10% 
center / 40% auto no-repeat, linear-gradient(to bottom, #555753, #888a85)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#2e3436</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #2e3436;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-chess.png') 10% center / 40% auto no-repeat, 
linear-gradient(to bottom, #555753, #888a85);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>firefox.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-firefox.png') 
10% center / 40% auto no-repeat, linear-gradient(to bottom, #d3d7cf, #eeeeec)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#babdb6</value>
-      <value key="GnomeSoftware::featured-text-color">#888a85</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(255,255,255,0.7)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #babdb6;
+text-shadow: 0 1px 1px rgba(255,255,255,0.7);
+color: #888a85;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#888a85, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-firefox.png') 10% center / 40% auto no-repeat, 
linear-gradient(to bottom, #d3d7cf, #eeeeec);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>gimp.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-gimp.png') left 
50% / 50% auto no-repeat, linear-gradient(to bottom, #8ac674, #cbddc3)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#2a6c10</value>
-      <value key="GnomeSoftware::featured-text-color">#333</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(255,255,255,0.7)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #2a6c10;
+text-shadow: 0 1px 1px rgba(255,255,255,0.7);
+color: #333;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#333, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-gimp.png') left 50% / 50% auto no-repeat, 
linear-gradient(to bottom, #8ac674, #cbddc3);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>inkscape.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-inkscape.png') 
20% / 60% auto no-repeat, linear-gradient(to bottom, #ccd6c3, #a7b797)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#819a6b</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 3px rgba(0,0,0,0.9),0 1px 2px 
rgba(0,0,0,0.7)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #819a6b;
+text-shadow: 0 1px 3px rgba(0,0,0,0.9),0 1px 2px rgba(0,0,0,0.7);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-inkscape.png') 20% / 60% auto no-repeat, 
linear-gradient(to bottom, #ccd6c3, #a7b797);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>mypaint.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-mypaint.png') 
left 67% / 50% auto no-repeat, linear-gradient(to bottom, #8fa5d9, #d8e0ef)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#4c52aa</value>
-      <value key="GnomeSoftware::featured-text-color">#362d89</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #4c52aa;
+color: #362d89;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#362d89, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-mypaint.png') left 67% / 50% auto no-repeat, 
linear-gradient(to bottom, #8fa5d9, #d8e0ef);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>org.gnome.Polari.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-polari.svg') 
70% 80% / 120% auto no-repeat, #43a570</value>
-      <value key="GnomeSoftware::featured-stroke-color">#4e9a06</value>
-      <value key="GnomeSoftware::featured-text-color">#a8c74f</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 2px #418e64</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #4e9a06;
+text-shadow: 0 2px #418e64;
+color: #a8c74f;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#a8c74f, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-polari.svg') 70% 80% / 120% auto no-repeat, #43a570;
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>org.gnome.Weather.Application.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-weather.png') 
left 80% / 50% auto no-repeat, url('@datadir@/gnome-software/featured-weather-bg.png'), linear-gradient(to 
bottom, #25486d, #6693ce)</value>
-      <value key="GnomeSoftware::featured-stroke-color">#d8e0ef</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #d8e0ef;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-weather.png') left 80% / 50% auto no-repeat, 
url('@datadir@/gnome-software/featured-weather-bg.png'), linear-gradient(to bottom, #25486d, #6693ce);
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>transmission-gtk.desktop</id>
     <metadata>
-      <value 
key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-transmission.png') 10% 20% / 
427px auto no-repeat, -gtk-gradient (radial, center bottom, 0, center center, 0.8, from(#ffc124), 
to(#b75200))</value>
-      <value key="GnomeSoftware::featured-stroke-color">#a40000</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #a40000;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-transmission.png') 10% 20% / 427px auto no-repeat, 
-gtk-gradient (radial, center bottom, 0, center center, 0.8, from(#ffc124), to(#b75200));
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>org.gnome.Builder.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-builder.png') 
left center / 100% auto no-repeat, url('@datadir@/gnome-software/featured-builder-bg.jpg') center / cover 
no-repeat</value>
-      <value key="GnomeSoftware::featured-stroke-color">#000000</value>
-      <value key="GnomeSoftware::featured-text-color">#ffffff</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(0,0,0,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #000000;
+text-shadow: 0 1px 1px rgba(0,0,0,0.5);
+color: #ffffff;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#ffffff, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-builder.png') left center / 100% auto no-repeat, 
url('@datadir@/gnome-software/featured-builder-bg.jpg') center / cover no-repeat;
+      </value>
     </metadata>
   </component>
 
   <component type="desktop">
     <id>org.gnome.Maps.desktop</id>
     <metadata>
-      <value key="GnomeSoftware::featured-background">url('@datadir@/gnome-software/featured-maps.png') left 
-10px / 352px auto no-repeat, url('@datadir@/gnome-software/featured-maps-bg.png') bottom center / contain 
no-repeat</value>
-      <value key="GnomeSoftware::featured-stroke-color">#ff0000</value>
-      <value key="GnomeSoftware::featured-text-color">#000000</value>
-      <value key="GnomeSoftware::featured-text-shadow">0 1px 1px rgba(255,255,255,0.5)</value>
+      <value key="GnomeSoftware::FeatureTile-css">
+border-color: #ff0000;
+text-shadow: 0 1px 1px rgba(255,255,255,0.5);
+color: #000000;
+-GtkWidget-focus-padding: 0;
+outline-color: alpha(#000000, 0.75);
+outline-style: dashed;
+outline-offset: 2px;
+background: url('@datadir@/gnome-software/featured-maps.png') left -10px / 352px auto no-repeat, 
url('@datadir@/gnome-software/featured-maps-bg.png') bottom center / contain no-repeat;
+      </value>
     </metadata>
   </component>
 
diff --git a/data/upgrade-bg.png b/data/upgrade-bg.png
new file mode 100644
index 0000000..19680a7
Binary files /dev/null and b/data/upgrade-bg.png differ
diff --git a/src/gs-app-tile.c b/src/gs-app-tile.c
index 7428225..0366ca8 100644
--- a/src/gs-app-tile.c
+++ b/src/gs-app-tile.c
@@ -127,6 +127,7 @@ void
 gs_app_tile_set_app (GsAppTile *tile, GsApp *app)
 {
        const GdkPixbuf *pixbuf;
+       const gchar *css;
        g_autofree gchar *text = NULL;
 
        g_return_if_fail (GS_IS_APP_TILE (tile));
@@ -153,6 +154,11 @@ gs_app_tile_set_app (GsAppTile *tile, GsApp *app)
                gs_image_set_from_pixbuf (GTK_IMAGE (tile->image), pixbuf);
        gtk_label_set_label (GTK_LABEL (tile->name), gs_app_get_name (app));
 
+       /* set custom css */
+       css = gs_app_get_metadata_item (app, "GnomeSoftware::AppTile-css");
+       if (css != NULL)
+               gs_utils_widget_set_custom_css (GTK_WIDGET (tile), css);
+
        /* some kinds have boring summaries */
        switch (gs_app_get_kind (app)) {
        case AS_APP_KIND_SHELL_EXTENSION:
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
index d72e091..214562d 100644
--- a/src/gs-feature-tile.c
+++ b/src/gs-feature-tile.c
@@ -25,6 +25,7 @@
 #include <gtk/gtk.h>
 
 #include "gs-feature-tile.h"
+#include "gs-utils.h"
 
 struct _GsFeatureTile
 {
@@ -35,7 +36,6 @@ struct _GsFeatureTile
        GtkWidget       *stack;
        GtkWidget       *title;
        GtkWidget       *subtitle;
-       GtkCssProvider  *provider;
 };
 
 G_DEFINE_TYPE (GsFeatureTile, gs_feature_tile, GTK_TYPE_BUTTON)
@@ -91,10 +91,7 @@ app_state_changed (GsApp *app, GParamSpec *pspec, GsFeatureTile *tile)
 void
 gs_feature_tile_set_app (GsFeatureTile *tile, GsApp *app)
 {
-       const gchar *background;
-       const gchar *stroke_color;
-       const gchar *text_color;
-       const gchar *text_shadow;
+       const gchar *css;
        g_autoptr(GString) data = NULL;
 
        g_return_if_fail (GS_IS_FEATURE_TILE (tile));
@@ -116,39 +113,10 @@ gs_feature_tile_set_app (GsFeatureTile *tile, GsApp *app)
        gtk_label_set_label (GTK_LABEL (tile->title), gs_app_get_name (app));
        gtk_label_set_label (GTK_LABEL (tile->subtitle), gs_app_get_summary (app));
 
-       /* check the app has the featured data */
-       text_color = gs_app_get_metadata_item (app, "GnomeSoftware::featured-text-color");
-       if (text_color == NULL) {
-               g_autofree gchar *tmp = NULL;
-               tmp = gs_app_to_string (app);
-               g_warning ("%s has no featured data: %s",
-                          gs_app_get_id (app), tmp);
-               return;
-       }
-       background = gs_app_get_metadata_item (app, "GnomeSoftware::featured-background");
-       stroke_color = gs_app_get_metadata_item (app, "GnomeSoftware::featured-stroke-color");
-       text_shadow = gs_app_get_metadata_item (app, "GnomeSoftware::featured-text-shadow");
-
-       data = g_string_sized_new (1024);
-       g_string_append (data, ".featured-tile {\n");
-       g_string_append_printf (data, "  border-color: %s;\n", stroke_color);
-       if (text_shadow != NULL)
-               g_string_append_printf (data, "  text-shadow: %s;\n", text_shadow);
-       g_string_append_printf (data, "  color: %s;\n", text_color);
-       g_string_append (data, "  -GtkWidget-focus-padding: 0;\n");
-       g_string_append_printf (data, "  outline-color: alpha(%s, 0.75);\n", text_color);
-       g_string_append (data, "  outline-style: dashed;\n");
-       g_string_append (data, "  outline-offset: 2px;\n");
-       g_string_append_printf (data, "  background: %s;\n", background);
-       g_string_append (data, "}\n");
-       g_string_append (data, ".featured-tile:hover {\n");
-       g_string_append (data, "  background: linear-gradient(to bottom,\n");
-       g_string_append (data, "                              alpha(#fff,0.16),\n");
-       g_string_append_printf (data,
-                               "                             alpha(#aaa,0.16)), %s;\n",
-                               background);
-       g_string_append (data, "}\n");
-       gtk_css_provider_load_from_data (tile->provider, data->str, -1, NULL);
+       /* set custom css */
+       css = gs_app_get_metadata_item (app, "GnomeSoftware::FeatureTile-css");
+       if (css != NULL)
+               gs_utils_widget_set_custom_css (GTK_WIDGET (tile), css);
 }
 
 static void
@@ -160,7 +128,6 @@ gs_feature_tile_destroy (GtkWidget *widget)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
 
        g_clear_object (&tile->app);
-       g_clear_object (&tile->provider);
 
        GTK_WIDGET_CLASS (gs_feature_tile_parent_class)->destroy (widget);
 }
@@ -170,11 +137,6 @@ gs_feature_tile_init (GsFeatureTile *tile)
 {
        gtk_widget_set_has_window (GTK_WIDGET (tile), FALSE);
        gtk_widget_init_template (GTK_WIDGET (tile));
-
-       tile->provider = gtk_css_provider_new ();
-       gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
-                                                  GTK_STYLE_PROVIDER (tile->provider),
-                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 }
 
 static void
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index d083104..6ca6fb1 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -103,6 +103,8 @@ app_state_changed (GsApp *app, GParamSpec *pspec, GsPopularTile *tile)
 void
 gs_popular_tile_set_app (GsPopularTile *tile, GsApp *app)
 {
+       const gchar *css;
+
        g_return_if_fail (GS_IS_POPULAR_TILE (tile));
        g_return_if_fail (GS_IS_APP (app) || app == NULL);
 
@@ -126,6 +128,11 @@ gs_popular_tile_set_app (GsPopularTile *tile, GsApp *app)
                          G_CALLBACK (app_state_changed), tile);
        app_state_changed (tile->app, NULL, tile);
 
+       /* set custom css */
+       css = gs_app_get_metadata_item (app, "GnomeSoftware::PopularTile-css");
+       if (css != NULL)
+               gs_utils_widget_set_custom_css (GTK_WIDGET (tile), css);
+
        gs_image_set_from_pixbuf (GTK_IMAGE (tile->image), gs_app_get_pixbuf (tile->app));
 
        gtk_label_set_label (GTK_LABEL (tile->label), gs_app_get_name (app));
diff --git a/src/gs-upgrade-banner.c b/src/gs-upgrade-banner.c
index c991f3e..94238ae 100644
--- a/src/gs-upgrade-banner.c
+++ b/src/gs-upgrade-banner.c
@@ -21,16 +21,18 @@
 
 #include "config.h"
 
-#include "gs-upgrade-banner.h"
-
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <stdlib.h>
 
+#include "gs-upgrade-banner.h"
+#include "gs-utils.h"
+
 typedef struct
 {
        GsApp           *app;
 
+       GtkWidget       *box_upgrades;
        GtkWidget       *button_upgrades_download;
        GtkWidget       *button_upgrades_install;
        GtkWidget       *button_upgrades_help;
@@ -212,6 +214,7 @@ void
 gs_upgrade_banner_set_app (GsUpgradeBanner *self, GsApp *app)
 {
        GsUpgradeBannerPrivate *priv = gs_upgrade_banner_get_instance_private (self);
+       const gchar *css;
 
        g_return_if_fail (GS_IS_UPGRADE_BANNER (self));
        g_return_if_fail (GS_IS_APP (app) || app == NULL);
@@ -230,6 +233,11 @@ gs_upgrade_banner_set_app (GsUpgradeBanner *self, GsApp *app)
        g_signal_connect (priv->app, "notify::progress",
                          G_CALLBACK (app_progress_changed), self);
 
+       /* set custom css */
+       css = gs_app_get_metadata_item (app, "GnomeSoftware::UpgradeBanner-css");
+       if (css != NULL)
+               gs_utils_widget_set_custom_css (priv->box_upgrades, css);
+
        gs_upgrade_banner_refresh (self);
 }
 
@@ -318,6 +326,7 @@ gs_upgrade_banner_class_init (GsUpgradeBannerClass *klass)
 
        gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/Software/gs-upgrade-banner.ui");
 
+       gtk_widget_class_bind_template_child_private (widget_class, GsUpgradeBanner, box_upgrades);
        gtk_widget_class_bind_template_child_private (widget_class, GsUpgradeBanner, 
button_upgrades_download);
        gtk_widget_class_bind_template_child_private (widget_class, GsUpgradeBanner, button_upgrades_install);
        gtk_widget_class_bind_template_child_private (widget_class, GsUpgradeBanner, button_upgrades_cancel);
diff --git a/src/gs-utils.c b/src/gs-utils.c
index 7f6fb1a..fc8c7ba 100644
--- a/src/gs-utils.c
+++ b/src/gs-utils.c
@@ -753,4 +753,64 @@ gs_utils_is_current_desktop (const gchar *name)
        return g_strv_contains ((const gchar * const *) names, name);
 }
 
+/**
+ * gs_utils_widget_css_parsing_error_cb:
+ */
+static void
+gs_utils_widget_css_parsing_error_cb (GtkCssProvider *provider,
+                                     GtkCssSection *section,
+                                     GError *error,
+                                     gpointer user_data)
+{
+       g_warning ("CSS parse error %i:%i: %s",
+                  gtk_css_section_get_start_line (section),
+                  gtk_css_section_get_start_position (section),
+                  error->message);
+}
+
+/**
+ * gs_utils_widget_set_custom_css:
+ **/
+void
+gs_utils_widget_set_custom_css (GtkWidget *widget, const gchar *css)
+{
+       GString *str = g_string_sized_new (1024);
+       GtkStyleContext *context;
+       g_autofree gchar *class_name = NULL;
+       g_autoptr(GtkCssProvider) provider = NULL;
+
+       /* invalid */
+       if (css == NULL)
+               return;
+
+       /* make into a proper CSS class */
+       class_name = g_strdup_printf ("themed-widget_%p", widget);
+       g_string_append_printf (str, ".%s {\n", class_name);
+       g_string_append_printf (str, "%s\n", css);
+       g_string_append (str, "}");
+
+       g_string_append_printf (str, ".%s:hover {\n", class_name);
+       g_string_append (str, "  opacity: 0.9;\n");
+       g_string_append (str, "}\n");
+
+       g_debug ("using custom CSS %s", str->str);
+
+       /* set the custom CSS class */
+       context = gtk_widget_get_style_context (widget);
+       gtk_style_context_add_class (context, class_name);
+
+       /* set up custom provider and store on the widget */
+       provider = gtk_css_provider_new ();
+       g_signal_connect (provider, "parsing-error",
+                         G_CALLBACK (gs_utils_widget_css_parsing_error_cb), NULL);
+       gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                                  GTK_STYLE_PROVIDER (provider),
+                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+       gtk_css_provider_load_from_data (provider, str->str, -1, NULL);
+       g_object_set_data_full (G_OBJECT (widget),
+                               "GnomeSoftware::provider",
+                               g_object_ref (provider),
+                               g_object_unref);
+}
+
 /* vim: set noexpandtab: */
diff --git a/src/gs-utils.h b/src/gs-utils.h
index 4c79d34..1ee9f17 100644
--- a/src/gs-utils.h
+++ b/src/gs-utils.h
@@ -69,6 +69,8 @@ const gchar   *gs_utils_get_content_rating    (void);
 #endif
 
 gboolean        gs_utils_is_current_desktop    (const gchar    *name);
+void            gs_utils_widget_set_custom_css (GtkWidget      *widget,
+                                                const gchar    *css);
 
 G_END_DECLS
 
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 9a526dc..a069c2c 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -635,7 +635,7 @@ gs_plugin_add_featured (GsPlugin *plugin,
                item = g_ptr_array_index (array, i);
                if (as_app_get_id (item) == NULL)
                        continue;
-               if (as_app_get_metadata_item (item, "GnomeSoftware::featured-background") == NULL)
+               if (as_app_get_metadata_item (item, "GnomeSoftware::FeatureTile-css") == NULL)
                        continue;
                app = gs_app_new (as_app_get_id_no_prefix (item));
                gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index 4fa269c..654c74b 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -254,6 +254,9 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                        "https://fedoraproject.org/wiki/Releases/24/Schedule";);
        gs_app_set_version (app, "25");
        gs_app_set_management_plugin (app, plugin->name);
+       gs_app_set_metadata (app, "GnomeSoftware::UpgradeBanner-css",
+                            "background: url('" DATADIR "/gnome-software/upgrade-bg.png');"
+                            "background-size: 100% 100%;");
        gs_plugin_add_app (list, app);
        return TRUE;
 }


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