#include <stdio.h>
#include <stdlib.h>
#include "demo_table.h"
#ifndef UI_WIN32
int main(
int argc,
char **argv) {
#ifdef UI_GTK4
ui_init(
NULL, argc, argv);
ui_onstartup(application_startup,
NULL);
ui_main();
#else
printf(
"not supported yet\n");
#endif
return 0;
}
#else
int WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd) {
return 0;
}
#endif
static void init_toolbar(
void) {
}
static void create_main_window(
void) {
UiObject *obj = ui_window(
"Table Demo");
MainWindow *wdata = ui_zalloc(obj->ctx,
sizeof(MainWindow));
wdata->model = ui_model_new(obj->ctx,
NULL);
wdata->data = ui_list_new(obj->ctx,
NULL);
wdata->indices = ui_list_new(obj->ctx,
NULL);
wdata->columnname = ui_string_new(obj->ctx,
NULL);
obj->window = wdata;
ui_table(obj, .fill =
TRUE, .list = wdata->data, .model = wdata->model,
.getvalue2 = row_get_data, .onsave = row_save);
ui_grid(obj, .margin =
10, .columnspacing =
6, .rowspacing =
6, .def_vfill =
TRUE) {
ui_rlabel(obj, .label =
"Index");
ui_dropdown(obj, .list = wdata->indices);
ui_rlabel(obj, .label =
"Name");
ui_textfield(obj, .value = wdata->columnname, .hfill =
TRUE, .hexpand =
TRUE);
ui_button(obj, .label =
"Add", .onclick = add_column);
ui_button(obj, .label =
"Remove", .onclick = remove_column);
ui_newline(obj);
ui_button(obj, .colspan =
6, .label =
"Add Row", .onclick = add_row);
}
update_indices(wdata);
ui_show(obj);
}
void application_startup(UiEvent *event,
void *userdata) {
init_toolbar();
create_main_window();
}
void update_indices(MainWindow *wdata) {
UiList *list = wdata->indices;
char *elm = list->first(list);
while(elm) {
free(elm);
elm = list->next(list);
}
ui_list_clear(wdata->indices);
char buf[
32];
for(
int i=
0;i<=wdata->model->columns;i++) {
snprintf(buf,
32,
"%d", i);
ui_list_append(list, strdup(buf));
}
ui_list_update(wdata->indices);
}
void add_column(UiEvent *event,
void *userdata) {
MainWindow *wdata = event->window;
char *name = ui_get(wdata->columnname);
size_t namelen = strlen(name);
if(namelen ==
0) {
printf(
"cannot add column: no name specified\n");
return;
}
int index = ui_list_getselection(wdata->indices);
ui_model_insert_column(wdata->model, index,
UI_STRING_EDITABLE,
NULL, name,
0,
TRUE);
ui_set(wdata->columnname,
"");
update_indices(wdata);
ui_list_setselection(wdata->indices, wdata->model->columns);
}
void remove_column(UiEvent *event,
void *userdata) {
MainWindow *wdata = event->window;
int index = ui_list_getselection(wdata->indices);
if(index <
0 || index >= wdata->model->columns) {
printf(
"cannot remove column: invalid index: %d\n", index);
return;
}
ui_model_remove_column(wdata->model, index);
update_indices(wdata);
ui_list_setselection(wdata->indices, wdata->model->columns);
}
void add_row(UiEvent *event,
void *userdata) {
MainWindow *wdata = event->window;
TableRow *row = malloc(
sizeof(TableRow));
memset(row,
0,
sizeof(TableRow));
ui_list_append(wdata->data, row);
ui_list_update(wdata->data);
print_table_data(wdata);
}
void* row_get_data(UiList *list,
void *elm,
int row,
int col,
void *userdata, UiBool *freeResult) {
TableRow *row_data = elm;
return row_get(row_data, col);
}
UiBool row_save(UiList *list,
void *elm,
int row,
int col, UiCellValue *value,
void *userdata) {
if(value->type !=
UI_STRING_EDITABLE) {
return FALSE;
}
TableRow *row_data = elm;
row_set(row_data, col, value->string);
return TRUE;
}
void row_set(TableRow *row,
int index,
const char *value) {
if(index >= row->capacity) {
size_t old_capacity = row->capacity;
row->capacity +=
8;
char **columns = calloc(row->capacity,
sizeof(
char*));
if(row->columns) {
memcpy(columns, row->columns, old_capacity *
sizeof(
char*));
free(row->columns);
}
row->columns = columns;
}
free(row->columns[index]);
row->columns[index] = strdup(value);
}
char* row_get(TableRow *row,
int index) {
if(index >= row->capacity) {
return NULL;
}
return row->columns[index];
}
void print_table_data(MainWindow *wdata) {
printf(
"table data:\n-----------------\n\n");
UiList *list = wdata->data;
TableRow *elm = list->first(list);
while(elm) {
for(
int i=
0;i<elm->capacity;i++) {
printf(
"[%d]: %s\n", i, elm->columns[i]);
}
printf(
"\n");
elm = list->next(list);
}
printf(
"\n\n");
}