5 #include "system/stacktrace.h"
7 #include "system/nth_alloc.h"
8 #include "system/str.h"
9 #include "math/point.h"
10 #include "game/sprite_font.h"
12 #include "./list_selector.h"
17 const Sprite_font *sprite_font;
21 const char *selected_item;
24 ListSelector *create_list_selector(const Sprite_font *sprite_font,
35 ListSelector *list_selector = PUSH_LT(lt, nth_alloc(sizeof(ListSelector)), free);
36 if (list_selector == NULL) {
39 list_selector->lt = lt;
41 list_selector->sprite_font = sprite_font;
43 list_selector->items = PUSH_LT(lt, nth_calloc(count, sizeof(const char*)), free);
44 if (list_selector->items == NULL) {
48 for (size_t i = 0; i < count; ++i) {
49 list_selector->items[i] = PUSH_LT(lt, string_duplicate(items[i], NULL), free);
50 if (list_selector->items[i] == NULL) {
55 list_selector->count = count;
56 list_selector->cursor = 0;
57 list_selector->selected_item = NULL;
62 void destroy_list_selector(ListSelector *list_selector)
64 trace_assert(list_selector);
65 RETURN_LT0(list_selector->lt);
68 int list_selector_render(const ListSelector *list_selector,
69 SDL_Renderer *renderer,
74 trace_assert(list_selector);
75 trace_assert(renderer);
77 for (size_t i = 0; i < list_selector->count; ++i) {
78 const Vec current_position = vec_sum(
80 vec(0.0f, (float) i * ((float) FONT_CHAR_HEIGHT * font_scale.y + padding_bottom)));
82 if (sprite_font_render_text(
83 list_selector->sprite_font,
87 rgba(1.0f, 1.0f, 1.0f, 1.0f),
88 list_selector->items[i]) < 0) {
92 if (i == list_selector->cursor) {
93 SDL_Rect boundary_box = rect_for_sdl(
94 sprite_font_boundary_box(
95 list_selector->sprite_font,
98 list_selector->items[i]));
99 if (SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) < 0) {
103 if (SDL_RenderDrawRect(renderer, &boundary_box) < 0) {
112 Vec list_selector_size(const ListSelector *list_selector,
114 float padding_bottom)
116 trace_assert(list_selector);
118 Vec result = vec(0.0f, 0.0f);
120 for (size_t i = 0; i < list_selector->count; ++i) {
121 Rect boundary_box = sprite_font_boundary_box(
122 list_selector->sprite_font,
125 list_selector->items[i]);
127 result.x = fmaxf(result.x, boundary_box.w);
128 result.y += boundary_box.y + padding_bottom;
134 int list_selector_update(ListSelector *list_selector, float delta_time)
136 trace_assert(list_selector);
142 int list_selector_event(ListSelector *list_selector, const SDL_Event *event)
144 trace_assert(list_selector);
147 switch (event->type) {
149 switch (event->key.keysym.sym) {
151 if (list_selector->cursor > 0) {
152 list_selector->cursor--;
156 if (list_selector->cursor < list_selector->count - 1) {
157 list_selector->cursor++;
161 list_selector->selected_item = list_selector->items[list_selector->cursor];
170 const char *list_selector_selected(const ListSelector *list_selector)
172 trace_assert(list_selector);
173 return list_selector->selected_item;