#include "game/level/boxes.h"
#include "game/level/level_editor/proto_rect.h"
#include "game/level/level_editor/color_picker.h"
+#include "game/level/level_editor/layer.h"
#include "system/stacktrace.h"
#include "system/nth_alloc.h"
+#include "system/lt.h"
#include "level_editor.h"
+// TODO(#802): Level Editor should modify boxes_layer instead of boxes
struct LevelEditor
{
+ Lt *lt;
Vec camera_position;
float camera_scale;
ProtoRect proto_rect;
ColorPicker color_picker;
- Boxes *boxes;
+ // TODO: boxes_layer is not connected with the level->boxes
+ Layer *boxes_layer;
+ bool drag;
};
-LevelEditor *create_level_editor(Boxes *boxes)
+LevelEditor *create_level_editor(void)
{
- LevelEditor *level_editor = nth_calloc(1, sizeof(LevelEditor));
- if (level_editor == NULL) {
+ Lt *lt = create_lt();
+ if (lt == NULL) {
return NULL;
}
+ LevelEditor *level_editor = PUSH_LT(lt, nth_calloc(1, sizeof(LevelEditor)), free);
+ if (level_editor == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+ level_editor->lt = lt;
+
level_editor->camera_position = vec(0.0f, 0.0f);
level_editor->camera_scale = 1.0f;
- level_editor->boxes = boxes;
level_editor->proto_rect.color = rgba(1.0f, 0.0f, 0.0f, 1.0f);
level_editor->color_picker.position = vec(0.0f, 0.0f);
level_editor->color_picker.proto_rect = &level_editor->proto_rect;
+ level_editor->boxes_layer = PUSH_LT(lt, create_layer(), destroy_layer);
+
+ if (level_editor->boxes_layer == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+
+ level_editor->drag = false;
return level_editor;
}
void destroy_level_editor(LevelEditor *level_editor)
{
trace_assert(level_editor);
- free(level_editor);
+ RETURN_LT0(level_editor->lt);
}
int level_editor_render(const LevelEditor *level_editor,
trace_assert(level_editor);
trace_assert(camera);
+ if (layer_render(level_editor->boxes_layer, camera) < 0) {
+ return -1;
+ }
+
if (proto_rect_render(&level_editor->proto_rect, camera) < 0) {
return -1;
}
trace_assert(level_editor);
trace_assert(event);
- switch (event->type) {
- case SDL_MOUSEMOTION: {
- const float sens = 1.0f / level_editor->camera_scale * 0.25f;
- vec_add(&level_editor->camera_position,
- vec((float) event->motion.xrel * sens, (float) event->motion.yrel * sens));
- } break;
+ (void) camera;
+ switch (event->type) {
case SDL_MOUSEWHEEL: {
// TODO(#679): zooming in edit mode is not smooth enough
if (event->wheel.y > 0) {
level_editor->camera_scale = fmaxf(0.1f, level_editor->camera_scale - 0.1f);
}
} break;
- }
- if (proto_rect_event(
- &level_editor->proto_rect,
- event,
- camera,
- level_editor->boxes) < 0) {
- return -1;
- }
+ case SDL_MOUSEBUTTONUP:
+ case SDL_MOUSEBUTTONDOWN: {
+ if (event->type == SDL_MOUSEBUTTONUP) {
+ const Vec position = camera_map_screen(camera, event->button.x, event->button.y);
+ if (layer_delete_rect_at(level_editor->boxes_layer, position) < 0) {
+ return -1;
+ }
+ }
- if (color_picker_event(&level_editor->color_picker, event) < 0) {
- return -1;
+ bool selected = false;
+ if (color_picker_mouse_button(
+ &level_editor->color_picker,
+ &event->button,
+ &selected) < 0) {
+ return -1;
+ }
+
+ if (!selected && proto_rect_mouse_button(
+ &level_editor->proto_rect,
+ &event->button,
+ level_editor->boxes_layer,
+ camera) < 0) {
+ return -1;
+ }
+
+ if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_MIDDLE) {
+ level_editor->drag = true;
+ }
+
+ if (event->type == SDL_MOUSEBUTTONUP && event->button.button == SDL_BUTTON_MIDDLE) {
+ level_editor->drag = false;
+ }
+ } break;
+
+ case SDL_MOUSEMOTION: {
+ if (level_editor->drag) {
+ const Vec next_position = camera_map_screen(camera, event->motion.x, event->motion.y);
+ const Vec prev_position = camera_map_screen(
+ camera,
+ event->motion.x + event->motion.xrel,
+ event->motion.y + event->motion.yrel);
+
+ vec_add(&level_editor->camera_position,
+ vec_sub(next_position, prev_position));
+ }
+
+ if (proto_rect_mouse_motion(&level_editor->proto_rect, &event->motion, camera) < 0) {
+ return -1;
+ }
+ } break;
}
return 0;