I have been working on adding commands to Butter, which is making use of the UndoManager discussed earlier. I talked more about it in the blog post, “DPS911 Release 6”, stating that the following items still need to be completed
- putting the code in the right place
- adding more commands
- adding shortcuts to command objects
I have now added 9 tests that make sure that the UndoManager is working correctly. I have also moved the code from butter-main.js, which is now just called main.js, to a new file named src/core/commands.js. For now, all of the commands and convenience functions are in this file. I have added more command objects, and now Butter can undo and redo the following
- adding track events
- removing track events
- adding tracks
- removing tracks
- changing the media url
All of the commits are here, and the diff is here. This is definitely my biggest patch that I have submitted to Butter, which is, so far, 399 additions and 21 deletions. There is still work that needs to be done. For the new code introduced to work cleanly, I still need to create a diagram of how all of this will work. Before I can do that, though, I need a diagram of Butter’s current design. Once the diagram is complete, everyone can see from a high level how objects interact with each other, and we can develop a workflow of what needs to be done when a new command needs to be created.
Implementing undo and redo for adding and removing a track was interesting, because when I deleted the first track and then undid the change, it was added as the last track. The problem ended up being an ordering issue, and I had to change a bit of code in a few areas. In the addTrack function in src/core/media.js, I added another argument, named order. If order is passed in, then that is the value that is set on the track. To actually make the the ordering work, I changed the code in src/timeline/track-container.js and src/timeline/trackhandles.js to use the insertBefore function rather than append on the container element. For example, src/core/trackhandles.js has the following code:
_listElement.insertBefore( trackDiv, _listElement.children[ e.data.order ] );
While testing out the undoing and redoing of adding/removing track events, I noticed a bug. The command object that is responsible for adding a track event was creating a new track event every time it was told to execute. This caused some weird behaviour, which took some digging to find. The fix was simply to create a new track event based on the one that was previously created instead of always creating a fresh one.
There is not enough time for this to be 100% complete before the semester, especially since I need to wait for a diagram to be created, and the new code still needs to go through review. However, I do plan on finishing this, because I would like to see it land in Butter, so that users can work on their projects knowing that they can undo and redo their changes.