table.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * src/table.c
  3. * https://gitlab.com/bztsrc/smgui
  4. *
  5. * Copyright (C) 2024 bzt (bztsrc@gitlab), MIT license
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to
  9. * deal in the Software without restriction, including without limitation the
  10. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  11. * sell copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
  20. * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
  22. * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * @brief State-Mode GUI demo program
  25. */
  26. #include <ui_table.h>
  27. #define UI_IMPLEMENTATION
  28. #include <ui.h>
  29. /* struct that we store in an array and want to display as a table */
  30. typedef struct {
  31. int selected;
  32. char depart[16];
  33. char *name;
  34. int salary;
  35. } row_t;
  36. /* comparators for sorting */
  37. static int depasc(const void *a, const void *b) { return strcmp(((row_t*)a)->depart, ((row_t*)b)->depart); }
  38. static int depdsc(const void *a, const void *b) { return strcmp(((row_t*)b)->depart, ((row_t*)a)->depart); }
  39. static int nameasc(const void *a, const void *b) { return strcmp(((row_t*)a)->name, ((row_t*)b)->name); }
  40. static int namedsc(const void *a, const void *b) { return strcmp(((row_t*)b)->name, ((row_t*)a)->name); }
  41. static int salasc(const void *a, const void *b) { return ((row_t*)a)->salary - ((row_t*)b)->salary; }
  42. static int saldsc(const void *a, const void *b) { return ((row_t*)b)->salary - ((row_t*)a)->salary; }
  43. ui_comp rowsort[] = { NULL, NULL, &depasc, &depdsc, &nameasc, &namedsc, &salasc, &saldsc };
  44. int main(int argc, char **argv)
  45. {
  46. /* strings are gathered into an array so that you can change the language on-the-fly */
  47. enum { WINDOW_TITLE, DEPART, NAME, SALARY };
  48. char *lang[] = { "Table demo", "Department", "Name", "Salary" };
  49. /* variables to store data */
  50. row_t rows[] = {
  51. { 0, "Design", "Jane Doe", 123 },
  52. { 0, "Dev", "Joe Doe", 234 },
  53. { 0, "Dev", "John Doe", 345 },
  54. { 0, "Marketing", "Jill Doe", 456 }
  55. };
  56. ui_image_t icons[256];
  57. /* form referencing those variables, you use a HTML flow like layout */
  58. ui_t ctx;
  59. ui_form_t table1[] = {
  60. { .type = UI_CHECK, .w = 24, .tblofs = offsetof(row_t, selected), .value = 1 },
  61. { .type = UI_LABEL, .w = UI_PERCENT(25), .tblhdr = DEPART, .tblofs = offsetof(row_t, depart) },
  62. { .type = UI_LABEL, .w = UI_PERCENT(50), .tblhdr = NAME, .tblofs = offsetof(row_t, name), .flags = UI_POINTER },
  63. { .type = UI_DEC32, .w = UI_PERPLUS(25, -24), .tblhdr = SALARY, .tblofs = offsetof(row_t, salary) },
  64. { .type = UI_END }
  65. };
  66. ui_form_t table2[] = {
  67. { .type = UI_IMAGE },
  68. { .type = UI_END }
  69. };
  70. ui_form_t form[] = {
  71. /* first table, each row displays multiple different columns, one for every struct field */
  72. { .type = UI_TABLE, .flags = UI_SCROLL, .x = 5, .y = 5, .w = UI_PERPLUS(100,-10), .h = UI_PERPLUS(50,-10), .m = 2,
  73. .ptr = &rows, .tblnum = sizeof(rows)/sizeof(rows[0]), .tblsiz = sizeof(rows[0]), .tblrow = 24,
  74. .data = &table1, .cmps = rowsort },
  75. /* second table, all columns in all rows displays the same kind, it's a grid */
  76. { .type = UI_TABLE, .flags = UI_SCROLL | UI_NOHEADER, .x = UI_ABS(5), .y = UI_PERCENT(50), .w = UI_PERPLUS(100,-10),
  77. .h = UI_PERPLUS(50,-5), .m = 8, .tblrow = 24, .tblcol = 24,
  78. .ptr = &icons, .tblnum = sizeof(icons)/sizeof(icons[0]), .tblsiz = sizeof(ui_image_t), .data = &table2 },
  79. { .type = UI_END }
  80. };
  81. /* a hacked image. These should actually be RGBA pixels, but -1U is 0xffffffff, which is full opaque white */
  82. uint32_t imgbuf[] = {
  83. 0, 0,-1,-1,-1, 0, 0, 0,
  84. 0,-1,-1,-1,-1,-1, 0, 0,
  85. -1,-1, 0,-1, 0,-1,-1, 0,
  86. -1,-1,-1,-1,-1,-1,-1, 0,
  87. -1, 0,-1,-1,-1, 0,-1, 0,
  88. 0,-1, 0, 0, 0,-1, 0, 0,
  89. 0, 0,-1,-1,-1, 0, 0, 0,
  90. 0, 0, 0, 0, 0, 0, 0, 0,
  91. };
  92. int i, tbl1 = 0, tbl2 = 0;
  93. memset(icons, 0, sizeof(icons));
  94. for(i = 0; i < (int)(sizeof(icons)/sizeof(icons[0])); i++) {
  95. icons[i].w = icons[i].h = 8;
  96. icons[i].p = 8 * 4;
  97. icons[i].buf = (uint8_t*)&imgbuf;
  98. }
  99. /* initialize the UI context, pass it the string array, the window size and icon */
  100. ui_init(&ctx, sizeof(lang)/sizeof(lang[0]), lang, 640, 480, NULL);
  101. /* wait until user closes the window */
  102. while(ui_event(&ctx, form)) {
  103. if(tbl1 != form[0].tblsel) {
  104. tbl1 = form[0].tblsel;
  105. printf("table1 selected row %d '%s'\n", tbl1, rows[tbl1].name);
  106. }
  107. if(tbl2 != form[1].tblsel) {
  108. tbl2 = form[1].tblsel;
  109. printf("table2 selected icon %d\n", tbl2);
  110. }
  111. }
  112. /* destroy window, free resources */
  113. ui_free(&ctx);
  114. (void)argc; (void)argv;
  115. return 0;
  116. }