diff options
author | nick_m <mainsbridge@gmail.com> | 2017-02-05 05:02:01 +1100 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2017-02-05 05:02:01 +1100 |
commit | 5031bdcf10bf7dbc8521598f3a60a0285b9abe1b (patch) | |
tree | 7ac0a6c5bddb47925878abe9c5e3d518af3c61f4 /gtk2_ardour/midi_region_view.cc | |
parent | fac04afbba35976dbf13a0e0c298b8af6f42a70f (diff) |
midi note drags are music-based.
- wysiwyg (during drag) when dragging more than one note across
a tempo change.
- introduces a muscal equivalent of snap_delta (only used for
note drags atm)
- split earliest note in selection into a separate function
- MRV::copy_selection() returns the equivalent _primary note
to avoid offset hell.
- RV::snap_frame_to_frame returns a MusicFrame
- prevent note drag moving before region start.
Diffstat (limited to 'gtk2_ardour/midi_region_view.cc')
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 80 |
1 files changed, 51 insertions, 29 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index da7f1a54b5..f9c088448e 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -2549,11 +2549,9 @@ MidiRegionView::add_to_selection (NoteBase* ev) } } -void -MidiRegionView::move_selection(double dx, double dy, double cumulative_dy) +Evoral::Beats +MidiRegionView::earliest_in_selection () { - typedef vector<boost::shared_ptr<NoteType> > PossibleChord; - PossibleChord to_play; Evoral::Beats earliest = Evoral::MaxBeats; for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { @@ -2562,10 +2560,27 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy) } } + return earliest; +} + +void +MidiRegionView::move_selection(double dx_qn, double dy, double cumulative_dy) +{ + typedef vector<boost::shared_ptr<NoteType> > PossibleChord; + Editor* editor = dynamic_cast<Editor*> (&trackview.editor()); + TempoMap& tmap (editor->session()->tempo_map()); + PossibleChord to_play; + Evoral::Beats earliest = earliest_in_selection(); + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { - if ((*i)->note()->time() == earliest) { - to_play.push_back ((*i)->note()); + NoteBase* n = *i; + if (n->note()->time() == earliest) { + to_play.push_back (n->note()); } + double const note_time_qn = session_relative_qn (n->note()->time().to_double()); + double const dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn)) + - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x; + (*i)->move_event(dx, dy); } @@ -2593,15 +2608,17 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy) } NoteBase* -MidiRegionView::copy_selection () +MidiRegionView::copy_selection (NoteBase* primary) { - NoteBase* note; _copy_drag_events.clear (); if (_selection.empty()) { return 0; } + NoteBase* note; + NoteBase* ret = 0; + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { boost::shared_ptr<NoteType> g (new NoteType (*((*i)->note()))); if (midi_view()->note_mode() == Sustained) { @@ -2614,29 +2631,34 @@ MidiRegionView::copy_selection () note = h; } + if ((*i) == primary) { + ret = note; + } + _copy_drag_events.push_back (note); } - return _copy_drag_events.front (); + return ret; } void -MidiRegionView::move_copies (double dx, double dy, double cumulative_dy) +MidiRegionView::move_copies (double dx_qn, double dy, double cumulative_dy) { typedef vector<boost::shared_ptr<NoteType> > PossibleChord; + Editor* editor = dynamic_cast<Editor*> (&trackview.editor()); + TempoMap& tmap (editor->session()->tempo_map()); PossibleChord to_play; - Evoral::Beats earliest = Evoral::MaxBeats; + Evoral::Beats earliest = earliest_in_selection(); for (CopyDragEvents::iterator i = _copy_drag_events.begin(); i != _copy_drag_events.end(); ++i) { - if ((*i)->note()->time() < earliest) { - earliest = (*i)->note()->time(); + NoteBase* n = *i; + if (n->note()->time() == earliest) { + to_play.push_back (n->note()); } - } + double const note_time_qn = session_relative_qn (n->note()->time().to_double()); + double const dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn)) + - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x; - for (CopyDragEvents::iterator i = _copy_drag_events.begin(); i != _copy_drag_events.end(); ++i) { - if ((*i)->note()->time() == earliest) { - to_play.push_back ((*i)->note()); - } (*i)->move_event(dx, dy); } @@ -2664,7 +2686,7 @@ MidiRegionView::move_copies (double dx, double dy, double cumulative_dy) } void -MidiRegionView::note_dropped(NoteBase *, frameoffset_t dt, int8_t dnote, bool copy) +MidiRegionView::note_dropped(NoteBase *, double d_qn, int8_t dnote, bool copy) { uint8_t lowest_note_in_selection = 127; uint8_t highest_note_in_selection = 0; @@ -2693,15 +2715,13 @@ MidiRegionView::note_dropped(NoteBase *, frameoffset_t dt, int8_t dnote, bool co if (highest_note_in_selection + dnote > 127) { highest_note_difference = highest_note_in_selection - 127; } - TempoMap& map (trackview.session()->tempo_map()); start_note_diff_command (_("move notes")); for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ++i) { - double const start_qn = _region->quarter_note() - midi_region()->start_beats(); - framepos_t new_frames = map.frame_at_quarter_note (start_qn + (*i)->note()->time().to_double()) + dt; - Evoral::Beats new_time = Evoral::Beats (map.quarter_note_at_frame (new_frames) - start_qn); + Evoral::Beats new_time = Evoral::Beats (max ((*i)->note()->time().to_double() + d_qn, midi_region()->start_beats())); + if (new_time < 0) { continue; } @@ -2734,16 +2754,12 @@ MidiRegionView::note_dropped(NoteBase *, frameoffset_t dt, int8_t dnote, bool co highest_note_difference = highest_note_in_selection - 127; } - TempoMap& map (trackview.session()->tempo_map()); start_note_diff_command (_("copy notes")); for (CopyDragEvents::iterator i = _copy_drag_events.begin(); i != _copy_drag_events.end() ; ++i) { /* update time */ - - double const start_qn = _region->quarter_note() - midi_region()->start_beats(); - framepos_t new_frames = map.frame_at_quarter_note (start_qn + (*i)->note()->time().to_double()) + dt; - Evoral::Beats new_time = Evoral::Beats (map.quarter_note_at_frame (new_frames) - start_qn); + Evoral::Beats new_time = Evoral::Beats (max ((*i)->note()->time().to_double() + d_qn, midi_region()->start_beats())); if (new_time < 0) { continue; @@ -2790,7 +2806,7 @@ framepos_t MidiRegionView::snap_pixel_to_sample(double x, bool ensure_snap) { PublicEditor& editor (trackview.editor()); - return snap_frame_to_frame (editor.pixel_to_sample (x), ensure_snap); + return snap_frame_to_frame (editor.pixel_to_sample (x), ensure_snap).frame; } /** @param x Pixel relative to the region position. @@ -4369,3 +4385,9 @@ MidiRegionView::note_to_y(uint8_t note) const { return contents_height() - (note + 1 - _current_range_min) * note_height() + 1; } + +double +MidiRegionView::session_relative_qn (double qn) const +{ + return qn + (region()->quarter_note() - midi_region()->start_beats()); +} |