You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.8 KiB
103 lines
3.8 KiB
function undo(state, context, event, options) { |
|
let need_draw = false; |
|
|
|
// Remove effect of latest own event, in a way that is recoverable |
|
|
|
// Iterate back to front to find the _latest_ event |
|
for (let i = state.events.length - 1; i >=0; --i) { |
|
const other_event = state.events[i]; |
|
let skipped = false; |
|
|
|
// Users can only undo their own, undeleted (not already undone) events |
|
if (other_event.user_id === event.user_id && !other_event.deleted) { |
|
// All "persistent" events (those that are pushed using SYN messages) should be handled here |
|
// "Transient" events are by design droppable, and should not be undone, nor saved in state.events at all |
|
switch (other_event.type) { |
|
case EVENT.STROKE: { |
|
other_event.deleted = true; |
|
if (other_event.bvh_node && !options.skip_bvh) { |
|
bvh_delete_stroke(state, other_event); |
|
} |
|
need_draw = true; |
|
break; |
|
} |
|
|
|
case EVENT.UNDO: { |
|
// do not undo an undo, we are not Notepad |
|
skipped = true; |
|
break; |
|
} |
|
|
|
case EVENT.IMAGE: { |
|
other_event.deleted = true; |
|
const image = get_image(context, other_event.image_id); |
|
if (image !== null) { |
|
image.deleted = true; |
|
} |
|
need_draw = true; |
|
break; |
|
} |
|
|
|
case EVENT.IMAGE_MOVE: { |
|
other_event.deleted = true; |
|
const image = get_image(context, other_event.image_id); |
|
if (image !== null) { |
|
image.move_head -= 2; |
|
image.at.x = image.move_history[image.move_head - 2]; |
|
image.at.y = image.move_history[image.move_head - 1]; |
|
need_draw = true; |
|
} else { |
|
console.warning('Undo image move for a non-existent image'); |
|
} |
|
break; |
|
} |
|
|
|
case EVENT.IMAGE_SCALE: { |
|
other_event.deleted = true; |
|
const image = get_image(context, other_event.image_id); |
|
if (image !== null) { |
|
image.scale_head -= 4; |
|
|
|
// NEXT: merge move and scale. Otherwise we can't know |
|
// that there have been move events inbetween scale |
|
|
|
image.at.x = image.scale_history[image.scale_head - 4]; |
|
image.at.y = image.scale_history[image.scale_head - 3]; |
|
image.width = image.scale_history[image.scale_head - 2]; |
|
image.height = image.scale_history[image.scale_head - 1]; |
|
need_draw = true; |
|
} else { |
|
console.warning('Undo image scale for a non-existent image'); |
|
} |
|
break; |
|
} |
|
|
|
case EVENT.ERASER: { |
|
other_event.deleted = true; |
|
const stroke = state.events[other_event.stroke_id]; |
|
stroke.deleted = false; |
|
if (!options.skip_bvh) { |
|
bvh_undelete_stroke(state, stroke); |
|
} |
|
need_draw = true; |
|
break; |
|
} |
|
|
|
default: { |
|
console.error('cant undo event type', other_event.type); |
|
break; |
|
} |
|
} |
|
|
|
if (!skipped) { |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return need_draw; |
|
} |
|
|
|
function redo() { |
|
console.log('TODO'); |
|
}
|
|
|