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 = {
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) {
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) {
}
}
} break;
+
+ case SDLK_z: {
+ if (event->key.keysym.mod & KMOD_CTRL) {
+ log_info("Undo\n");
+ undo_history_pop(level_editor->undo_history);
+ }
+ } break;
}
} break;
if (layer_event(
level_editor->layers[level_editor->layer_picker],
event,
- camera) < 0) {
+ camera,
+ level_editor->undo_history) < 0) {
return -1;
}
}
#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;
LayerPtr layers[LAYER_PICKER_N];
+ UndoHistory *undo_history;
+
bool drag;
const char *file_name;
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;
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);
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;
} 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_
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(
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);
#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)
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) {
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;
}
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);
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;
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);
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);
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) {
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);
lt,
nth_calloc(1, sizeof(UndoHistory)),
free);
+ undo_history->lt = lt;
undo_history->actions = PUSH_LT(
lt,
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;