added context menus (GTK)

Wed, 21 Jan 2015 12:29:03 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 21 Jan 2015 12:29:03 +0100
changeset 75
efe2f65bea17
parent 74
55718d4ed227
child 76
3782827378ab

added context menus (GTK)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/container.c file | annotate | diff | comparison | revisions
ui/gtk/container.h file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/gtk/tree.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Wed Jan 21 11:21:47 2015 +0100
+++ b/application/main.c	Wed Jan 21 12:29:03 2015 +0100
@@ -142,13 +142,13 @@
     ui_textfield(window, NULL);
     ui_end(window);
     ui_listview(window, list, (ui_model_getvalue_f)person_getvalue, action_activate, NULL);
-    //ui_contextmenu(window);
-    //ui_widget_menuitem(window, "OK", action_test, NULL);
-    //ui_widget_menuitem(window, "1", action_test, NULL);
-    //ui_widget_menuitem(window, "2", action_test, NULL);
-    //ui_widget_menuitem(window, "3", action_test, NULL);
-    //ui_widget_menuitem(window, "4", action_test, NULL);
-    //ui_widget_menuitem_st(window, UI_STOCK_CLOSE, action_test, NULL);
+    ui_contextmenu(window);
+    ui_widget_menuitem(window, "OK", action_test, NULL);
+    ui_widget_menuitem(window, "1", action_test, NULL);
+    ui_widget_menuitem(window, "2", action_test, NULL);
+    ui_widget_menuitem(window, "3", action_test, NULL);
+    ui_widget_menuitem(window, "4", action_test, NULL);
+    ui_widget_menuitem_st(window, UI_STOCK_CLOSE, action_test, NULL);
     
     
     ui_show(window);
--- a/ui/gtk/container.c	Wed Jan 21 11:21:47 2015 +0100
+++ b/ui/gtk/container.c	Wed Jan 21 12:29:03 2015 +0100
@@ -63,6 +63,7 @@
 void ui_frame_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) {
     gtk_container_add(GTK_CONTAINER(ct->widget), widget);
     ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 
 
@@ -95,6 +96,7 @@
     gtk_box_pack_start(GTK_BOX(ct->widget), widget, expand, fill, 0);
     
     ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 
 UiContainer* ui_grid_container(UiObject *obj, GtkWidget *grid) {
@@ -125,6 +127,7 @@
     grid->x++;
     
     ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 #endif
 #ifdef UI_GTK2
@@ -145,6 +148,9 @@
         grid->height = grid->y + 1;
         gtk_table_resize(GTK_TABLE(ct->widget), grid->width, grid->height);
     }
+    
+    ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 #endif
 
@@ -163,6 +169,9 @@
             GTK_NOTEBOOK(ct->widget),
             widget,
             gtk_label_new(ct->layout.label));
+    
+    ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 
 
@@ -271,10 +280,16 @@
 void ui_split_container_add1(UiContainer *ct, GtkWidget *widget, UiBool fill) {
     // TODO: remove
     gtk_paned_pack1(GTK_PANED(ct->widget), widget, TRUE, FALSE);
+    
+    ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 
 void ui_split_container_add2(UiContainer *ct, GtkWidget *widget, UiBool fill) {
     gtk_paned_pack2(GTK_PANED(ct->widget), widget, TRUE, FALSE);
+    
+    ui_reset_layout(ct->layout);
+    ct->current = widget;
 }
 
 
--- a/ui/gtk/container.h	Wed Jan 21 11:21:47 2015 +0100
+++ b/ui/gtk/container.h	Wed Jan 21 12:29:03 2015 +0100
@@ -61,6 +61,9 @@
 
 struct UiContainer {
     GtkWidget *widget;
+    GtkMenu *menu;
+    GtkWidget *current;
+    
     void (*add)(UiContainer*, GtkWidget*, UiBool);
     UiLayout layout;
 };
--- a/ui/gtk/menu.c	Wed Jan 21 11:21:47 2015 +0100
+++ b/ui/gtk/menu.c	Wed Jan 21 12:29:03 2015 +0100
@@ -36,6 +36,7 @@
 #include "../common/context.h"
 #include "../ui/properties.h"
 #include "../ui/window.h"
+#include "container.h"
 
 static UcxList *menus;
 static UcxList *current;
@@ -466,3 +467,132 @@
     i->value = value;
     gtk_check_menu_item_set_active(i->obj, value);
 }
+
+
+/*
+ * widget menu functions
+ */
+
+static gboolean ui_button_press_event(GtkWidget *widget, GdkEvent *event, GtkMenu *menu) {
+    if(event->type == GDK_BUTTON_PRESS) {
+        GdkEventButton *e = (GdkEventButton*)event;
+        if(e->button == 3) {
+            gtk_widget_show_all(GTK_WIDGET(menu));
+            gtk_menu_popup(menu, NULL, NULL, NULL, NULL, e->button, e->time);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+void ui_contextmenu(UiObject *obj) {
+    UiContainer *ct = uic_get_current_container(obj);
+    ui_contextmenu_w(obj, ct->current);
+}
+
+void ui_contextmenu_w(UiObject *obj, UIWIDGET widget) {
+    UiContainer *ct = uic_get_current_container(obj);
+    
+    GtkMenu *menu = GTK_MENU(gtk_menu_new());
+    g_signal_connect(widget, "button-press-event", (GCallback) ui_button_press_event, menu);
+    
+    ct->menu = menu;
+}
+
+void ui_widget_menuitem(UiObject *obj, char *label, ui_callback f, void *userdata) {
+    ui_widget_menuitem_gr(obj, label, f, userdata, -1);
+}
+
+void ui_widget_menuitem_gr(UiObject *obj, char *label, ui_callback f, void *userdata, ...) {
+    UiContainer *ct = uic_get_current_container(obj);
+    if(!ct->menu) {
+        return;
+    }
+    
+    // add groups
+    UcxList *groups = NULL;
+    va_list ap;
+    va_start(ap, userdata);
+    int group;
+    while((group = va_arg(ap, int)) != -1) {
+        ucx_list_append(groups, (void*)(intptr_t)group);
+    }
+    va_end(ap);
+    
+    // create menuitem
+    GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
+    
+    if(f) {
+        UiEventData *event = malloc(sizeof(UiEventData));
+        event->obj = obj;
+        event->userdata = userdata;
+        event->callback = f;
+        event->value = 0;
+
+        g_signal_connect(
+                widget,
+                "activate",
+                G_CALLBACK(ui_menu_event_wrapper),
+                event);
+        g_signal_connect(
+                widget,
+                "destroy",
+                G_CALLBACK(ui_destroy_userdata),
+                event);
+    }
+    
+    gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
+    
+    if(groups) {
+        uic_add_group_widget(obj->ctx, widget, groups);
+    }
+}
+
+void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) {
+    ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1);
+}
+
+void ui_widget_menuitem_stgr(UiObject *obj, char *stockid, ui_callback f, void *userdata, ...) {
+    UiContainer *ct = uic_get_current_container(obj);
+    if(!ct->menu) {
+        return;
+    }
+    
+    // add groups
+    UcxList *groups = NULL;
+    va_list ap;
+    va_start(ap, userdata);
+    int group;
+    while((group = va_arg(ap, int)) != -1) {
+        ucx_list_append(groups, (void*)(intptr_t)group);
+    }
+    va_end(ap);
+    
+    // create menuitem
+    GtkWidget *widget = gtk_image_menu_item_new_from_stock(stockid, obj->ctx->accel_group);
+    
+    if(f) {
+        UiEventData *event = malloc(sizeof(UiEventData));
+        event->obj = obj;
+        event->userdata = userdata;
+        event->callback = f;
+        event->value = 0;
+
+        g_signal_connect(
+                widget,
+                "activate",
+                G_CALLBACK(ui_menu_event_wrapper),
+                event);
+        g_signal_connect(
+                widget,
+                "destroy",
+                G_CALLBACK(ui_destroy_userdata),
+                event);
+    }
+    
+    gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
+    
+    if(groups) {
+        uic_add_group_widget(obj->ctx, widget, groups);
+    }
+}
--- a/ui/gtk/tree.c	Wed Jan 21 11:21:47 2015 +0100
+++ b/ui/gtk/tree.c	Wed Jan 21 12:29:03 2015 +0100
@@ -102,6 +102,10 @@
     UiContainer *ct = uic_get_current_container(obj);
     ct->add(ct, scroll_area, TRUE);
     
+    // ct->current should point to view, not scroll_area, to make it possible
+    // to add a context menu
+    ct->current = view;
+    
     return scroll_area;
 }
 
@@ -197,6 +201,10 @@
     UiContainer *ct = uic_get_current_container(obj);
     ct->add(ct, scroll_area, TRUE);
     
+    // ct->current should point to view, not scroll_area, to make it possible
+    // to add a context menu
+    ct->current = view;
+    
     return scroll_area;
 }
 

mercurial