gui/artwork: Rework importing album art

And add a test to check that everything is set correctly.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2016-09-06 11:09:41 -04:00
parent fc1e917aee
commit 0b231119d2
4 changed files with 43 additions and 34 deletions

View File

@ -11,11 +11,10 @@
static struct album *artwork_current = NULL; static struct album *artwork_current = NULL;
static unsigned int artwork_timeout = 0; static unsigned int artwork_timeout = 0;
static cairo_surface_t *__gui_artwork_scale(cairo_surface_t *orig) static cairo_surface_t *__gui_artwork_scale(cairo_surface_t *orig, int new_h)
{ {
int old_h = cairo_image_surface_get_height(orig); int old_h = cairo_image_surface_get_height(orig);
int old_w = cairo_image_surface_get_width(orig); int old_w = cairo_image_surface_get_width(orig);
int new_h = gui_builder_widget_height("artwork");
int new_w = (old_w * new_h) / old_h; int new_w = (old_w * new_h) / old_h;
int scale = gtk_widget_get_scale_factor(GTK_WIDGET(gui_artwork())); int scale = gtk_widget_get_scale_factor(GTK_WIDGET(gui_artwork()));
cairo_content_t content = cairo_surface_get_content(orig); cairo_content_t content = cairo_surface_get_content(orig);
@ -32,7 +31,7 @@ static cairo_surface_t *__gui_artwork_scale(cairo_surface_t *orig)
return scaled; return scaled;
} }
static cairo_surface_t *__gui_artwork_get(gchar *path) static cairo_surface_t *__gui_artwork_get(gchar *path, int new_h)
{ {
GdkPixbuf *pixbuf = path ? gdk_pixbuf_new_from_file(path, NULL) : NULL; GdkPixbuf *pixbuf = path ? gdk_pixbuf_new_from_file(path, NULL) : NULL;
cairo_surface_t *surface = NULL; cairo_surface_t *surface = NULL;
@ -43,7 +42,7 @@ static cairo_surface_t *__gui_artwork_get(gchar *path)
surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL); surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
if (surface) { if (surface) {
scaled = __gui_artwork_scale(surface); scaled = __gui_artwork_scale(surface, new_h);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} }
@ -51,65 +50,55 @@ static cairo_surface_t *__gui_artwork_get(gchar *path)
return scaled; return scaled;
} }
static bool __gui_artwork_set(struct track *track) static bool __gui_artwork_set_path(GtkImage *image, gchar *path, int new_h)
{ {
gchar *path = album_artwork_path(track->tr_album); cairo_surface_t *surface = __gui_artwork_get(path, new_h);
cairo_surface_t *surface = __gui_artwork_get(path);
bool status = surface != NULL; bool status = surface != NULL;
if (surface) { if (surface) {
gtk_image_set_from_surface(gui_artwork(), surface); gtk_image_set_from_surface(image, surface);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} else } else
gtk_image_set_from_icon_name(gui_artwork(), "image-missing", gtk_image_set_from_icon_name(image, "image-missing",
GTK_ICON_SIZE_DIALOG); GTK_ICON_SIZE_DIALOG);
g_free(path);
return status; return status;
} }
static gboolean __gui_artwork_timeout(gpointer data) static gboolean __gui_artwork_timeout(gpointer data)
{ {
struct track *track = audio_cur_track(); struct track *track = audio_cur_track();
bool status; int height = gui_builder_widget_height("artwork");
gchar *path;
bool status;
if (!track || track->tr_album == artwork_current) if (!track || track->tr_album == artwork_current)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
status = __gui_artwork_set(track); path = album_artwork_path(track->tr_album);
status = __gui_artwork_set_path(gui_artwork(), path, height);
gtk_widget_set_sensitive(GTK_WIDGET(gui_artwork()), status); gtk_widget_set_sensitive(GTK_WIDGET(gui_artwork()), status);
artwork_current = status ? track->tr_album : NULL; artwork_current = status ? track->tr_album : NULL;
artwork_timeout = status ? artwork_timeout : 0; artwork_timeout = status ? artwork_timeout : 0;
g_free(path);
return status ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE; return status ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
} }
void __artwork_update_preview(GtkFileChooser *chooser, gpointer data) void __gui_artwork_update_preview(GtkFileChooser *chooser, gpointer data)
{ {
GtkWidget *preview = gtk_file_chooser_get_preview_widget(chooser); GtkWidget *preview = gtk_file_chooser_get_preview_widget(chooser);
gchar *path = gtk_file_chooser_get_preview_filename(chooser); gchar *path = gtk_file_chooser_get_preview_filename(chooser);
GdkPixbuf *pix = gdk_pixbuf_new_from_file(path, NULL);
unsigned int old_w, scale;
cairo_surface_t *surface;
if (pix) {
old_w = gdk_pixbuf_get_width(pix);
scale = old_w / ARTWORK_PREVIEW_SIZE;
surface = gdk_cairo_surface_create_from_pixbuf(pix, scale, NULL);
if (surface) {
gtk_image_set_from_surface(GTK_IMAGE(preview), surface);
cairo_surface_destroy(surface);
}
}
__gui_artwork_set_path(GTK_IMAGE(preview), path, ARTWORK_PREVIEW_SIZE);
g_free(path); g_free(path);
} }
void __artwork_select_cover(GtkButton *button) void __gui_artwork_select_cover(GtkButton *button)
{ {
struct track *track = audio_cur_track(); struct track *track = audio_cur_track();
GtkWidget *preview, *dialog;
GtkFileFilter *filter; GtkFileFilter *filter;
GtkWidget *dialog;
GtkWidget *preview;
gchar *path; gchar *path;
if (!track) if (!track)
@ -129,13 +118,12 @@ void __artwork_select_cover(GtkButton *button)
gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), preview); gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), preview);
gtk_file_chooser_set_use_preview_label(GTK_FILE_CHOOSER(dialog), false); gtk_file_chooser_set_use_preview_label(GTK_FILE_CHOOSER(dialog), false);
g_signal_connect(dialog, "update-preview", (GCallback)__artwork_update_preview, NULL); g_signal_connect(dialog, "update-preview",
(GCallback)__gui_artwork_update_preview, NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
album_artwork_import(track->tr_album, path); gui_artwork_import(track, path);
artwork_current = NULL;
gui_artwork_set_cover();
g_free(path); g_free(path);
} }
@ -148,3 +136,12 @@ void gui_artwork_set_cover(void)
return; return;
artwork_timeout = g_timeout_add(2000, __gui_artwork_timeout, NULL); artwork_timeout = g_timeout_add(2000, __gui_artwork_timeout, NULL);
} }
void gui_artwork_import(struct track *track, gchar *path)
{
album_artwork_import(track->tr_album, path);
if (track == audio_cur_track()) {
artwork_current = NULL;
gui_artwork_set_cover();
}
}

View File

@ -8,6 +8,9 @@
/* Called to set artwork for a track. */ /* Called to set artwork for a track. */
void gui_artwork_set_cover(void); void gui_artwork_set_cover(void);
/* Called to import artwork for a track. */
void gui_artwork_import(struct track *, gchar *);
/* Called to get the cover image. */ /* Called to get the cover image. */
static inline GtkImage *gui_artwork(void) static inline GtkImage *gui_artwork(void)
{ {

View File

@ -284,7 +284,7 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="relief">none</property> <property name="relief">none</property>
<signal name="clicked" handler="__artwork_select_cover" swapped="no"/> <signal name="clicked" handler="__gui_artwork_select_cover" swapped="no"/>
<child> <child>
<object class="GtkImage" id="artwork"> <object class="GtkImage" id="artwork">
<property name="height_request">100</property> <property name="height_request">100</property>

View File

@ -34,6 +34,7 @@ static void test_artwork(void)
{ {
const gchar *name; const gchar *name;
GtkIconSize size; GtkIconSize size;
gchar *path;
g_assert_true(GTK_IS_IMAGE(gui_artwork())); g_assert_true(GTK_IS_IMAGE(gui_artwork()));
@ -60,6 +61,14 @@ static void test_artwork(void)
g_assert_cmpstr(name, ==, "image-missing"); g_assert_cmpstr(name, ==, "image-missing");
g_assert_cmpuint(size, ==, GTK_ICON_SIZE_DIALOG); g_assert_cmpuint(size, ==, GTK_ICON_SIZE_DIALOG);
g_assert_false(gtk_widget_is_sensitive(GTK_WIDGET(gui_artwork()))); g_assert_false(gtk_widget_is_sensitive(GTK_WIDGET(gui_artwork())));
path = album_artwork_path(track_get(0)->tr_album);
#ifdef CONFIG_ALBUM_ART_TEST
gui_artwork_import(track_get(1), path);
g_assert_cmpuint(gtk_image_get_storage_type(gui_artwork()), ==,
GTK_IMAGE_SURFACE);
#endif /* CONFIG_ALBUM_ART_TEST */
g_free(path);
} }
int main(int argc, char **argv) int main(int argc, char **argv)