]> git.lizzy.rs Git - nothing.git/commitdiff
(#824) Integrate UndoHistory with the LevelEditor
authorrexim <reximkut@gmail.com>
Sat, 3 Aug 2019 20:53:28 +0000 (03:53 +0700)
committerrexim <reximkut@gmail.com>
Sat, 3 Aug 2019 20:53:28 +0000 (03:53 +0700)
14 files changed:
src/game/level/level_editor.c
src/game/level/level_editor.h
src/game/level/level_editor/label_layer.c
src/game/level/level_editor/label_layer.h
src/game/level/level_editor/layer.c
src/game/level/level_editor/layer.h
src/game/level/level_editor/player_layer.c
src/game/level/level_editor/player_layer.h
src/game/level/level_editor/point_layer.c
src/game/level/level_editor/point_layer.h
src/game/level/level_editor/rect_layer.c
src/game/level/level_editor/rect_layer.h
src/game/level/level_editor/undo_history.c
src/game/level/level_editor/undo_history.h

index 2f49928357dddee2a42edae717cef816c30bbf0a..f9de16b56b226ed408bf97c8a13d6156a1d2053d 100644 (file)
@@ -134,7 +134,10 @@ LevelEditor *create_level_editor(void)
     level_editor->layers[LAYER_PICKER_BACKGROUND] = color_picker_as_layer(&level_editor->background_layer);
     level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(level_editor->label_layer);
 
-    level_editor->drag = false;
+    level_editor->undo_history = PUSH_LT(
+        lt,
+        create_undo_history(),
+        destroy_undo_history);
 
     level_editor->notice = (FadingWigglyText) {
         .wiggly_text = {
@@ -289,6 +292,11 @@ LevelEditor *create_level_editor_from_file(const char *file_name)
     level_editor->layers[LAYER_PICKER_BACKGROUND] = color_picker_as_layer(&level_editor->background_layer);
     level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(level_editor->label_layer);
 
+    level_editor->undo_history = PUSH_LT(
+        lt,
+        create_undo_history(),
+        destroy_undo_history);
+
     level_editor->drag = false;
 
     level_editor->notice = (FadingWigglyText) {
@@ -415,7 +423,7 @@ int level_editor_idle_event(LevelEditor *level_editor,
 
     switch (event->type) {
     case SDL_KEYDOWN: {
-        switch(event-> key.keysym.sym) {
+        switch(event->key.keysym.sym) {
         case SDLK_s: {
             if (!SDL_IsTextInputActive()) {
                 if (level_editor->file_name) {
@@ -427,6 +435,13 @@ int level_editor_idle_event(LevelEditor *level_editor,
                 }
             }
         } break;
+
+        case SDLK_z: {
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                log_info("Undo\n");
+                undo_history_pop(level_editor->undo_history);
+            }
+        } break;
         }
     } break;
 
@@ -490,7 +505,8 @@ int level_editor_idle_event(LevelEditor *level_editor,
         if (layer_event(
                 level_editor->layers[level_editor->layer_picker],
                 event,
-                camera) < 0) {
+                camera,
+                level_editor->undo_history) < 0) {
             return -1;
         }
     }
index ed86583b1ff9100e679a31197e3cce1863acc58c..d48a4ce09b65ccd307860aa9b93d06ee50132cc5 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "game/level/level_editor/layer.h"
 #include "game/level/level_editor/layer_picker.h"
+#include "game/level/level_editor/undo_history.h"
 #include "ui/wiggly_text.h"
 
 typedef struct LevelMetadata LevelMetadata;
@@ -41,6 +42,8 @@ struct LevelEditor
 
     LayerPtr layers[LAYER_PICKER_N];
 
+    UndoHistory *undo_history;
+
     bool drag;
 
     const char *file_name;
index a0085b2df5212c6a3c61da487b85d0f3238672a7..9075503a4dc6aed62db15fe2f51811457846bbfa 100644 (file)
@@ -536,11 +536,13 @@ int label_layer_edit_id_event(LabelLayer *label_layer,
 
 int label_layer_event(LabelLayer *label_layer,
                       const SDL_Event *event,
-                      const Camera *camera)
+                      const Camera *camera,
+                      UndoHistory *undo_history)
 {
     trace_assert(label_layer);
     trace_assert(event);
     trace_assert(camera);
+    trace_assert(undo_history);
 
     int changed = 0;
 
index 0992467880208c00e04e8cb366ac13763ef544c9..30c4d76bdf2b1e62576ec48cd304a1f42da4e17d 100644 (file)
@@ -24,7 +24,8 @@ int label_layer_render(const LabelLayer *label_layer,
                        int active);
 int label_layer_event(LabelLayer *label_layer,
                       const SDL_Event *event,
-                      const Camera *camera);
+                      const Camera *camera,
+                      UndoHistory *undo_history);
 
 size_t label_layer_count(const LabelLayer *label_layer);
 
index 783cec1ab2749802a467409702aa54600e122069..87a01d0c67bf815888d740d409cac16e340cffc8 100644 (file)
@@ -29,23 +29,25 @@ int layer_render(LayerPtr layer, Camera *camera, int active)
 
 int layer_event(LayerPtr layer,
                 const SDL_Event *event,
-                const Camera *camera)
+                const Camera *camera,
+                UndoHistory *undo_history)
 {
     switch (layer.type) {
     case LAYER_RECT:
-        return rect_layer_event(layer.ptr, event, camera);
+        return rect_layer_event(layer.ptr, event, camera, undo_history);
 
     case LAYER_POINT:
-        return point_layer_event(layer.ptr, event, camera);
+        return point_layer_event(layer.ptr, event, camera, undo_history);
 
     case LAYER_PLAYER:
-        return player_layer_event(layer.ptr, event, camera);
+        return player_layer_event(layer.ptr, event, camera, undo_history);
 
     case LAYER_COLOR_PICKER:
+        // TODO: undo history is not really applicable to color picker as layer
         return color_picker_event(layer.ptr, event, NULL);
 
     case LAYER_LABEL:
-        return label_layer_event(layer.ptr, event, camera);
+        return label_layer_event(layer.ptr, event, camera, undo_history);
     }
 
     return -1;
index e0b55a1173e6dd360f14d8e62c41e6b1ca78adfc..f3678fe0fee44172275101182e1601209021eca6 100644 (file)
@@ -15,9 +15,13 @@ typedef struct {
 } LayerPtr;
 
 typedef struct Camera Camera;
+typedef struct UndoHistory UndoHistory;
 
 int layer_render(LayerPtr layer, Camera *camera, int active);
-int layer_event(LayerPtr layer, const SDL_Event *event, const Camera *camera);
+int layer_event(LayerPtr layer,
+                const SDL_Event *event,
+                const Camera *camera,
+                UndoHistory *undo_history);
 int layer_dump_stream(LayerPtr layer, FILE *stream);
 
 #endif  // LAYER_H_
index 37955e1d857d40ea8fc647ccfb8f4dc1ded9ba5a..885bc785f63984670284e8084baac93059fdd66e 100644 (file)
@@ -76,12 +76,13 @@ int player_layer_render(const PlayerLayer *player_layer,
 
 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(
index 63cc7c03ed3f1c34d62f521da96f5002c8962483..50ec08ff2df20f95b60fd64d0fc7b3802d3cf829 100644 (file)
@@ -20,7 +20,8 @@ int player_layer_render(const PlayerLayer *player_layer,
                         int active);
 int player_layer_event(PlayerLayer *player_layer,
                        const SDL_Event *event,
-                       const Camera *camera);
+                       const Camera *camera,
+                       UndoHistory *undo_history);
 
 int player_layer_dump_stream(const PlayerLayer *player_layer,
                              FILE *filedump);
index f59f4e18e147850fe7b4d194e2e97eb2bcca7c83..1bb70cfa34b0815a95531a5df62031ade83ab898 100644 (file)
@@ -14,6 +14,7 @@
 #include "./point_layer.h"
 #include "math/extrema.h"
 #include "./color_picker.h"
+#include "undo_history.h"
 
 #define POINT_LAYER_ELEMENT_RADIUS 10.0f
 #define POINT_LAYER_ID_TEXT_SIZE vec(2.0f, 2.0f)
@@ -219,12 +220,27 @@ int point_layer_element_at(const PointLayer *point_layer,
     return -1;
 }
 
+static
+void point_layer_pop_element(void *layer, Context context)
+{
+    trace_assert(layer);
+    (void) context;
+
+    PointLayer *point_layer = layer;
+
+    dynarray_pop(point_layer->positions, NULL);
+    dynarray_pop(point_layer->colors, NULL);
+    dynarray_pop(point_layer->ids, NULL);
+}
+
 static
 int point_layer_add_element(PointLayer *point_layer,
                             Point position,
-                            Color color)
+                            Color color,
+                            UndoHistory *undo_history)
 {
     trace_assert(point_layer);
+    trace_assert(undo_history);
 
     char id[ID_MAX_SIZE];
     for (size_t i = 0; i < ID_MAX_SIZE - 1; ++i) {
@@ -236,6 +252,12 @@ int point_layer_add_element(PointLayer *point_layer,
     dynarray_push(point_layer->colors, &color);
     dynarray_push(point_layer->ids, id);
 
+    Action action =  {
+        .revert = point_layer_pop_element,
+        .layer = point_layer
+    };
+    undo_history_push(undo_history, action);
+
     return 0;
 }
 
@@ -252,7 +274,8 @@ void point_layer_delete_nth_element(PointLayer *point_layer,
 static
 int point_layer_idle_event(PointLayer *point_layer,
                            const SDL_Event *event,
-                           const Camera *camera)
+                           const Camera *camera,
+                           UndoHistory *undo_history)
 {
     trace_assert(point_layer);
     trace_assert(event);
@@ -287,7 +310,10 @@ int point_layer_idle_event(PointLayer *point_layer,
 
             if (point_layer->selected < 0) {
                 point_layer_add_element(
-                    point_layer, position, color_picker_rgba(&point_layer->color_picker));
+                    point_layer,
+                    position,
+                    color_picker_rgba(&point_layer->color_picker),
+                    undo_history);
             } else {
                 Color *colors = dynarray_data(point_layer->colors);
                 point_layer->state = POINT_LAYER_MOVE;
@@ -390,15 +416,17 @@ int point_layer_move_event(PointLayer *point_layer,
 
 int point_layer_event(PointLayer *point_layer,
                       const SDL_Event *event,
-                      const Camera *camera)
+                      const Camera *camera,
+                      UndoHistory *undo_history)
 {
     trace_assert(point_layer);
     trace_assert(event);
     trace_assert(camera);
+    trace_assert(undo_history);
 
     switch (point_layer->state) {
     case POINT_LAYER_IDLE:
-        return point_layer_idle_event(point_layer, event, camera);
+        return point_layer_idle_event(point_layer, event, camera, undo_history);
 
     case POINT_LAYER_EDIT_ID:
         return point_layer_edit_id_event(point_layer, event, camera);
index 83d6032c2f18b3220c82f7e6699d542acd08ab12..db06743ffe0aae3ed1e6467150fe8e4721aa7885 100644 (file)
@@ -21,7 +21,8 @@ int point_layer_render(const PointLayer *point_layer,
                        int active);
 int point_layer_event(PointLayer *point_layer,
                       const SDL_Event *event,
-                      const Camera *camera);
+                      const Camera *camera,
+                      UndoHistory *undo_history);
 
 int point_layer_dump_stream(const PointLayer *point_layer,
                             FILE *filedump);
index 118a63e6131941ef6358d13998fc31cfa704d5fb..d9ddcc04b695182e573f0fdefa911db221e436b9 100644 (file)
@@ -516,10 +516,14 @@ int rect_layer_render(const RectLayer *layer, Camera *camera, int active)
     return 0;
 }
 
-int rect_layer_event(RectLayer *layer, const SDL_Event *event, const Camera *camera)
+int rect_layer_event(RectLayer *layer,
+                     const SDL_Event *event,
+                     const Camera *camera,
+                     UndoHistory *undo_history)
 {
     trace_assert(layer);
     trace_assert(event);
+    trace_assert(undo_history);
 
     int selected = 0;
     if (color_picker_event(&layer->color_picker, event, &selected) < 0) {
index 89353e4d23ed72ead69ef7a6bdeb3c02557f8770..48e53caadb4c5507a1e7473856242d719260b94b 100644 (file)
@@ -12,7 +12,10 @@ RectLayer *create_rect_layer_from_line_stream(LineStream *line_stream);
 void destroy_rect_layer(RectLayer *layer);
 
 int rect_layer_render(const RectLayer *layer, Camera *camera, int active);
-int rect_layer_event(RectLayer *layer, const SDL_Event *event, const Camera *camera);
+int rect_layer_event(RectLayer *layer,
+                     const SDL_Event *event,
+                     const Camera *camera,
+                     UndoHistory *undo_history);
 
 int rect_layer_dump_stream(const RectLayer *layer, FILE *filedump);
 
index ce6666239a2b0777b09642a1b0e65a1d51a242b5..d69619e3f153ec2b7e2f192d7c93d880795845c6 100644 (file)
@@ -22,6 +22,7 @@ UndoHistory *create_undo_history(void)
         lt,
         nth_calloc(1, sizeof(UndoHistory)),
         free);
+    undo_history->lt = lt;
 
     undo_history->actions = PUSH_LT(
         lt,
index 7a119f1e3939b4ccbb7c056d895933b6973ac9d4..953bc1cdebc563138a8d5ab8c6c8fba4780c803a 100644 (file)
@@ -9,10 +9,10 @@ typedef struct {
     char data[CONTEXT_SIZE];
 } Context;
 
-typedef void (*RevertAction)(LayerPtr layer, Context context);
+typedef void (*RevertAction)(void *layer, Context context);
 
 typedef struct {
-    LayerPtr layer;
+    void *layer;
     Context context;
     RevertAction revert;
 } Action;