1 #include "game/camera.h"
3 #include "system/stacktrace.h"
4 #include "system/nth_alloc.h"
5 #include "system/log.h"
8 #include "rect_layer.h"
10 #include "system/line_stream.h"
11 #include "proto_rect.h"
12 #include "color_picker.h"
13 #include "system/str.h"
15 #define RECT_LAYER_ID_MAX_SIZE 36
17 /* TODO(#886): RectLayer does not allow to modify ids of Rects */
24 ColorPicker color_picker;
27 LayerPtr rect_layer_as_layer(RectLayer *rect_layer)
36 RectLayer *create_rect_layer(void)
40 RectLayer *layer = PUSH_LT(lt, nth_calloc(1, sizeof(RectLayer)), free);
48 create_dynarray(sizeof(char) * RECT_LAYER_ID_MAX_SIZE),
50 if (layer->ids == NULL) {
54 layer->rects = PUSH_LT(
56 create_dynarray(sizeof(Rect)),
58 if (layer->rects == NULL) {
62 layer->colors = PUSH_LT(
64 create_dynarray(sizeof(Color)),
66 if (layer->colors == NULL) {
70 layer->color_picker.color = rgba(1.0f, 0.0f, 0.0f, 1.0f);
71 layer->proto_rect.color_current = &layer->color_picker.color;
72 layer->proto_rect.layer_current = layer;
77 RectLayer *create_rect_layer_from_line_stream(LineStream *line_stream)
79 trace_assert(line_stream);
81 RectLayer *layer = create_rect_layer();
86 const char *line = line_stream_next(line_stream);
88 RETURN_LT(layer->lt, NULL);
92 if (sscanf(line, "%lu", &count) < 0) {
93 RETURN_LT(layer->lt, NULL);
96 for (size_t i = 0; i < count; ++i) {
97 line = line_stream_next(line_stream);
99 RETURN_LT(layer->lt, NULL);
104 char id[RECT_LAYER_ID_MAX_SIZE];
107 "%"STRINGIFY(RECT_LAYER_ID_MAX_SIZE)"s%f%f%f%f%6s\n",
112 RETURN_LT(layer->lt, NULL);
115 Color color = hexstr(hex);
117 dynarray_push(layer->rects, &rect);
118 dynarray_push(layer->ids, id);
119 dynarray_push(layer->colors, &color);
125 void destroy_rect_layer(RectLayer *layer)
128 RETURN_LT0(layer->lt);
131 int rect_layer_render(const RectLayer *layer, Camera *camera, float fa)
134 trace_assert(camera);
136 const size_t n = dynarray_count(layer->rects);
137 Rect *rects = dynarray_data(layer->rects);
138 Color *colors = dynarray_data(layer->colors);
140 for (size_t i = 0; i < n; ++i) {
141 if (camera_fill_rect(
146 rgba(1.0f, 1.0f, 1.0f, fa))) < 0) {
151 if (proto_rect_render(&layer->proto_rect, camera) < 0) {
155 if (color_picker_render(&layer->color_picker, camera) < 0) {
162 int rect_layer_event(RectLayer *layer, const SDL_Event *event, const Camera *camera)
167 switch(event->type) {
168 case SDL_MOUSEBUTTONDOWN:
169 case SDL_MOUSEBUTTONUP: {
170 bool selected = false;
171 if (color_picker_mouse_button(
172 &layer->color_picker,
178 if (!selected && proto_rect_mouse_button(
187 case SDL_MOUSEMOTION: {
188 if (proto_rect_mouse_motion(&layer->proto_rect, &event->motion, camera) < 0) {
197 int rect_layer_add_rect(RectLayer *layer, Rect rect, Color color)
201 if (dynarray_push(layer->rects, &rect) < 0) {
205 if (dynarray_push(layer->colors, &color) < 0) {
209 char id[RECT_LAYER_ID_MAX_SIZE];
210 for (size_t i = 0; i < RECT_LAYER_ID_MAX_SIZE - 1; ++i) {
211 id[i] = (char) ('a' + rand() % ('z' - 'a' + 1));
213 id[RECT_LAYER_ID_MAX_SIZE - 1] = '\0';
215 if (dynarray_push(layer->ids, id)) {
222 int rect_layer_delete_rect_at(RectLayer *layer, Vec position)
226 const size_t n = dynarray_count(layer->rects);
227 Rect *rects = dynarray_data(layer->rects);
229 for (size_t i = 0; i < n; ++i) {
230 if (rect_contains_point(rects[i], position)) {
231 dynarray_delete_at(layer->rects, i);
232 dynarray_delete_at(layer->colors, i);
240 size_t rect_layer_count(const RectLayer *layer)
242 return dynarray_count(layer->rects);
245 const Rect *rect_layer_rects(const RectLayer *layer)
247 return dynarray_data(layer->rects);
250 const Color *rect_layer_colors(const RectLayer *layer)
252 return dynarray_data(layer->colors);
255 const char *rect_layer_ids(const RectLayer *layer)
257 return dynarray_data(layer->ids);