gui/artwork: Rework setting album art
I cleaned up several of the functions and added tests for making sure everything is set correctly. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
bc1c462d36
commit
fc1e917aee
|
@ -8,23 +8,20 @@
|
||||||
|
|
||||||
#define ARTWORK_PREVIEW_SIZE 150
|
#define ARTWORK_PREVIEW_SIZE 150
|
||||||
|
|
||||||
static struct album *__artwork_cur_album = NULL;
|
static struct album *artwork_current = NULL;
|
||||||
static unsigned int __artwork_timeo_id = 0;
|
static unsigned int artwork_timeout = 0;
|
||||||
|
|
||||||
static cairo_surface_t *__artwork_scale_pixbuf(GdkPixbuf *pix)
|
static cairo_surface_t *__gui_artwork_scale(cairo_surface_t *orig)
|
||||||
{
|
{
|
||||||
int old_h = gdk_pixbuf_get_height(pix);
|
int old_h = cairo_image_surface_get_height(orig);
|
||||||
int old_w = gdk_pixbuf_get_width(pix);
|
int old_w = cairo_image_surface_get_width(orig);
|
||||||
int new_h = gui_builder_widget_height("position") +
|
int new_h = gui_builder_widget_height("artwork");
|
||||||
gui_builder_widget_height("o_tags");
|
|
||||||
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_surface_t *orig = gdk_cairo_surface_create_from_pixbuf(pix, 0,
|
|
||||||
NULL);
|
|
||||||
cairo_content_t content = cairo_surface_get_content(orig);
|
cairo_content_t content = cairo_surface_get_content(orig);
|
||||||
cairo_surface_t *new = cairo_surface_create_similar(orig, content,
|
cairo_surface_t *scaled = cairo_surface_create_similar(orig, content,
|
||||||
new_w, new_h);
|
new_w, new_h);
|
||||||
cairo_t *cairo = cairo_create(new);
|
cairo_t *cairo = cairo_create(scaled);
|
||||||
|
|
||||||
cairo_scale(cairo, (double)(scale * new_w) / old_w,
|
cairo_scale(cairo, (double)(scale * new_w) / old_w,
|
||||||
(double)(scale * new_h) / old_h);
|
(double)(scale * new_h) / old_h);
|
||||||
|
@ -32,38 +29,34 @@ static cairo_surface_t *__artwork_scale_pixbuf(GdkPixbuf *pix)
|
||||||
cairo_paint(cairo);
|
cairo_paint(cairo);
|
||||||
|
|
||||||
cairo_destroy(cairo);
|
cairo_destroy(cairo);
|
||||||
cairo_surface_destroy(orig);
|
return scaled;
|
||||||
return new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *__artwork_get_surface(struct track *track)
|
static cairo_surface_t *__gui_artwork_get(gchar *path)
|
||||||
{
|
{
|
||||||
gchar *path = album_artwork_path(track->tr_album);
|
GdkPixbuf *pixbuf = path ? gdk_pixbuf_new_from_file(path, NULL) : NULL;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface = NULL;
|
||||||
GdkPixbuf *pix;
|
cairo_surface_t *scaled = NULL;
|
||||||
|
|
||||||
if (!path)
|
if (!pixbuf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pix = gdk_pixbuf_new_from_file(path, NULL);
|
surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 0, NULL);
|
||||||
if (!pix)
|
if (surface) {
|
||||||
return NULL;
|
scaled = __gui_artwork_scale(surface);
|
||||||
surface = __artwork_scale_pixbuf(pix);
|
cairo_surface_destroy(surface);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_unref(G_OBJECT(pix));
|
g_object_unref(G_OBJECT(pixbuf));
|
||||||
g_free(path);
|
return scaled;
|
||||||
return surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool __artwork_set_pixbuf(void)
|
static bool __gui_artwork_set(struct track *track)
|
||||||
{
|
{
|
||||||
struct track *track = audio_cur_track();
|
gchar *path = album_artwork_path(track->tr_album);
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface = __gui_artwork_get(path);
|
||||||
|
bool status = surface != NULL;
|
||||||
|
|
||||||
if (!track || track->tr_album == __artwork_cur_album)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
surface = __artwork_get_surface(track);
|
|
||||||
if (surface) {
|
if (surface) {
|
||||||
gtk_image_set_from_surface(gui_artwork(), surface);
|
gtk_image_set_from_surface(gui_artwork(), surface);
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
@ -71,24 +64,23 @@ static bool __artwork_set_pixbuf(void)
|
||||||
gtk_image_set_from_icon_name(gui_artwork(), "image-missing",
|
gtk_image_set_from_icon_name(gui_artwork(), "image-missing",
|
||||||
GTK_ICON_SIZE_DIALOG);
|
GTK_ICON_SIZE_DIALOG);
|
||||||
|
|
||||||
gtk_widget_set_sensitive(GTK_WIDGET(gui_artwork()), surface != NULL);
|
g_free(path);
|
||||||
__artwork_cur_album = surface ? track->tr_album : NULL;
|
return status;
|
||||||
return (surface != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean __artwork_timeout(gpointer data)
|
static gboolean __gui_artwork_timeout(gpointer data)
|
||||||
{
|
{
|
||||||
if (__artwork_set_pixbuf()) {
|
struct track *track = audio_cur_track();
|
||||||
__artwork_timeo_id = 0;
|
bool status;
|
||||||
|
|
||||||
|
if (!track || track->tr_album == artwork_current)
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_artwork_set_cover(void)
|
status = __gui_artwork_set(track);
|
||||||
{
|
gtk_widget_set_sensitive(GTK_WIDGET(gui_artwork()), status);
|
||||||
if (!__artwork_set_pixbuf() && __artwork_timeo_id == 0)
|
artwork_current = status ? track->tr_album : NULL;
|
||||||
__artwork_timeo_id = g_timeout_add(2000, __artwork_timeout, NULL);
|
artwork_timeout = status ? artwork_timeout : 0;
|
||||||
|
return status ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __artwork_update_preview(GtkFileChooser *chooser, gpointer data)
|
void __artwork_update_preview(GtkFileChooser *chooser, gpointer data)
|
||||||
|
@ -142,10 +134,17 @@ void __artwork_select_cover(GtkButton *button)
|
||||||
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);
|
album_artwork_import(track->tr_album, path);
|
||||||
__artwork_cur_album = NULL;
|
artwork_current = NULL;
|
||||||
gui_artwork_set_cover();
|
gui_artwork_set_cover();
|
||||||
g_free(path);
|
g_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
gtk_widget_destroy(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gui_artwork_set_cover(void)
|
||||||
|
{
|
||||||
|
if (__gui_artwork_timeout(NULL) != G_SOURCE_CONTINUE)
|
||||||
|
return;
|
||||||
|
artwork_timeout = g_timeout_add(2000, __gui_artwork_timeout, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="o_tags">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 (c) Anna Schumaker.
|
* Copyright 2016 (c) Anna Schumaker.
|
||||||
*/
|
*/
|
||||||
|
#include <core/audio.h>
|
||||||
#include <core/core.h>
|
#include <core/core.h>
|
||||||
#include <core/idle.h>
|
#include <core/idle.h>
|
||||||
#include <gui/artwork.h>
|
#include <gui/artwork.h>
|
||||||
|
@ -10,8 +11,23 @@
|
||||||
#include <gui/sidebar.h>
|
#include <gui/sidebar.h>
|
||||||
#include <gui/treeview.h>
|
#include <gui/treeview.h>
|
||||||
|
|
||||||
|
static void test_audio_load(struct track *track)
|
||||||
|
{ gui_artwork_set_cover(); }
|
||||||
|
static void test_change_state(GstState state) { }
|
||||||
|
static void test_config_pause(int n) { }
|
||||||
|
|
||||||
|
static struct audio_ops test_audio_ops = {
|
||||||
|
.on_load = test_audio_load,
|
||||||
|
.on_state_change = test_change_state,
|
||||||
|
.on_config_pause = test_config_pause,
|
||||||
|
};
|
||||||
|
|
||||||
struct core_init_data init_data = {
|
struct core_init_data init_data = {
|
||||||
.playlist_ops = &playlist_ops,
|
.playlist_ops = &playlist_ops,
|
||||||
|
.audio_ops = &test_audio_ops,
|
||||||
|
#ifdef CONFIG_ALBUM_ART_TEST
|
||||||
|
.idle_async = true,
|
||||||
|
#endif /* CONFIG_ALBUM_ART_TEST */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void test_artwork(void)
|
static void test_artwork(void)
|
||||||
|
@ -27,6 +43,23 @@ 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())));
|
||||||
|
|
||||||
|
#ifdef CONFIG_ALBUM_ART_TEST
|
||||||
|
audio_load(track_get(0));
|
||||||
|
g_assert_cmpuint(gtk_image_get_storage_type(gui_artwork()), ==,
|
||||||
|
GTK_IMAGE_SURFACE);
|
||||||
|
#endif /* CONFIG_ALBUM_ART_TEST */
|
||||||
|
|
||||||
|
track_get(1)->tr_album = album_find(artist_find("Koji Kondo"),
|
||||||
|
genre_find("Video Game Music"),
|
||||||
|
"Hyrule Symphony 2", 1999);
|
||||||
|
audio_load(track_get(1));
|
||||||
|
gtk_image_get_icon_name(gui_artwork(), &name, &size);
|
||||||
|
g_assert_cmpuint(gtk_image_get_storage_type(gui_artwork()), ==,
|
||||||
|
GTK_IMAGE_ICON_NAME);
|
||||||
|
g_assert_cmpstr(name, ==, "image-missing");
|
||||||
|
g_assert_cmpuint(size, ==, GTK_ICON_SIZE_DIALOG);
|
||||||
|
g_assert_false(gtk_widget_is_sensitive(GTK_WIDGET(gui_artwork())));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
|
Loading…
Reference in New Issue