Relative snap - support magnetic mode (hackishly for now)

This commit is contained in:
nick_m 2015-05-17 04:26:05 +10:00
parent bbafb8f137
commit 91a34c596d
9 changed files with 92 additions and 11 deletions

View 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;

View 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,

View 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 ();
}

View 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
};

View 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;
}

View 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 */

View 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.

View 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();
}

View 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: