/* * Copyright 2014 (c) Anna Schumaker. */ #include #include #include #include #include #include #include static guint audio_timeout = 0; static guint popover_timeout = 0; static inline void __gui_audio_set_label_markup(GtkLabel *label, const gchar *size, const gchar *text) { const gchar *fmt = "%s"; gchar *markup = g_markup_printf_escaped(fmt, size, text); gtk_label_set_markup(label, markup); g_free(markup); } static void __gui_audio_load(struct track *track) { gchar *duration = string_sec2str(track->tr_length); __gui_audio_set_label_markup(gui_title_tag(), "xx-large", track->tr_title); __gui_audio_set_label_markup(gui_album_tag(), "x-large", track->tr_album->al_name); __gui_audio_set_label_markup(gui_artist_tag(), "x-large", track->tr_album->al_artist->ar_name); __gui_audio_set_label_markup(gui_duration(), "large", duration); __gui_audio_set_label_markup(gui_position(), "large", "0:00"); gtk_adjustment_set_upper(gui_seek(), track->tr_length); gui_pl_system_track_loaded(track); gui_treeview_scroll(); gui_artwork_set_cover(); gui_idle_enable(); g_free(duration); } static void __gui_audio_set_pause_text(int n, GstState state) { bool sensitive = true; gchar *text; if (n == -1) { sensitive = false; if (state == GST_STATE_PLAYING) text = g_strdup("Keep playing"); else text = g_strdup("Paused"); } else if (n == 0) text = g_strdup("Pause after this track"); else if (n == 1) text = g_strdup("Pause after next track"); else text = g_strdup_printf("Pause after %d tracks", n); gtk_widget_set_sensitive(GTK_WIDGET(gui_pause_down()), sensitive); gtk_entry_set_text(gui_pause_entry(), text); g_free(text); } static void __gui_audio_change_state(GstState state) { bool playing = (state == GST_STATE_PLAYING); gtk_widget_set_visible(GTK_WIDGET(gui_play_button()), !playing); gtk_widget_set_visible(GTK_WIDGET(gui_pause_button()), playing); __gui_audio_set_pause_text(audio_get_pause_count(), state); } static void __gui_audio_config_pause(int n) { __gui_audio_set_pause_text(n, audio_cur_state()); } struct audio_callbacks audio_cb = { .audio_cb_load = __gui_audio_load, .audio_cb_state_change = __gui_audio_change_state, .audio_cb_config_pause = __gui_audio_config_pause, }; void __gui_audio_pause(GtkButton *button, gpointer data) { audio_pause(); if (audio_get_pause_count() > -1) { gtk_popover_popup(gui_pause_popover()); popover_timeout = g_timeout_add_seconds(10, gui_audio_popover_timeout, NULL); } } void __gui_audio_pause_change_text(GtkEntry *entry, gpointer data) { const gchar *text = gtk_entry_get_text(entry); int n = audio_get_pause_count(); unsigned int i; if (g_str_match_string("Keep", text, true)) n = -1; else if (g_str_match_string("This", text, true)) n = 0; else if (g_str_match_string("Next", text, true)) n = 1; else { for (i = 0; text[i] != '\0'; i++) { if (!g_ascii_isdigit(text[i])) continue; if (i > 0 && text[i-1] == '-') i -= 1; n = g_strtod(text + i, NULL); break; } } if (!audio_pause_after(n)) __gui_audio_set_pause_text(audio_get_pause_count(), audio_cur_state()); } void __gui_audio_pause_inc(GtkButton *button, gpointer data) { audio_pause_after(audio_get_pause_count() + 1); } void __gui_audio_pause_dec(GtkButton *button, gpointer data) { audio_pause_after(audio_get_pause_count() - 1); } void __gui_audio_pause_popover_popdown(GtkButton *button, gpointer data) { gtk_popover_popdown(gui_pause_popover()); #ifdef CONFIG_TESTING gtk_widget_hide(GTK_WIDGET(gui_pause_popover())); #endif /* CONFIG_TESTING */ g_source_remove(popover_timeout); popover_timeout = 0; } void __gui_audio_pause_popover_clear(GtkButton *button, gpointer data) { audio_pause_after(-1); __gui_audio_pause_popover_popdown(button, data); } void __gui_audio_seek(GtkRange *range, GtkScrollType type, double value, gpointer data) { audio_seek(value * GST_SECOND); } void __gui_audio_volume_changed(GtkScaleButton *button, gdouble value, gpointer data) { audio_set_volume((unsigned int)value); } gboolean __gui_audio_can_accel(GtkWidget *widget, guint signal_id) { g_signal_stop_emission_by_name(widget, "can-activate-accel"); return !GTK_IS_ENTRY(gtk_window_get_focus(gui_window())) && gtk_widget_is_visible(widget) && gtk_widget_is_sensitive(widget); } void gui_audio_init() { gtk_scale_button_set_value(gui_volume_button(), audio_get_volume()); gtk_button_set_relief(GTK_BUTTON(gui_volume_button()), GTK_RELIEF_NORMAL); audio_timeout = g_timeout_add(500, gui_audio_timeout, NULL); } void gui_audio_deinit() { g_source_remove(audio_timeout); if (popover_timeout > 0) g_source_remove(popover_timeout); } int gui_audio_timeout(gpointer data) { gchar *position = string_sec2str(audio_position() / GST_SECOND); gtk_adjustment_set_upper(gui_seek(), audio_duration() / GST_SECOND); gtk_adjustment_set_value(gui_seek(), audio_position() / GST_SECOND); __gui_audio_set_label_markup(gui_position(), "large", position); g_free(position); return G_SOURCE_CONTINUE; } int gui_audio_popover_timeout(gpointer data) { __gui_audio_pause_popover_popdown(NULL, data); return G_SOURCE_REMOVE; }