# HG changeset patch # User William Pitcock # Date 1215294995 18000 # Node ID 5db8a7848565e6da326b8ae6d347c0fda599ec40 # Parent a5707f5711006abd2539edffce6571f07b13d666# Parent cd1e4d4aa0b925bee218d6eaa889a3c871ee1f08 Automated merge with ssh://hg.atheme.org//hg/audacious diff -r cd1e4d4aa0b9 -r 5db8a7848565 src/audacious/ui_new.c --- a/src/audacious/ui_new.c Sat Jul 05 16:55:24 2008 -0500 +++ b/src/audacious/ui_new.c Sat Jul 05 16:56:35 2008 -0500 @@ -27,6 +27,11 @@ #include "ui_new.h" static GtkWidget *label_prev, *label_current, *label_next; +static GtkWidget *slider; + +static gulong slider_change_handler_id; +static gboolean slider_is_moving = FALSE; +static gint update_song_timeout_source = 0; static gboolean window_delete() @@ -62,6 +67,12 @@ } static void +button_pause_pressed() +{ + playback_pause(); +} + +static void button_previous_pressed() { playlist_prev(playlist_get_active()); @@ -74,16 +85,91 @@ } static void -set_song_title(gpointer hook_data, gpointer user_data) +ui_set_current_song_title(gchar *text, gpointer user_data) { - gchar *title = - g_strdup_printf("%s", - playlist_get_info_text(playlist_get_active())); + gchar *title = g_strdup_printf("%s", text); gtk_label_set_text(GTK_LABEL(label_current), title); g_object_set(G_OBJECT(label_current), "use-markup", TRUE, NULL); g_free(title); } +static void +ui_playlist_update(Playlist *playlist, gpointer user_data) +{ + gchar *text = playlist_get_info_text(playlist); + ui_set_current_song_title(text, NULL); + g_free(text); +} + +static gboolean +ui_update_song_info(gpointer hook_data, gpointer user_data) +{ + if (!playback_get_playing()) + { + gtk_range_set_value(GTK_RANGE(slider), (gdouble)0); + return FALSE; + } + + if (slider_is_moving) + return TRUE; + + gint time = playback_get_time(); + gint length = playback_get_length(); + + g_signal_handler_block(slider, slider_change_handler_id); + gtk_range_set_range(GTK_RANGE(slider), 0.0, (gdouble)length); + gtk_range_set_value(GTK_RANGE(slider), (gdouble)time); + g_signal_handler_unblock(slider, slider_change_handler_id); + + return TRUE; +} + +static gboolean +ui_slider_value_changed_cb(GtkRange *range, gpointer user_data) +{ + /* we are not allowed to do a playback_seek() with values < 1, therefore + * we add 1 to be on the safe side --mf0102 */ + playback_seek(gtk_range_get_value(range)/1000 + 1); + + return TRUE; +} + +static gboolean +ui_slider_button_press_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) +{ + slider_is_moving = TRUE; + return FALSE; +} + +static gboolean +ui_slider_button_release_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) +{ + slider_is_moving = FALSE; + return FALSE; +} + +static void +ui_playback_begin(gpointer hook_data, gpointer user_data) +{ + ui_update_song_info(NULL, NULL); + update_song_timeout_source = + g_timeout_add_seconds(1, (GSourceFunc) ui_update_song_info, NULL); +} + +static void +ui_playback_stop(gpointer hook_data, gpointer user_data) +{ + if (update_song_timeout_source) { + g_source_remove(update_song_timeout_source); + update_song_timeout_source = 0; + } +} + +static void +ui_playback_end(gpointer hook_data, gpointer user_data) +{ + ui_update_song_info(NULL, NULL); +} static GtkToolItem * gtk_toolbar_button_add(GtkWidget *toolbar, void(*callback)(), const gchar *stock_id) @@ -118,10 +204,11 @@ and some control elements like position bar */ GtkToolItem *button_open, *button_add, - *button_play, *button_previous, *button_next; - + *button_play, *button_pause, + *button_previous, *button_next; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(window), 450, 150); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(window_delete), NULL); g_signal_connect(G_OBJECT(window), "destroy", @@ -134,15 +221,17 @@ buttonbox = gtk_toolbar_new(); button_open = gtk_toolbar_button_add(buttonbox, button_open_pressed, - GTK_STOCK_OPEN); + GTK_STOCK_OPEN); button_add = gtk_toolbar_button_add(buttonbox, button_add_pressed, - GTK_STOCK_ADD); + GTK_STOCK_ADD); button_play = gtk_toolbar_button_add(buttonbox, button_play_pressed, GTK_STOCK_MEDIA_PLAY); + button_pause = gtk_toolbar_button_add(buttonbox, button_pause_pressed, + GTK_STOCK_MEDIA_PAUSE); button_previous = gtk_toolbar_button_add(buttonbox, button_previous_pressed, - GTK_STOCK_MEDIA_PREVIOUS); + GTK_STOCK_MEDIA_PREVIOUS); button_next = gtk_toolbar_button_add(buttonbox, button_next_pressed, - GTK_STOCK_MEDIA_NEXT); + GTK_STOCK_MEDIA_NEXT); gtk_box_pack_start(GTK_BOX(vbox), buttonbox, FALSE, TRUE, 0); @@ -151,18 +240,43 @@ chbox = gtk_hbox_new(FALSE, 0); cvbox = gtk_vbox_new(FALSE, 0); label_current = gtk_markup_label_new("Current: ?"); + gtk_misc_set_alignment(GTK_MISC(label_current), 0.0, 0.5); gtk_box_pack_start(GTK_BOX(cvbox), label_current, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(chbox), cvbox, TRUE, TRUE, 0); label_prev = gtk_markup_label_new("Previous: ?"); label_next = gtk_markup_label_new("Next: ?"); + gtk_misc_set_alignment(GTK_MISC(label_prev), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(label_next), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(pcnbox), label_prev, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(pcnbox), chbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(pcnbox), label_next, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), pcnbox, TRUE, TRUE, 0); - hook_associate("title change", set_song_title, NULL); + slider = gtk_hscale_new(NULL); + gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE); + /* TODO: make this configureable */ + gtk_range_set_update_policy(GTK_RANGE(slider), GTK_UPDATE_DELAYED); + gtk_box_pack_end(GTK_BOX(cvbox), slider, TRUE, TRUE, 0); + + hook_associate("title change", (HookFunction) ui_set_current_song_title, NULL); + hook_associate("playback seek", (HookFunction) ui_update_song_info, NULL); + hook_associate("playback begin", (HookFunction) ui_playback_begin, NULL); + hook_associate("playback stop", (HookFunction) ui_playback_stop, NULL); + hook_associate("playback end", (HookFunction) ui_playback_end, NULL); + hook_associate("playlist update", (HookFunction) ui_playlist_update, NULL); + + slider_change_handler_id = + g_signal_connect(slider, "value-changed", + G_CALLBACK(ui_slider_value_changed_cb), NULL); + + g_signal_connect(slider, "button-press-event", + G_CALLBACK(ui_slider_button_press_cb), NULL); + g_signal_connect(slider, "button-release-event", + G_CALLBACK(ui_slider_button_release_cb), NULL); + + ui_playlist_update(playlist_get_active(), NULL); gtk_widget_show_all(window); gtk_main(); @@ -170,10 +284,24 @@ return TRUE; } +static gboolean +_ui_finalize(void) +{ + hook_dissociate("title change", (HookFunction) ui_set_current_song_title); + hook_dissociate("playback seek", (HookFunction) ui_update_song_info); + hook_dissociate("playback begin", (HookFunction) ui_playback_begin); + hook_dissociate("playback stop", (HookFunction) ui_playback_stop); + hook_dissociate("playback end", (HookFunction) ui_playback_end); + hook_dissociate("playlist update", (HookFunction) ui_playlist_update); + + return TRUE; +} + static Interface default_interface = { .id = "default", .desc = N_("Default Interface"), .init = _ui_initialize, + .fini = _ui_finalize, }; Interface *