diff -r 7a36f91c22f7 -r a499c8a72c15 ui/gtk/menu.c --- a/ui/gtk/menu.c Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/gtk/menu.c Tue Apr 01 11:53:10 2014 +0200 @@ -28,14 +28,15 @@ #include #include +#include #include "menu.h" #include "toolkit.h" #include "../common/context.h" #include "../ui/window.h" -UcxList *menus; -UcxList *current; +static UcxList *menus; +static UcxList *current; void ui_menu(char *label) { // free current menu hierarchy @@ -75,7 +76,7 @@ return; } current = ucx_list_remove(current, current); - UcxList *c = current; + //UcxList *c = current; } void ui_menuitem(char *label, ui_callback f, void *userdata) { @@ -135,6 +136,21 @@ cm->items = ucx_list_append(cm->items, item); } +void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) { + if(!current) { + return; + } + + UiMenuItemList *item = malloc(sizeof(UiMenuItemList)); + item->item.add_to = (ui_menu_add_f)add_menuitem_list_widget; + item->callback = f; + item->userdata = userdata; + item->list = items; + + UiMenu *cm = current->data; + cm->items = ucx_list_append(cm->items, item); +} + // private menu functions GtkWidget *ui_create_menubar(UiObject *obj) { if(menus == NULL) { @@ -146,7 +162,7 @@ UcxList *ls = menus; while(ls) { UiMenu *menu = ls->data; - menu->item.add_to(mb, &menu->item, obj); + menu->item.add_to(mb, 0, &menu->item, obj); ls = ls->next; } @@ -154,7 +170,7 @@ return mb; } -void add_menu_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj) { +void add_menu_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj) { UiMenu *menu = (UiMenu*)item; GtkWidget *menu_widget = gtk_menu_new(); @@ -162,17 +178,19 @@ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget); UcxList *ls = menu->items; + int index = 0; while(ls) { UiMenuItemI *i = ls->data; - i->add_to(menu_widget, i, obj); + i->add_to(menu_widget, index, i, obj); ls = ls->next; + index++; } gtk_menu_shell_append(GTK_MENU_SHELL(parent), menu_item); } -void add_menuitem_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj) { +void add_menuitem_widget(GtkWidget *parent, int index, UiMenuItemI *item, UiObject *obj) { UiMenuItem *i = (UiMenuItem*)item; //GtkWidget *widget = gtk_menu_item_new_with_label(i->title); @@ -183,6 +201,7 @@ event->obj = obj; event->user_data = i->userdata; event->callback = i->callback; + event->value = 0; g_signal_connect( widget, @@ -196,6 +215,7 @@ void add_menuitem_st_widget( GtkWidget *parent, + int index, UiMenuItemI *item, UiObject *obj) { @@ -208,6 +228,7 @@ event->obj = obj; event->user_data = i->userdata; event->callback = i->callback; + event->value = 0; g_signal_connect( widget, @@ -221,6 +242,7 @@ void add_menuseparator_widget( GtkWidget *parent, + int index, UiMenuItemI *item, UiObject *obj) { @@ -229,7 +251,7 @@ gtk_separator_menu_item_new()); } -void add_checkitem_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj) { +void add_checkitem_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) { UiCheckItem *ci = (UiCheckItem*)item; GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label); gtk_menu_shell_append(GTK_MENU_SHELL(p), widget); @@ -239,6 +261,7 @@ event->obj = obj; event->user_data = ci->userdata; event->callback = ci->callback; + event->value = 0; g_signal_connect( widget, @@ -248,7 +271,7 @@ } } -void add_checkitemnv_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj) { +void add_checkitemnv_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) { UiCheckItemNV *ci = (UiCheckItemNV*)item; GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label); gtk_menu_shell_append(GTK_MENU_SHELL(p), widget); @@ -265,14 +288,86 @@ } } +void add_menuitem_list_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) { + UiMenuItemList *il = (UiMenuItemList*)item; + UcxMempool *mp = obj->ctx->mempool; + + UiActiveMenuItemList *ls = ucx_mempool_malloc( + mp, + sizeof(UiActiveMenuItemList)); + + ls->object = obj; + ls->menu = GTK_MENU_SHELL(p); + ls->index = index; + ls->oldcount = 0; + ls->list = il->list; + ls->callback = il->callback; + ls->userdata = il->userdata; + + ls->list->observers = ui_add_observer( + ls->list->observers, + (ui_callback)ui_update_menuitem_list, + ls); + + ui_update_menuitem_list(NULL, ls); +} +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) { + // remove old items + if(list->oldcount > 0) { + int i = 0; + GList *mi = gtk_container_get_children(GTK_CONTAINER(list->menu)); + while(mi) { + if(i >= list->index && i < list->index + list->oldcount) { + gtk_container_remove(GTK_CONTAINER(list->menu), mi->data); + } + mi = mi->next; + i++; + } + } + + char *str = ui_list_first(list->list); + if(str) { + GtkWidget *widget = gtk_separator_menu_item_new(); + gtk_menu_shell_insert(list->menu, widget, list->index); + gtk_widget_show(widget); + } + int i = 1; + while(str) { + GtkWidget *widget = gtk_menu_item_new_with_label(str); + gtk_menu_shell_insert(list->menu, widget, list->index + i); + gtk_widget_show(widget); + + if(list->callback) { + // TODO: use mempool + UiEventData *event = malloc(sizeof(UiEventData)); + event->obj = list->object; + event->user_data = list->userdata; + event->callback = list->callback; + event->value = i - 1; + + g_signal_connect( + widget, + "activate", + G_CALLBACK(ui_menu_event_wrapper), + event); + } + + str = ui_list_next(list->list); + i++; + } + + list->oldcount = i; +} + void ui_menu_event_wrapper(GtkMenuItem *item, UiEventData *event) { UiEvent evt; evt.obj = event->obj; evt.window = event->obj->window; evt.document = event->obj->document; - evt.intval = 0; + evt.eventdata = NULL; + evt.intval = event->value; event->callback(&evt, event->user_data); } @@ -281,6 +376,7 @@ evt.obj = event->obj; evt.window = event->obj->window; evt.document = event->obj->document; + evt.eventdata = NULL; evt.intval = gtk_check_menu_item_get_active(ci); event->callback(&evt, event->user_data); }