mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
Relative snap - support magnetic mode (hackishly for now)
This commit is contained in:
parent
bbafb8f137
commit
91a34c596d
9 changed files with 92 additions and 11 deletions
|
|
@ -2653,6 +2653,16 @@ Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark)
|
||||||
snap_to_internal (start, direction, 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
|
void
|
||||||
Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool /*for_mark*/)
|
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
|
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_second = _session->frame_rate();
|
||||||
const framepos_t one_minute = _session->frame_rate() * 60;
|
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:
|
case SnapMagnetic:
|
||||||
|
|
||||||
|
if (no_magnets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (presnap > start) {
|
if (presnap > start) {
|
||||||
if (presnap > (start + pixel_to_sample(snap_threshold))) {
|
if (presnap > (start + pixel_to_sample(snap_threshold))) {
|
||||||
start = presnap;
|
start = presnap;
|
||||||
|
|
|
||||||
|
|
@ -440,6 +440,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false);
|
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,
|
void snap_to_with_modifier (framepos_t& first,
|
||||||
GdkEvent const * ev,
|
GdkEvent const * ev,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
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,
|
void snap_to_internal (framepos_t& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
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,
|
void timecode_snap_to_internal (framepos_t& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ Drag::setup_snap_delta (framepos_t pos)
|
||||||
{
|
{
|
||||||
if (_editor->snap_delta () == SnapRelative) {
|
if (_editor->snap_delta () == SnapRelative) {
|
||||||
framepos_t temp = pos;
|
framepos_t temp = pos;
|
||||||
_editor->snap_to (temp);
|
_editor->snap_to_no_magnets (temp);
|
||||||
_snap_delta = temp - pos;
|
_snap_delta = temp - pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2358,7 +2358,7 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
|
||||||
|
|
||||||
if (_editor->snap_delta () == SnapRelative) {
|
if (_editor->snap_delta () == SnapRelative) {
|
||||||
double temp;
|
double temp;
|
||||||
temp = region->snap_to_pixel(cnote->x0 ());
|
temp = region->snap_to_pixel_no_magnets (cnote->x0 ());
|
||||||
_snap_delta = temp - cnote->x0 ();
|
_snap_delta = temp - cnote->x0 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ protected:
|
||||||
return _last_pointer_frame;
|
return _last_pointer_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
framecnt_t snap_delta () const {
|
ARDOUR::frameoffset_t snap_delta () const {
|
||||||
return _snap_delta;
|
return _snap_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,7 +259,7 @@ private:
|
||||||
/* difference between some key position's snapped and unsnapped
|
/* difference between some key position's snapped and unsnapped
|
||||||
* framepos. used for relative snap.
|
* framepos. used for relative snap.
|
||||||
*/
|
*/
|
||||||
framecnt_t _snap_delta;
|
ARDOUR::frameoffset_t _snap_delta;
|
||||||
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2633,6 +2633,16 @@ MidiRegionView::snap_pixel_to_sample(double x)
|
||||||
return snap_frame_to_frame (editor.pixel_to_sample (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.
|
/** @param x Pixel relative to the region position.
|
||||||
* @return Snapped 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));
|
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
|
double
|
||||||
MidiRegionView::get_position_pixels()
|
MidiRegionView::get_position_pixels()
|
||||||
{
|
{
|
||||||
|
|
@ -2691,7 +2710,7 @@ MidiRegionView::region_frames_to_region_beats(framepos_t frames) const
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
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);
|
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;
|
int sign = 1;
|
||||||
/* negative beat offsets aren't allowed */
|
/* negative beat offsets aren't allowed */
|
||||||
if (delta_samps > 0) {
|
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) {
|
} 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;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2869,9 +2888,9 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
|
||||||
double delta_beats;
|
double delta_beats;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
if (delta_samps > 0) {
|
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) {
|
} 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;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,12 +254,24 @@ public:
|
||||||
*/
|
*/
|
||||||
double snap_to_pixel(double x);
|
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.
|
/** Snap a region relative pixel coordinate to frame units.
|
||||||
* @param x a pixel coordinate relative to region start
|
* @param x a pixel coordinate relative to region start
|
||||||
* @return the snapped framepos_t coordinate relative to region start
|
* @return the snapped framepos_t coordinate relative to region start
|
||||||
*/
|
*/
|
||||||
framepos_t snap_pixel_to_sample(double x);
|
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) */
|
/** Convert a timestamp in beats into frames (both relative to region position) */
|
||||||
framepos_t region_beats_to_region_frames(Evoral::Beats beats) const;
|
framepos_t region_beats_to_region_frames(Evoral::Beats beats) const;
|
||||||
/** Convert a timestamp in beats into absolute frames */
|
/** Convert a timestamp in beats into absolute frames */
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,10 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
|
||||||
virtual void snap_to (framepos_t& first,
|
virtual void snap_to (framepos_t& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false) = 0;
|
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.
|
/** Undo some transactions.
|
||||||
* @param n Number of transactions to undo.
|
* @param n Number of transactions to undo.
|
||||||
|
|
|
||||||
|
|
@ -962,3 +962,29 @@ RegionView::snap_frame_to_frame (frameoffset_t x) const
|
||||||
/* back to region relative */
|
/* back to region relative */
|
||||||
return frame - _region->position();
|
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();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 (ARDOUR::frameoffset_t) const;
|
||||||
|
ARDOUR::frameoffset_t snap_frame_to_frame_no_magnets (ARDOUR::frameoffset_t) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue