Fully implemented undo for: add/delete/edit of keys
Also takes into account if more than one key is being modified at once and such being handled as a collection of commands in a multi-command so it looks hand behaves correct from the users perspective. Closes #6
This commit is contained in:
parent
f4c315c137
commit
49af1595f0
429
ogl_editor/src/Commands.c
Normal file
429
ogl_editor/src/Commands.c
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
#include "Commands.h"
|
||||||
|
#include "RemoteConnection.h"
|
||||||
|
#include "Types.h"
|
||||||
|
#include "../../sync/sync.h"
|
||||||
|
#include "../../sync/track.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static struct sync_track** s_syncTracks;
|
||||||
|
static struct TrackData* s_trackData;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct Command
|
||||||
|
{
|
||||||
|
void* userData;
|
||||||
|
void (*exec)(void* userData);
|
||||||
|
void (*undo)(void* userData);
|
||||||
|
struct Command* next;
|
||||||
|
struct Command* prev;
|
||||||
|
} Command;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct CommandList
|
||||||
|
{
|
||||||
|
Command* first;
|
||||||
|
Command* last;
|
||||||
|
} CommandList;
|
||||||
|
|
||||||
|
static CommandList s_undoStack;
|
||||||
|
static CommandList s_redoStack;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_addEntry(CommandList* commandList, Command* command);
|
||||||
|
//static void CommandList_delEntry(CommandList* commandList, Command* command);
|
||||||
|
static void CommandList_clear(CommandList* commandList);
|
||||||
|
static bool CommandList_isEmpty(CommandList* list);
|
||||||
|
static void CommandList_pop(CommandList* commandList);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct MultiCommandData
|
||||||
|
{
|
||||||
|
CommandList list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct MultiCommandData* s_multiCommand;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_init(struct sync_track** syncTracks, struct TrackData* trackData)
|
||||||
|
{
|
||||||
|
s_syncTracks = syncTracks;
|
||||||
|
s_trackData = trackData;
|
||||||
|
|
||||||
|
memset(&s_undoStack, 0, sizeof(CommandList));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void execCommand(Command* command)
|
||||||
|
{
|
||||||
|
// set if we have multi command recording enabled)
|
||||||
|
if (s_multiCommand)
|
||||||
|
{
|
||||||
|
CommandList_addEntry(&s_multiCommand->list, command);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommandList_addEntry(&s_undoStack, command);
|
||||||
|
command->exec(command->userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandList_clear(&s_redoStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_beginMulti()
|
||||||
|
{
|
||||||
|
s_multiCommand = malloc(sizeof(struct MultiCommandData));
|
||||||
|
memset(s_multiCommand, 0, sizeof(struct MultiCommandData));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void execMultiCommand(void* userData)
|
||||||
|
{
|
||||||
|
Command* command;
|
||||||
|
struct MultiCommandData* data = (struct MultiCommandData*)userData;
|
||||||
|
|
||||||
|
for (command = data->list.first; command; command = command->next)
|
||||||
|
command->exec(command->userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void undoMultiCommand(void* userData)
|
||||||
|
{
|
||||||
|
Command* command;
|
||||||
|
struct MultiCommandData* data = (struct MultiCommandData*)userData;
|
||||||
|
|
||||||
|
for (command = data->list.first; command; command = command->next)
|
||||||
|
command->undo(command->userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_endMulti()
|
||||||
|
{
|
||||||
|
Command* command;
|
||||||
|
|
||||||
|
// Check if any command was added during multi command
|
||||||
|
|
||||||
|
if (CommandList_isEmpty(&s_multiCommand->list))
|
||||||
|
{
|
||||||
|
free(s_multiCommand);
|
||||||
|
s_multiCommand = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = malloc(sizeof(Command));
|
||||||
|
memset(command, 0, sizeof(Command));
|
||||||
|
|
||||||
|
command->userData = s_multiCommand;
|
||||||
|
command->exec = execMultiCommand;
|
||||||
|
command->undo = undoMultiCommand;
|
||||||
|
|
||||||
|
s_multiCommand = 0;
|
||||||
|
|
||||||
|
execCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct DeleteKeyData
|
||||||
|
{
|
||||||
|
int track;
|
||||||
|
int row;
|
||||||
|
struct track_key oldKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void execDeleteKey(void* userData)
|
||||||
|
{
|
||||||
|
struct DeleteKeyData* data = (struct DeleteKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
int idx = sync_find_key(t, data->row);
|
||||||
|
|
||||||
|
data->oldKey = t->keys[idx];
|
||||||
|
sync_del_key(t, data->row);
|
||||||
|
|
||||||
|
RemoteConnection_sendDeleteKeyCommand(t->name, data->row);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void undoDeleteKey(void* userData)
|
||||||
|
{
|
||||||
|
struct DeleteKeyData* data = (struct DeleteKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
sync_set_key(t, &data->oldKey);
|
||||||
|
|
||||||
|
RemoteConnection_sendSetKeyCommand(t->name, &data->oldKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_deleteKey(int track, int row)
|
||||||
|
{
|
||||||
|
struct DeleteKeyData* data;
|
||||||
|
Command* command;
|
||||||
|
struct sync_track* t = s_syncTracks[track];
|
||||||
|
|
||||||
|
if (!is_key_frame(t, row))
|
||||||
|
return;
|
||||||
|
|
||||||
|
command = malloc(sizeof(Command));
|
||||||
|
memset(command, 0, sizeof(Command));
|
||||||
|
|
||||||
|
command->userData = data = malloc(sizeof(struct DeleteKeyData));
|
||||||
|
command->exec = execDeleteKey;
|
||||||
|
command->undo = undoDeleteKey;
|
||||||
|
data->track = track;
|
||||||
|
data->row = row;
|
||||||
|
|
||||||
|
execCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct UpdateKeyData
|
||||||
|
{
|
||||||
|
int track;
|
||||||
|
struct track_key key;
|
||||||
|
struct track_key oldKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void execUpdateKey(void* userData)
|
||||||
|
{
|
||||||
|
struct UpdateKeyData* data = (struct UpdateKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
int idx = sync_find_key(t, data->key.row);
|
||||||
|
|
||||||
|
data->oldKey = t->keys[idx];
|
||||||
|
sync_set_key(t, &data->key);
|
||||||
|
|
||||||
|
RemoteConnection_sendSetKeyCommand(t->name, &data->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void undoUpdateKey(void* userData)
|
||||||
|
{
|
||||||
|
struct UpdateKeyData* data = (struct UpdateKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
sync_set_key(t, &data->oldKey);
|
||||||
|
|
||||||
|
RemoteConnection_sendSetKeyCommand(t->name, &data->oldKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_updateKey(int track, struct track_key* key)
|
||||||
|
{
|
||||||
|
struct UpdateKeyData* data;
|
||||||
|
Command* command;
|
||||||
|
|
||||||
|
command = malloc(sizeof(Command));
|
||||||
|
memset(command, 0, sizeof(Command));
|
||||||
|
|
||||||
|
command->userData = data = malloc(sizeof(struct UpdateKeyData));
|
||||||
|
command->exec = execUpdateKey;
|
||||||
|
command->undo = undoUpdateKey;
|
||||||
|
data->track = track;
|
||||||
|
data->key = *key;
|
||||||
|
|
||||||
|
execCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct InsertKeyData
|
||||||
|
{
|
||||||
|
int track;
|
||||||
|
struct track_key key;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void execInsertKey(void* userData)
|
||||||
|
{
|
||||||
|
struct InsertKeyData* data = (struct InsertKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
sync_set_key(t, &data->key);
|
||||||
|
|
||||||
|
RemoteConnection_sendSetKeyCommand(t->name, &data->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void undoInsertKey(void* userData)
|
||||||
|
{
|
||||||
|
struct InsertKeyData* data = (struct InsertKeyData*)userData;
|
||||||
|
struct sync_track* t = s_syncTracks[data->track];
|
||||||
|
sync_del_key(t, data->key.row);
|
||||||
|
|
||||||
|
RemoteConnection_sendDeleteKeyCommand(t->name, data->key.row);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_addOrUpdateKey(int track, struct track_key* key)
|
||||||
|
{
|
||||||
|
struct InsertKeyData* data;
|
||||||
|
Command* command;
|
||||||
|
struct sync_track* t = s_syncTracks[track];
|
||||||
|
|
||||||
|
if (is_key_frame(t, key->row))
|
||||||
|
{
|
||||||
|
Commands_updateKey(track, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = malloc(sizeof(Command));
|
||||||
|
memset(command, 0, sizeof(Command));
|
||||||
|
|
||||||
|
command->userData = data = malloc(sizeof(struct InsertKeyData));
|
||||||
|
command->exec = execInsertKey;
|
||||||
|
command->undo = undoInsertKey;
|
||||||
|
data->track = track;
|
||||||
|
data->key = *key;
|
||||||
|
|
||||||
|
execCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_undo()
|
||||||
|
{
|
||||||
|
Command* command;
|
||||||
|
|
||||||
|
if (CommandList_isEmpty(&s_undoStack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
command = s_undoStack.last;
|
||||||
|
CommandList_pop(&s_undoStack);
|
||||||
|
|
||||||
|
command->prev = 0;
|
||||||
|
command->next = 0;
|
||||||
|
|
||||||
|
CommandList_addEntry(&s_redoStack, command);
|
||||||
|
|
||||||
|
command->undo(command->userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_redo()
|
||||||
|
{
|
||||||
|
Command* command;
|
||||||
|
|
||||||
|
if (CommandList_isEmpty(&s_redoStack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
command = s_redoStack.last;
|
||||||
|
CommandList_pop(&s_redoStack);
|
||||||
|
|
||||||
|
CommandList_addEntry(&s_undoStack, command);
|
||||||
|
|
||||||
|
command->exec(command->userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_addEntry(CommandList* list, Command* command)
|
||||||
|
{
|
||||||
|
if (list->last)
|
||||||
|
{
|
||||||
|
list->last->next = command;
|
||||||
|
command->prev = list->last;
|
||||||
|
list->last = command;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list->first = command;
|
||||||
|
list->last = command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_unlinkEntry(CommandList* list, Command* command)
|
||||||
|
{
|
||||||
|
Command* prev;
|
||||||
|
Command* next;
|
||||||
|
|
||||||
|
prev = command->prev;
|
||||||
|
next = command->next;
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev->next = 0;
|
||||||
|
list->last = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
next->prev = 0;
|
||||||
|
list->first = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list->first = 0;
|
||||||
|
list->last = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_delEntry(CommandList* list, Command* command)
|
||||||
|
{
|
||||||
|
CommandList_unlinkEntry(list, command);
|
||||||
|
|
||||||
|
free(command->userData);
|
||||||
|
free(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_clear(CommandList* list)
|
||||||
|
{
|
||||||
|
while (list->last)
|
||||||
|
{
|
||||||
|
CommandList_delEntry(list, list->last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void CommandList_pop(CommandList* list)
|
||||||
|
{
|
||||||
|
CommandList_unlinkEntry(list, list->last);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool CommandList_isEmpty(CommandList* list)
|
||||||
|
{
|
||||||
|
return (!list->first && !list->last);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
29
ogl_editor/src/Commands.h
Normal file
29
ogl_editor/src/Commands.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _OGLEDITOR_COMMANDS_H_
|
||||||
|
#define _OGLEDITOR_COMMANDS_H_
|
||||||
|
|
||||||
|
struct sync_track;
|
||||||
|
struct track_key;
|
||||||
|
struct TrackData;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_init(struct sync_track** syncTracks, struct TrackData* trackData);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int Commands_needsSave();
|
||||||
|
|
||||||
|
void Commands_undo();
|
||||||
|
void Commands_redo();
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Commands_deleteKey(int track, int row);
|
||||||
|
void Commands_addOrUpdateKey(int track, struct track_key* key);
|
||||||
|
void Commands_toogleBookmark(int track, int row);
|
||||||
|
void Commands_updateKey(int track, struct track_key* key);
|
||||||
|
void Commands_beginMulti(); // Used (for example) when changing many value at the same time
|
||||||
|
void Commands_endMulti();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#include "minmax.h"
|
#include "minmax.h"
|
||||||
#include "TrackData.h"
|
#include "TrackData.h"
|
||||||
#include "RemoteConnection.h"
|
#include "RemoteConnection.h"
|
||||||
|
#include "Commands.h"
|
||||||
#include "MinecraftiaFont.h"
|
#include "MinecraftiaFont.h"
|
||||||
#include "../../sync/sync.h"
|
#include "../../sync/sync.h"
|
||||||
#include "../../sync/base.h"
|
#include "../../sync/base.h"
|
||||||
@ -488,6 +489,8 @@ static void deleteArea(int rowPos, int track, int bufferWidth, int bufferHeight)
|
|||||||
const int track_count = getTrackCount();
|
const int track_count = getTrackCount();
|
||||||
struct sync_track** tracks = getTracks();
|
struct sync_track** tracks = getTracks();
|
||||||
|
|
||||||
|
Commands_beginMulti();
|
||||||
|
|
||||||
for (i = 0; i < bufferWidth; ++i)
|
for (i = 0; i < bufferWidth; ++i)
|
||||||
{
|
{
|
||||||
struct sync_track* t;
|
struct sync_track* t;
|
||||||
@ -503,13 +506,11 @@ static void deleteArea(int rowPos, int track, int bufferWidth, int bufferHeight)
|
|||||||
{
|
{
|
||||||
int row = rowPos + j;
|
int row = rowPos + j;
|
||||||
|
|
||||||
if (is_key_frame(t, row))
|
Commands_deleteKey(trackIndex, row);
|
||||||
{
|
|
||||||
sync_del_key(t, row);
|
|
||||||
RemoteConnection_sendDeleteKeyCommand(t->name, row);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Commands_endMulti();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -519,6 +520,8 @@ static void biasSelection(float value, int selectLeft, int selectRight, int sele
|
|||||||
int track, row;
|
int track, row;
|
||||||
struct sync_track** tracks = getTracks();
|
struct sync_track** tracks = getTracks();
|
||||||
|
|
||||||
|
Commands_beginMulti();
|
||||||
|
|
||||||
for (track = selectLeft; track <= selectRight; ++track)
|
for (track = selectLeft; track <= selectRight; ++track)
|
||||||
{
|
{
|
||||||
struct sync_track* t = tracks[track];
|
struct sync_track* t = tracks[track];
|
||||||
@ -533,11 +536,11 @@ static void biasSelection(float value, int selectLeft, int selectRight, int sele
|
|||||||
newKey = t->keys[idx];
|
newKey = t->keys[idx];
|
||||||
newKey.value += value;
|
newKey.value += value;
|
||||||
|
|
||||||
sync_set_key(t, &newKey);
|
Commands_updateKey(track, &newKey);
|
||||||
|
|
||||||
RemoteConnection_sendSetKeyCommand(t->name, &newKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Commands_endMulti();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -572,11 +575,15 @@ static void endEditing()
|
|||||||
|
|
||||||
track_name = track->name;
|
track_name = track->name;
|
||||||
|
|
||||||
|
Commands_addOrUpdateKey(active_track, &key);
|
||||||
|
|
||||||
|
/*
|
||||||
sync_set_key(track, &key);
|
sync_set_key(track, &key);
|
||||||
|
|
||||||
rlog(R_INFO, "Setting key %f at %d row %d (name %s)\n", key.value, active_track, key.row, track_name);
|
rlog(R_INFO, "Setting key %f at %d row %d (name %s)\n", key.value, active_track, key.row, track_name);
|
||||||
|
|
||||||
RemoteConnection_sendSetKeyCommand(track_name, &key);
|
RemoteConnection_sendSetKeyCommand(track_name, &key);
|
||||||
|
*/
|
||||||
|
|
||||||
is_editing = false;
|
is_editing = false;
|
||||||
s_editorData.trackData.editText = 0;
|
s_editorData.trackData.editText = 0;
|
||||||
@ -876,6 +883,16 @@ bool Editor_keyDown(int key, int keyCode, int modifiers)
|
|||||||
handled_key = true;
|
handled_key = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == 'z' || key == 'Z')
|
||||||
|
{
|
||||||
|
if (modifiers & EMGUI_KEY_SHIFT)
|
||||||
|
Commands_redo();
|
||||||
|
else
|
||||||
|
Commands_undo();
|
||||||
|
|
||||||
|
handled_key = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle paste of data
|
// Handle paste of data
|
||||||
|
|
||||||
if (key == 'v' && (modifiers & EMGUI_KEY_COMMAND))
|
if (key == 'v' && (modifiers & EMGUI_KEY_COMMAND))
|
||||||
@ -1204,17 +1221,23 @@ static void setWindowTitle(const char* path)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void onFinishedLoad(const char* path)
|
||||||
|
{
|
||||||
|
Editor_update();
|
||||||
|
setWindowTitle(path);
|
||||||
|
setMostRecentFile(path);
|
||||||
|
//Commands_init(getTracks(), getTrackData());
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Editor_loadRecentFile(int id)
|
void Editor_loadRecentFile(int id)
|
||||||
{
|
{
|
||||||
char path[2048];
|
char path[2048];
|
||||||
strcpy(path, s_recentFiles[id]); // must be unique buffer when doing set mostRecent
|
strcpy(path, s_recentFiles[id]); // must be unique buffer when doing set mostRecent
|
||||||
|
|
||||||
if (LoadSave_loadRocketXML(path, getTrackData()))
|
if (LoadSave_loadRocketXML(path, getTrackData()))
|
||||||
{
|
onFinishedLoad(path);
|
||||||
Editor_update();
|
|
||||||
setWindowTitle(path);
|
|
||||||
setMostRecentFile(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1224,11 +1247,7 @@ static void onOpen()
|
|||||||
char currentFile[2048];
|
char currentFile[2048];
|
||||||
|
|
||||||
if (LoadSave_loadRocketXMLDialog(currentFile, getTrackData()))
|
if (LoadSave_loadRocketXMLDialog(currentFile, getTrackData()))
|
||||||
{
|
onFinishedLoad(currentFile);
|
||||||
Editor_update();
|
|
||||||
setWindowTitle(currentFile);
|
|
||||||
setMostRecentFile(currentFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "TrackData.h"
|
#include "TrackData.h"
|
||||||
|
#include "Commands.h"
|
||||||
#include "rlog.h"
|
#include "rlog.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -14,6 +15,9 @@ int TrackData_createGetTrack(TrackData* trackData, const char* name)
|
|||||||
trackData->tracks[index].color = TrackData_getNextColor(trackData);
|
trackData->tracks[index].color = TrackData_getNextColor(trackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trackData->syncData.tracks)
|
||||||
|
Commands_init(trackData->syncData.tracks, trackData);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user