[gnome-software/wip/hughsie/recolor-app-tile] Recolor the GsAppTile with a symbolic icon
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/recolor-app-tile] Recolor the GsAppTile with a symbolic icon
- Date: Wed, 6 Apr 2016 13:50:47 +0000 (UTC)
commit b3f9b14388dd0f8ae75c38a06b1d00a387347d6a
Author: Richard Hughes <richard hughsie com>
Date: Tue Apr 5 19:27:57 2016 +0100
Recolor the GsAppTile with a symbolic icon
data/Makefile.am | 1 +
data/tile-symbolic.svg | 259 ++++++++++++++++++++++++++++++++++++
src/gs-cmd.c | 2 +
src/gs-plugin.h | 1 +
src/gs-popular-tile.c | 25 ++++
src/gs-shell-overview.c | 9 +-
src/plugins/Makefile.am | 6 +
src/plugins/gs-plugin-key-colors.c | 232 ++++++++++++++++++++++++++++++++
8 files changed, 532 insertions(+), 3 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index e5a45f1..8fbcaf5 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 = \
+ tile-symbolic.svg \
featured-ardour.png \
featured-ardour-bg.png \
featured-blender.png \
diff --git a/data/tile-symbolic.svg b/data/tile-symbolic.svg
new file mode 100644
index 0000000..66b218c
--- /dev/null
+++ b/data/tile-symbolic.svg
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="60.959999mm"
+ height="60.959999mm"
+ viewBox="0 0 216 216"
+ id="svg6040"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="app-tile-pattern-bg-symbolic.svg">
+ <defs
+ id="defs6042" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="134.08264"
+ inkscape:cy="157.87158"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid6048"
+ originx="-79.969604"
+ originy="-688.97086" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata6045">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-79.969604,-147.39134)">
+ <g
+ id="g4251"
+ style="opacity:0.25030525">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6617"
+ d="m 79.969762,219.39121 35.999938,-35.99995 35.99995,35.99995 z"
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ inkscape:connector-curvature="0"
+ id="path6623"
+ d="M 223.96955,147.39131 187.9696,183.39126 151.96965,147.39131 Z"
+ class="error"
+
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,219.39126 35.99995,-35.99995 35.99995,35.99995 z"
+ id="path6625"
+ inkscape:connector-curvature="0" />
+ <path
+ class="error"
+
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,147.39131 35.99995,35.99995 -35.99995,36 z"
+ id="path6629"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path6643"
+ d="m 223.96955,219.39131 35.99995,-35.99995 35.99995,35.99995 z"
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ inkscape:connector-curvature="0"
+ id="path6647"
+ d="m 223.96955,147.39136 35.99995,35.99995 -35.99995,36 z"
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ inkscape:connector-curvature="0"
+ id="path6675"
+ d="M 151.96965,219.39131 115.9697,255.39126 79.969762,219.39131 Z"
+
style="fill:#29ff29;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ inkscape:connector-curvature="0"
+ id="path6679"
+ d="m 151.96965,291.39126 -35.9999,-35.99995 35.9999,-35.99995 z"
+ class="error"
+
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+
style="fill:#29ff29;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 79.969762,219.39131 35.999938,35.99995 -35.999938,36 z"
+ id="path6681"
+ inkscape:connector-curvature="0" />
+ <path
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 223.96955,219.39136 187.9696,255.39131 151.96965,219.39136 Z"
+ id="path6683"
+ inkscape:connector-curvature="0" />
+ <path
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 223.96955,291.39131 -35.9999,-35.99995 35.9999,-35.99995 z"
+ id="path6687"
+ inkscape:connector-curvature="0" />
+ <path
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 223.96955,219.39141 35.99995,35.99995 -35.99995,36 z"
+ id="path6697"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path6703"
+ d="m 79.969762,363.39131 35.999938,-35.99995 35.99995,35.99995 z"
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,363.39131 -35.9999,-35.99995 35.9999,-35.99995 z"
+ id="path6705"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path6713"
+ d="m 223.96955,363.39136 -35.9999,-35.99995 35.9999,-35.99995 z"
+
style="fill:#2929ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,291.39141 35.99995,35.99995 -35.99995,36 z"
+ id="path6715"
+ inkscape:connector-curvature="0" />
+ <path
+ class="error"
+
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 295.96945,291.39146 259.9695,327.39141 223.96955,291.39146 Z"
+ id="path6717"
+ inkscape:connector-curvature="0" />
+ <path
+ class="error"
+
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 295.96945,363.39141 -35.9999,-35.99995 35.9999,-35.99995 z"
+ id="path6721"
+ inkscape:connector-curvature="0" />
+ <path
+ class="error"
+
style="fill:#343434;fill-opacity:0.20165746;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 295.96945,363.39141 -35.9999,-35.99995 35.9999,-35.99995 z"
+ id="path6761"
+ inkscape:connector-curvature="0" />
+ <path
+ class="warning"
+ inkscape:connector-curvature="0"
+ id="path6763"
+ d="m 151.96967,363.39141 35.9999,-35.99995 -35.9999,-35.99995 z"
+
style="fill:#000000;fill-opacity:0.52173911;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="warning"
+
style="fill:#000000;fill-opacity:0.52173911;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96966,363.39129 -35.99995,-35.9999 -35.999954,35.9999 z"
+ id="path6765"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path6767"
+ d="m 223.96955,219.39123 -35.99995,-35.9999 -35.99995,35.9999 z"
+
style="fill:#000000;fill-opacity:0.52173911;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="error"
+ inkscape:connector-curvature="0"
+ id="path6773"
+ d="M 79.969782,291.39123 115.96968,255.39128 79.969782,219.39133 Z"
+
style="fill:#000000;fill-opacity:0.31521744;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="error"
+ inkscape:connector-curvature="0"
+ id="path6775"
+ d="m 151.96966,219.39133 -35.99995,35.9999 -35.999956,-35.9999 z"
+
style="fill:#000000;fill-opacity:0.52173911;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="error"
+
style="fill:#000000;fill-opacity:0.31521744;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,147.39133 35.99995,35.9999 35.99995,-35.9999 z"
+ id="path6777"
+ inkscape:connector-curvature="0" />
+ <path
+ class="warning"
+ inkscape:connector-curvature="0"
+ id="path6779"
+ d="m 223.96955,219.39129 35.99995,-35.9999 35.99995,35.9999 z"
+
style="fill:#000000;fill-opacity:0.31521744;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 151.96965,219.39121 115.9697,183.39127 151.96965,147.39132 Z"
+ id="path6781"
+ inkscape:connector-curvature="0" />
+ <path
+ class="success"
+ inkscape:connector-curvature="0"
+ id="path6783"
+ d="m 223.96955,219.39141 -35.9999,35.99995 35.9999,35.99995 z"
+
style="fill:#000000;fill-opacity:0.31521744;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ inkscape:connector-curvature="0"
+ id="path6785"
+ d="M 295.96945,291.39146 259.9695,255.39151 223.96955,291.39146 Z"
+ class="success"
+
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
+ <path
+ class="warning"
+
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,291.39131 35.99995,35.99995 35.99995,-35.99995 z"
+ id="path6787"
+ inkscape:connector-curvature="0" />
+ <path
+ class="warning"
+
style="fill:#000000;fill-opacity:0.31521744;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 151.96965,291.39133 35.99995,35.99991 35.99995,-35.99991 z"
+ id="path6789"
+ inkscape:connector-curvature="0" />
+ <path
+ class="success"
+
style="fill:#000000;fill-opacity:0.60326089;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 223.96955,363.39141 -35.9999,-35.99995 35.9999,-35.99995 z"
+ id="path6795"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/src/gs-cmd.c b/src/gs-cmd.c
index 116315c..927c7c3 100644
--- a/src/gs-cmd.c
+++ b/src/gs-cmd.c
@@ -144,6 +144,8 @@ gs_cmd_refine_flag_from_string (const gchar *flag, GError **error)
return GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS;
if (g_strcmp0 (flag, "review-ratings") == 0)
return GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS;
+ if (g_strcmp0 (flag, "background") == 0)
+ return GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND;
g_set_error (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 6242375..a800e84 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -112,6 +112,7 @@ typedef enum {
GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE = 1 << 17,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS = 1 << 18,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS = 1 << 19,
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND = 1 << 20,
GS_PLUGIN_REFINE_FLAGS_LAST
} GsPluginRefineFlags;
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index d083104..e8f5b48 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 *background;
+
g_return_if_fail (GS_IS_POPULAR_TILE (tile));
g_return_if_fail (GS_IS_APP (app) || app == NULL);
@@ -129,6 +131,29 @@ gs_popular_tile_set_app (GsPopularTile *tile, GsApp *app)
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));
+
+ /* do we have new CSS to use? */
+ background = gs_app_get_metadata_item (app, "GnomeSoftware::popular-background");
+ if (background != NULL) {
+ GtkStyleContext *context;
+ g_autofree gchar *css = NULL;
+ g_autoptr(GtkCssProvider) css_provider = NULL;
+ context = gtk_widget_get_style_context (GTK_WIDGET (tile));
+ css_provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider (context,
+ GTK_STYLE_PROVIDER (css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ css = g_strdup_printf (
+ ".view.tile {\n"
+ " padding: 0;\n"
+ " box-shadow: inset 0 1px @theme_base_color, 0 1px 1px
alpha(black,0.4);\n"
+ " border: 1px solid mix(@theme_base_color,@theme_fg_color,0.3);\n"
+ " background: %s;\n"
+ " background-size: 100%% 100%%;\n"
+ " background-repeat: no-repeat;\n"
+ "}", background);
+ gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
+ }
}
static void
diff --git a/src/gs-shell-overview.c b/src/gs-shell-overview.c
index ec35c82..71320bf 100644
--- a/src/gs-shell-overview.c
+++ b/src/gs-shell-overview.c
@@ -391,7 +391,8 @@ gs_shell_overview_load (GsShellOverview *self)
if (!priv->loading_featured) {
priv->loading_featured = TRUE;
gs_plugin_loader_get_featured_async (priv->plugin_loader,
- GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+ GS_PLUGIN_REFINE_FLAGS_DEFAULT |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND,
priv->cancellable,
gs_shell_overview_get_featured_cb,
self);
@@ -401,7 +402,8 @@ gs_shell_overview_load (GsShellOverview *self)
if (!priv->loading_popular) {
priv->loading_popular = TRUE;
gs_plugin_loader_get_popular_async (priv->plugin_loader,
- GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+ GS_PLUGIN_REFINE_FLAGS_DEFAULT |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND,
priv->cancellable,
gs_shell_overview_get_popular_cb,
self);
@@ -423,7 +425,8 @@ gs_shell_overview_load (GsShellOverview *self)
priv->loading_popular_rotating = TRUE;
gs_plugin_loader_get_category_apps_async (priv->plugin_loader,
featured_category,
- GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+ GS_PLUGIN_REFINE_FLAGS_DEFAULT |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND,
priv->cancellable,
gs_shell_overview_get_popular_rotating_cb,
load_data);
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 32d2605..da7ce58 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -31,6 +31,7 @@ noinst_LTLIBRARIES = \
plugindir = $(libdir)/gs-plugins-${GS_PLUGIN_API_VERSION}
plugin_LTLIBRARIES = \
libgs_plugin_appstream.la \
+ libgs_plugin_key_colors.la \
libgs_plugin_dummy.la \
libgs_plugin_hardcoded-blacklist.la \
libgs_plugin_menu-spec-categories.la \
@@ -94,6 +95,11 @@ libgs_plugin_dummy_la_LIBADD = $(GS_PLUGIN_LIBS)
libgs_plugin_dummy_la_LDFLAGS = -module -avoid-version
libgs_plugin_dummy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_key_colors_la_SOURCES = gs-plugin-key-colors.c
+libgs_plugin_key_colors_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_key_colors_la_LDFLAGS = -module -avoid-version
+libgs_plugin_key_colors_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
if HAVE_SHELL_EXTENSIONS
libgs_plugin_shell_extensions_la_SOURCES = gs-plugin-shell-extensions.c
libgs_plugin_shell_extensions_la_LIBADD = $(GS_PLUGIN_LIBS) $(JSON_GLIB_LIBS)
diff --git a/src/plugins/gs-plugin-key-colors.c b/src/plugins/gs-plugin-key-colors.c
new file mode 100644
index 0000000..05d8b91
--- /dev/null
+++ b/src/plugins/gs-plugin-key-colors.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2011-2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <gs-plugin.h>
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+ return "key-colors";
+}
+
+/**
+ * gs_plugin_get_deps:
+ */
+const gchar **
+gs_plugin_get_deps (GsPlugin *plugin)
+{
+ static const gchar *deps[] = {
+ "icons", /* need icon */
+ NULL };
+ return deps;
+}
+
+typedef struct {
+ gdouble R;
+ gdouble G;
+ gdouble B;
+} CdColorRGB;
+
+typedef struct {
+ guint8 R;
+ guint8 G;
+ guint8 B;
+} CdColorRGB8;
+
+/**
+ * cd_color_rgb8_to_uint32:
+ */
+static guint32
+cd_color_rgb8_to_uint32 (CdColorRGB8 *rgb)
+{
+ return (guint32) rgb->R |
+ (guint32) rgb->G << 8 |
+ (guint32) rgb->B << 16;
+}
+
+typedef struct {
+ CdColorRGB color;
+ guint cnt;
+} GsColorBin;
+
+/**
+ * gs_color_bin_sort_cb:
+ */
+static gint
+gs_color_bin_sort_cb (gconstpointer a, gconstpointer b)
+{
+ GsColorBin *s1 = (GsColorBin *) a;
+ GsColorBin *s2 = (GsColorBin *) b;
+ if (s1->cnt < s2->cnt)
+ return 1;
+ if (s1->cnt > s2->cnt)
+ return -1;
+ return 0;
+}
+
+/**
+ * gs_plugin_key_colors_calculate:
+ */
+static GPtrArray *
+gs_plugin_key_colors_calculate (GdkPixbuf *pb, guint number)
+{
+ GList *l;
+ GPtrArray *key_colors = NULL;
+ gint rowstride, n_channels;
+ gint x, y;
+ guchar *pixels, *p;
+ guint bin_size = 200;
+ guint i;
+ guint number_of_bins;
+ g_autoptr(AsImage) im = NULL;
+
+ /* go through each pixel */
+ n_channels = gdk_pixbuf_get_n_channels (pb);
+ rowstride = gdk_pixbuf_get_rowstride (pb);
+ pixels = gdk_pixbuf_get_pixels (pb);
+ key_colors = g_ptr_array_new_with_free_func (g_free);
+ for (bin_size = 250; bin_size > 0; bin_size -= 2) {
+ g_autoptr(GHashTable) hash = NULL;
+ hash = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_free);
+ for (y = 0; y < gdk_pixbuf_get_height (pb); y++) {
+ for (x = 0; x < gdk_pixbuf_get_width (pb); x++) {
+ CdColorRGB8 tmp;
+ GsColorBin *s;
+ gpointer key;
+
+ /* disregard any with alpha */
+ p = pixels + y * rowstride + x * n_channels;
+ if (p[3] != 255)
+ continue;
+
+ /* find in cache */
+ tmp.R = p[0] / bin_size;
+ tmp.G = p[1] / bin_size;
+ tmp.B = p[2] / bin_size;
+ key = GUINT_TO_POINTER (cd_color_rgb8_to_uint32 (&tmp));
+ s = g_hash_table_lookup (hash, key);
+ if (s != NULL) {
+ s->color.R += p[0];
+ s->color.G += p[1];
+ s->color.B += p[2];
+ s->cnt++;
+ continue;
+ }
+
+ /* add to hash table */
+ s = g_new0 (GsColorBin, 1);
+ s->color.R = p[0];
+ s->color.G = p[1];
+ s->color.B = p[2];
+ s->cnt = 1;
+ g_hash_table_insert (hash, key, s);
+ }
+ }
+
+ number_of_bins = g_hash_table_size (hash);
+// g_debug ("number of colors: %i", number_of_bins);
+ if (number_of_bins >= number) {
+ g_autoptr(GList) values = NULL;
+
+ /* order by most popular */
+ values = g_hash_table_get_values (hash);
+ values = g_list_sort (values, gs_color_bin_sort_cb);
+ for (l = values; l != NULL; l = l->next) {
+ GsColorBin *s = l->data;
+ CdColorRGB *color = g_new0 (CdColorRGB, 1);
+ color->R = s->color.R / s->cnt;
+ color->G = s->color.G / s->cnt;
+ color->B = s->color.B / s->cnt;
+ g_ptr_array_add (key_colors, color);
+ }
+ break;
+ }
+ }
+
+ /* the algorithm failed, so just return a monochrome ramp */
+ if (key_colors->len == 0) {
+ for (i = 0; i < 3; i++) {
+ CdColorRGB *color = g_new0 (CdColorRGB, 1);
+ color->R = 255 * i / 3;
+ color->G = color->R;
+ color->B = color->R;
+ g_ptr_array_add (key_colors, color);
+ }
+ }
+
+ return key_colors;
+}
+
+/**
+ * gs_plugin_refine_app:
+ */
+gboolean
+gs_plugin_refine_app (GsPlugin *plugin,
+ GsApp *app,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GdkPixbuf *pb;
+ CdColorRGB *color1;
+ CdColorRGB *color2;
+ CdColorRGB *color3;
+ g_autofree gchar *css = NULL;
+ g_autoptr(GdkPixbuf) pb_small = NULL;
+ g_autoptr(GPtrArray) key_colors = NULL;
+
+ /* add a rating */
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_BACKGROUND) == 0)
+ return TRUE;
+
+ /* already set */
+ if (gs_app_get_metadata_item (app, "GnomeSoftware::popular-background") != NULL)
+ return TRUE;
+
+ /* no pixbuf */
+ pb = gs_app_get_pixbuf (app);
+ if (pb == NULL)
+ return TRUE;
+
+ /* get a list of key colors */
+ pb_small = gdk_pixbuf_scale_simple (pb, 32, 32, GDK_INTERP_BILINEAR);
+ key_colors = gs_plugin_key_colors_calculate (pb_small, 10);
+ color1 = g_ptr_array_index (key_colors, 0);
+ color2 = g_ptr_array_index (key_colors, 1);
+ color3 = g_ptr_array_index (key_colors, 2);
+ css = g_strdup_printf ("-gtk-recolor(url(\"file://%s/gnome-software/tile-symbolic.svg\"), "
+ "error rgb(%.0f,%.0f,%.0f), "
+ "warning rgb(%.0f,%.0f,%.0f), "
+ "success rgb(%.0f,%.0f,%.0f))",
+ DATADIR,
+ color1->R, color1->G, color1->B,
+ color2->R, color2->G, color2->B,
+ color3->R, color3->G, color3->B);
+ gs_app_set_metadata (app, "GnomeSoftware::popular-background", css);
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]