ui/gtk/menu.c

branch
newapi
changeset 389
d15eca5fd8b3
parent 388
473c03f85197
child 390
b130f80ec7f9
equal deleted inserted replaced
388:473c03f85197 389:d15eca5fd8b3
73 } 73 }
74 74
75 return mb; 75 return mb;
76 } 76 }
77 77
78 GtkMenu* ui_create_menu(UiMenuBuilder *builder, UiObject *obj) {
79 GtkWidget *menu_widget = gtk_menu_new();
80 ui_add_menu_items(menu_widget, 0, builder->menus_begin, obj);
81 return GTK_MENU(menu_widget);
82 }
83
78 void ui_add_menu_items(GtkWidget *parent, int i, UiMenu *menu, UiObject *obj) { 84 void ui_add_menu_items(GtkWidget *parent, int i, UiMenu *menu, UiObject *obj) {
79 UiMenuItemI *it = menu->items_begin; 85 UiMenuItemI *it = menu->items_begin;
80 int index = 0; 86 int index = 0;
81 while(it) { 87 while(it) {
82 createMenuItem[it->type](parent, index, it, obj); 88 createMenuItem[it->type](parent, index, it, obj);
353 359
354 /* 360 /*
355 * widget menu functions 361 * widget menu functions
356 */ 362 */
357 363
358 /*
359 static gboolean ui_button_press_event(GtkWidget *widget, GdkEvent *event, GtkMenu *menu) { 364 static gboolean ui_button_press_event(GtkWidget *widget, GdkEvent *event, GtkMenu *menu) {
360 if(event->type == GDK_BUTTON_PRESS) { 365 if(event->type == GDK_BUTTON_PRESS) {
361 GdkEventButton *e = (GdkEventButton*)event; 366 GdkEventButton *e = (GdkEventButton*)event;
362 if(e->button == 3) { 367 if(e->button == 3) {
363 gtk_widget_show_all(GTK_WIDGET(menu)); 368 gtk_widget_show_all(GTK_WIDGET(menu));
366 } 371 }
367 } 372 }
368 return FALSE; 373 return FALSE;
369 } 374 }
370 375
371 UIMENU ui_contextmenu(UiObject *obj) { 376 void ui_widget_set_contextmenu(GtkWidget *widget, GtkMenu *menu) {
372 UiContainer *ct = uic_get_current_container(obj);
373 return ui_contextmenu_w(obj, ct->current);
374 }
375
376 UIMENU ui_contextmenu_w(UiObject *obj, UIWIDGET widget) {
377 UiContainer *ct = uic_get_current_container(obj);
378
379 GtkMenu *menu = GTK_MENU(gtk_menu_new());
380 g_signal_connect(widget, "button-press-event", (GCallback) ui_button_press_event, menu); 377 g_signal_connect(widget, "button-press-event", (GCallback) ui_button_press_event, menu);
381
382 ct->menu = menu;
383 return menu;
384 } 378 }
385 379
386 void ui_contextmenu_popup(UIMENU menu) { 380 void ui_contextmenu_popup(UIMENU menu) {
387 #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 16 381 #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 16
388 gtk_menu_popup_at_pointer(menu, NULL); 382 gtk_menu_popup_at_pointer(menu, NULL);
389 #else 383 #else
390 gtk_menu_popup(menu, NULL, NULL, 0, 0, 0, gtk_get_current_event_time()); 384 gtk_menu_popup(menu, NULL, NULL, 0, 0, 0, gtk_get_current_event_time());
391 #endif 385 #endif
392 }
393 */
394
395 void ui_widget_menuitem(UiObject *obj, char *label, ui_callback f, void *userdata) {
396 ui_widget_menuitem_gr(obj, label, f, userdata, -1);
397 }
398
399 void ui_widget_menuitem_gr(UiObject *obj, char *label, ui_callback f, void *userdata, ...) {
400 UiContainer *ct = uic_get_current_container(obj);
401 if(!ct->menu) {
402 return;
403 }
404
405 // add groups
406 CxList *groups = NULL;
407 va_list ap;
408 va_start(ap, userdata);
409 int group;
410 while((group = va_arg(ap, int)) != -1) {
411 if(!groups) {
412 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
413 }
414 cxListAdd(groups, &group);
415 }
416 va_end(ap);
417
418 // create menuitem
419 GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
420 gtk_widget_show(widget);
421
422 if(f) {
423 UiEventData *event = malloc(sizeof(UiEventData));
424 event->obj = obj;
425 event->userdata = userdata;
426 event->callback = f;
427 event->value = 0;
428 event->customdata = NULL;
429
430 g_signal_connect(
431 widget,
432 "activate",
433 G_CALLBACK(ui_menu_event_wrapper),
434 event);
435 g_signal_connect(
436 widget,
437 "destroy",
438 G_CALLBACK(ui_destroy_userdata),
439 event);
440 }
441
442 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
443
444 if(groups) {
445 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
446 cxListDestroy(groups);
447 }
448 }
449
450 void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) {
451 ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1);
452 }
453
454 void ui_widget_menuitem_stgr(UiObject *obj, char *stockid, ui_callback f, void *userdata, ...) {
455 UiContainer *ct = uic_get_current_container(obj);
456 if(!ct->menu) {
457 return;
458 }
459
460 // add groups
461 CxList *groups = NULL;
462 va_list ap;
463 va_start(ap, userdata);
464 int group;
465 while((group = va_arg(ap, int)) != -1) {
466 if(!groups) {
467 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
468 }
469 cxListAdd(groups, &group);
470 }
471 va_end(ap);
472
473 // create menuitem
474 GtkWidget *widget = gtk_image_menu_item_new_from_stock(stockid, obj->ctx->accel_group);
475 gtk_widget_show(widget);
476
477 if(f) {
478 UiEventData *event = malloc(sizeof(UiEventData));
479 event->obj = obj;
480 event->userdata = userdata;
481 event->callback = f;
482 event->value = 0;
483 event->customdata = NULL;
484
485 g_signal_connect(
486 widget,
487 "activate",
488 G_CALLBACK(ui_menu_event_wrapper),
489 event);
490 g_signal_connect(
491 widget,
492 "destroy",
493 G_CALLBACK(ui_destroy_userdata),
494 event);
495 }
496
497 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
498
499 if(groups) {
500 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
501 cxListDestroy(groups);
502 }
503 } 386 }
504 387
505 #endif /* GTK_MAJOR_VERSION <= 3 */ 388 #endif /* GTK_MAJOR_VERSION <= 3 */
506 389
507 390
702 } 585 }
703 586
704 list->oldcount = i; 587 list->oldcount = i;
705 } 588 }
706 589
590
591 /* --------------------- context menu / menubuilder --------------------- */
592
593 GtkPopoverMenu* ui_create_menu(UiMenuBuilder *builder, UiObject *obj) {
594 GMenu *menu = g_menu_new();
595 ui_gmenu_add_menu_items(menu, 0, builder->menus_begin, obj);
596 GtkWidget *contextmenu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
597 gtk_popover_set_has_arrow(GTK_POPOVER(contextmenu), FALSE);
598 gtk_widget_set_halign(contextmenu, GTK_ALIGN_START);
599 return GTK_POPOVER_MENU(contextmenu);
600 }
601
602 static void gesture_button_press(GtkGestureClick *gesture, gint n_press, gdouble x, gdouble y, gpointer user_data) {
603 gtk_popover_set_pointing_to (GTK_POPOVER (user_data), &(GdkRectangle){ x, y, 0, 0 });
604 gtk_popover_popup(GTK_POPOVER(user_data));
605 }
606
607 static void remove_popover(GtkWidget *object, GtkPopoverMenu *menu) {
608 gtk_widget_unparent(GTK_WIDGET(menu));
609 }
610
611 void ui_widget_set_contextmenu(GtkWidget *widget, GtkPopoverMenu *menu) {
612 GtkGesture *gesture = gtk_gesture_click_new();
613 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 3);
614 gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(gesture));
615 g_signal_connect(gesture, "pressed", G_CALLBACK(gesture_button_press), menu);
616 gtk_widget_set_parent(GTK_WIDGET(menu), widget);
617 g_signal_connect(
618 widget,
619 "destroy",
620 G_CALLBACK(remove_popover),
621 menu);
622 }
623
707 #endif 624 #endif

mercurial