/* vim: set ai et ts=4 sw=4: */ #ifdef HAVE_CONFIG_H #include #endif #include #include "liteamp.h" #include "util.h" #include "about.h" #include "tag.h" #include "uiinfo.h" #include "callbacks.h" /*-----------------------------------------------------------------*/ /** global application object */ Liteamp liteamp; /*-----------------------------------------------------------------*/ // // prototypes // static gboolean app_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer data); static gboolean app_delete_event_cb(GtkWidget* widget, GdkEvent* event, gpointer data); static void vol_eb_button_press_event_cb(GtkWidget* eventbox, GdkEventButton* event, gpointer data); static void vol_hs_adjust_bounds_cb(GtkRange* range, gpointer data); static gboolean vol_hs_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data); static gboolean vol_hs_button_release_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data); static gchar* pos_hs_format_value_cb(GtkScale* scale, gdouble value); static void pos_hs_adjust_bounds_cb(GtkRange* range, gpointer data); static gboolean pos_hs_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data); static gboolean pos_hs_button_release_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data); static gboolean pos_hs_mouse_scroll_event_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data); /*-----------------------------------------------------------------*/ void liteamp_init(GnomeProgram* program) { GtkStyle* style; g_print("INIT\n"); // initialize global objects memset(&liteamp, 0, sizeof(liteamp)); liteamp.program = program; // read prefs prefs_read(); //@@backport tag_init(); // mixer liteamp.mixer = mixer_new(); // initialize decoder decoder_init(); liteamp.update_vol_flag= FALSE; liteamp.update_pos_flag= FALSE; // create app widget liteamp.app = gnome_app_new(PACKAGE, _("liteamp")); // set application icon gnome_window_icon_set_from_file(GTK_WINDOW(liteamp.app), find_pixmap_file("liteamp.png")); // restore geometry if available if(prefs.geometry_x >= 0 && prefs.geometry_y >= 0) { gtk_window_move(liteamp_get_app_window(), prefs.geometry_x, prefs.geometry_y); } if(prefs.geometry_width >= 0 && prefs.geometry_height >= 0) { gtk_window_resize(liteamp_get_app_window(), prefs.geometry_width, prefs.geometry_height); } else { gtk_widget_set_size_request(liteamp.app, 400, 300); } // menu gnome_app_create_menus( GNOME_APP(liteamp.app), menubar_uiinfo); // toolbar gnome_app_create_toolbar( GNOME_APP(liteamp.app), toolbar_uiinfo); liteamp.toolbar = bonobo_dock_item_get_child( gnome_app_get_dock_item_by_name(GNOME_APP(liteamp.app), GNOME_APP_TOOLBAR_NAME)); // volume control on toolbar liteamp.vol_img = create_pixmap("vol.png"); liteamp.vol_eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(liteamp.vol_eb), liteamp.vol_img); liteamp.vol_hs = gtk_hscale_new_with_range( liteamp.mixer->vol_min, liteamp.mixer->vol_max, liteamp.mixer->vol_step); gtk_range_set_value(GTK_RANGE(liteamp.vol_hs), mixer_get_volume(liteamp.mixer)); gtk_scale_set_draw_value(GTK_SCALE(liteamp.vol_hs), FALSE); gtk_scale_set_digits(GTK_SCALE(liteamp.vol_hs), 0); gtk_widget_set_size_request(liteamp.vol_hs, 128, -1); g_signal_connect( G_OBJECT(liteamp.vol_hs), "adjust-bounds", G_CALLBACK(vol_hs_adjust_bounds_cb), NULL); g_signal_connect( G_OBJECT(liteamp.vol_hs), "button-press-event", G_CALLBACK(vol_hs_button_press_event_cb), NULL); g_signal_connect( G_OBJECT(liteamp.vol_hs), "button-release-event", G_CALLBACK(vol_hs_button_release_event_cb), NULL); liteamp.vol_hb = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(liteamp.vol_hb), liteamp.vol_eb, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(liteamp.vol_hb), liteamp.vol_hs, TRUE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(liteamp.vol_hb)); g_signal_connect( G_OBJECT(liteamp.vol_eb), "button-press-event", G_CALLBACK(vol_eb_button_press_event_cb), NULL); gtk_toolbar_append_space(GTK_TOOLBAR(liteamp.toolbar)); gtk_toolbar_append_widget( GTK_TOOLBAR(liteamp.toolbar), liteamp.vol_hb, NULL, NULL); // set toolbar style // FIXME: // how can i give priority to the specific buttons, // and use gnome default settings? gtk_toolbar_set_style(GTK_TOOLBAR(liteamp.toolbar), GTK_TOOLBAR_ICONS); // statusbar liteamp.statusbar = gnome_appbar_new( FALSE, TRUE, GNOME_PREFERENCES_NEVER); gnome_app_set_statusbar( GNOME_APP(liteamp.app), liteamp.statusbar); // menu hints gnome_app_install_menu_hints( GNOME_APP(liteamp.app), menubar_uiinfo); // playing info liteamp.info_lbl = gtk_label_new(NULL); gtk_label_set_justify( GTK_LABEL(liteamp.info_lbl), GTK_JUSTIFY_CENTER); gtk_label_set_line_wrap(GTK_LABEL(liteamp.info_lbl), TRUE); liteamp.info_eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(liteamp.info_eb), liteamp.info_lbl); liteamp.play_info = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(liteamp.play_info), liteamp.info_eb, TRUE, TRUE, 3); // playing position control liteamp.pos_hs = gtk_hscale_new_with_range(0, 1, 1); gtk_range_set_update_policy(GTK_RANGE(liteamp.pos_hs), GTK_UPDATE_DISCONTINUOUS); gtk_range_set_value(GTK_RANGE(liteamp.pos_hs), 0); gtk_scale_set_draw_value(GTK_SCALE(liteamp.pos_hs), TRUE); gtk_scale_set_value_pos(GTK_SCALE(liteamp.pos_hs), GTK_POS_RIGHT); gtk_scale_set_digits(GTK_SCALE(liteamp.pos_hs), 0); g_signal_connect( G_OBJECT(liteamp.pos_hs), "format-value", G_CALLBACK(pos_hs_format_value_cb), NULL); g_signal_connect( G_OBJECT(liteamp.pos_hs), "adjust-bounds", G_CALLBACK(pos_hs_adjust_bounds_cb), NULL); g_signal_connect( G_OBJECT(liteamp.pos_hs), "button-press-event", G_CALLBACK(pos_hs_button_press_event_cb), NULL); g_signal_connect( G_OBJECT(liteamp.pos_hs), "button-release-event", G_CALLBACK(pos_hs_button_release_event_cb), NULL); g_signal_connect( G_OBJECT(liteamp.pos_hs), "scroll_event", G_CALLBACK(pos_hs_mouse_scroll_event_cb), NULL); liteamp.play_pos = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(liteamp.play_pos), liteamp.pos_hs, TRUE, TRUE, 3); // sidebar liteamp.sidebar_sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(liteamp.sidebar_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); liteamp.sidebar_vp = gtk_viewport_new(NULL, NULL); style = gtk_widget_get_default_style(); gtk_widget_modify_bg(liteamp.sidebar_vp, GTK_STATE_NORMAL, &(style->bg[GTK_STATE_ACTIVE])); liteamp.sidebar = SIDEBAR(sidebar_new()); gtk_container_add( GTK_CONTAINER(liteamp.sidebar_vp), GTK_WIDGET(liteamp.sidebar)); gtk_container_add( GTK_CONTAINER(liteamp.sidebar_sw), liteamp.sidebar_vp); liteamp.sidebar_popup_menu = gnome_popup_menu_new(sidebar_popup_uiinfo); gnome_popup_menu_attach(liteamp.sidebar_popup_menu, liteamp.sidebar_vp, NULL); // playlist liteamp.playlist = PLAYLIST(playlist_new()); liteamp.playlist_sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(liteamp.playlist_sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(liteamp.playlist_sw), GTK_WIDGET(liteamp.playlist)); liteamp.playlist_popup_menu = gnome_popup_menu_new(playlist_popup_uiinfo); gnome_popup_menu_attach(liteamp.playlist_popup_menu, liteamp.info_eb, NULL); gnome_popup_menu_attach(liteamp.playlist_popup_menu, GTK_WIDGET(liteamp.playlist), NULL); // right vbox liteamp.right_vb = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(liteamp.right_vb), liteamp.play_info, FALSE, FALSE, 2); gtk_box_pack_start(GTK_BOX(liteamp.right_vb), liteamp.play_pos, FALSE, FALSE, 2); gtk_box_pack_start(GTK_BOX(liteamp.right_vb), liteamp.playlist_sw, TRUE, TRUE, 0); // contents hpane for sidebar with others liteamp.contents_hp = gtk_hpaned_new(); if(prefs.divider_position >= 0) { gtk_paned_set_position(GTK_PANED(liteamp.contents_hp), prefs.divider_position); } else { gtk_paned_set_position(GTK_PANED(liteamp.contents_hp), 100); } gtk_paned_pack1( GTK_PANED(liteamp.contents_hp), liteamp.sidebar_sw, FALSE, TRUE); gtk_paned_pack2( GTK_PANED(liteamp.contents_hp), liteamp.right_vb, TRUE, TRUE); gnome_app_set_contents(GNOME_APP(liteamp.app), liteamp.contents_hp); // signal handler g_signal_connect( G_OBJECT(liteamp.app), "key_press_event", G_CALLBACK(app_key_press_event_cb), NULL); g_signal_connect( GTK_OBJECT(liteamp.app), "delete-event", G_CALLBACK(app_delete_event_cb), NULL); } void liteamp_main() { g_print("MAIN\n"); liteamp_read_tracks(SIDEBAR_ITEM(liteamp.sidebar->items->data)); // TODO: auto load last playlist! //playlist_set_filename(liteamp.playlist, prefs.last_playlist); // init widget status // by preferences // init volume status liteamp_update_ui_volume(); // init menu status liteamp_update_ui_menu(); // init status bar text liteamp_update_ui_status(); // initialize info panel and position control // set player controls to stopped status liteamp_update_ui_play_info(NULL); liteamp_update_ui_play_status(); // TODO: auto start last played file. gtk_widget_show_all(GTK_WIDGET(liteamp.app)); // restore layout // this function must called after gtk_widget_show_all() liteamp_update_ui_layout(); // main event loop gtk_main(); } void liteamp_quit() { g_print("QUIT\n"); decoder_quit(); mixer_free(liteamp.mixer); prefs_write(); } /*-----------------------------------------------------------------*/ // // getters / setters // GtkWindow* liteamp_get_app_window(void) { return GTK_WINDOW(liteamp.app); } Sidebar* liteamp_get_sidebar(void) { return SIDEBAR(liteamp.sidebar); } Playlist* liteamp_get_playlist(void) { return PLAYLIST(liteamp.playlist); } /*-----------------------------------------------------------------*/ #if 0 void liteamp_read_tracks_all(void) { GList* list; SidebarItem* item; gchar* filename; gboolean parse_tag; // disable tag parsing in temporary parse_tag = prefs.parse_tag; prefs.parse_tag = prefs.parse_tag_all; // make empty playlist_set_filename(liteamp.playlist, NULL); // read 'all' playlist file list = liteamp.sidebar->items; while(list && list->data) { item = list->data; g_assert(SIDEBAR_ITEM(list->data)); filename = utf8_to_filename(item->filename); liteamp.playlist->filename = filename; playlist_read(liteamp.playlist); g_free(filename); list = g_list_next(list); } liteamp.playlist->filename = NULL; // restore tag parse options prefs.parse_tag = parse_tag; } #endif void liteamp_read_tracks(SidebarItem* item) { gchar* filename; // read a playlist file filename = utf8_to_filename(item->filename); playlist_set_filename(liteamp.playlist, filename); g_free(filename); liteamp_update_ui_menu(); liteamp_update_ui_status(); } /*-----------------------------------------------------------------*/ // // ui updates methods // generally, these functions called by callbacks only // void liteamp_update_ui_play_pos(void) { GtkRange* range; static gint prev_time = 0; gint cur_time; cur_time = decoder_get_cur_time(); // get_cur_time fail if ( cur_time == -1 ) return; // don't update ui if cur_time equal prev_time if(cur_time == prev_time) return; // don't update ui while dragging if(liteamp.update_pos_flag) return; range = GTK_RANGE(liteamp.pos_hs); if(g_mutex_trylock(gdk_threads_mutex)){ gtk_range_set_value(range, cur_time); g_mutex_unlock(gdk_threads_mutex); prev_time = cur_time; } } void liteamp_update_ui_play_status() { // FIXME: // each status has several widget related to itself // so, we'll change all widget within a time. // these are somewhat bogus methods, I think :-( GtkWidget* toolbar_start = get_toolbar_widget(TOOLBAR_START); GtkWidget* menu_play_start = get_play_menu_widget(MENU_PLAY_START); GtkWidget* popup_playlist_start = get_playlist_popup_widget(PLAYLIST_POPUP_START); GtkWidget* toolbar_pause = get_toolbar_widget(TOOLBAR_PAUSE); GtkWidget* menu_play_pause = get_play_menu_widget(MENU_PLAY_PAUSE); GtkWidget* popup_playlist_pause = get_playlist_popup_widget(PLAYLIST_POPUP_PAUSE); GtkWidget* toolbar_stop = get_toolbar_widget(TOOLBAR_STOP); GtkWidget* menu_play_stop = get_play_menu_widget(MENU_PLAY_STOP); GtkWidget* popup_playlist_stop = get_playlist_popup_widget(PLAYLIST_POPUP_STOP); gboolean paused; if(liteamp.play_status == PLAY_STATUS_STOP) { // show start gtk_widget_show(toolbar_start); gtk_widget_show(menu_play_start); gtk_widget_show(popup_playlist_start); // hide stop gtk_widget_hide(toolbar_stop); gtk_widget_hide(menu_play_stop); gtk_widget_hide(popup_playlist_stop); // on / off pause gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_pause), FALSE); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_play_pause), FALSE); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(popup_playlist_pause), FALSE); // disable pause gtk_widget_set_sensitive(toolbar_pause, FALSE); gtk_widget_set_sensitive(menu_play_pause, FALSE); gtk_widget_set_sensitive(popup_playlist_pause, FALSE); } else { // hide play gtk_widget_hide(toolbar_start); gtk_widget_hide(menu_play_start); gtk_widget_hide(popup_playlist_start); // show stop gtk_widget_show(toolbar_stop); gtk_widget_show(menu_play_stop); gtk_widget_show(popup_playlist_stop); paused = (liteamp.play_status == PLAY_STATUS_PAUSE); // on / off pause gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_pause), paused); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_play_pause), paused); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(popup_playlist_pause), paused); // enable pause gtk_widget_set_sensitive(toolbar_pause, TRUE); gtk_widget_set_sensitive(menu_play_pause, TRUE); gtk_widget_set_sensitive(popup_playlist_pause, TRUE); } } void liteamp_update_ui_play_info(const gchar* filename) { Tag* tag; gchar* info_str; gchar* title_str; gchar* album_str; gchar* artist_str; gchar* temp_str; if(filename && g_file_test(filename, G_FILE_TEST_EXISTS)) { tag = tag_new_from_file(filename); title_str = escape_str(tag->title); g_assert(title_str); if(tag->album != NULL && tag->artist != NULL) { album_str = escape_str(tag->album); artist_str = escape_str(tag->artist); g_assert(album_str); g_assert(artist_str); info_str = g_strdup_printf( _("%s\nFrom %s by %s"), title_str, album_str, artist_str); g_free(album_str); g_free(artist_str); } else { info_str = g_strdup_printf( _("%s"), title_str); } g_free(title_str); gtk_range_set_value(GTK_RANGE(liteamp.pos_hs), 0); gtk_range_set_range(GTK_RANGE(liteamp.pos_hs), 0, tag->seconds); gtk_widget_set_sensitive(liteamp.pos_hs, TRUE); gtk_widget_show(liteamp.pos_hs); tag_free(tag); liteamp.play_status = PLAY_STATUS_PLAY; } else { //gtk_widget_set_sensitive(liteamp.pos_hs, FALSE); gtk_widget_hide(liteamp.pos_hs); info_str = g_strdup( _("Not Playing")); liteamp.play_status = PLAY_STATUS_STOP; } gtk_label_set_markup(GTK_LABEL(liteamp.info_lbl), info_str); g_free(info_str); liteamp_update_ui_play_status(); } void liteamp_update_ui_play_shuffle(void) { GtkWidget* toolbar_shuffle = get_toolbar_widget(TOOLBAR_SHUFFLE); GtkWidget* menu_play_shuffle = get_play_menu_widget(MENU_PLAY_SHUFFLE); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_play_shuffle), prefs.play_shuffle); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_shuffle), prefs.play_shuffle); } void liteamp_update_ui_play_loop(void) { GtkWidget* toolbar_loop = get_toolbar_widget(TOOLBAR_LOOP); GtkWidget* menu_play_loop = get_play_menu_widget(MENU_PLAY_LOOP); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_play_loop), prefs.play_loop); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_loop), prefs.play_loop); } void liteamp_update_ui_play_mute(void) { GdkPixbuf* pixbuf; if(prefs.play_mute) { pixbuf = create_pixbuf("vol_mute.png"); gtk_widget_hide(liteamp.vol_hs); } else { pixbuf = create_pixbuf("vol.png"); gtk_widget_show(liteamp.vol_hs); } gtk_image_set_from_pixbuf(GTK_IMAGE(liteamp.vol_img), pixbuf); mixer_set_mute(liteamp.mixer, prefs.play_mute); } void liteamp_update_ui_play_effect(void) { } void liteamp_update_ui_layout(void) { if(prefs.view_toolbar) gtk_widget_show(gtk_widget_get_parent(liteamp.toolbar)); else gtk_widget_hide(gtk_widget_get_parent(liteamp.toolbar)); if(prefs.view_statusbar) gtk_widget_show(gtk_widget_get_parent(liteamp.statusbar)); else gtk_widget_hide(gtk_widget_get_parent(liteamp.statusbar)); if(prefs.view_sidebar) gtk_widget_show(GTK_WIDGET(liteamp.sidebar_sw)); else gtk_widget_hide(GTK_WIDGET(liteamp.sidebar_sw)); if(prefs.view_play_info) gtk_widget_show(liteamp.play_info); else gtk_widget_hide(liteamp.play_info); if(prefs.view_play_pos) gtk_widget_show(liteamp.play_pos); else gtk_widget_hide(liteamp.play_pos); } void liteamp_update_ui_volume(void) { GtkRange* range; // don't update ui while dragging if(liteamp.update_vol_flag) return; range = GTK_RANGE(liteamp.vol_hs); gtk_range_set_value(range, mixer_get_volume(liteamp.mixer)); } void liteamp_update_ui_menu(void) { gboolean readonly, empty; readonly = FALSE;//@@sidebar_item_is_stock(sidebar_get_active_item(liteamp_get_sidebar())); empty = playlist_clipboard_is_empty(liteamp_get_playlist()); // enable/disable menu items gtk_widget_set_sensitive(get_file_menu_widget(MENU_FILE_ADD_DIR), !readonly); gtk_widget_set_sensitive(get_file_menu_widget(MENU_FILE_ADD_FILE), !readonly); gtk_widget_set_sensitive(get_file_menu_widget(MENU_FILE_REMOVE_PLAYLIST), !readonly); gtk_widget_set_sensitive(get_edit_menu_widget(MENU_EDIT_CUT), !readonly); gtk_widget_set_sensitive(get_edit_menu_widget(MENU_EDIT_CLEAR), !readonly); gtk_widget_set_sensitive(get_edit_menu_widget(MENU_EDIT_PASTE), !readonly && !empty); gtk_widget_set_sensitive(get_sidebar_popup_widget(SIDEBAR_POPUP_ADD_DIR), !readonly); gtk_widget_set_sensitive(get_sidebar_popup_widget(SIDEBAR_POPUP_ADD_FILE), !readonly); gtk_widget_set_sensitive(get_sidebar_popup_widget(SIDEBAR_POPUP_REMOVE_PLAYLIST), !readonly); gtk_widget_set_sensitive(get_playlist_popup_widget(PLAYLIST_POPUP_CUT), !readonly); gtk_widget_set_sensitive(get_playlist_popup_widget(PLAYLIST_POPUP_CLEAR), !readonly); gtk_widget_set_sensitive(get_playlist_popup_widget(PLAYLIST_POPUP_PASTE), !readonly && !empty); // (de)activate menu items gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_play_menu_widget(MENU_PLAY_SHUFFLE)), prefs.play_shuffle); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_play_menu_widget(MENU_PLAY_LOOP)), prefs.play_loop); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_play_menu_widget(MENU_PLAY_MUTE)), prefs.play_mute); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_play_menu_widget(MENU_PLAY_EFFECT)), prefs.play_effect); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_view_menu_widget(MENU_VIEW_TOOLBAR)), prefs.view_toolbar); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_view_menu_widget(MENU_VIEW_STATUSBAR)), prefs.view_statusbar); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_view_menu_widget(MENU_VIEW_SIDEBAR)), prefs.view_sidebar); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_view_menu_widget(MENU_VIEW_PLAY_INFO)), prefs.view_play_info); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_view_menu_widget(MENU_VIEW_PLAY_POS)), prefs.view_play_pos); // (de)activate toolbar buttons gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(get_toolbar_widget(TOOLBAR_SHUFFLE)), prefs.play_shuffle); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(get_toolbar_widget(TOOLBAR_LOOP)), prefs.play_loop); } void liteamp_update_ui_status(void) { gnome_appbar_set_status( GNOME_APPBAR(liteamp.statusbar), playlist_get_status_text(liteamp.playlist)); } /*-----------------------------------------------------------------*/ // // callbacks // /** destory application window */ static gboolean app_delete_event_cb( GtkWidget* widget, GdkEvent* event, gpointer data) { gint x, y, width, height; // save geometry if needed if(prefs.save_geometry) { gtk_window_get_position(liteamp_get_app_window(), &x, &y); gtk_window_get_size(liteamp_get_app_window(), &width, &height); prefs.geometry_x = x; prefs.geometry_y = y; prefs.geometry_width = width; prefs.geometry_height = height; prefs.divider_position = gtk_paned_get_position(GTK_PANED(liteamp.contents_hp)); } gtk_widget_destroy(liteamp.app); gtk_main_quit();//gtk_exit(0); return FALSE; } /** Right,Left Key press event */ static gboolean app_key_press_event_cb( GtkWidget *widget, GdkEventKey *event, gpointer data) { gboolean retval = TRUE; gint curtime = decoder_get_cur_time(); if(curtime == -1) return FALSE; switch(event->keyval){ case GDK_Right: decoder_seek(SEEK_OFFSET+curtime); break; case GDK_Left: decoder_seek(-SEEK_OFFSET+curtime); break; default: retval = FALSE; } return retval; } /** toggle mute with button on toolbar */ static void vol_eb_button_press_event_cb( GtkWidget* eventbox, GdkEventButton* event, gpointer data) { gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(get_play_menu_widget(MENU_PLAY_MUTE)), !prefs.play_mute); } /** * sync mixer volume to ui */ static void vol_hs_adjust_bounds_cb( GtkRange* range, gpointer data) { if(liteamp.update_vol_flag) return; mixer_set_volume(liteamp.mixer, gtk_range_get_value(range)); } static gboolean vol_hs_button_press_event_cb( GtkWidget *widget, GdkEventButton *event, gpointer data) { liteamp.update_vol_flag = TRUE; return FALSE; } static gboolean vol_hs_button_release_event_cb( GtkWidget *widget, GdkEventButton *event, gpointer data) { liteamp.update_vol_flag = FALSE; return FALSE; } /** * get an format value for position control */ static gchar* pos_hs_format_value_cb(GtkScale* scale, gdouble value) { gchar time_str[20]; format_time_str(time_str, sizeof(time_str), (gulong)value); return g_strdup(time_str); } /** * sync decoder position with position ui */ static void pos_hs_adjust_bounds_cb( GtkRange* range, gpointer data) { GtkAdjustment* adjustment; if(liteamp.update_pos_flag) return; adjustment = gtk_range_get_adjustment(range); decoder_seek((gint)adjustment->value); } static gboolean pos_hs_button_press_event_cb( GtkWidget *widget, GdkEventButton *event, gpointer data) { liteamp.update_pos_flag = TRUE; return FALSE; } static gboolean pos_hs_button_release_event_cb( GtkWidget *widget, GdkEventButton *event, gpointer data) { liteamp.update_pos_flag = FALSE; return FALSE; } static gboolean pos_hs_mouse_scroll_event_cb( GtkWidget *widget, GdkEventScroll *event, gpointer data) { gboolean retval = TRUE; gint curtime = decoder_get_cur_time(); if(curtime == -1) return FALSE; switch (event->direction) { case GDK_SCROLL_UP: decoder_seek(SEEK_OFFSET+curtime); break; case GDK_SCROLL_DOWN: decoder_seek(-SEEK_OFFSET+curtime); break; default: retval = FALSE; } return retval; } /*liteamp.c*/