# HG changeset patch # User Olaf Wintermann # Date 1396345990 -7200 # Node ID a499c8a72c15141c6d402246f5e08270c20eafcd # Parent 7a36f91c22f74e289d2a39f3b2b35fe8a400d08c added menu item lists (GTK) diff -r 7a36f91c22f7 -r a499c8a72c15 application/main.c --- a/application/main.c Tue Apr 01 11:50:32 2014 +0200 +++ b/application/main.c Tue Apr 01 11:53:10 2014 +0200 @@ -64,6 +64,7 @@ ui_setval(wd->text, "--------"); ui_list_append(list, "abc"); + ui_notify(list->observers, NULL); } void action_close(UiEvent *event, void *data) { diff -r 7a36f91c22f7 -r a499c8a72c15 ui/common/types.c --- a/ui/common/types.c Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/common/types.c Tue Apr 01 11:53:10 2014 +0200 @@ -65,7 +65,13 @@ void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) { while(observer) { if(observer != exc) { - observer->callback(data, observer->data); + UiEvent evt; + evt.obj = NULL; + evt.window = NULL; + evt.document = NULL; + evt.eventdata = data; + evt.intval = 0; + observer->callback(&evt, observer->data); } observer = observer->next; } diff -r 7a36f91c22f7 -r a499c8a72c15 ui/gtk/button.c --- a/ui/gtk/button.c Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/gtk/button.c Tue Apr 01 11:53:10 2014 +0200 @@ -44,6 +44,7 @@ event->obj = obj; event->user_data = data; event->callback = f; + event->value = 0; g_signal_connect( button, @@ -64,6 +65,7 @@ e.obj = event->obj; e.window = event->obj->window; e.document = event->obj->document; - e.intval = 0; + e.eventdata = NULL; + e.intval = event->value; event->callback(&e, event->user_data); } 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); } diff -r 7a36f91c22f7 -r a499c8a72c15 ui/gtk/menu.h --- a/ui/gtk/menu.h Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/gtk/menu.h Tue Apr 01 11:53:10 2014 +0200 @@ -43,8 +43,11 @@ typedef struct UiStMenuItem UiStMenuItem; typedef struct UiCheckItem UiCheckItem; typedef struct UiCheckItemNV UiCheckItemNV; +typedef struct UiMenuItemList UiMenuItemList; -typedef GtkWidget*(*ui_menu_add_f)(GtkWidget *, UiMenuItemI*, UiObject*); +typedef struct UiActiveMenuItemList UiActiveMenuItemList; + +typedef GtkWidget*(*ui_menu_add_f)(GtkWidget *, int, UiMenuItemI*, UiObject*); struct UiMenuItemI { ui_menu_add_f add_to; @@ -84,15 +87,34 @@ char *varname; }; +struct UiMenuItemList { + UiMenuItemI item; + ui_callback callback; + void *userdata; + UiList *list; +}; + +struct UiActiveMenuItemList { + UiObject *object; + GtkMenuShell *menu; + int index; + int oldcount; + UiList *list; + ui_callback callback; + void *userdata; +}; + GtkWidget *ui_create_menubar(UiObject *obj); -void add_menu_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj); -void add_menuitem_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj); -void add_menuitem_st_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj); -void add_menuseparator_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj); -void add_checkitem_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj); -void add_checkitemnv_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj); +void add_menu_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj); +void add_menuitem_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj); +void add_menuitem_st_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj); +void add_menuseparator_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj); +void add_checkitem_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj); +void add_checkitemnv_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj); +void add_menuitem_list_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj); +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list); void ui_menu_event_wrapper(GtkMenuItem *item, UiEventData *event); void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiEventData *event); int ui_checkitem_get(UiInteger *i); diff -r 7a36f91c22f7 -r a499c8a72c15 ui/gtk/toolkit.h --- a/ui/gtk/toolkit.h Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/gtk/toolkit.h Tue Apr 01 11:53:10 2014 +0200 @@ -41,6 +41,7 @@ UiObject *obj; ui_callback callback; void *user_data; + int value; } UiEventData; diff -r 7a36f91c22f7 -r a499c8a72c15 ui/ui/toolkit.h --- a/ui/ui/toolkit.h Tue Apr 01 11:50:32 2014 +0200 +++ b/ui/ui/toolkit.h Tue Apr 01 11:53:10 2014 +0200 @@ -108,6 +108,7 @@ UiObject *obj; void *document; void *window; + void *eventdata; int intval; };