From ed255d1a0357305cac6b697ee5c7ab9018646a5b Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 11 Jan 2017 20:57:36 +0300 Subject: [PATCH] added recursive procedure for submenu. Used one struct for submenu: tray_menu --- example.c | 91 ++++++++++++++++++++++------------------------ tray.h | 105 ++++++++++++++++++++---------------------------------- 2 files changed, 82 insertions(+), 114 deletions(-) diff --git a/example.c b/example.c index 6761e63..82e01b4 100644 --- a/example.c +++ b/example.c @@ -16,34 +16,34 @@ static struct tray tray; -// static void toggle_cb(struct tray_menu *item) { -// printf("toggle cb\n"); -// item->checked = !item->checked; -// tray_update(&tray); -// } +static void toggle_cb(struct tray_menu *item) { + printf("toggle cb\n"); + item->checked = !item->checked; + tray_update(&tray); +} -// static void hello_cb(struct tray_menu *item) { -// (void)item; -// printf("hello cb\n"); -// if (strcmp(tray.icon, TRAY_ICON1) == 0) { -// tray.icon = TRAY_ICON2; -// } else { -// tray.icon = TRAY_ICON1; -// } -// tray_update(&tray); -// } +static void hello_cb(struct tray_menu *item) { + (void)item; + printf("hello cb\n"); + if (strcmp(tray.icon, TRAY_ICON1) == 0) { + tray.icon = TRAY_ICON2; + } else { + tray.icon = TRAY_ICON1; + } + tray_update(&tray); +} -// static void quit_cb(struct tray_menu *item) { -// (void)item; -// printf("quit cb\n"); -// tray_exit(); -// } +static void quit_cb(struct tray_menu *item) { + (void)item; + printf("quit cb\n"); + tray_exit(); +} -// static void submenu_cb(struct tray_submenu *item) { -// (void)item; -// printf("submenu cb\n"); -// tray_update(&tray); -// } +static void submenu_cb(struct tray_menu *item) { + (void)item; + printf("submenu cb!!!\n"); + tray_update(&tray); +} //struct tray_submenu *t_sm = (struct tray_submenu[]){{"First",submenu_cb}, {"Second",submenu_cb}, {NULL, NULL},}; @@ -62,32 +62,27 @@ static struct tray tray; // {"Quit", 0, 0, NULL, quit_cb, NULL}, // {NULL, 0, 0, NULL, NULL, NULL}}, // }; + +//Test tray init static struct tray tray = { .icon = TRAY_ICON1, - .menu = (struct tray_menu[]){{"Hello", NULL}, - {"Checked", NULL}, - {"SubMenu", (struct tray_menu[]){{"FIRST", NULL}, - {"SECOND", (struct tray_menu[]){{"THIRD", (struct tray_menu[]){{"7", NULL}, - {"8", NULL}, - {NULL, NULL}}}, - {"FOUR", (struct tray_menu[]){{"5", NULL}, - {"6", NULL}, - {NULL, NULL}}}, - {NULL, NULL}}}, - {NULL, NULL}} - }, - {NULL, NULL}}, + .menu = (struct tray_menu[]){{"Hello", 0, 0, NULL, hello_cb, NULL}, + {"Checked", 0, 1, NULL, toggle_cb, NULL}, + {"Disabled", 1, 0, NULL, NULL, NULL}, + {"-", 0, 0, NULL, NULL, NULL}, + {"Quit", 0, 0, NULL, quit_cb, NULL}, + {"SubMenu", 0, 0, (struct tray_menu[]){{"FIRST", 0, 1, NULL, submenu_cb, NULL}, + {"SECOND", 0, 0, (struct tray_menu[]){{"THIRD", 0, 0, (struct tray_menu[]){{"7", 0, 0, NULL, submenu_cb, NULL}, + {"-", 0, 0, NULL, NULL, NULL}, + {"8", 0, 0, NULL, submenu_cb, NULL}, + {NULL, 0, 0, NULL, NULL, NULL}}, NULL, NULL}, + {"FOUR", 0, 0, (struct tray_menu[]){{"5", 0, 0, NULL, submenu_cb, NULL}, + {"6", 0, 0, NULL, submenu_cb, NULL}, + {NULL, 0, 0, NULL, NULL, NULL}}, NULL, NULL}, + {NULL, 0, 0, NULL, NULL, NULL}} , NULL, NULL}, + {NULL, 0, 0, NULL, NULL, NULL}} , NULL, NULL }, + {NULL, 0, 0, NULL, NULL, NULL}}, }; -// static struct tray tray = { -// .icon = TRAY_ICON1, -// .menu = (struct tray_menu[]){{"Hello", NULL}, -// {"Checked", NULL}, -// {"SubMenu", (struct tray_menu[]){{"FIRST", NULL}, -// {"SECOND", NULL}, -// {NULL, NULL}} -// }, -// {NULL, NULL}}, -// }; int main() { if (tray_init(&tray) < 0) { printf("failed to create tray\n"); diff --git a/tray.h b/tray.h index 465e99e..e78e1cb 100644 --- a/tray.h +++ b/tray.h @@ -10,12 +10,12 @@ struct tray { struct tray_menu { char *text; - // int disabled; - // int checked; + int disabled; + int checked; struct tray_menu *submenu; - // void (*cb)(struct tray_menu *); - // void *context; + void (*cb)(struct tray_menu *); + void *context; }; static void tray_update(struct tray *tray); @@ -30,11 +30,11 @@ static void tray_update(struct tray *tray); static AppIndicator *indicator = NULL; static int loop_result = 0; -// static void _tray_menu_cb(GtkMenuItem *item, gpointer data) { -// (void)item; -// struct tray_menu *m = (struct tray_menu *)data; -// m->cb(m); -// } +static void _tray_menu_cb(GtkMenuItem *item, gpointer data) { + (void)item; + struct tray_menu *m = (struct tray_menu *)data; + m->cb(m); +} // static void _tray_submenu_cb(GtkMenuItem *item, gpointer data) { // (void)item; @@ -58,15 +58,13 @@ static int tray_loop(int blocking) { return loop_result; } +//recursive proc static void submenu_update(struct tray_menu *m, - GtkWidget *_item, GtkMenuShell *_submenu) { - - GtkMenuShell *submenu; //= (GtkMenuShell *)gtk_menu_new(); - + GtkWidget *_item, GtkMenuShell *_submenu) { + GtkMenuShell *submenu; for (struct tray_menu *s_m = m->submenu; s_m!=NULL && s_m->text!=NULL; s_m++) { GtkWidget *item; - if (s_m->submenu != NULL) { - printf("GO TO REC SUB %s\n", s_m->text); + if (s_m->submenu != NULL) { item = gtk_menu_item_new_with_label(s_m->text); submenu = (GtkMenuShell *)gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), (GtkWidget *)submenu); @@ -74,16 +72,23 @@ static void submenu_update(struct tray_menu *m, gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(_submenu), item); - } - else{ - gtk_menu_item_set_submenu(GTK_MENU_ITEM(_item), (GtkWidget *)_submenu); - item = gtk_menu_item_new_with_label(s_m->text); - - printf("--%s add to %s\n", gtk_menu_item_get_label((GtkMenuItem*)item), gtk_menu_item_get_label((GtkMenuItem*)_item)); - + }else if (strcmp(s_m->text, "-") == 0) { + gtk_menu_item_set_submenu(GTK_MENU_ITEM(_item), (GtkWidget *)_submenu); + item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(_submenu), item); } + else{ + gtk_menu_item_set_submenu(GTK_MENU_ITEM(_item), (GtkWidget *)_submenu); + item = gtk_check_menu_item_new_with_label(s_m->text); + gtk_widget_set_sensitive(item, !s_m->disabled); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), !!s_m->checked); + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(_submenu), item); + if (s_m->cb != NULL) { + g_signal_connect(item, "activate", G_CALLBACK(_tray_menu_cb), s_m); + } + } } } @@ -91,63 +96,31 @@ static void tray_update(struct tray *tray) { GtkMenuShell *menu = (GtkMenuShell *)gtk_menu_new(); for (struct tray_menu *m = tray->menu; m != NULL && m->text != NULL; m++) { GtkWidget *item; - if (m->submenu != NULL) { - printf("GO TO REC MAIN %s\n", m->text); + if (m->submenu != NULL) { GtkMenuShell *submenu = (GtkMenuShell *)gtk_menu_new(); item = gtk_menu_item_new_with_label(m->text); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), (GtkWidget *)submenu); submenu_update(m, item, submenu); - } - else { - item = gtk_menu_item_new_with_label(m->text); + } else if (strcmp(m->text, "-") == 0) { + item = gtk_separator_menu_item_new(); + } else { + item = gtk_check_menu_item_new_with_label(m->text); + gtk_widget_set_sensitive(item, !m->disabled); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), !!m->checked); } gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + if (m->cb != NULL) { + g_signal_connect(item, "activate", G_CALLBACK(_tray_menu_cb), m); + } } app_indicator_set_icon(indicator, tray->icon); + // GTK is all about reference counting, so previous menu should be destroyed + // here app_indicator_set_menu(indicator, GTK_MENU(menu)); } -// static void tray_update(struct tray *tray) { -// GtkMenuShell *menu = (GtkMenuShell *)gtk_menu_new(); -// for (struct tray_menu *m = tray->menu; m != NULL && m->text != NULL; m++) { -// GtkWidget *item; -// if (m->submenu != NULL) { -// GtkMenuShell *submenu = (GtkMenuShell *)gtk_menu_new(); -// item = gtk_menu_item_new_with_label(m->text); -// gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), (GtkWidget *)submenu); -// for (struct tray_submenu *s_m = m->submenu; s_m != NULL && s_m->text != NULL; s_m++) { - -// GtkWidget* submenu_item; -// submenu_item = gtk_menu_item_new_with_label(s_m->text); -// gtk_widget_show(submenu_item); -// gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item); -// if (s_m->cb != NULL) { -// g_signal_connect(submenu_item, "activate", G_CALLBACK(_tray_submenu_cb), s_m); -// } -// } - -// } -// else if (strcmp(m->text, "-") == 0) { -// item = gtk_separator_menu_item_new(); -// } else { -// item = gtk_check_menu_item_new_with_label(m->text); -// gtk_widget_set_sensitive(item, !m->disabled); -// gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), !!m->checked); -// } - -// gtk_widget_show(item); -// gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); -// if (m->cb != NULL) { -// g_signal_connect(item, "activate", G_CALLBACK(_tray_menu_cb), m); -// } -// } -// app_indicator_set_icon(indicator, tray->icon); -// // GTK is all about reference counting, so previous menu should be destroyed -// // here -// app_indicator_set_menu(indicator, GTK_MENU(menu)); -// } static void tray_exit() { loop_result = -1; }