~ruther/CTU-FEE-B0B35APO-Semestral-project

d81506c0ceee3304bc6dd61417f363f7fe5f4e0d — František Boháček 3 years ago 923fb6c
feat: add list container logic
2 files changed, 118 insertions(+), 3 deletions(-)

M lib-gui/include/gui.h
A lib-gui/src/gui_list_container.c
M lib-gui/include/gui.h => lib-gui/include/gui.h +27 -3
@@ 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__

A lib-gui/src/gui_list_container.c => lib-gui/src/gui_list_container.c +91 -0
@@ 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 :)
}

Do not follow this link