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 |