summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-11-11 20:33:51 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-11-11 20:33:51 +0100
commit526cbb98cf3f38657afc75ba9e468e3d9dd5232f (patch)
tree970e3bb1394379805758d3da6bc02369306eaa42 /plugins
parent69e0ddb79f353cbf67cbf8db9517e2e71ed87d5c (diff)
created gtkui plugin, started moving stuff out
Diffstat (limited to 'plugins')
-rw-r--r--plugins/gtkui/Makefile.am15
-rw-r--r--plugins/gtkui/callbacks.c1763
-rw-r--r--plugins/gtkui/callbacks.h694
-rw-r--r--plugins/gtkui/deadbeef.glade2493
-rw-r--r--plugins/gtkui/deadbeef.gladep10
-rw-r--r--plugins/gtkui/drawing.h74
-rw-r--r--plugins/gtkui/gdkdrawing.c150
-rw-r--r--plugins/gtkui/gtkplaylist.c2038
-rw-r--r--plugins/gtkui/gtkplaylist.h261
-rw-r--r--plugins/gtkui/gtksession.c44
-rw-r--r--plugins/gtkui/gtkui.c343
-rw-r--r--plugins/gtkui/interface.c1737
-rw-r--r--plugins/gtkui/interface.h12
13 files changed, 9634 insertions, 0 deletions
diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am
new file mode 100644
index 00000000..13ace983
--- /dev/null
+++ b/plugins/gtkui/Makefile.am
@@ -0,0 +1,15 @@
+#if HAVE_GTK
+#gtkuidir = $(libdir)/$(PACKAGE)
+#pkglib_LTLIBRARIES = gtkui.la
+#gtkui_la_SOURCES = gtkui.c\
+# callbacks.c interface.c support.c callbacks.h interface.h support.h\
+# gtkplaylist.c gtkplaylist.h\
+# drawing.h gdkdrawing.c\
+# gtksession.c
+#
+#
+#gtkui_la_LDFLAGS = -module
+#
+#gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS)
+#AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS)
+#endif
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
new file mode 100644
index 00000000..8d6d9bbf
--- /dev/null
+++ b/plugins/gtkui/callbacks.c
@@ -0,0 +1,1763 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <ctype.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+#include "common.h"
+
+#include "playlist.h"
+#include "gtkplaylist.h"
+#include "messagepump.h"
+#include "codec.h"
+#include "playback.h"
+#include "search.h"
+#include "streamer.h"
+#include "progress.h"
+#include "volume.h"
+#include "session.h"
+#include "conf.h"
+
+#include "plugins.h"
+
+extern GtkWidget *mainwin;
+extern gtkplaylist_t main_playlist;
+extern gtkplaylist_t search_playlist;
+
+gboolean
+playlist_tooltip_handler (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer unused)
+{
+ playItem_t *item = gtkpl_get_for_idx (&main_playlist, main_playlist.scrollpos + y / rowheight);
+ if (item && item->fname) {
+ gtk_tooltip_set_text (tooltip, item->fname);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+main_playlist_init (GtkWidget *widget) {
+ // init playlist control structure, and put it into widget user-data
+ memset (&main_playlist, 0, sizeof (main_playlist));
+ main_playlist.title = "playlist";
+ main_playlist.playlist = widget;
+ main_playlist.header = lookup_widget (mainwin, "header");
+ main_playlist.scrollbar = lookup_widget (mainwin, "playscroll");
+ main_playlist.hscrollbar = lookup_widget (mainwin, "playhscroll");
+ main_playlist.pcurr = &playlist_current_ptr;
+ main_playlist.pcount = &pl_count;
+ main_playlist.iterator = PL_MAIN;
+ main_playlist.multisel = 1;
+ main_playlist.scrollpos = 0;
+ main_playlist.hscrollpos = 0;
+ main_playlist.row = -1;
+ main_playlist.clicktime = -1;
+ main_playlist.nvisiblerows = 0;
+
+// FIXME: on 1st run, copy colwidths to new columns
+// main_playlist.colwidths = session_get_main_colwidths_ptr ();
+
+ DB_conf_item_t *col = conf_find ("playlist.column.", NULL);
+ if (!col) {
+ // create default set of columns
+ gtkpl_column_append (&main_playlist, gtkpl_column_alloc ("Playing", 50, DB_COLUMN_PLAYING, NULL, 0));
+ gtkpl_column_append (&main_playlist, gtkpl_column_alloc ("Artist / Album", 150, DB_COLUMN_ARTIST_ALBUM, NULL, 0));
+ gtkpl_column_append (&main_playlist, gtkpl_column_alloc ("Track №", 50, DB_COLUMN_TRACK, NULL, 1));
+ gtkpl_column_append (&main_playlist, gtkpl_column_alloc ("Title / Track Artist", 150, DB_COLUMN_TITLE, NULL, 0));
+ gtkpl_column_append (&main_playlist, gtkpl_column_alloc ("Duration", 50, DB_COLUMN_DURATION, NULL, 0));
+ }
+ else {
+ while (col) {
+ gtkpl_append_column_from_textdef (&main_playlist, col->value);
+ col = conf_find ("playlist.column.", col);
+ }
+ }
+
+ gtk_object_set_data (GTK_OBJECT (main_playlist.playlist), "ps", &main_playlist);
+ gtk_object_set_data (GTK_OBJECT (main_playlist.header), "ps", &main_playlist);
+ gtk_object_set_data (GTK_OBJECT (main_playlist.scrollbar), "ps", &main_playlist);
+ gtk_object_set_data (GTK_OBJECT (main_playlist.hscrollbar), "ps", &main_playlist);
+
+ // FIXME: filepath should be in properties dialog, while tooltip should be
+ // used to show text that doesn't fit in column width
+ if (conf_get_int ("playlist.showpathtooltip", 0)) {
+ GValue value = {0, };
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, TRUE);
+ g_object_set_property (G_OBJECT (widget), "has-tooltip", &value);
+ g_signal_connect (G_OBJECT (widget), "query-tooltip", G_CALLBACK (playlist_tooltip_handler), NULL);
+ }
+}
+
+void
+search_playlist_init (GtkWidget *widget) {
+ extern GtkWidget *searchwin;
+ // init playlist control structure, and put it into widget user-data
+ memset (&search_playlist, 0, sizeof (search_playlist));
+ search_playlist.title = "search";
+ search_playlist.playlist = widget;
+ search_playlist.header = lookup_widget (searchwin, "searchheader");
+ search_playlist.scrollbar = lookup_widget (searchwin, "searchscroll");
+ search_playlist.hscrollbar = lookup_widget (searchwin, "searchhscroll");
+ assert (search_playlist.header);
+ assert (search_playlist.scrollbar);
+ // main_playlist.pcurr = &search_current;
+ search_playlist.pcount = &search_count;
+ search_playlist.multisel = 0;
+ search_playlist.iterator = PL_SEARCH;
+ search_playlist.scrollpos = 0;
+ search_playlist.hscrollpos = 0;
+ search_playlist.row = -1;
+ search_playlist.clicktime = -1;
+ search_playlist.nvisiblerows = 0;
+
+// FIXME: port to new columns
+// search_playlist.colwidths = session_get_search_colwidths_ptr ();
+ // create default set of columns
+ DB_conf_item_t *col = conf_find ("search.column.", NULL);
+ if (!col) {
+ gtkpl_column_append (&search_playlist, gtkpl_column_alloc ("Artist / Album", 150, DB_COLUMN_ARTIST_ALBUM, NULL, 0));
+ gtkpl_column_append (&search_playlist, gtkpl_column_alloc ("Track №", 50, DB_COLUMN_TRACK, NULL, 1));
+ gtkpl_column_append (&search_playlist, gtkpl_column_alloc ("Title / Track Artist", 150, DB_COLUMN_TITLE, NULL, 0));
+ gtkpl_column_append (&search_playlist, gtkpl_column_alloc ("Duration", 50, DB_COLUMN_DURATION, NULL, 0));
+ }
+ else {
+ while (col) {
+ gtkpl_append_column_from_textdef (&search_playlist, col->value);
+ col = conf_find ("search.column.", col);
+ }
+ }
+ gtk_object_set_data (GTK_OBJECT (search_playlist.playlist), "ps", &search_playlist);
+ gtk_object_set_data (GTK_OBJECT (search_playlist.header), "ps", &search_playlist);
+ gtk_object_set_data (GTK_OBJECT (search_playlist.scrollbar), "ps", &search_playlist);
+ gtk_object_set_data (GTK_OBJECT (search_playlist.hscrollbar), "ps", &search_playlist);
+}
+
+// redraw
+gboolean
+on_playlist_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ // draw visible area of playlist
+ gtkpl_expose (ps, event->area.x, event->area.y, event->area.width, event->area.height);
+
+ return FALSE;
+}
+
+
+gboolean
+on_playlist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (event->button == 1) {
+ gtkpl_mouse1_pressed (ps, event->state, event->x, event->y, event->time);
+ }
+ return FALSE;
+}
+
+gboolean
+on_playlist_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (event->button == 1) {
+ gtkpl_mouse1_released (ps, event->state, event->x, event->y, event->time);
+ }
+ return FALSE;
+}
+
+gboolean
+on_playlist_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ gtkpl_mousemove (ps, event);
+ return FALSE;
+}
+
+
+void
+on_playscroll_value_changed (GtkRange *widget,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ int newscroll = gtk_range_get_value (GTK_RANGE (widget));
+ gtkpl_scroll (ps, newscroll);
+}
+
+static gboolean
+file_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
+ // get ext
+ const char *p = filter_info->filename + strlen (filter_info->filename)-1;
+ while (p >= filter_info->filename) {
+ if (*p == '.') {
+ break;
+ }
+ p--;
+ }
+ if (*p != '.') {
+ return FALSE;
+ }
+ p++;
+ DB_decoder_t **codecs = plug_get_decoder_list ();
+ for (int i = 0; codecs[i]; i++) {
+ if (codecs[i]->exts && codecs[i]->insert) {
+ const char **exts = codecs[i]->exts;
+ if (exts) {
+ for (int e = 0; exts[e]; e++) {
+ if (!strcasecmp (exts[e], p)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ if (!strcasecmp (p, "pls")) {
+ return TRUE;
+ }
+ if (!strcasecmp (p, "m3u")) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static GtkFileFilter *
+set_file_filter (GtkWidget *dlg, const char *name) {
+ if (!name) {
+ name = "Supported sound formats";
+ }
+
+ GtkFileFilter* flt;
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, name);
+
+ gtk_file_filter_add_custom (flt, GTK_FILE_FILTER_FILENAME, file_filter_func, NULL, NULL);
+#if 0
+ DB_decoder_t **codecs = plug_get_decoder_list ();
+ for (int i = 0; codecs[i]; i++) {
+ if (codecs[i]->exts && codecs[i]->insert) {
+ const char **exts = codecs[i]->exts;
+ if (exts) {
+ for (int e = 0; exts[e]; e++) {
+ char filter[20];
+ snprintf (filter, 20, "*.%s", exts[e]);
+ gtk_file_filter_add_pattern (flt, filter);
+ char *p;
+ for (p = filter; *p; p++) {
+ *p = toupper (*p);
+ }
+ gtk_file_filter_add_pattern (flt, filter);
+ }
+ }
+ }
+ }
+ gtk_file_filter_add_pattern (flt, "*.pls");
+ gtk_file_filter_add_pattern (flt, "*.m3u");
+#endif
+
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dlg), flt);
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, "Other files (*)");
+ gtk_file_filter_add_pattern (flt, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+}
+
+void
+on_open_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new ("Open file(s)...", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+
+ set_file_filter (dlg, NULL);
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
+ // restore folder
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), conf_get_str ("filechooser.lastdir", ""));
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ // store folder
+ gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
+ if (folder) {
+ conf_set_str ("filechooser.lastdir", folder);
+ g_free (folder);
+ }
+ if (response == GTK_RESPONSE_OK)
+ {
+ pl_free ();
+ GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (lst) {
+ messagepump_push (M_OPENFILES, (uintptr_t)lst, 0, 0);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+
+void
+on_add_files_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new ("Add file(s) to playlist...", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+
+ set_file_filter (dlg, NULL);
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
+
+ // restore folder
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), conf_get_str ("filechooser.lastdir", ""));
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ // store folder
+ gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
+ if (folder) {
+ conf_set_str ("filechooser.lastdir", folder);
+ g_free (folder);
+ }
+ if (response == GTK_RESPONSE_OK)
+ {
+ GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (lst) {
+ messagepump_push (M_ADDFILES, (uintptr_t)lst, 0, 0);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+void
+on_add_folders_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new ("Add folder(s) to playlist...", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+
+ set_file_filter (dlg, NULL);
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
+ // restore folder
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), conf_get_str ("filechooser.lastdir", ""));
+ int response = gtk_dialog_run (GTK_DIALOG (dlg));
+ // store folder
+ gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
+ if (folder) {
+ conf_set_str ("filechooser.lastdir", folder);
+ g_free (folder);
+ }
+ if (response == GTK_RESPONSE_OK)
+ {
+ gchar *folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+ GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (lst) {
+ messagepump_push (M_ADDDIRS, (uintptr_t)lst, 0, 0);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+
+void
+on_preferences1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_quit_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ progress_abort ();
+ messagepump_push (M_TERMINATE, 0, 0, 0);
+}
+
+
+void
+on_clear1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ pl_free ();
+ gtkplaylist_t *ps = &main_playlist;
+ GtkWidget *widget = ps->playlist;
+ gtkpl_setup_scrollbar (ps);
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ search_refresh ();
+}
+
+
+void
+on_select_all1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ pl_select_all ();
+ gtkplaylist_t *ps = &main_playlist;
+ GtkWidget *widget = ps->playlist;
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+}
+
+
+void
+on_remove1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ gtkplaylist_t *ps = &main_playlist;
+ GtkWidget *widget = ps->playlist;
+ ps->row = pl_delete_selected ();
+ if (ps->row != -1) {
+ playItem_t *it = pl_get_for_idx (ps->row);
+ if (it) {
+ it->selected = 1;
+ }
+ }
+ gtkpl_setup_scrollbar (ps);
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ search_refresh ();
+}
+
+
+void
+on_crop1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ gtkplaylist_t *ps = &main_playlist;
+ GtkWidget *widget = ps->playlist;
+ pl_crop_selected ();
+ gtkpl_setup_scrollbar (ps);
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ search_refresh ();
+}
+
+
+
+gboolean
+on_playlist_scroll_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ GdkEventScroll *ev = (GdkEventScroll*)event;
+ gtkpl_handle_scroll_event (ps, ev->direction);
+ return FALSE;
+}
+
+
+void
+on_stopbtn_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_STOPSONG, 0, 0, 0);
+}
+
+
+void
+on_playbtn_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_PLAYSONG, 0, 0, 0);
+}
+
+
+void
+on_pausebtn_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_PAUSESONG, 0, 0, 0);
+}
+
+
+void
+on_prevbtn_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_PREVSONG, 0, 0, 0);
+}
+
+
+void
+on_nextbtn_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_NEXTSONG, 0, 0, 0);
+}
+
+
+void
+on_playrand_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ messagepump_push (M_PLAYRANDOM, 0, 0, 0);
+}
+
+
+gboolean
+on_mainwin_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ gtkpl_keypress (&main_playlist, event->keyval, event->state);
+ return FALSE;
+}
+
+
+void
+on_playlist_drag_begin (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data)
+{
+}
+
+gboolean
+on_playlist_drag_motion (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ gtkpl_track_dragdrop (ps, y);
+ return FALSE;
+}
+
+
+gboolean
+on_playlist_drag_drop (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data)
+{
+#if 0
+ if (drag_context->targets) {
+ GdkAtom target_type = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, TARGET_SAMEWIDGET));
+ if (!target_type) {
+ return FALSE;
+ }
+ gtk_drag_get_data (widget, drag_context, target_type, time);
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+
+void
+on_playlist_drag_data_get (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *selection_data,
+ guint target_type,
+ guint time,
+ gpointer user_data)
+{
+ switch (target_type) {
+ case TARGET_SAMEWIDGET:
+ {
+ // format as "STRING" consisting of array of pointers
+ int nsel = pl_getselcount ();
+ if (!nsel) {
+ break; // something wrong happened
+ }
+ uint32_t *ptr = malloc (nsel * sizeof (uint32_t));
+ int idx = 0;
+ int i = 0;
+ for (playItem_t *it = playlist_head[PL_MAIN]; it; it = it->next[PL_MAIN], idx++) {
+ if (it->selected) {
+ ptr[i] = idx;
+ i++;
+ }
+ }
+ gtk_selection_data_set (selection_data, selection_data->target, sizeof (uint32_t) * 8, (gchar *)ptr, nsel * sizeof (uint32_t));
+ free (ptr);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+
+void
+on_playlist_drag_data_received (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint target_type,
+ guint time,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ gchar *ptr=(char*)data->data;
+ if (target_type == 0) { // uris
+ fprintf (stderr, "calling gtkpl_handle_fm_drag_drop\n");
+// if (!strncmp(ptr,"file:///",8)) {
+ gtkpl_handle_fm_drag_drop (ps, y, ptr, data->length);
+// }
+ }
+ else if (target_type == 1) {
+ uint32_t *d= (uint32_t *)ptr;
+ gtkpl_handle_drag_drop (ps, y, d, data->length/4);
+ }
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
+}
+
+
+void
+on_playlist_drag_data_delete (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data)
+{
+}
+
+
+gboolean
+on_playlist_drag_failed (GtkWidget *widget,
+ GdkDragContext *arg1,
+ GtkDragResult arg2,
+ gpointer user_data)
+{
+ return TRUE;
+}
+
+
+void
+on_playlist_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ gtkpl_track_dragdrop (ps, -1);
+}
+
+void
+on_voice1_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ codec_lock ();
+ if (str_playing_song.decoder && str_playing_song.decoder->mutevoice) {
+ str_playing_song.decoder->mutevoice (0, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 0 : 1);
+ }
+ codec_unlock ();
+}
+
+
+void
+on_voice2_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ codec_lock ();
+ if (str_playing_song.decoder && str_playing_song.decoder->mutevoice) {
+ str_playing_song.decoder->mutevoice (1, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 0 : 1);
+ }
+ codec_unlock ();
+}
+
+
+void
+on_voice3_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ codec_lock ();
+ if (str_playing_song.decoder && str_playing_song.decoder->mutevoice) {
+ str_playing_song.decoder->mutevoice (2, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 0 : 1);
+ }
+ codec_unlock ();
+}
+
+
+void
+on_voice4_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ codec_lock ();
+ if (str_playing_song.decoder && str_playing_song.decoder->mutevoice) {
+ str_playing_song.decoder->mutevoice (3, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 0 : 1);
+ }
+ codec_unlock ();
+}
+
+
+void
+on_voice5_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ codec_lock ();
+ if (str_playing_song.decoder && str_playing_song.decoder->mutevoice) {
+ str_playing_song.decoder->mutevoice (4, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 0 : 1);
+ }
+ codec_unlock ();
+}
+
+void
+on_order_linear_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.order", 0);
+}
+
+
+void
+on_order_shuffle_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.order", 1);
+}
+
+
+void
+on_order_random_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.order", 2);
+}
+
+
+void
+on_loop_all_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.loop", 0);
+}
+
+
+void
+on_loop_single_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.loop", 2);
+}
+
+
+void
+on_loop_disable_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playback.loop", 1);
+}
+
+void
+on_playlist_realize (GtkWidget *widget,
+ gpointer user_data)
+{
+ GtkTargetEntry entry = {
+ .target = "STRING",
+ .flags = GTK_TARGET_SAME_WIDGET/* | GTK_TARGET_OTHER_APP*/,
+ TARGET_SAMEWIDGET
+ };
+ // setup drag-drop source
+// gtk_drag_source_set (widget, GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_MOVE);
+ // setup drag-drop target
+ gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_drag_dest_add_uri_targets (widget);
+// gtk_drag_dest_set_track_motion (widget, TRUE);
+}
+
+void
+on_searchlist_realize (GtkWidget *widget,
+ gpointer user_data)
+{
+}
+
+
+
+
+
+void
+on_playlist_load_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *dlg = gtk_file_chooser_dialog_new ("Load Playlist", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+
+ GtkFileFilter* flt;
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, "DeaDBeeF playlist files (*.dbpl)");
+ gtk_file_filter_add_pattern (flt, "*.dbpl");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+
+ if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK)
+ {
+ gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+ if (fname) {
+ int res = pl_load (fname);
+ printf ("load result: %d\n", res);
+ g_free (fname);
+ gtkplaylist_t *ps = &main_playlist;
+ gtkpl_setup_scrollbar (ps);
+ gtkpl_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ search_refresh ();
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+char last_playlist_save_name[1024] = "";
+
+void
+save_playlist_as (void) {
+ GtkWidget *dlg = gtk_file_chooser_dialog_new ("Save Playlist As", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
+
+ GtkFileFilter* flt;
+ flt = gtk_file_filter_new ();
+ gtk_file_filter_set_name (flt, "DeaDBeeF playlist files (*.dbpl)");
+ gtk_file_filter_add_pattern (flt, "*.dbpl");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
+
+ if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK)
+ {
+ gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+ gtk_widget_destroy (dlg);
+
+ if (fname) {
+ int res = pl_save (fname);
+ printf ("save as res: %d\n", res);
+ if (res >= 0 && strlen (fname) < 1024) {
+ strcpy (last_playlist_save_name, fname);
+ }
+ g_free (fname);
+ }
+ }
+ else {
+ gtk_widget_destroy (dlg);
+ }
+}
+
+void
+on_playlist_save_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ if (!last_playlist_save_name[0]) {
+ save_playlist_as ();
+ }
+ else {
+ int res = pl_save (last_playlist_save_name);
+ printf ("save res: %d\n", res);
+ }
+}
+
+
+void
+on_playlist_save_as_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ save_playlist_as ();
+}
+
+
+static GdkPixmap *seekbar_backbuf;
+
+enum
+{
+ CORNER_NONE = 0,
+ CORNER_TOPLEFT = 1,
+ CORNER_TOPRIGHT = 2,
+ CORNER_BOTTOMLEFT = 4,
+ CORNER_BOTTOMRIGHT = 8,
+ CORNER_ALL = 15
+};
+
+static void
+clearlooks_rounded_rectangle (cairo_t * cr,
+ double x, double y, double w, double h,
+ double radius, uint8_t corners)
+{
+ if (radius < 0.01 || (corners == CORNER_NONE)) {
+ cairo_rectangle (cr, x, y, w, h);
+ return;
+ }
+
+ if (corners & CORNER_TOPLEFT)
+ cairo_move_to (cr, x + radius, y);
+ else
+ cairo_move_to (cr, x, y);
+
+ if (corners & CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 2);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ if (corners & CORNER_BOTTOMRIGHT)
+ cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+ else
+ cairo_line_to (cr, x + w, y + h);
+
+ if (corners & CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ if (corners & CORNER_TOPLEFT)
+ cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+ else
+ cairo_line_to (cr, x, y);
+
+}
+
+int seekbar_moving = 0;
+int seekbar_move_x = 0;
+
+void
+seekbar_draw (GtkWidget *widget) {
+ if (!widget) {
+ return;
+ }
+ gdk_draw_rectangle (seekbar_backbuf, widget->style->bg_gc[0], TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
+ cairo_t *cr;
+ cr = gdk_cairo_create (seekbar_backbuf);
+ if (!cr) {
+ return;
+ }
+ if (!str_playing_song.decoder || str_playing_song._duration < 0) {
+ clearlooks_rounded_rectangle (cr, 2, widget->allocation.height/2-4, widget->allocation.width-4, 8, 4, 0xff);
+ theme_set_cairo_source_rgb (cr, COLO_SEEKBAR_FRONT);
+ cairo_stroke (cr);
+ return;
+ }
+ float pos = 0;
+ if (seekbar_moving) {
+ int x = seekbar_move_x;
+ if (x < 0) {
+ x = 0;
+ }
+ if (x > widget->allocation.width-1) {
+ x = widget->allocation.width-1;
+ }
+ pos = x;
+ }
+ else {
+ if (str_playing_song.decoder && str_playing_song._duration > 0) {
+ pos = streamer_get_playpos () / str_playing_song._duration;
+ pos *= widget->allocation.width;
+ }
+ }
+ // left
+ if (pos > 0) {
+ theme_set_cairo_source_rgb (cr, COLO_SEEKBAR_FRONT);
+ cairo_rectangle (cr, 0, widget->allocation.height/2-4, pos, 8);
+ cairo_clip (cr);
+ clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff);
+ cairo_fill (cr);
+ cairo_reset_clip (cr);
+ }
+
+ // right
+ theme_set_cairo_source_rgb (cr, COLO_SEEKBAR_BACK);
+ cairo_rectangle (cr, pos, widget->allocation.height/2-4, widget->allocation.width-pos, 8);
+ cairo_clip (cr);
+ clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff);
+ cairo_fill (cr);
+ cairo_reset_clip (cr);
+
+ cairo_destroy (cr);
+}
+
+void
+seekbar_expose (GtkWidget *widget, int x, int y, int w, int h) {
+ gdk_draw_drawable (widget->window, widget->style->black_gc, seekbar_backbuf, x, y, x, y, w, h);
+}
+
+gboolean
+on_seekbar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ if (seekbar_backbuf) {
+ g_object_unref (seekbar_backbuf);
+ seekbar_backbuf = NULL;
+ }
+ seekbar_backbuf = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+ seekbar_draw (widget);
+ return FALSE;
+}
+
+gboolean
+on_seekbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ seekbar_expose (widget, event->area.x, event->area.y, event->area.width, event->area.height);
+ return FALSE;
+}
+
+gboolean
+on_seekbar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ if (seekbar_moving) {
+ seekbar_move_x = event->x;
+ seekbar_draw (widget);
+ seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+ return FALSE;
+}
+
+gboolean
+on_seekbar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ if (p_isstopped ()) {
+ return FALSE;
+ }
+ seekbar_moving = 1;
+ seekbar_move_x = event->x;
+ seekbar_draw (widget);
+ seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ return FALSE;
+}
+
+
+gboolean
+on_seekbar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ seekbar_moving = 0;
+ seekbar_draw (widget);
+ seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ float time = event->x * str_playing_song._duration / (widget->allocation.width);
+ if (time < 0) {
+ time = 0;
+ }
+ streamer_set_seek (time);
+// messagepump_push (M_SONGSEEK, 0, time * 1000, 0);
+ return FALSE;
+}
+
+
+
+static GdkPixmap *volumebar_backbuf;
+
+void
+volumebar_draw (GtkWidget *widget) {
+ if (!widget) {
+ return;
+ }
+ gdk_draw_rectangle (volumebar_backbuf, widget->style->bg_gc[0], TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
+ cairo_t *cr;
+ cr = gdk_cairo_create (volumebar_backbuf);
+ if (!cr) {
+ return;
+ }
+ float range = -volume_get_min_db ();
+ int n = widget->allocation.width / 4;
+ float vol = (range + volume_get_db ()) / range * n;
+ float h = 16;
+ for (int i = 0; i < n; i++) {
+ float iy = (float)i + 3;
+ if (i <= vol) {
+ theme_set_cairo_source_rgb (cr, COLO_VOLUMEBAR_FRONT);
+ }
+ else {
+ theme_set_cairo_source_rgb (cr, COLO_VOLUMEBAR_BACK);
+ }
+ cairo_rectangle (cr, i * 4, (widget->allocation.height/2-h/2) + h - 1 - (h* i / n), 3, h * iy / n);
+ cairo_fill (cr);
+ }
+
+ cairo_destroy (cr);
+}
+
+void
+volumebar_expose (GtkWidget *widget, int x, int y, int w, int h) {
+ gdk_draw_drawable (widget->window, widget->style->black_gc, volumebar_backbuf, x, y, x, y, w, h);
+}
+
+gboolean
+on_volumebar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ if (volumebar_backbuf) {
+ g_object_unref (volumebar_backbuf);
+ volumebar_backbuf = NULL;
+ }
+ volumebar_backbuf = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+ volumebar_draw (widget);
+ return FALSE;
+}
+
+gboolean
+on_volumebar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ volumebar_expose (widget, event->area.x, event->area.y, event->area.width, event->area.height);
+ return FALSE;
+}
+
+
+gboolean
+on_volumebar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ if (event->state & GDK_BUTTON1_MASK) {
+ float range = -volume_get_min_db ();
+ float volume = event->x / widget->allocation.width * range - range;
+ if (volume > 0) {
+ volume = 0;
+ }
+ if (volume < -range) {
+ volume = -range;
+ }
+ volume_set_db (volume);
+ volumebar_draw (widget);
+ volumebar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+ return FALSE;
+}
+
+gboolean
+on_volumebar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ float range = -volume_get_min_db ();
+ float volume = event->x / widget->allocation.width * range - range;
+ if (volume < -range) {
+ volume = -range;
+ }
+ if (volume > 0) {
+ volume = 0;
+ }
+ volume_set_db (volume);
+ volumebar_draw (widget);
+ volumebar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ return FALSE;
+}
+
+
+gboolean
+on_volumebar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ return FALSE;
+}
+
+void
+volumebar_notify_changed (void) {
+ GtkWidget *widget = lookup_widget (mainwin, "volumebar");
+ volumebar_draw (widget);
+ volumebar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+}
+
+gboolean
+on_mainwin_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ int conf_close_send_to_tray = conf_get_int ("close_send_to_tray", 0);
+ if (conf_close_send_to_tray) {
+ gtk_widget_hide (widget);
+ }
+ else {
+ messagepump_push (M_TERMINATE, 0, 0, 0);
+ }
+ return TRUE;
+}
+
+
+
+
+gboolean
+on_volumebar_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event,
+ gpointer user_data)
+{
+ float range = -volume_get_min_db ();
+ float vol = volume_get_db ();
+ if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) {
+ vol += 1;
+ }
+ else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) {
+ vol -= 1;
+ }
+ if (vol > 0) {
+ vol = 0;
+ }
+ else if (vol < -range) {
+ vol = -range;
+ }
+ volume_set_db (vol);
+ GtkWidget *volumebar = lookup_widget (mainwin, "volumebar");
+ volumebar_draw (volumebar);
+ volumebar_expose (volumebar, 0, 0, volumebar->allocation.width, volumebar->allocation.height);
+ return FALSE;
+}
+
+
+
+gboolean
+on_mainwin_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ session_capture_window_attrs ((uintptr_t)widget);
+ return FALSE;
+}
+
+
+void
+on_scroll_follows_playback_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ conf_set_int ("playlist.scroll.followplayback", gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)));
+}
+
+
+void
+on_find_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ search_start ();
+}
+
+void
+show_info_window (const char *fname, const char *title) {
+ GtkWidget *widget = create_helpwindow ();
+ gtk_window_set_title (GTK_WINDOW (widget), title);
+ gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (mainwin));
+ GtkWidget *txt = lookup_widget (widget, "helptext");
+ GtkTextBuffer *buffer = gtk_text_buffer_new (NULL);
+
+ FILE *fp = fopen (fname, "rb");
+ if (fp) {
+ fseek (fp, 0, SEEK_END);
+ size_t s = ftell (fp);
+ rewind (fp);
+ char buf[s+1];
+ if (fread (buf, 1, s, fp) != s) {
+ fprintf (stderr, "error reading help file contents\n");
+ const char *error = "Failed while reading help file";
+ gtk_text_buffer_set_text (buffer, error, strlen (error));
+ }
+ else {
+ buf[s] = 0;
+ gtk_text_buffer_set_text (buffer, buf, s);
+ }
+ fclose (fp);
+ }
+ else {
+ const char *error = "Failed to load help file";
+ gtk_text_buffer_set_text (buffer, error, strlen (error));
+ }
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (txt), buffer);
+ g_object_unref (buffer);
+ gtk_widget_show (widget);
+}
+
+void
+on_help1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ show_info_window (PREFIX "/share/doc/deadbeef/help.txt", "Help");
+}
+
+void
+on_about1_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ show_info_window (PREFIX "/share/doc/deadbeef/about.txt", "About DeaDBeeF " VERSION);
+}
+
+
+void
+on_playhscroll_value_changed (GtkRange *widget,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ int newscroll = gtk_range_get_value (GTK_RANGE (widget));
+ gtkpl_hscroll (ps, newscroll);
+}
+
+
+void
+on_searchhscroll_value_changed (GtkRange *widget,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ int newscroll = gtk_range_get_value (GTK_RANGE (widget));
+ gtkpl_hscroll (ps, newscroll);
+}
+
+
+gboolean
+on_helpwindow_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_Escape) {
+ gtk_widget_hide (widget);
+ gtk_widget_destroy (widget);
+ }
+ return FALSE;
+}
+
+
+void
+on_add_audio_cd_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ pl_add_file ("all.cda", NULL, NULL);
+ playlist_refresh ();
+}
+
+static GtkWidget *prefwin;
+
+static char alsa_device_names[100][64];
+static int num_alsa_devices;
+
+static void
+gtk_enum_sound_callback (const char *name, const char *desc, void *userdata) {
+ if (num_alsa_devices >= 100) {
+ fprintf (stderr, "wtf!! more than 100 alsa devices??\n");
+ return;
+ }
+ GtkComboBox *combobox = GTK_COMBO_BOX (userdata);
+ gtk_combo_box_append_text (combobox, desc);
+
+ if (!strcmp (conf_get_str ("alsa_soundcard", "default"), name)) {
+ gtk_combo_box_set_active (combobox, num_alsa_devices);
+ }
+
+ strncpy (alsa_device_names[num_alsa_devices], name, 63);
+ alsa_device_names[num_alsa_devices][63] = 0;
+ num_alsa_devices++;
+}
+
+void
+on_preferences_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *w = prefwin = create_prefwin ();
+ gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (mainwin));
+
+ // alsa_soundcard
+
+ const char *s = conf_get_str ("alsa_soundcard", "default");
+ GtkComboBox *combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_soundcard"));
+ gtk_combo_box_append_text (combobox, "Default Audio Device");
+ if (!strcmp (s, "default")) {
+ gtk_combo_box_set_active (combobox, 0);
+ }
+ num_alsa_devices = 1;
+ strcpy (alsa_device_names[0], "default");
+ palsa_enum_soundcards (gtk_enum_sound_callback, combobox);
+
+ // alsa resampling
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_alsa_resampling")), conf_get_int ("alsa.resample", 0));
+
+ // alsa freeonstop
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_alsa_freewhenstopped")), conf_get_int ("alsa.freeonstop", 0));
+
+ // src_quality
+ combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_src_quality"));
+ gtk_combo_box_set_active (combobox, conf_get_int ("src_quality", 2));
+
+ // replaygain_mode
+ combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_replaygain_mode"));
+ gtk_combo_box_set_active (combobox, conf_get_int ("replaygain_mode", 0));
+
+ // replaygain_scale
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_replaygain_scale")), conf_get_int ("replaygain_scale", 1));
+
+ // close_send_to_tray
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_close_send_to_tray")), conf_get_int ("close_send_to_tray", 0));
+
+ // network
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "pref_network_enableproxy")), conf_get_int ("network.proxy", 0));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyaddress")), conf_get_str ("network.proxy.address", ""));
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "pref_network_proxyport")), conf_get_str ("network.proxy.port", "8080"));
+ combobox = GTK_COMBO_BOX (lookup_widget (w, "pref_network_proxytype"));
+ const char *type = conf_get_str ("network.proxy.type", "HTTP");
+ if (!strcasecmp (type, "HTTP")) {
+ gtk_combo_box_set_active (combobox, 0);
+ }
+ else if (!strcasecmp (type, "HTTP_1_0")) {
+ gtk_combo_box_set_active (combobox, 1);
+ }
+ else if (!strcasecmp (type, "SOCKS4")) {
+ gtk_combo_box_set_active (combobox, 2);
+ }
+ else if (!strcasecmp (type, "SOCKS5")) {
+ gtk_combo_box_set_active (combobox, 3);
+ }
+ else if (!strcasecmp (type, "SOCKS4A")) {
+ gtk_combo_box_set_active (combobox, 4);
+ }
+ else if (!strcasecmp (type, "SOCKS5_HOSTNAME")) {
+ gtk_combo_box_set_active (combobox, 5);
+ }
+
+ // list of plugins
+ GtkTreeView *tree = GTK_TREE_VIEW (lookup_widget (w, "pref_pluginlist"));
+ GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);//GTK_LIST_STORE (gtk_tree_view_get_model (tree));
+ GtkCellRenderer *rend = gtk_cell_renderer_text_new ();
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes ("Title", rend, "text", 0, NULL);
+ gtk_tree_view_append_column (tree, col);
+ DB_plugin_t **plugins = plug_get_list ();
+ int i;
+ for (i = 0; plugins[i]; i++) {
+ GtkTreeIter it;
+ gtk_list_store_append (store, &it);
+ gtk_list_store_set (store, &it, 0, plugins[i]->name, -1);
+ }
+ gtk_tree_view_set_model (tree, GTK_TREE_MODEL (store));
+
+ gtk_widget_show (w);
+}
+
+
+void
+on_pref_soundcard_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ int active = gtk_combo_box_get_active (combobox);
+ if (active >= 0 && active < num_alsa_devices) {
+ conf_set_str ("alsa_soundcard", alsa_device_names[active]);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+ }
+}
+
+void
+on_pref_alsa_resampling_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ conf_set_int ("alsa.resample", active);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+}
+
+
+void
+on_pref_src_quality_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ int active = gtk_combo_box_get_active (combobox);
+ conf_set_int ("src_quality", active == -1 ? 2 : active);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+}
+
+
+void
+on_pref_replaygain_mode_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ int active = gtk_combo_box_get_active (combobox);
+ conf_set_int ("replaygain_mode", active == -1 ? 0 : active);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+}
+
+void
+on_pref_replaygain_scale_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ conf_set_int ("replaygain_scale", active);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+}
+
+
+void
+on_pref_close_send_to_tray_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ conf_set_int ("close_send_to_tray", active);
+ messagepump_push (M_CONFIGCHANGED, 0, 0, 0);
+}
+
+
+void
+on_pref_plugin_configure_activate (GtkButton *button,
+ gpointer user_data)
+{
+}
+
+void
+on_pref_pluginlist_cursor_changed (GtkTreeView *treeview,
+ gpointer user_data)
+{
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ // reset
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ DB_plugin_t **plugins = plug_get_list ();
+ DB_plugin_t *p = plugins[*indices];
+ assert (p);
+ GtkWidget *w = prefwin;//GTK_WIDGET (gtk_widget_get_parent_window (GTK_WIDGET (treeview)));
+ assert (w);
+ GtkEntry *e = GTK_ENTRY (lookup_widget (w, "pref_plugin_descr"));
+ gtk_entry_set_text (e, p->descr ? p->descr : "");
+ e = GTK_ENTRY (lookup_widget (w, "pref_plugin_author"));
+ gtk_entry_set_text (e, p->author ? p->author : "");
+ e = GTK_ENTRY (lookup_widget (w, "pref_plugin_email"));
+ gtk_entry_set_text (e, p->email ? p->email : "");
+ e = GTK_ENTRY (lookup_widget (w, "pref_plugin_website"));
+ gtk_entry_set_text (e, p->website ? p->website : "");
+}
+
+
+
+void
+on_artist_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_album_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_tracknum_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_duration_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_playing_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_title_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_custom_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_remove_column_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+
+}
+
+
+void
+on_pref_alsa_freewhenstopped_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ int active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ conf_set_int ("alsa.freeonstop", active);
+}
+
+void
+on_pref_network_proxyaddress_changed (GtkEditable *editable,
+ gpointer user_data)
+{
+ conf_set_str ("network.proxy.address", gtk_entry_get_text (GTK_ENTRY (editable)));
+}
+
+
+void
+on_pref_network_enableproxy_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ conf_set_int ("network.proxy", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)));
+}
+
+
+void
+on_pref_network_proxyport_changed (GtkEditable *editable,
+ gpointer user_data)
+{
+ conf_set_int ("network.proxy.port", atoi (gtk_entry_get_text (GTK_ENTRY (editable))));
+}
+
+
+void
+on_pref_network_proxytype_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+
+ int active = gtk_combo_box_get_active (combobox);
+ switch (active) {
+ case 0:
+ conf_set_str ("network.proxy.type", "HTTP");
+ break;
+ case 1:
+ conf_set_str ("network.proxy.type", "HTTP_1_0");
+ break;
+ case 2:
+ conf_set_str ("network.proxy.type", "SOCKS4");
+ break;
+ case 3:
+ conf_set_str ("network.proxy.type", "SOCKS5");
+ break;
+ case 4:
+ conf_set_str ("network.proxy.type", "SOCKS4A");
+ break;
+ case 5:
+ conf_set_str ("network.proxy.type", "SOCKS5_HOSTNAME");
+ break;
+ default:
+ conf_set_str ("network.proxy.type", "HTTP");
+ break;
+ }
+}
+
+
+gboolean
+on_prefwin_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_Escape) {
+ gtk_widget_hide (widget);
+ gtk_widget_destroy (widget);
+ }
+ return FALSE;
+}
+
+
+static GtkWidget *addlocation_window;
+
+void
+on_add_location_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *widget = addlocation_window = create_addlocation ();
+ gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (mainwin));
+ gtk_widget_show (widget);
+}
+
+static void
+add_location_destroy (void) {
+ if (addlocation_window) {
+ gtk_widget_hide (addlocation_window);
+ gtk_widget_destroy (addlocation_window);
+ addlocation_window = NULL;
+ }
+}
+
+void
+on_addlocation_entry_activate (GtkEntry *entry,
+ gpointer user_data)
+{
+ const char *text = gtk_entry_get_text (entry);
+ if (text) {
+ pl_add_file (text, NULL, NULL);
+ playlist_refresh ();
+ }
+ add_location_destroy ();
+}
+
+void
+on_addlocation_ok_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ if (addlocation_window) {
+ GtkEntry *entry = GTK_ENTRY (lookup_widget (addlocation_window, "addlocation_entry"));
+ if (entry) {
+ const char *text = gtk_entry_get_text (entry);
+ if (text) {
+ pl_add_file (text, NULL, NULL);
+ playlist_refresh ();
+ }
+ }
+ }
+ add_location_destroy ();
+}
+
+gboolean
+on_addlocation_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_Escape) {
+ add_location_destroy ();
+ }
+ return FALSE;
+}
+
+
+
+
+
+
diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h
new file mode 100644
index 00000000..d2e3f61a
--- /dev/null
+++ b/plugins/gtkui/callbacks.h
@@ -0,0 +1,694 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+#include <gtk/gtk.h>
+
+
+void
+on_addbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_playbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_volume_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_playpos_value_changed (GtkRange *range,
+ gpointer user_data);
+
+gboolean
+on_playlist_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+void
+on_playlist_realize (GtkWidget *widget,
+ gpointer user_data);
+
+gboolean
+on_playlist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+void
+on_playscroll_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_open_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_add_files_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_add_folder1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_preferences1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_quit_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_clear1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_select_all1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_remove1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_crop1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_about1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+gboolean
+on_playlist_scroll_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+void
+on_stopbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_playbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pausebtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_prevbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_nextbtn_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_playrand_clicked (GtkButton *button,
+ gpointer user_data);
+
+gboolean
+on_mainwin_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+void
+on_playlist_drag_begin (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data);
+
+gboolean
+on_playlist_drag_motion (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data);
+
+gboolean
+on_playlist_drag_drop (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data);
+
+void
+on_playlist_drag_data_get (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data);
+
+void
+on_playlist_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data);
+
+gboolean
+on_playlist_drag_failed (GtkWidget *widget,
+ GdkDragContext *arg1,
+ GtkDragResult arg2,
+ gpointer user_data);
+
+void
+on_playlist_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time,
+ gpointer user_data);
+
+gboolean
+on_playlist_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+void
+on_voice1_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_voice2_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_voice3_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_voice4_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_voice5_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_playlist_drag_data_received (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data);
+
+void
+on_playlist_drag_data_delete (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data);
+
+gboolean
+on_header_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_header_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+void
+on_header_realize (GtkWidget *widget,
+ gpointer user_data);
+
+gboolean
+on_header_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+gboolean
+on_header_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_header_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+void
+on_order_linear_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_order_shuffle_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_order_random_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_loop_all_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_loop_single_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_loop_disable_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+gboolean
+on_searchwin_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+void
+on_searchentry_changed (GtkEditable *editable,
+ gpointer user_data);
+
+gboolean
+on_searchheader_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_searchheader_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_searchheader_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_searchheader_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_searchheader_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+gboolean
+on_searchlist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_searchlist_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_searchlist_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_searchlist_scroll_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+void
+on_searchscroll_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_searchlist_realize (GtkWidget *widget,
+ gpointer user_data);
+
+gboolean
+on_header_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_header_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_header_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_header_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_header_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_scroll_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_playlist_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+
+void
+on_playscroll_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_playlist_load_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_playlist_save_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_playlist_save_as_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+gboolean
+on_seekbar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
+
+void
+on_main_quit (GtkObject *object,
+ gpointer user_data);
+
+gboolean
+on_mainwin_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+void
+volumebar_draw (GtkWidget *widget);
+void
+volumebar_expose (GtkWidget *widget, int x, int y, int w, int h);
+
+
+
+void
+on_progress_abort (GtkButton *button,
+ gpointer user_data);
+
+gboolean
+on_addprogress_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+gboolean
+on_volumebar_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event,
+ gpointer user_data);
+
+
+void
+on_order_shuffle_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+gboolean
+on_mainwin_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+void
+on_cursor_follows_playback_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_scroll_follows_playback_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_find_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_add_folders_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_clear1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_select_all1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_remove1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_find_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+
+void
+on_help1_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_playhscroll_value_changed (GtkRange *range,
+ gpointer user_data);
+
+void
+on_searchhscroll_value_changed (GtkRange *range,
+ gpointer user_data);
+
+gboolean
+on_helpwindow_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+void
+on_add_audio_cd_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_preferences_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_pref_soundcard_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_pref_samplerate_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_pref_src_quality_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_pref_replaygain_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_replaygain_scale_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_close_send_to_tray_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_plugin_configure_activate (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_src_quality_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_conf_replaygain_mode_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_pref_replaygain_mode_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_pref_pluginlist_cursor_changed (GtkTreeView *treeview,
+ gpointer user_data);
+
+gboolean
+on_header_popup_menu (GtkWidget *widget,
+ gpointer user_data);
+
+void
+on_artist_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_album_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_tracknum_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_duration_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_playing_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_title_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_custom_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_remove_column_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_pref_alsa_resampling_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_alsa_freewhenstopped_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_soundcard_editing_done (GtkCellEditable *celleditable,
+ gpointer user_data);
+
+void
+on_pref_soundcard_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+void
+on_pref_network_proxyaddress_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_pref_network_enableproxy_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_pref_network_proxyport_changed (GtkEditable *editable,
+ gpointer user_data);
+
+void
+on_pref_network_proxytype_changed (GtkComboBox *combobox,
+ gpointer user_data);
+
+gboolean
+on_prefwin_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+void
+on_addlocation_ok_activate (GtkButton *button,
+ gpointer user_data);
+
+gboolean
+on_addlocation_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+void
+on_add_location_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
+on_location_activate (GtkEntry *entry,
+ gpointer user_data);
+
+void
+on_addlocation_ok_clicked (GtkButton *button,
+ gpointer user_data);
+
+void
+on_addlocation_entry_activate (GtkEntry *entry,
+ gpointer user_data);
diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade
new file mode 100644
index 00000000..c71e3a65
--- /dev/null
+++ b/plugins/gtkui/deadbeef.glade
@@ -0,0 +1,2493 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainwin">
+ <property name="visible">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="title" translatable="yes">DeaDBeeF</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">500</property>
+ <property name="default_height">300</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="icon_name"></property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="key_press_event" handler="on_mainwin_key_press_event" last_modification_time="Thu, 30 Jul 2009 21:14:26 GMT"/>
+ <signal name="delete_event" handler="on_mainwin_delete_event" last_modification_time="Thu, 13 Aug 2009 20:35:55 GMT"/>
+ <signal name="configure_event" handler="on_mainwin_configure_event" last_modification_time="Sun, 23 Aug 2009 15:26:53 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <property name="pack_direction">GTK_PACK_DIRECTION_LTR</property>
+ <property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="open">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Open file(s)</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_open_activate" last_modification_time="Sat, 04 Jul 2009 12:57:58 GMT"/>
+ <accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image120">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="add_files">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add file(s)</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_add_files_activate" last_modification_time="Sat, 04 Jul 2009 13:04:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image121">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="add_folders">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add folder(s)</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_add_folders_activate" last_modification_time="Sun, 06 Sep 2009 17:51:40 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image122">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="add_audio_cd">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add Audio CD</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_add_audio_cd_activate" last_modification_time="Sat, 10 Oct 2009 15:29:22 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image123">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="add_location1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add location</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_add_location_activate" last_modification_time="Sat, 07 Nov 2009 18:03:26 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Quit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_quit_activate" last_modification_time="Sat, 04 Jul 2009 12:57:58 GMT"/>
+ <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image124">
+ <property name="visible">True</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="edit1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Edit</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="edit1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="clear1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Clear</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_clear1_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image125">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="select_all1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Select all</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_select_all1_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
+ <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="selection1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Selection</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="selection1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="remove1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Remove</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_remove1_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
+ <accelerator key="Delete" modifiers="0" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image126">
+ <property name="visible">True</property>
+ <property name="stock">gtk-remove</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="crop1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Crop</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_crop1_activate" last_modification_time="Sat, 04 Jul 2009 13:04:01 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="find1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Find</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_find_activate" last_modification_time="Sun, 06 Sep 2009 18:30:03 GMT"/>
+ <accelerator key="F" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator5">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="preferences">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Preferences</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_preferences_activate" last_modification_time="Sat, 10 Oct 2009 15:50:29 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="playlist1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Playlist</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="playlist1_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="playlist_load">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Load</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playlist_load_activate" last_modification_time="Sun, 09 Aug 2009 19:04:52 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="playlist_save">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playlist_save_activate" last_modification_time="Sun, 09 Aug 2009 19:04:52 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="playlist_save_as">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save As</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playlist_save_as_activate" last_modification_time="Sun, 09 Aug 2009 19:04:52 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="order1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Order</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="order1_menu">
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="order_linear">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Linear</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <signal name="activate" handler="on_order_linear_activate" last_modification_time="Sat, 08 Aug 2009 12:26:33 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="order_shuffle">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Shuffle</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">order_linear</property>
+ <signal name="activate" handler="on_order_shuffle_activate" last_modification_time="Fri, 21 Aug 2009 16:46:02 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="order_random">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Random</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">order_linear</property>
+ <signal name="activate" handler="on_order_random_activate" last_modification_time="Sat, 08 Aug 2009 12:26:33 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="looping1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Looping</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="looping1_menu">
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="loop_all">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Loop All</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <signal name="activate" handler="on_loop_all_activate" last_modification_time="Sat, 08 Aug 2009 12:26:33 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="loop_single">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Loop Single Song</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">loop_all</property>
+ <signal name="activate" handler="on_loop_single_activate" last_modification_time="Sat, 08 Aug 2009 12:26:33 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkRadioMenuItem" id="loop_disable">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Don't Loop</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="group">loop_all</property>
+ <signal name="activate" handler="on_loop_disable_activate" last_modification_time="Sat, 08 Aug 2009 12:26:33 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="scroll_follows_playback">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Scroll follows playback</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <signal name="activate" handler="on_scroll_follows_playback_activate" last_modification_time="Wed, 02 Sep 2009 17:46:43 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem4_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="about1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about1_activate" last_modification_time="Sat, 04 Jul 2009 12:57:58 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="help1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Help</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_help1_activate" last_modification_time="Tue, 08 Sep 2009 17:32:06 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image127">
+ <property name="visible">True</property>
+ <property name="stock">gtk-help</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="stopbtn">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_stopbtn_clicked" last_modification_time="Sun, 05 Jul 2009 10:48:41 GMT"/>
+ <accelerator key="v" modifiers="0" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image7">
+ <property name="visible">True</property>
+ <property name="pixbuf">stop_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="playbtn">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_playbtn_clicked" last_modification_time="Sun, 05 Jul 2009 10:48:53 GMT"/>
+ <accelerator key="x" modifiers="0" signal="activate"/>
+ <accelerator key="Return" modifiers="0" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="pixbuf">play_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="pausebtn">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_pausebtn_clicked" last_modification_time="Sun, 05 Jul 2009 10:49:01 GMT"/>
+ <accelerator key="c" modifiers="0" signal="activate"/>
+ <accelerator key="p" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="pixbuf">pause_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="prevbtn">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_prevbtn_clicked" last_modification_time="Sun, 05 Jul 2009 10:49:08 GMT"/>
+ <accelerator key="z" modifiers="0" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="pixbuf">prev_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="nextbtn">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_nextbtn_clicked" last_modification_time="Sun, 05 Jul 2009 10:49:12 GMT"/>
+ <accelerator key="b" modifiers="0" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="pixbuf">next_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="playrand">
+ <property name="visible">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_playrand_clicked" last_modification_time="Sun, 05 Jul 2009 10:49:16 GMT"/>
+ <accelerator key="n" modifiers="0" signal="activate"/>
+
+ <child>
+ <widget class="GtkImage" id="image6">
+ <property name="visible">True</property>
+ <property name="pixbuf">random_24.png</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkDrawingArea" id="volumebar">
+ <property name="width_request">70</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <signal name="button_press_event" handler="on_volumebar_button_press_event" last_modification_time="Tue, 11 Aug 2009 18:57:49 GMT"/>
+ <signal name="button_release_event" handler="on_volumebar_button_release_event" last_modification_time="Tue, 11 Aug 2009 18:57:51 GMT"/>
+ <signal name="configure_event" handler="on_volumebar_configure_event" last_modification_time="Tue, 11 Aug 2009 18:57:55 GMT"/>
+ <signal name="expose_event" handler="on_volumebar_expose_event" last_modification_time="Tue, 11 Aug 2009 18:58:00 GMT"/>
+ <signal name="motion_notify_event" handler="on_volumebar_motion_notify_event" last_modification_time="Tue, 11 Aug 2009 18:58:05 GMT"/>
+ <signal name="scroll_event" handler="on_volumebar_scroll_event" last_modification_time="Tue, 18 Aug 2009 18:44:31 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkDrawingArea" id="seekbar">
+ <property name="width_request">200</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <signal name="button_press_event" handler="on_seekbar_button_press_event" last_modification_time="Tue, 11 Aug 2009 17:47:59 GMT"/>
+ <signal name="button_release_event" handler="on_seekbar_button_release_event" last_modification_time="Tue, 11 Aug 2009 17:48:02 GMT"/>
+ <signal name="configure_event" handler="on_seekbar_configure_event" last_modification_time="Tue, 11 Aug 2009 17:48:06 GMT"/>
+ <signal name="expose_event" handler="on_seekbar_expose_event" last_modification_time="Tue, 11 Aug 2009 17:48:11 GMT"/>
+ <signal name="motion_notify_event" handler="on_seekbar_motion_notify_event" last_modification_time="Tue, 11 Aug 2009 17:48:18 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id=" ">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkDrawingArea" id="header">
+ <property name="height_request">24</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <signal name="expose_event" handler="on_header_expose_event" last_modification_time="Thu, 06 Aug 2009 14:54:29 GMT"/>
+ <signal name="configure_event" handler="on_header_configure_event" last_modification_time="Thu, 06 Aug 2009 14:54:33 GMT"/>
+ <signal name="realize" handler="on_header_realize" last_modification_time="Thu, 06 Aug 2009 14:54:41 GMT"/>
+ <signal name="motion_notify_event" handler="on_header_motion_notify_event" last_modification_time="Thu, 06 Aug 2009 16:33:54 GMT"/>
+ <signal name="button_press_event" handler="on_header_button_press_event" last_modification_time="Thu, 06 Aug 2009 16:42:32 GMT"/>
+ <signal name="button_release_event" handler="on_header_button_release_event" last_modification_time="Thu, 06 Aug 2009 16:47:31 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkDrawingArea" id="playlist">
+ <property name="visible">True</property>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property>
+ <signal name="configure_event" handler="on_playlist_configure_event" last_modification_time="Sat, 04 Jul 2009 00:03:23 GMT"/>
+ <signal name="expose_event" handler="on_playlist_expose_event" last_modification_time="Sat, 04 Jul 2009 00:03:29 GMT"/>
+ <signal name="realize" handler="on_playlist_realize" last_modification_time="Sat, 04 Jul 2009 00:03:36 GMT"/>
+ <signal name="button_press_event" handler="on_playlist_button_press_event" last_modification_time="Sat, 04 Jul 2009 00:41:38 GMT"/>
+ <signal name="scroll_event" handler="on_playlist_scroll_event" last_modification_time="Sat, 04 Jul 2009 17:16:21 GMT"/>
+ <signal name="drag_begin" handler="on_playlist_drag_begin" last_modification_time="Fri, 31 Jul 2009 10:36:23 GMT"/>
+ <signal name="drag_motion" handler="on_playlist_drag_motion" last_modification_time="Fri, 31 Jul 2009 10:36:30 GMT"/>
+ <signal name="drag_drop" handler="on_playlist_drag_drop" last_modification_time="Fri, 31 Jul 2009 10:36:39 GMT"/>
+ <signal name="drag_data_get" handler="on_playlist_drag_data_get" last_modification_time="Fri, 31 Jul 2009 10:36:43 GMT"/>
+ <signal name="drag_end" handler="on_playlist_drag_end" last_modification_time="Fri, 31 Jul 2009 11:41:00 GMT"/>
+ <signal name="drag_failed" handler="on_playlist_drag_failed" last_modification_time="Fri, 31 Jul 2009 11:41:05 GMT"/>
+ <signal name="drag_leave" handler="on_playlist_drag_leave" last_modification_time="Fri, 31 Jul 2009 11:41:11 GMT"/>
+ <signal name="button_release_event" handler="on_playlist_button_release_event" last_modification_time="Fri, 31 Jul 2009 12:20:56 GMT"/>
+ <signal name="motion_notify_event" handler="on_playlist_motion_notify_event" last_modification_time="Fri, 31 Jul 2009 12:23:49 GMT"/>
+ <signal name="drag_data_received" handler="on_playlist_drag_data_received" last_modification_time="Mon, 03 Aug 2009 12:07:39 GMT"/>
+ <signal name="drag_data_delete" handler="on_playlist_drag_data_delete" last_modification_time="Mon, 03 Aug 2009 12:35:47 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVScrollbar" id="playscroll">
+ <property name="visible">True</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">0 0 1 1 0 0</property>
+ <signal name="value_changed" handler="on_playscroll_value_changed" last_modification_time="Sat, 04 Jul 2009 01:42:24 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHScrollbar" id="playhscroll">
+ <property name="visible">True</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">0 0 0 0 0 0</property>
+ <signal name="value_changed" handler="on_playhscroll_value_changed" last_modification_time="Sun, 13 Sep 2009 09:53:45 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkStatusbar" id="statusbar">
+ <property name="visible">True</property>
+ <property name="has_resize_grip">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="searchwin">
+ <property name="width_request">600</property>
+ <property name="height_request">150</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="title" translatable="yes">Search</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="key_press_event" handler="on_searchwin_key_press_event" last_modification_time="Sat, 08 Aug 2009 18:19:17 GMT"/>
+ <signal name="delete_event" handler="gtk_widget_hide_on_delete" last_modification_time="Sat, 08 Aug 2009 23:03:33 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="searchentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">True</property>
+ <signal name="changed" handler="on_searchentry_changed" last_modification_time="Sat, 08 Aug 2009 18:18:17 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">0</property>
+
+ <child>
+ <widget class="GtkVScrollbar" id="searchscroll">
+ <property name="visible">True</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">0 0 1 1 0 0</property>
+ <signal name="value_changed" handler="on_playscroll_value_changed" last_modification_time="Sat, 08 Aug 2009 23:47:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkDrawingArea" id="searchheader">
+ <property name="height_request">24</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <signal name="button_press_event" handler="on_header_button_press_event" last_modification_time="Sat, 08 Aug 2009 22:38:34 GMT"/>
+ <signal name="button_release_event" handler="on_header_button_release_event" last_modification_time="Sat, 08 Aug 2009 22:38:38 GMT"/>
+ <signal name="configure_event" handler="on_header_configure_event" last_modification_time="Sat, 08 Aug 2009 22:38:42 GMT"/>
+ <signal name="expose_event" handler="on_header_expose_event" last_modification_time="Sat, 08 Aug 2009 22:38:46 GMT"/>
+ <signal name="motion_notify_event" handler="on_header_motion_notify_event" last_modification_time="Sat, 08 Aug 2009 22:38:49 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkDrawingArea" id="searchlist">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property>
+ <signal name="button_press_event" handler="on_playlist_button_press_event" last_modification_time="Sat, 08 Aug 2009 22:37:04 GMT"/>
+ <signal name="configure_event" handler="on_searchlist_configure_event" last_modification_time="Sat, 08 Aug 2009 18:51:52 GMT"/>
+ <signal name="expose_event" handler="on_playlist_expose_event" last_modification_time="Sat, 08 Aug 2009 22:36:26 GMT"/>
+ <signal name="scroll_event" handler="on_playlist_scroll_event" last_modification_time="Sat, 08 Aug 2009 22:36:45 GMT"/>
+ <signal name="realize" handler="on_searchlist_realize" last_modification_time="Sat, 08 Aug 2009 19:12:45 GMT"/>
+ <signal name="button_release_event" handler="on_playlist_button_release_event" last_modification_time="Sat, 08 Aug 2009 22:37:24 GMT"/>
+ <signal name="motion_notify_event" handler="on_playlist_motion_notify_event" last_modification_time="Sat, 08 Aug 2009 22:38:04 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHScrollbar" id="searchhscroll">
+ <property name="visible">True</property>
+ <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+ <property name="inverted">False</property>
+ <property name="adjustment">0 0 0 0 0 0</property>
+ <signal name="value_changed" handler="on_searchhscroll_value_changed" last_modification_time="Sun, 13 Sep 2009 10:07:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkMenu" id="traymenu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="stop2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Stop</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_stopbtn_clicked" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image59">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-stop</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="play2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Play</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playbtn_clicked" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image60">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-play</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="pause2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Pause</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_pausebtn_clicked" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image61">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-pause</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="previous2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Previous</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_prevbtn_clicked" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image62">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-previous</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="next2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Next</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_nextbtn_clicked" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image63">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-next</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="play_random1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Play Random</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playrand_clicked" last_modification_time="Sun, 16 Aug 2009 14:48:58 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator4">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="about3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about1_activate" last_modification_time="Sun, 06 Sep 2009 18:34:01 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image64">
+ <property name="visible">True</property>
+ <property name="stock">gtk-about</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator3">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Quit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_quit_activate" last_modification_time="Sun, 16 Aug 2009 14:45:24 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image65">
+ <property name="visible">True</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="addprogress">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Adding files...</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="delete_event" handler="on_addprogress_delete_event" last_modification_time="Sun, 16 Aug 2009 17:20:03 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="progresstitle">
+ <property name="width_request">500</property>
+ <property name="visible">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="width_request">83</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Abort</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_progress_abort" last_modification_time="Sun, 16 Aug 2009 17:17:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="helpwindow">
+ <property name="width_request">600</property>
+ <property name="height_request">400</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_KEY_PRESS_MASK</property>
+ <property name="title" translatable="yes">Help</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="key_press_event" handler="on_helpwindow_key_press_event" last_modification_time="Sun, 04 Oct 2009 19:06:07 GMT"/>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTextView" id="helptext">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_WORD</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">10</property>
+ <property name="right_margin">10</property>
+ <property name="indent">0</property>
+ <property name="text" translatable="yes"></property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="prefwin">
+ <property name="width_request">642</property>
+ <property name="height_request">372</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Preferences</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="key_press_event" handler="on_prefwin_key_press_event" last_modification_time="Sat, 07 Nov 2009 15:47:40 GMT"/>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+
+ <child>
+ <widget class="GtkTable" id="table3">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">3</property>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Output device</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Software ALSA resampling</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">SRC quality (libsamplerate)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Replaygain mode</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Replaygain peak scale</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Release ALSA while stopped</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="pref_alsa_resampling">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_alsa_resampling_clicked" last_modification_time="Sat, 24 Oct 2009 16:50:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="pref_replaygain_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_replaygain_scale_clicked" last_modification_time="Sat, 10 Oct 2009 18:52:10 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="pref_alsa_freewhenstopped">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_alsa_freewhenstopped_clicked" last_modification_time="Sat, 07 Nov 2009 11:37:02 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="pref_soundcard">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_pref_soundcard_changed" last_modification_time="Sat, 07 Nov 2009 14:12:28 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="pref_src_quality">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">sinc_best_quality
+sinc_medium_quality
+sinc_fastest
+sinc_zero_order_hold
+linear</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_pref_src_quality_changed" last_modification_time="Sat, 10 Oct 2009 19:02:36 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="pref_replaygain_mode">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Disable
+Track
+Album</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_pref_replaygain_mode_changed" last_modification_time="Sat, 10 Oct 2009 19:22:23 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="Sound">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sound</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table4">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="n_rows">1</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">3</property>
+
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Close minimizes to tray</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="pref_close_send_to_tray">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_close_send_to_tray_clicked" last_modification_time="Sat, 10 Oct 2009 18:52:15 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">GUI</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table6">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">3</property>
+
+ <child>
+ <widget class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Enable proxy server</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Proxy server address</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_network_proxyaddress">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_pref_network_proxyaddress_changed" last_modification_time="Sat, 07 Nov 2009 15:13:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="pref_network_enableproxy">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="clicked" handler="on_pref_network_enableproxy_clicked" last_modification_time="Sat, 07 Nov 2009 15:12:34 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Proxy server port</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_network_proxyport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="on_pref_network_proxyport_changed" last_modification_time="Sat, 07 Nov 2009 15:13:18 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Proxy type</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="pref_network_proxytype">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">HTTP
+HTTP_1_0
+SOCKS4
+SOCKS5
+SOCKS4A
+SOCKS5_HOSTNAME</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="on_pref_network_proxytype_changed" last_modification_time="Sat, 07 Nov 2009 15:36:03 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Network</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="width_request">280</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="pref_pluginlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="cursor_changed" handler="on_pref_pluginlist_cursor_changed" last_modification_time="Sat, 10 Oct 2009 19:54:17 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table5">
+ <property name="width_request">400</property>
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Description</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Author(s)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Email</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Website</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_plugin_descr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_plugin_author">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_plugin_email">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="pref_plugin_website">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugins</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkMenu" id="headermenu">
+
+ <child>
+ <widget class="GtkMenuItem" id="add_column">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add column</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="add_column_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="artist">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Artist</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_artist_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="album">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Album</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_album_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="tracknum">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Track number</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_tracknum_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="duration">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Duration</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_duration_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="playing">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Playing status</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_playing_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="title">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Title</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_title_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator7">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="custom">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Custom</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_custom_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="remove_column">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Remove this column</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_remove_column_activate" last_modification_time="Mon, 19 Oct 2009 19:30:04 GMT"/>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="addlocation">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Add Location</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="key_press_event" handler="on_addlocation_key_press_event" last_modification_time="Sat, 07 Nov 2009 17:25:40 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox7">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="addlocation_entry">
+ <property name="width_request">346</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ <signal name="activate" handler="on_addlocation_entry_activate" last_modification_time="Sat, 07 Nov 2009 18:13:04 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox8">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="addlocation_ok">
+ <property name="width_request">83</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">OK</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_addlocation_ok_clicked" last_modification_time="Sat, 07 Nov 2009 18:12:00 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/plugins/gtkui/deadbeef.gladep b/plugins/gtkui/deadbeef.gladep
new file mode 100644
index 00000000..22ea860c
--- /dev/null
+++ b/plugins/gtkui/deadbeef.gladep
@@ -0,0 +1,10 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+ <name>Deadbeef</name>
+ <program_name>deadbeef</program_name>
+ <source_directory></source_directory>
+ <gnome_support>FALSE</gnome_support>
+ <gettext_support>FALSE</gettext_support>
+</glade-project>
diff --git a/plugins/gtkui/drawing.h b/plugins/gtkui/drawing.h
new file mode 100644
index 00000000..23c350b6
--- /dev/null
+++ b/plugins/gtkui/drawing.h
@@ -0,0 +1,74 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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 __DRAWING_H
+#define __DRAWING_H
+
+#include <stdint.h>
+
+// abstract api for drawing primitives
+
+void
+draw_init (void);
+
+void
+draw_free (void);
+
+void
+draw_begin (uintptr_t canvas);
+
+void
+draw_end (void);
+
+uintptr_t
+draw_load_pixbuf (const char *fname);
+
+void
+draw_get_canvas_size (uintptr_t canvas, int *w, int *h);
+
+void
+draw_copy (uintptr_t dest_canvas, uintptr_t src_canvas, int dx, int dy, int sx, int sy, int w, int h);
+
+void
+draw_pixbuf (uintptr_t dest_canvas, uintptr_t pixbuf, int dx, int dy, int sx, int sy, int w, int h);
+
+void
+draw_set_fg_color (float *rgb);
+
+void
+draw_set_bg_color (float *rgb);
+
+void
+draw_line (float x1, float y1, float x2, float y2);
+
+void
+draw_rect (float x, float y, float w, float h, int fill);
+
+float
+draw_get_font_size (void);
+
+void
+draw_text (float x, float y, int width, int align, const char *text);
+
+void
+draw_text_with_colors (float x, float y, int width, int align, const char *text);
+
+void
+draw_get_text_extents (const char *text, int len, int *w, int *h);
+
+#endif // __DRAWING_H
diff --git a/plugins/gtkui/gdkdrawing.c b/plugins/gtkui/gdkdrawing.c
new file mode 100644
index 00000000..621ee92e
--- /dev/null
+++ b/plugins/gtkui/gdkdrawing.c
@@ -0,0 +1,150 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "drawing.h"
+#include "support.h"
+
+static GdkDrawable *drawable;
+static GdkGC *gc;
+static GdkColor clrfg;
+static GdkColor clrbg;
+static int pango_ready;
+static PangoContext *pangoctx;
+static PangoLayout *pangolayout;
+
+void
+draw_begin (uintptr_t canvas) {
+ drawable = GDK_DRAWABLE (canvas);
+ gc = gdk_gc_new (drawable);
+}
+
+void
+draw_end (void) {
+// if (pango_ready) {
+// g_object_unref (pangolayout);
+// g_object_unref (pangoctx);
+// pango_ready = 0;
+// }
+ drawable = NULL;
+ if (gc) {
+ g_object_unref (gc);
+ gc = NULL;
+ }
+}
+
+void
+draw_copy (uintptr_t dest_canvas, uintptr_t src_canvas, int dx, int dy, int sx, int sy, int w, int h) {
+ gdk_draw_drawable (GDK_DRAWABLE (dest_canvas), gc, GDK_DRAWABLE (src_canvas), dx, dy, sx, sy, w, h);
+}
+
+uintptr_t
+draw_load_pixbuf (const char *fname) {
+ return (uintptr_t)create_pixbuf (fname);
+}
+
+void
+draw_pixbuf (uintptr_t dest_canvas, uintptr_t pixbuf, int dx, int dy, int sx, int sy, int w, int h) {
+ gdk_pixbuf_render_to_drawable (GDK_PIXBUF (pixbuf), GDK_DRAWABLE (dest_canvas), gc, sx, sy, dx, dy, w, h, GDK_RGB_DITHER_NONE, 0, 0);
+}
+
+void
+draw_get_canvas_size (uintptr_t canvas, int *w, int *h) {
+ gdk_drawable_get_size (GDK_DRAWABLE (canvas), w, h);
+}
+
+void
+draw_set_fg_color (float *rgb) {
+ clrfg.red = rgb[0] * 0xffff;
+ clrfg.green = rgb[1] * 0xffff;
+ clrfg.blue = rgb[2] * 0xffff;
+ gdk_gc_set_rgb_fg_color (gc, &clrfg);
+}
+
+void
+draw_set_bg_color (float *rgb) {
+ clrbg.red = rgb[0] * 0xffff;
+ clrbg.green = rgb[1] * 0xffff;
+ clrbg.blue = rgb[2] * 0xffff;
+ gdk_gc_set_rgb_bg_color (gc, &clrbg);
+}
+
+void
+draw_line (float x1, float y1, float x2, float y2) {
+ gdk_draw_line (drawable, gc, x1, y1, x2, y2);
+}
+
+void
+draw_rect (float x, float y, float w, float h, int fill) {
+ gdk_draw_rectangle (drawable, gc, fill, x, y, w, h);
+}
+
+static inline void
+draw_init_font (void) {
+ if (!pango_ready) {
+ pangoctx = gdk_pango_context_get ();
+ pangolayout = pango_layout_new (pangoctx);
+ pango_layout_set_ellipsize (pangolayout, PANGO_ELLIPSIZE_END);
+ GtkStyle *style = gtk_widget_get_default_style ();
+ PangoFontDescription *desc = style->font_desc;
+ pango_layout_set_font_description (pangolayout, desc);
+ pango_ready = 1;
+ }
+}
+
+float
+draw_get_font_size (void) {
+ GdkScreen *screen = gdk_screen_get_default ();
+ float dpi = gdk_screen_get_resolution (screen);
+ GtkStyle *style = gtk_widget_get_default_style ();
+ PangoFontDescription *desc = style->font_desc;
+ return (float)pango_font_description_get_size (desc) / PANGO_SCALE * dpi / 72;
+}
+
+void
+draw_text (float x, float y, int width, int align, const char *text) {
+ draw_init_font ();
+ pango_layout_set_width (pangolayout, width*PANGO_SCALE);
+ pango_layout_set_alignment (pangolayout, align ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT);
+ pango_layout_set_text (pangolayout, text, -1);
+ gdk_draw_layout (drawable, gc, x, y, pangolayout);
+}
+
+void
+draw_text_with_colors (float x, float y, int width, int align, const char *text) {
+ draw_init_font ();
+ pango_layout_set_width (pangolayout, width*PANGO_SCALE);
+ pango_layout_set_alignment (pangolayout, align ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT);
+ pango_layout_set_text (pangolayout, text, -1);
+ gdk_draw_layout_with_colors (drawable, gc, x, y, pangolayout, &clrfg, &clrbg);
+}
+
+void
+draw_get_text_extents (const char *text, int len, int *w, int *h) {
+ draw_init_font ();
+ pango_layout_set_text (pangolayout, text, len);
+ PangoRectangle ext;
+ pango_layout_get_pixel_extents (pangolayout, &ext, NULL);
+ *w = ext.width;
+ *h = ext.height;
+}
diff --git a/plugins/gtkui/gtkplaylist.c b/plugins/gtkui/gtkplaylist.c
new file mode 100644
index 00000000..cef45ea4
--- /dev/null
+++ b/plugins/gtkui/gtkplaylist.c
@@ -0,0 +1,2038 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "gtkplaylist.h"
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+#include "playlist.h"
+#include "playback.h"
+#include "codec.h"
+#include "common.h"
+#include "messagepump.h"
+#include "streamer.h"
+#include "search.h"
+#include "progress.h"
+#include "drawing.h"
+#include "session.h"
+#include "deadbeef.h"
+#include "conf.h"
+#include "timeline.h"
+
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
+
+extern GtkWidget *mainwin;
+extern GtkStatusIcon *trayicon;
+extern gtkplaylist_t main_playlist;
+
+// orange on dark color scheme
+float colo_dark_orange[COLO_COUNT][3] = {
+ { 0x7f/255.f, 0x7f/255.f, 0x7f/255.f }, // cursor
+ { 0x1d/255.f, 0x1f/255.f, 0x1b/255.f }, // odd
+ { 0x21/255.f, 0x23/255.f, 0x1f/255.f }, // even
+ { 0xaf/255.f, 0xa7/255.f, 0x9e/255.f }, // sel odd
+ { 0xa7/255.f, 0x9f/255.f, 0x96/255.f }, // sel even
+ { 0xf4/255.f, 0x7e/255.f, 0x46/255.f }, // text
+ { 0, 0, 0 }, // sel text
+ { 0x1d/255.f, 0x1f/255.f, 0x1b/255.f }, // seekbar back
+ { 0xf4/255.f, 0x7e/255.f, 0x46/255.f }, // seekbar front
+ { 0x1d/255.f, 0x1f/255.f, 0x1b/255.f }, // volumebar back
+ { 0xf4/255.f, 0x7e/255.f, 0x46/255.f }, // volumebar front
+ { 0xf4/255.f, 0x7e/255.f, 0x46/255.f }, // dragdrop marker
+};
+
+float colo_white_blue[COLO_COUNT][3] = {
+ { 0x7f/255.f, 0x7f/255.f, 0x7f/255.f }, // cursor
+ { 1, 1, 1 }, // odd
+ { 0xea/255.f, 0xeb/255.f, 0xec/255.f }, // even
+ { 0x24/255.f, 0x89/255.f, 0xb8/255.f }, // sel odd
+ { 0x20/255.f, 0x85/255.f, 0xb4/255.f }, // sel even
+ { 0, 0, 0 }, // text
+ { 1, 1, 1 }, // sel text
+ { 0x1d/255.f, 0x1f/255.f, 0x1b/255.f }, // seekbar back
+ { 0x24/255.f, 0x89/255.f, 0xb8/255.f }, // seekbar front
+ { 0x1d/255.f, 0x1f/255.f, 0x1b/255.f }, // volumebar back
+ { 0x24/255.f, 0x89/255.f, 0xb8/255.f }, // volumebar front
+ { 0x09/255.f, 0x22/255.f, 0x3a/255.f }, // dragdrop marker
+};
+
+#define MIN_COLUMN_WIDTH 16
+
+// current color scheme
+float colo_current[COLO_COUNT][3];
+
+// playlist row height
+int rowheight = -1;
+
+// playlist scrolling during dragging
+static int playlist_scroll_mode = 0; // 0=select, 1=dragndrop
+static int playlist_scroll_pointer_y = -1;
+static int playlist_scroll_direction = 0;
+static int playlist_scroll_active = 0;
+static struct timeval tm_prevscroll;
+static float scroll_sleep_time = 0;
+
+static uintptr_t play16_pixbuf;
+static uintptr_t pause16_pixbuf;
+static uintptr_t buffering16_pixbuf;
+
+static GdkCursor* cursor_sz;
+static GdkCursor* cursor_drag;
+static int header_dragging = -1;
+static int header_sizing = -1;
+static int header_dragpt[2];
+
+#define COLHDR_ANIM_TIME 0.2f
+
+typedef struct {
+ int c1;
+ int c2;
+ int x1, x2;
+ int dx1, dx2;
+ // animated values
+ int ax1, ax2;
+ timeline_t *timeline;
+ int anim_active;
+ gtkplaylist_t *pl;
+} colhdr_animator_t;
+
+static colhdr_animator_t colhdr_anim;
+
+static gboolean
+redraw_header (void *data) {
+ colhdr_animator_t *anim = (colhdr_animator_t *)data;
+ gtkpl_header_draw (anim->pl);
+ gtkpl_expose_header (anim->pl, 0, 0, anim->pl->header->allocation.width, anim->pl->header->allocation.height);
+ return FALSE;
+}
+
+static int
+colhdr_anim_cb (float _progress, int _last, void *_ctx) {
+ colhdr_animator_t *anim = (colhdr_animator_t *)_ctx;
+ anim->ax1 = anim->x1 + (float)(anim->dx1 - anim->x1) * _progress;
+ anim->ax2 = anim->x2 + (float)(anim->dx2 - anim->x2) * _progress;
+// printf ("%f %d %d\n", _progress, anim->ax1, anim->ax2);
+ g_idle_add (redraw_header, anim);
+ if (_last) {
+ anim->anim_active = 0;
+ }
+ return 0;
+}
+
+static void
+colhdr_anim_swap (gtkplaylist_t *pl, int c1, int c2, int x1, int x2) {
+ // interrupt previous anim
+ if (!colhdr_anim.timeline) {
+ colhdr_anim.timeline = timeline_create ();
+ }
+ colhdr_anim.pl = pl;
+
+ colhdr_anim.c1 = c1;
+ colhdr_anim.c2 = c2;
+
+ // find c1 and c2 in column list and setup coords
+ // note: columns are already swapped, so their coords must be reversed,
+ // as if before swap
+ gtkpl_column_t *c;
+ int idx = 0;
+ int x = 0;
+ for (c = pl->columns; c; c = c->next, idx++) {
+ if (idx == c1) {
+ colhdr_anim.x1 = x1;
+ colhdr_anim.dx2 = x;
+ }
+ else if (idx == c2) {
+ colhdr_anim.x2 = x2;
+ colhdr_anim.dx1 = x;
+ }
+ x += c->width;
+ }
+ colhdr_anim.anim_active = 1;
+ timeline_stop (colhdr_anim.timeline, 0);
+ timeline_init (colhdr_anim.timeline, COLHDR_ANIM_TIME, 100, colhdr_anim_cb, &colhdr_anim);
+ timeline_start (colhdr_anim.timeline);
+}
+
+// that must be called before gtk_init
+void
+gtkpl_init (void) {
+ //memcpy (colo_current, colo_system_gtk, sizeof (colo_current));
+ //memcpy (colo_current, colo_dark_orange, sizeof (colo_current));
+ play16_pixbuf = draw_load_pixbuf ("play_16.png");
+ pause16_pixbuf = draw_load_pixbuf ("pause_16.png");
+ buffering16_pixbuf = draw_load_pixbuf ("buffering_16.png");
+ rowheight = draw_get_font_size () + 12;
+ memcpy (colo_current, colo_white_blue, sizeof (colo_current));
+}
+
+void
+gtkpl_free (gtkplaylist_t *pl) {
+ if (colhdr_anim.timeline) {
+ timeline_free (colhdr_anim.timeline, 1);
+ colhdr_anim.timeline = 0;
+ }
+ while (pl->columns) {
+ gtkpl_column_t *next = pl->columns->next;
+ gtkpl_column_free (pl->columns);
+ pl->columns = next;
+ }
+}
+
+void
+theme_set_cairo_source_rgb (cairo_t *cr, int col) {
+ cairo_set_source_rgb (cr, colo_current[col][0], colo_current[col][1], colo_current[col][2]);
+}
+
+void
+theme_set_fg_color (int col) {
+ draw_set_fg_color (colo_current[col]);
+}
+
+void
+theme_set_bg_color (int col) {
+ draw_set_bg_color (colo_current[col]);
+}
+
+void
+gtkpl_setup_scrollbar (gtkplaylist_t *ps) {
+ GtkWidget *playlist = ps->playlist;
+ int h = playlist->allocation.height / rowheight;
+ int size = (*ps->pcount);
+ if (h >= size) {
+ size = 0;
+ }
+ GtkWidget *scroll = ps->scrollbar;
+ if (ps->row >= (*ps->pcount)) {
+ ps->row = (*ps->pcount) - 1;
+ }
+ if (ps->scrollpos > (*ps->pcount)-ps->nvisiblerows+1) {
+ int n = (*ps->pcount) - ps->nvisiblerows + 1;
+ ps->scrollpos = max (0, n);
+ gtk_range_set_value (GTK_RANGE (scroll), ps->scrollpos);
+ }
+ if (size == 0) {
+ gtk_widget_hide (scroll);
+ }
+ else {
+ GtkAdjustment *adj = (GtkAdjustment*)gtk_adjustment_new (gtk_range_get_value (GTK_RANGE (scroll)), 0, size, 1, h, h);
+ gtk_range_set_adjustment (GTK_RANGE (scroll), adj);
+ gtk_widget_show (scroll);
+ }
+}
+
+void
+gtkpl_setup_hscrollbar (gtkplaylist_t *ps) {
+ GtkWidget *playlist = ps->playlist;
+ int w = playlist->allocation.width;
+ int size = 0;
+ int i;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c; c = c->next) {
+ size += c->width;
+ }
+ if (w >= size) {
+ size = 0;
+ }
+ GtkWidget *scroll = ps->hscrollbar;
+ if (ps->hscrollpos >= size-w) {
+ int n = size-w-1;
+ ps->hscrollpos = max (0, n);
+ gtk_range_set_value (GTK_RANGE (scroll), ps->hscrollpos);
+ }
+ if (size == 0) {
+ gtk_widget_hide (scroll);
+ }
+ else {
+ GtkAdjustment *adj = (GtkAdjustment*)gtk_adjustment_new (gtk_range_get_value (GTK_RANGE (scroll)), 0, size, 1, w, w);
+ gtk_range_set_adjustment (GTK_RANGE (scroll), adj);
+ gtk_widget_show (scroll);
+ }
+}
+
+void
+gtkpl_redraw_pl_row_novis (gtkplaylist_t *ps, int row, playItem_t *it) {
+ draw_begin ((uintptr_t)ps->backbuf);
+ gtkpl_draw_pl_row_back (ps, row, it);
+ if (it) {
+ gtkpl_draw_pl_row (ps, row, it);
+ }
+ draw_end ();
+}
+
+void
+gtkpl_redraw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it) {
+ int x, y, w, h;
+ GtkWidget *widget = ps->playlist;
+ x = 0;
+ y = (row - ps->scrollpos) * rowheight;
+ w = widget->allocation.width;
+ h = rowheight;
+
+ gtkpl_redraw_pl_row_novis (ps, row, it);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, x, y, x, y, w, h);
+}
+
+void
+gtkpl_draw_pl_row_back (gtkplaylist_t *ps, int row, playItem_t *it) {
+ // draw background
+ float w;
+ int start, end;
+ int startx, endx;
+ int width, height;
+ draw_get_canvas_size ((uintptr_t)ps->backbuf, &width, &height);
+ w = width;
+ if (it && ((it->selected && ps->multisel) || (row == ps->row && !ps->multisel))) {
+ if (row % 2) {
+ theme_set_fg_color (COLO_PLAYLIST_SEL_EVEN);
+ }
+ else {
+ theme_set_fg_color (COLO_PLAYLIST_SEL_ODD);
+ }
+ draw_rect (0, row * rowheight - ps->scrollpos * rowheight, width, rowheight, 1);
+ }
+ else {
+ if (row % 2) {
+ theme_set_fg_color (COLO_PLAYLIST_EVEN);
+ }
+ else {
+ theme_set_fg_color (COLO_PLAYLIST_ODD);
+ }
+ draw_rect (0, row * rowheight - ps->scrollpos * rowheight, width, rowheight, 1);
+ }
+ if (row == ps->row) {
+ theme_set_fg_color (COLO_PLAYLIST_CURSOR);
+ draw_rect (0, row * rowheight - ps->scrollpos * rowheight, width, rowheight-1, 0);
+ }
+}
+
+void
+gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it) {
+ if (row-ps->scrollpos >= ps->nvisiblerows || row-ps->scrollpos < 0) {
+// fprintf (stderr, "WARNING: attempt to draw row outside of screen bounds (%d)\n", row-ps->scrollpos);
+ return;
+ }
+ int width, height;
+ draw_get_canvas_size ((uintptr_t)ps->backbuf, &width, &height);
+ if (it && ((it->selected && ps->multisel) || (row == ps->row && !ps->multisel))) {
+ if (row % 2) {
+ theme_set_bg_color (COLO_PLAYLIST_SEL_EVEN);
+ }
+ else {
+ theme_set_bg_color (COLO_PLAYLIST_SEL_ODD);
+ }
+ theme_set_fg_color (COLO_PLAYLIST_SEL_TEXT);
+ }
+ else {
+ if (row % 2) {
+ theme_set_bg_color (COLO_PLAYLIST_EVEN);
+ }
+ else {
+ theme_set_bg_color (COLO_PLAYLIST_ODD);
+ }
+ theme_set_fg_color (COLO_PLAYLIST_TEXT);
+ }
+ // draw as columns
+ char dur[50];
+ pl_format_title (it, dur, sizeof (dur), "%l");
+
+ const char *artist = pl_find_meta (it, "artist");
+ if (!artist) {
+ artist = "?";
+ }
+ const char *album = pl_find_meta (it, "album");
+ if (!album) {
+ album = "?";
+ }
+ const char *track = pl_find_meta (it, "track");
+ if (!track) {
+ track = "";
+ }
+ const char *title = pl_find_meta (it, "title");
+ if (!title) {
+ title = "?";
+ }
+ char artistalbum[1024];
+ pl_format_title (it, artistalbum, sizeof (artistalbum), "%a - %b");
+#if 0
+ const char *columns[pl_ncolumns] = {
+ "",
+ artistalbum,
+ track,
+ title,
+ dur
+ };
+#endif
+ int x = -ps->hscrollpos;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c; c = c->next) {
+ if (it == playlist_current_ptr && c->id == DB_COLUMN_PLAYING/* && !p_isstopped ()*/) {
+ int paused = p_ispaused ();
+ int buffering = !streamer_ok_to_read (-1);
+ uintptr_t pixbuf;
+ if (paused) {
+ pixbuf = pause16_pixbuf;
+ }
+ else if (!buffering) {
+ pixbuf = play16_pixbuf;
+ }
+ else {
+ pixbuf = buffering16_pixbuf;
+ }
+ draw_pixbuf ((uintptr_t)ps->backbuf, pixbuf, x + c->width/2 - 8 - ps->hscrollpos, (row - ps->scrollpos) * rowheight + rowheight/2 - 8, 0, 0, 16, 16);
+ }
+ else {
+ char fmt_text[1024];
+ const char *text = NULL;
+ if (c->id != -1) {
+ switch (c->id) {
+ case DB_COLUMN_ARTIST_ALBUM:
+ text = artistalbum;
+ break;
+ case DB_COLUMN_ARTIST:
+ text = artist;
+ break;
+ case DB_COLUMN_ALBUM:
+ text = album;
+ break;
+ case DB_COLUMN_TITLE:
+ text = title;
+ break;
+ case DB_COLUMN_DURATION:
+ text = dur;
+ break;
+ case DB_COLUMN_TRACK:
+ text = track;
+ break;
+ }
+ }
+ else if (c->format) {
+ pl_format_title (it, fmt_text, sizeof (fmt_text), c->format);
+ text = fmt_text;
+ }
+ if (text) {
+ if (c->align_right) {
+ draw_text_with_colors (x+5, row * rowheight - ps->scrollpos * rowheight + rowheight/2 - draw_get_font_size ()/2 - 2, c->width-10, 1, text);
+ }
+ else {
+ draw_text_with_colors (x + 5, row * rowheight - ps->scrollpos * rowheight + rowheight/2 - draw_get_font_size ()/2 - 2, c->width-10, 0, text);
+ }
+ }
+ }
+ x += c->width;
+ }
+}
+
+
+void
+gtkpl_draw_playlist (gtkplaylist_t *ps, int x, int y, int w, int h) {
+ GtkWidget *widget = ps->playlist;
+ if (!ps->backbuf) {
+ return;
+ }
+ draw_begin ((uintptr_t)ps->backbuf);
+ int row;
+ int row1;
+ int row2;
+ int row2_full;
+ row1 = max (0, y / rowheight + ps->scrollpos);
+ row2 = min ((*ps->pcount), (y+h) / rowheight + ps->scrollpos + 1);
+ row2_full = (y+h) / rowheight + ps->scrollpos + 1;
+ // draw background
+ playItem_t *it = gtkpl_get_for_idx (ps, ps->scrollpos);
+ playItem_t *it_copy = it;
+ for (row = row1; row < row2_full; row++) {
+ gtkpl_draw_pl_row_back (ps, row, it);
+ if (it) {
+ it = it->next[ps->iterator];
+ }
+ }
+ it = it_copy;
+ int idx = 0;
+ for (row = row1; row < row2; row++, idx++) {
+ gtkpl_draw_pl_row (ps, row, it);
+ it = it->next[ps->iterator];
+ }
+
+ draw_end ();
+}
+
+void
+gtkpl_configure (gtkplaylist_t *ps) {
+ gtkpl_setup_scrollbar (ps);
+ gtkpl_setup_hscrollbar (ps);
+ GtkWidget *widget = ps->playlist;
+ if (ps->backbuf) {
+ g_object_unref (ps->backbuf);
+ ps->backbuf = NULL;
+ }
+ ps->nvisiblerows = ceil (widget->allocation.height / (float)rowheight);
+ ps->nvisiblefullrows = floor (widget->allocation.height / (float)rowheight);
+ ps->backbuf = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+}
+
+// change properties
+gboolean
+on_playlist_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+// extern void main_playlist_init (GtkWidget *widget);
+// main_playlist_init (widget);
+ GTKPL_PROLOGUE;
+ gtkpl_configure (ps);
+ return FALSE;
+}
+
+void
+gtkpl_expose (gtkplaylist_t *ps, int x, int y, int w, int h) {
+ GtkWidget *widget = ps->playlist;
+ if (widget->window) {
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, x, y, x, y, w, h);
+ }
+}
+
+void
+gtkpl_expose_header (gtkplaylist_t *ps, int x, int y, int w, int h) {
+ GtkWidget *widget = ps->header;
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf_header, x, y, x, y, w, h);
+}
+
+void
+gtkpl_select_single (gtkplaylist_t *ps, int sel) {
+ if (!ps->multisel) {
+ return;
+ }
+ int idx=0;
+ GtkWidget *widget = ps->playlist;
+ for (playItem_t *it = playlist_head[ps->iterator]; it; it = it->next[ps->iterator], idx++) {
+ if (idx == sel) {
+ if (!it->selected) {
+ it->selected = 1;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+ else if (it->selected) {
+ it->selected = 0;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+}
+
+// {{{ expected behaviour for mouse1 without modifiers:
+// {{{ [+] if clicked unselected item:
+// unselect all
+// select clicked item
+// ps->row = clicked
+// redraw
+// start 'area selection' mode
+// }}}
+// {{{ [+] if clicked selected item:
+// ps->row = clicked
+// redraw
+// wait until next release or motion event, whichever is 1st
+// if release is 1st:
+// unselect all except clicked, redraw
+// else if motion is 1st:
+// enter drag-drop mode
+// }}}
+// }}}
+static int areaselect = 0;
+static int areaselect_x = -1;
+static int areaselect_y = -1;
+static int areaselect_dx = -1;
+static int areaselect_dy = -1;
+static int dragwait = 0;
+static int shift_sel_anchor = -1;
+
+void
+gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) {
+ // cursor must be set here, but selection must be handled in keyrelease
+ if ((*ps->pcount) == 0) {
+ return;
+ }
+ GtkWidget *widget = ps->playlist;
+ // remember mouse coords for doubleclick detection
+ ps->lastpos[0] = ex;
+ ps->lastpos[1] = ey;
+ // select item
+ int y = ey/rowheight + ps->scrollpos;
+ if (y < 0 || y >= (*ps->pcount)) {
+ y = -1;
+ }
+
+ if (time - ps->clicktime < 0.5
+ && fabs(ps->lastpos[0] - ex) < 3
+ && fabs(ps->lastpos[1] - ey) < 3) {
+ // doubleclick - play this item
+ if (ps->row != -1) {
+ playItem_t *it = gtkpl_get_for_idx (ps, ps->row);
+ it->selected = 1;
+ int r = pl_get_idx_of (it);
+ int prev = main_playlist.row;
+ if (prev != r) {
+ main_playlist.row = r;
+ if (prev != -1) {
+ gtkpl_redraw_pl_row (&main_playlist, prev, pl_get_for_idx (prev));
+ }
+ if (r != -1) {
+ gtkpl_redraw_pl_row (&main_playlist, r, it);
+ }
+ }
+ messagepump_push (M_PLAYSONGNUM, 0, r, 0);
+ return;
+ }
+
+ // prevent next click to trigger doubleclick
+ ps->clicktime = time-1;
+ }
+ else {
+ ps->clicktime = time;
+ }
+
+ int sel = y;
+ if (y == -1) {
+ y = (*ps->pcount) - 1;
+ }
+ int prev = ps->row;
+ ps->row = y;
+ shift_sel_anchor = ps->row;
+ // handle multiple selection
+ if (ps->multisel) {
+ if (!(state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)))
+ {
+ playItem_t *it = gtkpl_get_for_idx (ps, sel);
+ if (!it || !it->selected) {
+ // reset selection, and set it to single item
+ gtkpl_select_single (ps, sel);
+ areaselect = 1;
+ areaselect_x = ex;
+ areaselect_y = ey;
+ areaselect_dx = -1;
+ areaselect_dy = -1;
+ shift_sel_anchor = ps->row;
+ }
+ else {
+ dragwait = 1;
+ gtkpl_redraw_pl_row (ps, prev, gtkpl_get_for_idx (ps, prev));
+ if (ps->row != prev) {
+ gtkpl_redraw_pl_row (ps, ps->row, gtkpl_get_for_idx (ps, ps->row));
+ }
+ }
+ }
+ else if (state & GDK_CONTROL_MASK) {
+ // toggle selection
+ if (y != -1) {
+ playItem_t *it = gtkpl_get_for_idx (ps, y);
+ if (it) {
+ it->selected = 1 - it->selected;
+ gtkpl_redraw_pl_row (ps, y, it);
+ }
+ }
+ }
+ else if (state & GDK_SHIFT_MASK) {
+ // select range
+ int start = min (prev, ps->row);
+ int end = max (prev, ps->row);
+ int idx = 0;
+ for (playItem_t *it = playlist_head[ps->iterator]; it; it = it->next[ps->iterator], idx++) {
+ if (idx >= start && idx <= end) {
+ if (!it->selected) {
+ it->selected = 1;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+ else {
+ if (it->selected) {
+ it->selected = 0;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+ }
+ }
+ if (ps->row != -1 && sel == -1) {
+ gtkpl_redraw_pl_row (ps, ps->row, gtkpl_get_for_idx (ps, ps->row));
+ }
+ }
+ else {
+ if (ps->row != -1) {
+ gtkpl_redraw_pl_row (ps, ps->row, gtkpl_get_for_idx (ps, ps->row));
+ }
+ }
+ if (prev != -1 && prev != ps->row) {
+ gtkpl_redraw_pl_row (ps, prev, gtkpl_get_for_idx (ps, prev));
+ }
+
+}
+
+void
+gtkpl_mouse1_released (gtkplaylist_t *ps, int state, int ex, int ey, double time) {
+ if (dragwait) {
+ dragwait = 0;
+ int y = ey/rowheight + ps->scrollpos;
+ gtkpl_select_single (ps, y);
+ }
+ else if (areaselect) {
+ playlist_scroll_direction = 0;
+ playlist_scroll_pointer_y = -1;
+ areaselect = 0;
+ }
+}
+
+#if 0
+void
+gtkpl_draw_areasel (GtkWidget *widget, int x, int y) {
+ // erase previous rect using 4 blits from ps->backbuffer
+ if (areaselect_dx != -1) {
+ int sx = min (areaselect_x, areaselect_dx);
+ int sy = min (areaselect_y, areaselect_dy);
+ int dx = max (areaselect_x, areaselect_dx);
+ int dy = max (areaselect_y, areaselect_dy);
+ int w = dx - sx + 1;
+ int h = dy - sy + 1;
+ //gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, dx - sx + 1, dy - sy + 1);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, w, 1);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy, sx, sy, 1, h);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx, sy + h - 1, sx, sy + h - 1, w, 1);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, sx + w - 1, sy, sx + w - 1, sy, 1, h);
+ }
+ areaselect_dx = x;
+ areaselect_dy = y;
+ cairo_t *cr;
+ cr = gdk_cairo_create (widget->window);
+ if (!cr) {
+ return;
+ }
+ theme_set_fg_color (COLO_PLAYLIST_CURSOR);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_line_width (cr, 1);
+ int sx = min (areaselect_x, x);
+ int sy = min (areaselect_y, y);
+ int dx = max (areaselect_x, x);
+ int dy = max (areaselect_y, y);
+ cairo_rectangle (cr, sx, sy, dx-sx, dy-sy);
+ cairo_stroke (cr);
+ gtkpl_cairo_destroy (cr);
+}
+#endif
+
+static gboolean
+gtkpl_scroll_playlist_cb (gpointer data) {
+ gtkplaylist_t *ps = (gtkplaylist_t *)data;
+ playlist_scroll_active = 1;
+ struct timeval tm;
+ gettimeofday (&tm, NULL);
+ if (tm.tv_sec - tm_prevscroll.tv_sec + (tm.tv_usec - tm_prevscroll.tv_usec) / 1000000.0 < scroll_sleep_time) {
+ return TRUE;
+ }
+ memcpy (&tm_prevscroll, &tm, sizeof (tm));
+ if (playlist_scroll_pointer_y == -1) {
+ playlist_scroll_active = 0;
+ return FALSE;
+ }
+ if (playlist_scroll_direction == 0) {
+ playlist_scroll_active = 0;
+ return FALSE;
+ }
+ int sc = ps->scrollpos + playlist_scroll_direction;
+ if (sc < 0) {
+ playlist_scroll_active = 0;
+ return FALSE;
+ }
+ if (sc >= *ps->pcount) {
+ playlist_scroll_active = 0;
+ return FALSE;
+ }
+ GDK_THREADS_ENTER ();
+ gtk_range_set_value (GTK_RANGE (ps->scrollbar), sc);
+ if (playlist_scroll_mode == 0) {
+ GdkEventMotion ev;
+ ev.y = playlist_scroll_pointer_y;
+ gtkpl_mousemove (ps, &ev);
+ }
+ else if (playlist_scroll_mode == 1) {
+ gtkpl_track_dragdrop (ps, playlist_scroll_pointer_y);
+ }
+ GDK_THREADS_LEAVE ();
+ scroll_sleep_time -= 0.1;
+ if (scroll_sleep_time < 0.05) {
+ scroll_sleep_time = 0.05;
+ }
+ return TRUE;
+}
+
+void
+gtkpl_mousemove (gtkplaylist_t *ps, GdkEventMotion *event) {
+ if (dragwait) {
+ GtkWidget *widget = ps->playlist;
+ if (gtk_drag_check_threshold (widget, ps->lastpos[0], event->x, ps->lastpos[1], event->y)) {
+ dragwait = 0;
+ GtkTargetEntry entry = {
+ .target = "STRING",
+ .flags = GTK_TARGET_SAME_WIDGET,
+ .info = TARGET_SAMEWIDGET
+ };
+ GtkTargetList *lst = gtk_target_list_new (&entry, 1);
+ gtk_drag_begin (widget, lst, GDK_ACTION_MOVE, TARGET_SAMEWIDGET, (GdkEvent *)event);
+ }
+ }
+ else if (areaselect) {
+ GtkWidget *widget = ps->playlist;
+ int y = event->y/rowheight + ps->scrollpos;
+ //if (y != shift_sel_anchor)
+ {
+ int start = min (y, shift_sel_anchor);
+ int end = max (y, shift_sel_anchor);
+ int idx=0;
+ for (playItem_t *it = playlist_head[ps->iterator]; it; it = it->next[ps->iterator], idx++) {
+ if (idx >= start && idx <= end) {
+ if (!it->selected) {
+ it->selected = 1;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+ else if (it->selected) {
+ it->selected = 0;
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ }
+ }
+
+ if (event->y < 10) {
+ playlist_scroll_mode = 0;
+ playlist_scroll_pointer_y = event->y;
+ playlist_scroll_direction = -1;
+ // start scrolling up
+ if (!playlist_scroll_active) {
+ scroll_sleep_time = 0.2;
+ gettimeofday (&tm_prevscroll, NULL);
+ g_idle_add (gtkpl_scroll_playlist_cb, ps);
+ }
+ }
+ else if (event->y > ps->playlist->allocation.height-10) {
+ playlist_scroll_mode = 0;
+ playlist_scroll_pointer_y = event->y;
+ playlist_scroll_direction = 1;
+ // start scrolling up
+ if (!playlist_scroll_active) {
+ scroll_sleep_time = 0.2;
+ gettimeofday (&tm_prevscroll, NULL);
+ g_idle_add (gtkpl_scroll_playlist_cb, ps);
+ }
+ }
+ else {
+ playlist_scroll_direction = 0;
+ playlist_scroll_pointer_y = -1;
+ }
+ // debug only
+ // gtkpl_draw_areasel (widget, event->x, event->y);
+ }
+}
+
+void
+gtkpl_handle_scroll_event (gtkplaylist_t *ps, int direction) {
+ GtkWidget *range = ps->scrollbar;;
+ GtkWidget *playlist = ps->playlist;
+ int h = playlist->allocation.height / rowheight;
+ int size = (*ps->pcount);
+ if (h >= size) {
+ size = 0;
+ }
+ if (size == 0) {
+ return;
+ }
+ // pass event to scrollbar
+ GtkAdjustment* adj = gtk_range_get_adjustment (GTK_RANGE (range));
+ int newscroll = gtk_range_get_value (GTK_RANGE (range));
+ if (direction == GDK_SCROLL_UP) {
+ newscroll -= 2;
+ }
+ else if (direction == GDK_SCROLL_DOWN) {
+ newscroll += 2;
+ }
+ gtk_range_set_value (GTK_RANGE (range), newscroll);
+}
+
+void
+gtkpl_scroll (gtkplaylist_t *ps, int newscroll) {
+ if (newscroll != ps->scrollpos) {
+ GtkWidget *widget = ps->playlist;
+ int di = newscroll - ps->scrollpos;
+ int d = abs (di);
+ if (d < ps->nvisiblerows) {
+ if (di > 0) {
+ gdk_draw_drawable (ps->backbuf, widget->style->black_gc, ps->backbuf, 0, d * rowheight, 0, 0, widget->allocation.width, widget->allocation.height-d * rowheight);
+ int i;
+ ps->scrollpos = newscroll;
+ int start = ps->nvisiblerows-d-1;
+ start = max (0, ps->nvisiblerows-d-1);
+ for (i = start; i <= ps->nvisiblerows; i++) {
+ gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, gtkpl_get_for_idx (ps, i+ps->scrollpos));
+ }
+ }
+ else {
+ gdk_draw_drawable (ps->backbuf, widget->style->black_gc, ps->backbuf, 0, 0, 0, d*rowheight, widget->allocation.width, widget->allocation.height);
+ ps->scrollpos = newscroll;
+ int i;
+ for (i = 0; i <= d+1; i++) {
+ gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, gtkpl_get_for_idx (ps, i+ps->scrollpos));
+ }
+ }
+ }
+ else {
+ ps->scrollpos = newscroll;
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+}
+
+void
+gtkpl_hscroll (gtkplaylist_t *ps, int newscroll) {
+ if (newscroll != ps->hscrollpos) {
+ ps->hscrollpos = newscroll;
+ GtkWidget *widget = ps->playlist;
+ gtkpl_header_draw (ps);
+ gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+}
+
+void
+gtkpl_randomsong (void) {
+ p_stop ();
+ pl_randomsong ();
+}
+
+void
+gtkpl_playsongnum (int idx) {
+ p_stop ();
+ streamer_set_nextsong (idx, 1);
+}
+
+void
+gtkpl_songchanged (gtkplaylist_t *ps, int from, int to) {
+ if (!dragwait && to != -1) {
+ GtkWidget *widget = ps->playlist;
+ if (conf_get_int ("playlist.scroll.followplayback", 0)) {
+ if (to < ps->scrollpos || to >= ps->scrollpos + ps->nvisiblefullrows) {
+ gtk_range_set_value (GTK_RANGE (ps->scrollbar), to - ps->nvisiblerows/2);
+ }
+ }
+ }
+
+ if (from >= 0) {
+ gtkpl_redraw_pl_row (ps, from, gtkpl_get_for_idx (ps, from));
+ }
+ if (to >= 0) {
+ gtkpl_redraw_pl_row (ps, to, gtkpl_get_for_idx (ps, to));
+ }
+}
+
+void
+gtkpl_keypress (gtkplaylist_t *ps, int keyval, int state) {
+ GtkWidget *widget = ps->playlist;
+ GtkWidget *range = ps->scrollbar;
+ int prev = ps->row;
+ int newscroll = ps->scrollpos;
+// C-f is now handled by gtk
+// if ((keyval == GDK_F || keyval == GDK_f) && (state & GDK_CONTROL_MASK)) {
+// search_start ();
+// }
+// else
+// if ((keyval == GDK_A || keyval == GDK_a) && (state & GDK_CONTROL_MASK)) {
+// // select all
+// pl_select_all ();
+// gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+// gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
+// return;
+// }
+// else if ((keyval == GDK_P || keyval == GDK_p) && (state & GDK_CONTROL_MASK)) {
+// messagepump_push (M_PAUSESONG, 0, 0, 0);
+// }
+// else
+// if (keyval == GDK_Return && ps->row != -1) {
+// messagepump_push (M_PLAYSONGNUM, 0, ps->row, 0);
+// return;
+// }
+// else
+// if (keyval == GDK_Delete) {
+// pl_delete_selected ();
+// playlist_refresh ();
+// return;
+// }
+// else
+ if (keyval == GDK_Down && ps->row < (*ps->pcount) - 1) {
+ ps->row++;
+ if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) {
+ newscroll = ps->row - widget->allocation.height / rowheight + 1;
+ }
+ }
+ else if (keyval == GDK_r) {
+ extern int replaygain;
+ replaygain = 1-replaygain;
+ fprintf (stderr, "replaygain=%d\n", replaygain);
+ }
+ else if (keyval == GDK_t) {
+ extern int replaygain_scale;
+ replaygain_scale = 1-replaygain_scale;
+ fprintf (stderr, "replaygain_scale=%d\n", replaygain_scale);
+ }
+ else if (keyval == GDK_Up && ps->row > 0) {
+ ps->row--;
+ if (ps->row < ps->scrollpos) {
+ newscroll = ps->row;
+ }
+ }
+ else if (keyval == GDK_Page_Down && ps->row < (*ps->pcount) - 1) {
+ ps->row += 10;
+ if (ps->row >= (*ps->pcount)) {
+ ps->row = (*ps->pcount) - 1;
+ }
+ if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) {
+ newscroll = ps->row - widget->allocation.height / rowheight + 1;
+ }
+ }
+ else if (keyval == GDK_Page_Up && ps->row > 0) {
+ ps->row -= 10;
+ if (ps->row < 0) {
+ ps->row = 0;
+ }
+ if (ps->row < ps->scrollpos) {
+ newscroll = ps->row;
+ }
+ }
+ else if (keyval == GDK_End && ps->row != (*ps->pcount) - 1) {
+ ps->row = (*ps->pcount) - 1;
+ if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) {
+ newscroll = ps->row - widget->allocation.height / rowheight + 1;
+ }
+ }
+ else if (keyval == GDK_Home && ps->row != 0) {
+ ps->row = 0;
+ if (ps->row < ps->scrollpos) {
+ newscroll = ps->row;
+ }
+ }
+ if (state & GDK_SHIFT_MASK) {
+ // select all between shift_sel_anchor and ps->row
+ if (prev != ps->row) {
+ int minvis = ps->scrollpos;
+ int maxvis = ps->scrollpos + ps->nvisiblerows-1;
+ int start = min (ps->row, shift_sel_anchor);
+ int end = max (ps->row, shift_sel_anchor);
+ int idx=0;
+ for (playItem_t *it = playlist_head[ps->iterator]; it; it = it->next[ps->iterator], idx++) {
+ if (idx >= start && idx <= end) {
+ it->selected = 1;
+ if (idx >= minvis && idx <= maxvis) {
+ if (newscroll == ps->scrollpos) {
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ else {
+ gtkpl_redraw_pl_row_novis (ps, idx, it);
+ }
+ }
+ }
+ else if (it->selected)
+ {
+ it->selected = 0;
+ if (idx >= minvis && idx <= maxvis) {
+ if (newscroll == ps->scrollpos) {
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ else {
+ gtkpl_redraw_pl_row_novis (ps, idx, it);
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ // reset selection, set new single cursor/selection
+ if (prev != ps->row) {
+ int minvis = ps->scrollpos;
+ int maxvis = ps->scrollpos + ps->nvisiblerows-1;
+ shift_sel_anchor = ps->row;
+ int idx=0;
+ for (playItem_t *it = playlist_head[ps->iterator]; it; it = it->next[ps->iterator], idx++) {
+ if (idx == ps->row) {
+ if (!it->selected) {
+ it->selected = 1;
+ if (idx >= minvis && idx <= maxvis) {
+ if (newscroll == ps->scrollpos) {
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ else {
+ gtkpl_redraw_pl_row_novis (ps, idx, it);
+ }
+ }
+ }
+ }
+ else if (it->selected) {
+ it->selected = 0;
+ if (idx >= minvis && idx <= maxvis) {
+ if (newscroll == ps->scrollpos) {
+ gtkpl_redraw_pl_row (ps, idx, it);
+ }
+ else {
+ gtkpl_redraw_pl_row_novis (ps, idx, it);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (newscroll != ps->scrollpos) {
+ gtk_range_set_value (GTK_RANGE (range), newscroll);
+ }
+}
+
+static int drag_motion_y = -1;
+
+void
+gtkpl_track_dragdrop (gtkplaylist_t *ps, int y) {
+ GtkWidget *widget = ps->playlist;
+ if (drag_motion_y != -1) {
+ // erase previous track
+ gdk_draw_drawable (widget->window, widget->style->black_gc, ps->backbuf, 0, drag_motion_y * rowheight-3, 0, drag_motion_y * rowheight-3, widget->allocation.width, 7);
+
+ }
+ if (y == -1) {
+ drag_motion_y = -1;
+ return;
+ }
+ draw_begin ((uintptr_t)widget->window);
+ drag_motion_y = y / rowheight;
+
+ theme_set_fg_color (COLO_DRAGDROP_MARKER);
+ draw_rect (0, drag_motion_y * rowheight-1, widget->allocation.width, 3, 1);
+ draw_rect (0, drag_motion_y * rowheight-3, 3, 7, 1);
+ draw_rect (widget->allocation.width-3, drag_motion_y * rowheight-3, 3, 7, 1);
+ draw_end ();
+ if (y < 10) {
+ playlist_scroll_pointer_y = y;
+ playlist_scroll_direction = -1;
+ playlist_scroll_mode = 1;
+ // start scrolling up
+ if (!playlist_scroll_active) {
+ scroll_sleep_time = 0.2;
+ gettimeofday (&tm_prevscroll, NULL);
+ g_idle_add (gtkpl_scroll_playlist_cb, ps);
+ }
+ }
+ else if (y > ps->playlist->allocation.height-10) {
+ playlist_scroll_mode = 1;
+ playlist_scroll_pointer_y = y;
+ playlist_scroll_direction = 1;
+ // start scrolling up
+ if (!playlist_scroll_active) {
+ scroll_sleep_time = 0.2;
+ gettimeofday (&tm_prevscroll, NULL);
+ g_idle_add (gtkpl_scroll_playlist_cb, ps);
+ }
+ }
+ else {
+ playlist_scroll_direction = 0;
+ playlist_scroll_pointer_y = -1;
+ }
+}
+
+void
+gtkpl_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length) {
+ int drop_row = drop_y / rowheight + ps->scrollpos;
+ playItem_t *drop_before = gtkpl_get_for_idx (ps, drop_row);
+ while (drop_before && drop_before->selected) {
+ drop_before = drop_before->next[ps->iterator];
+ }
+ // unlink items from playlist, and link together
+ playItem_t *head = NULL;
+ playItem_t *tail = NULL;
+ int processed = 0;
+ int idx = 0;
+ playItem_t *next = NULL;
+ for (playItem_t *it = playlist_head[ps->iterator]; it && processed < length; it = next, idx++) {
+ next = it->next[ps->iterator];
+ if (idx == d[processed]) {
+ if (it->prev[ps->iterator]) {
+ it->prev[ps->iterator]->next[ps->iterator] = it->next[ps->iterator];
+ }
+ else {
+ playlist_head[ps->iterator] = it->next[ps->iterator];
+ }
+ if (it->next[ps->iterator]) {
+ it->next[ps->iterator]->prev[ps->iterator] = it->prev[ps->iterator];
+ }
+ else {
+ playlist_tail[ps->iterator] = it->prev[ps->iterator];
+ }
+ if (tail) {
+ tail->next[ps->iterator] = it;
+ it->prev[ps->iterator] = tail;
+ tail = it;
+ }
+ else {
+ head = tail = it;
+ it->prev[ps->iterator] = it->next[ps->iterator] = NULL;
+ }
+ processed++;
+ }
+ }
+ // find insertion point
+ playItem_t *drop_after = NULL;
+ if (drop_before) {
+ drop_after = drop_before->prev[ps->iterator];
+ }
+ else {
+ drop_after = playlist_tail[ps->iterator];
+ }
+ // insert in between
+ head->prev[ps->iterator] = drop_after;
+ if (drop_after) {
+ drop_after->next[ps->iterator] = head;
+ }
+ else {
+ playlist_head[ps->iterator] = head;
+ }
+ tail->next[ps->iterator] = drop_before;
+ if (drop_before) {
+ drop_before->prev[ps->iterator] = tail;
+ }
+ else {
+ playlist_tail[ps->iterator] = tail;
+ }
+}
+
+void
+on_playlist_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ // invalidate entire cache - slow, but rare
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ playlist_scroll_direction = 0;
+ playlist_scroll_pointer_y = -1;
+}
+
+void
+strcopy_special (char *dest, const char *src, int len) {
+ while (len > 0) {
+ if (*src == '%' && len >= 3) {
+ int charcode = 0;
+ int byte;
+ byte = tolower (src[2]);
+ if (byte >= '0' && byte <= '9') {
+ charcode = byte - '0';
+ }
+ else if (byte >= 'a' && byte <= 'f') {
+ charcode = byte - 'a' + 10;
+ }
+ else {
+ charcode = '?';
+ }
+ if (charcode != '?') {
+ byte = tolower (src[1]);
+ if (byte >= '0' && byte <= '9') {
+ charcode |= (byte - '0') << 4;
+ }
+ else if (byte >= 'a' && byte <= 'f') {
+ charcode |= (byte - 'a' + 10) << 4;
+ }
+ else {
+ charcode = '?';
+ }
+ }
+ *dest = charcode;
+ dest++;
+ src += 3;
+ len -= 3;
+ continue;
+ }
+ else {
+ *dest++ = *src++;
+ len--;
+ }
+ }
+ *dest = 0;
+}
+
+int
+gtkpl_add_file_info_cb (playItem_t *it, void *data) {
+ if (progress_is_aborted ()) {
+ return -1;
+ }
+ GDK_THREADS_ENTER();
+ progress_settext (it->fname);
+ GDK_THREADS_LEAVE();
+#if 0
+ GtkEntry *e = (GtkEntry *)data;
+ GDK_THREADS_ENTER();
+ gtk_entry_set_text (GTK_ENTRY (e), it->fname);
+ GDK_THREADS_LEAVE();
+ usleep (100);
+ countdown = 10;
+#endif
+ return 0;
+}
+
+void
+gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y) {
+ GDK_THREADS_ENTER();
+ progress_show ();
+ GDK_THREADS_LEAVE();
+
+ int drop_row = drop_y / rowheight + ps->scrollpos;
+ playItem_t *drop_before = gtkpl_get_for_idx (ps, drop_row);
+ playItem_t *after = NULL;
+ if (drop_before) {
+ after = drop_before->prev[ps->iterator];
+ }
+ else {
+ after = playlist_tail[ps->iterator];
+ }
+ const uint8_t *p = (const uint8_t*)ptr;
+ while (*p) {
+ const uint8_t *pe = p;
+ while (*pe && *pe > ' ') {
+ pe++;
+ }
+ if (pe - p < 4096 && pe - p > 7) {
+ char fname[(int)(pe - p)];
+ strcopy_special (fname, p, pe-p);
+ //strncpy (fname, p, pe - p);
+ //fname[pe - p] = 0;
+ int abort = 0;
+ playItem_t *inserted = pl_insert_dir (after, fname, &abort, gtkpl_add_file_info_cb, NULL);
+ if (!inserted && !abort) {
+ inserted = pl_insert_file (after, fname, &abort, gtkpl_add_file_info_cb, NULL);
+ }
+ if (inserted) {
+ after = inserted;
+ }
+ }
+ p = pe;
+ // skip whitespace
+ while (*p && *p <= ' ') {
+ p++;
+ }
+ }
+ free (ptr);
+
+ GDK_THREADS_ENTER();
+ progress_hide ();
+ playlist_refresh ();
+ GDK_THREADS_LEAVE();
+}
+
+void
+gtkpl_handle_fm_drag_drop (gtkplaylist_t *ps, int drop_y, void *ptr, int length) {
+ // this happens when dropped from file manager
+ char *mem = malloc (length+1);
+ memcpy (mem, ptr, length);
+ mem[length] = 0;
+ // we don't pass control structure, but there's only one drag-drop view currently
+ messagepump_push (M_FMDRAGDROP, (uintptr_t)mem, length, drop_y);
+}
+
+void
+gtkpl_header_draw (gtkplaylist_t *ps) {
+ GtkWidget *widget = ps->header;
+ int x = -ps->hscrollpos;
+ int w = 100;
+ int h = widget->allocation.height;
+ const char *detail = "toolbar";
+
+ // fill background
+ gtk_paint_box (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, NULL, detail, 0, 0, widget->allocation.width, widget->allocation.height);
+ draw_begin ((uintptr_t)ps->backbuf_header);
+ x = -ps->hscrollpos;
+ gtkpl_column_t *c;
+ int need_draw_moving = 0;
+ int idx = 0;
+ for (c = ps->columns; c; c = c->next, idx++) {
+ w = c->width;
+ int xx = x;
+ if (colhdr_anim.anim_active) {
+ if (idx == colhdr_anim.c2) {
+ xx = colhdr_anim.ax1;
+ }
+ else if (idx == colhdr_anim.c1) {
+ xx = colhdr_anim.ax2;
+ }
+ }
+ if (header_dragging < 0 || idx != header_dragging) {
+ if (xx >= widget->allocation.width) {
+ continue;
+ }
+ if (w > 0) {
+ gtk_paint_vline (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, NULL, NULL, NULL, 0, h, xx+w - 2);
+ GdkColor *gdkfg = &widget->style->fg[0];
+ float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff};
+ draw_set_fg_color (fg);
+ draw_text (xx + 5, h/2-draw_get_font_size()/2, c->width-10, 0, c->title);
+ }
+ }
+ else {
+ need_draw_moving = 1;
+ }
+ x += w;
+ }
+ if (need_draw_moving) {
+ x = -ps->hscrollpos;
+ idx = 0;
+ for (c = ps->columns; c; c = c->next, idx++) {
+ w = c->width;
+ if (idx == header_dragging) {
+ if (colhdr_anim.anim_active) {
+ if (idx == colhdr_anim.c2) {
+ x = colhdr_anim.ax1;
+ }
+ else if (idx == colhdr_anim.c1) {
+ x = colhdr_anim.ax2;
+ }
+ }
+ // draw empty slot
+ if (x < widget->allocation.width) {
+ gtk_paint_box (widget->style, ps->backbuf_header, GTK_STATE_ACTIVE, GTK_SHADOW_ETCHED_IN, NULL, NULL, "button", x, 0, w, h);
+ }
+ x = c->movepos;
+ if (x >= widget->allocation.width) {
+ break;
+ }
+ if (w > 0) {
+ gtk_paint_box (widget->style, ps->backbuf_header, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, NULL, "button", x, 0, w, h);
+ GdkColor *gdkfg = &widget->style->fg[0];
+ float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff};
+ draw_set_fg_color (fg);
+ draw_text (x + 5, h/2-draw_get_font_size()/2, c->width-10, 0, c->title);
+ }
+ break;
+ }
+ x += w;
+ }
+ }
+ draw_end ();
+}
+
+gboolean
+on_header_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ gtkpl_header_draw (ps);
+ gtkpl_expose_header (ps, event->area.x, event->area.y, event->area.width, event->area.height);
+ return FALSE;
+}
+
+
+gboolean
+on_header_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (ps->backbuf_header) {
+ g_object_unref (ps->backbuf_header);
+ ps->backbuf_header = NULL;
+ }
+ ps->backbuf_header = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+ gtkpl_header_draw (ps);
+ return FALSE;
+}
+
+
+void
+on_header_realize (GtkWidget *widget,
+ gpointer user_data)
+{
+ // create cursor for sizing headers
+ int h = draw_get_font_size ();
+ gtk_widget_set_size_request (widget, -1, h + 10);
+ cursor_sz = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
+ cursor_drag = gdk_cursor_new (GDK_FLEUR);
+}
+
+float last_header_motion_ev = -1;
+int prev_header_x = -1;
+
+gboolean
+on_header_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (header_dragging >= 0) {
+ gdk_window_set_cursor (widget->window, cursor_drag);
+ gtkpl_column_t *c;
+ int i;
+ for (i = 0, c = ps->columns; i < header_dragging && c; c = c->next, i++);
+ c->movepos = event->x - header_dragpt[0];
+
+ // find closest column to the left
+ int inspos = -1;
+ gtkpl_column_t *cc;
+ int x = 0;
+ int idx = 0;
+ int x1 = -1, x2 = -1;
+ for (cc = ps->columns; cc; cc = cc->next, idx++) {
+ if (x < c->movepos && x + c->width > c->movepos) {
+ inspos = idx;
+ x1 = x;
+ }
+ else if (idx == header_dragging) {
+ x2 = x;
+ }
+ x += cc->width;
+ }
+ if (inspos >= 0 && inspos != header_dragging) {
+ int c1 = inspos;
+ int c2 = header_dragging;
+ // remove c from list
+ if (c == ps->columns) {
+ ps->columns = c->next;
+ }
+ else {
+ for (cc = ps->columns; cc; cc = cc->next) {
+ if (cc->next == c) {
+ cc->next = c->next;
+ }
+ }
+ }
+ c->next = NULL;
+ // reinsert c at position inspos update header_dragging to new idx
+ header_dragging = inspos;
+ if (inspos == 0) {
+ c->next = ps->columns;
+ ps->columns = c;
+ }
+ else {
+ idx = 0;
+ gtkpl_column_t *prev = NULL;
+ for (cc = ps->columns; cc; cc = cc->next, idx++, prev = cc) {
+ if (idx+1 == inspos) {
+ gtkpl_column_t *next = cc->next;
+ cc->next = c;
+ c->next = next;
+ break;
+ }
+ }
+ }
+// colhdr_anim_swap (ps, c1, c2, x1, x2);
+ // force redraw of everything
+// gtkpl_setup_hscrollbar (ps);
+ gtkpl_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_column_update_config (ps, c, i);
+ }
+ else {
+ // only redraw that if not animating
+ gtkpl_header_draw (ps);
+ gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
+ }
+ }
+ else if (header_sizing >= 0) {
+ // limit event rate
+ if (event->time - last_header_motion_ev < 50 || prev_header_x == event->x) {
+ return FALSE;
+ }
+ last_header_motion_ev = event->time;
+ prev_header_x = event->x;
+ gdk_window_set_cursor (widget->window, cursor_sz);
+ // get column start pos
+ int x = -ps->hscrollpos;
+ int i = 0;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c && i < header_sizing; c = c->next, i++) {
+ x += c->width;
+ }
+
+ int newx = event->x > x + MIN_COLUMN_WIDTH ? event->x : x + MIN_COLUMN_WIDTH;
+ c->width = newx - x;
+ gtkpl_setup_hscrollbar (ps);
+ gtkpl_header_draw (ps);
+ gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
+ gtkpl_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_column_update_config (ps, c, i);
+ }
+ else {
+ int x = -ps->hscrollpos;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c; c = c->next) {
+ int w = c->width;
+ if (w > 0) { // ignore collapsed columns (hack for search window)
+ if (event->x >= x + w - 2 && event->x <= x + w) {
+ gdk_window_set_cursor (widget->window, cursor_sz);
+ break;
+ }
+ else {
+ gdk_window_set_cursor (widget->window, NULL);
+ }
+ }
+ else {
+ gdk_window_set_cursor (widget->window, NULL);
+ }
+ x += w;
+ }
+ }
+ return FALSE;
+}
+
+gboolean
+on_header_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (event->button == 1) {
+ // start sizing/dragging
+ header_dragging = -1;
+ header_sizing = -1;
+ header_dragpt[0] = event->x;
+ header_dragpt[1] = event->y;
+ int x = -ps->hscrollpos;
+ int i = 0;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c; c = c->next, i++) {
+ int w = c->width;
+ if (event->x >= x + w - 2 && event->x <= x + w) {
+ header_sizing = i;
+ header_dragging = -1;
+ break;
+ }
+ else if (event->x > x + 2 && event->x < x + w - 2) {
+ header_dragpt[0] = event->x - x;
+ header_dragging = i;
+ header_sizing = -1;
+ break;
+ }
+ x += w;
+ }
+ }
+ prev_header_x = -1;
+ last_header_motion_ev = -1;
+ return FALSE;
+}
+
+gboolean
+on_header_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ GTKPL_PROLOGUE;
+ if (event->button == 1) {
+ header_sizing = -1;
+ int x = 0;
+ gtkpl_column_t *c;
+ for (c = ps->columns; c; c = c->next) {
+ int w = c->width;
+ if (event->x >= x + w - 2 && event->x <= x + w) {
+ gdk_window_set_cursor (widget->window, cursor_sz);
+ break;
+ }
+ else {
+ gdk_window_set_cursor (widget->window, NULL);
+ }
+ x += w;
+ }
+ if (header_dragging >= 0) {
+ header_dragging = -1;
+ gtkpl_setup_hscrollbar (ps);
+ gtkpl_header_draw (ps);
+ gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height);
+ gtkpl_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height);
+ gtkpl_column_rewrite_config (ps);
+ }
+ }
+// NOTE: disabled for 0.3.0 release
+// else if (event->button == 3) {
+// GtkWidget *menu = create_headermenu ();
+// gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, widget, 0, gtk_get_current_event_time());
+// }
+ return FALSE;
+}
+
+void
+gtkpl_add_dir (gtkplaylist_t *ps, char *folder) {
+ GDK_THREADS_ENTER();
+ progress_show ();
+ GDK_THREADS_LEAVE();
+ pl_add_dir (folder, gtkpl_add_file_info_cb, NULL);
+ g_free (folder);
+ GDK_THREADS_ENTER();
+ progress_hide ();
+ playlist_refresh ();
+ GDK_THREADS_LEAVE();
+}
+
+static void
+gtkpl_adddir_cb (gpointer data, gpointer userdata) {
+ pl_add_dir (data, gtkpl_add_file_info_cb, userdata);
+ g_free (data);
+}
+
+void
+gtkpl_add_dirs (gtkplaylist_t *ps, GSList *lst) {
+ GDK_THREADS_ENTER();
+ progress_show ();
+ GDK_THREADS_LEAVE();
+ g_slist_foreach(lst, gtkpl_adddir_cb, NULL);
+ g_slist_free (lst);
+ GDK_THREADS_ENTER();
+ progress_hide ();
+ playlist_refresh ();
+ GDK_THREADS_LEAVE();
+}
+
+static void
+gtkpl_addfile_cb (gpointer data, gpointer userdata) {
+ pl_add_file (data, gtkpl_add_file_info_cb, userdata);
+ g_free (data);
+}
+
+void
+gtkpl_add_files (gtkplaylist_t *ps, GSList *lst) {
+ GDK_THREADS_ENTER();
+ progress_show ();
+ GDK_THREADS_LEAVE();
+ g_slist_foreach(lst, gtkpl_addfile_cb, NULL);
+ g_slist_free (lst);
+ GDK_THREADS_ENTER();
+ progress_hide ();
+ playlist_refresh ();
+ GDK_THREADS_LEAVE();
+}
+
+void
+gtkpl_playsong (gtkplaylist_t *ps) {
+ if (p_ispaused ()) {
+ p_unpause ();
+ }
+ else if (ps->row != -1) {
+ p_stop ();
+ streamer_set_nextsong (ps->row, 1);
+ }
+ else {
+ p_stop ();
+ streamer_set_nextsong (0, 1);
+ }
+}
+
+int
+gtkpl_get_idx_of (gtkplaylist_t *ps, playItem_t *it) {
+ playItem_t *c = playlist_head[ps->iterator];
+ int idx = 0;
+ while (c && c != it) {
+ c = c->next[ps->iterator];
+ idx++;
+ }
+ if (!c) {
+ return -1;
+ }
+ return idx;
+}
+
+playItem_t *
+gtkpl_get_for_idx (gtkplaylist_t *ps, int idx) {
+ playItem_t *it = playlist_head[ps->iterator];
+ while (idx--) {
+ if (!it)
+ return NULL;
+ it = it->next[ps->iterator];
+ }
+ return it;
+}
+
+void
+playlist_refresh (void) {
+ extern gtkplaylist_t main_playlist;
+ gtkplaylist_t *ps = &main_playlist;
+ gtkpl_setup_scrollbar (ps);
+ GtkWidget *widget = ps->playlist;
+ gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
+ search_refresh ();
+}
+
+gtkpl_column_t *
+gtkpl_column_alloc (const char *title, int width, int id, const char *format, int align_right) {
+ gtkpl_column_t *c = malloc (sizeof (gtkpl_column_t));
+ memset (c, 0, sizeof (gtkpl_column_t));
+ c->title = strdup (title);
+ c->id = id;
+ c->format = format ? strdup (format) : NULL;
+ c->width = width;
+ c->align_right = align_right;
+ return c;
+}
+
+void
+gtkpl_column_append (gtkplaylist_t *pl, gtkpl_column_t *c) {
+ int idx = 0;
+ if (pl->columns) {
+ idx++;
+ gtkpl_column_t *tail = pl->columns;
+ while (tail->next) {
+ tail = tail->next;
+ idx++;
+ }
+ tail->next = c;
+ }
+ else {
+ pl->columns = c;
+ }
+ gtkpl_column_update_config (pl, c, idx);
+}
+
+void
+gtkpl_column_free (gtkpl_column_t *c) {
+ if (c->title) {
+ free (c->title);
+ }
+ if (c->format) {
+ free (c->format);
+ }
+ free (c);
+}
+
+void
+gtkpl_column_remove (gtkplaylist_t *pl, gtkpl_column_t *c) {
+ if (pl->columns == c) {
+ pl->columns = pl->columns->next;
+ gtkpl_column_free (c);
+ return;
+ }
+ gtkpl_column_t *cc = pl->columns;
+ while (cc) {
+ if (cc->next == c) {
+ cc->next = cc->next->next;
+ gtkpl_column_free (c);
+ return;
+ }
+ cc = cc->next;
+ }
+ assert (cc && "gtkpl: attempted to remove column that is not in list");
+}
+
+void
+gtkpl_append_column_from_textdef (gtkplaylist_t *pl, const uint8_t *def) {
+ // syntax: "title" "format" id width alignright
+ char title[128];
+ char format[128];
+ int id;
+ int width;
+ int align_right;
+ // title
+ if (*def != '"') {
+ return;
+ }
+ def++;
+ if (*def == 0) {
+ return;
+ }
+ const uint8_t *e = def;
+ e++;
+ while (*e && *e != '"') {
+ e++;
+ }
+ if (*e == 0) {
+ return;
+ }
+ memcpy (title, def, e-def);
+ title[e-def] = 0;
+ // skip whitespace
+ def = e;
+ def++;
+ while (*def && *def <= ' ') {
+ def++;
+ }
+ if (*def == 0) {
+ return;
+ }
+ // format
+ if (*def != '"') {
+ return;
+ }
+ def++;
+ if (*def == 0) {
+ return;
+ }
+ e = def;
+ while (*e && *e != '"') {
+ e++;
+ }
+ if (*e == 0) {
+ return;
+ }
+ memcpy (format, def, e-def);
+ format[e-def] = 0;
+ // skip whitespace
+ def = e;
+ def++;
+ while (*def && *def <= ' ') {
+ def++;
+ }
+ if (*def == 0) {
+ return;
+ }
+ // id
+ e = def;
+ while (*e && (isdigit (*e) || *e == '-')) {
+ e++;
+ }
+ if (*e == 0) {
+ return;
+ }
+ {
+ char s[e-def+1];
+ memcpy (s, def, e-def);
+ s[e-def] = 0;
+ id = atoi (s);
+ }
+ // skip whitespace
+ def = e;
+ def++;
+ while (*def && *def <= ' ') {
+ def++;
+ }
+ if (*def == 0) {
+ return;
+ }
+ // width
+ e = def;
+ while (*e && isdigit (*e)) {
+ e++;
+ }
+ if (*e == 0) {
+ return;
+ }
+ {
+ char s[e-def+1];
+ memcpy (s, def, e-def);
+ s[e-def] = 0;
+ width = atoi (s);
+ }
+ // skip whitespace
+ def = e;
+ def++;
+ while (*def && *def <= ' ') {
+ def++;
+ }
+ if (*def == 0) {
+ return;
+ }
+ // align_right
+ e = def;
+ while (*e && isdigit (*e)) {
+ e++;
+ }
+ {
+ char s[e-def+1];
+ memcpy (s, def, e-def);
+ s[e-def] = 0;
+ align_right = atoi (s);
+ }
+ gtkpl_column_append (pl, gtkpl_column_alloc (title, width, id, format[0] ? format : NULL, align_right));
+}
+
+void
+gtkpl_column_update_config (gtkplaylist_t *pl, gtkpl_column_t *c, int idx) {
+ char key[128];
+ char value[128];
+ snprintf (key, sizeof (key), "%s.column.%d", pl->title, idx);
+ snprintf (value, sizeof (value), "\"%s\" \"%s\" %d %d %d", c->title, c->format ? c->format : "", c->id, c->width, c->align_right);
+ conf_set_str (key, value);
+}
+
+void
+gtkpl_column_rewrite_config (gtkplaylist_t *pl) {
+ char key[128];
+ char value[128];
+ snprintf (key, sizeof (key), "%s.column.", pl->title);
+ conf_remove_items (key);
+
+ gtkpl_column_t *c;
+ int i = 0;
+ for (c = pl->columns; c; c = c->next, i++) {
+ snprintf (key, sizeof (key), "%s.column.%d", pl->title, i);
+ snprintf (value, sizeof (value), "\"%s\" \"%s\" %d %d %d", c->title, c->format ? c->format : "", c->id, c->width, c->align_right);
+ conf_set_str (key, value);
+ }
+}
+
+void
+set_tray_tooltip (const char *text) {
+#if (GTK_MINOR_VERSION < 16)
+ gtk_status_icon_set_tooltip (trayicon, text);
+#else
+ gtk_status_icon_set_tooltip_text (trayicon, text);
+#endif
+}
+
+void
+gtkpl_current_track_changed (playItem_t *it) {
+ char str[600];
+ char dname[512];
+ pl_format_item_display_name (it, dname, 512);
+ snprintf (str, 600, "DeaDBeeF - %s", dname);
+ gtk_window_set_title (GTK_WINDOW (mainwin), str);
+ set_tray_tooltip (str);
+}
+
+void
+gtkpl_songchanged_wrapper (int from, int to) {
+ GDK_THREADS_ENTER ();
+ // update window title
+ if (from >= 0 || to >= 0) {
+ if (to >= 0) {
+ playItem_t *it = pl_get_for_idx (to);
+ if (it) { // it might have been deleted after event was sent
+ gtkpl_current_track_changed (it);
+ }
+ }
+ else {
+ gtk_window_set_title (GTK_WINDOW (mainwin), "DeaDBeeF");
+ set_tray_tooltip ("DeaDBeeF");
+ }
+ }
+ // update playlist view
+ gtkpl_songchanged (&main_playlist, from, to);
+ GDK_THREADS_LEAVE ();
+}
diff --git a/plugins/gtkui/gtkplaylist.h b/plugins/gtkui/gtkplaylist.h
new file mode 100644
index 00000000..2e827839
--- /dev/null
+++ b/plugins/gtkui/gtkplaylist.h
@@ -0,0 +1,261 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __GTKPLAYLIST_H
+#define __GTKPLAYLIST_H
+
+#include <gtk/gtk.h>
+#include <stdint.h>
+#include <assert.h>
+#include "playlist.h"
+
+// drag and drop targets
+enum {
+ TARGET_URILIST,
+ TARGET_SAMEWIDGET,
+};
+
+// color scheme constants
+enum {
+ COLO_PLAYLIST_CURSOR,
+ COLO_PLAYLIST_ODD,
+ COLO_PLAYLIST_EVEN,
+ COLO_PLAYLIST_SEL_ODD,
+ COLO_PLAYLIST_SEL_EVEN,
+ COLO_PLAYLIST_TEXT,
+ COLO_PLAYLIST_SEL_TEXT,
+ COLO_SEEKBAR_BACK,
+ COLO_SEEKBAR_FRONT,
+ COLO_VOLUMEBAR_BACK,
+ COLO_VOLUMEBAR_FRONT,
+ COLO_DRAGDROP_MARKER,
+ COLO_COUNT
+};
+
+//#define pl_ncolumns 5
+//#define pl_colname_max 100
+
+typedef struct gtkpl_column_s {
+ char *title;
+ int id; // id is faster than format, set to -1 to use format
+ char *format;
+ int width;
+ int movepos; // valid only while `moving' is 1
+ struct gtkpl_column_s *next;
+ unsigned align_right : 1;
+// unsigned moving : 1;
+} gtkpl_column_t;
+
+// structure of this kind must be set as user data for playlist, header and scrollbar widgets
+// pointer to this structure must be passed too all functions that
+// implement playlist functionality (like this pointer)
+typedef struct {
+ // cached gtk/gdk object pointers
+ GtkWidget *playlist;
+ GtkWidget *header;
+ GtkWidget *scrollbar;
+ GtkWidget *hscrollbar;
+ GdkPixmap *backbuf;
+ GdkPixmap *backbuf_header;
+ const char *title; // unique id, used for config writing, etc
+ // parameters
+ playItem_t **pcurr; // pointer to current item
+ int *pcount; // pointer to count of items in list
+ int iterator; // index into next array of playItem_t struct
+ int lastpos[2]; // last mouse position (for playlist widget)
+ int multisel; // if it uses multiple selection
+ // current state
+ int scrollpos;
+ int hscrollpos;
+ int row;
+ double clicktime; // for doubleclick detection
+ int nvisiblerows;
+ int nvisiblefullrows;
+// int *colwidths;//[pl_ncolumns]; // current column widths
+// int ncolumns;
+ gtkpl_column_t *columns;
+} gtkplaylist_t;
+
+#define GTKPL_PROLOGUE \
+ gtkplaylist_t *ps = (gtkplaylist_t *)gtk_object_get_data (GTK_OBJECT (widget), "ps"); assert (ps);
+
+extern int rowheight;
+
+// that must be called before gtk_init
+void
+gtkpl_init (void);
+
+void
+gtkpl_free (gtkplaylist_t *pl);
+
+void
+gtkpl_redraw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it);
+
+void
+gtkpl_redraw_pl_row_novis (gtkplaylist_t *ps, int row, playItem_t *it);
+
+void
+gtkpl_setup_scrollbar (gtkplaylist_t *ps);
+
+void
+gtkpl_draw_pl_row_back (gtkplaylist_t *ps, int row, playItem_t *it);
+
+void
+gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it);
+
+void
+gtkpl_draw_playlist (gtkplaylist_t *ps, int x, int y, int w, int h);
+
+void
+gtkpl_reconf (gtkplaylist_t *ps);
+
+void
+gtkpl_expose (gtkplaylist_t *ps, int x, int y, int w, int h);
+
+void
+gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time);
+
+void
+gtkpl_mouse1_released (gtkplaylist_t *ps, int state, int ex, int ey, double time);
+
+void
+gtkpl_mousemove (gtkplaylist_t *ps, GdkEventMotion *event);
+
+void
+gtkpl_scroll (gtkplaylist_t *ps, int newscroll);
+
+void
+gtkpl_hscroll (gtkplaylist_t *ps, int newscroll);
+
+void
+gtkpl_handle_scroll_event (gtkplaylist_t *ps, int direction);
+
+void
+gtkpl_keypress (gtkplaylist_t *ps, int keyval, int state);
+
+void
+gtkpl_track_dragdrop (gtkplaylist_t *ps, int y);
+
+void
+gtkpl_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length);
+
+void
+gtkpl_handle_fm_drag_drop (gtkplaylist_t *ps, int drop_y, void *ptr, int length);
+
+void
+gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y);
+
+void
+gtkpl_select_single (gtkplaylist_t *ps, int sel);
+
+void
+gtkpl_header_draw (gtkplaylist_t *ps);
+
+void
+gtkpl_add_dir (gtkplaylist_t *ps, char *folder);
+
+void
+gtkpl_add_dirs (gtkplaylist_t *ps, GSList *lst);
+
+void
+gtkpl_add_files (gtkplaylist_t *ps, GSList *lst);
+
+void
+gtkpl_configure (gtkplaylist_t *ps);
+
+int
+gtkpl_get_idx_of (gtkplaylist_t *ps, playItem_t *it);
+
+playItem_t *
+gtkpl_get_for_idx (gtkplaylist_t *ps, int idx);
+
+// this functions take value from passed playlist, that's why it's here
+void
+gtkpl_playsong (gtkplaylist_t *ps);
+
+void
+gtkpl_songchanged (gtkplaylist_t *ps, int from, int to);
+
+// these functions operate on global playlist level,
+// no need to pass gtkplaylist_t ptr to them
+
+void
+gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y);
+
+// these functions should not belong here
+void
+gtkpl_prevsong (void);
+
+void
+gtkpl_nextsong (void);
+
+void
+gtkpl_randomsong (void);
+
+void
+gtkpl_pausesong (void);
+
+void
+gtkpl_playsongnum (int idx);
+
+void
+theme_set_fg_color (int col);
+
+void
+theme_set_bg_color (int col);
+
+void
+theme_set_cairo_source_rgb (cairo_t *cr, int col);
+
+void
+playlist_refresh (void);
+
+// column utilities
+gtkpl_column_t *
+gtkpl_column_alloc (const char *title, int width, int id, const char *format, int align_right);
+
+void
+gtkpl_column_append (gtkplaylist_t *pl, gtkpl_column_t *c);
+
+void
+gtkpl_column_remove (gtkplaylist_t *pl, gtkpl_column_t *c);
+
+void
+gtkpl_column_free (gtkpl_column_t *c);
+
+void
+gtkpl_append_column_from_textdef (gtkplaylist_t *pl, const uint8_t *def);
+
+void
+gtkpl_column_update_config (gtkplaylist_t *pl, gtkpl_column_t *c, int idx);
+
+void
+gtkpl_column_rewrite_config (gtkplaylist_t *pl);
+
+void
+gtkpl_expose_header (gtkplaylist_t *ps, int x, int y, int w, int h);
+
+void
+set_tray_tooltip (const char *text);
+
+void
+gtkpl_songchanged_wrapper (int from, int to);
+
+void
+gtkpl_current_track_changed (playItem_t *it);
+
+#endif // __GTKPLAYLIST_H
diff --git a/plugins/gtkui/gtksession.c b/plugins/gtkui/gtksession.c
new file mode 100644
index 00000000..e24706b6
--- /dev/null
+++ b/plugins/gtkui/gtksession.c
@@ -0,0 +1,44 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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.
+*/
+#include <stdio.h>
+#include <gtk/gtk.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "session.h"
+#include "conf.h"
+
+void
+session_capture_window_attrs (uintptr_t window) {
+ GtkWindow *wnd = GTK_WINDOW (window);
+ int win_attrs[4];
+ gtk_window_get_position (wnd, &win_attrs[0], &win_attrs[1]);
+ gtk_window_get_size (wnd, &win_attrs[2], &win_attrs[3]);
+ conf_set_int ("mainwin.geometry.x", win_attrs[0]);
+ conf_set_int ("mainwin.geometry.y", win_attrs[1]);
+ conf_set_int ("mainwin.geometry.w", win_attrs[2]);
+ conf_set_int ("mainwin.geometry.h", win_attrs[3]);
+}
+
+void
+session_restore_window_attrs (uintptr_t window) {
+ GtkWindow *wnd = GTK_WINDOW (window);
+ gtk_window_move (wnd, conf_get_int ("mainwin.geometry.x", 40), conf_get_int ("mainwin.geometry.y", 40));
+ gtk_window_resize (wnd, conf_get_int ("mainwin.geometry.w", 500), conf_get_int ("mainwin.geometry.h", 300));
+}
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
new file mode 100644
index 00000000..c5a87056
--- /dev/null
+++ b/plugins/gtkui/gtkui.c
@@ -0,0 +1,343 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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.
+*/
+#include "../../deadbeef.h"
+#include <gtk/gtk.h>
+#include "gtkplaylist.h"
+#include "search.h"
+#include "progress.h"
+#include "interface.h"
+#include "callbacks.h"
+#include "support.h"
+
+// main widgets
+GtkWidget *mainwin;
+GtkWidget *searchwin;
+GtkStatusIcon *trayicon;
+GtkWidget *traymenu;
+
+// playlist configuration structures
+gtkplaylist_t main_playlist;
+gtkplaylist_t search_playlist;
+
+// update status bar and window title
+static int sb_context_id = -1;
+static char sb_text[512];
+static float last_songpos = -1;
+
+static void
+update_songinfo (void) {
+ char sbtext_new[512] = "-";
+ float songpos = last_songpos;
+
+ int daystotal = (int)pl_totaltime / (3600*24);
+ int hourtotal = ((int)pl_totaltime / 3600) % 24;
+ int mintotal = ((int)pl_totaltime/60) % 60;
+ int sectotal = ((int)pl_totaltime) % 60;
+
+ char totaltime_str[512] = "";
+ if (daystotal == 0)
+ snprintf (totaltime_str, sizeof (totaltime_str), "%d:%02d:%02d", hourtotal, mintotal, sectotal);
+
+ else if (daystotal == 1)
+ snprintf (totaltime_str, sizeof (totaltime_str), "1 day %d:%02d:%02d", hourtotal, mintotal, sectotal);
+
+ else
+ snprintf (totaltime_str, sizeof (totaltime_str), "%d days %d:%02d:%02d", daystotal, hourtotal, mintotal, sectotal);
+
+ if (p_isstopped ()) {
+ snprintf (sbtext_new, sizeof (sbtext_new), "Stopped | %s total playtime", totaltime_str);
+ songpos = 0;
+ }
+ else if (str_playing_song.decoder) {
+// codec_lock ();
+ DB_decoder_t *c = str_playing_song.decoder;
+ float playpos = streamer_get_playpos ();
+ int minpos = playpos / 60;
+ int secpos = playpos - minpos * 60;
+ int mindur = str_playing_song._duration / 60;
+ int secdur = str_playing_song._duration - mindur * 60;
+
+ const char *mode = c->info.channels == 1 ? "Mono" : "Stereo";
+ int samplerate = c->info.samplerate;
+ int bitspersample = c->info.bps;
+ songpos = playpos;
+// codec_unlock ();
+
+ char t[100];
+ if (str_playing_song._duration >= 0) {
+ snprintf (t, sizeof (t), "%d:%02d", mindur, secdur);
+ }
+ else {
+ strcpy (t, "-:--");
+ }
+
+ char sbitrate[20] = "";
+#if 0 // NOTE: do not enable that for stable branch yet
+ int bitrate = streamer_get_bitrate ();
+ if (bitrate > 0) {
+ snprintf (sbitrate, sizeof (sbitrate), "%d kbps ", bitrate);
+ }
+#endif
+ const char *spaused = p_ispaused () ? "Paused | " : "";
+ snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d songs | %s total playtime", spaused, str_playing_song.filetype ? str_playing_song.filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, pl_getcount (), totaltime_str);
+ }
+
+ if (strcmp (sbtext_new, sb_text)) {
+ strcpy (sb_text, sbtext_new);
+
+ // form statusline
+ GDK_THREADS_ENTER();
+ // FIXME: don't update if window is not visible
+ GtkStatusbar *sb = GTK_STATUSBAR (lookup_widget (mainwin, "statusbar"));
+ if (sb_context_id == -1) {
+ sb_context_id = gtk_statusbar_get_context_id (sb, "msg");
+ }
+
+ gtk_statusbar_pop (sb, sb_context_id);
+ gtk_statusbar_push (sb, sb_context_id, sb_text);
+
+ GDK_THREADS_LEAVE();
+ }
+
+ if (songpos != last_songpos) {
+ void seekbar_draw (GtkWidget *widget);
+ void seekbar_expose (GtkWidget *widget, int x, int y, int w, int h);
+ if (mainwin) {
+ GtkWidget *widget = lookup_widget (mainwin, "seekbar");
+ // translate volume to seekbar pixels
+ songpos /= str_playing_song._duration;
+ songpos *= widget->allocation.width;
+ if ((int)(songpos*2) != (int)(last_songpos*2)) {
+ GDK_THREADS_ENTER();
+ seekbar_draw (widget);
+ seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height);
+ GDK_THREADS_LEAVE();
+ last_songpos = songpos;
+ }
+ }
+ }
+}
+
+gboolean
+on_trayicon_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event,
+ gpointer user_data)
+{
+ float vol = volume_get_db ();
+ if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) {
+ vol += 1;
+ }
+ else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) {
+ vol -= 1;
+ }
+ if (vol > 0) {
+ vol = 0;
+ }
+ else if (vol < -60) {
+ vol = -60;
+ }
+ volume_set_db (vol);
+ GtkWidget *volumebar = lookup_widget (mainwin, "volumebar");
+ volumebar_draw (volumebar);
+ volumebar_expose (volumebar, 0, 0, volumebar->allocation.width, volumebar->allocation.height);
+ return FALSE;
+}
+
+#if GTK_MINOR_VERSION<=14
+gboolean
+on_trayicon_activate (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ if (GTK_WIDGET_VISIBLE (mainwin)) {
+ gtk_widget_hide (mainwin);
+ }
+ else {
+ gtk_widget_show (mainwin);
+ gtk_window_present (GTK_WINDOW (mainwin));
+ }
+ return FALSE;
+}
+#endif
+
+gboolean
+on_trayicon_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ if (event->button == 1) {
+ if (GTK_WIDGET_VISIBLE (mainwin)) {
+ gtk_widget_hide (mainwin);
+ }
+ else {
+ gtk_widget_show (mainwin);
+ gtk_window_present (GTK_WINDOW (mainwin));
+ }
+ }
+ return FALSE;
+}
+
+gboolean
+on_trayicon_popup_menu (GtkWidget *widget,
+ guint button,
+ guint time,
+ gpointer user_data)
+{
+ gtk_menu_popup (GTK_MENU (traymenu), NULL, NULL, gtk_status_icon_position_menu, trayicon, button, time);
+ return FALSE;
+}
+
+void
+guiplug_showwindow (void) {
+ GDK_THREADS_ENTER();
+ gtk_widget_show (mainwin);
+ gtk_window_present (GTK_WINDOW (mainwin));
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_play_current_song (void) {
+ GDK_THREADS_ENTER();
+ gtkpl_playsong (&main_playlist);
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_shutdown (void) {
+ GDK_THREADS_ENTER();
+ gtk_widget_hide (mainwin);
+ gtk_main_quit ();
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_songchanged (int from, int to) {
+ gtkpl_songchanged_wrapper (from, to);
+}
+
+void
+guiplug_start_current_track (void) {
+ gtkpl_playsong (&main_playlist);
+ if (playlist_current_ptr) {
+ GDK_THREADS_ENTER();
+ gtkpl_redraw_pl_row (&main_playlist, pl_get_idx_of (playlist_current_ptr), playlist_current_ptr);
+ GDK_THREADS_LEAVE();
+ }
+}
+void
+guiplug_track_changed (int idx) {
+ playItem_t *it = pl_get_for_idx (idx);
+ if (it) {
+ GDK_THREADS_ENTER();
+ gtkpl_redraw_pl_row (&main_playlist, idx, it);
+ if (it == playlist_current_ptr) {
+ gtkpl_current_track_changed (it);
+ }
+ GDK_THREADS_LEAVE();
+ }
+}
+
+void
+guiplug_start_track (int idx) {
+ GDK_THREADS_ENTER();
+ gtkpl_playsongnum (idx);
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_track_paused (int idx) {
+ GDK_THREADS_ENTER();
+ gtkpl_redraw_pl_row (&main_playlist, idx, pl_get_for_idx (idx));
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_start_random (void) {
+ GDK_THREADS_ENTER();
+ gtkpl_randomsong ();
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_add_dir (const char *dir) {
+ // long time processing
+ // float t1 = (float)clock () / CLOCKS_PER_SEC;
+ gtkpl_add_dir (&main_playlist, dir);
+ // float t2 = (float)clock () / CLOCKS_PER_SEC;
+ // printf ("time: %f\n", t2-t1);
+}
+
+void
+guiplug_add_dirs (GSList *dirs) {
+ // long time processing
+ // float t1 = (float)clock () / CLOCKS_PER_SEC;
+ gtkpl_add_dirs (&main_playlist, dirs);
+ // float t2 = (float)clock () / CLOCKS_PER_SEC;
+ // printf ("time: %f\n", t2-t1);
+}
+
+void
+guiplug_add_files (GSList *files) {
+ gtkpl_add_files (&main_playlist, files);
+}
+
+void
+guiplug_open_files (GSList *files) {
+ gtkpl_add_files (&main_playlist, files);
+ gtkpl_playsong (&main_playlist);
+}
+
+void
+guiplug_refresh_playlist (void) {
+ GDK_THREADS_ENTER();
+ playlist_refresh ();
+ search_refresh ();
+ GDK_THREADS_LEAVE();
+}
+
+void
+guiplug_add_fm_dropped_files (char *files, int p1, int p2) {
+ gtkpl_add_fm_dropped_files (&main_playlist, (char *)ctx, p1, p2);
+}
+
+void
+guiplug_frameupdate (void) {
+ update_songinfo ();
+}
+
+void
+guiplug_reset_selection (void) {
+ search_playlist.row = -1;
+ main_playlist.row = -1;
+}
+
+// define plugin interface
+static DB_gui_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 0,
+ .plugin.version_minor = 1,
+ .plugin.type = DB_PLUGIN_MISC,
+ .plugin.name = "Standard GTK2 user interface",
+ .plugin.descr = "",
+ .plugin.author = "Alexey Yakovenko",
+ .plugin.email = "waker@users.sourceforge.net",
+ .plugin.website = "http://deadbeef.sf.net",
+ .plugin.start = gtkui_start,
+ .plugin.stop = gtkui_stop
+};
diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c
new file mode 100644
index 00000000..88acb8d0
--- /dev/null
+++ b/plugins/gtkui/interface.c
@@ -0,0 +1,1737 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+#define GLADE_HOOKUP_OBJECT(component,widget,name) \
+ g_object_set_data_full (G_OBJECT (component), name, \
+ gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
+
+#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
+ g_object_set_data (G_OBJECT (component), name, widget)
+
+GtkWidget*
+create_mainwin (void)
+{
+ GtkWidget *mainwin;
+ GtkWidget *vbox1;
+ GtkWidget *menubar1;
+ GtkWidget *menuitem1;
+ GtkWidget *menuitem1_menu;
+ GtkWidget *open;
+ GtkWidget *image120;
+ GtkWidget *separator2;
+ GtkWidget *add_files;
+ GtkWidget *image121;
+ GtkWidget *add_folders;
+ GtkWidget *image122;
+ GtkWidget *add_audio_cd;
+ GtkWidget *image123;
+ GtkWidget *add_location1;
+ GtkWidget *separatormenuitem1;
+ GtkWidget *quit;
+ GtkWidget *image124;
+ GtkWidget *edit1;
+ GtkWidget *edit1_menu;
+ GtkWidget *clear1;
+ GtkWidget *image125;
+ GtkWidget *select_all1;
+ GtkWidget *selection1;
+ GtkWidget *selection1_menu;
+ GtkWidget *remove1;
+ GtkWidget *image126;
+ GtkWidget *crop1;
+ GtkWidget *find1;
+ GtkWidget *separator5;
+ GtkWidget *preferences;
+ GtkWidget *playlist1;
+ GtkWidget *playlist1_menu;
+ GtkWidget *playlist_load;
+ GtkWidget *playlist_save;
+ GtkWidget *playlist_save_as;
+ GtkWidget *order1;
+ GtkWidget *order1_menu;
+ GSList *order_linear_group = NULL;
+ GtkWidget *order_linear;
+ GtkWidget *order_shuffle;
+ GtkWidget *order_random;
+ GtkWidget *looping1;
+ GtkWidget *looping1_menu;
+ GSList *loop_all_group = NULL;
+ GtkWidget *loop_all;
+ GtkWidget *loop_single;
+ GtkWidget *loop_disable;
+ GtkWidget *scroll_follows_playback;
+ GtkWidget *menuitem4;
+ GtkWidget *menuitem4_menu;
+ GtkWidget *about1;
+ GtkWidget *help1;
+ GtkWidget *image127;
+ GtkWidget *hbox2;
+ GtkWidget *hbox3;
+ GtkWidget *stopbtn;
+ GtkWidget *image7;
+ GtkWidget *playbtn;
+ GtkWidget *image2;
+ GtkWidget *pausebtn;
+ GtkWidget *image3;
+ GtkWidget *prevbtn;
+ GtkWidget *image4;
+ GtkWidget *nextbtn;
+ GtkWidget *image5;
+ GtkWidget *playrand;
+ GtkWidget *image6;
+ GtkWidget *volumebar;
+ GtkWidget *seekbar;
+ GtkWidget *table1;
+ GtkWidget *_;
+ GtkWidget *vbox3;
+ GtkWidget *header;
+ GtkWidget *playlist;
+ GtkWidget *playscroll;
+ GtkWidget *playhscroll;
+ GtkWidget *statusbar;
+ GtkAccelGroup *accel_group;
+
+ accel_group = gtk_accel_group_new ();
+
+ mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_events (mainwin, GDK_KEY_PRESS_MASK);
+ gtk_window_set_title (GTK_WINDOW (mainwin), "DeaDBeeF");
+ gtk_window_set_default_size (GTK_WINDOW (mainwin), 500, 300);
+
+ vbox1 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox1);
+ gtk_container_add (GTK_CONTAINER (mainwin), vbox1);
+
+ menubar1 = gtk_menu_bar_new ();
+ gtk_widget_show (menubar1);
+ gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
+
+ menuitem1 = gtk_menu_item_new_with_mnemonic ("_File");
+ gtk_widget_show (menuitem1);
+ gtk_container_add (GTK_CONTAINER (menubar1), menuitem1);
+
+ menuitem1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu);
+
+ open = gtk_image_menu_item_new_with_mnemonic ("_Open file(s)");
+ gtk_widget_show (open);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), open);
+ gtk_widget_add_accelerator (open, "activate", accel_group,
+ GDK_O, (GdkModifierType) GDK_CONTROL_MASK,
+ GTK_ACCEL_VISIBLE);
+
+ image120 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image120);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (open), image120);
+
+ separator2 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator2);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), separator2);
+ gtk_widget_set_sensitive (separator2, FALSE);
+
+ add_files = gtk_image_menu_item_new_with_mnemonic ("Add file(s)");
+ gtk_widget_show (add_files);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), add_files);
+
+ image121 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image121);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_files), image121);
+
+ add_folders = gtk_image_menu_item_new_with_mnemonic ("Add folder(s)");
+ gtk_widget_show (add_folders);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), add_folders);
+
+ image122 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image122);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_folders), image122);
+
+ add_audio_cd = gtk_image_menu_item_new_with_mnemonic ("Add Audio CD");
+ gtk_widget_show (add_audio_cd);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), add_audio_cd);
+
+ image123 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image123);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_audio_cd), image123);
+
+ add_location1 = gtk_menu_item_new_with_mnemonic ("Add location");
+ gtk_widget_show (add_location1);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), add_location1);
+
+ separatormenuitem1 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separatormenuitem1);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), separatormenuitem1);
+ gtk_widget_set_sensitive (separatormenuitem1, FALSE);
+
+ quit = gtk_image_menu_item_new_with_mnemonic ("_Quit");
+ gtk_widget_show (quit);
+ gtk_container_add (GTK_CONTAINER (menuitem1_menu), quit);
+ gtk_widget_add_accelerator (quit, "activate", accel_group,
+ GDK_Q, (GdkModifierType) GDK_CONTROL_MASK,
+ GTK_ACCEL_VISIBLE);
+
+ image124 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image124);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (quit), image124);
+
+ edit1 = gtk_menu_item_new_with_mnemonic ("Edit");
+ gtk_widget_show (edit1);
+ gtk_container_add (GTK_CONTAINER (menubar1), edit1);
+
+ edit1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (edit1), edit1_menu);
+
+ clear1 = gtk_image_menu_item_new_with_mnemonic ("_Clear");
+ gtk_widget_show (clear1);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), clear1);
+
+ image125 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image125);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear1), image125);
+
+ select_all1 = gtk_menu_item_new_with_mnemonic ("Select all");
+ gtk_widget_show (select_all1);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), select_all1);
+ gtk_widget_add_accelerator (select_all1, "activate", accel_group,
+ GDK_A, (GdkModifierType) GDK_CONTROL_MASK,
+ GTK_ACCEL_VISIBLE);
+
+ selection1 = gtk_menu_item_new_with_mnemonic ("Selection");
+ gtk_widget_show (selection1);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), selection1);
+
+ selection1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (selection1), selection1_menu);
+
+ remove1 = gtk_image_menu_item_new_with_mnemonic ("Remove");
+ gtk_widget_show (remove1);
+ gtk_container_add (GTK_CONTAINER (selection1_menu), remove1);
+ gtk_widget_add_accelerator (remove1, "activate", accel_group,
+ GDK_Delete, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+
+ image126 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image126);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (remove1), image126);
+
+ crop1 = gtk_menu_item_new_with_mnemonic ("Crop");
+ gtk_widget_show (crop1);
+ gtk_container_add (GTK_CONTAINER (selection1_menu), crop1);
+
+ find1 = gtk_menu_item_new_with_mnemonic ("_Find");
+ gtk_widget_show (find1);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), find1);
+ gtk_widget_add_accelerator (find1, "activate", accel_group,
+ GDK_F, (GdkModifierType) GDK_CONTROL_MASK,
+ GTK_ACCEL_VISIBLE);
+
+ separator5 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator5);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), separator5);
+ gtk_widget_set_sensitive (separator5, FALSE);
+
+ preferences = gtk_menu_item_new_with_mnemonic ("Preferences");
+ gtk_widget_show (preferences);
+ gtk_container_add (GTK_CONTAINER (edit1_menu), preferences);
+
+ playlist1 = gtk_menu_item_new_with_mnemonic ("Playlist");
+ gtk_widget_show (playlist1);
+ gtk_container_add (GTK_CONTAINER (menubar1), playlist1);
+
+ playlist1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (playlist1), playlist1_menu);
+
+ playlist_load = gtk_menu_item_new_with_mnemonic ("Load");
+ gtk_widget_show (playlist_load);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), playlist_load);
+
+ playlist_save = gtk_menu_item_new_with_mnemonic ("Save");
+ gtk_widget_show (playlist_save);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), playlist_save);
+
+ playlist_save_as = gtk_menu_item_new_with_mnemonic ("Save As");
+ gtk_widget_show (playlist_save_as);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), playlist_save_as);
+
+ order1 = gtk_menu_item_new_with_mnemonic ("Order");
+ gtk_widget_show (order1);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), order1);
+
+ order1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (order1), order1_menu);
+
+ order_linear = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, "Linear");
+ order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_linear));
+ gtk_widget_show (order_linear);
+ gtk_container_add (GTK_CONTAINER (order1_menu), order_linear);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_linear), TRUE);
+
+ order_shuffle = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, "Shuffle");
+ order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_shuffle));
+ gtk_widget_show (order_shuffle);
+ gtk_container_add (GTK_CONTAINER (order1_menu), order_shuffle);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_shuffle), TRUE);
+
+ order_random = gtk_radio_menu_item_new_with_mnemonic (order_linear_group, "Random");
+ order_linear_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (order_random));
+ gtk_widget_show (order_random);
+ gtk_container_add (GTK_CONTAINER (order1_menu), order_random);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (order_random), TRUE);
+
+ looping1 = gtk_menu_item_new_with_mnemonic ("Looping");
+ gtk_widget_show (looping1);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), looping1);
+
+ looping1_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (looping1), looping1_menu);
+
+ loop_all = gtk_radio_menu_item_new_with_mnemonic (loop_all_group, "Loop All");
+ loop_all_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (loop_all));
+ gtk_widget_show (loop_all);
+ gtk_container_add (GTK_CONTAINER (looping1_menu), loop_all);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (loop_all), TRUE);
+
+ loop_single = gtk_radio_menu_item_new_with_mnemonic (loop_all_group, "Loop Single Song");
+ loop_all_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (loop_single));
+ gtk_widget_show (loop_single);
+ gtk_container_add (GTK_CONTAINER (looping1_menu), loop_single);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (loop_single), TRUE);
+
+ loop_disable = gtk_radio_menu_item_new_with_mnemonic (loop_all_group, "Don't Loop");
+ loop_all_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (loop_disable));
+ gtk_widget_show (loop_disable);
+ gtk_container_add (GTK_CONTAINER (looping1_menu), loop_disable);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (loop_disable), TRUE);
+
+ scroll_follows_playback = gtk_check_menu_item_new_with_mnemonic ("Scroll follows playback");
+ gtk_widget_show (scroll_follows_playback);
+ gtk_container_add (GTK_CONTAINER (playlist1_menu), scroll_follows_playback);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (scroll_follows_playback), TRUE);
+
+ menuitem4 = gtk_menu_item_new_with_mnemonic ("_Help");
+ gtk_widget_show (menuitem4);
+ gtk_container_add (GTK_CONTAINER (menubar1), menuitem4);
+
+ menuitem4_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu);
+
+ about1 = gtk_menu_item_new_with_mnemonic ("_About");
+ gtk_widget_show (about1);
+ gtk_container_add (GTK_CONTAINER (menuitem4_menu), about1);
+
+ help1 = gtk_image_menu_item_new_with_mnemonic ("Help");
+ gtk_widget_show (help1);
+ gtk_container_add (GTK_CONTAINER (menuitem4_menu), help1);
+
+ image127 = gtk_image_new_from_stock ("gtk-help", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image127);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (help1), image127);
+
+ hbox2 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox2);
+ gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 0);
+
+ hbox3 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox3);
+ gtk_box_pack_start (GTK_BOX (hbox2), hbox3, TRUE, TRUE, 0);
+
+ stopbtn = gtk_button_new ();
+ gtk_widget_show (stopbtn);
+ gtk_box_pack_start (GTK_BOX (hbox3), stopbtn, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (stopbtn, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (stopbtn, "activate", accel_group,
+ GDK_v, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (stopbtn), GTK_RELIEF_NONE);
+
+ image7 = create_pixmap (mainwin, "stop_24.png");
+ gtk_widget_show (image7);
+ gtk_container_add (GTK_CONTAINER (stopbtn), image7);
+
+ playbtn = gtk_button_new ();
+ gtk_widget_show (playbtn);
+ gtk_box_pack_start (GTK_BOX (hbox3), playbtn, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (playbtn, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (playbtn, "activate", accel_group,
+ GDK_x, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_widget_add_accelerator (playbtn, "activate", accel_group,
+ GDK_Return, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (playbtn), GTK_RELIEF_NONE);
+
+ image2 = create_pixmap (mainwin, "play_24.png");
+ gtk_widget_show (image2);
+ gtk_container_add (GTK_CONTAINER (playbtn), image2);
+
+ pausebtn = gtk_button_new ();
+ gtk_widget_show (pausebtn);
+ gtk_box_pack_start (GTK_BOX (hbox3), pausebtn, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (pausebtn, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (pausebtn, "activate", accel_group,
+ GDK_c, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_widget_add_accelerator (pausebtn, "activate", accel_group,
+ GDK_p, (GdkModifierType) GDK_CONTROL_MASK,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (pausebtn), GTK_RELIEF_NONE);
+
+ image3 = create_pixmap (mainwin, "pause_24.png");
+ gtk_widget_show (image3);
+ gtk_container_add (GTK_CONTAINER (pausebtn), image3);
+
+ prevbtn = gtk_button_new ();
+ gtk_widget_show (prevbtn);
+ gtk_box_pack_start (GTK_BOX (hbox3), prevbtn, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (prevbtn, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (prevbtn, "activate", accel_group,
+ GDK_z, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (prevbtn), GTK_RELIEF_NONE);
+
+ image4 = create_pixmap (mainwin, "prev_24.png");
+ gtk_widget_show (image4);
+ gtk_container_add (GTK_CONTAINER (prevbtn), image4);
+
+ nextbtn = gtk_button_new ();
+ gtk_widget_show (nextbtn);
+ gtk_box_pack_start (GTK_BOX (hbox3), nextbtn, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (nextbtn, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (nextbtn, "activate", accel_group,
+ GDK_b, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (nextbtn), GTK_RELIEF_NONE);
+
+ image5 = create_pixmap (mainwin, "next_24.png");
+ gtk_widget_show (image5);
+ gtk_container_add (GTK_CONTAINER (nextbtn), image5);
+
+ playrand = gtk_button_new ();
+ gtk_widget_show (playrand);
+ gtk_box_pack_start (GTK_BOX (hbox3), playrand, FALSE, FALSE, 0);
+ GTK_WIDGET_UNSET_FLAGS (playrand, GTK_CAN_FOCUS);
+ gtk_widget_add_accelerator (playrand, "activate", accel_group,
+ GDK_n, (GdkModifierType) 0,
+ GTK_ACCEL_VISIBLE);
+ gtk_button_set_relief (GTK_BUTTON (playrand), GTK_RELIEF_NONE);
+
+ image6 = create_pixmap (mainwin, "random_24.png");
+ gtk_widget_show (image6);
+ gtk_container_add (GTK_CONTAINER (playrand), image6);
+
+ volumebar = gtk_drawing_area_new ();
+ gtk_widget_show (volumebar);
+ gtk_box_pack_start (GTK_BOX (hbox2), volumebar, FALSE, TRUE, 2);
+ gtk_widget_set_size_request (volumebar, 70, -1);
+ gtk_widget_set_events (volumebar, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+ seekbar = gtk_drawing_area_new ();
+ gtk_widget_show (seekbar);
+ gtk_box_pack_start (GTK_BOX (hbox2), seekbar, FALSE, TRUE, 2);
+ gtk_widget_set_size_request (seekbar, 200, -1);
+ gtk_widget_set_events (seekbar, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+ table1 = gtk_table_new (2, 2, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
+
+ _ = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (_);
+ gtk_table_attach (GTK_TABLE (table1), _, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (_), 3);
+
+ vbox3 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox3);
+ gtk_box_pack_start (GTK_BOX (_), vbox3, TRUE, TRUE, 0);
+
+ header = gtk_drawing_area_new ();
+ gtk_widget_show (header);
+ gtk_box_pack_start (GTK_BOX (vbox3), header, FALSE, TRUE, 0);
+ gtk_widget_set_size_request (header, -1, 24);
+ gtk_widget_set_events (header, GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+ playlist = gtk_drawing_area_new ();
+ gtk_widget_show (playlist);
+ gtk_box_pack_start (GTK_BOX (vbox3), playlist, TRUE, TRUE, 0);
+ gtk_widget_set_events (playlist, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+ playscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1, 1, 0, 0)));
+ gtk_widget_show (playscroll);
+ gtk_table_attach (GTK_TABLE (table1), playscroll, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ playhscroll = gtk_hscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0)));
+ gtk_widget_show (playhscroll);
+ gtk_table_attach (GTK_TABLE (table1), playhscroll, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ statusbar = gtk_statusbar_new ();
+ gtk_widget_show (statusbar);
+ gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0);
+
+ g_signal_connect ((gpointer) mainwin, "key_press_event",
+ G_CALLBACK (on_mainwin_key_press_event),
+ NULL);
+ g_signal_connect ((gpointer) mainwin, "delete_event",
+ G_CALLBACK (on_mainwin_delete_event),
+ NULL);
+ g_signal_connect ((gpointer) mainwin, "configure_event",
+ G_CALLBACK (on_mainwin_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) open, "activate",
+ G_CALLBACK (on_open_activate),
+ NULL);
+ g_signal_connect ((gpointer) add_files, "activate",
+ G_CALLBACK (on_add_files_activate),
+ NULL);
+ g_signal_connect ((gpointer) add_folders, "activate",
+ G_CALLBACK (on_add_folders_activate),
+ NULL);
+ g_signal_connect ((gpointer) add_audio_cd, "activate",
+ G_CALLBACK (on_add_audio_cd_activate),
+ NULL);
+ g_signal_connect ((gpointer) add_location1, "activate",
+ G_CALLBACK (on_add_location_activate),
+ NULL);
+ g_signal_connect ((gpointer) quit, "activate",
+ G_CALLBACK (on_quit_activate),
+ NULL);
+ g_signal_connect ((gpointer) clear1, "activate",
+ G_CALLBACK (on_clear1_activate),
+ NULL);
+ g_signal_connect ((gpointer) select_all1, "activate",
+ G_CALLBACK (on_select_all1_activate),
+ NULL);
+ g_signal_connect ((gpointer) remove1, "activate",
+ G_CALLBACK (on_remove1_activate),
+ NULL);
+ g_signal_connect ((gpointer) crop1, "activate",
+ G_CALLBACK (on_crop1_activate),
+ NULL);
+ g_signal_connect ((gpointer) find1, "activate",
+ G_CALLBACK (on_find_activate),
+ NULL);
+ g_signal_connect ((gpointer) preferences, "activate",
+ G_CALLBACK (on_preferences_activate),
+ NULL);
+ g_signal_connect ((gpointer) playlist_load, "activate",
+ G_CALLBACK (on_playlist_load_activate),
+ NULL);
+ g_signal_connect ((gpointer) playlist_save, "activate",
+ G_CALLBACK (on_playlist_save_activate),
+ NULL);
+ g_signal_connect ((gpointer) playlist_save_as, "activate",
+ G_CALLBACK (on_playlist_save_as_activate),
+ NULL);
+ g_signal_connect ((gpointer) order_linear, "activate",
+ G_CALLBACK (on_order_linear_activate),
+ NULL);
+ g_signal_connect ((gpointer) order_shuffle, "activate",
+ G_CALLBACK (on_order_shuffle_activate),
+ NULL);
+ g_signal_connect ((gpointer) order_random, "activate",
+ G_CALLBACK (on_order_random_activate),
+ NULL);
+ g_signal_connect ((gpointer) loop_all, "activate",
+ G_CALLBACK (on_loop_all_activate),
+ NULL);
+ g_signal_connect ((gpointer) loop_single, "activate",
+ G_CALLBACK (on_loop_single_activate),
+ NULL);
+ g_signal_connect ((gpointer) loop_disable, "activate",
+ G_CALLBACK (on_loop_disable_activate),
+ NULL);
+ g_signal_connect ((gpointer) scroll_follows_playback, "activate",
+ G_CALLBACK (on_scroll_follows_playback_activate),
+ NULL);
+ g_signal_connect ((gpointer) about1, "activate",
+ G_CALLBACK (on_about1_activate),
+ NULL);
+ g_signal_connect ((gpointer) help1, "activate",
+ G_CALLBACK (on_help1_activate),
+ NULL);
+ g_signal_connect ((gpointer) stopbtn, "clicked",
+ G_CALLBACK (on_stopbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) playbtn, "clicked",
+ G_CALLBACK (on_playbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pausebtn, "clicked",
+ G_CALLBACK (on_pausebtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) prevbtn, "clicked",
+ G_CALLBACK (on_prevbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) nextbtn, "clicked",
+ G_CALLBACK (on_nextbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) playrand, "clicked",
+ G_CALLBACK (on_playrand_clicked),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "button_press_event",
+ G_CALLBACK (on_volumebar_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "button_release_event",
+ G_CALLBACK (on_volumebar_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "configure_event",
+ G_CALLBACK (on_volumebar_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "expose_event",
+ G_CALLBACK (on_volumebar_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "motion_notify_event",
+ G_CALLBACK (on_volumebar_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) volumebar, "scroll_event",
+ G_CALLBACK (on_volumebar_scroll_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "button_press_event",
+ G_CALLBACK (on_seekbar_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "button_release_event",
+ G_CALLBACK (on_seekbar_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "configure_event",
+ G_CALLBACK (on_seekbar_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "expose_event",
+ G_CALLBACK (on_seekbar_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "motion_notify_event",
+ G_CALLBACK (on_seekbar_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) header, "expose_event",
+ G_CALLBACK (on_header_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) header, "configure_event",
+ G_CALLBACK (on_header_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) header, "realize",
+ G_CALLBACK (on_header_realize),
+ NULL);
+ g_signal_connect ((gpointer) header, "motion_notify_event",
+ G_CALLBACK (on_header_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) header, "button_press_event",
+ G_CALLBACK (on_header_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) header, "button_release_event",
+ G_CALLBACK (on_header_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "configure_event",
+ G_CALLBACK (on_playlist_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "expose_event",
+ G_CALLBACK (on_playlist_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "realize",
+ G_CALLBACK (on_playlist_realize),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "button_press_event",
+ G_CALLBACK (on_playlist_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "scroll_event",
+ G_CALLBACK (on_playlist_scroll_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_begin",
+ G_CALLBACK (on_playlist_drag_begin),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_motion",
+ G_CALLBACK (on_playlist_drag_motion),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_drop",
+ G_CALLBACK (on_playlist_drag_drop),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_data_get",
+ G_CALLBACK (on_playlist_drag_data_get),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_end",
+ G_CALLBACK (on_playlist_drag_end),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_failed",
+ G_CALLBACK (on_playlist_drag_failed),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_leave",
+ G_CALLBACK (on_playlist_drag_leave),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "button_release_event",
+ G_CALLBACK (on_playlist_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "motion_notify_event",
+ G_CALLBACK (on_playlist_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_data_received",
+ G_CALLBACK (on_playlist_drag_data_received),
+ NULL);
+ g_signal_connect ((gpointer) playlist, "drag_data_delete",
+ G_CALLBACK (on_playlist_drag_data_delete),
+ NULL);
+ g_signal_connect ((gpointer) playscroll, "value_changed",
+ G_CALLBACK (on_playscroll_value_changed),
+ NULL);
+ g_signal_connect ((gpointer) playhscroll, "value_changed",
+ G_CALLBACK (on_playhscroll_value_changed),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (mainwin, mainwin, "mainwin");
+ GLADE_HOOKUP_OBJECT (mainwin, vbox1, "vbox1");
+ GLADE_HOOKUP_OBJECT (mainwin, menubar1, "menubar1");
+ GLADE_HOOKUP_OBJECT (mainwin, menuitem1, "menuitem1");
+ GLADE_HOOKUP_OBJECT (mainwin, menuitem1_menu, "menuitem1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, open, "open");
+ GLADE_HOOKUP_OBJECT (mainwin, image120, "image120");
+ GLADE_HOOKUP_OBJECT (mainwin, separator2, "separator2");
+ GLADE_HOOKUP_OBJECT (mainwin, add_files, "add_files");
+ GLADE_HOOKUP_OBJECT (mainwin, image121, "image121");
+ GLADE_HOOKUP_OBJECT (mainwin, add_folders, "add_folders");
+ GLADE_HOOKUP_OBJECT (mainwin, image122, "image122");
+ GLADE_HOOKUP_OBJECT (mainwin, add_audio_cd, "add_audio_cd");
+ GLADE_HOOKUP_OBJECT (mainwin, image123, "image123");
+ GLADE_HOOKUP_OBJECT (mainwin, add_location1, "add_location1");
+ GLADE_HOOKUP_OBJECT (mainwin, separatormenuitem1, "separatormenuitem1");
+ GLADE_HOOKUP_OBJECT (mainwin, quit, "quit");
+ GLADE_HOOKUP_OBJECT (mainwin, image124, "image124");
+ GLADE_HOOKUP_OBJECT (mainwin, edit1, "edit1");
+ GLADE_HOOKUP_OBJECT (mainwin, edit1_menu, "edit1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, clear1, "clear1");
+ GLADE_HOOKUP_OBJECT (mainwin, image125, "image125");
+ GLADE_HOOKUP_OBJECT (mainwin, select_all1, "select_all1");
+ GLADE_HOOKUP_OBJECT (mainwin, selection1, "selection1");
+ GLADE_HOOKUP_OBJECT (mainwin, selection1_menu, "selection1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, remove1, "remove1");
+ GLADE_HOOKUP_OBJECT (mainwin, image126, "image126");
+ GLADE_HOOKUP_OBJECT (mainwin, crop1, "crop1");
+ GLADE_HOOKUP_OBJECT (mainwin, find1, "find1");
+ GLADE_HOOKUP_OBJECT (mainwin, separator5, "separator5");
+ GLADE_HOOKUP_OBJECT (mainwin, preferences, "preferences");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist1, "playlist1");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist1_menu, "playlist1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist_load, "playlist_load");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist_save, "playlist_save");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist_save_as, "playlist_save_as");
+ GLADE_HOOKUP_OBJECT (mainwin, order1, "order1");
+ GLADE_HOOKUP_OBJECT (mainwin, order1_menu, "order1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, order_linear, "order_linear");
+ GLADE_HOOKUP_OBJECT (mainwin, order_shuffle, "order_shuffle");
+ GLADE_HOOKUP_OBJECT (mainwin, order_random, "order_random");
+ GLADE_HOOKUP_OBJECT (mainwin, looping1, "looping1");
+ GLADE_HOOKUP_OBJECT (mainwin, looping1_menu, "looping1_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, loop_all, "loop_all");
+ GLADE_HOOKUP_OBJECT (mainwin, loop_single, "loop_single");
+ GLADE_HOOKUP_OBJECT (mainwin, loop_disable, "loop_disable");
+ GLADE_HOOKUP_OBJECT (mainwin, scroll_follows_playback, "scroll_follows_playback");
+ GLADE_HOOKUP_OBJECT (mainwin, menuitem4, "menuitem4");
+ GLADE_HOOKUP_OBJECT (mainwin, menuitem4_menu, "menuitem4_menu");
+ GLADE_HOOKUP_OBJECT (mainwin, about1, "about1");
+ GLADE_HOOKUP_OBJECT (mainwin, help1, "help1");
+ GLADE_HOOKUP_OBJECT (mainwin, image127, "image127");
+ GLADE_HOOKUP_OBJECT (mainwin, hbox2, "hbox2");
+ GLADE_HOOKUP_OBJECT (mainwin, hbox3, "hbox3");
+ GLADE_HOOKUP_OBJECT (mainwin, stopbtn, "stopbtn");
+ GLADE_HOOKUP_OBJECT (mainwin, image7, "image7");
+ GLADE_HOOKUP_OBJECT (mainwin, playbtn, "playbtn");
+ GLADE_HOOKUP_OBJECT (mainwin, image2, "image2");
+ GLADE_HOOKUP_OBJECT (mainwin, pausebtn, "pausebtn");
+ GLADE_HOOKUP_OBJECT (mainwin, image3, "image3");
+ GLADE_HOOKUP_OBJECT (mainwin, prevbtn, "prevbtn");
+ GLADE_HOOKUP_OBJECT (mainwin, image4, "image4");
+ GLADE_HOOKUP_OBJECT (mainwin, nextbtn, "nextbtn");
+ GLADE_HOOKUP_OBJECT (mainwin, image5, "image5");
+ GLADE_HOOKUP_OBJECT (mainwin, playrand, "playrand");
+ GLADE_HOOKUP_OBJECT (mainwin, image6, "image6");
+ GLADE_HOOKUP_OBJECT (mainwin, volumebar, "volumebar");
+ GLADE_HOOKUP_OBJECT (mainwin, seekbar, "seekbar");
+ GLADE_HOOKUP_OBJECT (mainwin, table1, "table1");
+ GLADE_HOOKUP_OBJECT (mainwin, _, "_");
+ GLADE_HOOKUP_OBJECT (mainwin, vbox3, "vbox3");
+ GLADE_HOOKUP_OBJECT (mainwin, header, "header");
+ GLADE_HOOKUP_OBJECT (mainwin, playlist, "playlist");
+ GLADE_HOOKUP_OBJECT (mainwin, playscroll, "playscroll");
+ GLADE_HOOKUP_OBJECT (mainwin, playhscroll, "playhscroll");
+ GLADE_HOOKUP_OBJECT (mainwin, statusbar, "statusbar");
+
+ gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group);
+
+ return mainwin;
+}
+
+GtkWidget*
+create_searchwin (void)
+{
+ GtkWidget *searchwin;
+ GtkWidget *vbox4;
+ GtkWidget *searchentry;
+ GtkWidget *table2;
+ GtkWidget *searchscroll;
+ GtkWidget *vbox5;
+ GtkWidget *searchheader;
+ GtkWidget *searchlist;
+ GtkWidget *searchhscroll;
+
+ searchwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_size_request (searchwin, 600, 150);
+ gtk_widget_set_events (searchwin, GDK_KEY_PRESS_MASK);
+ gtk_window_set_title (GTK_WINDOW (searchwin), "Search");
+ gtk_window_set_position (GTK_WINDOW (searchwin), GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (searchwin), TRUE);
+ gtk_window_set_skip_pager_hint (GTK_WINDOW (searchwin), TRUE);
+
+ vbox4 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox4);
+ gtk_container_add (GTK_CONTAINER (searchwin), vbox4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox4), 4);
+
+ searchentry = gtk_entry_new ();
+ gtk_widget_show (searchentry);
+ gtk_box_pack_start (GTK_BOX (vbox4), searchentry, FALSE, FALSE, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (searchentry), 8226);
+ gtk_entry_set_activates_default (GTK_ENTRY (searchentry), TRUE);
+
+ table2 = gtk_table_new (2, 2, FALSE);
+ gtk_widget_show (table2);
+ gtk_box_pack_start (GTK_BOX (vbox4), table2, TRUE, TRUE, 0);
+
+ searchscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1, 1, 0, 0)));
+ gtk_widget_show (searchscroll);
+ gtk_table_attach (GTK_TABLE (table2), searchscroll, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ vbox5 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox5);
+ gtk_table_attach (GTK_TABLE (table2), vbox5, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+ searchheader = gtk_drawing_area_new ();
+ gtk_widget_show (searchheader);
+ gtk_box_pack_start (GTK_BOX (vbox5), searchheader, FALSE, TRUE, 0);
+ gtk_widget_set_size_request (searchheader, -1, 24);
+ gtk_widget_set_events (searchheader, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+ searchlist = gtk_drawing_area_new ();
+ gtk_widget_show (searchlist);
+ gtk_box_pack_start (GTK_BOX (vbox5), searchlist, TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS (searchlist, GTK_CAN_DEFAULT);
+ gtk_widget_set_events (searchlist, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+ searchhscroll = gtk_hscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0)));
+ gtk_widget_show (searchhscroll);
+ gtk_table_attach (GTK_TABLE (table2), searchhscroll, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ g_signal_connect ((gpointer) searchwin, "key_press_event",
+ G_CALLBACK (on_searchwin_key_press_event),
+ NULL);
+ g_signal_connect ((gpointer) searchwin, "delete_event",
+ G_CALLBACK (gtk_widget_hide_on_delete),
+ NULL);
+ g_signal_connect ((gpointer) searchentry, "changed",
+ G_CALLBACK (on_searchentry_changed),
+ NULL);
+ g_signal_connect ((gpointer) searchscroll, "value_changed",
+ G_CALLBACK (on_playscroll_value_changed),
+ NULL);
+ g_signal_connect ((gpointer) searchheader, "button_press_event",
+ G_CALLBACK (on_header_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) searchheader, "button_release_event",
+ G_CALLBACK (on_header_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) searchheader, "configure_event",
+ G_CALLBACK (on_header_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) searchheader, "expose_event",
+ G_CALLBACK (on_header_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) searchheader, "motion_notify_event",
+ G_CALLBACK (on_header_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "button_press_event",
+ G_CALLBACK (on_playlist_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "configure_event",
+ G_CALLBACK (on_searchlist_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "expose_event",
+ G_CALLBACK (on_playlist_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "scroll_event",
+ G_CALLBACK (on_playlist_scroll_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "realize",
+ G_CALLBACK (on_searchlist_realize),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "button_release_event",
+ G_CALLBACK (on_playlist_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) searchlist, "motion_notify_event",
+ G_CALLBACK (on_playlist_motion_notify_event),
+ NULL);
+ g_signal_connect ((gpointer) searchhscroll, "value_changed",
+ G_CALLBACK (on_searchhscroll_value_changed),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (searchwin, searchwin, "searchwin");
+ GLADE_HOOKUP_OBJECT (searchwin, vbox4, "vbox4");
+ GLADE_HOOKUP_OBJECT (searchwin, searchentry, "searchentry");
+ GLADE_HOOKUP_OBJECT (searchwin, table2, "table2");
+ GLADE_HOOKUP_OBJECT (searchwin, searchscroll, "searchscroll");
+ GLADE_HOOKUP_OBJECT (searchwin, vbox5, "vbox5");
+ GLADE_HOOKUP_OBJECT (searchwin, searchheader, "searchheader");
+ GLADE_HOOKUP_OBJECT (searchwin, searchlist, "searchlist");
+ GLADE_HOOKUP_OBJECT (searchwin, searchhscroll, "searchhscroll");
+
+ gtk_widget_grab_default (searchlist);
+ return searchwin;
+}
+
+GtkWidget*
+create_traymenu (void)
+{
+ GtkWidget *traymenu;
+ GtkWidget *stop2;
+ GtkWidget *image59;
+ GtkWidget *play2;
+ GtkWidget *image60;
+ GtkWidget *pause2;
+ GtkWidget *image61;
+ GtkWidget *previous2;
+ GtkWidget *image62;
+ GtkWidget *next2;
+ GtkWidget *image63;
+ GtkWidget *play_random1;
+ GtkWidget *separator4;
+ GtkWidget *about3;
+ GtkWidget *image64;
+ GtkWidget *separator3;
+ GtkWidget *quit;
+ GtkWidget *image65;
+
+ traymenu = gtk_menu_new ();
+
+ stop2 = gtk_image_menu_item_new_with_mnemonic ("Stop");
+ gtk_widget_show (stop2);
+ gtk_container_add (GTK_CONTAINER (traymenu), stop2);
+
+ image59 = gtk_image_new_from_stock ("gtk-media-stop", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image59);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stop2), image59);
+
+ play2 = gtk_image_menu_item_new_with_mnemonic ("Play");
+ gtk_widget_show (play2);
+ gtk_container_add (GTK_CONTAINER (traymenu), play2);
+
+ image60 = gtk_image_new_from_stock ("gtk-media-play", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image60);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (play2), image60);
+
+ pause2 = gtk_image_menu_item_new_with_mnemonic ("Pause");
+ gtk_widget_show (pause2);
+ gtk_container_add (GTK_CONTAINER (traymenu), pause2);
+
+ image61 = gtk_image_new_from_stock ("gtk-media-pause", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image61);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pause2), image61);
+
+ previous2 = gtk_image_menu_item_new_with_mnemonic ("Previous");
+ gtk_widget_show (previous2);
+ gtk_container_add (GTK_CONTAINER (traymenu), previous2);
+
+ image62 = gtk_image_new_from_stock ("gtk-media-previous", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image62);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous2), image62);
+
+ next2 = gtk_image_menu_item_new_with_mnemonic ("Next");
+ gtk_widget_show (next2);
+ gtk_container_add (GTK_CONTAINER (traymenu), next2);
+
+ image63 = gtk_image_new_from_stock ("gtk-media-next", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image63);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next2), image63);
+
+ play_random1 = gtk_menu_item_new_with_mnemonic ("Play Random");
+ gtk_widget_show (play_random1);
+ gtk_container_add (GTK_CONTAINER (traymenu), play_random1);
+
+ separator4 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator4);
+ gtk_container_add (GTK_CONTAINER (traymenu), separator4);
+ gtk_widget_set_sensitive (separator4, FALSE);
+
+ about3 = gtk_image_menu_item_new_with_mnemonic ("About");
+ gtk_widget_show (about3);
+ gtk_container_add (GTK_CONTAINER (traymenu), about3);
+
+ image64 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image64);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (about3), image64);
+
+ separator3 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator3);
+ gtk_container_add (GTK_CONTAINER (traymenu), separator3);
+ gtk_widget_set_sensitive (separator3, FALSE);
+
+ quit = gtk_image_menu_item_new_with_mnemonic ("Quit");
+ gtk_widget_show (quit);
+ gtk_container_add (GTK_CONTAINER (traymenu), quit);
+
+ image65 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image65);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (quit), image65);
+
+ g_signal_connect ((gpointer) stop2, "activate",
+ G_CALLBACK (on_stopbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) play2, "activate",
+ G_CALLBACK (on_playbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pause2, "activate",
+ G_CALLBACK (on_pausebtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) previous2, "activate",
+ G_CALLBACK (on_prevbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) next2, "activate",
+ G_CALLBACK (on_nextbtn_clicked),
+ NULL);
+ g_signal_connect ((gpointer) play_random1, "activate",
+ G_CALLBACK (on_playrand_clicked),
+ NULL);
+ g_signal_connect ((gpointer) about3, "activate",
+ G_CALLBACK (on_about1_activate),
+ NULL);
+ g_signal_connect ((gpointer) quit, "activate",
+ G_CALLBACK (on_quit_activate),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (traymenu, traymenu, "traymenu");
+ GLADE_HOOKUP_OBJECT (traymenu, stop2, "stop2");
+ GLADE_HOOKUP_OBJECT (traymenu, image59, "image59");
+ GLADE_HOOKUP_OBJECT (traymenu, play2, "play2");
+ GLADE_HOOKUP_OBJECT (traymenu, image60, "image60");
+ GLADE_HOOKUP_OBJECT (traymenu, pause2, "pause2");
+ GLADE_HOOKUP_OBJECT (traymenu, image61, "image61");
+ GLADE_HOOKUP_OBJECT (traymenu, previous2, "previous2");
+ GLADE_HOOKUP_OBJECT (traymenu, image62, "image62");
+ GLADE_HOOKUP_OBJECT (traymenu, next2, "next2");
+ GLADE_HOOKUP_OBJECT (traymenu, image63, "image63");
+ GLADE_HOOKUP_OBJECT (traymenu, play_random1, "play_random1");
+ GLADE_HOOKUP_OBJECT (traymenu, separator4, "separator4");
+ GLADE_HOOKUP_OBJECT (traymenu, about3, "about3");
+ GLADE_HOOKUP_OBJECT (traymenu, image64, "image64");
+ GLADE_HOOKUP_OBJECT (traymenu, separator3, "separator3");
+ GLADE_HOOKUP_OBJECT (traymenu, quit, "quit");
+ GLADE_HOOKUP_OBJECT (traymenu, image65, "image65");
+
+ return traymenu;
+}
+
+GtkWidget*
+create_addprogress (void)
+{
+ GtkWidget *addprogress;
+ GtkWidget *vbox6;
+ GtkWidget *progresstitle;
+ GtkWidget *hbox7;
+ GtkWidget *label22;
+ GtkWidget *button1;
+
+ addprogress = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (addprogress), "Adding files...");
+ gtk_window_set_position (GTK_WINDOW (addprogress), GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (addprogress), TRUE);
+ gtk_window_set_skip_pager_hint (GTK_WINDOW (addprogress), TRUE);
+
+ vbox6 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox6);
+ gtk_container_add (GTK_CONTAINER (addprogress), vbox6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox6), 4);
+
+ progresstitle = gtk_entry_new ();
+ gtk_widget_show (progresstitle);
+ gtk_box_pack_start (GTK_BOX (vbox6), progresstitle, TRUE, FALSE, 0);
+ gtk_widget_set_size_request (progresstitle, 500, -1);
+ GTK_WIDGET_UNSET_FLAGS (progresstitle, GTK_CAN_FOCUS);
+ gtk_editable_set_editable (GTK_EDITABLE (progresstitle), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (progresstitle), 8226);
+
+ hbox7 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox7);
+ gtk_box_pack_start (GTK_BOX (vbox6), hbox7, FALSE, TRUE, 2);
+
+ label22 = gtk_label_new ("");
+ gtk_widget_show (label22);
+ gtk_box_pack_start (GTK_BOX (hbox7), label22, TRUE, FALSE, 0);
+
+ button1 = gtk_button_new_with_mnemonic ("Abort");
+ gtk_widget_show (button1);
+ gtk_box_pack_start (GTK_BOX (hbox7), button1, FALSE, FALSE, 0);
+ gtk_widget_set_size_request (button1, 83, -1);
+ GTK_WIDGET_UNSET_FLAGS (button1, GTK_CAN_FOCUS);
+
+ g_signal_connect ((gpointer) addprogress, "delete_event",
+ G_CALLBACK (on_addprogress_delete_event),
+ NULL);
+ g_signal_connect ((gpointer) button1, "clicked",
+ G_CALLBACK (on_progress_abort),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (addprogress, addprogress, "addprogress");
+ GLADE_HOOKUP_OBJECT (addprogress, vbox6, "vbox6");
+ GLADE_HOOKUP_OBJECT (addprogress, progresstitle, "progresstitle");
+ GLADE_HOOKUP_OBJECT (addprogress, hbox7, "hbox7");
+ GLADE_HOOKUP_OBJECT (addprogress, label22, "label22");
+ GLADE_HOOKUP_OBJECT (addprogress, button1, "button1");
+
+ return addprogress;
+}
+
+GtkWidget*
+create_helpwindow (void)
+{
+ GtkWidget *helpwindow;
+ GtkWidget *scrolledwindow1;
+ GtkWidget *helptext;
+
+ helpwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_size_request (helpwindow, 600, 400);
+ gtk_widget_set_events (helpwindow, GDK_KEY_PRESS_MASK);
+ gtk_window_set_title (GTK_WINDOW (helpwindow), "Help");
+ gtk_window_set_modal (GTK_WINDOW (helpwindow), TRUE);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (helpwindow), TRUE);
+
+ scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow1);
+ gtk_container_add (GTK_CONTAINER (helpwindow), scrolledwindow1);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ helptext = gtk_text_view_new ();
+ gtk_widget_show (helptext);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow1), helptext);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (helptext), FALSE);
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (helptext), GTK_WRAP_WORD);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (helptext), 10);
+ gtk_text_view_set_right_margin (GTK_TEXT_VIEW (helptext), 10);
+
+ g_signal_connect ((gpointer) helpwindow, "key_press_event",
+ G_CALLBACK (on_helpwindow_key_press_event),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (helpwindow, helpwindow, "helpwindow");
+ GLADE_HOOKUP_OBJECT (helpwindow, scrolledwindow1, "scrolledwindow1");
+ GLADE_HOOKUP_OBJECT (helpwindow, helptext, "helptext");
+
+ return helpwindow;
+}
+
+GtkWidget*
+create_prefwin (void)
+{
+ GtkWidget *prefwin;
+ GtkWidget *notebook2;
+ GtkWidget *table3;
+ GtkWidget *label4;
+ GtkWidget *label5;
+ GtkWidget *label6;
+ GtkWidget *label8;
+ GtkWidget *label9;
+ GtkWidget *label15;
+ GtkWidget *pref_alsa_resampling;
+ GtkWidget *pref_replaygain_scale;
+ GtkWidget *pref_alsa_freewhenstopped;
+ GtkWidget *pref_soundcard;
+ GtkWidget *pref_src_quality;
+ GtkWidget *pref_replaygain_mode;
+ GtkWidget *Sound;
+ GtkWidget *table4;
+ GtkWidget *label7;
+ GtkWidget *pref_close_send_to_tray;
+ GtkWidget *label2;
+ GtkWidget *table6;
+ GtkWidget *label17;
+ GtkWidget *label18;
+ GtkWidget *pref_network_proxyaddress;
+ GtkWidget *pref_network_enableproxy;
+ GtkWidget *label19;
+ GtkWidget *pref_network_proxyport;
+ GtkWidget *label20;
+ GtkWidget *pref_network_proxytype;
+ GtkWidget *label16;
+ GtkWidget *hpaned1;
+ GtkWidget *scrolledwindow2;
+ GtkWidget *pref_pluginlist;
+ GtkWidget *table5;
+ GtkWidget *label11;
+ GtkWidget *label12;
+ GtkWidget *label13;
+ GtkWidget *label14;
+ GtkWidget *pref_plugin_descr;
+ GtkWidget *pref_plugin_author;
+ GtkWidget *pref_plugin_email;
+ GtkWidget *pref_plugin_website;
+ GtkWidget *label3;
+
+ prefwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_size_request (prefwin, 642, 372);
+ gtk_window_set_title (GTK_WINDOW (prefwin), "Preferences");
+ gtk_window_set_modal (GTK_WINDOW (prefwin), TRUE);
+
+ notebook2 = gtk_notebook_new ();
+ gtk_widget_show (notebook2);
+ gtk_container_add (GTK_CONTAINER (prefwin), notebook2);
+
+ table3 = gtk_table_new (6, 2, FALSE);
+ gtk_widget_show (table3);
+ gtk_container_add (GTK_CONTAINER (notebook2), table3);
+ gtk_container_set_border_width (GTK_CONTAINER (table3), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table3), 3);
+
+ label4 = gtk_label_new ("Output device");
+ gtk_widget_show (label4);
+ gtk_table_attach (GTK_TABLE (table3), label4, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
+
+ label5 = gtk_label_new ("Software ALSA resampling");
+ gtk_widget_show (label5);
+ gtk_table_attach (GTK_TABLE (table3), label5, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
+
+ label6 = gtk_label_new ("SRC quality (libsamplerate)");
+ gtk_widget_show (label6);
+ gtk_table_attach (GTK_TABLE (table3), label6, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
+
+ label8 = gtk_label_new ("Replaygain mode");
+ gtk_widget_show (label8);
+ gtk_table_attach (GTK_TABLE (table3), label8, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label8), 0, 0.5);
+
+ label9 = gtk_label_new ("Replaygain peak scale");
+ gtk_widget_show (label9);
+ gtk_table_attach (GTK_TABLE (table3), label9, 0, 1, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5);
+
+ label15 = gtk_label_new ("Release ALSA while stopped");
+ gtk_widget_show (label15);
+ gtk_table_attach (GTK_TABLE (table3), label15, 0, 1, 5, 6,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label15), 0, 0.5);
+
+ pref_alsa_resampling = gtk_check_button_new_with_mnemonic ("");
+ gtk_widget_show (pref_alsa_resampling);
+ gtk_table_attach (GTK_TABLE (table3), pref_alsa_resampling, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ pref_replaygain_scale = gtk_check_button_new_with_mnemonic ("");
+ gtk_widget_show (pref_replaygain_scale);
+ gtk_table_attach (GTK_TABLE (table3), pref_replaygain_scale, 1, 2, 4, 5,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ pref_alsa_freewhenstopped = gtk_check_button_new_with_mnemonic ("");
+ gtk_widget_show (pref_alsa_freewhenstopped);
+ gtk_table_attach (GTK_TABLE (table3), pref_alsa_freewhenstopped, 1, 2, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ pref_soundcard = gtk_combo_box_new_text ();
+ gtk_widget_show (pref_soundcard);
+ gtk_table_attach (GTK_TABLE (table3), pref_soundcard, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ pref_src_quality = gtk_combo_box_new_text ();
+ gtk_widget_show (pref_src_quality);
+ gtk_table_attach (GTK_TABLE (table3), pref_src_quality, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_best_quality");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_medium_quality");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_fastest");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "sinc_zero_order_hold");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_src_quality), "linear");
+
+ pref_replaygain_mode = gtk_combo_box_new_text ();
+ gtk_widget_show (pref_replaygain_mode);
+ gtk_table_attach (GTK_TABLE (table3), pref_replaygain_mode, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_replaygain_mode), "Disable");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_replaygain_mode), "Track");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_replaygain_mode), "Album");
+
+ Sound = gtk_label_new ("Sound");
+ gtk_widget_show (Sound);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 0), Sound);
+
+ table4 = gtk_table_new (1, 2, FALSE);
+ gtk_widget_show (table4);
+ gtk_container_add (GTK_CONTAINER (notebook2), table4);
+ gtk_container_set_border_width (GTK_CONTAINER (table4), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table4), 3);
+
+ label7 = gtk_label_new ("Close minimizes to tray");
+ gtk_widget_show (label7);
+ gtk_table_attach (GTK_TABLE (table4), label7, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
+
+ pref_close_send_to_tray = gtk_check_button_new_with_mnemonic ("");
+ gtk_widget_show (pref_close_send_to_tray);
+ gtk_table_attach (GTK_TABLE (table4), pref_close_send_to_tray, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ label2 = gtk_label_new ("GUI");
+ gtk_widget_show (label2);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 1), label2);
+
+ table6 = gtk_table_new (4, 2, FALSE);
+ gtk_widget_show (table6);
+ gtk_container_add (GTK_CONTAINER (notebook2), table6);
+ gtk_container_set_border_width (GTK_CONTAINER (table6), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table6), 3);
+
+ label17 = gtk_label_new ("Enable proxy server");
+ gtk_widget_show (label17);
+ gtk_table_attach (GTK_TABLE (table6), label17, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label17), 0, 0.5);
+
+ label18 = gtk_label_new ("Proxy server address");
+ gtk_widget_show (label18);
+ gtk_table_attach (GTK_TABLE (table6), label18, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label18), 0, 0.5);
+
+ pref_network_proxyaddress = gtk_entry_new ();
+ gtk_widget_show (pref_network_proxyaddress);
+ gtk_table_attach (GTK_TABLE (table6), pref_network_proxyaddress, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_network_proxyaddress), 8226);
+
+ pref_network_enableproxy = gtk_check_button_new_with_mnemonic ("");
+ gtk_widget_show (pref_network_enableproxy);
+ gtk_table_attach (GTK_TABLE (table6), pref_network_enableproxy, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ label19 = gtk_label_new ("Proxy server port");
+ gtk_widget_show (label19);
+ gtk_table_attach (GTK_TABLE (table6), label19, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label19), 0, 0.5);
+
+ pref_network_proxyport = gtk_entry_new ();
+ gtk_widget_show (pref_network_proxyport);
+ gtk_table_attach (GTK_TABLE (table6), pref_network_proxyport, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_network_proxyport), 8226);
+
+ label20 = gtk_label_new ("Proxy type");
+ gtk_widget_show (label20);
+ gtk_table_attach (GTK_TABLE (table6), label20, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label20), 0, 0.5);
+
+ pref_network_proxytype = gtk_combo_box_new_text ();
+ gtk_widget_show (pref_network_proxytype);
+ gtk_table_attach (GTK_TABLE (table6), pref_network_proxytype, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "HTTP");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "HTTP_1_0");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "SOCKS4");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "SOCKS5");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "SOCKS4A");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (pref_network_proxytype), "SOCKS5_HOSTNAME");
+
+ label16 = gtk_label_new ("Network");
+ gtk_widget_show (label16);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 2), label16);
+
+ hpaned1 = gtk_hpaned_new ();
+ gtk_widget_show (hpaned1);
+ gtk_container_add (GTK_CONTAINER (notebook2), hpaned1);
+
+ scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow2);
+ gtk_paned_pack1 (GTK_PANED (hpaned1), scrolledwindow2, FALSE, TRUE);
+ gtk_widget_set_size_request (scrolledwindow2, 280, -1);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_IN);
+
+ pref_pluginlist = gtk_tree_view_new ();
+ gtk_widget_show (pref_pluginlist);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow2), pref_pluginlist);
+
+ table5 = gtk_table_new (4, 2, FALSE);
+ gtk_widget_show (table5);
+ gtk_paned_pack2 (GTK_PANED (hpaned1), table5, TRUE, TRUE);
+ gtk_widget_set_size_request (table5, 400, -1);
+
+ label11 = gtk_label_new ("Description");
+ gtk_widget_show (label11);
+ gtk_table_attach (GTK_TABLE (table5), label11, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5);
+
+ label12 = gtk_label_new ("Author(s)");
+ gtk_widget_show (label12);
+ gtk_table_attach (GTK_TABLE (table5), label12, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label12), 0, 0.5);
+
+ label13 = gtk_label_new ("Email");
+ gtk_widget_show (label13);
+ gtk_table_attach (GTK_TABLE (table5), label13, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label13), 0, 0.5);
+
+ label14 = gtk_label_new ("Website");
+ gtk_widget_show (label14);
+ gtk_table_attach (GTK_TABLE (table5), label14, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label14), 0, 0.5);
+
+ pref_plugin_descr = gtk_entry_new ();
+ gtk_widget_show (pref_plugin_descr);
+ gtk_table_attach (GTK_TABLE (table5), pref_plugin_descr, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_descr), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_descr), 9679);
+
+ pref_plugin_author = gtk_entry_new ();
+ gtk_widget_show (pref_plugin_author);
+ gtk_table_attach (GTK_TABLE (table5), pref_plugin_author, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_author), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_author), 9679);
+
+ pref_plugin_email = gtk_entry_new ();
+ gtk_widget_show (pref_plugin_email);
+ gtk_table_attach (GTK_TABLE (table5), pref_plugin_email, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_email), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_email), 9679);
+
+ pref_plugin_website = gtk_entry_new ();
+ gtk_widget_show (pref_plugin_website);
+ gtk_table_attach (GTK_TABLE (table5), pref_plugin_website, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_editable_set_editable (GTK_EDITABLE (pref_plugin_website), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (pref_plugin_website), 9679);
+
+ label3 = gtk_label_new ("Plugins");
+ gtk_widget_show (label3);
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 3), label3);
+
+ g_signal_connect ((gpointer) prefwin, "key_press_event",
+ G_CALLBACK (on_prefwin_key_press_event),
+ NULL);
+ g_signal_connect ((gpointer) pref_alsa_resampling, "clicked",
+ G_CALLBACK (on_pref_alsa_resampling_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pref_replaygain_scale, "clicked",
+ G_CALLBACK (on_pref_replaygain_scale_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pref_alsa_freewhenstopped, "clicked",
+ G_CALLBACK (on_pref_alsa_freewhenstopped_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pref_soundcard, "changed",
+ G_CALLBACK (on_pref_soundcard_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_src_quality, "changed",
+ G_CALLBACK (on_pref_src_quality_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_replaygain_mode, "changed",
+ G_CALLBACK (on_pref_replaygain_mode_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_close_send_to_tray, "clicked",
+ G_CALLBACK (on_pref_close_send_to_tray_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pref_network_proxyaddress, "changed",
+ G_CALLBACK (on_pref_network_proxyaddress_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_network_enableproxy, "clicked",
+ G_CALLBACK (on_pref_network_enableproxy_clicked),
+ NULL);
+ g_signal_connect ((gpointer) pref_network_proxyport, "changed",
+ G_CALLBACK (on_pref_network_proxyport_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_network_proxytype, "changed",
+ G_CALLBACK (on_pref_network_proxytype_changed),
+ NULL);
+ g_signal_connect ((gpointer) pref_pluginlist, "cursor_changed",
+ G_CALLBACK (on_pref_pluginlist_cursor_changed),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (prefwin, prefwin, "prefwin");
+ GLADE_HOOKUP_OBJECT (prefwin, notebook2, "notebook2");
+ GLADE_HOOKUP_OBJECT (prefwin, table3, "table3");
+ GLADE_HOOKUP_OBJECT (prefwin, label4, "label4");
+ GLADE_HOOKUP_OBJECT (prefwin, label5, "label5");
+ GLADE_HOOKUP_OBJECT (prefwin, label6, "label6");
+ GLADE_HOOKUP_OBJECT (prefwin, label8, "label8");
+ GLADE_HOOKUP_OBJECT (prefwin, label9, "label9");
+ GLADE_HOOKUP_OBJECT (prefwin, label15, "label15");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_alsa_resampling, "pref_alsa_resampling");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_replaygain_scale, "pref_replaygain_scale");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_alsa_freewhenstopped, "pref_alsa_freewhenstopped");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_soundcard, "pref_soundcard");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_src_quality, "pref_src_quality");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_replaygain_mode, "pref_replaygain_mode");
+ GLADE_HOOKUP_OBJECT (prefwin, Sound, "Sound");
+ GLADE_HOOKUP_OBJECT (prefwin, table4, "table4");
+ GLADE_HOOKUP_OBJECT (prefwin, label7, "label7");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_close_send_to_tray, "pref_close_send_to_tray");
+ GLADE_HOOKUP_OBJECT (prefwin, label2, "label2");
+ GLADE_HOOKUP_OBJECT (prefwin, table6, "table6");
+ GLADE_HOOKUP_OBJECT (prefwin, label17, "label17");
+ GLADE_HOOKUP_OBJECT (prefwin, label18, "label18");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_network_proxyaddress, "pref_network_proxyaddress");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_network_enableproxy, "pref_network_enableproxy");
+ GLADE_HOOKUP_OBJECT (prefwin, label19, "label19");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_network_proxyport, "pref_network_proxyport");
+ GLADE_HOOKUP_OBJECT (prefwin, label20, "label20");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_network_proxytype, "pref_network_proxytype");
+ GLADE_HOOKUP_OBJECT (prefwin, label16, "label16");
+ GLADE_HOOKUP_OBJECT (prefwin, hpaned1, "hpaned1");
+ GLADE_HOOKUP_OBJECT (prefwin, scrolledwindow2, "scrolledwindow2");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_pluginlist, "pref_pluginlist");
+ GLADE_HOOKUP_OBJECT (prefwin, table5, "table5");
+ GLADE_HOOKUP_OBJECT (prefwin, label11, "label11");
+ GLADE_HOOKUP_OBJECT (prefwin, label12, "label12");
+ GLADE_HOOKUP_OBJECT (prefwin, label13, "label13");
+ GLADE_HOOKUP_OBJECT (prefwin, label14, "label14");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_descr, "pref_plugin_descr");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_author, "pref_plugin_author");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_email, "pref_plugin_email");
+ GLADE_HOOKUP_OBJECT (prefwin, pref_plugin_website, "pref_plugin_website");
+ GLADE_HOOKUP_OBJECT (prefwin, label3, "label3");
+
+ return prefwin;
+}
+
+GtkWidget*
+create_headermenu (void)
+{
+ GtkWidget *headermenu;
+ GtkWidget *add_column;
+ GtkWidget *add_column_menu;
+ GtkWidget *artist;
+ GtkWidget *album;
+ GtkWidget *tracknum;
+ GtkWidget *duration;
+ GtkWidget *playing;
+ GtkWidget *title;
+ GtkWidget *separator7;
+ GtkWidget *custom;
+ GtkWidget *remove_column;
+
+ headermenu = gtk_menu_new ();
+
+ add_column = gtk_menu_item_new_with_mnemonic ("Add column");
+ gtk_widget_show (add_column);
+ gtk_container_add (GTK_CONTAINER (headermenu), add_column);
+
+ add_column_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (add_column), add_column_menu);
+
+ artist = gtk_menu_item_new_with_mnemonic ("Artist");
+ gtk_widget_show (artist);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), artist);
+
+ album = gtk_menu_item_new_with_mnemonic ("Album");
+ gtk_widget_show (album);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), album);
+
+ tracknum = gtk_menu_item_new_with_mnemonic ("Track number");
+ gtk_widget_show (tracknum);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), tracknum);
+
+ duration = gtk_menu_item_new_with_mnemonic ("Duration");
+ gtk_widget_show (duration);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), duration);
+
+ playing = gtk_menu_item_new_with_mnemonic ("Playing status");
+ gtk_widget_show (playing);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), playing);
+
+ title = gtk_menu_item_new_with_mnemonic ("Title");
+ gtk_widget_show (title);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), title);
+
+ separator7 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator7);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), separator7);
+ gtk_widget_set_sensitive (separator7, FALSE);
+
+ custom = gtk_menu_item_new_with_mnemonic ("Custom");
+ gtk_widget_show (custom);
+ gtk_container_add (GTK_CONTAINER (add_column_menu), custom);
+
+ remove_column = gtk_menu_item_new_with_mnemonic ("Remove this column");
+ gtk_widget_show (remove_column);
+ gtk_container_add (GTK_CONTAINER (headermenu), remove_column);
+
+ g_signal_connect ((gpointer) artist, "activate",
+ G_CALLBACK (on_artist_activate),
+ NULL);
+ g_signal_connect ((gpointer) album, "activate",
+ G_CALLBACK (on_album_activate),
+ NULL);
+ g_signal_connect ((gpointer) tracknum, "activate",
+ G_CALLBACK (on_tracknum_activate),
+ NULL);
+ g_signal_connect ((gpointer) duration, "activate",
+ G_CALLBACK (on_duration_activate),
+ NULL);
+ g_signal_connect ((gpointer) playing, "activate",
+ G_CALLBACK (on_playing_activate),
+ NULL);
+ g_signal_connect ((gpointer) title, "activate",
+ G_CALLBACK (on_title_activate),
+ NULL);
+ g_signal_connect ((gpointer) custom, "activate",
+ G_CALLBACK (on_custom_activate),
+ NULL);
+ g_signal_connect ((gpointer) remove_column, "activate",
+ G_CALLBACK (on_remove_column_activate),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (headermenu, headermenu, "headermenu");
+ GLADE_HOOKUP_OBJECT (headermenu, add_column, "add_column");
+ GLADE_HOOKUP_OBJECT (headermenu, add_column_menu, "add_column_menu");
+ GLADE_HOOKUP_OBJECT (headermenu, artist, "artist");
+ GLADE_HOOKUP_OBJECT (headermenu, album, "album");
+ GLADE_HOOKUP_OBJECT (headermenu, tracknum, "tracknum");
+ GLADE_HOOKUP_OBJECT (headermenu, duration, "duration");
+ GLADE_HOOKUP_OBJECT (headermenu, playing, "playing");
+ GLADE_HOOKUP_OBJECT (headermenu, title, "title");
+ GLADE_HOOKUP_OBJECT (headermenu, separator7, "separator7");
+ GLADE_HOOKUP_OBJECT (headermenu, custom, "custom");
+ GLADE_HOOKUP_OBJECT (headermenu, remove_column, "remove_column");
+
+ return headermenu;
+}
+
+GtkWidget*
+create_addlocation (void)
+{
+ GtkWidget *addlocation;
+ GtkWidget *vbox7;
+ GtkWidget *addlocation_entry;
+ GtkWidget *hbox8;
+ GtkWidget *label21;
+ GtkWidget *addlocation_ok;
+
+ addlocation = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (addlocation), "Add Location");
+ gtk_window_set_modal (GTK_WINDOW (addlocation), TRUE);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (addlocation), TRUE);
+
+ vbox7 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox7);
+ gtk_container_add (GTK_CONTAINER (addlocation), vbox7);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox7), 4);
+
+ addlocation_entry = gtk_entry_new ();
+ gtk_widget_show (addlocation_entry);
+ gtk_box_pack_start (GTK_BOX (vbox7), addlocation_entry, FALSE, FALSE, 0);
+ gtk_widget_set_size_request (addlocation_entry, 346, -1);
+ gtk_entry_set_invisible_char (GTK_ENTRY (addlocation_entry), 8226);
+
+ hbox8 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox8);
+ gtk_box_pack_start (GTK_BOX (vbox7), hbox8, FALSE, TRUE, 2);
+
+ label21 = gtk_label_new ("");
+ gtk_widget_show (label21);
+ gtk_box_pack_start (GTK_BOX (hbox8), label21, TRUE, FALSE, 0);
+
+ addlocation_ok = gtk_button_new_with_mnemonic ("OK");
+ gtk_widget_show (addlocation_ok);
+ gtk_box_pack_start (GTK_BOX (hbox8), addlocation_ok, FALSE, FALSE, 0);
+ gtk_widget_set_size_request (addlocation_ok, 83, -1);
+ GTK_WIDGET_UNSET_FLAGS (addlocation_ok, GTK_CAN_FOCUS);
+
+ g_signal_connect ((gpointer) addlocation, "key_press_event",
+ G_CALLBACK (on_addlocation_key_press_event),
+ NULL);
+ g_signal_connect ((gpointer) addlocation_entry, "activate",
+ G_CALLBACK (on_addlocation_entry_activate),
+ NULL);
+ g_signal_connect ((gpointer) addlocation_ok, "clicked",
+ G_CALLBACK (on_addlocation_ok_clicked),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (addlocation, addlocation, "addlocation");
+ GLADE_HOOKUP_OBJECT (addlocation, vbox7, "vbox7");
+ GLADE_HOOKUP_OBJECT (addlocation, addlocation_entry, "addlocation_entry");
+ GLADE_HOOKUP_OBJECT (addlocation, hbox8, "hbox8");
+ GLADE_HOOKUP_OBJECT (addlocation, label21, "label21");
+ GLADE_HOOKUP_OBJECT (addlocation, addlocation_ok, "addlocation_ok");
+
+ return addlocation;
+}
+
diff --git a/plugins/gtkui/interface.h b/plugins/gtkui/interface.h
new file mode 100644
index 00000000..f9b470ff
--- /dev/null
+++ b/plugins/gtkui/interface.h
@@ -0,0 +1,12 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+GtkWidget* create_mainwin (void);
+GtkWidget* create_searchwin (void);
+GtkWidget* create_traymenu (void);
+GtkWidget* create_addprogress (void);
+GtkWidget* create_helpwindow (void);
+GtkWidget* create_prefwin (void);
+GtkWidget* create_headermenu (void);
+GtkWidget* create_addlocation (void);