ui/gtk/menu.c

changeset 44
473954dc6b74
parent 42
9af327d0e0e4
child 46
31bc86844659
equal deleted inserted replaced
43:ef01d2c90128 44:473954dc6b74
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->var = var;
601 UiList *list = var->value;
602
603 ls->callback = il->callback;
604 ls->userdata = il->userdata;
605
606 list->observers = ui_add_observer(
607 list->observers,
608 (ui_callback)ui_update_gmenu_item_list,
609 ls);
610
611 GSimpleAction *action = g_simple_action_new(item->id, g_variant_type_new("i"));
612 g_action_map_add_action(obj->ctx->action_map, G_ACTION(action));
613 snprintf(ls->action, 32, "win.%s", item->id);
614
615
616 UiEventData *event = malloc(sizeof(UiEventData));
617 event->obj = obj;
618 event->userdata = il->userdata;
619 event->callback = il->callback;
620 event->customdata = var;
621 event->value = 0;
622
623 g_signal_connect(
624 action,
625 "activate",
626 G_CALLBACK(ui_menu_list_item_activate_event_wrapper),
627 event);
628 g_signal_connect(
629 obj->widget,
630 "destroy",
631 G_CALLBACK(ui_destroy_userdata),
632 event);
633
634 ui_update_gmenu_item_list(NULL, ls);
635 }
636
637 void ui_activate_event_wrapper(GSimpleAction* self, GVariant* parameter, UiEventData *event) {
638 int intval = event->value;
639 if(parameter && g_variant_is_of_type(parameter, G_VARIANT_TYPE_INT32)) {
640 intval = g_variant_get_int32(parameter);
641 }
642
643 UiEvent evt;
644 evt.obj = event->obj;
645 evt.window = event->obj->window;
646 evt.document = event->obj->ctx->document;
647 evt.eventdata = event->customdata;
648 evt.intval = intval;
649 event->callback(&evt, event->userdata);
650 }
651
652 void ui_menu_list_item_activate_event_wrapper(GSimpleAction* self, GVariant* parameter, UiEventData *event) {
653 int index = g_variant_get_int32(parameter);
654 UiVar *var = event->customdata;
655 UiList *list = var->value;
656
657 UiEvent evt;
658 evt.obj = event->obj;
659 evt.window = event->obj->window;
660 evt.document = event->obj->ctx->document;
661 evt.eventdata = ui_list_get(list, index);
662 evt.intval = index;
663 event->callback(&evt, event->userdata);
664
665 }
666
667 void ui_update_gmenu_item_list(UiEvent *event, UiActiveGMenuItemList *list) {
668 // remove old items
669 for(int i=0;i<list->oldcount;i++) {
670 g_menu_remove(list->menu, list->index);
671 }
672 UiList *ls = list->var->value;
673
674 // add list items
675 ui_getvaluefunc getvalue = list->getvalue;
676 int i = 0;
677 void* elm = ui_list_first(ls);
678 while(elm) {
679 char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
680
681 GMenuItem *item = g_menu_item_new(label, NULL);
682 GVariant *v = g_variant_new("i", i);
683 g_menu_item_set_action_and_target_value(item, list->action, v);
684 g_menu_insert_item(list->menu, list->index+i, item);
685
686 elm = ui_list_next(ls);
687 i++;
688 }
689
690 list->oldcount = i;
691 }
692
693 #endif

mercurial