/* * Copyright 2014 (c) Anna Schumaker. */ #include #include #include #include #include #include #include #include #include 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("%s", 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 */