Relative snap - support magnetic mode (hackishly for now)
authornick_m <mainsbridge@gmail.com>
Sat, 16 May 2015 18:26:05 +0000 (04:26 +1000)
committernick_m <mainsbridge@gmail.com>
Sat, 16 May 2015 18:26:05 +0000 (04:26 +1000)
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_drag.h
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/public_editor.h
gtk2_ardour/region_view.cc
gtk2_ardour/region_view.h

index 60aa58dbb0ac5b96dcbafd4edcd1cc885b5a394a..a45e243da5a6ee822012d9845775afa0e45ae1fe 100644 (file)
@@ -2653,6 +2653,16 @@ Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark)
        snap_to_internal (start, direction, for_mark);
 }
 
+void
+Editor::snap_to_no_magnets (framepos_t& start, RoundMode direction, bool for_mark)
+{
+       if (!_session || _snap_mode == SnapOff) {
+               return;
+       }
+
+       snap_to_internal (start, direction, for_mark, true);
+}
+
 void
 Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool /*for_mark*/)
 {
@@ -2720,7 +2730,7 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool
 }
 
 void
-Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark)
+Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark, bool no_magnets)
 {
        const framepos_t one_second = _session->frame_rate();
        const framepos_t one_minute = _session->frame_rate() * 60;
@@ -2890,6 +2900,10 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark)
 
        case SnapMagnetic:
 
+               if (no_magnets) {
+                       return;
+               }
+
                if (presnap > start) {
                        if (presnap > (start + pixel_to_sample(snap_threshold))) {
                                start = presnap;
index 0e1661aca9e3034bc6b954c265ac6ca4603d8348..988d20efd25a3fad8d6368fde8c86a832629e431 100644 (file)
@@ -440,6 +440,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
                      ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
                      bool              for_mark  = false);
 
+       void snap_to_no_magnets (framepos_t&       first,
+                     ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
+                     bool              for_mark  = false);
+
        void snap_to_with_modifier (framepos_t&       first,
                                    GdkEvent const *  ev,
                                    ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
@@ -2140,7 +2144,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
 
        void snap_to_internal (framepos_t&       first,
                               ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
-                              bool              for_mark  = false);
+                              bool              for_mark  = false,
+                              bool              no_magnets = false);
 
        void timecode_snap_to_internal (framepos_t&       first,
                                        ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
index f7f4cd2873fd7a9c054f51cc0fa2755dc148f05e..966ab7002f19cde2dbf5f9d5a12aea59f746c845 100644 (file)
@@ -366,7 +366,7 @@ Drag::setup_snap_delta (framepos_t pos)
 {
        if (_editor->snap_delta () == SnapRelative) {
                framepos_t temp = pos;
-               _editor->snap_to (temp);
+               _editor->snap_to_no_magnets (temp);
                _snap_delta = temp - pos;
        }
 }
@@ -2358,7 +2358,7 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
 
        if (_editor->snap_delta () == SnapRelative) {
                double temp;
-               temp = region->snap_to_pixel(cnote->x0 ());
+               temp = region->snap_to_pixel_no_magnets (cnote->x0 ());
                _snap_delta = temp - cnote->x0 ();
        }
 
index 5fb183671f423738ad9ee0dac2975d894aa888cb..a58d95dfa1be340801cd5386ce55920a10addee8 100644 (file)
@@ -217,7 +217,7 @@ protected:
                return _last_pointer_frame;
        }
 
-       framecnt_t snap_delta () const {
+       ARDOUR::frameoffset_t snap_delta () const {
                return _snap_delta;
        }
 
@@ -259,7 +259,7 @@ private:
        /* difference between some key position's snapped and unsnapped
         *  framepos. used for relative snap.
         */
-       framecnt_t _snap_delta;
+       ARDOUR::frameoffset_t _snap_delta;
        CursorContext::Handle _cursor_ctx; ///< cursor change context
 };
 
index 97a71003ebc96fa35560b18abfe8edc8968d353e..3ecadc4775c1ed7ab6e05ed527b8d547cb526c79 100644 (file)
@@ -2633,6 +2633,16 @@ MidiRegionView::snap_pixel_to_sample(double x)
        return snap_frame_to_frame (editor.pixel_to_sample (x));
 }
 
+/** @param x Pixel relative to the region position explicitly (no magnetic snap)
+ *  @return Snapped frame relative to the region position.
+ */
+framepos_t
+MidiRegionView::snap_pixel_to_sample_no_magnets (double x)
+{
+       PublicEditor& editor (trackview.editor());
+       return snap_frame_to_frame_no_magnets (editor.pixel_to_sample (x));
+}
+
 /** @param x Pixel relative to the region position.
  *  @return Snapped pixel relative to the region position.
  */
@@ -2642,6 +2652,15 @@ MidiRegionView::snap_to_pixel(double x)
        return (double) trackview.editor().sample_to_pixel(snap_pixel_to_sample(x));
 }
 
+/** @param x Pixel relative to the region position.
+ *  @return Explicitly snapped pixel relative to the region position (no magnetic snap).
+ */
+double
+MidiRegionView::snap_to_pixel_no_magnets (double x)
+{
+       return (double) trackview.editor().sample_to_pixel(snap_pixel_to_sample_no_magnets(x));
+}
+
 double
 MidiRegionView::get_position_pixels()
 {
@@ -2691,7 +2710,7 @@ MidiRegionView::region_frames_to_region_beats(framepos_t frames) const
 }
 
 double
-MidiRegionView::region_frames_to_region_beats_double(framepos_t frames) const
+MidiRegionView::region_frames_to_region_beats_double (framepos_t frames) const
 {
        return _region_relative_time_converter_double.from(frames);
 }
@@ -2794,9 +2813,9 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
                        int sign = 1;
                        /* negative beat offsets aren't allowed */
                        if (delta_samps > 0) {
-                               delta_beats = _region_relative_time_converter_double.from(delta_samps);
+                               delta_beats = region_frames_to_region_beats_double (delta_samps);
                        } else if (delta_samps < 0) {
-                               delta_beats = _region_relative_time_converter_double.from( - delta_samps);
+                               delta_beats = region_frames_to_region_beats_double ( - delta_samps);
                                sign = -1;
                        }
 
@@ -2869,9 +2888,9 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
                double delta_beats;
                int sign = 1;
                if (delta_samps > 0) {
-                       delta_beats = _region_relative_time_converter_double.from(delta_samps);
+                       delta_beats = region_frames_to_region_beats_double (delta_samps);
                } else if (delta_samps < 0) {
-                       delta_beats = _region_relative_time_converter_double.from( - delta_samps);
+                       delta_beats = region_frames_to_region_beats_double ( - delta_samps);
                        sign = -1;
                }
 
index cfdb50a99c140015b5b3a3b390a5aa06cfffcfe9..7329c6facc02c3b18379acf35b48bb63fa275a8b 100644 (file)
@@ -254,12 +254,24 @@ public:
         */
        double snap_to_pixel(double x);
 
+       /** Snap a region relative pixel coordinate to pixel units explicitly (no magnetic snap).
+        * @param x a pixel coordinate relative to region start
+        * @return the explicitly snapped pixel coordinate relative to region start
+        */
+       double snap_to_pixel_no_magnets (double x);
+
        /** Snap a region relative pixel coordinate to frame units.
         * @param x a pixel coordinate relative to region start
         * @return the snapped framepos_t coordinate relative to region start
         */
        framepos_t snap_pixel_to_sample(double x);
 
+       /** Explicitly snap a region relative pixel coordinate to frame units (no magnetic snap).
+        * @param x a pixel coordinate relative to region start
+        * @return the explicitly snapped framepos_t coordinate relative to region start
+        */
+       framepos_t snap_pixel_to_sample_no_magnets (double x);
+
        /** Convert a timestamp in beats into frames (both relative to region position) */
        framepos_t region_beats_to_region_frames(Evoral::Beats beats) const;
        /** Convert a timestamp in beats into absolute frames */
index a8ecbb5f40d2acc83da7e5bd06409f9f16957c8f..dc845e6f8944c31932c1819eaefafa914f2294ce 100644 (file)
@@ -148,6 +148,10 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
        virtual void snap_to (framepos_t&       first,
                              ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
                              bool              for_mark  = false) = 0;
+       /** Snap a value according to the current snap setting. */
+       virtual void snap_to_no_magnets (framepos_t&       first,
+                             ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
+                             bool              for_mark  = false) = 0;
 
        /** Undo some transactions.
         * @param n Number of transactions to undo.
index be96cd4058bb0b4fbbec286abd7aaae57eecaacd..cd83154a9fde7c9b591e90626d590cb10173ef85 100644 (file)
@@ -962,3 +962,29 @@ RegionView::snap_frame_to_frame (frameoffset_t x) const
        /* back to region relative */
        return frame - _region->position();
 }
+
+/** Snap a frame offset within our region using the current snap settings.
+ *  @param x Frame offset from this region's position.
+ *  @return Snapped frame offset from this region's position.
+ */
+frameoffset_t
+RegionView::snap_frame_to_frame_no_magnets (frameoffset_t x) const
+{
+       PublicEditor& editor = trackview.editor();
+
+       /* x is region relative, convert it to global absolute frames */
+       framepos_t const session_frame = x + _region->position();
+
+       /* try a snap in either direction */
+       framepos_t frame = session_frame;
+       editor.snap_to_no_magnets (frame, RoundNearest);
+
+       /* if we went off the beginning of the region, snap forwards */
+       if (frame < _region->position ()) {
+               frame = session_frame;
+               editor.snap_to_no_magnets (frame, RoundUpAlways);
+       }
+
+       /* back to region relative */
+       return frame - _region->position();
+}
index 92006c556cbfeaed903e889f515ea36560e23fdd..77abb5e2a96437771f26249442e751915ffebecf 100644 (file)
@@ -122,6 +122,7 @@ class RegionView : public TimeAxisViewItem
        };
 
        ARDOUR::frameoffset_t snap_frame_to_frame (ARDOUR::frameoffset_t) const;
+       ARDOUR::frameoffset_t snap_frame_to_frame_no_magnets (ARDOUR::frameoffset_t) const;
        
   protected: