4 #include "edit_field.h"
5 #include "game/sprite_font.h"
6 #include "sdl/renderer.h"
8 #include "system/nth_alloc.h"
10 #define BUFFER_CAPACITY 256
18 const Sprite_font *font;
23 static void edit_field_left(Edit_field *edit_field);
24 static void edit_field_right(Edit_field *edit_field);
25 static void edit_field_backspace(Edit_field *edit_field);
26 static void edit_field_delete(Edit_field *edit_field);
27 static void edit_field_insert_char(Edit_field *edit_field, char c);
29 Edit_field *create_edit_field(const Sprite_font *font,
41 Edit_field *const edit_field = PUSH_LT(lt, nth_alloc(sizeof(Edit_field)), free);
42 if (edit_field == NULL) {
47 edit_field->buffer = PUSH_LT(lt, nth_alloc(sizeof(char) * (BUFFER_CAPACITY + 10)), free);
48 if (edit_field->buffer == NULL) {
52 edit_field->buffer_size = 0;
53 edit_field->cursor = 0;
54 edit_field->font = font;
55 edit_field->font_size = font_size;
56 edit_field->font_color = font_color;
58 edit_field->buffer[edit_field->buffer_size] = 0;
63 void destroy_edit_field(Edit_field *edit_field)
66 RETURN_LT0(edit_field->lt);
69 int edit_field_render(const Edit_field *edit_field,
70 SDL_Renderer *renderer,
76 const float cursor_y_overflow = 10.0f;
77 const float cursor_width = 2.0f;
79 if (sprite_font_render_text(edit_field->font,
82 edit_field->font_size,
83 edit_field->font_color,
84 edit_field->buffer) < 0) {
88 /* TODO(#363): the size of the cursor does not correspond to font size */
91 rect(position.x + (float) edit_field->cursor * (float) FONT_CHAR_WIDTH * edit_field->font_size.x,
92 position.y - cursor_y_overflow,
94 FONT_CHAR_HEIGHT * edit_field->font_size.y + cursor_y_overflow * 2.0f),
95 edit_field->font_color) < 0) {
102 int edit_field_handle_event(Edit_field *edit_field,
103 const SDL_Event *event)
108 switch (event->type) {
110 switch (event->key.keysym.sym) {
112 edit_field_left(edit_field);
116 edit_field_right(edit_field);
120 edit_field_backspace(edit_field);
124 edit_field_delete(edit_field);
131 case SDL_TEXTINPUT: {
132 size_t n = strlen(event->text.text);
133 for (size_t i = 0; i < n; ++i) {
134 edit_field_insert_char(edit_field, event->text.text[i]);
144 const char *edit_field_as_text(const Edit_field *edit_field)
147 return edit_field->buffer;
150 static void edit_field_left(Edit_field *edit_field)
152 if (edit_field->cursor > 0) {
153 edit_field->cursor--;
157 static void edit_field_right(Edit_field *edit_field)
160 if (edit_field->cursor < edit_field->buffer_size) {
161 edit_field->cursor++;
165 static void edit_field_backspace(Edit_field *edit_field)
169 if (edit_field->cursor == 0) {
173 for (size_t i = edit_field->cursor; i < edit_field->buffer_size; ++i) {
174 edit_field->buffer[i - 1] = edit_field->buffer[i];
177 edit_field->cursor--;
178 edit_field->buffer[--edit_field->buffer_size] = 0;
181 static void edit_field_delete(Edit_field *edit_field)
185 if (edit_field->cursor >= edit_field->buffer_size) {
189 for (size_t i = edit_field->cursor; i < edit_field->buffer_size; ++i) {
190 edit_field->buffer[i] = edit_field->buffer[i + 1];
193 edit_field->buffer[--edit_field->buffer_size] = 0;
196 static void edit_field_insert_char(Edit_field *edit_field, char c)
200 if (edit_field->buffer_size >= BUFFER_CAPACITY) {
204 for (int64_t i = (int64_t) edit_field->buffer_size - 1; i >= (int64_t) edit_field->cursor; --i) {
205 edit_field->buffer[i + 1] = edit_field->buffer[i];
208 edit_field->buffer[edit_field->cursor++] = c;
209 edit_field->buffer[++edit_field->buffer_size] = 0;
212 void edit_field_clean(Edit_field *edit_field)
216 edit_field->cursor = 0;
217 edit_field->buffer_size = 0;
218 edit_field->buffer[0] = 0;
221 void edit_field_replace(Edit_field *edit_field, const char *text)
225 edit_field_clean(edit_field);
231 size_t n = strlen(text);
232 for (size_t i = 0; i < n; ++i) {
233 edit_field_insert_char(edit_field, text[i]);