196 lines
5.1 KiB
C
196 lines
5.1 KiB
C
/*
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/audio.h>
|
|
#include <core/collection.h>
|
|
#include <core/playlist.h>
|
|
#include <core/string.h>
|
|
#include <gui/audio.h>
|
|
#include <gui/builder.h>
|
|
#include <gui/idle.h>
|
|
#include <gui/view.h>
|
|
#include <glib/gi18n.h>
|
|
|
|
static bool __audio_have_cover = false;
|
|
|
|
static inline void __audio_set_label(const gchar *label, const gchar *size,
|
|
const gchar *text)
|
|
{
|
|
gchar *markup = g_markup_printf_escaped("<span size='%s'>%s</span>",
|
|
size, text);
|
|
gtk_label_set_markup(GTK_LABEL(gui_builder_widget(label)), markup);
|
|
g_free(markup);
|
|
}
|
|
|
|
static inline void __audio_set_time_label(const gchar *label, unsigned int time)
|
|
{
|
|
gchar *str = string_sec2str(time);
|
|
__audio_set_label(label, "large", str);
|
|
g_free(str);
|
|
}
|
|
|
|
static GdkPixbuf *__audio_get_pixbuf(struct track *track)
|
|
{
|
|
gchar *path = album_artwork_path(track->tr_album);
|
|
GdkPixbuf *pix;
|
|
int height;
|
|
|
|
if (!path)
|
|
return NULL;
|
|
|
|
height = gui_builder_widget_height("o_position") +
|
|
gui_builder_widget_height("o_tags");
|
|
pix = gdk_pixbuf_new_from_file_at_scale(path, -1, height, true, NULL);
|
|
g_free(path);
|
|
|
|
return pix;
|
|
}
|
|
|
|
static void __audio_get_cover(struct track *track)
|
|
{
|
|
GtkImage *cover = GTK_IMAGE(gui_builder_widget("o_cover"));
|
|
GdkPixbuf *pix = __audio_get_pixbuf(track);
|
|
|
|
if (pix) {
|
|
gtk_image_set_from_pixbuf(cover, pix);
|
|
g_object_unref(G_OBJECT(pix));
|
|
} else
|
|
gtk_image_set_from_icon_name(cover, "image-missing", GTK_ICON_SIZE_DIALOG);
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(cover), pix != NULL);
|
|
__audio_have_cover = (pix != NULL);
|
|
}
|
|
|
|
void __audio_select_cover(GtkButton *button)
|
|
{
|
|
GtkFileFilter *filter;
|
|
GtkWidget *dialog;
|
|
gchar *path;
|
|
|
|
filter = gtk_file_filter_new();
|
|
dialog = gtk_file_chooser_dialog_new("Choose an image",
|
|
GTK_WINDOW(gui_builder_widget("o_window")),
|
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
|
_("_Open"), GTK_RESPONSE_ACCEPT,
|
|
NULL);
|
|
|
|
gtk_file_filter_add_mime_type(filter, "image/*");
|
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
|
|
gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(dialog), true);
|
|
|
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
album_artwork_import(audio_cur_track()->tr_album, path);
|
|
g_free(path);
|
|
}
|
|
|
|
gtk_widget_destroy(dialog);
|
|
g_object_unref(filter);
|
|
}
|
|
|
|
static void __audio_load(struct track *track)
|
|
{
|
|
__audio_set_label("o_title", "xx-large", track->tr_title);
|
|
__audio_set_label("o_artist", "x-large", track->tr_artist->ar_name);
|
|
__audio_set_label("o_album", "x-large", track->tr_album->al_name);
|
|
__audio_set_time_label("o_duration", track->tr_length);
|
|
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui_builder_widget("o_hide")),
|
|
playlist_has(PL_HIDDEN, track));
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui_builder_widget("o_favorite")),
|
|
playlist_has(PL_FAVORITED, track));
|
|
|
|
gui_view_scroll();
|
|
__audio_get_cover(track);
|
|
}
|
|
|
|
static void __audio_change_state(GstState state)
|
|
{
|
|
if (state == GST_STATE_PLAYING) {
|
|
gtk_widget_hide(gui_builder_widget("o_play"));
|
|
gtk_widget_show(gui_builder_widget("o_pause"));
|
|
} else {
|
|
gtk_widget_show(gui_builder_widget("o_play"));
|
|
gtk_widget_hide(gui_builder_widget("o_pause"));
|
|
}
|
|
}
|
|
|
|
static void __audio_config_pause(int n)
|
|
{
|
|
GtkComboBox *combo = GTK_COMBO_BOX(gui_builder_widget("o_pause_after"));
|
|
gtk_combo_box_set_active(combo, n + 1);
|
|
}
|
|
|
|
void __audio_pause_changed(GtkComboBox *combo, gpointer data)
|
|
{
|
|
int val = gtk_combo_box_get_active(combo) - 1;
|
|
audio_pause_after(val);
|
|
}
|
|
|
|
void __audio_seek(GtkRange *range, GtkScrollType type, double value, gpointer data)
|
|
{
|
|
audio_seek(value * GST_SECOND);
|
|
}
|
|
|
|
void __audio_favorite(GtkToggleButton *toggle, gpointer data)
|
|
{
|
|
if (gtk_toggle_button_get_active(toggle))
|
|
playlist_add(PL_FAVORITED, audio_cur_track());
|
|
else
|
|
playlist_remove(PL_FAVORITED, audio_cur_track());
|
|
}
|
|
|
|
void __audio_hide(GtkToggleButton *toggle, gpointer data)
|
|
{
|
|
if (gtk_toggle_button_get_active(toggle)) {
|
|
if (collection_ban(audio_cur_track()))
|
|
audio_next();
|
|
} else
|
|
collection_unban(audio_cur_track());
|
|
}
|
|
|
|
static int __audio_timeout(gpointer data)
|
|
{
|
|
struct track *track = audio_cur_track();
|
|
GtkAdjustment *progress = data;
|
|
|
|
gtk_adjustment_set_upper(progress, audio_duration() / GST_SECOND);
|
|
gtk_adjustment_set_value(progress, audio_position() / GST_SECOND);
|
|
__audio_set_time_label("o_position", audio_position() / GST_SECOND);
|
|
|
|
if (track && !__audio_have_cover)
|
|
__audio_get_cover(track);
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
}
|
|
|
|
gboolean __audio_can_accel(GtkWidget *widget, guint signal_id)
|
|
{
|
|
GtkWindow *window = GTK_WINDOW(gui_builder_widget("o_window"));
|
|
g_signal_stop_emission_by_name(widget, "can-activate-accel");
|
|
return !GTK_IS_ENTRY(gtk_window_get_focus(window)) &&
|
|
gtk_widget_is_visible(widget) &&
|
|
gtk_widget_is_sensitive(widget);
|
|
}
|
|
|
|
|
|
|
|
struct audio_ops audio_ops = {
|
|
__audio_load,
|
|
__audio_change_state,
|
|
__audio_config_pause,
|
|
};
|
|
|
|
void gui_audio_init()
|
|
{
|
|
g_timeout_add(500, __audio_timeout, gui_builder_object("o_progress"));
|
|
}
|
|
|
|
#ifdef CONFIG_TESTING
|
|
void test_gui_audio_timeout()
|
|
{
|
|
__audio_timeout(gui_builder_object("o_progress"));
|
|
}
|
|
#endif /* CONFIG_TESTING */
|