UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2026 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 32 #include "demo_table.h" 33 34 #ifndef UI_WIN32 35 36 int main(int argc, char **argv) { 37 #ifdef UI_GTK4 38 ui_init(NULL, argc, argv); 39 ui_onstartup(application_startup, NULL); 40 ui_main(); 41 #else 42 printf("not supported yet\n"); 43 #endif 44 return 0; 45 } 46 47 #else 48 49 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { 50 //ui_init(NULL, argc, argv); 51 //ui_onstartup(application_startup, NULL); 52 //ui_main(); 53 return 0; 54 } 55 56 #endif 57 58 static void init_toolbar(void) { 59 60 } 61 62 static void create_main_window(void) { 63 UiObject *obj = ui_window("Table Demo"); 64 65 MainWindow *wdata = ui_zalloc(obj->ctx, sizeof(MainWindow)); 66 wdata->model = ui_model_new(obj->ctx, NULL); 67 wdata->data = ui_list_new(obj->ctx, NULL); 68 wdata->indices = ui_list_new(obj->ctx, NULL); 69 wdata->columnname = ui_string_new(obj->ctx, NULL); 70 71 obj->window = wdata; 72 73 ui_table(obj, .fill = TRUE, .list = wdata->data, .model = wdata->model, 74 .getvalue2 = row_get_data, .onsave = row_save); 75 76 ui_grid(obj, .margin = 10, .columnspacing = 6, .rowspacing = 6, .def_vfill = TRUE) { 77 ui_rlabel(obj, .label = "Index"); 78 ui_dropdown(obj, .list = wdata->indices); 79 ui_rlabel(obj, .label = "Name"); 80 ui_textfield(obj, .value = wdata->columnname, .hfill = TRUE, .hexpand = TRUE); 81 ui_button(obj, .label = "Add", .onclick = add_column); 82 ui_button(obj, .label = "Remove", .onclick = remove_column); 83 84 ui_newline(obj); 85 ui_button(obj, .colspan = 6, .label = "Add Row", .onclick = add_row); 86 } 87 88 update_indices(wdata); 89 90 ui_show(obj); 91 } 92 93 void application_startup(UiEvent *event, void *userdata) { 94 init_toolbar(); 95 create_main_window(); 96 } 97 98 void update_indices(MainWindow *wdata) { 99 UiList *list = wdata->indices; 100 101 // clear previous values 102 char *elm = list->first(list); 103 while(elm) { 104 free(elm); 105 elm = list->next(list); 106 } 107 ui_list_clear(wdata->indices); 108 109 char buf[32]; 110 for(int i=0;i<=wdata->model->columns;i++) { 111 snprintf(buf, 32, "%d", i); 112 ui_list_append(list, strdup(buf)); 113 } 114 115 ui_list_update(wdata->indices); 116 } 117 118 void add_column(UiEvent *event, void *userdata) { 119 MainWindow *wdata = event->window; 120 121 char *name = ui_get(wdata->columnname); 122 size_t namelen = strlen(name); 123 124 if(namelen == 0) { 125 printf("cannot add column: no name specified\n"); 126 return; 127 } 128 129 int index = ui_list_getselection(wdata->indices); 130 131 ui_model_insert_column(wdata->model, index, UI_STRING_EDITABLE, NULL, name, 0, TRUE); 132 ui_set(wdata->columnname, ""); 133 134 update_indices(wdata); 135 136 ui_list_setselection(wdata->indices, wdata->model->columns); 137 } 138 139 void remove_column(UiEvent *event, void *userdata) { 140 MainWindow *wdata = event->window; 141 int index = ui_list_getselection(wdata->indices); 142 143 if(index < 0 || index >= wdata->model->columns) { 144 printf("cannot remove column: invalid index: %d\n", index); 145 return; 146 } 147 148 ui_model_remove_column(wdata->model, index); 149 update_indices(wdata); 150 ui_list_setselection(wdata->indices, wdata->model->columns); 151 } 152 153 void add_row(UiEvent *event, void *userdata) { 154 MainWindow *wdata = event->window; 155 156 TableRow *row = malloc(sizeof(TableRow)); 157 memset(row, 0, sizeof(TableRow)); 158 159 ui_list_append(wdata->data, row); 160 ui_list_update(wdata->data); 161 162 print_table_data(wdata); 163 } 164 165 void* row_get_data(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { 166 TableRow *row_data = elm; 167 return row_get(row_data, col); 168 } 169 170 UiBool row_save(UiList *list, void *elm, int row, int col, UiCellValue *value, void *userdata) { 171 if(value->type != UI_STRING_EDITABLE) { 172 return FALSE; 173 } 174 TableRow *row_data = elm; 175 row_set(row_data, col, value->string); 176 177 return TRUE; 178 } 179 180 void row_set(TableRow *row, int index, const char *value) { 181 if(index >= row->capacity) { 182 size_t old_capacity = row->capacity; 183 row->capacity += 8; 184 char **columns = calloc(row->capacity, sizeof(char*)); 185 if(row->columns) { 186 memcpy(columns, row->columns, old_capacity * sizeof(char*)); 187 free(row->columns); 188 } 189 row->columns = columns; 190 } 191 free(row->columns[index]); 192 row->columns[index] = strdup(value); 193 } 194 195 char* row_get(TableRow *row, int index) { 196 if(index >= row->capacity) { 197 return NULL; 198 } 199 return row->columns[index]; 200 } 201 202 203 void print_table_data(MainWindow *wdata) { 204 printf("table data:\n-----------------\n\n"); 205 UiList *list = wdata->data; 206 TableRow *elm = list->first(list); 207 while(elm) { 208 for(int i=0;i<elm->capacity;i++) { 209 printf("[%d]: %s\n", i, elm->columns[i]); 210 } 211 printf("\n"); 212 213 elm = list->next(list); 214 } 215 printf("\n\n"); 216 } 217