ui/gtk/menu.c

branch
newapi
changeset 389
d15eca5fd8b3
parent 388
473c03f85197
child 390
b130f80ec7f9
--- a/ui/gtk/menu.c	Thu Nov 21 12:04:53 2024 +0100
+++ b/ui/gtk/menu.c	Thu Nov 21 13:17:56 2024 +0100
@@ -75,6 +75,12 @@
     return mb;
 }
 
+GtkMenu* ui_create_menu(UiMenuBuilder *builder, UiObject *obj) {
+    GtkWidget *menu_widget = gtk_menu_new();
+    ui_add_menu_items(menu_widget, 0, builder->menus_begin, obj);
+    return GTK_MENU(menu_widget);
+}
+
 void ui_add_menu_items(GtkWidget *parent, int i, UiMenu *menu, UiObject *obj) {
     UiMenuItemI *it = menu->items_begin;
     int index = 0;
@@ -355,7 +361,6 @@
  * 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;
@@ -368,19 +373,8 @@
     return FALSE;
 }
 
-UIMENU ui_contextmenu(UiObject *obj) {
-    UiContainer *ct = uic_get_current_container(obj);
-    return ui_contextmenu_w(obj, ct->current);
-}
-
-UIMENU ui_contextmenu_w(UiObject *obj, UIWIDGET widget) {
-    UiContainer *ct = uic_get_current_container(obj);
-    
-    GtkMenu *menu = GTK_MENU(gtk_menu_new());
+void ui_widget_set_contextmenu(GtkWidget *widget, GtkMenu *menu) {
     g_signal_connect(widget, "button-press-event", (GCallback) ui_button_press_event, menu);
-    
-    ct->menu = menu;
-    return menu;
 }
 
 void ui_contextmenu_popup(UIMENU menu) {
@@ -390,117 +384,6 @@
     gtk_menu_popup(menu, NULL, NULL, 0, 0, 0, gtk_get_current_event_time());
 #endif
 }
-*/
-
-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
-    CxList *groups = NULL;
-    va_list ap;
-    va_start(ap, userdata);
-    int group;
-    while((group = va_arg(ap, int)) != -1) {
-        if(!groups) {
-            groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
-        }
-        cxListAdd(groups, &group);
-    }
-    va_end(ap);
-    
-    // create menuitem
-    GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
-    gtk_widget_show(widget);
-    
-    if(f) {
-        UiEventData *event = malloc(sizeof(UiEventData));
-        event->obj = obj;
-        event->userdata = userdata;
-        event->callback = f;
-        event->value = 0;
-        event->customdata = NULL;
-
-        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, (ui_enablefunc)ui_set_enabled, groups);
-        cxListDestroy(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
-    CxList *groups = NULL;
-    va_list ap;
-    va_start(ap, userdata);
-    int group;
-    while((group = va_arg(ap, int)) != -1) {
-        if(!groups) {
-            groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
-        }
-        cxListAdd(groups, &group);
-    }
-    va_end(ap);
-    
-    // create menuitem
-    GtkWidget *widget = gtk_image_menu_item_new_from_stock(stockid, obj->ctx->accel_group);
-    gtk_widget_show(widget);
-    
-    if(f) {
-        UiEventData *event = malloc(sizeof(UiEventData));
-        event->obj = obj;
-        event->userdata = userdata;
-        event->callback = f;
-        event->value = 0;
-        event->customdata = NULL;
-
-        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, (ui_enablefunc)ui_set_enabled, groups);
-        cxListDestroy(groups);
-    }
-}
 
 #endif /* GTK_MAJOR_VERSION <= 3 */
 
@@ -704,4 +587,38 @@
     list->oldcount = i;
 }
 
+
+/* --------------------- context menu / menubuilder --------------------- */
+
+GtkPopoverMenu* ui_create_menu(UiMenuBuilder *builder, UiObject *obj) {
+    GMenu *menu = g_menu_new();
+    ui_gmenu_add_menu_items(menu, 0, builder->menus_begin, obj);
+    GtkWidget *contextmenu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
+    gtk_popover_set_has_arrow(GTK_POPOVER(contextmenu), FALSE);
+    gtk_widget_set_halign(contextmenu, GTK_ALIGN_START);
+    return GTK_POPOVER_MENU(contextmenu);
+}
+
+static void gesture_button_press(GtkGestureClick *gesture, gint n_press, gdouble x, gdouble y, gpointer user_data) {
+    gtk_popover_set_pointing_to (GTK_POPOVER (user_data), &(GdkRectangle){ x, y, 0, 0 });
+    gtk_popover_popup(GTK_POPOVER(user_data));
+}
+
+static void remove_popover(GtkWidget *object, GtkPopoverMenu *menu) {
+    gtk_widget_unparent(GTK_WIDGET(menu));
+}
+
+void ui_widget_set_contextmenu(GtkWidget *widget, GtkPopoverMenu *menu) {
+    GtkGesture *gesture = gtk_gesture_click_new();
+    gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 3);
+    gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(gesture));
+    g_signal_connect(gesture, "pressed", G_CALLBACK(gesture_button_press), menu);
+    gtk_widget_set_parent(GTK_WIDGET(menu), widget);
+    g_signal_connect(
+                widget,
+                "destroy",
+                G_CALLBACK(remove_popover),
+                menu);
+}
+
 #endif

mercurial