ui/gtk/menu.c

branch
newapi
changeset 311
450a813dc2a5
parent 294
7232a8e68eeb
child 312
3f2b3d15668b
equal deleted inserted replaced
310:4918f9132552 311:450a813dc2a5
40 #include "container.h" 40 #include "container.h"
41 41
42 #include <cx/linked_list.h> 42 #include <cx/linked_list.h>
43 #include <cx/array_list.h> 43 #include <cx/array_list.h>
44 44
45 #if UI_GTK2 || UI_GTK3 45 #if GTK_MAJOR_VERSION <= 3
46
47 46
48 static ui_menu_add_f createMenuItem[] = { 47 static ui_menu_add_f createMenuItem[] = {
49 /* UI_MENU */ add_menu_widget, 48 /* UI_MENU */ add_menu_widget,
50 /* UI_MENU_ITEM */ add_menuitem_widget, 49 /* UI_MENU_ITEM */ add_menuitem_widget,
51 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, 50 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
499 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups); 498 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
500 cxListDestroy(groups); 499 cxListDestroy(groups);
501 } 500 }
502 } 501 }
503 502
504 #endif /* UI_GTK2 || UI_GTK3 */ 503 #endif /* GTK_MAJOR_VERSION <= 3 */
504
505
506
507 #if GTK_MAJOR_VERSION >= 4
508
509
510
511 static ui_gmenu_add_f createMenuItem[] = {
512 /* UI_MENU */ ui_gmenu_add_menu,
513 /* UI_MENU_ITEM */ ui_gmenu_add_menuitem,
514 /* UI_MENU_CHECK_ITEM */ ui_gmenu_add_checkitem,
515 /* UI_MENU_RADIO_ITEM */ ui_gmenu_add_radioitem,
516 /* UI_MENU_ITEM_LIST */ ui_gmenu_add_menuitem_list,
517 /* UI_MENU_CHECKITEM_LIST */ ui_gmenu_add_menuitem_list,
518 /* UI_MENU_RADIOITEM_LIST */ ui_gmenu_add_menuitem_list,
519 /* UI_MENU_SEPARATOR */ ui_gmenu_add_menuseparator
520 };
521
522 void ui_gmenu_add_menu_items(GMenu *parent, int i, UiMenu *menu, UiObject *obj) {
523 UiMenuItemI *it = menu->items_begin;
524 int index = 0;
525 while(it) {
526 createMenuItem[it->type](parent, index, it, obj);
527 it = it->next;
528 index++;
529 }
530 }
531
532 void ui_gmenu_add_menu(GMenu *parent, int index, UiMenuItemI *item, UiObject *obj) {
533 UiMenu *mi = (UiMenu*)item;
534 GMenu *menu = g_menu_new();
535 ui_gmenu_add_menu_items(menu, 0, mi, obj);
536 g_menu_append_submenu(parent, mi->label, G_MENU_MODEL(menu));
537 }
538
539 void ui_gmenu_add_menuitem(GMenu *parent, int index, UiMenuItemI *item, UiObject *obj) {
540 UiMenuItem *i = (UiMenuItem*)item;
541
542 GSimpleAction *action = g_simple_action_new(item->id, NULL);
543 g_action_map_add_action(obj->ctx->action_map, G_ACTION(action));
544
545 if(i->callback != NULL) {
546 UiEventData *event = malloc(sizeof(UiEventData));
547 event->obj = obj;
548 event->userdata = i->userdata;
549 event->callback = i->callback;
550 event->value = 0;
551 event->customdata = NULL;
552
553 g_signal_connect(
554 action,
555 "activate",
556 G_CALLBACK(ui_activate_event_wrapper),
557 event);
558 g_signal_connect(
559 obj->widget,
560 "destroy",
561 G_CALLBACK(ui_destroy_userdata),
562 event);
563 }
564
565 char action_name[32];
566 snprintf(action_name, 32, "win.%s", item->id);
567 g_menu_append(parent, i->label, action_name);
568 }
569
570 void ui_gmenu_add_menuseparator(GMenu *p, int index, UiMenuItemI *item, UiObject *obj) {
571
572 }
573
574 void ui_gmenu_add_checkitem(GMenu *p, int index, UiMenuItemI *item, UiObject *obj) {
575 UiMenuCheckItem *checkitem = (UiMenuCheckItem*)item;
576
577 // TODO
578 }
579
580 void ui_gmenu_add_radioitem(GMenu *p, int index, UiMenuItemI *item, UiObject *obj) {
581
582 }
583
584 void ui_gmenu_add_menuitem_list(GMenu *p, int index, UiMenuItemI *item, UiObject *obj) {
585 UiMenuItemList *il = (UiMenuItemList*)item;
586
587 const CxAllocator *a = obj->ctx->allocator;
588
589 UiActiveGMenuItemList *ls = cxMalloc(
590 a,
591 sizeof(UiActiveGMenuItemList));
592
593 ls->object = obj;
594 ls->menu = p;
595 ls->index = index;
596 ls->oldcount = 0;
597 ls->getvalue = il->getvalue;
598
599 UiVar* var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST);
600 ls->list = var->value;
601
602 ls->callback = il->callback;
603 ls->userdata = il->userdata;
604
605 ls->list->observers = ui_add_observer(
606 ls->list->observers,
607 (ui_callback)ui_update_gmenu_item_list,
608 ls);
609
610 GSimpleAction *action = g_simple_action_new(item->id, g_variant_type_new("i"));
611 g_action_map_add_action(obj->ctx->action_map, G_ACTION(action));
612 snprintf(ls->action, 32, "win.%s", item->id);
613
614
615 UiEventData *event = malloc(sizeof(UiEventData));
616 event->obj = obj;
617 event->userdata = il->userdata;
618 event->callback = il->callback;
619 event->customdata = NULL;
620 event->value = 0;
621
622 g_signal_connect(
623 action,
624 "activate",
625 G_CALLBACK(ui_activate_event_wrapper),
626 event);
627 g_signal_connect(
628 obj->widget,
629 "destroy",
630 G_CALLBACK(ui_destroy_userdata),
631 event);
632
633 ui_update_gmenu_item_list(NULL, ls);
634 }
635
636 void ui_activate_event_wrapper(GSimpleAction* self, GVariant* parameter, UiEventData *event) {
637 int intval = event->value;
638 if(parameter && g_variant_is_of_type(parameter, G_VARIANT_TYPE_INT32)) {
639 intval = g_variant_get_int32(parameter);
640 }
641
642 UiEvent evt;
643 evt.obj = event->obj;
644 evt.window = event->obj->window;
645 evt.document = event->obj->ctx->document;
646 evt.eventdata = event->customdata;
647 evt.intval = intval;
648 event->callback(&evt, event->userdata);
649 }
650
651 void ui_update_gmenu_item_list(UiEvent *event, UiActiveGMenuItemList *list) {
652 // remove old items
653 for(int i=0;i<list->oldcount;i++) {
654 g_menu_remove(list->menu, list->index);
655 }
656
657 // add list items
658 ui_getvaluefunc getvalue = list->getvalue;
659 int i = 0;
660 void* elm = ui_list_first(list->list);
661 while(elm) {
662 char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
663
664 GMenuItem *item = g_menu_item_new(label, NULL);
665 GVariant *v = g_variant_new("i", i);
666 g_menu_item_set_action_and_target_value(item, list->action, v);
667 g_menu_insert_item(list->menu, list->index+i, item);
668
669 elm = ui_list_next(list->list);
670 i++;
671 }
672
673 list->oldcount = i;
674 }
675
676 #endif

mercurial