ui/gtk/menu.c

changeset 16
a499c8a72c15
parent 2
eeb50c534497
child 18
06be29a56f8b
--- 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 <stdio.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #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);    
 }

mercurial