From aa460609c68f8b10179a1c6a968911c343653f47 Mon Sep 17 00:00:00 2001 From: waker Date: Thu, 11 Jul 2013 19:14:27 +0200 Subject: gtkui: added API for creating playlist context menu --- plugins/gtkui/Makefile.am | 1 + plugins/gtkui/callbacks.h | 12 -- plugins/gtkui/ddbtabstrip.c | 260 +-------------------------------------- plugins/gtkui/gtkui.c | 4 +- plugins/gtkui/gtkui.h | 6 + plugins/gtkui/gtkui_api.h | 3 + plugins/gtkui/pltmenu.c | 288 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 301 insertions(+), 273 deletions(-) create mode 100644 plugins/gtkui/pltmenu.c (limited to 'plugins') diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am index 0471465d..f2b8df06 100644 --- a/plugins/gtkui/Makefile.am +++ b/plugins/gtkui/Makefile.am @@ -41,6 +41,7 @@ GTKUI_SOURCES = gtkui.c gtkui.h\ gtkuigl.c gtkuigl.h\ hotkeys.c hotkeys.h\ actionhandlers.c actionhandlers.h\ + pltmenu.c\ $(SM_SOURCES) sdkdir = $(pkgincludedir) diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index ed24522c..51be8d09 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -642,18 +642,6 @@ on_tabbar_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data); -void -on_rename_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data); - -void -on_remove_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data); - -void -on_add_new_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data); - void on_load_playlist1_activate (GtkMenuItem *menuitem, gpointer user_data); diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index 1022d87b..5b54c78d 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -42,21 +42,6 @@ extern GtkWidget *theme_button; #define arrow_sz 10 #define arrow_widget_width (arrow_sz+4) -void -plt_get_title_wrapper (int plt, char *buffer, int len) { - if (plt == -1) { - strcpy (buffer, ""); - return; - } - ddb_playlist_t *p = deadbeef->plt_get_for_idx (plt); - deadbeef->plt_get_title (p, buffer, len); - deadbeef->plt_unref (p); - char *end; - if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) { - *end = 0; - } -} - static void ddb_tabstrip_send_configure (DdbTabStrip *darea) { @@ -843,249 +828,6 @@ get_tab_under_cursor (DdbTabStrip *ts, int x) { return -1; } -void -on_rename_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - GtkWidget *dlg = create_entrydialog (); - gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK); - gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist")); - GtkWidget *e; - e = lookup_widget (dlg, "title_label"); - gtk_label_set_text (GTK_LABEL(e), _("Title:")); - e = lookup_widget (dlg, "title"); - char t[1000]; - plt_get_title_wrapper (tab_clicked, t, sizeof (t)); - gtk_entry_set_text (GTK_ENTRY (e), t); - int res = gtk_dialog_run (GTK_DIALOG (dlg)); - if (res == GTK_RESPONSE_OK) { - const char *text = gtk_entry_get_text (GTK_ENTRY (e)); - deadbeef->pl_lock (); - ddb_playlist_t *p = deadbeef->plt_get_for_idx (tab_clicked); - deadbeef->plt_set_title (p, text); - deadbeef->plt_unref (p); - deadbeef->pl_unlock (); - } - gtk_widget_destroy (dlg); -} - - -void -on_remove_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - if (tab_clicked != -1) { - deadbeef->plt_remove (tab_clicked); - search_refresh (); - int playlist = deadbeef->plt_get_curr_idx (); - deadbeef->conf_set_int ("playlist.current", playlist); - } -} - -void -on_add_new_playlist1_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - int playlist = gtkui_add_new_playlist (); - if (playlist != -1) { - gtkui_playlist_set_curr (playlist); - } -} - -static void -on_actionitem_activate (GtkMenuItem *menuitem, - DB_plugin_action_t *action) -{ - if (action->flags & DB_ACTION_USING_API_14) { - ddb_playlist_t *plt = NULL; - if (tab_clicked != -1) { - plt = deadbeef->plt_get_for_idx (tab_clicked); - } - typedef int (*action_callback_14_t)(struct DB_plugin_action_s *action, void *userdata); - ((action_callback_14_t)action->callback) (action, plt); - if (plt) { - deadbeef->plt_unref (plt); - } - } - else { - action->callback (action, DDB_ACTION_CTX_PLAYLIST); - } -} - -static GtkWidget* -find_popup (GtkWidget *widget, - const gchar *widget_name) -{ - GtkWidget *parent, *found_widget; - - for (;;) - { - if (GTK_IS_MENU (widget)) - parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); - else - parent = gtk_widget_get_parent (widget); - if (!parent) - parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); - if (parent == NULL) - break; - widget = parent; - } - - found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), - widget_name); - return found_widget; -} - -void -add_tab_actions (GtkWidget *menu) { - DB_plugin_t **plugins = deadbeef->plug_get_list(); - int i; - - int added_entries = 0; - for (i = 0; plugins[i]; i++) - { - if (!plugins[i]->get_actions) - continue; - - DB_plugin_action_t *actions = plugins[i]->get_actions (NULL); - DB_plugin_action_t *action; - - int count = 0; - for (action = actions; action; action = action->next) - { - char *tmp = NULL; - if (!(action->flags & DB_ACTION_MULTIPLE_TRACKS)) - continue; - - // create submenus (separated with '/') - const char *prev = action->title; - while (*prev && *prev == '/') { - prev++; - } - - GtkWidget *popup = NULL; - - for (;;) { - const char *slash = strchr (prev, '/'); - if (slash && *(slash-1) != '\\') { - char name[slash-prev+1]; - // replace \/ with / - const char *p = prev; - char *t = name; - while (*p && p < slash) { - if (*p == '\\' && *(p+1) == '/') { - *t++ = '/'; - p += 2; - } - else { - *t++ = *p++; - } - } - *t = 0; - - // add popup - GtkWidget *prev_menu = popup ? popup : menu; - - popup = find_popup (prev_menu, name); - if (!popup) { - GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (_(name)); - gtk_widget_show (item); - gtk_container_add (GTK_CONTAINER (prev_menu), item); - popup = gtk_menu_new (); - //HOOKUP_OBJECT (prev_menu, popup, name); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), popup); - } - } - else { - break; - } - prev = slash+1; - } - - - count++; - added_entries++; - GtkWidget *actionitem; - - // replace \/ with / - const char *p = popup ? prev : action->title; - char title[strlen (p)+1]; - char *t = title; - while (*p) { - if (*p == '\\' && *(p+1) == '/') { - *t++ = '/'; - p += 2; - } - else { - *t++ = *p++; - } - } - *t = 0; - - actionitem = gtk_menu_item_new_with_mnemonic (_(title)); - gtk_widget_show (actionitem); - gtk_container_add (popup ? GTK_CONTAINER (popup) : GTK_CONTAINER (menu), actionitem); - - g_signal_connect ((gpointer) actionitem, "activate", - G_CALLBACK (on_actionitem_activate), - action); - } - } -} - -GtkWidget* -create_plmenu (void) -{ - GtkWidget *plmenu; - GtkWidget *rename_playlist1; - GtkWidget *remove_playlist1; - GtkWidget *add_new_playlist1; - GtkWidget *separator11; - GtkWidget *load_playlist1; - GtkWidget *save_playlist1; - GtkWidget *save_all_playlists1; - - plmenu = gtk_menu_new (); - - rename_playlist1 = gtk_menu_item_new_with_mnemonic (_("Rename Playlist")); - if (tab_clicked == -1) { - gtk_widget_set_sensitive (rename_playlist1, FALSE); - } - gtk_widget_show (rename_playlist1); - gtk_container_add (GTK_CONTAINER (plmenu), rename_playlist1); - - remove_playlist1 = gtk_menu_item_new_with_mnemonic (_("Remove Playlist")); - if (tab_clicked == -1) { - gtk_widget_set_sensitive (remove_playlist1, FALSE); - } - gtk_widget_show (remove_playlist1); - gtk_container_add (GTK_CONTAINER (plmenu), remove_playlist1); - - add_new_playlist1 = gtk_menu_item_new_with_mnemonic (_("Add New Playlist")); - gtk_widget_show (add_new_playlist1); - gtk_container_add (GTK_CONTAINER (plmenu), add_new_playlist1); - - g_signal_connect ((gpointer) rename_playlist1, "activate", - G_CALLBACK (on_rename_playlist1_activate), - NULL); - g_signal_connect ((gpointer) remove_playlist1, "activate", - G_CALLBACK (on_remove_playlist1_activate), - NULL); - g_signal_connect ((gpointer) add_new_playlist1, "activate", - G_CALLBACK (on_add_new_playlist1_activate), - NULL); - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF (plmenu, plmenu, "plmenu"); - GLADE_HOOKUP_OBJECT (plmenu, rename_playlist1, "rename_playlist1"); - GLADE_HOOKUP_OBJECT (plmenu, remove_playlist1, "remove_playlist1"); - GLADE_HOOKUP_OBJECT (plmenu, add_new_playlist1, "add_new_playlist1"); - - add_tab_actions (plmenu); - - return plmenu; -} - static void tabstrip_scroll_left (DdbTabStrip *ts) { int tab = deadbeef->plt_get_curr_idx (); @@ -1206,7 +948,7 @@ on_tabstrip_button_press_event(GtkWidget *widget, tab_moved = 0; } else if (event->button == 3) { - GtkWidget *menu = create_plmenu (); + GtkWidget *menu = gtkui_create_pltmenu (tab_clicked); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, widget, 0, gtk_get_current_event_time()); } else if (event->button == 2) { diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index c5cb456f..8aeca349 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -85,6 +85,7 @@ int (*gtkui_original_plt_add_file) (ddb_playlist_t *plt, const char *fname, int int (*gtkui_original_pl_add_files_begin) (ddb_playlist_t *plt); void (*gtkui_original_pl_add_files_end) (void); +// cached config variable int gtkui_embolden_current_track; #define TRAY_ICON "deadbeef_tray_icon" @@ -1250,8 +1251,6 @@ gtkui_show_info_window (const char *fname, const char *title, GtkWidget **pwindo g_object_unref (buffer); gtk_widget_show (widget); } - - static int gtkui_start (void) { fprintf (stderr, "gtkui plugin compiled for gtk version: %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); @@ -1745,5 +1744,6 @@ static ddb_gtkui_t plugin = { .w_append = w_append, .w_replace = w_replace, .w_remove = w_remove, + .create_pltmenu = gtkui_create_pltmenu, .api_version = GTKUI_API_VERSION, }; diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index 9b5ac899..0065bb21 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -161,4 +161,10 @@ gtkui_show_info_window (const char *fname, const char *title, GtkWidget **pwindo void on_gtkui_info_window_delete (GtkWidget *widget, GtkTextDirection previous_direction, GtkWidget **pwindow); +GtkWidget* +gtkui_create_pltmenu (int plt_idx); + +void +plt_get_title_wrapper (int plt, char *buffer, int len); + #endif diff --git a/plugins/gtkui/gtkui_api.h b/plugins/gtkui/gtkui_api.h index 28e76f98..8013bab1 100644 --- a/plugins/gtkui/gtkui_api.h +++ b/plugins/gtkui/gtkui_api.h @@ -132,5 +132,8 @@ typedef struct { // remove the widget from its container void (*w_remove) (ddb_gtkui_widget_t *cont, ddb_gtkui_widget_t *child); + + // function to create the standard playlist context menu + GtkWidget* (*create_pltmenu) (int plt_idx); } ddb_gtkui_t; #endif diff --git a/plugins/gtkui/pltmenu.c b/plugins/gtkui/pltmenu.c new file mode 100644 index 00000000..abfe7885 --- /dev/null +++ b/plugins/gtkui/pltmenu.c @@ -0,0 +1,288 @@ +/* + DeaDBeeF -- the music player + Copyright (C) 2009-2012 Alexey Yakovenko and other contributors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../deadbeef.h" +#include +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#include "../../gettext.h" +#include +#include +#include "gtkui.h" +#include "interface.h" +#include "support.h" + +// selected playlist for the context menu +static int pltmenu_idx; + +void +plt_get_title_wrapper (int plt, char *buffer, int len) { + if (plt == -1) { + strcpy (buffer, ""); + return; + } + ddb_playlist_t *p = deadbeef->plt_get_for_idx (plt); + deadbeef->plt_get_title (p, buffer, len); + deadbeef->plt_unref (p); + char *end; + if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) { + *end = 0; + } +} + +static void +on_rename_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + GtkWidget *dlg = create_entrydialog (); + gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK); + gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist")); + GtkWidget *e; + e = lookup_widget (dlg, "title_label"); + gtk_label_set_text (GTK_LABEL(e), _("Title:")); + e = lookup_widget (dlg, "title"); + char t[1000]; + plt_get_title_wrapper (pltmenu_idx, t, sizeof (t)); + gtk_entry_set_text (GTK_ENTRY (e), t); + int res = gtk_dialog_run (GTK_DIALOG (dlg)); + if (res == GTK_RESPONSE_OK) { + const char *text = gtk_entry_get_text (GTK_ENTRY (e)); + deadbeef->pl_lock (); + ddb_playlist_t *p = deadbeef->plt_get_for_idx (pltmenu_idx); + deadbeef->plt_set_title (p, text); + deadbeef->plt_unref (p); + deadbeef->pl_unlock (); + } + gtk_widget_destroy (dlg); +} + +static void +on_remove_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + if (pltmenu_idx != -1) { + deadbeef->plt_remove (pltmenu_idx); + search_refresh (); + int playlist = deadbeef->plt_get_curr_idx (); + deadbeef->conf_set_int ("playlist.current", playlist); + } +} + +static void +on_add_new_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + int playlist = gtkui_add_new_playlist (); + if (playlist != -1) { + gtkui_playlist_set_curr (playlist); + } +} + +static void +on_actionitem_activate (GtkMenuItem *menuitem, + DB_plugin_action_t *action) +{ + if (action->flags & DB_ACTION_USING_API_14) { + ddb_playlist_t *plt = NULL; + if (pltmenu_idx != -1) { + plt = deadbeef->plt_get_for_idx (pltmenu_idx); + } + typedef int (*action_callback_14_t)(struct DB_plugin_action_s *action, void *userdata); + ((action_callback_14_t)action->callback) (action, plt); + if (plt) { + deadbeef->plt_unref (plt); + } + } + else { + action->callback (action, DDB_ACTION_CTX_PLAYLIST); + } +} + +static GtkWidget* +find_popup (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = gtk_widget_get_parent (widget); + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + return found_widget; +} + +static void +add_tab_actions (GtkWidget *menu) { + DB_plugin_t **plugins = deadbeef->plug_get_list(); + int i; + + int added_entries = 0; + for (i = 0; plugins[i]; i++) + { + if (!plugins[i]->get_actions) + continue; + + DB_plugin_action_t *actions = plugins[i]->get_actions (NULL); + DB_plugin_action_t *action; + + int count = 0; + for (action = actions; action; action = action->next) + { + char *tmp = NULL; + if (!(action->flags & DB_ACTION_MULTIPLE_TRACKS)) + continue; + + // create submenus (separated with '/') + const char *prev = action->title; + while (*prev && *prev == '/') { + prev++; + } + + GtkWidget *popup = NULL; + + for (;;) { + const char *slash = strchr (prev, '/'); + if (slash && *(slash-1) != '\\') { + char name[slash-prev+1]; + // replace \/ with / + const char *p = prev; + char *t = name; + while (*p && p < slash) { + if (*p == '\\' && *(p+1) == '/') { + *t++ = '/'; + p += 2; + } + else { + *t++ = *p++; + } + } + *t = 0; + + // add popup + GtkWidget *prev_menu = popup ? popup : menu; + + popup = find_popup (prev_menu, name); + if (!popup) { + GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (_(name)); + gtk_widget_show (item); + gtk_container_add (GTK_CONTAINER (prev_menu), item); + popup = gtk_menu_new (); + //HOOKUP_OBJECT (prev_menu, popup, name); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), popup); + } + } + else { + break; + } + prev = slash+1; + } + + + count++; + added_entries++; + GtkWidget *actionitem; + + // replace \/ with / + const char *p = popup ? prev : action->title; + char title[strlen (p)+1]; + char *t = title; + while (*p) { + if (*p == '\\' && *(p+1) == '/') { + *t++ = '/'; + p += 2; + } + else { + *t++ = *p++; + } + } + *t = 0; + + actionitem = gtk_menu_item_new_with_mnemonic (_(title)); + gtk_widget_show (actionitem); + gtk_container_add (popup ? GTK_CONTAINER (popup) : GTK_CONTAINER (menu), actionitem); + + g_signal_connect ((gpointer) actionitem, "activate", + G_CALLBACK (on_actionitem_activate), + action); + } + } +} + +GtkWidget* +gtkui_create_pltmenu (int plt_idx) { + GtkWidget *plmenu; + GtkWidget *rename_playlist1; + GtkWidget *remove_playlist1; + GtkWidget *add_new_playlist1; + GtkWidget *separator11; + GtkWidget *load_playlist1; + GtkWidget *save_playlist1; + GtkWidget *save_all_playlists1; + + plmenu = gtk_menu_new (); + pltmenu_idx = plt_idx; + + rename_playlist1 = gtk_menu_item_new_with_mnemonic (_("Rename Playlist")); + if (pltmenu_idx == -1) { + gtk_widget_set_sensitive (rename_playlist1, FALSE); + } + gtk_widget_show (rename_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), rename_playlist1); + + remove_playlist1 = gtk_menu_item_new_with_mnemonic (_("Remove Playlist")); + if (pltmenu_idx == -1) { + gtk_widget_set_sensitive (remove_playlist1, FALSE); + } + gtk_widget_show (remove_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), remove_playlist1); + + add_new_playlist1 = gtk_menu_item_new_with_mnemonic (_("Add New Playlist")); + gtk_widget_show (add_new_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), add_new_playlist1); + + g_signal_connect ((gpointer) rename_playlist1, "activate", + G_CALLBACK (on_rename_playlist1_activate), + NULL); + g_signal_connect ((gpointer) remove_playlist1, "activate", + G_CALLBACK (on_remove_playlist1_activate), + NULL); + g_signal_connect ((gpointer) add_new_playlist1, "activate", + G_CALLBACK (on_add_new_playlist1_activate), + NULL); + + add_tab_actions (plmenu); + + return plmenu; +} + -- cgit v1.2.3