ui/common/context.c

changeset 1203
35779840ebfd
parent 1201
fd7dc0716ab6
equal deleted inserted replaced
1202:412790168d30 1203:35779840ebfd
65 65
66 ctx->documents = cxLinkedListCreate(mp->allocator, CX_STORE_POINTERS); 66 ctx->documents = cxLinkedListCreate(mp->allocator, CX_STORE_POINTERS);
67 ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget)); 67 ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget));
68 ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32); 68 ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32);
69 cxSetCompareFunc(ctx->states, cx_cmp_int); 69 cxSetCompareFunc(ctx->states, cx_cmp_int);
70 ctx->suppressed_states = cxArrayListCreate(mp->allocator, sizeof(int), 16);
71 cxSetCompareFunc(ctx->suppressed_states, cx_cmp_int);
70 72
71 ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8); 73 ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8);
72 ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0); 74 ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0);
73 75
74 #if UI_GTK2 || UI_GTK3 76 #if UI_GTK2 || UI_GTK3
680 682
681 // enable/disable group widgets 683 // enable/disable group widgets
682 uic_check_state_widgets(ui_context_toplevel_parent(ctx)); 684 uic_check_state_widgets(ui_context_toplevel_parent(ctx));
683 } 685 }
684 686
687 void ui_suppress_state(UiContext *ctx, int state) {
688 if(!cxListIndexValid(ctx->suppressed_states, cxListFind(ctx->suppressed_states, &state))) {
689 cxListAdd(ctx->suppressed_states, &state);
690 }
691
692 // enable/disable group widgets
693 uic_check_state_widgets(ui_context_toplevel_parent(ctx));
694 }
695
696 void ui_unsuppress_state(UiContext *ctx, int state) {
697 int i = cxListFind(ctx->suppressed_states, &state);
698 if(i != -1) {
699 cxListRemove(ctx->suppressed_states, i);
700 }
701
702 // enable/disable group widgets
703 uic_check_state_widgets(ui_context_toplevel_parent(ctx));
704 }
705
685 typedef struct StatesList { 706 typedef struct StatesList {
686 CX_ARRAY(int, states); 707 CX_ARRAY(int, states);
708 CX_ARRAY(int, suppressed);
687 } StatesList; 709 } StatesList;
688 710
689 static void add_ctx_states(UiContext *ctx, StatesList *states) { 711 static void add_ctx_states(UiContext *ctx, StatesList *states) {
690 size_t nstates = cxListSize(ctx->states); 712 size_t nstates = cxListSize(ctx->states);
691 int *ctx_states = cxListAt(ctx->states, 0);; 713 int *ctx_states = cxListAt(ctx->states, 0);
714
715 size_t nsuppressed = cxListSize(ctx->suppressed_states);
716 int *ctx_suppressed_states = cxListAt(ctx->suppressed_states, 0);
692 717
693 cx_array_add_array(states->states, ctx_states, nstates); 718 cx_array_add_array(states->states, ctx_states, nstates);
719 cx_array_add_array(states->suppressed, ctx_suppressed_states, nsuppressed);
694 720
695 CxIterator i = cxListIterator(ctx->documents); 721 CxIterator i = cxListIterator(ctx->documents);
696 cx_foreach(void *, doc, i) { 722 cx_foreach(void *, doc, i) {
697 UiContext *doc_ctx = ui_document_context(doc); 723 UiContext *doc_ctx = ui_document_context(doc);
698 add_ctx_states(doc_ctx, states); 724 add_ctx_states(doc_ctx, states);
700 } 726 }
701 727
702 int* ui_active_states(UiContext *ctx, int *nstates) { 728 int* ui_active_states(UiContext *ctx, int *nstates) {
703 StatesList states; 729 StatesList states;
704 cx_array_init(states.states, 32); 730 cx_array_init(states.states, 32);
731 cx_array_init(states.suppressed, 8);
705 add_ctx_states(ctx, &states); 732 add_ctx_states(ctx, &states);
733
734 // remove suppressed states
735 for(size_t i=0;i<states.suppressed.size;i++) {
736 int suppressed = states.suppressed.data[i];
737 // important to use ssize_t for the index here
738 for(ssize_t s=0;s<states.states.size;s++) {
739 if(states.states.data[s] == suppressed) {
740 // this state is suppressed
741 if(s+1 < states.states.size) {
742 // copy last element to the current position
743 states.states.data[s] = states.states.data[states.states.size-1];
744 // we need to check the current index again
745 s--;
746 }
747 states.states.size--;
748 }
749 }
750 }
751
752 free(states.suppressed.data);
706 *nstates = (int)states.states.size; 753 *nstates = (int)states.states.size;
707 return states.states.data; 754 return states.states.data;
708 } 755 }
709 756
710 void uic_check_state_widgets(UiContext *ctx) { 757 void uic_check_state_widgets(UiContext *ctx) {
711 if(!ctx) { 758 if(!ctx) {
712 return; 759 return;
713 } 760 }
714 761
715 int ngroups = 0; 762 int nstates = 0;
716 int *groups = ui_active_states(ctx, &ngroups); 763 int *states = ui_active_states(ctx, &nstates);
717 764
718 CxIterator i = cxListIterator(ctx->state_widgets); 765 CxIterator i = cxListIterator(ctx->state_widgets);
719 cx_foreach(UiStateWidget *, gw, i) { 766 cx_foreach(UiStateWidget *, gw, i) {
720 char *check = calloc(1, gw->numstates); 767 char *check = calloc(1, gw->numstates);
721 768
722 for(int i=0;i<ngroups;i++) { 769 for(int i=0;i<nstates;i++) {
723 for(int k=0;k<gw->numstates;k++) { 770 for(int k=0;k<gw->numstates;k++) {
724 if(groups[i] == gw->states[k]) { 771 if(states[i] == gw->states[k]) {
725 check[k] = 1; 772 check[k] = 1;
726 } 773 }
727 } 774 }
728 } 775 }
729 776
736 } 783 }
737 free(check); 784 free(check);
738 gw->enable(gw->widget, enable); 785 gw->enable(gw->widget, enable);
739 } 786 }
740 787
741 free(groups); 788 free(states);
742 } 789 }
743 790
744 void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) { 791 void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) {
745 if(enable == NULL) { 792 if(enable == NULL) {
746 enable = (ui_enablefunc)ui_set_enabled; 793 enable = (ui_enablefunc)ui_set_enabled;

mercurial