summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-02-28 04:00:38 +0000
committerCarl Hetherington <carl@carlh.net>2011-02-28 04:00:38 +0000
commitc75b17e3bab17b852ab69868bbfdffd7ad1f73bf (patch)
tree06d25a67352757a16ee1592e1bc23de49e19c564
parent60f48d24f40e6d73b1ccf5dc2885d45570626212 (diff)
Update ghost MIDI regions in automation tracks when zoom changes. Fixes #3803.
git-svn-id: svn://localhost/ardour2/branches/3.0@8985 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ghostregion.cc50
-rw-r--r--gtk2_ardour/ghostregion.h6
-rw-r--r--gtk2_ardour/midi_region_view.cc18
-rw-r--r--gtk2_ardour/midi_region_view.h2
4 files changed, 73 insertions, 3 deletions
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<Note *> (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<MidiGhostRegion::Event*> 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<NoteType> 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<NoteType> 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<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*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<NoteType>);
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);