Add modification tracking to the editor and wire it into undo/redo
This commit is contained in:
parent
9c5b241cae
commit
28a26cdc14
@ -3363,9 +3363,7 @@ export class Editor extends PrimaryView {
|
|||||||
this.save_button = _make_button("Save", ev => {
|
this.save_button = _make_button("Save", ev => {
|
||||||
this.save_level();
|
this.save_level();
|
||||||
});
|
});
|
||||||
if (this.stored_level) {
|
|
||||||
this.save_button.disabled = ! this.conductor.stored_game.editor_metadata;
|
|
||||||
}
|
|
||||||
_make_button("Download level as C2M", ev => {
|
_make_button("Download level as C2M", ev => {
|
||||||
// TODO also allow download as CCL
|
// TODO also allow download as CCL
|
||||||
// TODO support getting warnings + errors out of synthesis
|
// TODO support getting warnings + errors out of synthesis
|
||||||
@ -3831,6 +3829,9 @@ export class Editor extends PrimaryView {
|
|||||||
if (! stored_pack.editor_metadata)
|
if (! stored_pack.editor_metadata)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.modified = false;
|
||||||
|
this.undo_modification_offset = 0;
|
||||||
|
|
||||||
// Update the pack itself
|
// Update the pack itself
|
||||||
// TODO maybe should keep this around, but there's a tricky order of operations thing
|
// TODO maybe should keep this around, but there's a tricky order of operations thing
|
||||||
// with it
|
// with it
|
||||||
@ -3850,6 +3851,7 @@ export class Editor extends PrimaryView {
|
|||||||
if (this._level_browser) {
|
if (this._level_browser) {
|
||||||
this._level_browser.expire(this.conductor.level_index);
|
this._level_browser.expire(this.conductor.level_index);
|
||||||
}
|
}
|
||||||
|
this._update_ui_after_edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -3864,6 +3866,7 @@ export class Editor extends PrimaryView {
|
|||||||
this.stored_level = stored_level;
|
this.stored_level = stored_level;
|
||||||
this.update_viewport_size();
|
this.update_viewport_size();
|
||||||
this.update_cell_coordinates();
|
this.update_cell_coordinates();
|
||||||
|
this.modified = false;
|
||||||
|
|
||||||
// Remember current level for an editor level
|
// Remember current level for an editor level
|
||||||
if (this.conductor.stored_game.editor_metadata) {
|
if (this.conductor.stored_game.editor_metadata) {
|
||||||
@ -3895,10 +3898,6 @@ export class Editor extends PrimaryView {
|
|||||||
this.redraw_entire_level();
|
this.redraw_entire_level();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.save_button) {
|
|
||||||
this.save_button.disabled = ! this.conductor.stored_game.editor_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._done_setup) {
|
if (this._done_setup) {
|
||||||
// XXX this doesn't work yet if setup hasn't run because the undo button won't exist
|
// XXX this doesn't work yet if setup hasn't run because the undo button won't exist
|
||||||
this.reset_undo();
|
this.reset_undo();
|
||||||
@ -4260,9 +4259,8 @@ export class Editor extends PrimaryView {
|
|||||||
_done(redo, undo, modifies = true) {
|
_done(redo, undo, modifies = true) {
|
||||||
// TODO parallel arrays would be smaller
|
// TODO parallel arrays would be smaller
|
||||||
this.undo_entry.push([undo, redo]);
|
this.undo_entry.push([undo, redo]);
|
||||||
|
if (modifies) {
|
||||||
if (this.redo_stack.length > 0) {
|
this.undo_entry.modifies = true;
|
||||||
this.redo_stack.length = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4283,7 +4281,11 @@ export class Editor extends PrimaryView {
|
|||||||
this.undo_entry = [];
|
this.undo_entry = [];
|
||||||
this.undo_stack = [];
|
this.undo_stack = [];
|
||||||
this.redo_stack = [];
|
this.redo_stack = [];
|
||||||
this._update_undo_redo_enabled();
|
// Number of steps we'd need to take (negative if redo, positive if undo) to reach a
|
||||||
|
// pristine saved state. May also be null, meaning the pristine state is in a redo branch
|
||||||
|
// that has been overwritten and is thus unreachable.
|
||||||
|
this.undo_modification_offset = 0;
|
||||||
|
this._update_ui_after_edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
undo() {
|
undo() {
|
||||||
@ -4293,6 +4295,7 @@ export class Editor extends PrimaryView {
|
|||||||
if (this.undo_entry.length > 0) {
|
if (this.undo_entry.length > 0) {
|
||||||
entry = this.undo_entry;
|
entry = this.undo_entry;
|
||||||
this.undo_entry = [];
|
this.undo_entry = [];
|
||||||
|
console.warn("lingering undo entry");
|
||||||
}
|
}
|
||||||
else if (this.undo_stack.length > 0) {
|
else if (this.undo_stack.length > 0) {
|
||||||
entry = this.undo_stack.pop();
|
entry = this.undo_stack.pop();
|
||||||
@ -4306,7 +4309,9 @@ export class Editor extends PrimaryView {
|
|||||||
entry[i][0]();
|
entry[i][0]();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._update_undo_redo_enabled();
|
this._track_undo_offset(-1, entry.modifies);
|
||||||
|
|
||||||
|
this._update_ui_after_edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
redo() {
|
redo() {
|
||||||
@ -4320,21 +4325,56 @@ export class Editor extends PrimaryView {
|
|||||||
redo();
|
redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._update_undo_redo_enabled();
|
this._track_undo_offset(+1, entry.modifies);
|
||||||
|
|
||||||
|
this._update_ui_after_edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
commit_undo() {
|
_track_undo_offset(delta, modifies) {
|
||||||
if (this.undo_entry.length > 0) {
|
if (this.undo_modification_offset === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (this.undo_modification_offset === 0) {
|
||||||
|
if (modifies) {
|
||||||
|
this.modified = true;
|
||||||
|
this.undo_modification_offset += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.undo_modification_offset += delta;
|
||||||
|
if (this.undo_modification_offset === 0) {
|
||||||
|
this.modified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_undo(label = null) {
|
||||||
|
if (this.undo_entry.length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.undo_entry.modifies) {
|
||||||
|
this.modified = true;
|
||||||
|
}
|
||||||
this.undo_stack.push(this.undo_entry);
|
this.undo_stack.push(this.undo_entry);
|
||||||
this.undo_entry = [];
|
this.undo_entry = [];
|
||||||
|
|
||||||
|
// Doing an action always erases the redo stack
|
||||||
|
if (this.redo_stack.length > 0) {
|
||||||
|
this.redo_stack.length = 0;
|
||||||
|
if (this.undo_modification_offset < 0) {
|
||||||
|
// Pristine state was in the future, so it's now unreachable
|
||||||
|
this.undo_modification_offset = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._update_undo_redo_enabled();
|
this._update_ui_after_edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_undo_redo_enabled() {
|
_update_ui_after_edit() {
|
||||||
this.undo_button.disabled = this.undo_stack.length === 0;
|
this.undo_button.disabled = this.undo_stack.length === 0;
|
||||||
this.redo_button.disabled = this.redo_stack.length === 0;
|
this.redo_button.disabled = this.redo_stack.length === 0;
|
||||||
|
this.save_button.disabled = ! (
|
||||||
|
this.stored_level && this.modified && this.conductor.stored_game.editor_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user