Mercurial > audlegacy
changeset 2348:564e8a1fe09a trunk
[svn] - made a public API for fileinfopopup (popup that displays metadata, the same used in playlist); now plugins can include ui_fileinfopopup.h to display metadata popups (i.e. statusicon and libnotify plugins)
author | giacomo |
---|---|
date | Tue, 16 Jan 2007 10:33:13 -0800 |
parents | 74bbc3e18cba |
children | aa15ae72f7fb |
files | ChangeLog src/audacious/Makefile src/audacious/main.c src/audacious/ui_fileinfo.c src/audacious/ui_fileinfo.h src/audacious/ui_fileinfopopup.c src/audacious/ui_fileinfopopup.h src/audacious/ui_playlist.c |
diffstat | 8 files changed, 513 insertions(+), 238 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Jan 16 05:17:18 2007 -0800 +++ b/ChangeLog Tue Jan 16 10:33:13 2007 -0800 @@ -1,3 +1,13 @@ +2007-01-16 13:17:18 +0000 William Pitcock <nenolod@sacredspiral.co.uk> + revision [3704] + - fix W:input.c(422) [input_check_file]:Implicit declaration + 'vfs_buffered_file_new_from_uri' (automatic function fallback to int) + as reported by sun cc + + trunk/src/audacious/input.c | 4 ++++ + 1 file changed, 4 insertions(+) + + 2007-01-16 12:41:05 +0000 Michael Farber <01mf02@gmail.com> revision [3702] removed xmms_create_dirbrowser, small config db fixes
--- a/src/audacious/Makefile Tue Jan 16 05:17:18 2007 -0800 +++ b/src/audacious/Makefile Tue Jan 16 10:33:13 2007 -0800 @@ -36,6 +36,7 @@ playlist.h \ playlist_container.h \ plugin.h \ + ui_fileinfopopup.h \ ui_preferences.h \ util.h \ vfs.h \ @@ -67,6 +68,7 @@ ui_skinselector.c \ ui_preferences.c \ ui_fileinfo.c \ + ui_fileinfopopup.c \ ui_playlist.c \ ui_manager.c \ ui_equalizer.c \
--- a/src/audacious/main.c Tue Jan 16 05:17:18 2007 -0800 +++ b/src/audacious/main.c Tue Jan 16 10:33:13 2007 -0800 @@ -1238,7 +1238,6 @@ create_prefs_window(); create_fileinfo_window(); - create_filepopup_window(); if (cfg.player_visible) mainwin_show(TRUE);
--- a/src/audacious/ui_fileinfo.c Tue Jan 16 05:17:18 2007 -0800 +++ b/src/audacious/ui_fileinfo.c Tue Jan 16 10:33:13 2007 -0800 @@ -63,7 +63,6 @@ #include "ui_playlist.h" GtkWidget *fileinfo_win; -GtkWidget *filepopup_win; static void fileinfo_entry_set_text(const char *entry, const char *text) @@ -133,144 +132,6 @@ g_object_unref(G_OBJECT(pixbuf)); } -static void -filepopup_entry_set_text(const char *entry, const char *text) -{ - GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); - GtkWidget *widget = glade_xml_get_widget(xml, entry); - - if (xml == NULL || widget == NULL) - return; - - gtk_label_set_text(GTK_LABEL(widget), text); -} - -static void -filepopup_entry_set_image(const char *entry, const char *text) -{ - GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); - GtkWidget *widget = glade_xml_get_widget(xml, entry); - GdkPixbuf *pixbuf; - int width, height; - double aspect; - GdkPixbuf *pixbuf2; - - if (xml == NULL || widget == NULL) - return; - - pixbuf = gdk_pixbuf_new_from_file(text, NULL); - - if (pixbuf == NULL) - return; - - width = gdk_pixbuf_get_width(GDK_PIXBUF(pixbuf)); - height = gdk_pixbuf_get_height(GDK_PIXBUF(pixbuf)); - - if(strcmp(DATA_DIR "/images/audio.png", text)) - { - if(width == 0) - width = 1; - aspect = (double)height / (double)width; - if(aspect > 1.0) { - height = (int)(cfg.filepopup_pixelsize * aspect); - width = cfg.filepopup_pixelsize; - } else { - height = cfg.filepopup_pixelsize; - width = (int)(cfg.filepopup_pixelsize / aspect); - } - pixbuf2 = gdk_pixbuf_scale_simple(GDK_PIXBUF(pixbuf), width, height, GDK_INTERP_BILINEAR); - g_object_unref(G_OBJECT(pixbuf)); - pixbuf = pixbuf2; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(widget), GDK_PIXBUF(pixbuf)); - g_object_unref(G_OBJECT(pixbuf)); -} - -static void -filepopup_entry_set_text_free(const char *entry, char *text) -{ - GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); - GtkWidget *widget = glade_xml_get_widget(xml, entry); - - if (xml == NULL || widget == NULL) - return; - - gtk_label_set_text(GTK_LABEL(widget), text); - - g_free(text); -} - -static gboolean -filepopup_pointer_check_iter(gpointer unused) -{ - gint x, y, pos; - TitleInput *tuple; - static gint prev_x = 0, prev_y = 0, ctr = 0, prev_pos = -1; - static gint shaded_pos = -1, shaded_prev_pos = -1; - gboolean skip = FALSE; - GdkWindow *win; - Playlist *playlist = playlist_get_active(); - - win = gdk_window_at_pointer(NULL, NULL); - gdk_window_get_pointer(GDK_WINDOW(playlistwin->window), &x, &y, NULL); - pos = playlist_list_get_playlist_position(playlistwin_list, x, y); - - if (win == NULL - || cfg.show_filepopup_for_tuple == FALSE - || playlistwin_list->pl_tooltips == FALSE - || pos != prev_pos - || win != GDK_WINDOW(playlistwin->window)) - { - prev_pos = pos; - ctr = 0; - if ( filepopup_win->window != NULL && - gdk_window_is_viewable(GDK_WINDOW(filepopup_win->window)) ) - filepopup_hide(NULL); - return TRUE; - } - - if (prev_x == x && prev_y == y) - ctr++; - else - { - ctr = 0; - prev_x = x; - prev_y = y; - filepopup_hide(NULL); - return TRUE; - } - - if (filepopup_win->window == NULL) - skip = TRUE; - - if (playlistwin_is_shaded()) { - shaded_pos = playlist_get_position(playlist); - if (shaded_prev_pos != shaded_pos) - skip = TRUE; - } - - if (ctr >= cfg.filepopup_delay && (skip == TRUE || gdk_window_is_viewable(GDK_WINDOW(filepopup_win->window)) != TRUE)) { - if (pos == -1 && !playlistwin_is_shaded()) { - filepopup_hide(NULL); - return TRUE; - } - else { /* shaded mode */ - tuple = playlist_get_tuple(playlist, shaded_pos); - filepopup_hide(NULL); - filepopup_show_for_tuple(tuple); - shaded_prev_pos = shaded_pos; - } - - prev_pos = pos; - - tuple = playlist_get_tuple(playlist, pos); - filepopup_show_for_tuple(tuple); - } - - return TRUE; -} - void fileinfo_hide(gpointer unused) { gtk_widget_hide(fileinfo_win); @@ -288,22 +149,6 @@ fileinfo_entry_set_image("image_artwork", DATA_DIR "/images/audio.png"); } -void filepopup_hide(gpointer unused) -{ - gtk_widget_hide(filepopup_win); - - filepopup_entry_set_text("label_title", ""); - filepopup_entry_set_text("label_artist", ""); - filepopup_entry_set_text("label_album", ""); - filepopup_entry_set_text("label_genre", ""); - filepopup_entry_set_text("label_track", ""); - filepopup_entry_set_text("label_year", ""); - filepopup_entry_set_text("label_length", ""); - - - gtk_window_resize(GTK_WINDOW(filepopup_win), 1, 1); -} - void create_fileinfo_window(void) { @@ -327,27 +172,6 @@ } void -create_filepopup_window(void) -{ - const gchar *glade_file = DATA_DIR "/glade/fileinfo_popup.glade"; - GladeXML *xml; - GtkWidget *widget; - - xml = glade_xml_new_or_die(_("Track Information Popup"), glade_file, NULL, NULL); - - glade_xml_signal_autoconnect(xml); - - filepopup_win = glade_xml_get_widget(xml, "win_pl_popup"); - g_object_set_data(G_OBJECT(filepopup_win), "glade-xml", xml); - gtk_window_set_transient_for(GTK_WINDOW(filepopup_win), GTK_WINDOW(mainwin)); - - widget = glade_xml_get_widget(xml, "image_artwork"); - gtk_image_set_from_file(GTK_IMAGE(widget), DATA_DIR "/images/audio.png"); - - g_timeout_add(50, filepopup_pointer_check_iter, NULL); -} - -void fileinfo_show_for_tuple(TitleInput *tuple) { gchar *tmp = NULL; @@ -553,63 +377,6 @@ } void -filepopup_show_for_tuple(TitleInput *tuple) -{ - gchar *tmp = NULL; - gint x, y, x_off = 3, y_off = 3, h, w; - - static gchar *last_artwork = NULL; - const static char default_artwork[] = DATA_DIR "/images/audio.png"; - - if (tuple == NULL) - return; - - gtk_widget_realize(filepopup_win); - - filepopup_entry_set_text("label_title", tuple->track_name); - filepopup_entry_set_text("label_artist", tuple->performer); - filepopup_entry_set_text("label_album", tuple->album_name); - filepopup_entry_set_text("label_genre", tuple->genre); - - if (tuple->length != -1) - filepopup_entry_set_text_free("label_length", g_strdup_printf("%d:%02d", tuple->length / 60000, (tuple->length / 1000) % 60)); - - if (tuple->year != 0) - filepopup_entry_set_text_free("label_year", g_strdup_printf("%d", tuple->year)); - - if (tuple->track_number != 0) - filepopup_entry_set_text_free("label_track", g_strdup_printf("%d", tuple->track_number)); - - tmp = fileinfo_recursive_get_image(tuple->file_path, tuple->file_name, 0); - if (tmp) { // picture found - if (!last_artwork || strcmp(last_artwork, tmp)) { // new picture - filepopup_entry_set_image("image_artwork", tmp); - g_free(last_artwork); - last_artwork = tmp; - } - else { // same picture - } - } - else { // no picture found - if (!last_artwork || strcmp(last_artwork, default_artwork)) { - filepopup_entry_set_image("image_artwork", default_artwork); - g_free(last_artwork); - last_artwork = g_strdup(default_artwork); - } - else { - } - } - - gdk_window_get_pointer(NULL, &x, &y, NULL); - gtk_window_get_size(GTK_WINDOW(filepopup_win), &w, &h); - if (gdk_screen_width()-(w+3) < x) x_off = (w*-1)-3; - if (gdk_screen_height()-(h+3) < y) y_off = (h*-1)-3; - gtk_window_move(GTK_WINDOW(filepopup_win), x + x_off, y + y_off); - - gtk_widget_show(filepopup_win); -} - -void fileinfo_show_for_path(gchar *path) { TitleInput *tuple = input_get_song_tuple(path);
--- a/src/audacious/ui_fileinfo.h Tue Jan 16 05:17:18 2007 -0800 +++ b/src/audacious/ui_fileinfo.h Tue Jan 16 10:33:13 2007 -0800 @@ -21,13 +21,12 @@ #ifndef _UI_FILEINFO_H_ #define _UI_FILEINFO_H_ +#include "titlestring.h" +#include <glib.h> + void create_fileinfo_window(void); -void create_filepopup_window(void); void fileinfo_show_for_tuple(TitleInput *tuple); -void filepopup_show_for_tuple(TitleInput *tuple); gchar* fileinfo_recursive_get_image(const gchar* path, const gchar* file_name, gint depth); void fileinfo_show_for_path(gchar *path); -void filepopup_hide(gpointer unused); - #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audacious/ui_fileinfopopup.c Tue Jan 16 10:33:13 2007 -0800 @@ -0,0 +1,375 @@ +/* + * Audacious: A cross-platform multimedia player + * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill, + * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <glade/glade.h> +#include <string.h> + +#include "glade.h" +#include "titlestring.h" +#include "ui_fileinfopopup.h" +#include "main.h" +#include "ui_main.h" + + +static void +filepopup_entry_set_text(GtkWidget *filepopup_win, const char *entry, const char *text) +{ + GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); + GtkWidget *widget = glade_xml_get_widget(xml, entry); + + if (xml == NULL || widget == NULL) + return; + + gtk_label_set_text(GTK_LABEL(widget), text); +} + +static void +filepopup_entry_set_image(GtkWidget *filepopup_win, const char *entry, const char *text) +{ + GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); + GtkWidget *widget = glade_xml_get_widget(xml, entry); + GdkPixbuf *pixbuf; + int width, height; + double aspect; + GdkPixbuf *pixbuf2; + + if (xml == NULL || widget == NULL) + return; + + pixbuf = gdk_pixbuf_new_from_file(text, NULL); + + if (pixbuf == NULL) + return; + + width = gdk_pixbuf_get_width(GDK_PIXBUF(pixbuf)); + height = gdk_pixbuf_get_height(GDK_PIXBUF(pixbuf)); + + if(strcmp(DATA_DIR "/images/audio.png", text)) + { + if(width == 0) + width = 1; + aspect = (double)height / (double)width; + if(aspect > 1.0) { + height = (int)(cfg.filepopup_pixelsize * aspect); + width = cfg.filepopup_pixelsize; + } else { + height = cfg.filepopup_pixelsize; + width = (int)(cfg.filepopup_pixelsize / aspect); + } + pixbuf2 = gdk_pixbuf_scale_simple(GDK_PIXBUF(pixbuf), width, height, GDK_INTERP_BILINEAR); + g_object_unref(G_OBJECT(pixbuf)); + pixbuf = pixbuf2; + } + + gtk_image_set_from_pixbuf(GTK_IMAGE(widget), GDK_PIXBUF(pixbuf)); + g_object_unref(G_OBJECT(pixbuf)); +} + +static void +filepopup_entry_set_text_free(GtkWidget *filepopup_win, const char *entry, char *text) +{ + GladeXML *xml = g_object_get_data(G_OBJECT(filepopup_win), "glade-xml"); + GtkWidget *widget = glade_xml_get_widget(xml, entry); + + if (xml == NULL || widget == NULL) + return; + + gtk_label_set_text(GTK_LABEL(widget), text); + + g_free(text); +} + +static gboolean +has_front_cover_extension(const gchar *name) +{ + char *ext; + + ext = strrchr(name, '.'); + if (!ext) { + /* No file extension */ + return FALSE; + } + + return g_strcasecmp(ext, ".jpg") == 0 || + g_strcasecmp(ext, ".jpeg") == 0 || + g_strcasecmp(ext, ".png") == 0; +} + +static gboolean +cover_name_filter(const gchar *name, const gchar *filter, const gboolean ret_on_empty) +{ + gboolean result = FALSE; + gchar **splitted; + gchar *current; + gchar *lname; + gint i; + + if (!filter || strlen(filter) == 0) { + return ret_on_empty; + } + + splitted = g_strsplit(filter, ",", 0); + + lname = g_strdup(name); + g_strdown(lname); + + for (i = 0; !result && (current = splitted[i]); i++) { + gchar *stripped = g_strstrip(g_strdup(current)); + g_strdown(stripped); + + result = result || strstr(lname, stripped); + + g_free(stripped); + } + + g_free(lname); + g_strfreev(splitted); + + return result; +} + +/* Check wether it's an image we want */ +static gboolean +is_front_cover_image(const gchar *imgfile) +{ + return cover_name_filter(imgfile, cfg.cover_name_include, TRUE) && + !cover_name_filter(imgfile, cfg.cover_name_exclude, FALSE); +} + +static gboolean +is_file_image(const gchar *imgfile, const gchar *file_name) +{ + char *imgfile_ext, *file_name_ext; + size_t imgfile_len, file_name_len; + + imgfile_ext = strrchr(imgfile, '.'); + if (!imgfile_ext) { + /* No file extension */ + return FALSE; + } + + file_name_ext = strrchr(file_name, '.'); + if (!file_name_ext) { + /* No file extension */ + return FALSE; + } + + imgfile_len = (imgfile_ext - imgfile); + file_name_len = (file_name_ext - file_name); + + if (imgfile_len == file_name_len) { + return (g_ascii_strncasecmp(imgfile, file_name, imgfile_len) == 0); + } else { + return FALSE; + } +} + +static gchar* +fileinfo_recursive_get_image(const gchar* path, + const gchar* file_name, gint depth) +{ + GDir *d; + + if (cfg.recurse_for_cover && depth > cfg.recurse_for_cover_depth) + return NULL; + + d = g_dir_open(path, 0, NULL); + + if (d) { + const gchar *f; + + if (cfg.use_file_cover && file_name) { + /* Look for images matching file name */ + while((f = g_dir_read_name(d))) { + gchar *newpath = g_strconcat(path, "/", f, NULL); + + if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) && + has_front_cover_extension(f) && + is_file_image(f, file_name)) { + g_dir_close(d); + return newpath; + } + + g_free(newpath); + } + g_dir_rewind(d); + } + + /* Search for files using filter */ + while ((f = g_dir_read_name(d))) { + gchar *newpath = g_strconcat(path, "/", f, NULL); + + if (!g_file_test(newpath, G_FILE_TEST_IS_DIR) && + has_front_cover_extension(f) && + is_front_cover_image(f)) { + g_dir_close(d); + return newpath; + } + + g_free(newpath); + } + g_dir_rewind(d); + + /* checks whether recursive or not. */ + if (!cfg.recurse_for_cover) { + g_dir_close(d); + return NULL; + } + + /* Descend into directories recursively. */ + while ((f = g_dir_read_name(d))) { + gchar *newpath = g_strconcat(path, "/", f, NULL); + + if(g_file_test(newpath, G_FILE_TEST_IS_DIR)) { + gchar *tmp = fileinfo_recursive_get_image(newpath, + NULL, depth + 1); + if(tmp) { + g_free(newpath); + g_dir_close(d); + return tmp; + } + } + + g_free(newpath); + } + + g_dir_close(d); + } + + return NULL; +} + + + +GtkWidget * +audacious_fileinfopopup_create(void) +{ + const gchar *glade_file = DATA_DIR "/glade/fileinfo_popup.glade"; + GladeXML *xml; + GtkWidget *widget; + GtkWidget *filepopup_win; + + xml = glade_xml_new_or_die(_("Track Information Popup"), glade_file, NULL, NULL); + + glade_xml_signal_autoconnect(xml); + + filepopup_win = glade_xml_get_widget(xml, "win_pl_popup"); + g_object_set_data(G_OBJECT(filepopup_win), "glade-xml", xml); + gtk_window_set_transient_for(GTK_WINDOW(filepopup_win), GTK_WINDOW(mainwin)); + + widget = glade_xml_get_widget(xml, "image_artwork"); + gtk_image_set_from_file(GTK_IMAGE(widget), DATA_DIR "/images/audio.png"); + g_object_set_data( G_OBJECT(filepopup_win) , "last_artwork" , NULL ); + + return filepopup_win; +} + +void +audacious_fileinfopopup_destroy(GtkWidget *filepopup_win) +{ + gchar *last_artwork = g_object_get_data( G_OBJECT(filepopup_win) , "last_artwork" ); + if ( last_artwork != NULL ) g_free(last_artwork); + g_object_unref( g_object_get_data(G_OBJECT(filepopup_win), "glade-xml") ); + gtk_widget_destroy( filepopup_win ); + return; +} + +void +audacious_fileinfopopup_show_from_tuple(GtkWidget *filepopup_win, TitleInput *tuple) +{ + gchar *tmp = NULL; + gint x, y, x_off = 3, y_off = 3, h, w; + + gchar *last_artwork = g_object_get_data( G_OBJECT(filepopup_win) , "last_artwork" ); + const static char default_artwork[] = DATA_DIR "/images/audio.png"; + + if (tuple == NULL) + return; + + gtk_widget_realize(filepopup_win); + + filepopup_entry_set_text(filepopup_win, "label_title", tuple->track_name); + filepopup_entry_set_text(filepopup_win, "label_artist", tuple->performer); + filepopup_entry_set_text(filepopup_win, "label_album", tuple->album_name); + filepopup_entry_set_text(filepopup_win, "label_genre", tuple->genre); + + if (tuple->length != -1) + filepopup_entry_set_text_free(filepopup_win, "label_length", g_strdup_printf("%d:%02d", tuple->length / 60000, (tuple->length / 1000) % 60)); + + if (tuple->year != 0) + filepopup_entry_set_text_free(filepopup_win, "label_year", g_strdup_printf("%d", tuple->year)); + + if (tuple->track_number != 0) + filepopup_entry_set_text_free(filepopup_win, "label_track", g_strdup_printf("%d", tuple->track_number)); + + tmp = fileinfo_recursive_get_image(tuple->file_path, tuple->file_name, 0); + if (tmp) { // picture found + if (!last_artwork || strcmp(last_artwork, tmp)) { // new picture + filepopup_entry_set_image(filepopup_win, "image_artwork", tmp); + if (last_artwork) g_free(last_artwork); + last_artwork = tmp; + g_object_set_data( G_OBJECT(filepopup_win) , "last_artwork" , last_artwork ); + } + else { // same picture + } + } + else { // no picture found + if (!last_artwork || strcmp(last_artwork, default_artwork)) { + filepopup_entry_set_image(filepopup_win, "image_artwork", default_artwork); + if (last_artwork) g_free(last_artwork); + last_artwork = g_strdup(default_artwork); + g_object_set_data( G_OBJECT(filepopup_win) , "last_artwork" , last_artwork ); + } + else { + } + } + + gdk_window_get_pointer(NULL, &x, &y, NULL); + gtk_window_get_size(GTK_WINDOW(filepopup_win), &w, &h); + if (gdk_screen_width()-(w+3) < x) x_off = (w*-1)-3; + if (gdk_screen_height()-(h+3) < y) y_off = (h*-1)-3; + gtk_window_move(GTK_WINDOW(filepopup_win), x + x_off, y + y_off); + + gtk_widget_show(filepopup_win); +} + + +void +audacious_fileinfopopup_hide(GtkWidget *filepopup_win, gpointer unused) +{ + gtk_widget_hide(filepopup_win); + + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_title", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_artist", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_album", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_genre", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_track", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_year", ""); + filepopup_entry_set_text(GTK_WIDGET(filepopup_win), "label_length", ""); + + gtk_window_resize(GTK_WINDOW(filepopup_win), 1, 1); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audacious/ui_fileinfopopup.h Tue Jan 16 10:33:13 2007 -0800 @@ -0,0 +1,35 @@ +/* + * Audacious: A cross-platform multimedia player + * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill, + * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _UI_FILEINFOPOPUP_H_ +#define _UI_FILEINFOPOPUP_H_ + +#include "audacious/titlestring.h" +#include <gtk/gtk.h> + +/* create/destroy */ +GtkWidget* audacious_fileinfopopup_create(void); +void audacious_fileinfopopup_destroy(GtkWidget* fileinfopopup_win); + +/* show/hide */ +void audacious_fileinfopopup_show_from_tuple(GtkWidget *fileinfopopup_win, TitleInput *tuple); +void audacious_fileinfopopup_hide(GtkWidget *filepopup_win, gpointer unused); + +#endif
--- a/src/audacious/ui_playlist.c Tue Jan 16 05:17:18 2007 -0800 +++ b/src/audacious/ui_playlist.c Tue Jan 16 10:33:13 2007 -0800 @@ -45,6 +45,7 @@ #include "main.h" #include "ui_main.h" #include "ui_manager.h" +#include "ui_fileinfopopup.h" #include "actions-playlist.h" #include "playback.h" #include "playlist.h" @@ -68,6 +69,9 @@ static gboolean playlistwin_hint_flag = FALSE; +static GtkWidget *playlistwin_infopopup = NULL; +static gint playlistwin_infopopup_sid = 0; + static PlaylistSlider *playlistwin_slider = NULL; static TextBox *playlistwin_time_min, *playlistwin_time_sec; static TextBox *playlistwin_info, *playlistwin_sinfo; @@ -85,6 +89,8 @@ static void playlistwin_draw_frame(void); +static gboolean playlistwin_fileinfopopup_probe(gpointer * filepopup_win); + gboolean playlistwin_is_shaded(void) @@ -1780,6 +1786,8 @@ playlistwin_create_widgets(); playlistwin_update_info(playlist_get_active()); + playlistwin_infopopup = audacious_fileinfopopup_create(); + gtk_window_add_accel_group(GTK_WINDOW(playlistwin), ui_manager_get_accel_group()); } @@ -1797,6 +1805,9 @@ playlistwin_set_toprow(0); playlist_check_pos_current(playlist_get_active()); + playlistwin_infopopup_sid = g_timeout_add( + 50 , (GSourceFunc)playlistwin_fileinfopopup_probe , playlistwin_infopopup ); + gtk_widget_show(playlistwin); } @@ -1811,6 +1822,10 @@ tbutton_set_toggled(mainwin_pl, FALSE); cfg.playlist_visible = FALSE; + /* no point in probing for playlistwin_infopopup trigger when the playlistwin is hidden */ + if ( playlistwin_infopopup_sid != 0 ) + g_source_remove( playlistwin_infopopup_sid ); + if ( cfg.player_visible ) { gtk_window_present(GTK_WINDOW(mainwin)); @@ -2142,3 +2157,76 @@ return FALSE; } } + + +/* fileinfopopup callback for playlistwin */ +static gboolean +playlistwin_fileinfopopup_probe(gpointer * filepopup_win) +{ + gint x, y, pos; + TitleInput *tuple; + static gint prev_x = 0, prev_y = 0, ctr = 0, prev_pos = -1; + static gint shaded_pos = -1, shaded_prev_pos = -1; + gboolean skip = FALSE; + GdkWindow *win; + Playlist *playlist = playlist_get_active(); + + win = gdk_window_at_pointer(NULL, NULL); + gdk_window_get_pointer(GDK_WINDOW(playlistwin->window), &x, &y, NULL); + pos = playlist_list_get_playlist_position(playlistwin_list, x, y); + + if (win == NULL + || cfg.show_filepopup_for_tuple == FALSE + || playlistwin_list->pl_tooltips == FALSE + || pos != prev_pos + || win != GDK_WINDOW(playlistwin->window)) + { + prev_pos = pos; + ctr = 0; + if ( GTK_WIDGET(filepopup_win)->window != NULL && + gdk_window_is_viewable(GDK_WINDOW(GTK_WIDGET(filepopup_win)->window)) ) + audacious_fileinfopopup_hide(GTK_WIDGET(filepopup_win), NULL); + return TRUE; + } + + if (prev_x == x && prev_y == y) + ctr++; + else + { + ctr = 0; + prev_x = x; + prev_y = y; + audacious_fileinfopopup_hide(GTK_WIDGET(filepopup_win), NULL); + return TRUE; + } + + if (GTK_WIDGET(filepopup_win)->window == NULL) + skip = TRUE; + + if (playlistwin_is_shaded()) { + shaded_pos = playlist_get_position(playlist); + if (shaded_prev_pos != shaded_pos) + skip = TRUE; + } + + if (ctr >= cfg.filepopup_delay && (skip == TRUE || gdk_window_is_viewable(GDK_WINDOW(GTK_WIDGET(filepopup_win)->window)) != TRUE)) { + if (pos == -1 && !playlistwin_is_shaded()) { + audacious_fileinfopopup_hide(GTK_WIDGET(filepopup_win), NULL); + return TRUE; + } + else { /* shaded mode */ + tuple = playlist_get_tuple(playlist, shaded_pos); + audacious_fileinfopopup_hide(GTK_WIDGET(filepopup_win), NULL); + audacious_fileinfopopup_show_from_tuple(GTK_WIDGET(filepopup_win), tuple); + shaded_prev_pos = shaded_pos; + } + + prev_pos = pos; + + tuple = playlist_get_tuple(playlist, pos); + audacious_fileinfopopup_show_from_tuple(GTK_WIDGET(filepopup_win), tuple); + } + + return TRUE; +} +