I’m trying to write a piano roll, but I’m not sure what would be a nice design to do so. Maybe asking here is a bit outside of the scope of the forum, but I reckon there’s a good chance someone else did the same thing before me.
My initial guess would be to make a big PianoRollComponent that has a number of NoteComponent children and lives inside a Viewport.
One concern here is possibly having loads of child components; however my immediate concern is the following:
I figured my data could simply be a wrapper around MidiMessageSequence that notifies Listeners on changes so that data and GUI are automatically kept in sync.
I imagine an edit sequence to look something like this:
- Mouse event handling in NoteComponent, modifies MidiMessageSequence data through wrapper, which notifies listeners telling which event changed.
- PianoRollComponent listens for event changes and updates the NoteComponent corresponding to the changed event.
This sounds good but step 2 requires me to maintain a map between events in the MidiMessageSequence and corresponding NoteComponents; which doesn’t seem right (and requires a MidiMessageSequence alternative that doesn’t invalidate iterators or has some event id).
Another option would be to have PianoRollComponent do all drawing of notes and corresponding mouse handling itself, and on changes to the data simply redraw the entire visible area. Or the same thing but destroying/creating NoteComponents for every change to the data or the Viewport’s visible area.
Anybody got a nice solution?