Redo working
This commit is contained in:
@@ -20,7 +20,8 @@ struct HistoryEntry {
|
||||
};
|
||||
|
||||
struct History {
|
||||
Array<HistoryEntry> entries;
|
||||
Array<HistoryEntry> undo_stack;
|
||||
Array<HistoryEntry> redo_stack;
|
||||
int debug_edit_phase;
|
||||
};
|
||||
|
||||
@@ -287,49 +288,19 @@ void MergeCursors(Window *window) {
|
||||
new_cursors.add(it);
|
||||
}
|
||||
}
|
||||
Assert(new_cursors.len <= window->cursors.len);
|
||||
window->cursors.dealloc();
|
||||
window->cursors = new_cursors;
|
||||
}
|
||||
|
||||
void UndoEdit(Window *window) {
|
||||
if (window->history.entries.len <= 0) return;
|
||||
|
||||
HistoryEntry entry = window->history.entries.pop();
|
||||
_ApplyEdits(&window->buffer, entry.edits);
|
||||
|
||||
window->cursors.dealloc();
|
||||
window->cursors = entry.cursors;
|
||||
|
||||
void SaveHistoryBeforeMergeCursor(Window *window, Array<HistoryEntry> *stack) {
|
||||
HistoryEntry *entry = stack->alloc();
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
For(entry.edits) Dealloc(sys_allocator, &it.string.data);
|
||||
entry.edits.dealloc();
|
||||
|
||||
// Generate layout
|
||||
Clear(&window->layout_arena);
|
||||
window->layout = CalculateLayout(&window->layout_arena, window->buffer, window->font, window->font_size, window->font_spacing);
|
||||
}
|
||||
|
||||
void BeforeEdit(Window *window) {
|
||||
Assert(window->history.debug_edit_phase == 0);
|
||||
window->history.debug_edit_phase += 1;
|
||||
|
||||
{
|
||||
History &h = window->history;
|
||||
HistoryEntry *entry = h.entries.alloc();
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
Assert(window->cursors.len);
|
||||
entry->cursors = window->cursors.tight_copy(sys_allocator);
|
||||
}
|
||||
|
||||
MergeCursors(window);
|
||||
}
|
||||
|
||||
void ApplyEdits(Window *window, Array<Edit> edits) {
|
||||
Assert(window->history.debug_edit_phase == 1);
|
||||
window->history.debug_edit_phase += 1;
|
||||
|
||||
{
|
||||
HistoryEntry *entry = window->history.entries.last();
|
||||
void SaveHistoryBeforeApplyEdits(Window *window, Array<HistoryEntry> *stack, Array<Edit> edits) {
|
||||
HistoryEntry *entry = stack->last();
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
entry->edits = edits.tight_copy(sys_allocator);
|
||||
|
||||
@@ -359,8 +330,68 @@ void ApplyEdits(Window *window, Array<Edit> edits) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RedoEdit(Window *window) {
|
||||
if (window->history.redo_stack.len <= 0) return;
|
||||
|
||||
HistoryEntry entry = window->history.redo_stack.pop();
|
||||
|
||||
SaveHistoryBeforeMergeCursor(window, &window->history.undo_stack);
|
||||
SaveHistoryBeforeApplyEdits(window, &window->history.undo_stack, entry.edits);
|
||||
_ApplyEdits(&window->buffer, entry.edits);
|
||||
|
||||
window->cursors.dealloc();
|
||||
window->cursors = entry.cursors;
|
||||
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
For(entry.edits) Dealloc(sys_allocator, &it.string.data);
|
||||
entry.edits.dealloc();
|
||||
|
||||
// Generate layout
|
||||
Clear(&window->layout_arena);
|
||||
window->layout = CalculateLayout(&window->layout_arena, window->buffer, window->font, window->font_size, window->font_spacing);
|
||||
}
|
||||
|
||||
void UndoEdit(Window *window) {
|
||||
if (window->history.undo_stack.len <= 0) return;
|
||||
|
||||
HistoryEntry entry = window->history.undo_stack.pop();
|
||||
|
||||
SaveHistoryBeforeMergeCursor(window, &window->history.redo_stack);
|
||||
SaveHistoryBeforeApplyEdits(window, &window->history.redo_stack, entry.edits);
|
||||
_ApplyEdits(&window->buffer, entry.edits);
|
||||
|
||||
window->cursors.dealloc();
|
||||
window->cursors = entry.cursors;
|
||||
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
For(entry.edits) Dealloc(sys_allocator, &it.string.data);
|
||||
entry.edits.dealloc();
|
||||
|
||||
// Generate layout
|
||||
Clear(&window->layout_arena);
|
||||
window->layout = CalculateLayout(&window->layout_arena, window->buffer, window->font, window->font_size, window->font_spacing);
|
||||
}
|
||||
|
||||
void BeforeEdit(Window *window) {
|
||||
Assert(window->history.debug_edit_phase == 0);
|
||||
window->history.debug_edit_phase += 1;
|
||||
Assert(window->cursors.len);
|
||||
SaveHistoryBeforeMergeCursor(window, &window->history.undo_stack);
|
||||
For(window->history.redo_stack) {
|
||||
it.cursors.dealloc();
|
||||
ForItem(edit, it.edits) Dealloc(it.edits.allocator, &edit.string.data);
|
||||
it.edits.dealloc();
|
||||
}
|
||||
window->history.redo_stack.dealloc();
|
||||
MergeCursors(window);
|
||||
}
|
||||
|
||||
void ApplyEdits(Window *window, Array<Edit> edits) {
|
||||
Assert(window->history.debug_edit_phase == 1);
|
||||
window->history.debug_edit_phase += 1;
|
||||
SaveHistoryBeforeApplyEdits(window, &window->history.undo_stack, edits);
|
||||
_ApplyEdits(&window->buffer, edits);
|
||||
}
|
||||
|
||||
@@ -368,7 +399,7 @@ void AfterEdit(Window *window, Array<Edit> edits) {
|
||||
Assert(window->history.debug_edit_phase == 2);
|
||||
window->history.debug_edit_phase -= 2;
|
||||
|
||||
HistoryEntry *entry = window->history.entries.last();
|
||||
HistoryEntry *entry = window->history.undo_stack.last();
|
||||
Assert(entry->cursors.len);
|
||||
Assert(entry->edits.len);
|
||||
|
||||
|
||||
@@ -316,9 +316,15 @@ int main() {
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && (IsKeyPressed(KEY_Z) || IsKeyPressedRepeat(KEY_Z))) {
|
||||
if ((IsKeyPressed(KEY_Z) || IsKeyPressedRepeat(KEY_Z))) {
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
||||
RedoEdit(focused_window);
|
||||
} else {
|
||||
UndoEdit(focused_window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_DELETE) || IsKeyPressedRepeat(KEY_DELETE)) {
|
||||
// Select things to delete
|
||||
|
||||
Reference in New Issue
Block a user