| 524 return ctx->parent; |
524 return ctx->parent; |
| 525 } |
525 } |
| 526 |
526 |
| 527 |
527 |
| 528 void ui_set_group(UiContext *ctx, int group) { |
528 void ui_set_group(UiContext *ctx, int group) { |
| 529 if(!cxListIndexValid(ctx->groups, cxListFind(ctx->groups, &group))) { |
529 if(!cxListIndexValid(ctx->states, cxListFind(ctx->states, &group))) { |
| 530 cxListAdd(ctx->groups, &group); |
530 cxListAdd(ctx->states, &group); |
| 531 } |
531 } |
| 532 |
532 |
| 533 // enable/disable group widgets |
533 // enable/disable group widgets |
| 534 uic_check_group_widgets(ctx); |
534 uic_check_state_widgets(ctx); |
| 535 } |
535 } |
| 536 |
536 |
| 537 void ui_unset_group(UiContext *ctx, int group) { |
537 void ui_unset_group(UiContext *ctx, int group) { |
| 538 int i = cxListFind(ctx->groups, &group); |
538 int i = cxListFind(ctx->states, &group); |
| 539 if(i != -1) { |
539 if(i != -1) { |
| 540 cxListRemove(ctx->groups, i); |
540 cxListRemove(ctx->states, i); |
| 541 } |
541 } |
| 542 |
542 |
| 543 // enable/disable group widgets |
543 // enable/disable group widgets |
| 544 uic_check_group_widgets(ctx); |
544 uic_check_state_widgets(ctx); |
| 545 } |
545 } |
| 546 |
546 |
| 547 int* ui_active_groups(UiContext *ctx, int *ngroups) { |
547 int* ui_active_groups(UiContext *ctx, int *ngroups) { |
| 548 *ngroups = cxListSize(ctx->groups); |
548 *ngroups = cxListSize(ctx->states); |
| 549 return cxListAt(ctx->groups, 0); |
549 return cxListAt(ctx->states, 0); |
| 550 } |
550 } |
| 551 |
551 |
| 552 void uic_check_group_widgets(UiContext *ctx) { |
552 void uic_check_state_widgets(UiContext *ctx) { |
| 553 int ngroups = 0; |
553 int ngroups = 0; |
| 554 int *groups = ui_active_groups(ctx, &ngroups); |
554 int *groups = ui_active_groups(ctx, &ngroups); |
| 555 |
555 |
| 556 CxIterator i = cxListIterator(ctx->group_widgets); |
556 CxIterator i = cxListIterator(ctx->state_widgets); |
| 557 cx_foreach(UiGroupWidget *, gw, i) { |
557 cx_foreach(UiStateWidget *, gw, i) { |
| 558 char *check = calloc(1, gw->numgroups); |
558 char *check = calloc(1, gw->numstates); |
| 559 |
559 |
| 560 for(int i=0;i<ngroups;i++) { |
560 for(int i=0;i<ngroups;i++) { |
| 561 for(int k=0;k<gw->numgroups;k++) { |
561 for(int k=0;k<gw->numstates;k++) { |
| 562 if(groups[i] == gw->groups[k]) { |
562 if(groups[i] == gw->states[k]) { |
| 563 check[k] = 1; |
563 check[k] = 1; |
| 564 } |
564 } |
| 565 } |
565 } |
| 566 } |
566 } |
| 567 |
567 |
| 568 int enable = 1; |
568 int enable = 1; |
| 569 for(int i=0;i<gw->numgroups;i++) { |
569 for(int i=0;i<gw->numstates;i++) { |
| 570 if(check[i] == 0) { |
570 if(check[i] == 0) { |
| 571 enable = 0; |
571 enable = 0; |
| 572 break; |
572 break; |
| 573 } |
573 } |
| 574 } |
574 } |
| 575 free(check); |
575 free(check); |
| 576 gw->enable(gw->widget, enable); |
576 gw->enable(gw->widget, enable); |
| 577 } |
577 } |
| 578 } |
578 } |
| 579 |
579 |
| 580 void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) { |
580 void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) { |
| 581 if(enable == NULL) { |
581 if(enable == NULL) { |
| 582 enable = (ui_enablefunc)ui_set_enabled; |
582 enable = (ui_enablefunc)ui_set_enabled; |
| 583 } |
583 } |
| 584 // get groups |
584 // get states |
| 585 CxList *groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16); |
585 CxList *states = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16); |
| 586 va_list ap; |
586 va_list ap; |
| 587 va_start(ap, enable); |
587 va_start(ap, enable); |
| 588 int group; |
588 int state; |
| 589 while((group = va_arg(ap, int)) != -1) { |
589 while((state = va_arg(ap, int)) != -1) { |
| 590 cxListAdd(groups, &group); |
590 cxListAdd(states, &state); |
| 591 } |
591 } |
| 592 va_end(ap); |
592 va_end(ap); |
| 593 |
593 |
| 594 uic_add_group_widget(ctx, widget, enable, groups); |
594 uic_add_state_widget(ctx, widget, enable, states); |
| 595 |
595 |
| 596 cxListFree(groups); |
596 cxListFree(states); |
| 597 } |
597 } |
| 598 |
598 |
| 599 void ui_widget_set_groups2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *groups, int ngroups) { |
599 void ui_widget_set_states2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *states, int nstates) { |
| 600 if(enable == NULL) { |
600 if(enable == NULL) { |
| 601 enable = (ui_enablefunc)ui_set_enabled; |
601 enable = (ui_enablefunc)ui_set_enabled; |
| 602 } |
602 } |
| 603 CxList *ls = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), ngroups); |
603 CxList *ls = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), nstates); |
| 604 for(int i=0;i<ngroups;i++) { |
604 for(int i=0;i<nstates;i++) { |
| 605 cxListAdd(ls, groups+i); |
605 cxListAdd(ls, states+i); |
| 606 } |
606 } |
| 607 uic_add_group_widget(ctx, widget, enable, ls); |
607 uic_add_state_widget(ctx, widget, enable, ls); |
| 608 cxListFree(ls); |
608 cxListFree(ls); |
| 609 } |
609 } |
| 610 |
610 |
| 611 void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates) { |
611 void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates) { |
| 612 ui_widget_set_groups2(ctx, widget, (ui_enablefunc)ui_set_visible, states, nstates); |
612 ui_widget_set_states2(ctx, widget, (ui_enablefunc)ui_set_visible, states, nstates); |
| 613 } |
613 } |
| 614 |
614 |
| 615 size_t uic_group_array_size(const int *groups) { |
615 size_t uic_state_array_size(const int *states) { |
| 616 int i; |
616 int i; |
| 617 for(i=0;groups[i] >= 0;i++) { } |
617 for(i=0;states[i] >= 0;i++) { } |
| 618 return i; |
618 return i; |
| 619 } |
619 } |
| 620 |
620 |
| 621 void uic_add_group_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *groups) { |
621 void uic_add_state_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *states) { |
| 622 uic_add_group_widget_i(ctx, widget, enable, cxListAt(groups, 0), cxListSize(groups)); |
622 uic_add_state_widget_i(ctx, widget, enable, cxListAt(states, 0), cxListSize(states)); |
| 623 } |
623 } |
| 624 |
624 |
| 625 void uic_add_group_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *groups, size_t numgroups) { |
625 void uic_add_state_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *states, size_t numstates) { |
| 626 const CxAllocator *a = ctx->allocator; |
626 const CxAllocator *a = ctx->allocator; |
| 627 UiGroupWidget gw; |
627 UiStateWidget gw; |
| 628 |
628 |
| 629 gw.widget = widget; |
629 gw.widget = widget; |
| 630 gw.enable = enable; |
630 gw.enable = enable; |
| 631 gw.numgroups = numgroups; |
631 gw.numstates = numstates; |
| 632 gw.groups = cxCalloc(a, numgroups, sizeof(int)); |
632 gw.states = cxCalloc(a, numstates, sizeof(int)); |
| 633 |
633 |
| 634 // copy groups |
634 // copy states |
| 635 if(groups) { |
635 if(states) { |
| 636 memcpy(gw.groups, groups, gw.numgroups * sizeof(int)); |
636 memcpy(gw.states, states, gw.numstates * sizeof(int)); |
| 637 } |
637 } |
| 638 |
638 |
| 639 cxListAdd(ctx->group_widgets, &gw); |
639 cxListAdd(ctx->state_widgets, &gw); |
| 640 } |
640 } |
| 641 |
641 |
| 642 void uic_remove_group_widget(UiContext *ctx, void *widget) { |
642 void uic_remove_state_widget(UiContext *ctx, void *widget) { |
| 643 (void)cxListFindRemove(ctx->group_widgets, widget); |
643 (void)cxListFindRemove(ctx->state_widgets, widget); |
| 644 } |
644 } |
| 645 |
645 |
| 646 UIEXPORT void *ui_allocator(UiContext *ctx) { |
646 UIEXPORT void *ui_allocator(UiContext *ctx) { |
| 647 return (void*)ctx->allocator; |
647 return (void*)ctx->allocator; |
| 648 } |
648 } |