Working undo
This commit is contained in:
parent
1c622da928
commit
3251e2f03b
|
@ -235,7 +235,7 @@ func _input(event: InputEvent) -> void:
|
|||
sel_col = int(gridpos.x)
|
||||
drag_action = DragAction.DRAW_COLOR
|
||||
drag_color = posmod(cell_colors.get_cell(sel_row, sel_col) + (1 if event.button_index==BUTTON_LEFT else -1), N_COLORS)
|
||||
cell_colors.set_cell(sel_row, sel_col, drag_color)
|
||||
set_cell_color(sel_row, sel_col, drag_color)
|
||||
|
||||
elif event is InputEventMouseMotion and event.button_mask:
|
||||
if drag_action == DragAction.TEST_LINE:
|
||||
|
@ -268,99 +268,134 @@ func _input(event: InputEvent) -> void:
|
|||
sel_row = int(gridpos.y)
|
||||
sel_col = int(gridpos.x)
|
||||
set_cell_color(sel_row, sel_col, drag_color)
|
||||
elif event is InputEventKey and event.pressed:
|
||||
match event.scancode:
|
||||
KEY_Z:
|
||||
undo()
|
||||
|
||||
var undo_stack = []
|
||||
|
||||
class UndoAction:
|
||||
var action_type
|
||||
var cell_row
|
||||
var cell_col
|
||||
var cell_row: int
|
||||
var cell_col: int
|
||||
var activated: bool
|
||||
func _init(action, row, col) -> void:
|
||||
action_type = action
|
||||
cell_row = row
|
||||
cell_col = col
|
||||
activated = false
|
||||
|
||||
class UndoActionCorner extends UndoAction:
|
||||
func _init(action, row, col).(action, row, col) -> void:
|
||||
pass
|
||||
var corner_marks
|
||||
var corner_mark
|
||||
var set: bool # False = clear
|
||||
func _init(row, col, corner_mark, set, corner_marks).(corner_mark, row, col) -> void:
|
||||
self.corner_marks = corner_marks
|
||||
self.corner_mark = corner_mark
|
||||
self.set = set
|
||||
|
||||
func _to_string() -> String:
|
||||
match action_type:
|
||||
UndoActions.SET_L_RIGHT:
|
||||
return '+L %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
UndoActions.CLEAR_L_RIGHT:
|
||||
return '-L %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
UndoActions.SET_X_RIGHT:
|
||||
return '+X %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
UndoActions.CLEAR_X_RIGHT:
|
||||
return '-X %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
UndoActions.SET_L_DOWN:
|
||||
return '+L %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
UndoActions.CLEAR_L_DOWN:
|
||||
return '-L %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
UndoActions.SET_X_DOWN:
|
||||
return '+X %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
UndoActions.CLEAR_X_DOWN:
|
||||
return '-X %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
var prefix = '+' if set else '-'
|
||||
match corner_mark:
|
||||
CornerMark.L_RIGHT:
|
||||
return prefix+'L %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
CornerMark.X_RIGHT:
|
||||
return prefix+'X %s%d:%d'%[Common.num2alpha(cell_col), cell_row-1, cell_row]
|
||||
CornerMark.L_DOWN:
|
||||
return prefix+'L %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
CornerMark.X_DOWN:
|
||||
return prefix+'X %s%d:%s'%[Common.num2alpha(cell_col-1), cell_row, Common.num2alpha(cell_col)]
|
||||
_:
|
||||
return 'unk %d %s%d'%[action_type, Common.num2alpha(cell_col), cell_row]
|
||||
return 'unk %s%d %s%d'%[prefix, corner_mark, Common.num2alpha(cell_col), cell_row]
|
||||
|
||||
func activate() -> void:
|
||||
activated = true
|
||||
if set:
|
||||
corner_marks.set_flag(cell_row, cell_col, corner_mark)
|
||||
else:
|
||||
corner_marks.clear_flag(cell_row, cell_col, corner_mark)
|
||||
|
||||
func undo() -> void:
|
||||
activated = false
|
||||
if set:
|
||||
corner_marks.clear_flag(cell_row, cell_col, corner_mark)
|
||||
else:
|
||||
corner_marks.set_flag(cell_row, cell_col, corner_mark)
|
||||
|
||||
class UndoActionCell extends UndoAction:
|
||||
var set_state
|
||||
var prev_state
|
||||
func _init(action, row, col, set_state, prev_state).(action, row, col) -> void:
|
||||
var old_state
|
||||
var cell_colors
|
||||
func _init(action, row, col, set_state, cell_colors).(action, row, col) -> void:
|
||||
self.set_state = set_state
|
||||
self.prev_state = prev_state
|
||||
self.old_state = set_state
|
||||
self.cell_colors = cell_colors
|
||||
|
||||
func _to_string() -> String:
|
||||
match action_type:
|
||||
UndoActions.SET_COLOR:
|
||||
return 'C%d->%d %s%d'%[set_state, prev_state, Common.num2alpha(cell_col), cell_row]
|
||||
return 'C%d<-%d %s%d'%[set_state, old_state, Common.num2alpha(cell_col), cell_row]
|
||||
_:
|
||||
return 'unk %d %s%d'%[action_type, Common.num2alpha(cell_col), cell_row]
|
||||
|
||||
func set_cell_color(row, col, new_color):
|
||||
var old_color = cell_colors.get_cell(row, col)
|
||||
if old_color != new_color:
|
||||
cell_colors.set_cell(row, col, new_color)
|
||||
undo_stack.append(UndoActionCell.new(UndoActions.SET_COLOR, row, col, new_color, old_color))
|
||||
func activate() -> void:
|
||||
assert(not activated)
|
||||
activated = true
|
||||
match action_type:
|
||||
UndoActions.SET_COLOR:
|
||||
old_state = cell_colors.get_cell(cell_row, cell_col)
|
||||
cell_colors.set_cell(cell_row, cell_col, set_state)
|
||||
|
||||
func undo() -> void:
|
||||
assert(activated)
|
||||
activated = false
|
||||
match action_type:
|
||||
UndoActions.SET_COLOR:
|
||||
cell_colors.set_cell(cell_row, cell_col, old_state)
|
||||
|
||||
func do_action(action):
|
||||
action.activate()
|
||||
undo_stack.append(action)
|
||||
|
||||
func undo():
|
||||
if !undo_stack.empty():
|
||||
var action = undo_stack.pop_back()
|
||||
action.undo()
|
||||
|
||||
func set_cell_color(row, col, new_color):
|
||||
if new_color != cell_colors.get_cell(row, col):
|
||||
do_action(UndoActionCell.new(UndoActions.SET_COLOR, row, col, new_color, cell_colors))
|
||||
|
||||
# TODO: Refactor all this nonsense a bit more
|
||||
func set_line_right(row, col):
|
||||
if !corner_marks.get_flag(row, col, CornerMark.L_RIGHT) and !corner_marks.get_flag(row, col, CornerMark.X_RIGHT):
|
||||
corner_marks.set_flag(row, col, CornerMark.L_RIGHT)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.SET_L_RIGHT, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.L_RIGHT, true, corner_marks))
|
||||
|
||||
func set_line_down(row, col):
|
||||
if !corner_marks.get_flag(row, col, CornerMark.L_DOWN) and !corner_marks.get_flag(row, col, CornerMark.X_DOWN):
|
||||
corner_marks.set_flag(row, col, CornerMark.L_DOWN)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.SET_L_DOWN, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.L_DOWN, true, corner_marks))
|
||||
|
||||
func clear_line_right(row, col):
|
||||
if corner_marks.get_flag(row, col, CornerMark.L_RIGHT):
|
||||
corner_marks.clear_flag(row, col, CornerMark.L_RIGHT)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_L_RIGHT, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.L_RIGHT, false, corner_marks))
|
||||
|
||||
func clear_line_down(row, col):
|
||||
if corner_marks.get_flag(row, col, CornerMark.L_DOWN):
|
||||
corner_marks.clear_flag(row, col, CornerMark.L_DOWN)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_L_DOWN, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.L_DOWN, false, corner_marks))
|
||||
|
||||
func set_x_right(row, col):
|
||||
if !corner_marks.get_flag(row, col, CornerMark.L_RIGHT) and !corner_marks.get_flag(row, col, CornerMark.X_RIGHT):
|
||||
corner_marks.set_flag(row, col, CornerMark.X_RIGHT)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.SET_X_RIGHT, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.X_RIGHT, true, corner_marks))
|
||||
|
||||
func set_x_down(row, col):
|
||||
if !corner_marks.get_flag(row, col, CornerMark.L_DOWN) and !corner_marks.get_flag(row, col, CornerMark.X_DOWN):
|
||||
corner_marks.set_flag(row, col, CornerMark.X_DOWN)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.SET_X_DOWN, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.X_DOWN, true, corner_marks))
|
||||
|
||||
func clear_x_right(row, col):
|
||||
if corner_marks.get_flag(row, col, CornerMark.X_RIGHT):
|
||||
corner_marks.clear_flag(row, col, CornerMark.X_RIGHT)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_X_RIGHT, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.X_RIGHT, false, corner_marks))
|
||||
|
||||
func clear_x_down(row, col):
|
||||
if corner_marks.get_flag(row, col, CornerMark.X_DOWN):
|
||||
corner_marks.clear_flag(row, col, CornerMark.X_DOWN)
|
||||
undo_stack.append(UndoActionCorner.new(UndoActions.CLEAR_X_DOWN, row, col))
|
||||
do_action(UndoActionCorner.new(row, col, CornerMark.X_DOWN, false, corner_marks))
|
||||
|
|
Loading…
Reference in New Issue