X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame%2Flevel%2Flevel_editor%2Flabel_layer.c;h=ec5b7f9e417e4373dc16237bdbbaf496f8c892a7;hb=7cf04bb466f5f32e35b82cacd0d448dabe47d858;hp=88080b3c8b995eddb528cdf8044fad0fef64b518;hpb=ab55f2d1e21dc99e2ef976d6f3fc27a06832b4d1;p=nothing.git diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 88080b3c..ec5b7f9e 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -18,6 +18,8 @@ #define LABEL_LAYER_SELECTION_THICCNESS 5.0f +// TODO(#999): LabelLayer does not support UndoHistory + typedef enum { LABEL_LAYER_IDLE = 0, LABEL_LAYER_MOVE, @@ -25,8 +27,6 @@ typedef enum { LABEL_LAYER_EDIT_ID } LabelLayerState; -// TODO(#963): LabelLayer cannot add the labels -// TODO(#964): LabelLayer cannot modify the labels' id struct LabelLayer { Lt *lt; LabelLayerState state; @@ -185,7 +185,7 @@ int label_layer_render(const LabelLayer *label_layer, /* TODO(#891): LabelLayer doesn't show the final position of Label after the animation */ for (size_t i = 0; i < n; ++i) { - if (label_layer->state == LABEL_LAYER_EDIT_TEXT) { + if (label_layer->state == LABEL_LAYER_EDIT_TEXT && label_layer->selected == (int) i) { if (edit_field_render_world( label_layer->edit_field, camera, @@ -205,7 +205,7 @@ int label_layer_render(const LabelLayer *label_layer, } } - if (label_layer->state == LABEL_LAYER_EDIT_ID) { + if (label_layer->state == LABEL_LAYER_EDIT_ID && label_layer->selected == (int)i) { if (edit_field_render_world( label_layer->edit_field, camera, @@ -270,15 +270,24 @@ int label_layer_element_at(LabelLayer *label_layer, trace_assert(label_layer); const size_t n = dynarray_count(label_layer->texts); + char *ids = dynarray_data(label_layer->ids); char *texts = dynarray_data(label_layer->texts); Point *positions = dynarray_data(label_layer->positions); for (size_t i = 0; i < n; ++i) { - Rect boundary = sprite_font_boundary_box( - font, - positions[i], - LABELS_SIZE, - texts + i * LABEL_LAYER_TEXT_MAX_SIZE); + Rect boundary = rect_boundary2( + sprite_font_boundary_box( + font, + positions[i], + LABELS_SIZE, + texts + i * LABEL_LAYER_TEXT_MAX_SIZE), + sprite_font_boundary_box( + font, + vec_sub( + positions[i], + vec(0.0f, FONT_CHAR_HEIGHT)), + vec(1.0f, 1.0f), + ids + i * LABEL_LAYER_ID_MAX_SIZE)); if (rect_contains_point(boundary, position)) { return (int) i; @@ -288,6 +297,41 @@ int label_layer_element_at(LabelLayer *label_layer, return -1; } +static +void label_layer_delete_nth_label(LabelLayer *label_layer, + size_t i) +{ + trace_assert(label_layer); + dynarray_delete_at(label_layer->ids, i); + dynarray_delete_at(label_layer->positions, i); + dynarray_delete_at(label_layer->colors, i); + dynarray_delete_at(label_layer->texts, i); +} + +static +int label_layer_add_label(LabelLayer *label_layer, + Point position, + Color color) +{ + trace_assert(label_layer); + + // TODO(#982): id generation code is duplicated in label_layer, point_layer and rect_layer + char id[LABEL_LAYER_ID_MAX_SIZE]; + for (size_t i = 0; i < LABEL_LAYER_ID_MAX_SIZE - 1; ++i) { + id[i] = (char) ('a' + rand() % ('z' - 'a' + 1)); + } + id[LABEL_LAYER_ID_MAX_SIZE - 1] = '\0'; + + size_t n = dynarray_count(label_layer->ids); + + dynarray_push(label_layer->ids, id); + dynarray_push(label_layer->positions, &position); + dynarray_push(label_layer->colors, &color); + dynarray_push_empty(label_layer->texts); + + return (int) n; +} + static int label_layer_idle_event(LabelLayer *label_layer, const SDL_Event *event, @@ -323,6 +367,21 @@ int label_layer_idle_event(LabelLayer *label_layer, label_layer->color_picker = create_color_picker_from_rgba(colors[element]); + } else { + label_layer->selected = label_layer_add_label( + label_layer, + position, + color_picker_rgba( + &label_layer->color_picker)); + label_layer->state = LABEL_LAYER_EDIT_TEXT; + edit_field_replace( + label_layer->edit_field, + texts + label_layer->selected * LABEL_LAYER_TEXT_MAX_SIZE); + edit_field_restyle( + label_layer->edit_field, + LABELS_SIZE, + colors[label_layer->selected]); + SDL_StartTextInput(); } } break; } @@ -357,6 +416,15 @@ int label_layer_idle_event(LabelLayer *label_layer, SDL_StartTextInput(); } } break; + + case SDLK_DELETE: { + if (label_layer->selected >= 0) { + label_layer_delete_nth_label( + label_layer, + (size_t) label_layer->selected); + label_layer->selected = -1; + } + } break; } } break; } @@ -410,13 +478,22 @@ int label_layer_edit_text_event(LabelLayer *label_layer, switch (event->type) { case SDL_KEYDOWN: { - if (event->key.keysym.sym == SDLK_RETURN) { + switch (event->key.keysym.sym) { + case SDLK_RETURN: { char *text = (char*)dynarray_data(label_layer->texts) + label_layer->selected * LABEL_LAYER_TEXT_MAX_SIZE; memset(text, 0, LABEL_LAYER_TEXT_MAX_SIZE); memcpy(text, edit_field_as_text(label_layer->edit_field), LABEL_LAYER_TEXT_MAX_SIZE - 1); label_layer->state = LABEL_LAYER_IDLE; + SDL_StopTextInput(); return 0; + } break; + + case SDLK_ESCAPE: { + label_layer->state = LABEL_LAYER_IDLE; + SDL_StopTextInput(); + return 0; + } break; } } break; } @@ -434,31 +511,40 @@ int label_layer_edit_id_event(LabelLayer *label_layer, trace_assert(camera); trace_assert(label_layer->selected >= 0); - switch (event->type) { case SDL_KEYDOWN: { - if (event->key.keysym.sym == SDLK_RETURN) { + switch (event->key.keysym.sym) { + case SDLK_RETURN: { char *id = (char*)dynarray_data(label_layer->ids) + label_layer->selected * LABEL_LAYER_ID_MAX_SIZE; memset(id, 0, LABEL_LAYER_ID_MAX_SIZE); memcpy(id, edit_field_as_text(label_layer->edit_field), LABEL_LAYER_ID_MAX_SIZE - 1); label_layer->state = LABEL_LAYER_IDLE; + SDL_StopTextInput(); return 0; + } break; + + case SDLK_ESCAPE: { + label_layer->state = LABEL_LAYER_IDLE; + SDL_StopTextInput(); + return 0; + } break; } } break; } - return edit_field_event(label_layer->edit_field, event); } int label_layer_event(LabelLayer *label_layer, const SDL_Event *event, - const Camera *camera) + const Camera *camera, + UndoHistory *undo_history) { trace_assert(label_layer); trace_assert(event); trace_assert(camera); + trace_assert(undo_history); int changed = 0; @@ -469,10 +555,13 @@ int label_layer_event(LabelLayer *label_layer, return -1; } - if (changed && label_layer->selected >= 0) { - Color *colors = dynarray_data(label_layer->colors); - colors[label_layer->selected] = - color_picker_rgba(&label_layer->color_picker); + if (changed) { + if (label_layer->selected >= 0) { + Color *colors = dynarray_data(label_layer->colors); + colors[label_layer->selected] = + color_picker_rgba(&label_layer->color_picker); + } + return 0; } switch (label_layer->state) {