]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/level_editor/player_layer.c
Merge pull request #1046 from tsoding/704
[nothing.git] / src / game / level / level_editor / player_layer.c
index 93012931e748ea28372b540764a983abc7b94709..2cfc4f75169c7eacbc1d62a3bc62226b052dda09 100644 (file)
@@ -7,53 +7,72 @@
 #include "player_layer.h"
 #include "system/nth_alloc.h"
 #include "system/log.h"
+#include "undo_history.h"
 
-PlayerLayer *create_player_layer(Vec position, Color color)
+typedef struct {
+    PlayerLayer *layer;
+    Point position;
+    Color color;
+} UndoContext;
+
+static
+UndoContext player_layer_create_undo_context(PlayerLayer *player_layer)
 {
-    Lt *lt = create_lt();
+    UndoContext context = {
+        .layer = player_layer,
+        .position = player_layer->position,
+        .color = player_layer->prev_color
+    };
 
-    PlayerLayer *player_layer = PUSH_LT(lt, nth_calloc(1, sizeof(PlayerLayer)), free);
-    player_layer->lt = lt;
+    return context;
+}
 
-    player_layer->position = position;
-    player_layer->color_picker = create_color_picker_from_rgba(color);
+static
+void player_layer_undo(void *context, size_t context_size)
+{
+    trace_assert(context);
+    trace_assert(sizeof(UndoContext) == context_size);
+
+    UndoContext *undo_context = context;
+    PlayerLayer *player_layer = undo_context->layer;
 
-    return player_layer;
+    player_layer->position = undo_context->position;
+    player_layer->color_picker = create_color_picker_from_rgba(undo_context->color);
+    player_layer->prev_color = undo_context->color;
 }
 
-PlayerLayer *create_player_layer_from_line_stream(LineStream *line_stream)
+PlayerLayer create_player_layer(Vec position, Color color)
 {
-    trace_assert(line_stream);
+    return (PlayerLayer) {
+        .position = position,
+        .color_picker = create_color_picker_from_rgba(color),
+        .prev_color = color
+    };
+}
 
-    PlayerLayer *player_layer = create_player_layer(
-        vec(0.0f, 0.0f), COLOR_BLACK);
+PlayerLayer create_player_layer_from_line_stream(LineStream *line_stream)
+{
+    trace_assert(line_stream);
 
     const char *line = line_stream_next(line_stream);
-    if (line == NULL) {
-        log_fail("Could not read Player Layer\n");
-        RETURN_LT(player_layer->lt, NULL);
-    }
+    trace_assert(line);
 
-    char colorstr[7];
-    Point position;
-    if (sscanf(line,
-               "%f%f%6s",
-               &position.x,
-               &position.y,
-               colorstr) == EOF) {
-        log_fail("Could not read Player Layer\n");
-        RETURN_LT(player_layer->lt, NULL);
+    char colorstr[7] = "000000";
+    Point position = vec(0.0f, 0.0f);
+
+    const int bound =
+        sscanf(line, "%f%f%6s", &position.x, &position.y, colorstr);
+
+#define BOUND_EXPECTED 3
+    if (bound != BOUND_EXPECTED) {
+        log_fail("Could not read Player Layer properly. Parsed tokens: %d. Expected: %d\n",
+                 bound, BOUND_EXPECTED);
     }
+#undef BOUND_EXPECTED
 
     return create_player_layer(position, hexstr(colorstr));
 }
 
-void destroy_player_layer(PlayerLayer *player_layer)
-{
-    trace_assert(player_layer);
-    destroy_lt(player_layer->lt);
-}
-
 LayerPtr player_layer_as_layer(PlayerLayer *player_layer)
 {
     LayerPtr layer = {
@@ -77,38 +96,61 @@ int player_layer_render(const PlayerLayer *player_layer,
                 vec(25.0f, 25.0f)),
             color_scale(
                 color_picker_rgba(&player_layer->color_picker),
-                rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.0f))) < 0) {
+                rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f))) < 0) {
         return -1;
     }
 
-    if (active && color_picker_render(&player_layer->color_picker, camera)) {
+    if (active && color_picker_render(
+            &player_layer->color_picker,
+            camera)) {
         return -1;
     }
 
     return 0;
 }
 
-
 int player_layer_event(PlayerLayer *player_layer,
                        const SDL_Event *event,
-                       const Camera *camera)
+                       const Camera *camera,
+                       UndoHistory *undo_history)
 {
     trace_assert(player_layer);
     trace_assert(event);
     trace_assert(camera);
-
+    trace_assert(undo_history);
 
     int selected = 0;
     if (color_picker_event(
             &player_layer->color_picker,
             event,
+            camera,
             &selected) < 0) {
         return -1;
     }
 
+    if (selected && !color_picker_drag(&player_layer->color_picker)) {
+        UndoContext context =
+            player_layer_create_undo_context(player_layer);
+        undo_history_push(
+            undo_history,
+            player_layer_undo,
+            &context,
+            sizeof(context));
+        player_layer->prev_color = color_picker_rgba(&player_layer->color_picker);
+    }
+
     if (!selected &&
-        event->type == SDL_MOUSEBUTTONUP &&
+        event->type == SDL_MOUSEBUTTONDOWN &&
         event->button.button == SDL_BUTTON_LEFT) {
+
+        UndoContext context =
+            player_layer_create_undo_context(player_layer);
+
+        undo_history_push(
+            undo_history,
+            player_layer_undo,
+            &context, sizeof(context));
+
         player_layer->position =
             camera_map_screen(camera,
                               event->button.x,