From 5bcb9adbf801f436c17932e75915c160c7ced33f Mon Sep 17 00:00:00 2001 From: nick_m Date: Mon, 21 Nov 2016 04:02:21 +1100 Subject: rework mouse hit creation (percussive mode) - mostly as per #7130. - snap behaviour is round to nearest - holding down button 1 while dragging creates many (if not already present) hits. --- gtk2_ardour/editor_drag.cc | 94 +++++++++++++++++++++++++++++++++++++++++ gtk2_ardour/midi_region_view.cc | 14 ++++-- 2 files changed, 105 insertions(+), 3 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index bc082e9c8c..6a663daf9f 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6333,6 +6333,100 @@ NoteCreateDrag::aborted (bool) } +PercussiveCreateDrag::PercussiveCreateDrag (Editor* e, ArdourCanvas::Item* i, MidiRegionView* rv) + : Drag (e, i) + , _region_view (rv) + , _y (0.0) +{ +} + +PercussiveCreateDrag::~PercussiveCreateDrag () +{ +} + +framecnt_t +PercussiveCreateDrag::grid_frames (framepos_t t) const +{ + bool success; + Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, t); + if (!success) { + grid_beats = Evoral::Beats(1); + } + const Evoral::Beats t_beats = _region_view->region_frames_to_region_beats (t); + + return _region_view->region_beats_to_region_frames (t_beats + grid_beats) + - _region_view->region_beats_to_region_frames (t_beats); + +} + +void +PercussiveCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) +{ + Drag::start_grab (event, cursor); + + TempoMap& map (_editor->session()->tempo_map()); + + const framepos_t pf = _drags->current_pointer_frame (); + const int32_t divisions = _editor->get_grid_music_divisions (event->button.state); + + bool success = false; + Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, pf); + if (!success) { + grid_beats = Evoral::Beats(1); + } + + const double eqaf = map.exact_qn_at_frame (pf, divisions); + const framepos_t start = map.frame_at_quarter_note (eqaf) - _region_view->region()->position(); + + MidiStreamView* sv = _region_view->midi_stream_view (); + _y = sv->note_to_y (sv->y_to_note (y_to_region (event->button.y))); + + _region_view->create_note_at (start, _y, grid_beats, event->button.state, false); +} + +void +PercussiveCreateDrag::motion (GdkEvent* event, bool) +{ + TempoMap& map (_editor->session()->tempo_map()); + + const framepos_t pf = _drags->current_pointer_frame (); + const int32_t divisions = _editor->get_grid_music_divisions (event->button.state); + const double eqaf = map.exact_qn_at_frame (pf, divisions); + const framepos_t start = map.frame_at_quarter_note (eqaf) - _region_view->region()->position (); + + MidiStreamView* sv = _region_view->midi_stream_view (); + _y = sv->note_to_y (sv->y_to_note (y_to_region (event->button.y))); + + bool success = false; + Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, pf); + if (!success) { + grid_beats = Evoral::Beats(1); + } + + _region_view->create_note_at (start, _y, grid_beats, event->button.state, false); + +} + +void +PercussiveCreateDrag::finished (GdkEvent* /* ev */, bool /* had_movement */) +{ + +} + +double +PercussiveCreateDrag::y_to_region (double y) const +{ + double x = 0; + _region_view->get_canvas_group()->canvas_to_item (x, y); + return y; +} + +void +PercussiveCreateDrag::aborted (bool) +{ + // umm.. +} + CrossfadeEdgeDrag::CrossfadeEdgeDrag (Editor* e, AudioRegionView* rv, ArdourCanvas::Item* i, bool start_yn) : Drag (e, i) , arv (rv) diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 0ae27f4698..7d8082964a 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -497,13 +497,20 @@ MidiRegionView::button_press (GdkEventButton* ev) if (_mouse_state != SelectTouchDragging) { _pressed_button = ev->button; - _mouse_state = Pressed; if (m == MouseDraw || (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()))) { - editor->drags()->set (new NoteCreateDrag (dynamic_cast (editor), group, this), (GdkEvent *) ev); + + if (midi_view()->note_mode() == Percussive) { + editor->drags()->set (new PercussiveCreateDrag (dynamic_cast (editor), group, this), (GdkEvent *) ev); + } else { + editor->drags()->set (new NoteCreateDrag (dynamic_cast (editor), group, this), (GdkEvent *) ev); + } + _mouse_state = AddDragging; remove_ghost_note (); hide_verbose_cursor (); + } else { + _mouse_state = Pressed; } return true; @@ -3745,7 +3752,8 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state) framepos_t const unsnapped_frame = editor.pixel_to_sample (x); const int32_t divisions = editor.get_grid_music_divisions (state); - const Evoral::Beats snapped_beats = snap_frame_to_grid_underneath (unsnapped_frame, divisions, true); + const bool shift_snap = midi_view()->note_mode() != Percussive; + const Evoral::Beats snapped_beats = snap_frame_to_grid_underneath (unsnapped_frame, divisions, shift_snap); /* ghost note may have been snapped before region */ if (_ghost_note && snapped_beats.to_double() < 0.0) { -- cgit v1.2.3