summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-10-17 22:57:28 +0200
committerGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-10-17 22:57:28 +0200
commit60350fd75a0fbb59dab7161ebf602991243f9e51 (patch)
treee776a742ed79ca21b9e62faca8089ab7477cf53f
parent273fb55a248353d51dacfa7ac8853cb0b87340a5 (diff)
gtkui: improved cover widget
-rw-r--r--plugins/gtkui/plcommon.c1
-rw-r--r--plugins/gtkui/widgets.c112
2 files changed, 97 insertions, 16 deletions
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index ea634519..dd0df61e 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -135,7 +135,6 @@ deferred_cover_load_cb (void *ctx) {
grp = grp->next;
int last = 0;
if (!grp || grp_y >= a.height + lv->scrollpos) {
- printf ("queue redraw for cover size %d\n", lv->new_cover_size);
last = 1;
}
GdkPixbuf *pixbuf = get_cover_art_callb (deadbeef->pl_find_meta (((DB_playItem_t *)group_it), ":URI"), artist, album, lv->new_cover_size, NULL, NULL);
diff --git a/plugins/gtkui/widgets.c b/plugins/gtkui/widgets.c
index cb249835..0b8cde31 100644
--- a/plugins/gtkui/widgets.c
+++ b/plugins/gtkui/widgets.c
@@ -116,6 +116,9 @@ typedef struct {
typedef struct {
ddb_gtkui_widget_t base;
GtkWidget *drawarea;
+ int cover_size;
+ int new_cover_size;
+ guint cover_refresh_timeout_id;
} w_coverart_t;
typedef struct {
@@ -1948,6 +1951,7 @@ w_selproperties_create (void) {
static gboolean
coverart_redraw_cb (void *user_data) {
w_coverart_t *w = user_data;
+ w->cover_size = w->new_cover_size;
gtk_widget_queue_draw (w->drawarea);
return FALSE;
}
@@ -1958,31 +1962,107 @@ coverart_avail_callback (void *user_data) {
}
static gboolean
+coverart_redraw_single_cb (void *user_data) {
+ w_coverart_t *w = user_data;
+ gtk_widget_queue_draw (w->drawarea);
+ return FALSE;
+}
+
+static void
+coverart_avail_callback_single (gpointer user_data) {
+ g_idle_add (coverart_redraw_single_cb, user_data);
+}
+
+static gboolean
+deferred_cover_load_cb (void *ctx) {
+ w_coverart_t *w = ctx;
+ w->cover_refresh_timeout_id = 0;
+ DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
+ if (!it) {
+ return FALSE;
+ }
+ GtkAllocation a;
+ gtk_widget_get_allocation (GTK_WIDGET (w->drawarea), &a);
+ deadbeef->pl_lock ();
+ const char *album = deadbeef->pl_find_meta (it, "album");
+ const char *artist = deadbeef->pl_find_meta (it, "artist");
+ if (!album || !*album) {
+ album = deadbeef->pl_find_meta (it, "title");
+ }
+ GdkPixbuf *pixbuf = get_cover_art_callb (deadbeef->pl_find_meta (((DB_playItem_t *)it), ":URI"), artist, album, w->new_cover_size, NULL, NULL);
+ deadbeef->pl_unlock ();
+ deadbeef->pl_item_unref (it);
+ queue_cover_callback (coverart_avail_callback, w);
+ if (pixbuf) {
+ g_object_unref (pixbuf);
+ }
+
+ return FALSE;
+}
+
+static gboolean
coverart_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) {
DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
GtkAllocation a;
gtk_widget_get_allocation (widget, &a);
int width = a.width;
int height = a.height;
- const char *album = NULL, *artist = NULL;
- if (it) {
- album = deadbeef->pl_find_meta (it, "album");
- artist = deadbeef->pl_find_meta (it, "artist");
+
+ w_coverart_t *w = user_data;
+ int real_size = min (width, height);
+ if (w->cover_size == -1) {
+ w->cover_size = w->new_cover_size = real_size;
+ }
+ if (real_size > 0 && it) {
+ if (w->new_cover_size != real_size) {
+ w->new_cover_size = real_size;
+ if (w->cover_refresh_timeout_id) {
+ g_source_remove (w->cover_refresh_timeout_id);
+ w->cover_refresh_timeout_id = 0;
+ }
+ if (w->cover_size == -1) {
+ w->cover_size = real_size;
+ }
+ else {
+ if (!w->cover_refresh_timeout_id) {
+ w->cover_refresh_timeout_id = g_timeout_add (1000, deferred_cover_load_cb, w);
+ }
+ }
+ }
+ int size = w->cover_size;
+
+ float scale = (float)real_size / size;
+
+ deadbeef->pl_lock ();
+ const char *album = deadbeef->pl_find_meta (it, "album");
+ const char *artist = deadbeef->pl_find_meta (it, "artist");
if (!album || !*album) {
album = deadbeef->pl_find_meta (it, "title");
}
- }
- GdkPixbuf *pixbuf = get_cover_art_callb (it ? deadbeef->pl_find_meta ((it), ":URI") : NULL, artist, album, min(width,height), coverart_avail_callback, user_data);
+ GdkPixbuf *pixbuf = get_cover_art_callb (it ? deadbeef->pl_find_meta ((it), ":URI") : NULL, artist, album, real_size == size ? size : -1, coverart_avail_callback_single, user_data);
+ deadbeef->pl_unlock ();
- if (pixbuf) {
- int pw = gdk_pixbuf_get_width (pixbuf);
- int ph = gdk_pixbuf_get_height (pixbuf);
- gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
- cairo_rectangle (cr, 0, 0, pw, ph);
- cairo_fill (cr);
- g_object_unref (pixbuf);
- }
- if (it) {
+ int hq = 0;
+ if (!pixbuf) {
+ pixbuf = cover_get_default_pixbuf ();
+ hq = 1;
+ }
+
+ if (pixbuf) {
+ size = gdk_pixbuf_get_width (pixbuf);
+ float art_scale = (float)real_size / size;
+ int pw = real_size;
+ if (gdk_pixbuf_get_width (pixbuf) < gdk_pixbuf_get_height (pixbuf)) {
+ art_scale *= (float)gdk_pixbuf_get_width (pixbuf) / gdk_pixbuf_get_height (pixbuf);
+ }
+ int ph = pw;
+ cairo_rectangle (cr, 0, 0, pw, ph);
+ cairo_scale (cr, art_scale, art_scale);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source(cr), hq ? CAIRO_FILTER_GAUSSIAN : CAIRO_FILTER_FAST);
+ cairo_fill (cr);
+ g_object_unref (pixbuf);
+ }
deadbeef->pl_item_unref (it);
}
return TRUE;
@@ -2024,6 +2104,8 @@ w_coverart_create (void) {
w->base.widget = gtk_event_box_new ();
w->base.message = coverart_message;
w->drawarea = gtk_drawing_area_new ();
+ w->cover_size = -1;
+ w->new_cover_size = -1;
gtk_widget_show (w->drawarea);
gtk_container_add (GTK_CONTAINER (w->base.widget), w->drawarea);
#if !GTK_CHECK_VERSION(3,0,0)