Flip History Strategy Guide

Handling a Gesture

This chapter shows to implement a simple gesture, that is an undo step that relates to multiple commits of the document.

Overview

One common modifications of the document occurs over a gesture. That is, the actual modification of the document integrates multiple commits, but the undo step and publication to the outside world happens once the gesture is said to be "finished".

Example of such modifications are :

The general idea of the modifications is that it spans over time. In this case the document is modified gradually as the gesture is performed. This allows on each commit to notify the observers so that the document views show an up-to-date of the document, even if this does not make the actual undo step stored in the history.

Implementation

The following code illustrates a modification of the document such as a mouse gesture to change gradually the tempo of a song.

Document document (Model::use (), 123456789UL, 'appl', 'gui ');
Carrier carrier (document);   (1)
History <HistoryStoreMemory> history (document);
Song & song = document.root <Song> ();
[...]
song.tempo = 120.0;
document.commit ();           (2)
[...]
song.tempo = 130.0;
document.commit ();           (2)
[...]
song.tempo = 140.0;
document.commit ();           (2)
[...]
auto tx = document.squash (); (3)
history.add_undo_step (tx);   (4)
document.push ();             (5)
  1. Squash only works when the document is connected to a carrier
  2. Modify the document gradually and commit to notify observer
  3. Squash the push stack to make a single transaction out of the multiple commits
  4. Store this resulting transaction in an undo step
  5. Typically, the client of the library would advertise this document modification to the outside world at that moment

The next chapter, Handling a Non-deterministic Gesture will show a strategy to use for undo/redo in the case of a more complex gesture.