From d81506c0ceee3304bc6dd61417f363f7fe5f4e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Thu, 24 Jun 2021 07:41:48 +0200 Subject: [PATCH] feat: add list container logic --- lib-gui/include/gui.h | 30 +++++++++-- lib-gui/src/gui_list_container.c | 91 ++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 lib-gui/src/gui_list_container.c diff --git a/lib-gui/include/gui.h b/lib-gui/include/gui.h index 6b8a506e930eb7ca5a0f1f8a097590f328bb3c17..8de699b51ffd9a3ea17b90ce1445354f9d0c1289 100644 --- a/lib-gui/include/gui.h +++ b/lib-gui/include/gui.h @@ -39,9 +39,17 @@ typedef enum { CONT_ONE, } container_type_t; +typedef bool (*render_item)(void *state, uint32_t index, renderer_t *renderer, int16_t beg_x, int16_t beg_y); + typedef struct { - // items - // scroll + void *state; + render_item render_item_fn; + render_item render_header_fn; + uint32_t items_count; + uint16_t item_height; + + int16_t scroll_x; + int16_t scroll_y; } list_container_t; typedef struct { @@ -301,6 +309,22 @@ component_t *gui_group_container_add_component(container_t *container, void gui_group_container_render(gui_t *gui, container_t *container); void gui_group_container_update(gui_t *gui, container_t *container); -// handle commands +// list_container.c +container_t gui_list_container_create(void *state, uint32_t items_count, + uint16_t item_height, + render_item render_it, + render_item render_header); + +void gui_list_scroll(container_t *container, int16_t x, int16_t y); +bool gui_list_container_set_state(container_t *container, void *state, + uint32_t items_count); +bool gui_list_container_set_item_height(container_t *container, + uint16_t item_height); +bool gui_list_container_set_render_function(container_t *container, + render_item render_it, + render_item render_header); + +void gui_list_container_render(gui_t *gui, container_t *container); +void gui_list_container_update(gui_t *gui, container_t *container); #endif // __GUI_H__ diff --git a/lib-gui/src/gui_list_container.c b/lib-gui/src/gui_list_container.c new file mode 100644 index 0000000000000000000000000000000000000000..48bcde658a44dfd3b89af07dcaca5151426bd2d3 --- /dev/null +++ b/lib-gui/src/gui_list_container.c @@ -0,0 +1,91 @@ +#include "gui.h" +#include "renderer.h" + +container_t gui_list_container_create(void *state, uint32_t items_count, + uint16_t item_height, + render_item render_it, + render_item render_header) { + list_container_t list = { + .item_height = item_height, + .items_count = items_count, + .state = state, + .scroll_x = 0, + .scroll_y = 0, + .render_header_fn = render_header, + .render_item_fn = render_it, + }; + + container_t container = { + .focusable = true, + .focused = false, + .height = item_height * items_count, + .width = 0, + .inner.list = list, + .x = 0, + .y = 0 + }; + + return container; +} + +void gui_list_scroll(container_t *container, int16_t x, int16_t y) { + container->inner.list.scroll_x += x; + container->inner.list.scroll_y += y; +} + +bool gui_list_container_set_state(container_t *container, void *state, + uint32_t items_count) { + container->inner.list.state = state; + container->inner.list.items_count = items_count; + return true; +} + +bool gui_list_container_set_item_height(container_t *container, + uint16_t item_height) { + container->inner.list.item_height = item_height; + return true; +} + +bool gui_list_container_set_render_function(container_t *container, render_item render_it, + render_item render_header) { + container->inner.list.render_item_fn = render_it; + container->inner.list.render_header_fn = render_header; + return true; +} + +void gui_list_container_render(gui_t *gui, container_t *container) { + renderer_translate(gui->renderer, container->x, container->y); + renderer_set_draw_area(gui->renderer, gui->size.x, gui->size.y); + + list_container_t list = container->inner.list; + if (list.scroll_x < 0) { + list.scroll_x = 0; + } + + if (list.scroll_y < 0) { + list.scroll_y = 0; + } + container->inner.list = list; + + uint16_t item_height = list.item_height; + + int32_t first_index = list.scroll_y / item_height; + if (first_index < 0) { + first_index = 0; + } + uint32_t items_count = gui->size.y / item_height; + uint32_t end_index = first_index + items_count; + + int32_t beg_x = -list.scroll_x; + int32_t beg_y = -list.scroll_y + first_index * item_height; + + for (int i = first_index; i < end_index; i++) { + int32_t y = beg_y + i * item_height; + + list.render_item_fn(list.state, i, gui->renderer, beg_x, y); + } +} + +void gui_list_container_update(gui_t *gui, container_t *container) { + // do nothing :) +}