From 3a9cc83e788e21ec443750295e12249a465ab625 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Mon, 11 Oct 2021 16:10:04 -0700 Subject: [PATCH] Bugfix: Undo/Redo works for the Doodad Editor Changed dependencies around so the undo/redo feature works on doodads as well as levels. --- pkg/doodads/doodad.go | 7 ++++++- pkg/uix/canvas.go | 2 ++ pkg/uix/canvas_editable.go | 2 ++ pkg/uix/canvas_strokes.go | 26 ++++++++++++++++++-------- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/pkg/doodads/doodad.go b/pkg/doodads/doodad.go index 10d07ad..51a3788 100644 --- a/pkg/doodads/doodad.go +++ b/pkg/doodads/doodad.go @@ -2,6 +2,7 @@ package doodads import ( "git.kirsle.net/apps/doodle/pkg/balance" + "git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/go/render" @@ -17,6 +18,9 @@ type Doodad struct { Hitbox render.Rect `json:"hitbox"` Layers []Layer `json:"layers"` Tags map[string]string `json:"data"` // arbitrary key/value data storage + + // Undo history, temporary live data not persisted to the level file. + UndoHistory *drawtool.History `json:"-" msgpack:"-"` } // Layer holds a layer of drawing data for a Doodad. @@ -43,7 +47,8 @@ func New(size int) *Doodad { Chunker: level.NewChunker(size), }, }, - Tags: map[string]string{}, + Tags: map[string]string{}, + UndoHistory: drawtool.NewHistory(balance.UndoHistory), } } diff --git a/pkg/uix/canvas.go b/pkg/uix/canvas.go index 2cede8c..fc8eb43 100644 --- a/pkg/uix/canvas.go +++ b/pkg/uix/canvas.go @@ -54,6 +54,7 @@ type Canvas struct { // Underlying chunk data for the drawing. level *level.Level chunks *level.Chunker + doodad *doodads.Doodad modified bool // set to True when the drawing has been modified, like in Editor Mode. // Actors to superimpose on top of the drawing. @@ -179,6 +180,7 @@ func (w *Canvas) LoadLevel(level *level.Level) { // LoadDoodad initializes a Canvas from a Doodad object. func (w *Canvas) LoadDoodad(d *doodads.Doodad) { // TODO more safe + w.doodad = d w.Load(d.Palette, d.Layers[0].Chunker) } diff --git a/pkg/uix/canvas_editable.go b/pkg/uix/canvas_editable.go index 14b1d88..f72f519 100644 --- a/pkg/uix/canvas_editable.go +++ b/pkg/uix/canvas_editable.go @@ -106,6 +106,8 @@ func (w *Canvas) commitStroke(tool drawtool.Tool, addHistory bool) { // Add the stroke to level history. if w.level != nil && addHistory { w.level.UndoHistory.AddStroke(w.currentStroke) + } else if w.doodad != nil && addHistory { + w.doodad.UndoHistory.AddStroke(w.currentStroke) } w.RemoveStroke(w.currentStroke) diff --git a/pkg/uix/canvas_strokes.go b/pkg/uix/canvas_strokes.go index fc575e8..350b415 100644 --- a/pkg/uix/canvas_strokes.go +++ b/pkg/uix/canvas_strokes.go @@ -42,12 +42,17 @@ func (w *Canvas) RemoveStroke(stroke *drawtool.Stroke) bool { // added to the level. Returns false and emits a warning to the log if the // canvas has no level loaded properly. func (w *Canvas) UndoStroke() bool { - if w.level == nil { - log.Error("Canvas.UndoStroke: no Level currently available to the canvas") + var undoer *drawtool.History + if w.level != nil { + undoer = w.level.UndoHistory + } else if w.doodad != nil { + undoer = w.doodad.UndoHistory + } else { + log.Error("Canvas.UndoStroke: no Level or Doodad currently available to the canvas") return false } - latest := w.level.UndoHistory.Latest() + latest := undoer.Latest() if latest != nil { // TODO: only single-thickness lines will restore the original color; // thick lines just delete their pixels from the world due to performance. @@ -93,23 +98,28 @@ func (w *Canvas) UndoStroke() bool { } } - return w.level.UndoHistory.Undo() + return undoer.Undo() } // RedoStroke rolls the level's UndoHistory forwards again and replays the // recently undone changes. func (w *Canvas) RedoStroke() bool { - if w.level == nil { - log.Error("Canvas.UndoStroke: no Level currently available to the canvas") + var undoer *drawtool.History + if w.level != nil { + undoer = w.level.UndoHistory + } else if w.doodad != nil { + undoer = w.doodad.UndoHistory + } else { + log.Error("Canvas.UndoStroke: no Level or Doodad currently available to the canvas") return false } - ok := w.level.UndoHistory.Redo() + ok := undoer.Redo() if !ok { return false } - latest := w.level.UndoHistory.Latest() + latest := undoer.Latest() // We stored the ActiveSwatch on this stroke as we drew it. Recover it // and place the pixels back down.