Fix bug where drawing long notes placed the new note on the previous snap line.
authornick_m <mainsbridge@gmail.com>
Thu, 22 Sep 2016 19:06:03 +0000 (05:06 +1000)
committernick_m <mainsbridge@gmail.com>
Thu, 22 Sep 2016 19:06:03 +0000 (05:06 +1000)
- NoteCreateDrag already applies this shift, so it was
  always applied twice to the note start frame.

gtk2_ardour/editor_drag.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h

index c35d1fedef25c93a33cbe9b37155f4637fc32427..f7b75a5855dee56e32f4991e194bba91b26ccebb 100644 (file)
@@ -6190,8 +6190,8 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
        const framepos_t pf = _drags->current_pointer_frame ();
        const int32_t divisions = _editor->get_grid_music_divisions (event->button.state);
 
-       const double qaf = map.quarter_note_at_frame (pf);
-       double eqaf;
+       double eqaf = map.exact_qn_at_frame (pf, divisions);
+
        if (divisions != 0) {
                bool success = false;
                Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, pf);
@@ -6199,17 +6199,16 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                        grid_beats = Evoral::Beats(1);
                }
 
-               eqaf = map.exact_qn_at_frame (pf, divisions);
+               const double qaf = map.quarter_note_at_frame (pf);
 
                /* Hack so that we always snap to the note that we are over, instead of snapping
                   to the next one if we're more than halfway through the one we're over.
                */
-               const double rem = fmod (qaf, grid_beats.to_double());
-               if (rem >= grid_beats.to_double() / 2.0) {
+
+               const double rem = eqaf - qaf;
+               if (rem >= 0.0 && eqaf - grid_beats.to_double() > _region_view->region()->pulse() * 4.0) {
                        eqaf -= grid_beats.to_double();
                }
-       } else {
-               eqaf = qaf;
        }
 
        _note[0] = map.frame_at_quarter_note (eqaf) - _region_view->region()->position();
@@ -6257,7 +6256,7 @@ NoteCreateDrag::finished (GdkEvent* ev, bool had_movement)
        const double qn_length = map.quarter_note_at_frame (start_sess_rel + length) - map.quarter_note_at_frame (start_sess_rel);
 
        Evoral::Beats qn_length_beats = max (one_tick, Evoral::Beats (qn_length));
-       _region_view->create_note_at (start, _drag_rect->y0(), qn_length_beats, ev->button.state);
+       _region_view->create_note_at (start, _drag_rect->y0(), qn_length_beats, ev->button.state, false);
 }
 
 double
index 49aac7bbc0863f93ae29880c0625a0db9b3c307f..a2aa46f3ff607c354ba200dc2672d3535cd8916f 100644 (file)
@@ -551,7 +551,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                                        group->canvas_to_item (event_x, event_y);
 
                                        Evoral::Beats beats = get_grid_beats(editor.pixel_to_sample(event_x) + _region->position());
-                                       create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state);
+                                       create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state, true);
                                } else {
                                        clear_editor_note_selection ();
                                }
@@ -561,7 +561,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                case MouseDraw:
                        {
                                Evoral::Beats beats = get_grid_beats(editor.pixel_to_sample(event_x) + _region->position());
-                               create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state);
+                               create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state, true);
                                break;
                        }
                default:
@@ -916,7 +916,7 @@ MidiRegionView::show_list_editor ()
  * \param snap_t true to snap t to the grid, otherwise false.
  */
 void
-MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state)
+MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state, bool shift_snap)
 {
        if (length < 2 * DBL_EPSILON) {
                return;
@@ -932,7 +932,7 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, ui
 
        // Start of note in frames relative to region start
        const int32_t divisions = trackview.editor().get_grid_music_divisions (state);
-       Evoral::Beats beat_time = snap_frame_to_grid_underneath (t, divisions);
+       Evoral::Beats beat_time = snap_frame_to_grid_underneath (t, divisions, shift_snap);
 
        const double  note     = view->y_to_note(y);
        const uint8_t chan     = mtv->get_channel_for_add();
@@ -3743,7 +3743,7 @@ 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 double snapped_region_qn = snap_frame_to_grid_underneath (unsnapped_frame, divisions).to_double();
+       const double snapped_region_qn = snap_frame_to_grid_underneath (unsnapped_frame, divisions, true).to_double();
 
        Evoral::Beats snapped_beats = Evoral::Beats (snapped_region_qn);
        /* calculate time in beats relative to start of source */
@@ -4116,12 +4116,12 @@ MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const
  *  @return beat duration of p snapped to the grid subdivision underneath it.
  */
 Evoral::Beats
-MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, int32_t divisions) const
+MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, int32_t divisions, bool shift_snap) const
 {
        TempoMap& map (trackview.session()->tempo_map());
        double eqaf = map.exact_qn_at_frame (p + _region->position(), divisions);
 
-       if (divisions != 0) {
+       if (divisions != 0 && shift_snap) {
                const double qaf = map.quarter_note_at_frame (p + _region->position());
                /* Hack so that we always snap to the note that we are over, instead of snapping
                   to the next one if we're more than halfway through the one we're over.
index c79227d5a995f3b2d6f9ab8ca3932d60f1c10582..db769b44fcde38c17ac3fa0be316c10ff0be3328 100644 (file)
@@ -325,8 +325,9 @@ public:
         * \param y vertical position in pixels
         * \param length duration of the note in beats
         * \param state the keyboard modifier mask for the canvas event (click).
+        * \param shift_snap true alters snap behavior to round down always (false if the gui has already done that).
         */
-       void create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state);
+       void create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state, bool shift_snap);
 
        /** An external request to clear the note selection, remove MRV from editor
         * selection.
@@ -508,7 +509,7 @@ private:
 
        bool _mouse_changed_selection;
 
-       Evoral::Beats snap_frame_to_grid_underneath (framepos_t p, int32_t divisions) const;
+       Evoral::Beats snap_frame_to_grid_underneath (framepos_t p, int32_t divisions, bool shift_snap) const;
 
        PBD::ScopedConnection _mouse_mode_connection;