This also uses the new API exposed by MidiViewBackground so that the header simply re-uses
the same exact position & height values computed by the background for its note lines.
PianoRollHeaderBase is the base class with the shared implementation.
PianoRollHeader is the GTK widget derived class.
ArdourCanvas::PianoRollHeader is the canvas item derived class.
Both PianoRollHeader implementations have to implement various methods that gloss
over the differences between drawing and event handling in a GTK widget context
or in a canvas item context
1. use a RectSet instead of a LineSet to draw note lines. Cairo provides
different coordinate -> pixel coloration rules for rectangles than for lines,
and it makes more sense in this case to use rectangles rather than fat lines.
2. change ::draw_note_lines() to ::setup_note_lines() since the method
doesn't actually draw anything.
This includes note heights, note positions, contents height
for streamviews, positions of tracks. It makes zero sense to think of these as
having potentially fractional positions.
In addition, fractional note heights and positions lead to numerous
errors drawing MIDI stuff at the pixel level.
1. do the math when we add a new coord, not at every render call
2. correctly decide whether to force an odd-width line on an integer
coordinate to a half pixel, or an even-width line on a non-integer
coordinate to a whole pixel.
a collection of rectangles, conceptually similar to LineSet
this avoids keeping around N different Canvas::Rectangles and instead
collapses a related set of them down to a single item
FLAC files are either read-only or write-only.
When recording the GUI may ask for additional data to render.
Depending on zoom level, this may require seeking in the audio
data, which in case of FLAC is not possible, and should fail silently:
ARDOUR::SndFileSource::read_unlocked()
ARDOUR::AudioRegion::read_peaks()
ArdourWaveView::WaveView::process_draw_request()
If an idle data captured callback executed AFTER the code trigger by capture
end, it would call ::begin_write() which would end up calling clear_events()
which would delete all notes in the correctly setup MidiView.
Now, the idle data capture callback no longer does anything of significance if
the TriggerBox is not actively recording. In addition, we do not call
begin_write() in the MidiView if it is not already set up for capture
display (this is triggered by changes in the TriggerBox's record enable state
and the first data captured callback from an RT thread. Further,
::begin_write(), if called, only deletes notes that were in
_active_notes (though this should probably never happen).