diff --git a/include/ui_list.h b/include/ui_list.h new file mode 100644 index 0000000..f96f972 --- /dev/null +++ b/include/ui_list.h @@ -0,0 +1,28 @@ +#ifndef UI_LIST_H +#define UI_LIST_H + +#include "SDL_pixels.h" +#include "SDL_render.h" +#include "aliases/aliases.h" + +typedef struct { + union { + u32 colour; + SDL_Color rgba; + }; +} colour_t; + +typedef struct { + u64 item_w; + u64 item_h; + u64 selected; + u64 length; + SDL_Texture **textures; + SDL_Texture **selected_textures; +} ui_list_t; + +u64 ui_list(const ui_list_t *list, u64 x, u64 y, u64 padding, i64 mouse_x, + i64 mouse_y, i64 clicked_x, i64 clicked_y, SDL_Renderer *renderer, + colour_t bg_colour, colour_t hover_colour); + +#endif // !UI_LIST_H diff --git a/src/ui_list.c b/src/ui_list.c new file mode 100644 index 0000000..39f6573 --- /dev/null +++ b/src/ui_list.c @@ -0,0 +1,78 @@ +#include "ui_list.h" +#include "SDL_rect.h" +#include "SDL_render.h" +#include "aliases/aliases.h" +#include +#include + +bool aabb(SDL_Rect *rect, i64 x, i64 y) { + return x >= rect->x && y >= rect->y && x < rect->x + rect->w && + y < rect->y + rect->h; +} + +bool draw_element(SDL_Texture *texture, SDL_Texture *selected_texture, + bool selected, u64 x, u64 y, u64 item_w, u64 item_h, + u64 padding, i64 mouse_x, i64 mouse_y, i64 clicked_x, + i64 clicked_y, SDL_Renderer *renderer, colour_t bg_colour, + colour_t hover_colour) { + bool output = false; + + SDL_Rect bg_dest = {.x = x - padding, + .y = y - padding, + .w = item_w + padding * 2, + .h = item_h + padding * 2 + 1}; + + SDL_Rect texture_dest = {.x = x, .y = y, .w = 0, .h = 0}; + + colour_t c = bg_colour; + bool hovered = false; + + if (aabb(&bg_dest, mouse_x, mouse_y)) { + hovered = true; + c = hover_colour; + } + + if (aabb(&bg_dest, clicked_x, clicked_y)) { + output = true; + } + + SDL_SetRenderDrawColor(renderer, c.rgba.r, c.rgba.g, c.rgba.b, c.rgba.a); + + SDL_Texture *render_texture = + (selected || hovered) ? selected_texture : texture; + + i32 texture_w; + i32 texture_h; + + SDL_QueryTexture(render_texture, NULL, NULL, &texture_w, &texture_h); + + i32 x_offset = (item_w - texture_w) / 2; + texture_dest.x += x_offset; + texture_dest.w = texture_w; + texture_dest.h = texture_h; + + (selected || hovered) ? SDL_RenderFillRect(renderer, &bg_dest) + : SDL_RenderDrawRect(renderer, &bg_dest); + + SDL_RenderCopy(renderer, render_texture, NULL, &texture_dest); + + return output; +} + +u64 ui_list(const ui_list_t *list, u64 x, u64 y, u64 padding, i64 mouse_x, + i64 mouse_y, i64 clicked_x, i64 clicked_y, SDL_Renderer *renderer, + colour_t bg_colour, colour_t hover_colour) { + u64 selected = list->selected; + + for (u64 i = 0; i < list->length; ++i) { + if (draw_element(list->textures[i], list->selected_textures[i], + i == list->selected, x, + y + (list->item_h + padding * 2) * i, list->item_w, + list->item_h, padding, mouse_x, mouse_y, clicked_x, + clicked_y, renderer, bg_colour, hover_colour)) { + selected = i; + } + } + + return selected; +}