3 #include "system/stacktrace.h"
4 #include "system/line_stream.h"
5 #include "system/log.h"
7 #include "system/nth_alloc.h"
8 #include "system/str.h"
10 #include "game/camera.h"
11 #include "./point_layer.h"
13 #define POINT_LAYER_ELEMENT_RADIUS 10.0f
24 // TODO(#837): PointLayer does not allow to edit itself
26 PointLayer *create_point_layer_from_line_stream(LineStream *line_stream)
28 trace_assert(line_stream);
35 PointLayer *point_layer = PUSH_LT(lt, nth_calloc(1, sizeof(PointLayer)), free);
36 if (point_layer == NULL) {
41 point_layer->points = PUSH_LT(lt, create_dynarray(sizeof(Point)), destroy_dynarray);
42 if (point_layer->points == NULL) {
46 point_layer->colors = PUSH_LT(lt, create_dynarray(sizeof(Color)), destroy_dynarray);
47 if (point_layer->colors == NULL) {
51 point_layer->ids = PUSH_LT(lt, create_dynarray(sizeof(char) * ID_MAX_SIZE), destroy_dynarray);
52 if (point_layer->ids == NULL) {
56 point_layer->selected = -1;
60 line_stream_next(line_stream),
63 log_fail("Could not read amount of points");
70 for (size_t i = 0; i < count; ++i) {
72 line_stream_next(line_stream),
73 "%"STRINGIFY(ID_MAX_SIZE)"s%f%f%6s",
74 id, &x, &y, color_name) < 0) {
75 log_fail("Could not read %dth goal\n", i);
78 const Color color = hexstr(color_name);
79 const Point point = vec(x, y);
81 dynarray_push(point_layer->colors, &color);
82 dynarray_push(point_layer->points, &point);
83 dynarray_push(point_layer->ids, id);
89 void destroy_point_layer(PointLayer *point_layer)
91 trace_assert(point_layer);
92 RETURN_LT0(point_layer->lt);
95 int point_layer_render(const PointLayer *point_layer,
98 trace_assert(point_layer);
101 const int n = (int) dynarray_count(point_layer->points);
102 Point *points = dynarray_data(point_layer->points);
103 Color *colors = dynarray_data(point_layer->colors);
105 for (int i = 0; i < n; ++i) {
106 const Triangle t = triangle_mat3x3_product(
107 equilateral_triangle(),
109 trans_mat(points[i].x, points[i].y),
110 scale_mat(POINT_LAYER_ELEMENT_RADIUS)));
112 if (i == point_layer->selected) {
113 const Triangle t0 = triangle_mat3x3_product(
114 equilateral_triangle(),
116 trans_mat(points[i].x, points[i].y),
119 if (camera_fill_triangle(camera, t0, color_invert(colors[i])) < 0) {
124 if (camera_fill_triangle(camera, t, colors[i]) < 0) {
132 // TODO(#841): PointLayer does not allow to remove elements
134 int point_layer_mouse_button(PointLayer *point_layer,
135 const SDL_MouseButtonEvent *event,
136 const Camera *camera,
139 trace_assert(point_layer);
142 if (event->type == SDL_MOUSEBUTTONDOWN && event->button == SDL_BUTTON_LEFT) {
143 const int n = (int) dynarray_count(point_layer->points);
144 const Point *points = dynarray_data(point_layer->points);
145 const Point point = camera_map_screen(camera, event->x, event->y);
147 for (int i = 0; i < n; ++i) {
148 if (vec_length(vec_sub(points[i], point)) < POINT_LAYER_ELEMENT_RADIUS) {
149 point_layer->selected = i;
154 char id[ID_MAX_SIZE];
156 // TODO(#842): PointLayer does not allow to specify an id of a point
157 for (size_t i = 0; i < ID_MAX_SIZE - 1; ++i) {
158 id[i] = (char) ('a' + rand() % ('z' - 'a' + 1));
161 dynarray_push(point_layer->points, &point);
162 dynarray_push(point_layer->colors, &color);
163 dynarray_push(point_layer->ids, id);
169 int point_layer_keyboard(PointLayer *point_layer,
170 const SDL_KeyboardEvent *event)
172 trace_assert(point_layer);
175 if (event->type == SDL_KEYDOWN && event->keysym.sym == SDLK_DELETE) {
176 if (0 <= point_layer->selected && point_layer->selected < (int) dynarray_count(point_layer->points)) {
177 dynarray_delete_at(point_layer->points, (size_t) point_layer->selected);
178 dynarray_delete_at(point_layer->colors, (size_t) point_layer->selected);
179 dynarray_delete_at(point_layer->ids, (size_t) point_layer->selected);
182 point_layer->selected = -1;
188 size_t point_layer_count(const PointLayer *point_layer)
190 trace_assert(point_layer);
191 return dynarray_count(point_layer->points);
194 const Point *point_layer_points(const PointLayer *point_layer)
196 trace_assert(point_layer);
197 return dynarray_data(point_layer->points);
200 const Color *point_layer_colors(const PointLayer *point_layer)
202 trace_assert(point_layer);
203 return dynarray_data(point_layer->colors);
206 const char *point_layer_ids(const PointLayer *point_layer)
208 trace_assert(point_layer);
209 return dynarray_data(point_layer->ids);