add ui_suppress_state/ui_unsuppress_state default tip

Tue, 16 Jun 2026 17:29:14 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 16 Jun 2026 17:29:14 +0200
changeset 1203
35779840ebfd
parent 1202
412790168d30

add ui_suppress_state/ui_unsuppress_state

application/demo_states.c file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/application/demo_states.c	Mon Jun 15 21:16:47 2026 +0200
+++ b/application/demo_states.c	Tue Jun 16 17:29:14 2026 +0200
@@ -90,6 +90,42 @@
     }
 }
 
+static void doc_suppress_state1(UiEvent *event, void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    if(event->intval) {
+        ui_suppress_state(ctx, 1);
+    } else {
+        ui_unsuppress_state(ctx, 1);
+    }
+}
+
+static void doc_suppress_state2(UiEvent *event, void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    if(event->intval) {
+        ui_suppress_state(ctx, 2);
+    } else {
+        ui_unsuppress_state(ctx, 2);
+    }
+}
+
+static void doc_suppress_state3(UiEvent *event, void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    if(event->intval) {
+        ui_suppress_state(ctx, 3);
+    } else {
+        ui_unsuppress_state(ctx, 3);
+    }
+}
+
+static void doc_suppress_state4(UiEvent *event, void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    if(event->intval) {
+        ui_suppress_state(ctx, 4);
+    } else {
+        ui_unsuppress_state(ctx, 4);
+    }
+}
+
 static void application_startup(UiEvent *event, void *userdata) {
     UiObject *obj = ui_window("States Demo");
     
@@ -117,21 +153,35 @@
         ui_frame(obj, .label = "Doc 1", .fill = TRUE, .margin = 10, .padding = 10, .spacing = 10, .subcontainer = UI_CONTAINER_VBOX) {
             ui_togglebutton(obj, .label = "Attach", .onchange = doc1_attachment);
             
-            ui_hbox(obj, .margin = 10, .spacing = 8) {
+            ui_grid(obj, .margin = 10, .columnspacing = 8, .rowspacing = 8, .def_hfill = TRUE) {
                 ui_togglebutton(obj, .label = "Enable 1", .onchange = doc_enable_state1, .onchangedata = doc1);
                 ui_togglebutton(obj, .label = "Enable 2", .onchange = doc_enable_state2, .onchangedata = doc1);
                 ui_togglebutton(obj, .label = "Enable 3", .onchange = doc_enable_state3, .onchangedata = doc1);
                 ui_togglebutton(obj, .label = "Enable 4", .onchange = doc_enable_state4, .onchangedata = doc1);
+                
+                ui_newline(obj);
+                
+                ui_togglebutton(obj, .label = "Suppress 1", .onchange = doc_suppress_state1, .onchangedata = doc1);
+                ui_togglebutton(obj, .label = "Suppress 2", .onchange = doc_suppress_state2, .onchangedata = doc1);
+                ui_togglebutton(obj, .label = "Suppress 3", .onchange = doc_suppress_state3, .onchangedata = doc1);
+                ui_togglebutton(obj, .label = "Suppress 4", .onchange = doc_suppress_state4, .onchangedata = doc1);
             }
             
             ui_frame(obj, .label = "Doc 2", .fill = TRUE, .margin = 10, .padding = 10, .spacing = 10, .subcontainer = UI_CONTAINER_VBOX) {
                 ui_togglebutton(obj, .label = "Attach", .onchange = doc2_attachment);
             
-                ui_hbox(obj, .margin = 10, .spacing = 8) {
+                ui_grid(obj, .margin = 10, .columnspacing = 8, .rowspacing = 8, .def_hfill = TRUE) {
                     ui_togglebutton(obj, .label = "Enable 1", .onchange = doc_enable_state1, .onchangedata = doc2);
                     ui_togglebutton(obj, .label = "Enable 2", .onchange = doc_enable_state2, .onchangedata = doc2);
                     ui_togglebutton(obj, .label = "Enable 3", .onchange = doc_enable_state3, .onchangedata = doc2);
                     ui_togglebutton(obj, .label = "Enable 4", .onchange = doc_enable_state4, .onchangedata = doc2);
+                    
+                    ui_newline(obj);
+                    
+                    ui_togglebutton(obj, .label = "Suppress 1", .onchange = doc_suppress_state1, .onchangedata = doc2);
+                    ui_togglebutton(obj, .label = "Suppress 2", .onchange = doc_suppress_state2, .onchangedata = doc2);
+                    ui_togglebutton(obj, .label = "Suppress 3", .onchange = doc_suppress_state3, .onchangedata = doc2);
+                    ui_togglebutton(obj, .label = "Suppress 4", .onchange = doc_suppress_state4, .onchangedata = doc2);
                 }
             }
         }
--- a/ui/common/context.c	Mon Jun 15 21:16:47 2026 +0200
+++ b/ui/common/context.c	Tue Jun 16 17:29:14 2026 +0200
@@ -67,6 +67,8 @@
     ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget));
     ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32);
     cxSetCompareFunc(ctx->states, cx_cmp_int);
+    ctx->suppressed_states = cxArrayListCreate(mp->allocator, sizeof(int), 16);
+    cxSetCompareFunc(ctx->suppressed_states, cx_cmp_int);
     
     ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8);
     ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0);
@@ -682,15 +684,39 @@
     uic_check_state_widgets(ui_context_toplevel_parent(ctx));
 }
 
+void ui_suppress_state(UiContext *ctx, int state) {
+    if(!cxListIndexValid(ctx->suppressed_states, cxListFind(ctx->suppressed_states, &state))) {
+        cxListAdd(ctx->suppressed_states, &state);
+    }
+    
+    // enable/disable group widgets
+    uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+void ui_unsuppress_state(UiContext *ctx, int state) {
+    int i = cxListFind(ctx->suppressed_states, &state);
+    if(i != -1) {
+        cxListRemove(ctx->suppressed_states, i);
+    }
+    
+    // enable/disable group widgets
+    uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
 typedef struct StatesList {
     CX_ARRAY(int, states);
+    CX_ARRAY(int, suppressed);
 } StatesList;
 
 static void add_ctx_states(UiContext *ctx, StatesList *states) {
     size_t nstates = cxListSize(ctx->states);
-    int *ctx_states = cxListAt(ctx->states, 0);;
+    int *ctx_states = cxListAt(ctx->states, 0);
+    
+    size_t nsuppressed = cxListSize(ctx->suppressed_states);
+    int *ctx_suppressed_states = cxListAt(ctx->suppressed_states, 0);
     
     cx_array_add_array(states->states, ctx_states, nstates);
+    cx_array_add_array(states->suppressed, ctx_suppressed_states, nsuppressed);
     
     CxIterator i = cxListIterator(ctx->documents);
     cx_foreach(void *, doc, i) {
@@ -702,7 +728,28 @@
 int* ui_active_states(UiContext *ctx, int *nstates) {
     StatesList states;
     cx_array_init(states.states, 32);
+    cx_array_init(states.suppressed, 8);
     add_ctx_states(ctx, &states);
+    
+    // remove suppressed states
+    for(size_t i=0;i<states.suppressed.size;i++) {
+        int suppressed = states.suppressed.data[i];
+        // important to use ssize_t for the index here
+        for(ssize_t s=0;s<states.states.size;s++) {
+            if(states.states.data[s] == suppressed) {
+                // this state is suppressed
+                if(s+1 < states.states.size) {
+                    // copy last element to the current position
+                    states.states.data[s] = states.states.data[states.states.size-1];
+                    // we need to check the current index again
+                    s--;
+                }
+                states.states.size--;
+            }
+        }
+    }
+    
+    free(states.suppressed.data);
     *nstates = (int)states.states.size;
     return states.states.data;
 }
@@ -712,16 +759,16 @@
         return;
     }
     
-    int ngroups = 0;
-    int *groups = ui_active_states(ctx, &ngroups);
+    int nstates = 0;
+    int *states = ui_active_states(ctx, &nstates);
     
     CxIterator i = cxListIterator(ctx->state_widgets);
     cx_foreach(UiStateWidget *, gw, i) {
         char *check = calloc(1, gw->numstates);
         
-        for(int i=0;i<ngroups;i++) {
+        for(int i=0;i<nstates;i++) {
             for(int k=0;k<gw->numstates;k++) {
-                if(groups[i] == gw->states[k]) {
+                if(states[i] == gw->states[k]) {
                     check[k] = 1;
                 }
             }
@@ -738,7 +785,7 @@
         gw->enable(gw->widget, enable);
     }
     
-    free(groups);
+    free(states);
 }
 
 void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) {
--- a/ui/common/context.h	Mon Jun 15 21:16:47 2026 +0200
+++ b/ui/common/context.h	Tue Jun 16 17:29:14 2026 +0200
@@ -75,6 +75,7 @@
     CxMap         *vars;
     
     CxList        *states; // int list
+    CxList        *suppressed_states; // int list
     CxList        *state_widgets; // UiGroupWidget list
     
     CxMap         *actions; // key: action name (string), value: UiAction
--- a/ui/ui/toolkit.h	Mon Jun 15 21:16:47 2026 +0200
+++ b/ui/ui/toolkit.h	Tue Jun 16 17:29:14 2026 +0200
@@ -624,6 +624,8 @@
 
 UIEXPORT void ui_set_state(UiContext *ctx, int state);
 UIEXPORT void ui_unset_state(UiContext *ctx, int state);
+UIEXPORT void ui_suppress_state(UiContext *ctx, int state);
+UIEXPORT void ui_unsuppress_state(UiContext *ctx, int state);
 UIEXPORT int* ui_active_states(UiContext *ctx, int *nstates);
     
 UIEXPORT void* ui_allocator(UiContext *ctx);

mercurial