123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /*
- * src/table.c
- * https://gitlab.com/bztsrc/smgui
- *
- * Copyright (C) 2024 bzt (bztsrc@gitlab), MIT license
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
- * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * @brief State-Mode GUI demo program
- */
- #include <ui_table.h>
- #define UI_IMPLEMENTATION
- #include <ui.h>
- /* struct that we store in an array and want to display as a table */
- typedef struct {
- int selected;
- char depart[16];
- char *name;
- int salary;
- } row_t;
- /* comparators for sorting */
- static int depasc(const void *a, const void *b) { return strcmp(((row_t*)a)->depart, ((row_t*)b)->depart); }
- static int depdsc(const void *a, const void *b) { return strcmp(((row_t*)b)->depart, ((row_t*)a)->depart); }
- static int nameasc(const void *a, const void *b) { return strcmp(((row_t*)a)->name, ((row_t*)b)->name); }
- static int namedsc(const void *a, const void *b) { return strcmp(((row_t*)b)->name, ((row_t*)a)->name); }
- static int salasc(const void *a, const void *b) { return ((row_t*)a)->salary - ((row_t*)b)->salary; }
- static int saldsc(const void *a, const void *b) { return ((row_t*)b)->salary - ((row_t*)a)->salary; }
- ui_comp rowsort[] = { NULL, NULL, &depasc, &depdsc, &nameasc, &namedsc, &salasc, &saldsc };
- int main(int argc, char **argv)
- {
- /* strings are gathered into an array so that you can change the language on-the-fly */
- enum { WINDOW_TITLE, DEPART, NAME, SALARY };
- char *lang[] = { "Table demo", "Department", "Name", "Salary" };
- /* variables to store data */
- row_t rows[] = {
- { 0, "Design", "Jane Doe", 123 },
- { 0, "Dev", "Joe Doe", 234 },
- { 0, "Dev", "John Doe", 345 },
- { 0, "Marketing", "Jill Doe", 456 }
- };
- ui_image_t icons[256];
- /* form referencing those variables, you use a HTML flow like layout */
- ui_t ctx;
- ui_form_t table1[] = {
- { .type = UI_CHECK, .w = 24, .tblofs = offsetof(row_t, selected), .value = 1 },
- { .type = UI_LABEL, .w = UI_PERCENT(25), .tblhdr = DEPART, .tblofs = offsetof(row_t, depart) },
- { .type = UI_LABEL, .w = UI_PERCENT(50), .tblhdr = NAME, .tblofs = offsetof(row_t, name), .flags = UI_POINTER },
- { .type = UI_DEC32, .w = UI_PERPLUS(25, -24), .tblhdr = SALARY, .tblofs = offsetof(row_t, salary) },
- { .type = UI_END }
- };
- ui_form_t table2[] = {
- { .type = UI_IMAGE },
- { .type = UI_END }
- };
- ui_form_t form[] = {
- /* first table, each row displays multiple different columns, one for every struct field */
- { .type = UI_TABLE, .flags = UI_SCROLL, .x = 5, .y = 5, .w = UI_PERPLUS(100,-10), .h = UI_PERPLUS(50,-10), .m = 2,
- .ptr = &rows, .tblnum = sizeof(rows)/sizeof(rows[0]), .tblsiz = sizeof(rows[0]), .tblrow = 24,
- .data = &table1, .cmps = rowsort },
- /* second table, all columns in all rows displays the same kind, it's a grid */
- { .type = UI_TABLE, .flags = UI_SCROLL | UI_NOHEADER, .x = UI_ABS(5), .y = UI_PERCENT(50), .w = UI_PERPLUS(100,-10),
- .h = UI_PERPLUS(50,-5), .m = 8, .tblrow = 24, .tblcol = 24,
- .ptr = &icons, .tblnum = sizeof(icons)/sizeof(icons[0]), .tblsiz = sizeof(ui_image_t), .data = &table2 },
- { .type = UI_END }
- };
- /* a hacked image. These should actually be RGBA pixels, but -1U is 0xffffffff, which is full opaque white */
- uint32_t imgbuf[] = {
- 0, 0,-1,-1,-1, 0, 0, 0,
- 0,-1,-1,-1,-1,-1, 0, 0,
- -1,-1, 0,-1, 0,-1,-1, 0,
- -1,-1,-1,-1,-1,-1,-1, 0,
- -1, 0,-1,-1,-1, 0,-1, 0,
- 0,-1, 0, 0, 0,-1, 0, 0,
- 0, 0,-1,-1,-1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- };
- int i, tbl1 = 0, tbl2 = 0;
- memset(icons, 0, sizeof(icons));
- for(i = 0; i < (int)(sizeof(icons)/sizeof(icons[0])); i++) {
- icons[i].w = icons[i].h = 8;
- icons[i].p = 8 * 4;
- icons[i].buf = (uint8_t*)&imgbuf;
- }
- /* initialize the UI context, pass it the string array, the window size and icon */
- ui_init(&ctx, sizeof(lang)/sizeof(lang[0]), lang, 640, 480, NULL);
- /* wait until user closes the window */
- while(ui_event(&ctx, form)) {
- if(tbl1 != form[0].tblsel) {
- tbl1 = form[0].tblsel;
- printf("table1 selected row %d '%s'\n", tbl1, rows[tbl1].name);
- }
- if(tbl2 != form[1].tblsel) {
- tbl2 = form[1].tblsel;
- printf("table2 selected icon %d\n", tbl2);
- }
- }
- /* destroy window, free resources */
- ui_free(&ctx);
- (void)argc; (void)argv;
- return 0;
- }
|