Fix parenting of image transform undoables

`cancel()` inside `undoable()` action callback caused it to navigate history,
and it would navigate all the way to the start of the last pointer gesture because
`history_node_to_cancel_to` was only set on pointerdown, not taking into account non-pointer-gesture operations.
The point was to allow undoing Fill With Color when canceling, but with the old definition of `history_node_to_cancel_to` it would have needed to be set in scattered places.
Now I'm defining it where it can be null, and if it's null, canceling should just go back to the history node at the start of `cancel()` (after making history nodes if applicable by telling tools to finish).
main
Isaiah Odhner 2019-12-15 20:54:03 -05:00
parent 9092d86ee2
commit 51fe6913ee
3 changed files with 20 additions and 8 deletions

View File

@ -58,7 +58,7 @@ let text_tool_font = {
let root_history_node = make_history_node({name: "App Not Loaded Properly - Please send a bug report."}); // will be replaced
let current_history_node = root_history_node;
let history_node_to_cancel_to = current_history_node;
let history_node_to_cancel_to = null;
/** array of history nodes */
let undos = [];
/** array of history nodes */
@ -734,7 +734,7 @@ $canvas.on("pointerdown", e => {
$G.on("pointermove", canvas_pointer_move);
$G.one("pointerup", (e) => {
$G.one("pointerup", (e, canceling) => {
button = undefined;
reverse = false;
@ -752,6 +752,10 @@ $canvas.on("pointerdown", e => {
for (const interval_id of interval_ids) {
clearInterval(interval_id);
}
if (!canceling) {
history_node_to_cancel_to = null;
}
});
};

View File

@ -267,7 +267,8 @@ function reset_file(){
function reset_canvas_and_history(){
undos.length = 0;
redos.length = 0;
history_node_to_cancel_to = current_history_node = root_history_node = make_history_node({name: "New Document"});
current_history_node = root_history_node = make_history_node({name: "New Document"});
history_node_to_cancel_to = null;
canvas.width = Math.max(1, my_canvas_width);
canvas.height = Math.max(1, my_canvas_height);
@ -1044,7 +1045,12 @@ function undoable({name, icon, use_loose_canvas_changes, soft}, callback){
saved = false;
const before_callback_history_node = current_history_node;
callback && callback();
if (current_history_node !== before_callback_history_node) {
show_error_message(`History node switched during undoable callback for ${name}. This shouldn't happen.`);
window.console && console.log(`History node switched during undoable callback for ${name}, from`, before_callback_history_node, "to", current_history_node);
}
const image_data = ctx.getImageData(0, 0, canvas.width, canvas.height);
@ -1230,7 +1236,8 @@ function show_document_history() {
function cancel(going_to_history_node){
// Note: this function should be idempotent.
// `cancel(); cancel();` should do the same thing as `cancel();`
$G.triggerHandler("pointerup");
history_node_to_cancel_to = history_node_to_cancel_to || current_history_node;
$G.triggerHandler("pointerup", ["canceling"]);
for (const selected_tool of selected_tools) {
selected_tool.cancel && selected_tool.cancel();
}
@ -1239,6 +1246,7 @@ function cancel(going_to_history_node){
// which isn't good, but there's no real conflict resolution in multi-user mode anyways
go_to_history_node(history_node_to_cancel_to, true);
}
history_node_to_cancel_to = null;
update_helper_layer();
}
function meld_selection_into_canvas(going_to_history_node) {
@ -1448,9 +1456,9 @@ function image_invert(){
}
function clear(){
deselect();
cancel();
undoable({name: "Clear"}, () => {
deselect();
cancel();
saved = false;
if(transparency){

View File

@ -413,12 +413,12 @@ function apply_image_transformation(meta, fn){
selection.replace_source_canvas(new_canvas);
});
}else{
deselect();
cancel();
undoable({
name: meta.name,
icon: meta.icon,
}, () => {
deselect();
cancel();
saved = false;
ctx.copy(new_canvas);