diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc index 4c2f17d29d..4cb14f661a 100644 --- a/gtk2_ardour/ghostregion.cc +++ b/gtk2_ardour/ghostregion.cc @@ -163,6 +163,7 @@ AudioGhostRegion::set_colors () */ MidiGhostRegion::MidiGhostRegion(TimeAxisView& tv, TimeAxisView& source_tv, double initial_unit_pos) : GhostRegion(tv.ghost_group(), tv, source_tv, initial_unit_pos) + , _optimization_iterator (events.end ()) { base_rect->lower_to_bottom(); update_range (); @@ -176,6 +177,7 @@ MidiGhostRegion::MidiGhostRegion(TimeAxisView& tv, TimeAxisView& source_tv, doub */ MidiGhostRegion::MidiGhostRegion(MidiStreamView& msv, TimeAxisView& source_tv, double initial_unit_pos) : GhostRegion(msv.midi_underlay_group, msv.trackview(), source_tv, initial_unit_pos) + , _optimization_iterator (events.end ()) { base_rect->lower_to_bottom(); update_range (); @@ -322,3 +324,51 @@ MidiGhostRegion::clear_events() events.clear(); } +/** Update the x positions of our representation of a parent's note. + * @param parent The CanvasNote from the parent MidiRegionView. + */ +void +MidiGhostRegion::update_note (ArdourCanvas::CanvasNote* parent) +{ + Event* ev = find_event (parent); + if (!ev) { + return; + } + + Note* note = dynamic_cast (ev); + if (note) { + double const x1 = parent->property_x1 (); + double const x2 = parent->property_x2 (); + note->rect->property_x1 () = x1; + note->rect->property_x2 () = x2; + } +} + +/** Given a note in our parent region (ie the actual MidiRegionView), find our + * representation of it. + * @return Our Event, or 0 if not found. + */ + +MidiGhostRegion::Event * +MidiGhostRegion::find_event (ArdourCanvas::CanvasNote* parent) +{ + /* we are using _optimization_iterator to speed up the common case where a caller + is going through our notes in order. + */ + + if (_optimization_iterator != events.end()) { + ++_optimization_iterator; + } + + if (_optimization_iterator != events.end() && (*_optimization_iterator)->event == parent) { + return *_optimization_iterator; + } + + for (_optimization_iterator = events.begin(); _optimization_iterator != events.end(); ++_optimization_iterator) { + if ((*_optimization_iterator)->event == parent) { + return *_optimization_iterator; + } + } + + return 0; +} diff --git a/gtk2_ardour/ghostregion.h b/gtk2_ardour/ghostregion.h index f0198e3b17..a4e4b893f1 100644 --- a/gtk2_ardour/ghostregion.h +++ b/gtk2_ardour/ghostregion.h @@ -113,11 +113,17 @@ public: void add_note(ArdourCanvas::CanvasNote*); void add_hit(ArdourCanvas::CanvasHit*); + void update_note (ArdourCanvas::CanvasNote *); void clear_events(); +private: + + MidiGhostRegion::Event* find_event (ArdourCanvas::CanvasNote *); + typedef std::list EventList; EventList events; + EventList::iterator _optimization_iterator; }; #endif /* __ardour_gtk_ghost_region_h__ */ diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index e76433bcae..f7b9c8f9e0 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1457,8 +1457,12 @@ MidiRegionView::note_in_region_range(const boost::shared_ptr note, boo return !outside; } +/** Update a canvas note's size from its model note. + * @param ev Canvas note to update. + * @param update_ghost_regions true to update the note in any ghost regions that we have, otherwise false. + */ void -MidiRegionView::update_note (CanvasNote* ev) +MidiRegionView::update_note (CanvasNote* ev, bool update_ghost_regions) { boost::shared_ptr note = ev->note(); @@ -1501,6 +1505,15 @@ MidiRegionView::update_note (CanvasNote* ev) /* outline all edges */ ev->property_outline_what() = (guint32) 0xF; } + + if (update_ghost_regions) { + for (std::vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + MidiGhostRegion* gr = dynamic_cast (*i); + if (gr) { + gr->update_note (ev); + } + } + } } double @@ -3148,7 +3161,8 @@ MidiRegionView::update_ghost_note (double x, double y) _ghost_note->note()->set_length (length); _ghost_note->note()->set_note (midi_stream_view()->y_to_note (y)); - update_note (_ghost_note); + /* the ghost note does not appear in ghost regions, so pass false in here */ + update_note (_ghost_note, false); show_verbose_canvas_cursor (_ghost_note->note ()); } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index edf418afb4..d7634141fb 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -409,7 +409,7 @@ class MidiRegionView : public RegionView ArdourCanvas::CanvasNoteEvent* find_canvas_note (boost::shared_ptr); Events::iterator _optimization_iterator; - void update_note (ArdourCanvas::CanvasNote*); + void update_note (ArdourCanvas::CanvasNote *, bool update_ghost_regions = true); double update_hit (ArdourCanvas::CanvasHit *); void create_ghost_note (double, double); void update_ghost_note (double, double);