Tempo ramps - consolidate meter dragging code.
[ardour.git] / gtk2_ardour / editor_drag.cc
index f60a8758b0ad14cca8031a0741d8db6be48d57c4..16c1862dd8fee3050f04df31135274ae0d2eabc2 100644 (file)
@@ -3142,10 +3142,6 @@ MeterMarkerDrag::setup_pointer_frame_offset ()
 void
 MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
 {
-       if (!_marker->meter().movable()) {
-               //return;
-       }
-
        if (first_move) {
 
                // create a dummy marker to catch events, then hide it.
@@ -3189,25 +3185,16 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
                }
        }
 
-       framepos_t const pf = adjusted_current_frame (event, false);
-       if (_marker->meter().position_lock_style() == MusicTime) {
-               TempoMap& map (_editor->session()->tempo_map());
-               Timecode::BBT_Time bbt;
-               map.bbt_time (pf, bbt);
-               /* round bbt to bars */
-               map.round_bbt (bbt, -1, RoundNearest);
-
-               if ((bbt.bars != _real_section->bbt().bars && pf > last_pointer_frame())
-                   || (bbt.bars < _real_section->bbt().bars && pf < last_pointer_frame())) {
+       framepos_t pf = adjusted_current_frame (event);
 
-                       /* move meter beat-based */
-                       _editor->session()->tempo_map().gui_move_meter_bbt (_real_section, bbt);
-               }
-       } else {
-               /* AudioTime */
-               /* move meter frame-based */
-               _editor->session()->tempo_map().gui_move_meter_frame (_real_section, pf);
+       if (_real_section->position_lock_style() == AudioTime && _editor->snap_musical()) {
+               /* never snap to music for audio locked */
+               pf = adjusted_current_frame (event, false);
        }
+
+       _editor->session()->tempo_map().gui_move_meter (_real_section, pf);
+
+       setup_pointer_frame_offset ();
        _marker->set_position (pf);
        show_verbose_cursor_time (_real_section->frame());
 }
@@ -3281,6 +3268,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
        if (!_real_section->active()) {
                return;
        }
+
        if (first_move) {
 
                // mvc drag - create a dummy marker to catch events, hide it.
@@ -3342,7 +3330,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
                                } else if (use_snap) {
                                        map.round_bbt (bbt, _editor->get_grid_beat_divisions (0), RoundNearest);
                                }
-                               double const pulse = map.predict_tempo_pulse (_real_section, map.frame_time (bbt));
+                               double const pulse = map.predict_tempo_position (_real_section, bbt).first;
                                _real_section = map.add_tempo (_marker->tempo(), pulse, 0, _real_section->type(), MusicTime);
                        } else {
                                if (use_snap && _editor->snap_type() == SnapToBar) {
@@ -3351,7 +3339,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
                                        map.round_bbt (bbt, _editor->get_grid_beat_divisions (0), RoundNearest);
                                }
                                if (use_snap) {
-                                       frame = map.predict_tempo_frame (_real_section, bbt);
+                                       frame = map.predict_tempo_position (_real_section, bbt).second;
                                }
                                _real_section = map.add_tempo (_marker->tempo(), 0.0, frame, _real_section->type(), AudioTime);
                        }
@@ -3362,25 +3350,30 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
        framepos_t pf;
 
        if (Keyboard::modifier_state_contains (event->button.state, ArdourKeyboard::constraint_modifier ())) {
+               /* use vertical movement to alter tempo .. should be log */
                double new_bpm = _real_section->beats_per_minute() + ((last_pointer_y() - current_pointer_y()) / 5.0);
-               _editor->session()->tempo_map().gui_change_tempo (_real_section, Tempo (new_bpm, _real_section->note_type()));
                stringstream strs;
+
+               _editor->session()->tempo_map().gui_change_tempo (_real_section, Tempo (new_bpm, _real_section->note_type()));
                strs << new_bpm;
                show_verbose_cursor_text (strs.str());
+
        } else if (_movable && !_real_section->locked_to_meter()) {
+
                if (!_editor->snap_musical()) {
                        /* snap normally (this is not self-referential).*/
                        pf = adjusted_current_frame (event);
+
                } else {
                        /* but this is.
                           we can't use the map for anything related to tempo,
                           so we round bbt using meters, which have no dependency
                           on pulse for this kind of thing.
                        */
-                       bool use_snap;
                        TempoMap& map (_editor->session()->tempo_map());
+                       Timecode::BBT_Time when;
+                       bool use_snap;
 
-                       pf = adjusted_current_frame (event, false);
                        if (ArdourKeyboard::indicates_snap (event->button.state)) {
                                if (_editor->snap_mode() == Editing::SnapOff) {
                                        use_snap = true;
@@ -3395,36 +3388,24 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
                                }
                        }
 
-                       Timecode::BBT_Time when;
+                       pf = adjusted_current_frame (event);
                        map.bbt_time (pf, when);
 
-                       if (_real_section->position_lock_style() == MusicTime) {
-
-                               const double pulse = map.predict_tempo_pulse (_real_section, pf);
-                               when = map.pulse_to_bbt (pulse);
-                               if (use_snap && _editor->snap_type() == SnapToBar) {
-                                       map.round_bbt (when, -1, (pf > _real_section->frame()) ? RoundUpMaybe : RoundDownMaybe);
-                               } else if (use_snap) {
-                                       map.round_bbt (when, _editor->get_grid_beat_divisions (0), RoundNearest);
-                               }
+                       if (use_snap && _editor->snap_type() == SnapToBar) {
+                               map.round_bbt (when, -1, (pf > _real_section->frame()) ? RoundUpMaybe : RoundDownMaybe);
 
-                               const double beat = map.bbt_to_beats (when);
-                               map.gui_move_tempo_beat (_real_section, beat);
-                       } else {
-                               if (use_snap && _editor->snap_type() == SnapToBar) {
-                                       map.round_bbt (when, -1, (pf > _real_section->frame()) ? RoundUpMaybe : RoundDownMaybe);
-                               } else if (use_snap) {
-                                       map.round_bbt (when, _editor->get_grid_beat_divisions (0), RoundNearest);
-                               }
-                               if (use_snap) {
-                                       pf = map.predict_tempo_frame (_real_section, when);
-                               }
-                               map.gui_move_tempo_frame (_real_section, pf);
                        }
+                       const pair<double, framepos_t> future_pos = map.predict_tempo_position (_real_section, when);
+                       map.gui_move_tempo (_real_section, future_pos);
+
                }
 
                show_verbose_cursor_time (_real_section->frame());
        }
+
+       /* this has moved the bar lines themselves, so recalibrate the offset */
+       setup_pointer_frame_offset();
+
        _marker->set_position (pf);
 }