206 lines
5.3 KiB
C
206 lines
5.3 KiB
C
/*
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/string.h>
|
|
#include <gui/artwork.h>
|
|
#include <gui/audio.h>
|
|
#include <gui/idle.h>
|
|
#include <gui/playlist.h>
|
|
#include <gui/treeview.h>
|
|
#include <gui/window.h>
|
|
|
|
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 = "<span size='%s'>%s</span>";
|
|
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;
|
|
}
|