From ac6bf2bad50653d84388269a6629d121b8c37b8f Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sun, 21 Oct 2007 15:15:47 +0100 Subject: [PATCH] start to create menu items corresponding to control items Organization: Straylight/Edgeware From: Richard Kettlewell --- disobedience/control.c | 75 ++++++++++++++++++++++++++----------- disobedience/disobedience.h | 2 +- disobedience/menu.c | 21 +++++++---- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/disobedience/control.c b/disobedience/control.c index 39bced1..6542f82 100644 --- a/disobedience/control.c +++ b/disobedience/control.c @@ -45,6 +45,7 @@ static void update_disable(const struct icon *); static void update_rtp(const struct icon *); static void update_nortp(const struct icon *); static void clicked_icon(GtkButton *, gpointer); +static void clicked_menu(GtkMenuItem *, gpointer userdata); static int enable_rtp(disorder_eclient *c, disorder_eclient_no_response *completed, @@ -79,8 +80,8 @@ struct icon { /** @brief Text for tooltip */ const char *tip; - /** @brief Called when button is clicked (activated) */ - void (*clicked)(GtkButton *button, gpointer userdata); + /** @brief Associated menu item or NULL */ + const char *menuitem; /** @brief Called to update button when state may have changed */ void (*update)(const struct icon *i); @@ -92,28 +93,40 @@ struct icon { /** @brief Pointer to button */ GtkWidget *button; + + /** @brief Pointer to menu item */ + GtkWidget *item; }; /** @brief Table of all icons */ static struct icon icons[] = { - { "pause.png", "Pause playing track", clicked_icon, update_pause, - disorder_eclient_pause, 0 }, - { "play.png", "Resume playing track", clicked_icon, update_play, - disorder_eclient_resume, 0 }, - { "cross.png", "Cancel playing track", clicked_icon, update_scratch, - disorder_eclient_scratch_playing, 0 }, - { "random.png", "Enable random play", clicked_icon, update_random_enable, - disorder_eclient_random_enable, 0 }, - { "randomcross.png", "Disable random play", clicked_icon, update_random_disable, - disorder_eclient_random_disable, 0 }, - { "notes.png", "Enable play", clicked_icon, update_enable, - disorder_eclient_enable, 0 }, - { "notescross.png", "Disable play", clicked_icon, update_disable, - disorder_eclient_disable, 0 }, - { "speaker.png", "Play network stream", clicked_icon, update_rtp, - enable_rtp, 0 }, - { "speakercross.png", "Stop playing network stream", clicked_icon, update_nortp, - disable_rtp, 0 }, + { "pause.png", "Pause playing track", 0, + update_pause, + disorder_eclient_pause, 0, 0 }, + { "play.png", "Resume playing track", 0, + update_play, + disorder_eclient_resume, 0, 0 }, + { "cross.png", "Cancel playing track", "/Control/Scratch", + update_scratch, + disorder_eclient_scratch_playing, 0, 0 }, + { "random.png", "Enable random play", 0, + update_random_enable, + disorder_eclient_random_enable, 0, 0 }, + { "randomcross.png", "Disable random play", 0, + update_random_disable, + disorder_eclient_random_disable, 0, 0 }, + { "notes.png", "Enable play", 0, + update_enable, + disorder_eclient_enable, 0, 0 }, + { "notescross.png", "Disable play", 0, + update_disable, + disorder_eclient_disable, 0, 0 }, + { "speaker.png", "Play network stream", 0, + update_rtp, + enable_rtp, 0, 0 }, + { "speakercross.png", "Stop playing network stream", 0, + update_nortp, + disable_rtp, 0, 0 }, }; /** @brief Count of icons */ @@ -141,6 +154,7 @@ GtkWidget *control_widget(void) { NW(hbox); D(("control_widget")); + assert(mainmenufactory); /* ordering must be right */ for(n = 0; n < NICONS; ++n) { NW(button); icons[n].button = gtk_button_new(); @@ -154,13 +168,19 @@ GtkWidget *control_widget(void) { gtk_container_add(GTK_CONTAINER(icons[n].button), content); gtk_tooltips_set_tip(tips, icons[n].button, icons[n].tip, ""); g_signal_connect(G_OBJECT(icons[n].button), "clicked", - G_CALLBACK(icons[n].clicked), &icons[n]); + G_CALLBACK(clicked_icon), &icons[n]); /* pop the icon in a vbox so it doesn't get vertically stretch if there are * taller things in the control bar */ NW(vbox); vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), icons[n].button, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); + if(icons[n].menuitem) { + icons[n].item = gtk_item_factory_get_widget(mainmenufactory, + icons[n].menuitem); + g_signal_connect(G_OBJECT(icons[n].item), "activate", + G_CALLBACK(clicked_menu), &icons[n]); + } } /* create the adjustments for the volume control */ NW(adjustment); @@ -234,6 +254,12 @@ static void update_icon(const struct icon *icon, /* Only both updating usability if the button is visible */ if(visible) gtk_widget_set_sensitive(icon->button, usable); + if(icon->item) { + /* There's an associated menu item */ + (visible ? gtk_widget_show : gtk_widget_hide)(icon->item); + if(visible) + gtk_widget_set_sensitive(icon->item, usable); + } } static void update_pause(const struct icon *icon) { @@ -297,6 +323,13 @@ static void clicked_icon(GtkButton attribute((unused)) *button, icon->action(client, 0, 0); } +static void clicked_menu(GtkMenuItem attribute((unused)) *menuitem, + gpointer userdata) { + const struct icon *icon = userdata; + + icon->action(client, 0, 0); +} + /** @brief Called when the volume has been adjusted */ static void volume_adjusted(GtkAdjustment attribute((unused)) *a, gpointer attribute((unused)) user_data) { diff --git a/disobedience/disobedience.h b/disobedience/disobedience.h index 6614d8b..884ebfe 100644 --- a/disobedience/disobedience.h +++ b/disobedience/disobedience.h @@ -113,7 +113,7 @@ extern int choosealpha; /* break up choose by letter */ extern GtkTooltips *tips; extern int rtp_supported; extern int rtp_is_running; - +extern GtkItemFactory *mainmenufactory; extern const disorder_eclient_log_callbacks log_callbacks; diff --git a/disobedience/menu.c b/disobedience/menu.c index db51ba8..5085be2 100644 --- a/disobedience/menu.c +++ b/disobedience/menu.c @@ -26,6 +26,9 @@ static GtkWidget *selectall_widget; static GtkWidget *properties_widget; +/** @brief Main menu widgets */ +GtkItemFactory *mainmenufactory; + static void about_popup_got_version(void *v, const char *value); /** @brief Called when the quit option is activated @@ -141,35 +144,39 @@ GtkWidget *menubar(GtkWidget *w) { 0, 0 }, { (char *)"/File/Quit Disobedience", (char *)"Q", quit_program, 0, (char *)"", GTK_STOCK_QUIT }, + { (char *)"/Edit", 0, 0, 0, (char *)"", 0 }, { (char *)"/Edit/Select all tracks", (char *)"A", select_all, 0, 0, 0 }, { (char *)"/Edit/Track properties", 0, properties_item, 0, 0, 0 }, + + { (char *)"/Control", 0, 0, 0, (char *)"", 0 }, + { (char *)"/Control/Scratch", (char *)"S", 0, 0, 0, 0 }, + { (char *)"/Help", 0, 0, 0, (char *)"", 0 }, { (char *)"/Help/About DisOrder", 0, about_popup, 0, (char *)"", GTK_STOCK_ABOUT }, }; - GtkItemFactory *itemfactory; GtkAccelGroup *accel = gtk_accel_group_new(); D(("add_menubar")); /* TODO: item factories are deprecated in favour of some XML thing */ - itemfactory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "", - accel); - gtk_item_factory_create_items(itemfactory, + mainmenufactory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "", + accel); + gtk_item_factory_create_items(mainmenufactory, sizeof entries / sizeof *entries, (GtkItemFactoryEntry *)entries, 0); gtk_window_add_accel_group(GTK_WINDOW(w), accel); - selectall_widget = gtk_item_factory_get_widget(itemfactory, + selectall_widget = gtk_item_factory_get_widget(mainmenufactory, "/Edit/Select all tracks"); - properties_widget = gtk_item_factory_get_widget(itemfactory, + properties_widget = gtk_item_factory_get_widget(mainmenufactory, "/Edit/Track properties"); assert(selectall_widget != 0); assert(properties_widget != 0); - return gtk_item_factory_get_widget(itemfactory, + return gtk_item_factory_get_widget(mainmenufactory, ""); /* menu bar had better not expand vertically if the window is too big */ } -- [mdw]