X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame%2Flevel%2Flevel_editor%2Fpoint_layer.c;h=ea8a37a6f97d60bc5726a174372f2ef2f83e6b7e;hb=eb0e88f193a7355943506243b3cc4fac074e240b;hp=76fd0d9d099fcf1352a0ddcb748ed93ad40ca560;hpb=ff4e6eac03370cf175d51aa78fe809f8a7a58f0d;p=nothing.git diff --git a/src/game/level/level_editor/point_layer.c b/src/game/level/level_editor/point_layer.c index 76fd0d9d..ea8a37a6 100644 --- a/src/game/level/level_editor/point_layer.c +++ b/src/game/level/level_editor/point_layer.c @@ -1,4 +1,6 @@ -#include +#include + +#include #include "dynarray.h" #include "game/camera.h" @@ -11,12 +13,13 @@ #include "ui/edit_field.h" #include "./point_layer.h" #include "math/extrema.h" +#include "./color_picker.h" #define POINT_LAYER_ELEMENT_RADIUS 10.0f typedef enum { - POINT_LAYER_NORMAL_STATE = 0, - POINT_LAYER_ID_EDITING_STATE + POINT_LAYER_IDLE = 0, + POINT_LAYER_EDIT_ID } PointLayerState; struct PointLayer @@ -28,14 +31,20 @@ struct PointLayer Dynarray/**/ *ids; Edit_field *edit_field; int selected; + ColorPicker color_picker; }; -// TODO(#837): PointLayer does not allow to edit itself - -PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) +LayerPtr point_layer_as_layer(PointLayer *point_layer) { - trace_assert(line_stream); + LayerPtr layer = { + .type = LAYER_POINT, + .ptr = point_layer + }; + return layer; +} +PointLayer *create_point_layer(void) +{ Lt *lt = create_lt(); PointLayer *point_layer = PUSH_LT(lt, nth_calloc(1, sizeof(PointLayer)), free); @@ -44,7 +53,7 @@ PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) } point_layer->lt = lt; - point_layer->state = POINT_LAYER_NORMAL_STATE; + point_layer->state = POINT_LAYER_IDLE; point_layer->points = PUSH_LT(lt, create_dynarray(sizeof(Point)), destroy_dynarray); if (point_layer->points == NULL) { @@ -61,13 +70,32 @@ PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) RETURN_LT(lt, NULL); } + point_layer->edit_field = PUSH_LT( + lt, + create_edit_field( + vec(5.0f, 5.0f), + rgba(0.0f, 0.0f, 0.0f, 1.0f)), + destroy_edit_field); + if (point_layer->edit_field == NULL) { + RETURN_LT(lt, NULL); + } + + return point_layer; +} + +PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) +{ + trace_assert(line_stream); + + PointLayer *point_layer = create_point_layer(); + size_t count = 0; if (sscanf( line_stream_next(line_stream), - "%lu", + "%zu", &count) == EOF) { log_fail("Could not read amount of points"); - RETURN_LT(lt, NULL); + RETURN_LT(point_layer->lt, NULL); } char color_name[7]; @@ -79,7 +107,7 @@ PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) "%"STRINGIFY(ID_MAX_SIZE)"s%f%f%6s", id, &x, &y, color_name) < 0) { log_fail("Could not read %dth goal\n", i); - RETURN_LT(lt, NULL); + RETURN_LT(point_layer->lt, NULL); } const Color color = hexstr(color_name); const Point point = vec(x, y); @@ -89,18 +117,10 @@ PointLayer *create_point_layer_from_line_stream(LineStream *line_stream) dynarray_push(point_layer->ids, id); } - point_layer->edit_field = PUSH_LT( - point_layer->lt, - create_edit_field( - vec(5.0f, 5.0f), - rgba(0.0f, 0.0f, 0.0f, 1.0f)), - destroy_edit_field); - if (point_layer->edit_field == NULL) { - RETURN_LT(point_layer->lt, NULL); - } - point_layer->selected = -1; + point_layer->color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f)); + return point_layer; } @@ -111,7 +131,8 @@ void destroy_point_layer(PointLayer *point_layer) } int point_layer_render(const PointLayer *point_layer, - Camera *camera) + Camera *camera, + int active) { trace_assert(point_layer); trace_assert(camera); @@ -127,6 +148,10 @@ int point_layer_render(const PointLayer *point_layer, trans_mat(points[i].x, points[i].y), scale_mat(POINT_LAYER_ELEMENT_RADIUS))); + const Color color = color_scale( + colors[i], + rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f)); + if (i == point_layer->selected) { const Triangle t0 = triangle_mat3x3_product( equilateral_triangle(), @@ -134,21 +159,21 @@ int point_layer_render(const PointLayer *point_layer, trans_mat(points[i].x, points[i].y), scale_mat(15.0f))); - if (camera_fill_triangle(camera, t0, color_invert(colors[i])) < 0) { + if (camera_fill_triangle(camera, t0, color_invert(color)) < 0) { return -1; } } - if (camera_fill_triangle(camera, t, colors[i]) < 0) { + if (camera_fill_triangle(camera, t, color) < 0) { return -1; } /* TODO(#854): The ids of PointLayer are not displayed constantly */ } - if (point_layer->state == POINT_LAYER_ID_EDITING_STATE) { + if (point_layer->state == POINT_LAYER_EDIT_ID) { /* TODO(#855): PointLayer edit field is not scaled on zoom */ - if (edit_field_render( + if (edit_field_render_screen( point_layer->edit_field, camera, camera_point(camera, points[point_layer->selected])) < 0) { @@ -156,123 +181,142 @@ int point_layer_render(const PointLayer *point_layer, } } + if (active && color_picker_render(&point_layer->color_picker, camera) < 0) { + return -1; + } + + return 0; } -// TODO(#841): PointLayer does not allow to remove elements - -int point_layer_mouse_button(PointLayer *point_layer, - const SDL_MouseButtonEvent *event, - const Camera *camera, - Color color) +static +int point_layer_idle_event(PointLayer *point_layer, + const SDL_Event *event, + const Camera *camera) { trace_assert(point_layer); trace_assert(event); + trace_assert(camera); - if (point_layer->state == POINT_LAYER_NORMAL_STATE && - event->type == SDL_MOUSEBUTTONDOWN && - event->button == SDL_BUTTON_LEFT) { - const int n = (int) dynarray_count(point_layer->points); - const Point *points = dynarray_data(point_layer->points); - const Point point = camera_map_screen(camera, event->x, event->y); - - for (int i = 0; i < n; ++i) { - if (vec_length(vec_sub(points[i], point)) < POINT_LAYER_ELEMENT_RADIUS) { - point_layer->selected = i; - return 0; - } - } - - char id[ID_MAX_SIZE]; - - // TODO(#842): PointLayer does not allow to specify an id of a point - for (size_t i = 0; i < ID_MAX_SIZE - 1; ++i) { - id[i] = (char) ('a' + rand() % ('z' - 'a' + 1)); - } - id[ID_MAX_SIZE - 1] = '\0'; - - dynarray_push(point_layer->points, &point); - dynarray_push(point_layer->colors, &color); - dynarray_push(point_layer->ids, id); + int selected = 0; + if (color_picker_event( + &point_layer->color_picker, + event, + &selected) < 0) { + return -1; } - return 0; -} + if (selected) { + return 0; + } -int point_layer_keyboard(PointLayer *point_layer, - const SDL_KeyboardEvent *key) -{ - trace_assert(point_layer); - trace_assert(key); - - switch(point_layer->state) { - case POINT_LAYER_NORMAL_STATE: { - if (key->type == SDL_KEYDOWN) { - switch (key->keysym.sym) { - case SDLK_DELETE: { - if (0 <= point_layer->selected && point_layer->selected < (int) dynarray_count(point_layer->points)) { - dynarray_delete_at(point_layer->points, (size_t) point_layer->selected); - dynarray_delete_at(point_layer->colors, (size_t) point_layer->selected); - dynarray_delete_at(point_layer->ids, (size_t) point_layer->selected); + switch (event->type) { + case SDL_MOUSEBUTTONDOWN: { + switch (event->button.button) { + case SDL_BUTTON_LEFT: { + const int n = (int) dynarray_count(point_layer->points); + const Point *points = dynarray_data(point_layer->points); + const Point point = camera_map_screen(camera, event->button.x, event->button.y); + const Color color = color_picker_rgba(&point_layer->color_picker); + + for (int i = 0; i < n; ++i) { + if (vec_length(vec_sub(points[i], point)) < POINT_LAYER_ELEMENT_RADIUS) { + point_layer->selected = i; + return 0; } - point_layer->selected = -1; - } break; - - case SDLK_F2: { - if (point_layer->selected >= 0) { - char *ids = dynarray_data(point_layer->ids); - point_layer->state = POINT_LAYER_ID_EDITING_STATE; - edit_field_replace( - point_layer->edit_field, - ids + ID_MAX_SIZE * point_layer->selected); - SDL_StartTextInput(); - } - } break; + } + + char id[ID_MAX_SIZE]; - default: {} + for (size_t i = 0; i < ID_MAX_SIZE - 1; ++i) { + id[i] = (char) ('a' + rand() % ('z' - 'a' + 1)); } + id[ID_MAX_SIZE - 1] = '\0'; + + dynarray_push(point_layer->points, &point); + dynarray_push(point_layer->colors, &color); + dynarray_push(point_layer->ids, id); + } break; } } break; - case POINT_LAYER_ID_EDITING_STATE: { - if (edit_field_keyboard(point_layer->edit_field, key) < 0) { - return -1; - } + case SDL_KEYDOWN: { + switch (event->key.keysym.sym) { + case SDLK_DELETE: { + if (0 <= point_layer->selected && point_layer->selected < (int) dynarray_count(point_layer->points)) { + dynarray_delete_at(point_layer->points, (size_t) point_layer->selected); + dynarray_delete_at(point_layer->colors, (size_t) point_layer->selected); + dynarray_delete_at(point_layer->ids, (size_t) point_layer->selected); + } + point_layer->selected = -1; + } break; - if (key->type == SDL_KEYDOWN) { - switch(key->keysym.sym) { - case SDLK_RETURN: { + case SDLK_F2: { + if (point_layer->selected >= 0) { char *ids = dynarray_data(point_layer->ids); - const char *text = edit_field_as_text(point_layer->edit_field); - size_t n = max_size_t(strlen(text), ID_MAX_SIZE - 1); - memcpy(ids + point_layer->selected * ID_MAX_SIZE, text, n); - *(ids + point_layer->selected * ID_MAX_SIZE + n) = '\0'; - point_layer->state = POINT_LAYER_NORMAL_STATE; - SDL_StopTextInput(); - } break; - - case SDLK_ESCAPE: { - point_layer->state = POINT_LAYER_NORMAL_STATE; - SDL_StopTextInput(); - } break; + point_layer->state = POINT_LAYER_EDIT_ID; + edit_field_replace( + point_layer->edit_field, + ids + ID_MAX_SIZE * point_layer->selected); + SDL_StartTextInput(); } + } break; } } break; } - return 0; } -int point_layer_text_input(PointLayer *point_layer, - const SDL_TextInputEvent *text_input) +static +int point_layer_edit_id_event(PointLayer *point_layer, + const SDL_Event *event, + const Camera *camera) +{ + trace_assert(point_layer); + trace_assert(event); + trace_assert(camera); + + switch (event->type) { + case SDL_KEYDOWN: { + switch(event->key.keysym.sym) { + case SDLK_RETURN: { + char *ids = dynarray_data(point_layer->ids); + const char *text = edit_field_as_text(point_layer->edit_field); + size_t n = max_size_t(strlen(text), ID_MAX_SIZE - 1); + memcpy(ids + point_layer->selected * ID_MAX_SIZE, text, n); + *(ids + point_layer->selected * ID_MAX_SIZE + n) = '\0'; + point_layer->state = POINT_LAYER_IDLE; + SDL_StopTextInput(); + return 0; + } break; + + case SDLK_ESCAPE: { + point_layer->state = POINT_LAYER_IDLE; + SDL_StopTextInput(); + return 0; + } break; + } + } break; + } + + return edit_field_event(point_layer->edit_field, event); +} + +int point_layer_event(PointLayer *point_layer, + const SDL_Event *event, + const Camera *camera) { trace_assert(point_layer); - trace_assert(text_input); + trace_assert(event); + trace_assert(camera); + + switch (point_layer->state) { + case POINT_LAYER_IDLE: + return point_layer_idle_event(point_layer, event, camera); - if (point_layer->state == POINT_LAYER_ID_EDITING_STATE) { - /* TODO(#856): Special development keybindings interfere with id editing field */ - return edit_field_text_input(point_layer->edit_field, text_input); + case POINT_LAYER_EDIT_ID: + return point_layer_edit_id_event(point_layer, event, camera); } return 0; @@ -301,3 +345,26 @@ const char *point_layer_ids(const PointLayer *point_layer) trace_assert(point_layer); return dynarray_data(point_layer->ids); } + +int point_layer_dump_stream(const PointLayer *point_layer, + FILE *filedump) +{ + trace_assert(point_layer); + trace_assert(filedump); + + size_t n = dynarray_count(point_layer->ids); + char *ids = dynarray_data(point_layer->ids); + Point *points = dynarray_data(point_layer->points); + Color *colors = dynarray_data(point_layer->colors); + + fprintf(filedump, "%zd\n", n); + for (size_t i = 0; i < n; ++i) { + fprintf(filedump, "%s %f %f ", + ids + ID_MAX_SIZE * i, + points[i].x, points[i].y); + color_hex_to_stream(colors[i], filedump); + fprintf(filedump, "\n"); + } + + return 0; +}