]> git.lizzy.rs Git - nothing.git/blobdiff - src/ui/edit_field.c
(#813) Implement player_layer_render
[nothing.git] / src / ui / edit_field.c
index 349f3376c608f77b912a8af1f1c6b85d3ac7a4f2..e9244d83cb976f83e15a285d580040935f318346 100644 (file)
@@ -1,11 +1,12 @@
-#include <assert.h>
 #include <stdbool.h>
 
 #include "edit_field.h"
+#include "game/camera.h"
 #include "game/sprite_font.h"
 #include "sdl/renderer.h"
-#include "system/error.h"
 #include "system/lt.h"
+#include "system/nth_alloc.h"
+#include "system/stacktrace.h"
 
 #define BUFFER_CAPACITY 256
 
@@ -15,10 +16,8 @@ struct Edit_field
     char *buffer;
     size_t buffer_size;
     size_t cursor;
-    const Sprite_font *font;
     Vec font_size;
     Color font_color;
-    bool shift_key;
 };
 
 static void edit_field_left(Edit_field *edit_field);
@@ -27,52 +26,26 @@ static void edit_field_backspace(Edit_field *edit_field);
 static void edit_field_delete(Edit_field *edit_field);
 static void edit_field_insert_char(Edit_field *edit_field, char c);
 
-static char shift_char(char c)
+Edit_field *create_edit_field(Vec font_size,
+                              Color font_color)
 {
-    if (c == '9') {
-        return '(';
-    } else if (c == '0') {
-        return ')';
-    } else if (c == '=') {
-        return '+';
-    } else if (c == '\'') {
-        return '"';
-    }else {
-        return c;
-    }
-}
-
-Edit_field *create_edit_field(const Sprite_font *font,
-                                Vec font_size,
-                                Color font_color)
-{
-    assert(font);
-
     Lt *lt = create_lt();
 
-    if (lt == NULL) {
-        return NULL;
-    }
-
-    Edit_field *const edit_field = PUSH_LT(lt, malloc(sizeof(Edit_field)), free);
+    Edit_field *const edit_field = PUSH_LT(lt, nth_calloc(1, sizeof(Edit_field)), free);
     if (edit_field == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
     edit_field->lt = lt;
 
-    edit_field->buffer = PUSH_LT(lt, malloc(sizeof(char) * (BUFFER_CAPACITY + 10)), free);
+    edit_field->buffer = PUSH_LT(lt, nth_calloc(1, sizeof(char) * (BUFFER_CAPACITY + 10)), free);
     if (edit_field->buffer == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
 
     edit_field->buffer_size = 0;
     edit_field->cursor = 0;
-    edit_field->font = font;
     edit_field->font_size = font_size;
     edit_field->font_color = font_color;
-    edit_field->shift_key = false;
 
     edit_field->buffer[edit_field->buffer_size] = 0;
 
@@ -81,34 +54,34 @@ Edit_field *create_edit_field(const Sprite_font *font,
 
 void destroy_edit_field(Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
     RETURN_LT0(edit_field->lt);
 }
 
 int edit_field_render(const Edit_field *edit_field,
-                      SDL_Renderer *renderer,
-                      Point position)
+                      Camera *camera,
+                      Point screen_position)
 {
-    assert(edit_field);
-    assert(renderer);
+    trace_assert(edit_field);
+    trace_assert(camera);
 
     const float cursor_y_overflow = 10.0f;
     const float cursor_width = 2.0f;
 
-    if (sprite_font_render_text(edit_field->font,
-                                renderer,
-                                position,
-                                edit_field->font_size,
-                                edit_field->font_color,
-                                edit_field->buffer) < 0) {
+    if (camera_render_text_screen(
+            camera,
+            edit_field->buffer,
+            edit_field->font_size,
+            edit_field->font_color,
+            screen_position) < 0) {
         return -1;
     }
 
     /* TODO(#363): the size of the cursor does not correspond to font size */
-    if (fill_rect(
-            renderer,
-            rect(position.x + (float) edit_field->cursor * (float) FONT_CHAR_WIDTH * edit_field->font_size.x,
-                 position.y - cursor_y_overflow,
+    if (camera_fill_rect_screen(
+            camera,
+            rect(screen_position.x + (float) edit_field->cursor * (float) FONT_CHAR_WIDTH * edit_field->font_size.x,
+                 screen_position.y - cursor_y_overflow,
                  cursor_width,
                  FONT_CHAR_HEIGHT * edit_field->font_size.y + cursor_y_overflow * 2.0f),
             edit_field->font_color) < 0) {
@@ -118,62 +91,9 @@ int edit_field_render(const Edit_field *edit_field,
     return 0;
 }
 
-int edit_field_handle_event(Edit_field *edit_field,
-                            const SDL_Event *event)
-{
-    assert(edit_field);
-    assert(event);
-
-    switch (event->type) {
-    case SDL_KEYDOWN:
-        switch (event->key.keysym.sym) {
-        case SDLK_LEFT:
-            edit_field_left(edit_field);
-            break;
-
-        case SDLK_RIGHT:
-            edit_field_right(edit_field);
-            break;
-
-        case SDLK_BACKSPACE:
-            edit_field_backspace(edit_field);
-            break;
-
-        case SDLK_RSHIFT:
-        case SDLK_LSHIFT:
-            edit_field->shift_key = true;
-            break;
-
-        case SDLK_DELETE:
-            edit_field_delete(edit_field);
-            break;
-
-        default: {
-            edit_field_insert_char(edit_field, (char) event->key.keysym.sym);
-        }
-        }
-        break;
-
-    case SDL_KEYUP:
-        switch (event->key.keysym.sym) {
-        case SDLK_RSHIFT:
-        case SDLK_LSHIFT:
-            edit_field->shift_key = false;
-            break;
-
-        default: {}
-        }
-        break;
-
-    default: {}
-    }
-
-    return 0;
-}
-
 const char *edit_field_as_text(const Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
     return edit_field->buffer;
 }
 
@@ -186,7 +106,7 @@ static void edit_field_left(Edit_field *edit_field)
 
 static void edit_field_right(Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
     if (edit_field->cursor < edit_field->buffer_size) {
         edit_field->cursor++;
     }
@@ -194,7 +114,7 @@ static void edit_field_right(Edit_field *edit_field)
 
 static void edit_field_backspace(Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
 
     if (edit_field->cursor == 0) {
         return;
@@ -210,7 +130,7 @@ static void edit_field_backspace(Edit_field *edit_field)
 
 static void edit_field_delete(Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
 
     if (edit_field->cursor >= edit_field->buffer_size) {
         return;
@@ -225,11 +145,7 @@ static void edit_field_delete(Edit_field *edit_field)
 
 static void edit_field_insert_char(Edit_field *edit_field, char c)
 {
-    assert(edit_field);
-
-    if (edit_field->shift_key) {
-        c = shift_char(c);
-    }
+    trace_assert(edit_field);
 
     if (edit_field->buffer_size >= BUFFER_CAPACITY) {
         return;
@@ -245,7 +161,7 @@ static void edit_field_insert_char(Edit_field *edit_field, char c)
 
 void edit_field_clean(Edit_field *edit_field)
 {
-    assert(edit_field);
+    trace_assert(edit_field);
 
     edit_field->cursor = 0;
     edit_field->buffer_size = 0;
@@ -254,7 +170,61 @@ void edit_field_clean(Edit_field *edit_field)
 
 void edit_field_replace(Edit_field *edit_field, const char *text)
 {
-    assert(edit_field);
-    assert(text);
-    /* TODO(#388): edit_field_replace is not implemented */
+    trace_assert(edit_field);
+
+    edit_field_clean(edit_field);
+
+    if (text == NULL) {
+        return;
+    }
+
+    size_t n = strlen(text);
+    for (size_t i = 0; i < n; ++i) {
+        edit_field_insert_char(edit_field, text[i]);
+    }
+}
+
+int edit_field_keyboard(Edit_field *edit_field,
+                        const SDL_KeyboardEvent *key)
+{
+    trace_assert(edit_field);
+    trace_assert(key);
+
+    if (key->type == SDL_KEYDOWN) {
+        switch (key->keysym.sym) {
+        case SDLK_LEFT:
+            edit_field_left(edit_field);
+            break;
+
+        case SDLK_RIGHT:
+            edit_field_right(edit_field);
+            break;
+
+        case SDLK_BACKSPACE:
+            edit_field_backspace(edit_field);
+            break;
+
+        case SDLK_DELETE:
+            edit_field_delete(edit_field);
+            break;
+
+        default: {}
+        }
+    }
+
+    return 0;
+}
+
+int edit_field_text_input(Edit_field *edit_field,
+                          const SDL_TextInputEvent *text_input)
+{
+    trace_assert(edit_field);
+    trace_assert(text_input);
+
+    size_t n = strlen(text_input->text);
+    for (size_t i = 0; i < n; ++i) {
+        edit_field_insert_char(edit_field, text_input->text[i]);
+    }
+
+    return 0;
 }