summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-10-16 22:43:52 +0200
committerGravatar Alexey Yakovenko <waker@users.sourceforge.net>2013-10-16 22:43:52 +0200
commite93a9b2d9677b7ef3142a03f370ef545659b5773 (patch)
tree3005858226bb439a72c5cc852ee55b7ea52ec198
parentc700c20bb67117dd57ff3130b1a1d46c53b8c626 (diff)
gtkui: several fixes/improvements in playlist cover rendering
-rw-r--r--plugins/artwork/artwork.c2
-rw-r--r--plugins/artwork/artwork.h5
-rw-r--r--plugins/gtkui/coverart.c56
-rw-r--r--plugins/gtkui/coverart.h5
-rw-r--r--plugins/gtkui/ddblistview.c3
-rw-r--r--plugins/gtkui/plcommon.c17
6 files changed, 76 insertions, 12 deletions
diff --git a/plugins/artwork/artwork.c b/plugins/artwork/artwork.c
index cf4b25e0..23d05886 100644
--- a/plugins/artwork/artwork.c
+++ b/plugins/artwork/artwork.c
@@ -90,7 +90,6 @@ static const char *get_default_cover (void) {
int
make_cache_dir_path (char *path, int size, const char *artist, int img_size) {
const char *cache = getenv ("XDG_CACHE_HOME");
-
int sz;
if (img_size == -1) {
@@ -1484,4 +1483,5 @@ static DB_artwork_plugin_t plugin = {
.reset = artwork_reset,
.get_default_cover = get_default_cover,
.get_album_art_sync = get_album_art_sync,
+ .make_cache_path = make_cache_path,
};
diff --git a/plugins/artwork/artwork.h b/plugins/artwork/artwork.h
index 1c60475c..117e263d 100644
--- a/plugins/artwork/artwork.h
+++ b/plugins/artwork/artwork.h
@@ -10,6 +10,8 @@ typedef void (*artwork_callback) (const char *fname, const char *artist, const c
typedef struct {
DB_misc_t plugin;
// returns filename of cached image, or NULL
+ // negative size has special meanings:
+ // -1: return default cover if not available (otherwise NULL will be returned)
char* (*get_album_art) (const char *fname, const char *artist, const char *album, int size, artwork_callback callback, void *user_data);
// this has to be called to clear queue on exit, before caller terminates
@@ -19,6 +21,9 @@ typedef struct {
// synchronously get filename
char* (*get_album_art_sync) (const char *fname, const char *artist, const char *album, int size);
+
+ // creates full path string for cache storage
+ void (*make_cache_path) (char *path, int size, const char *album, const char *artist, int img_size);
} DB_artwork_plugin_t;
#endif /*__ARTWORK_H*/
diff --git a/plugins/gtkui/coverart.c b/plugins/gtkui/coverart.c
index c3d93b8d..0e08d180 100644
--- a/plugins/gtkui/coverart.c
+++ b/plugins/gtkui/coverart.c
@@ -65,15 +65,19 @@ static void
queue_add (const char *fname, int width, void (*callback) (void *user_data), void *user_data) {
deadbeef->mutex_lock (mutex);
load_query_t *q;
- for (q = queue; q; q = q->next) {
- if (!strcmp (q->fname, fname) && width == q->width) {
- deadbeef->mutex_unlock (mutex);
- return; // dupe
+ if (fname) {
+ for (q = queue; q; q = q->next) {
+ if (!strcmp (q->fname, fname) && width == q->width) {
+ deadbeef->mutex_unlock (mutex);
+ return; // dupe
+ }
}
}
q = malloc (sizeof (load_query_t));
memset (q, 0, sizeof (load_query_t));
- q->fname = strdup (fname);
+ if (fname) {
+ q->fname = strdup (fname);
+ }
q->width = width;
q->callback = callback;
q->user_data = user_data;
@@ -138,6 +142,14 @@ loading_thread (void *none) {
}
}
deadbeef->mutex_unlock (mutex);
+ if (!queue->fname) {
+ if (queue->callback) {
+ queue->callback (queue->user_data);
+ }
+ queue_pop ();
+ continue;
+ }
+
if (cache_min == -1) {
trace ("coverart pixbuf cache overflow, waiting...\n");
usleep (500000);
@@ -250,12 +262,46 @@ get_pixbuf (const char *fname, int width, void (*callback)(void *user_data), voi
return NULL;
}
+void
+queue_cover_callback (void (*callback)(void *user_data), void *user_data) {
+ queue_add (NULL, -1, callback, user_data);
+}
+
GdkPixbuf *
get_cover_art_callb (const char *fname, const char *artist, const char *album, int width, void (*callback) (void *user_data), void *user_data) {
if (!coverart_plugin) {
return NULL;
}
+
+ if (width == -1) {
+ char path[2048];
+ coverart_plugin->make_cache_path (path, sizeof (path), album, artist, -1);
+ deadbeef->mutex_lock (mutex);
+ int i_largest = -1;
+ int size_largest = -1;
+ for (int i = 0; i < CACHE_SIZE; i++) {
+ if (!cache[i].pixbuf) {
+ continue;
+ }
+ if (!strcmp (cache[i].fname, path)) {
+ gettimeofday (&cache[i].tm, NULL);
+ if (cache[i].width > size_largest) {
+ size_largest = cache[i].width;
+ i_largest = i;
+ }
+ }
+ }
+ if (i_largest != -1) {
+ GdkPixbuf *pb = cache[i_largest].pixbuf;
+ g_object_ref (pb);
+ deadbeef->mutex_unlock (mutex);
+ return pb;
+ }
+ deadbeef->mutex_unlock (mutex);
+ return NULL;
+ }
+
cover_avail_info_t *dt = malloc (sizeof (cover_avail_info_t));
dt->width = width;
dt->callback = callback;
diff --git a/plugins/gtkui/coverart.h b/plugins/gtkui/coverart.h
index 5f6bc2ef..d3658caf 100644
--- a/plugins/gtkui/coverart.h
+++ b/plugins/gtkui/coverart.h
@@ -40,5 +40,10 @@ cover_art_init (void);
void
cover_art_free (void);
+// simply inserts callback point into queue
+// the callback will be called when the loading queue reaches this request
+void
+queue_cover_callback (void (*callback)(void *user_data), void *user_data);
+
#endif
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c
index e3027654..103971fb 100644
--- a/plugins/gtkui/ddblistview.c
+++ b/plugins/gtkui/ddblistview.c
@@ -662,8 +662,11 @@ ddb_listview_list_pickpoint_y (DdbListview *listview, int y, DdbListviewGroup **
return -1;
}
+int render_idx = 0;
+
void
ddb_listview_list_render (DdbListview *listview, cairo_t *cr, int x, int y, int w, int h) {
+ render_idx = 0;
cairo_set_line_width (cr, 1);
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
GtkWidget *treeview = theme_treeview;
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index 041593e0..b509cbd7 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -138,7 +138,10 @@ deferred_cover_load_cb (void *ctx) {
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, last ? redraw_playlist : NULL, lv);
+ GdkPixbuf *pixbuf = get_cover_art_callb (deadbeef->pl_find_meta (((DB_playItem_t *)group_it), ":URI"), artist, album, lv->new_cover_size, NULL, NULL);
+ if (last) {
+ queue_cover_callback (redraw_playlist, lv);
+ }
if (pixbuf) {
g_object_unref (pixbuf);
}
@@ -209,7 +212,6 @@ void draw_column_data (DdbListview *listview, cairo_t *cr, DdbListviewIter it, D
}
}
int art_width = listview->cover_size;
- float art_scale = (float)real_art_width / art_width;
int art_y = y; // dest y
int art_h = height;
int sy; // source y
@@ -224,8 +226,10 @@ void draw_column_data (DdbListview *listview, cairo_t *cr, DdbListviewIter it, D
int h = cwidth - group_y;
h = min (height, art_h);
- GdkPixbuf *pixbuf = get_cover_art_callb (deadbeef->pl_find_meta (((DB_playItem_t *)group_it), ":URI"), artist, album, art_width, redraw_playlist_single, listview);
+ GdkPixbuf *pixbuf = get_cover_art_callb (deadbeef->pl_find_meta (((DB_playItem_t *)group_it), ":URI"), artist, album, real_art_width == art_width ? art_width : -1, redraw_playlist_single, listview);
if (pixbuf) {
+ art_width = gdk_pixbuf_get_width (pixbuf);
+ float art_scale = (float)real_art_width / art_width;
int pw = real_art_width;
int ph;
if (group_pinned == 1 && gtkui_groups_pinned) {
@@ -240,9 +244,9 @@ void draw_column_data (DdbListview *listview, cairo_t *cr, DdbListviewIter it, D
cairo_save (cr);
if (group_pinned == 1 && gtkui_groups_pinned) {
int ph_real = gdk_pixbuf_get_height (pixbuf);
- if (grp_next_y <= ph_real + listview->grouptitle_height) {
- cairo_rectangle (cr, x + ART_PADDING_HORZ, grp_next_y - ph_real, pw, ph);
- cairo_translate (cr, (x + ART_PADDING_HORZ)-0, grp_next_y - ph_real);
+ if (grp_next_y <= ph_real * art_scale + listview->grouptitle_height) {
+ cairo_rectangle (cr, x + ART_PADDING_HORZ, grp_next_y - ph_real * art_scale, pw, ph);
+ cairo_translate (cr, (x + ART_PADDING_HORZ)-0, grp_next_y - ph_real * art_scale);
}
else {
cairo_rectangle (cr, x + ART_PADDING_HORZ, listview->grouptitle_height, pw, ph);
@@ -261,6 +265,7 @@ void draw_column_data (DdbListview *listview, cairo_t *cr, DdbListviewIter it, D
cairo_fill (cr);
cairo_restore (cr);
}
+ g_object_unref (pixbuf);
}
}
}