summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2015-01-20 11:09:59 +0100
committerBastien Nocera <hadess@hadess.net>2015-01-20 11:09:59 +0100
commit542079d35d59b57c4753793fcfb7a04c351a979c (patch)
tree70de5f97f6e19783a7aa36ab670ababd76546239
parent754679c6f0d58ee1e93a6b923d9eb8b20d8f2d9f (diff)
downloadtotem-542079d35d59b57c4753793fcfb7a04c351a979c.tar.gz
grilo: Modify appearance of source icons
In the channels view, modify the source channels icons to have a slightly transparent background, and frame the icon, allowing us to avoid having to create grilo specific icons. See https://bugzilla.gnome.org/show_bug.cgi?id=736548
-rw-r--r--src/icon-helpers.c144
1 files changed, 104 insertions, 40 deletions
diff --git a/src/icon-helpers.c b/src/icon-helpers.c
index 08d556a97..b26ca5373 100644
--- a/src/icon-helpers.c
+++ b/src/icon-helpers.c
@@ -33,6 +33,8 @@
#define DEFAULT_MAX_THREADS 5
#define THUMB_SEARCH_SIZE 256
#define THUMB_SEARCH_HEIGHT (THUMB_SEARCH_SIZE / 4 * 3)
+#define SOURCES_MAX_HEIGHT 32
+#define VIDEO_ICON_SIZE 16
typedef enum {
ICON_BOX = 0,
@@ -47,6 +49,12 @@ static GThreadPool *thumbnail_pool;
static GdkPixbuf *icons[NUM_ICONS];
static GHashTable *cache_thumbnails; /* key=url, value=GdkPixbuf */
+static GdkPixbuf *load_icon (GdkPixbuf *pixbuf, gboolean with_border, gboolean resize);
+static GdkPixbuf *load_named_icon (Totem *totem,
+ const char *name,
+ int size,
+ gboolean with_border);
+
static gboolean
media_is_local (GrlMedia *media)
{
@@ -90,6 +98,16 @@ load_thumbnail_cb (GObject *source_object,
/* Cache it */
file = g_task_get_task_data (task);
if (file) {
+ gboolean is_source;
+
+ is_source = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "is-source"));
+ if (is_source) {
+ GdkPixbuf *new_pixbuf;
+
+ new_pixbuf = load_icon (pixbuf, TRUE, TRUE);
+ g_object_unref (pixbuf);
+ pixbuf = new_pixbuf;
+ }
g_hash_table_insert (cache_thumbnails,
g_file_get_uri (G_FILE (file)),
g_object_ref (pixbuf));
@@ -107,6 +125,7 @@ get_stream_thumbnail_cb (GObject *source_object,
GTask *task = user_data;
GFileInputStream *stream;
GError *error = NULL;
+ gboolean is_source;
stream = g_file_read_finish (G_FILE (source_object), res, &error);
if (!stream) {
@@ -115,9 +134,10 @@ get_stream_thumbnail_cb (GObject *source_object,
return;
}
+ is_source = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "is-source"));
gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream),
- THUMB_SEARCH_SIZE,
- THUMB_SEARCH_HEIGHT,
+ is_source ? -1 : THUMB_SEARCH_SIZE,
+ is_source ? -1 : THUMB_SEARCH_HEIGHT,
TRUE,
g_task_get_cancellable (task),
load_thumbnail_cb,
@@ -276,6 +296,8 @@ totem_grilo_get_thumbnail (GObject *object,
file = g_file_icon_get_file (G_FILE_ICON (icon));
url_thumb = g_file_get_uri (file);
g_object_unref (file);
+
+ g_object_set_data (G_OBJECT (task), "is-source", GUINT_TO_POINTER (TRUE));
}
}
if (url_thumb == NULL) {
@@ -310,34 +332,17 @@ put_pixel (guchar *p)
}
static GdkPixbuf *
-load_icon (Totem *totem,
- const char *name,
- int size,
- gboolean with_border)
+load_icon (GdkPixbuf *pixbuf,
+ gboolean with_border,
+ gboolean resize)
{
- GApplication *app;
- GdkScreen *screen;
- GIcon *icon;
- GList *windows;
- GtkIconInfo *info;
- GtkIconTheme *theme;
- GtkStyleContext *context;
- GdkPixbuf *pixbuf, *ret;
+ GdkPixbuf *ret;
guchar *pixels;
int rowstride;
int x, y;
-
- app = g_application_get_default ();
- windows = gtk_application_get_windows (GTK_APPLICATION (app));
- if (windows == NULL)
- return NULL;
-
- icon = g_themed_icon_new (name);
- screen = gdk_screen_get_default ();
- theme = gtk_icon_theme_get_for_screen (screen);
- info = gtk_icon_theme_lookup_by_gicon (theme, icon, size, GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
- context = gtk_widget_get_style_context (GTK_WIDGET (windows->data));
- pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
+ int width, height;
+ gdouble offset_x, offset_y, scale;
+ int dest_x, dest_y;
ret = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
TRUE,
@@ -345,11 +350,10 @@ load_icon (Totem *totem,
pixels = gdk_pixbuf_get_pixels (ret);
rowstride = gdk_pixbuf_get_rowstride (ret);
- /* Clean up */
- gdk_pixbuf_fill (ret, 0x00000000);
-
- /* Draw a border */
+ /* Clean up and draw a border */
if (with_border) {
+ gdk_pixbuf_fill (ret, 0x00000088);
+
/* top */
for (x = 0; x < THUMB_SEARCH_SIZE; x++)
put_pixel (pixels + x * 4);
@@ -362,14 +366,74 @@ load_icon (Totem *totem,
/* right */
for (y = 1; y < THUMB_SEARCH_HEIGHT - 1; y++)
put_pixel (pixels + y * rowstride + (THUMB_SEARCH_SIZE - 1) * 4);
+ } else {
+ gdk_pixbuf_fill (ret, 0x00000000);
+ }
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ if (resize &&
+ (width > (THUMB_SEARCH_SIZE / 4 * 3) ||
+ height > SOURCES_MAX_HEIGHT)) {
+ gdouble scale_x, scale_y;
+ scale_x = ((gdouble) THUMB_SEARCH_SIZE / 4.0 * 3.0) / (gdouble) width;
+ scale_y = (gdouble) SOURCES_MAX_HEIGHT / (gdouble) height;
+ if (scale_y < 1.0)
+ scale = scale_y;
+ else
+ scale = MIN(MIN(scale_x, scale_y), 1.0);
+ } else {
+ scale = 1.0;
}
- /* Put the icon in the middle */
- gdk_pixbuf_copy_area (pixbuf, 0, 0,
- gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
- ret,
- (THUMB_SEARCH_SIZE - gdk_pixbuf_get_width (pixbuf)) / 2,
- (THUMB_SEARCH_HEIGHT - gdk_pixbuf_get_height (pixbuf)) / 2);
+ /* Put the icon in the middle, with help from this post:
+ * http://permalink.gmane.org/gmane.comp.desktop.rox.devel/9065 */
+ offset_x = (THUMB_SEARCH_SIZE - width * scale) / 2;
+ offset_y = (THUMB_SEARCH_HEIGHT - height * scale) / 2;
+ dest_x = MAX(offset_x, 0);
+ dest_y = MAX(offset_y, 0);
+ gdk_pixbuf_composite (pixbuf, ret,
+ dest_x, dest_y,
+ MIN(THUMB_SEARCH_SIZE, width * scale),
+ MIN(THUMB_SEARCH_HEIGHT, height * scale),
+ offset_x,
+ offset_y,
+ scale, scale,
+ GDK_INTERP_BILINEAR,
+ 255);
+
+ return ret;
+}
+
+static GdkPixbuf *
+load_named_icon (Totem *totem,
+ const char *name,
+ int size,
+ gboolean with_border)
+{
+ GApplication *app;
+ GdkScreen *screen;
+ GIcon *icon;
+ GList *windows;
+ GtkIconInfo *info;
+ GtkIconTheme *theme;
+ GtkStyleContext *context;
+ GdkPixbuf *pixbuf, *ret;
+
+ app = g_application_get_default ();
+ windows = gtk_application_get_windows (GTK_APPLICATION (app));
+ if (windows == NULL)
+ return NULL;
+
+ icon = g_themed_icon_new (name);
+ screen = gdk_screen_get_default ();
+ theme = gtk_icon_theme_get_for_screen (screen);
+ info = gtk_icon_theme_lookup_by_gicon (theme, icon, size, GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
+ context = gtk_widget_get_style_context (GTK_WIDGET (windows->data));
+ pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
+
+ ret = load_icon (pixbuf, with_border, FALSE);
g_object_unref (pixbuf);
g_object_unref (info);
@@ -435,10 +499,10 @@ totem_grilo_clear_icons (void)
void
totem_grilo_setup_icons (Totem *totem)
{
- icons[ICON_BOX] = load_icon (totem, "folder-symbolic", THUMB_SEARCH_HEIGHT, FALSE);
- icons[ICON_VIDEO] = load_icon (totem, "folder-videos-symbolic", 16, TRUE);
- icons[ICON_VIDEO_THUMBNAILING] = load_icon (totem, "content-loading-symbolic", 16, TRUE);
- icons[ICON_OPTICAL] = load_icon (totem, "media-optical-dvd-symbolic", THUMB_SEARCH_HEIGHT, FALSE);
+ icons[ICON_BOX] = load_named_icon (totem, "folder-symbolic", THUMB_SEARCH_HEIGHT, FALSE);
+ icons[ICON_VIDEO] = load_named_icon (totem, "folder-videos-symbolic", VIDEO_ICON_SIZE, TRUE);
+ icons[ICON_VIDEO_THUMBNAILING] = load_named_icon (totem, "content-loading-symbolic", VIDEO_ICON_SIZE, TRUE);
+ icons[ICON_OPTICAL] = load_named_icon (totem, "media-optical-dvd-symbolic", THUMB_SEARCH_HEIGHT, FALSE);
cache_thumbnails = g_hash_table_new_full (g_str_hash,
g_str_equal,