From e131fd391ded68c2a0634f26edb03410b5f46349 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Nov 2010 01:04:53 +0000 Subject: Put MIDI notes into their own canvas group, and reparent this group during start trims to stop the notes moving. Improves the visual display on start trim of a MIDI region. git-svn-id: svn://localhost/ardour2/branches/3.0@8080 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_drag.cc | 6 ++++++ gtk2_ardour/midi_region_view.cc | 45 +++++++++++++++++++++++++++++------------ gtk2_ardour/midi_region_view.h | 8 ++++++++ gtk2_ardour/region_view.h | 7 +++++++ 4 files changed, 53 insertions(+), 13 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 900fd0ea4c..d8d321cddc 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -1551,6 +1551,9 @@ TrimDrag::start_grab (GdkEvent* event, Gdk::Cursor*) switch (_operation) { case StartTrim: _editor->show_verbose_time_cursor (region_start, 10); + for (list::iterator i = _views.begin(); i != _views.end(); ++i) { + i->view->trim_start_starting (); + } break; case EndTrim: _editor->show_verbose_time_cursor (region_end, 10); @@ -1717,6 +1720,9 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred) } for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) { + if (_operation == StartTrim) { + i->view->trim_start_ending (); + } i->view->region()->resume_property_changes (); } } diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index a11b038db4..09262bdd19 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -87,13 +87,14 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _model_name(string()) , _custom_device_mode(string()) , _active_notes(0) - , _note_group(new ArdourCanvas::Group(*parent)) + , _note_group(new ArdourCanvas::Group(*group)) , _diff_command(0) , _ghost_note(0) , _drag_rect (0) , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) , _sort_needed (true) @@ -126,6 +127,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) , _sort_needed (true) @@ -156,6 +158,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other) , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) , _sort_needed (true) @@ -188,6 +191,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptrcontents_height(); boost::shared_ptr sysex = boost::shared_ptr( - new CanvasSysEx(*this, *group, text, height, x, 1.0)); + new CanvasSysEx(*this, *_note_group, text, height, x, 1.0)); // Show unless program change is beyond the region bounds if (time - _region->start() >= _region->length() || time < _region->start()) { @@ -1177,6 +1179,7 @@ MidiRegionView::~MidiRegionView () delete _note_group; delete _diff_command; delete _step_edit_cursor; + delete _temporary_note_group; } void @@ -1499,11 +1502,9 @@ MidiRegionView::add_note(const boost::shared_ptr note, bool visible) assert(note->time() >= 0); assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive); - ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); - if (midi_view()->note_mode() == Sustained) { - CanvasNote* ev_rect = new CanvasNote(*this, *group, note); + CanvasNote* ev_rect = new CanvasNote(*this, *_note_group, note); update_note (ev_rect); @@ -1521,7 +1522,7 @@ MidiRegionView::add_note(const boost::shared_ptr note, bool visible) const double diamond_size = midi_stream_view()->note_height() / 2.0; - CanvasHit* ev_diamond = new CanvasHit(*this, *group, diamond_size, note); + CanvasHit* ev_diamond = new CanvasHit(*this, *_note_group, diamond_size, note); update_hit (ev_diamond); @@ -1586,13 +1587,12 @@ MidiRegionView::add_pgm_change(PCEvent& program, const string& displaytext) { assert(program.time >= 0); - ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); const double x = trackview.editor().frame_to_pixel(beats_to_frames(program.time)); double height = midi_stream_view()->contents_height(); boost::shared_ptr pgm_change = boost::shared_ptr( - new CanvasProgramChange(*this, *group, + new CanvasProgramChange(*this, *_note_group, displaytext, height, x, 1.0, @@ -2202,7 +2202,7 @@ MidiRegionView::begin_resizing (bool /*at_front*/) // create a new SimpleRect from the note which will be the resize preview SimpleRect *resize_rect = new SimpleRect( - *group, note->x1(), note->y1(), note->x2(), note->y2()); + *_note_group, note->x1(), note->y1(), note->x2(), note->y2()); // calculate the colors: get the color settings uint32_t fill_color = UINT_RGBA_CHANGE_A( @@ -3004,7 +3004,7 @@ MidiRegionView::update_ghost_note (double x, double y) _last_ghost_x = x; _last_ghost_y = y; - group->w2i (x, y); + _note_group->w2i (x, y); framepos_t f = trackview.editor().pixel_to_frame (x) + _region->position (); trackview.editor().snap_to (f); f -= _region->position (); @@ -3033,7 +3033,7 @@ MidiRegionView::create_ghost_note (double x, double y) _ghost_note = 0; boost::shared_ptr g (new NoteType); - _ghost_note = new NoEventCanvasNote (*this, *group, g); + _ghost_note = new NoEventCanvasNote (*this, *_note_group, g); update_ghost_note (x, y); _ghost_note->show (); @@ -3228,3 +3228,22 @@ MidiRegionView::data_recorded (boost::shared_ptr buf, boost::weak_pt midi_stream_view()->check_record_layers (region(), back); } + +void +MidiRegionView::trim_start_starting () +{ + /* Reparent the note group to the region view's parent, so that it doesn't change + when the region view is trimmed. + */ + _temporary_note_group = new ArdourCanvas::Group (*group->property_parent ()); + _temporary_note_group->move (group->property_x(), group->property_y()); + _note_group->reparent (*_temporary_note_group); +} + +void +MidiRegionView::trim_start_ending () +{ + _note_group->reparent (*group); + delete _temporary_note_group; + _temporary_note_group = 0; +} diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 794ec867c6..de9851aa20 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -282,6 +282,9 @@ class MidiRegionView : public RegionView void selection_as_notelist (Notes& selected, bool allow_all_if_none_selected = false); void enable_display (bool); + + void trim_start_starting (); + void trim_start_ending (); protected: /** Allows derived types to specify their visibility requirements @@ -373,6 +376,11 @@ class MidiRegionView : public RegionView Evoral::MusicalTime _step_edit_cursor_width; Evoral::MusicalTime _step_edit_cursor_position; + /** A group used to temporarily reparent _note_group to during start trims, so + * that the notes don't move with the parent region view. + */ + ArdourCanvas::Group* _temporary_note_group; + MouseState _mouse_state; int _pressed_button; diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 1e8c09bdba..60de56d76f 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -96,7 +96,14 @@ class RegionView : public TimeAxisViewItem return _time_converter; } + /** Called when a start trim is about to begin */ + virtual void trim_start_starting () {} + void trim_start (framepos_t, bool); + + /** Called when a start trim has finished */ + virtual void trim_start_ending () {} + void trim_end (framepos_t, bool); void trim_contents (framepos_t, bool, bool); virtual void thaw_after_trim (); -- cgit v1.2.3