5 #include "system/line_stream.h"
6 #include "system/stacktrace.h"
7 #include "system/nth_alloc.h"
9 #include "system/str.h"
10 #include "system/log.h"
11 #include "math/point.h"
12 #include "label_layer.h"
15 #include "game/camera.h"
16 #include "color_picker.h"
18 #define LABEL_LAYER_ID_MAX_SIZE 36
25 // TODO: LabelLayer cannot specify the color of the labels
26 // TODO: LabelLayer cannot add the labels
27 // TODO: LabelLayer cannot modify the labels' text
28 // TODO: LabelLayer cannot modify the labels' id
31 LabelLayerState state;
37 ColorPicker color_picker;
40 LayerPtr label_layer_as_layer(LabelLayer *label_layer)
49 LabelLayer *create_label_layer(void)
53 LabelLayer *label_layer = PUSH_LT(
54 lt, nth_calloc(1, sizeof(LabelLayer)), free);
55 if (label_layer == NULL) {
60 label_layer->ids = PUSH_LT(
62 create_dynarray(sizeof(char) * LABEL_LAYER_ID_MAX_SIZE),
64 if (label_layer->ids == NULL) {
68 label_layer->positions = PUSH_LT(lt, create_dynarray(sizeof(Point)), destroy_dynarray);
69 if (label_layer->positions == NULL) {
73 label_layer->colors = PUSH_LT(lt, create_dynarray(sizeof(Color)), destroy_dynarray);
74 if (label_layer->colors == NULL) {
78 label_layer->texts = PUSH_LT(lt, create_dynarray(sizeof(char*)), destroy_dynarray);
79 if (label_layer->texts == NULL) {
83 label_layer->color_picker = create_color_picker_from_rgba(COLOR_RED);
84 label_layer->selected = -1;
89 LabelLayer *create_label_layer_from_line_stream(LineStream *line_stream)
91 trace_assert(line_stream);
92 LabelLayer *label_layer = create_label_layer();
94 if (label_layer == NULL) {
95 RETURN_LT(label_layer->lt, NULL);
98 const char *line = line_stream_next(line_stream);
100 log_fail("Could not read amount of labels\n");
101 RETURN_LT(label_layer->lt, NULL);
105 if (sscanf(line, "%zu", &n) == EOF) {
106 log_fail("Could not parse amount of labels\n");
107 RETURN_LT(label_layer->lt, NULL);
110 for (size_t i = 0; i < n; ++i) {
112 char id[LABEL_LAYER_ID_MAX_SIZE];
115 line = line_stream_next(line_stream);
117 log_fail("Could not read label meta info\n");
118 RETURN_LT(label_layer->lt, NULL);
123 "%"STRINGIFY(LABEL_LAYER_ID_MAX_SIZE)"s%f%f%6s\n",
124 id, &position.x, &position.y, hex) == EOF) {
125 log_fail("Could not parse label meta info\n");
126 RETURN_LT(label_layer->lt, NULL);
129 Color color = hexstr(hex);
131 dynarray_push(label_layer->ids, id);
132 dynarray_push(label_layer->positions, &position);
133 dynarray_push(label_layer->colors, &color);
135 line = line_stream_next(line_stream);
137 log_fail("Could not read label text\n");
140 char *label_text = PUSH_LT(label_layer->lt, string_duplicate(line, NULL), free);
141 trim_endline(label_text);
142 dynarray_push(label_layer->texts, &label_text);
148 void destroy_label_layer(LabelLayer *label_layer)
150 trace_assert(label_layer);
151 destroy_lt(label_layer->lt);
154 int label_layer_render(const LabelLayer *label_layer,
158 trace_assert(label_layer);
159 trace_assert(camera);
161 if (active && color_picker_render(&label_layer->color_picker, camera) < 0) {
165 size_t n = dynarray_count(label_layer->ids);
166 Point *positions = dynarray_data(label_layer->positions);
167 Color *colors = dynarray_data(label_layer->colors);
168 char **texts = dynarray_data(label_layer->texts);
170 /* TODO(#891): LabelLayer doesn't show the final position of Label after the animation */
171 for (size_t i = 0; i < n; ++i) {
172 if (camera_render_text(
178 rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f)),
188 int label_layer_element_at(LabelLayer *label_layer,
189 const Sprite_font *font,
192 trace_assert(label_layer);
194 const size_t n = dynarray_count(label_layer->texts);
195 char **texts = dynarray_data(label_layer->texts);
196 Point *positions = dynarray_data(label_layer->positions);
198 for (size_t i = 0; i < n; ++i) {
199 Rect boundary = sprite_font_boundary_box(
205 if (rect_contains_point(boundary, position)) {
214 int label_layer_idle_event(LabelLayer *label_layer,
215 const SDL_Event *event,
216 const Camera *camera)
218 trace_assert(label_layer);
220 trace_assert(camera);
222 switch (event->type) {
223 case SDL_MOUSEBUTTONDOWN: {
224 switch (event->button.button) {
225 case SDL_BUTTON_LEFT: {
226 const Point position = camera_map_screen(
231 const int element = label_layer_element_at(
237 label_layer->selected = element;
238 label_layer->state = LABEL_LAYER_MOVE;
249 int label_layer_move_event(LabelLayer *label_layer,
250 const SDL_Event *event,
251 const Camera *camera)
253 trace_assert(label_layer);
255 trace_assert(camera);
256 trace_assert(label_layer->selected >= 0);
258 switch (event->type) {
259 case SDL_MOUSEMOTION: {
260 Point *positions = dynarray_data(label_layer->positions);
261 positions[label_layer->selected] =
268 case SDL_MOUSEBUTTONUP: {
269 switch (event->button.button) {
270 case SDL_BUTTON_LEFT: {
271 label_layer->state = LABEL_LAYER_IDLE;
280 int label_layer_event(LabelLayer *label_layer,
281 const SDL_Event *event,
282 const Camera *camera)
284 trace_assert(label_layer);
286 trace_assert(camera);
288 switch (label_layer->state) {
289 case LABEL_LAYER_IDLE:
290 return label_layer_idle_event(label_layer, event, camera);
292 case LABEL_LAYER_MOVE:
293 return label_layer_move_event(label_layer, event, camera);
299 size_t label_layer_count(const LabelLayer *label_layer)
301 return dynarray_count(label_layer->ids);
304 char *label_layer_ids(const LabelLayer *label_layer)
306 return dynarray_data(label_layer->ids);
309 Point *label_layer_positions(const LabelLayer *label_layer)
311 return dynarray_data(label_layer->positions);
314 Color *label_layer_colors(const LabelLayer *label_layer)
316 return dynarray_data(label_layer->colors);
319 char **labels_layer_texts(const LabelLayer *label_layer)
321 return dynarray_data(label_layer->texts);
324 int label_layer_dump_stream(const LabelLayer *label_layer, FILE *filedump)
326 trace_assert(label_layer);
327 trace_assert(filedump);
329 size_t n = dynarray_count(label_layer->ids);
330 char *ids = dynarray_data(label_layer->ids);
331 Point *positions = dynarray_data(label_layer->positions);
332 Color *colors = dynarray_data(label_layer->colors);
333 char **texts = dynarray_data(label_layer->texts);
335 fprintf(filedump, "%zd\n", n);
336 for (size_t i = 0; i < n; ++i) {
337 fprintf(filedump, "%s %f %f ",
338 ids + LABEL_LAYER_ID_MAX_SIZE * i,
339 positions[i].x, positions[i].y);
340 color_hex_to_stream(colors[i], filedump);
341 fprintf(filedump, "\n%s\n", texts[i]);