+ // Display region contents
+ region_view->set_height (child_height());
+ region_view->display_model(source->model());
+}
+
+void
+MidiStreamView::display_track (boost::shared_ptr<Track> tr)
+{
+ StreamView::display_track (tr);
+
+ draw_note_lines();
+
+ NoteRangeChanged();
+}
+
+void
+MidiStreamView::update_contents_metrics(boost::shared_ptr<Region> r)
+{
+ boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(r);
+ if (mr) {
+ mr->midi_source(0)->load_model();
+ _range_dirty = update_data_note_range(
+ mr->model()->lowest_note(),
+ mr->model()->highest_note());
+ }
+}
+
+bool
+MidiStreamView::update_data_note_range(uint8_t min, uint8_t max)
+{
+ bool dirty = false;
+ if (min < _data_note_min) {
+ _data_note_min = min;
+ dirty = true;
+ }
+ if (max > _data_note_max) {
+ _data_note_max = max;
+ dirty = true;
+ }
+ return dirty;
+}
+
+void
+MidiStreamView::redisplay_track ()
+{
+ if (!_trackview.is_midi_track()) {
+ return;
+ }
+
+ list<RegionView*>::iterator i;
+
+ // Load models if necessary, and find note range of all our contents
+ _range_dirty = false;
+ _data_note_min = 127;
+ _data_note_max = 0;
+ _trackview.track()->playlist()->foreach_region(
+ sigc::mem_fun (*this, &StreamView::update_contents_metrics)
+ );
+
+ // No notes, use default range
+ if (!_range_dirty) {
+ _data_note_min = 60;
+ _data_note_max = 71;
+ }
+
+ // Extend visible range to show newly recorded data, if necessary
+ _lowest_note = std::min(_lowest_note, _data_note_min);
+ _highest_note = std::max(_highest_note, _data_note_max);
+
+ veto_note_range(_lowest_note, _highest_note);
+
+ // Flag region views as invalid and disable drawing