Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
ui_plugin_menu.c
Go to the documentation of this file.
00001 /*
00002  * ui_plugin_menu.c
00003  * Copyright 2009-2011 John Lindgren
00004  *
00005  * This file is part of Audacious.
00006  *
00007  * Audacious is free software: you can redistribute it and/or modify it under
00008  * the terms of the GNU General Public License as published by the Free Software
00009  * Foundation, version 2 or version 3 of the License.
00010  *
00011  * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY
00012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00013  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * Audacious. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * The Audacious team does not consider modular code linking to Audacious or
00019  * using our public API to be a derived work.
00020  */
00021 
00022 #include <glib.h>
00023 #include <gtk/gtk.h>
00024 
00025 #include "misc.h"
00026 
00027 struct Item {
00028     MenuFunc func;
00029     const char * name;
00030     const char * icon;
00031 };
00032 
00033 static GList * items[AUD_MENU_COUNT];
00034 static GtkWidget * menus[AUD_MENU_COUNT];
00035 
00036 static void add_to_menu (GtkWidget * menu, struct Item * item)
00037 {
00038     GtkWidget * widget = gtk_image_menu_item_new_with_mnemonic (item->name);
00039     g_object_set_data ((GObject *) widget, "func", (void *) item->func);
00040     g_signal_connect (widget, "activate", item->func, NULL);
00041 
00042     if (item->icon)
00043         gtk_image_menu_item_set_image ((GtkImageMenuItem *) widget,
00044          gtk_image_new_from_stock (item->icon, GTK_ICON_SIZE_MENU));
00045 
00046     gtk_widget_show (widget);
00047     gtk_menu_shell_append ((GtkMenuShell *) menu, widget);
00048 }
00049 
00050 /* GtkWidget * get_plugin_menu (int id) */
00051 void * get_plugin_menu (int id)
00052 {
00053     if (! menus[id])
00054     {
00055         menus[id] = gtk_menu_new ();
00056         g_signal_connect (menus[id], "destroy", (GCallback)
00057          gtk_widget_destroyed, & menus[id]);
00058 
00059         for (GList * node = items[id]; node; node = node->next)
00060             add_to_menu (menus[id], node->data);
00061     }
00062 
00063     return menus[id];
00064 }
00065 
00066 void plugin_menu_add (int id, MenuFunc func, const char * name,
00067  const char * icon)
00068 {
00069     struct Item * item = g_slice_new (struct Item);
00070     item->name = name;
00071     item->icon = icon;
00072     item->func = func;
00073 
00074     items[id] = g_list_append (items[id], item);
00075 
00076     if (menus[id])
00077         add_to_menu (menus[id], item);
00078 }
00079 
00080 static void remove_cb (GtkWidget * widget, MenuFunc func)
00081 {
00082     if ((MenuFunc) g_object_get_data ((GObject *) widget, "func") == func)
00083         gtk_widget_destroy (widget);
00084 }
00085 
00086 void plugin_menu_remove (int id, MenuFunc func)
00087 {
00088     if (menus[id])
00089         gtk_container_foreach ((GtkContainer *) menus[id], (GtkCallback)
00090          remove_cb, (void *) func);
00091 
00092     GList * next;
00093     for (GList * node = items[id]; node; node = next)
00094     {
00095         next = node->next;
00096 
00097         if (((struct Item *) node->data)->func == func)
00098         {
00099             g_slice_free (struct Item, node->data);
00100             items[id] = g_list_delete_link (items[id], node);
00101         }
00102     }
00103 }