rework snap
snap now fills in a struct (MusicFrame) which contins a snapped frame along with a music divisor. this gives useful information wrt magnetic snap which may or may not have rounded to an exact musical position. region position may now be set musically (using quarter notes for now). this patch fixes several problems in the current code: - dragging a list of music-locked regions now maintains correct musical offsets within the list. - splitting regions using magnetic snap works correctly (#7192) - cut drag should now work correctly with magnetic snap. - musical length of split midi regions is no longer frame based.
This commit is contained in:
parent
a21a414615
commit
59daffea1d
@ -1347,11 +1347,10 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
|
|||||||
/* don't create points that can't be seen */
|
/* don't create points that can't be seen */
|
||||||
|
|
||||||
update_envelope_visibility ();
|
update_envelope_visibility ();
|
||||||
|
|
||||||
framepos_t rpos = region ()->position ();
|
framepos_t rpos = region ()->position ();
|
||||||
framepos_t fx = trackview.editor().pixel_to_sample (mx) + rpos;
|
MusicFrame snap_pos (trackview.editor().pixel_to_sample (mx) + rpos, 0);
|
||||||
trackview.editor ().snap_to_with_modifier (fx, ev);
|
trackview.editor ().snap_to_with_modifier (snap_pos, ev);
|
||||||
fx -= rpos;
|
framepos_t fx = snap_pos.frame - rpos;
|
||||||
|
|
||||||
if (fx > _region->length()) {
|
if (fx > _region->length()) {
|
||||||
return;
|
return;
|
||||||
|
@ -605,7 +605,7 @@ AutomationTimeAxisView::build_display_menu ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when, double y, bool with_guard_points)
|
AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t frame, double y, bool with_guard_points)
|
||||||
{
|
{
|
||||||
if (!_line) {
|
if (!_line) {
|
||||||
return;
|
return;
|
||||||
@ -632,16 +632,18 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when,
|
|||||||
|
|
||||||
_line->view_to_model_coord (x, y);
|
_line->view_to_model_coord (x, y);
|
||||||
|
|
||||||
|
MusicFrame when (frame, 0);
|
||||||
_editor.snap_to_with_modifier (when, event);
|
_editor.snap_to_with_modifier (when, event);
|
||||||
|
|
||||||
XMLNode& before = list->get_state();
|
XMLNode& before = list->get_state();
|
||||||
std::list<Selectable*> results;
|
std::list<Selectable*> results;
|
||||||
if (list->editor_add (when, y, with_guard_points)) {
|
|
||||||
|
if (list->editor_add (when.frame, y, with_guard_points)) {
|
||||||
XMLNode& after = list->get_state();
|
XMLNode& after = list->get_state();
|
||||||
_editor.begin_reversible_command (_("add automation event"));
|
_editor.begin_reversible_command (_("add automation event"));
|
||||||
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
|
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
|
||||||
|
|
||||||
_line->get_selectables (when, when, 0.0, 1.0, results);
|
_line->get_selectables (when.frame, when.frame, 0.0, 1.0, results);
|
||||||
_editor.get_selection ().set (results);
|
_editor.get_selection ().set (results);
|
||||||
|
|
||||||
_editor.commit_reversible_command ();
|
_editor.commit_reversible_command ();
|
||||||
@ -650,7 +652,7 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AutomationTimeAxisView::paste (framepos_t pos, const Selection& selection, PasteContext& ctx, const int32_t sub_num)
|
AutomationTimeAxisView::paste (framepos_t pos, const Selection& selection, PasteContext& ctx, const int32_t divisions)
|
||||||
{
|
{
|
||||||
if (_line) {
|
if (_line) {
|
||||||
return paste_one (pos, ctx.count, ctx.times, selection, ctx.counts, ctx.greedy);
|
return paste_one (pos, ctx.count, ctx.times, selection, ctx.counts, ctx.greedy);
|
||||||
|
@ -2734,7 +2734,7 @@ Editor::trackview_by_y_position (double y, bool trackview_relative_offset) const
|
|||||||
* @param event Event to get current key modifier information from, or 0.
|
* @param event Event to get current key modifier information from, or 0.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundMode direction, bool for_mark)
|
Editor::snap_to_with_modifier (MusicFrame& start, GdkEvent const * event, RoundMode direction, bool for_mark)
|
||||||
{
|
{
|
||||||
if (!_session || !event) {
|
if (!_session || !event) {
|
||||||
return;
|
return;
|
||||||
@ -2743,6 +2743,8 @@ Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundM
|
|||||||
if (ArdourKeyboard::indicates_snap (event->button.state)) {
|
if (ArdourKeyboard::indicates_snap (event->button.state)) {
|
||||||
if (_snap_mode == SnapOff) {
|
if (_snap_mode == SnapOff) {
|
||||||
snap_to_internal (start, direction, for_mark);
|
snap_to_internal (start, direction, for_mark);
|
||||||
|
} else {
|
||||||
|
start.set (start.frame, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_snap_mode != SnapOff) {
|
if (_snap_mode != SnapOff) {
|
||||||
@ -2750,14 +2752,17 @@ Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundM
|
|||||||
} else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) {
|
} else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) {
|
||||||
/* SnapOff, but we pressed the snap_delta modifier */
|
/* SnapOff, but we pressed the snap_delta modifier */
|
||||||
snap_to_internal (start, direction, for_mark);
|
snap_to_internal (start, direction, for_mark);
|
||||||
|
} else {
|
||||||
|
start.set (start.frame, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark, bool ensure_snap)
|
Editor::snap_to (MusicFrame& start, RoundMode direction, bool for_mark, bool ensure_snap)
|
||||||
{
|
{
|
||||||
if (!_session || (_snap_mode == SnapOff && !ensure_snap)) {
|
if (!_session || (_snap_mode == SnapOff && !ensure_snap)) {
|
||||||
|
start.set (start.frame, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2765,8 +2770,9 @@ Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark, bool ens
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool /*for_mark*/)
|
Editor::timecode_snap_to_internal (MusicFrame& pos, RoundMode direction, bool /*for_mark*/)
|
||||||
{
|
{
|
||||||
|
framepos_t start = pos.frame;
|
||||||
const framepos_t one_timecode_second = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame());
|
const framepos_t one_timecode_second = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame());
|
||||||
framepos_t one_timecode_minute = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame() * 60);
|
framepos_t one_timecode_minute = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame() * 60);
|
||||||
|
|
||||||
@ -2828,14 +2834,16 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool
|
|||||||
fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg;
|
fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg;
|
||||||
abort(); /*NOTREACHED*/
|
abort(); /*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos.set (start, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark, bool ensure_snap)
|
Editor::snap_to_internal (MusicFrame& start, RoundMode direction, bool for_mark, bool ensure_snap)
|
||||||
{
|
{
|
||||||
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;
|
||||||
framepos_t presnap = start;
|
framepos_t presnap = start.frame;
|
||||||
framepos_t before;
|
framepos_t before;
|
||||||
framepos_t after;
|
framepos_t after;
|
||||||
|
|
||||||
@ -2847,95 +2855,104 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark,
|
|||||||
|
|
||||||
case SnapToCDFrame:
|
case SnapToCDFrame:
|
||||||
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
||||||
start % (one_second/75) == 0) {
|
start.frame % (one_second/75) == 0) {
|
||||||
/* start is already on a whole CD frame, do nothing */
|
/* start is already on a whole CD frame, do nothing */
|
||||||
} else if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
|
} else if (((direction == 0) && (start.frame % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
|
||||||
start = (framepos_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
|
start.frame = (framepos_t) ceil ((double) start.frame / (one_second / 75)) * (one_second / 75);
|
||||||
} else {
|
} else {
|
||||||
start = (framepos_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
|
start.frame = (framepos_t) floor ((double) start.frame / (one_second / 75)) * (one_second / 75);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start.set (start.frame, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToSeconds:
|
case SnapToSeconds:
|
||||||
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
||||||
start % one_second == 0) {
|
start.frame % one_second == 0) {
|
||||||
/* start is already on a whole second, do nothing */
|
/* start is already on a whole second, do nothing */
|
||||||
} else if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
|
} else if (((direction == 0) && (start.frame % one_second > one_second / 2)) || (direction > 0)) {
|
||||||
start = (framepos_t) ceil ((double) start / one_second) * one_second;
|
start.frame = (framepos_t) ceil ((double) start.frame / one_second) * one_second;
|
||||||
} else {
|
} else {
|
||||||
start = (framepos_t) floor ((double) start / one_second) * one_second;
|
start.frame = (framepos_t) floor ((double) start.frame / one_second) * one_second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start.set (start.frame, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToMinutes:
|
case SnapToMinutes:
|
||||||
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
|
||||||
start % one_minute == 0) {
|
start.frame % one_minute == 0) {
|
||||||
/* start is already on a whole minute, do nothing */
|
/* start is already on a whole minute, do nothing */
|
||||||
} else if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
|
} else if (((direction == 0) && (start.frame % one_minute > one_minute / 2)) || (direction > 0)) {
|
||||||
start = (framepos_t) ceil ((double) start / one_minute) * one_minute;
|
start.frame = (framepos_t) ceil ((double) start.frame / one_minute) * one_minute;
|
||||||
} else {
|
} else {
|
||||||
start = (framepos_t) floor ((double) start / one_minute) * one_minute;
|
start.frame = (framepos_t) floor ((double) start.frame / one_minute) * one_minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start.set (start.frame, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToBar:
|
case SnapToBar:
|
||||||
start = _session->tempo_map().round_to_bar (start, direction);
|
start = _session->tempo_map().round_to_bar (start.frame, direction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToBeat:
|
case SnapToBeat:
|
||||||
start = _session->tempo_map().round_to_beat (start, direction);
|
start = _session->tempo_map().round_to_beat (start.frame, direction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToBeatDiv128:
|
case SnapToBeatDiv128:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 128, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 128, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv64:
|
case SnapToBeatDiv64:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 64, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 64, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv32:
|
case SnapToBeatDiv32:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 32, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 32, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv28:
|
case SnapToBeatDiv28:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 28, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 28, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv24:
|
case SnapToBeatDiv24:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 24, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 24, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv20:
|
case SnapToBeatDiv20:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 20, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 20, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv16:
|
case SnapToBeatDiv16:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 16, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 16, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv14:
|
case SnapToBeatDiv14:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 14, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 14, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv12:
|
case SnapToBeatDiv12:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 12, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 12, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv10:
|
case SnapToBeatDiv10:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 10, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 10, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv8:
|
case SnapToBeatDiv8:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 8, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 8, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv7:
|
case SnapToBeatDiv7:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 7, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 7, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv6:
|
case SnapToBeatDiv6:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 6, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 6, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv5:
|
case SnapToBeatDiv5:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 5, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 5, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv4:
|
case SnapToBeatDiv4:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 4, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 4, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv3:
|
case SnapToBeatDiv3:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 3, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 3, direction);
|
||||||
break;
|
break;
|
||||||
case SnapToBeatDiv2:
|
case SnapToBeatDiv2:
|
||||||
start = _session->tempo_map().round_to_quarter_note_subdivision (start, 2, direction);
|
start = _session->tempo_map().round_to_quarter_note_subdivision (start.frame, 2, direction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToMark:
|
case SnapToMark:
|
||||||
@ -2943,29 +2960,31 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_session->locations()->marks_either_side (start, before, after);
|
_session->locations()->marks_either_side (start.frame, before, after);
|
||||||
|
|
||||||
if (before == max_framepos && after == max_framepos) {
|
if (before == max_framepos && after == max_framepos) {
|
||||||
/* No marks to snap to, so just don't snap */
|
/* No marks to snap to, so just don't snap */
|
||||||
return;
|
return;
|
||||||
} else if (before == max_framepos) {
|
} else if (before == max_framepos) {
|
||||||
start = after;
|
start.frame = after;
|
||||||
} else if (after == max_framepos) {
|
} else if (after == max_framepos) {
|
||||||
start = before;
|
start.frame = before;
|
||||||
} else if (before != max_framepos && after != max_framepos) {
|
} else if (before != max_framepos && after != max_framepos) {
|
||||||
if ((direction == RoundUpMaybe || direction == RoundUpAlways))
|
if ((direction == RoundUpMaybe || direction == RoundUpAlways))
|
||||||
start = after;
|
start.frame = after;
|
||||||
else if ((direction == RoundDownMaybe || direction == RoundDownAlways))
|
else if ((direction == RoundDownMaybe || direction == RoundDownAlways))
|
||||||
start = before;
|
start.frame = before;
|
||||||
else if (direction == 0 ) {
|
else if (direction == 0 ) {
|
||||||
if ((start - before) < (after - start)) {
|
if ((start.frame - before) < (after - start.frame)) {
|
||||||
start = before;
|
start.frame = before;
|
||||||
} else {
|
} else {
|
||||||
start = after;
|
start.frame = after;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start.set (start.frame, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SnapToRegionStart:
|
case SnapToRegionStart:
|
||||||
@ -2978,9 +2997,9 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark,
|
|||||||
vector<framepos_t>::iterator next = region_boundary_cache.end ();
|
vector<framepos_t>::iterator next = region_boundary_cache.end ();
|
||||||
|
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
next = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
|
next = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start.frame);
|
||||||
} else {
|
} else {
|
||||||
next = std::lower_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
|
next = std::lower_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next != region_boundary_cache.begin ()) {
|
if (next != region_boundary_cache.begin ()) {
|
||||||
@ -2991,12 +3010,15 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark,
|
|||||||
framepos_t const p = (prev == region_boundary_cache.end()) ? region_boundary_cache.front () : *prev;
|
framepos_t const p = (prev == region_boundary_cache.end()) ? region_boundary_cache.front () : *prev;
|
||||||
framepos_t const n = (next == region_boundary_cache.end()) ? region_boundary_cache.back () : *next;
|
framepos_t const n = (next == region_boundary_cache.end()) ? region_boundary_cache.back () : *next;
|
||||||
|
|
||||||
if (start > (p + n) / 2) {
|
if (start.frame > (p + n) / 2) {
|
||||||
start = n;
|
start.frame = n;
|
||||||
} else {
|
} else {
|
||||||
start = p;
|
start.frame = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start.set (start.frame, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3010,21 +3032,20 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presnap > start) {
|
if (presnap > start.frame) {
|
||||||
if (presnap > (start + pixel_to_sample(snap_threshold))) {
|
if (presnap > (start.frame + pixel_to_sample(snap_threshold))) {
|
||||||
start = presnap;
|
start.set (presnap, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (presnap < start) {
|
} else if (presnap < start.frame) {
|
||||||
if (presnap < (start - pixel_to_sample(snap_threshold))) {
|
if (presnap < (start.frame - pixel_to_sample(snap_threshold))) {
|
||||||
start = presnap;
|
start.set (presnap, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* handled at entry */
|
/* handled at entry */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4067,9 +4088,9 @@ Editor::get_paste_offset (framepos_t pos, unsigned paste_count, framecnt_t durat
|
|||||||
framecnt_t offset = paste_count * duration;
|
framecnt_t offset = paste_count * duration;
|
||||||
|
|
||||||
/* snap offset so pos + offset is aligned to the grid */
|
/* snap offset so pos + offset is aligned to the grid */
|
||||||
framepos_t offset_pos = pos + offset;
|
MusicFrame offset_pos (pos + offset, 0);
|
||||||
snap_to(offset_pos, RoundUpMaybe);
|
snap_to(offset_pos, RoundUpMaybe);
|
||||||
offset = offset_pos - pos;
|
offset = offset_pos.frame - pos;
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -4740,6 +4761,8 @@ Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_
|
|||||||
ep = EditAtPlayhead;
|
ep = EditAtPlayhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MusicFrame snap_mf (0, 0);
|
||||||
|
|
||||||
switch (ep) {
|
switch (ep) {
|
||||||
case EditAtPlayhead:
|
case EditAtPlayhead:
|
||||||
if (_dragging_playhead) {
|
if (_dragging_playhead) {
|
||||||
@ -4772,7 +4795,9 @@ Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_
|
|||||||
/* XXX not right but what can we do ? */
|
/* XXX not right but what can we do ? */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
snap_to (where);
|
snap_mf.frame = where;
|
||||||
|
snap_to (snap_mf);
|
||||||
|
where = snap_mf.frame;
|
||||||
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use mouse @ %1\n", where));
|
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use mouse @ %1\n", where));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -452,18 +452,18 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||||||
|
|
||||||
TrackViewList axis_views_from_routes (boost::shared_ptr<ARDOUR::RouteList>) const;
|
TrackViewList axis_views_from_routes (boost::shared_ptr<ARDOUR::RouteList>) const;
|
||||||
|
|
||||||
void snap_to (framepos_t& first,
|
void snap_to (ARDOUR::MusicFrame& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false,
|
bool for_mark = false,
|
||||||
bool ensure_snap = false);
|
bool ensure_snap = false);
|
||||||
|
|
||||||
void snap_to_with_modifier (framepos_t& first,
|
void snap_to_with_modifier (ARDOUR::MusicFrame& first,
|
||||||
GdkEvent const * ev,
|
GdkEvent const * ev,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false);
|
bool for_mark = false);
|
||||||
|
|
||||||
void snap_to (framepos_t& first,
|
void snap_to (ARDOUR::MusicFrame& first,
|
||||||
framepos_t& last,
|
ARDOUR::MusicFrame& last,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false);
|
bool for_mark = false);
|
||||||
|
|
||||||
@ -542,7 +542,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||||||
|
|
||||||
/* editing operations that need to be public */
|
/* editing operations that need to be public */
|
||||||
void mouse_add_new_marker (framepos_t where, bool is_cd=false);
|
void mouse_add_new_marker (framepos_t where, bool is_cd=false);
|
||||||
void split_regions_at (framepos_t, RegionSelection&, const int32_t sub_num, bool snap = true);
|
void split_regions_at (ARDOUR::MusicFrame, RegionSelection&, bool snap = true);
|
||||||
void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false);
|
void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false);
|
||||||
RegionSelection get_regions_from_selection_and_mouse (framepos_t);
|
RegionSelection get_regions_from_selection_and_mouse (framepos_t);
|
||||||
|
|
||||||
@ -2152,12 +2152,12 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||||||
void select_next_route ();
|
void select_next_route ();
|
||||||
void select_prev_route ();
|
void select_prev_route ();
|
||||||
|
|
||||||
void snap_to_internal (framepos_t& first,
|
void snap_to_internal (ARDOUR::MusicFrame& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false,
|
bool for_mark = false,
|
||||||
bool ensure_snap = false);
|
bool ensure_snap = false);
|
||||||
|
|
||||||
void timecode_snap_to_internal (framepos_t& first,
|
void timecode_snap_to_internal (ARDOUR::MusicFrame& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false);
|
bool for_mark = false);
|
||||||
|
|
||||||
|
@ -449,7 +449,6 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
|
|||||||
{
|
{
|
||||||
vector<string> paths;
|
vector<string> paths;
|
||||||
GdkEvent ev;
|
GdkEvent ev;
|
||||||
framepos_t frame;
|
|
||||||
double cy;
|
double cy;
|
||||||
|
|
||||||
if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) {
|
if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) {
|
||||||
@ -461,9 +460,8 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
|
|||||||
ev.button.x = x;
|
ev.button.x = x;
|
||||||
ev.button.y = y;
|
ev.button.y = y;
|
||||||
|
|
||||||
frame = window_event_sample (&ev, 0, &cy);
|
MusicFrame when (window_event_sample (&ev, 0, &cy), 0);
|
||||||
|
snap_to (when);
|
||||||
snap_to (frame);
|
|
||||||
|
|
||||||
bool copy = ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY);
|
bool copy = ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -471,9 +469,9 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
|
|||||||
the main event loop with GTK/Quartz. Since import/embed wants
|
the main event loop with GTK/Quartz. Since import/embed wants
|
||||||
to push up a progress dialog, defer all this till we go idle.
|
to push up a progress dialog, defer all this till we go idle.
|
||||||
*/
|
*/
|
||||||
Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, frame, cy, copy));
|
Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, when.frame, cy, copy));
|
||||||
#else
|
#else
|
||||||
drop_paths_part_two (paths, frame, cy, copy);
|
drop_paths_part_two (paths, when.frame, cy, copy);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ Drag::Drag (Editor* e, ArdourCanvas::Item* i, bool trackview_only)
|
|||||||
, _raw_grab_frame (0)
|
, _raw_grab_frame (0)
|
||||||
, _grab_frame (0)
|
, _grab_frame (0)
|
||||||
, _last_pointer_frame (0)
|
, _last_pointer_frame (0)
|
||||||
, _snap_delta (0)
|
, _snap_delta (0, 0)
|
||||||
, _constraint_pressed (false)
|
, _constraint_pressed (false)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
|
|||||||
_raw_grab_frame = _editor->canvas_event_sample (event, &_grab_x, &_grab_y);
|
_raw_grab_frame = _editor->canvas_event_sample (event, &_grab_x, &_grab_y);
|
||||||
|
|
||||||
setup_pointer_frame_offset ();
|
setup_pointer_frame_offset ();
|
||||||
_grab_frame = adjusted_frame (_raw_grab_frame, event);
|
_grab_frame = adjusted_frame (_raw_grab_frame, event).frame;
|
||||||
_last_pointer_frame = _grab_frame;
|
_last_pointer_frame = _grab_frame;
|
||||||
_last_pointer_x = _grab_x;
|
_last_pointer_x = _grab_x;
|
||||||
|
|
||||||
@ -324,13 +324,13 @@ Drag::end_grab (GdkEvent* event)
|
|||||||
return _move_threshold_passed;
|
return _move_threshold_passed;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
MusicFrame
|
||||||
Drag::adjusted_frame (framepos_t f, GdkEvent const * event, bool snap) const
|
Drag::adjusted_frame (framepos_t f, GdkEvent const * event, bool snap) const
|
||||||
{
|
{
|
||||||
framepos_t pos = 0;
|
MusicFrame pos (f, 0);
|
||||||
|
|
||||||
if (f > _pointer_frame_offset) {
|
if (f > _pointer_frame_offset) {
|
||||||
pos = f - _pointer_frame_offset;
|
pos.frame = f - _pointer_frame_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap) {
|
if (snap) {
|
||||||
@ -343,14 +343,14 @@ Drag::adjusted_frame (framepos_t f, GdkEvent const * event, bool snap) const
|
|||||||
framepos_t
|
framepos_t
|
||||||
Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const
|
Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const
|
||||||
{
|
{
|
||||||
return adjusted_frame (_drags->current_pointer_frame (), event, snap);
|
return adjusted_frame (_drags->current_pointer_frame (), event, snap).frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
frameoffset_t
|
frameoffset_t
|
||||||
Drag::snap_delta (guint state) const
|
Drag::snap_delta (guint state) const
|
||||||
{
|
{
|
||||||
if (ArdourKeyboard::indicates_snap_delta (state)) {
|
if (ArdourKeyboard::indicates_snap_delta (state)) {
|
||||||
return _snap_delta;
|
return _snap_delta.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -373,11 +373,11 @@ Drag::current_pointer_y () const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Drag::setup_snap_delta (framepos_t pos)
|
Drag::setup_snap_delta (MusicFrame pos)
|
||||||
{
|
{
|
||||||
framepos_t temp = pos;
|
MusicFrame snap (pos);
|
||||||
_editor->snap_to (temp, ARDOUR::RoundNearest, false, true);
|
_editor->snap_to (snap, ARDOUR::RoundNearest, false, true);
|
||||||
_snap_delta = temp - pos;
|
_snap_delta = snap - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -513,7 +513,7 @@ Drag::show_verbose_cursor_text (string const & text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Region>
|
boost::shared_ptr<Region>
|
||||||
Drag::add_midi_region (MidiTimeAxisView* view, bool commit, const int32_t sub_num)
|
Drag::add_midi_region (MidiTimeAxisView* view, bool commit)
|
||||||
{
|
{
|
||||||
if (_editor->session()) {
|
if (_editor->session()) {
|
||||||
const TempoMap& map (_editor->session()->tempo_map());
|
const TempoMap& map (_editor->session()->tempo_map());
|
||||||
@ -522,7 +522,7 @@ Drag::add_midi_region (MidiTimeAxisView* view, bool commit, const int32_t sub_nu
|
|||||||
might be wrong.
|
might be wrong.
|
||||||
*/
|
*/
|
||||||
framecnt_t len = map.frame_at_beat (max (0.0, map.beat_at_frame (pos)) + 1.0) - pos;
|
framecnt_t len = map.frame_at_beat (max (0.0, map.beat_at_frame (pos)) + 1.0) - pos;
|
||||||
return view->add_region (grab_frame(), len, commit, sub_num);
|
return view->add_region (grab_frame(), len, commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::shared_ptr<Region>();
|
return boost::shared_ptr<Region>();
|
||||||
@ -599,33 +599,11 @@ RegionDrag::find_time_axis_view (TimeAxisView* t) const
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** determines if @pos is the closest frame to an exact musical division when using SnapMagnetic.
|
|
||||||
* (SnapMagnetic may snap to an exact division or no division at all).
|
|
||||||
* this is a hotfix for musical region position/trim. we should really
|
|
||||||
* deliver musical divisors when snapping magnetically to avoid this.
|
|
||||||
*/
|
|
||||||
int32_t
|
|
||||||
RegionDrag::current_music_divisor (framepos_t pos, int32_t button_state)
|
|
||||||
{
|
|
||||||
int32_t divisions = _editor->get_grid_music_divisions (button_state);
|
|
||||||
|
|
||||||
if (_editor->snap_mode() == Editing::SnapMagnetic && !ArdourKeyboard::indicates_snap (button_state)) {
|
|
||||||
TempoMap& tmap (_editor->session()->tempo_map());
|
|
||||||
const framepos_t exact_qn_pos = tmap.frame_at_quarter_note (tmap.exact_qn_at_frame (pos, divisions));
|
|
||||||
|
|
||||||
if (pos != exact_qn_pos) {
|
|
||||||
/* magnetic has not snapped */
|
|
||||||
divisions = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return divisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
|
RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
|
||||||
: RegionDrag (e, i, p, v)
|
: RegionDrag (e, i, p, v)
|
||||||
, _brushing (b)
|
, _brushing (b)
|
||||||
, _ignore_video_lock (false)
|
, _ignore_video_lock (false)
|
||||||
|
, _last_position (0, 0)
|
||||||
, _total_x_delta (0)
|
, _total_x_delta (0)
|
||||||
, _last_pointer_time_axis_view (0)
|
, _last_pointer_time_axis_view (0)
|
||||||
, _last_pointer_layer (0)
|
, _last_pointer_layer (0)
|
||||||
@ -640,9 +618,9 @@ void
|
|||||||
RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
{
|
{
|
||||||
Drag::start_grab (event, cursor);
|
Drag::start_grab (event, cursor);
|
||||||
setup_snap_delta (_last_frame_position);
|
setup_snap_delta (_last_position);
|
||||||
|
|
||||||
show_verbose_cursor_time (_last_frame_position);
|
show_verbose_cursor_time (_last_position.frame);
|
||||||
|
|
||||||
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (current_pointer_y ());
|
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (current_pointer_y ());
|
||||||
if (tv.first) {
|
if (tv.first) {
|
||||||
@ -662,14 +640,13 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_region_position)
|
RegionMotionDrag::compute_x_delta (GdkEvent const * event, MusicFrame* pending_region_position)
|
||||||
{
|
{
|
||||||
/* compute the amount of pointer motion in frames, and where
|
/* compute the amount of pointer motion in frames, and where
|
||||||
the region would be if we moved it by that much.
|
the region would be if we moved it by that much.
|
||||||
*/
|
*/
|
||||||
*pending_region_position = adjusted_frame (_drags->current_pointer_frame (), event, false);
|
*pending_region_position = adjusted_frame (_drags->current_pointer_frame (), event, false);
|
||||||
|
|
||||||
framepos_t sync_frame;
|
|
||||||
framecnt_t sync_offset;
|
framecnt_t sync_offset;
|
||||||
int32_t sync_dir;
|
int32_t sync_dir;
|
||||||
|
|
||||||
@ -677,34 +654,35 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r
|
|||||||
|
|
||||||
/* we don't handle a sync point that lies before zero.
|
/* we don't handle a sync point that lies before zero.
|
||||||
*/
|
*/
|
||||||
if (sync_dir >= 0 || (sync_dir < 0 && *pending_region_position >= sync_offset)) {
|
if (sync_dir >= 0 || (sync_dir < 0 && pending_region_position->frame >= sync_offset)) {
|
||||||
|
|
||||||
framecnt_t const sd = snap_delta (event->button.state);
|
framecnt_t const sd = snap_delta (event->button.state);
|
||||||
sync_frame = *pending_region_position + (sync_dir * sync_offset) + sd;
|
MusicFrame sync_snap (pending_region_position->frame + (sync_dir * sync_offset) + sd, 0);
|
||||||
|
_editor->snap_to_with_modifier (sync_snap, event);
|
||||||
_editor->snap_to_with_modifier (sync_frame, event);
|
if (sync_offset == 0 && sd == 0) {
|
||||||
|
*pending_region_position = sync_snap;
|
||||||
*pending_region_position = _primary->region()->adjust_to_sync (sync_frame) - sd;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*pending_region_position = _last_frame_position;
|
pending_region_position->set (_primary->region()->adjust_to_sync (sync_snap.frame) - sd, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*pending_region_position = _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pending_region_position > max_framepos - _primary->region()->length()) {
|
if (pending_region_position->frame > max_framepos - _primary->region()->length()) {
|
||||||
*pending_region_position = _last_frame_position;
|
*pending_region_position = _last_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
double dx = 0;
|
double dx = 0;
|
||||||
|
|
||||||
bool const x_move_allowed = !_x_constrained;
|
bool const x_move_allowed = !_x_constrained;
|
||||||
|
|
||||||
if ((*pending_region_position != _last_frame_position) && x_move_allowed) {
|
if ((pending_region_position->frame != _last_position.frame) && x_move_allowed) {
|
||||||
|
|
||||||
/* x movement since last time (in pixels) */
|
/* x movement since last time (in pixels) */
|
||||||
dx = (static_cast<double> (*pending_region_position) - _last_frame_position) / _editor->samples_per_pixel;
|
dx = (static_cast<double> (pending_region_position->frame) - _last_position.frame) / _editor->samples_per_pixel;
|
||||||
|
|
||||||
/* total x movement */
|
/* total x movement */
|
||||||
framecnt_t total_dx = *pending_region_position;
|
framecnt_t total_dx = pending_region_position->frame;
|
||||||
if (regions_came_from_canvas()) {
|
if (regions_came_from_canvas()) {
|
||||||
total_dx = total_dx - grab_frame ();
|
total_dx = total_dx - grab_frame ();
|
||||||
}
|
}
|
||||||
@ -713,7 +691,7 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r
|
|||||||
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
|
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||||
if ((i->view->region()->position() + total_dx) < 0) {
|
if ((i->view->region()->position() + total_dx) < 0) {
|
||||||
dx = 0;
|
dx = 0;
|
||||||
*pending_region_position = _last_frame_position;
|
*pending_region_position = _last_position;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -954,9 +932,9 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Work out the change in x */
|
/* Work out the change in x */
|
||||||
framepos_t pending_region_position;
|
MusicFrame pending_region_position (0, 0);
|
||||||
double const x_delta = compute_x_delta (event, &pending_region_position);
|
double const x_delta = compute_x_delta (event, &pending_region_position);
|
||||||
_last_frame_position = pending_region_position;
|
_last_position = pending_region_position;
|
||||||
|
|
||||||
/* calculate hidden tracks in current y-axis delta */
|
/* calculate hidden tracks in current y-axis delta */
|
||||||
int delta_skip = 0;
|
int delta_skip = 0;
|
||||||
@ -1159,7 +1137,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
i->layer += this_delta_layer;
|
i->layer += this_delta_layer;
|
||||||
|
|
||||||
if (_brushing) {
|
if (_brushing) {
|
||||||
_editor->mouse_brush_insert_region (rv, pending_region_position);
|
_editor->mouse_brush_insert_region (rv, pending_region_position.frame);
|
||||||
} else {
|
} else {
|
||||||
Duple track_origin;
|
Duple track_origin;
|
||||||
|
|
||||||
@ -1206,7 +1184,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
_total_x_delta += x_delta;
|
_total_x_delta += x_delta;
|
||||||
|
|
||||||
if (x_delta != 0 && !_brushing) {
|
if (x_delta != 0 && !_brushing) {
|
||||||
show_verbose_cursor_time (_last_frame_position);
|
show_verbose_cursor_time (_last_position.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep track of pointer movement */
|
/* keep track of pointer movement */
|
||||||
@ -1296,12 +1274,7 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
const boost::shared_ptr<const Region> original = rv->region();
|
const boost::shared_ptr<const Region> original = rv->region();
|
||||||
boost::shared_ptr<Region> region_copy;
|
boost::shared_ptr<Region> region_copy;
|
||||||
|
|
||||||
if (rv == _primary) {
|
region_copy = RegionFactory::create (original, true);
|
||||||
region_copy = RegionFactory::create (original, true
|
|
||||||
, current_music_divisor (original->position(), event->button.state));
|
|
||||||
} else {
|
|
||||||
region_copy = RegionFactory::create (original, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need to set this so that the drop zone code can work. This doesn't
|
/* need to set this so that the drop zone code can work. This doesn't
|
||||||
actually put the region into the playlist, but just sets a weak pointer
|
actually put the region into the playlist, but just sets a weak pointer
|
||||||
@ -1399,16 +1372,15 @@ RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred)
|
|||||||
i->view->get_canvas_group()->show ();
|
i->view->get_canvas_group()->show ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const changed_position = (_last_frame_position != _primary->region()->position());
|
bool const changed_position = (_last_position.frame != _primary->region()->position());
|
||||||
bool const changed_tracks = (_time_axis_views[_views.front().time_axis_view] != &_views.front().view->get_time_axis_view());
|
bool const changed_tracks = (_time_axis_views[_views.front().time_axis_view] != &_views.front().view->get_time_axis_view());
|
||||||
framecnt_t const drag_delta = _primary->region()->position() - _last_frame_position;
|
|
||||||
|
|
||||||
if (_copy) {
|
if (_copy) {
|
||||||
|
|
||||||
finished_copy (
|
finished_copy (
|
||||||
changed_position,
|
changed_position,
|
||||||
changed_tracks,
|
changed_tracks,
|
||||||
drag_delta,
|
_last_position,
|
||||||
ev->button.state
|
ev->button.state
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1417,7 +1389,7 @@ RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred)
|
|||||||
finished_no_copy (
|
finished_no_copy (
|
||||||
changed_position,
|
changed_position,
|
||||||
changed_tracks,
|
changed_tracks,
|
||||||
drag_delta,
|
_last_position,
|
||||||
ev->button.state
|
ev->button.state
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1462,15 +1434,16 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr<Region> region,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed_tracks*/, framecnt_t const drag_delta, int32_t const ev_state)
|
RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed_tracks*/, MusicFrame last_position, int32_t const ev_state)
|
||||||
{
|
{
|
||||||
RegionSelection new_views;
|
RegionSelection new_views;
|
||||||
PlaylistSet modified_playlists;
|
PlaylistSet modified_playlists;
|
||||||
RouteTimeAxisView* new_time_axis_view = 0;
|
RouteTimeAxisView* new_time_axis_view = 0;
|
||||||
|
framecnt_t const drag_delta = _primary->region()->position() - _last_position.frame;
|
||||||
|
|
||||||
int32_t divisor = current_music_divisor (_primary->region()->position() - drag_delta, ev_state);
|
|
||||||
TempoMap& tmap (_editor->session()->tempo_map());
|
TempoMap& tmap (_editor->session()->tempo_map());
|
||||||
double qn_delta = _primary->region()->quarter_note() - tmap.exact_qn_at_frame (_primary->region()->position() - drag_delta, divisor);
|
const double last_pos_qn = tmap.exact_qn_at_frame (last_position.frame, last_position.division);
|
||||||
|
const double qn_delta = _primary->region()->quarter_note() - last_pos_qn;
|
||||||
|
|
||||||
if (_brushing) {
|
if (_brushing) {
|
||||||
/* all changes were made during motion event handlers */
|
/* all changes were made during motion event handlers */
|
||||||
@ -1495,12 +1468,16 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t where;
|
MusicFrame where (0, 0);
|
||||||
|
double quarter_note;
|
||||||
|
|
||||||
if (changed_position && !_x_constrained) {
|
if (changed_position && !_x_constrained) {
|
||||||
where = i->view->region()->position() - drag_delta;
|
where.set (i->view->region()->position() - drag_delta, 0);
|
||||||
|
quarter_note = i->view->region()->quarter_note() - qn_delta;
|
||||||
} else {
|
} else {
|
||||||
where = i->view->region()->position();
|
/* region has not moved - divisor will not affect musical pos */
|
||||||
|
where.set (i->view->region()->position(), 0);
|
||||||
|
quarter_note = i->view->region()->quarter_note();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->time_axis_view < 0 || i->time_axis_view >= (int)_time_axis_views.size()) {
|
if (i->time_axis_view < 0 || i->time_axis_view >= (int)_time_axis_views.size()) {
|
||||||
@ -1528,17 +1505,16 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed
|
|||||||
|
|
||||||
if (dest_rtv != 0) {
|
if (dest_rtv != 0) {
|
||||||
RegionView* new_view;
|
RegionView* new_view;
|
||||||
if (i->view == _primary) {
|
if (i->view == _primary && !_x_constrained) {
|
||||||
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, where,
|
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, last_position, last_pos_qn,
|
||||||
modified_playlists, current_music_divisor (where, ev_state));
|
modified_playlists, true);
|
||||||
} else {
|
} else {
|
||||||
if (i->view->region()->position_lock_style() == AudioTime) {
|
if (i->view->region()->position_lock_style() == AudioTime) {
|
||||||
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, where,
|
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, where, quarter_note,
|
||||||
modified_playlists, 0);
|
modified_playlists);
|
||||||
} else {
|
} else {
|
||||||
where = tmap.frame_at_quarter_note (i->view->region()->quarter_note() - qn_delta);
|
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, where, quarter_note,
|
||||||
new_view = insert_region_into_playlist (i->view->region(), dest_rtv, i->layer, where,
|
modified_playlists, true);
|
||||||
modified_playlists, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,7 +1551,7 @@ void
|
|||||||
RegionMoveDrag::finished_no_copy (
|
RegionMoveDrag::finished_no_copy (
|
||||||
bool const changed_position,
|
bool const changed_position,
|
||||||
bool const changed_tracks,
|
bool const changed_tracks,
|
||||||
framecnt_t const drag_delta,
|
MusicFrame last_position,
|
||||||
int32_t const ev_state
|
int32_t const ev_state
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1584,13 +1560,14 @@ RegionMoveDrag::finished_no_copy (
|
|||||||
PlaylistSet frozen_playlists;
|
PlaylistSet frozen_playlists;
|
||||||
set<RouteTimeAxisView*> views_to_update;
|
set<RouteTimeAxisView*> views_to_update;
|
||||||
RouteTimeAxisView* new_time_axis_view = 0;
|
RouteTimeAxisView* new_time_axis_view = 0;
|
||||||
|
framecnt_t const drag_delta = _primary->region()->position() - _last_position.frame;
|
||||||
|
|
||||||
typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
|
typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
|
||||||
PlaylistMapping playlist_mapping;
|
PlaylistMapping playlist_mapping;
|
||||||
|
|
||||||
int32_t divisor = current_music_divisor (_primary->region()->position() - drag_delta, ev_state);
|
|
||||||
TempoMap& tmap (_editor->session()->tempo_map());
|
TempoMap& tmap (_editor->session()->tempo_map());
|
||||||
double qn_delta = _primary->region()->quarter_note() - tmap.exact_qn_at_frame (_primary->region()->position() - drag_delta, divisor);
|
const double last_pos_qn = tmap.exact_qn_at_frame (last_position.frame, last_position.division);
|
||||||
|
const double qn_delta = _primary->region()->quarter_note() - last_pos_qn;
|
||||||
|
|
||||||
std::set<boost::shared_ptr<const Region> > uniq;
|
std::set<boost::shared_ptr<const Region> > uniq;
|
||||||
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
|
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
|
||||||
@ -1640,12 +1617,15 @@ RegionMoveDrag::finished_no_copy (
|
|||||||
|
|
||||||
views_to_update.insert (dest_rtv);
|
views_to_update.insert (dest_rtv);
|
||||||
|
|
||||||
framepos_t where;
|
MusicFrame where (0, 0);
|
||||||
|
double quarter_note;
|
||||||
|
|
||||||
if (changed_position && !_x_constrained) {
|
if (changed_position && !_x_constrained) {
|
||||||
where = rv->region()->position() - drag_delta;
|
where.set (rv->region()->position() - drag_delta, 0);
|
||||||
|
quarter_note = i->view->region()->quarter_note() - qn_delta;
|
||||||
} else {
|
} else {
|
||||||
where = rv->region()->position();
|
where.set (rv->region()->position(), 0);
|
||||||
|
quarter_note = i->view->region()->quarter_note();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed_tracks) {
|
if (changed_tracks) {
|
||||||
@ -1654,21 +1634,20 @@ RegionMoveDrag::finished_no_copy (
|
|||||||
RegionView* new_view;
|
RegionView* new_view;
|
||||||
if (rv == _primary) {
|
if (rv == _primary) {
|
||||||
new_view = insert_region_into_playlist (
|
new_view = insert_region_into_playlist (
|
||||||
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, where,
|
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, last_position, last_pos_qn,
|
||||||
modified_playlists, current_music_divisor (where, ev_state)
|
modified_playlists, true
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (rv->region()->position_lock_style() == AudioTime) {
|
if (rv->region()->position_lock_style() == AudioTime) {
|
||||||
|
|
||||||
new_view = insert_region_into_playlist (
|
new_view = insert_region_into_playlist (
|
||||||
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, where,
|
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, where, quarter_note,
|
||||||
modified_playlists, 0
|
modified_playlists
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
where = tmap.frame_at_quarter_note (rv->region()->quarter_note() - qn_delta);
|
|
||||||
new_view = insert_region_into_playlist (
|
new_view = insert_region_into_playlist (
|
||||||
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, where,
|
RegionFactory::create (rv->region (), true), dest_rtv, dest_layer, where, quarter_note,
|
||||||
modified_playlists, 0
|
modified_playlists, true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1730,13 +1709,14 @@ RegionMoveDrag::finished_no_copy (
|
|||||||
playlist->freeze ();
|
playlist->freeze ();
|
||||||
}
|
}
|
||||||
if (rv == _primary) {
|
if (rv == _primary) {
|
||||||
rv->region()->set_position (where, current_music_divisor (where, ev_state));
|
rv->region()->set_position (where.frame, last_position.division);
|
||||||
} else {
|
} else {
|
||||||
if (rv->region()->position_lock_style() == AudioTime) {
|
if (rv->region()->position_lock_style() == AudioTime) {
|
||||||
rv->region()->set_position (where, 0);
|
/* move by frame offset */
|
||||||
|
rv->region()->set_position (where.frame, 0);
|
||||||
} else {
|
} else {
|
||||||
rv->region()->set_position (tmap.frame_at_quarter_note (rv->region()->quarter_note() - qn_delta), 0);
|
/* move by music offset */
|
||||||
|
rv->region()->set_position_music (rv->region()->quarter_note() - qn_delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
|
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
|
||||||
@ -1840,9 +1820,10 @@ RegionMoveDrag::insert_region_into_playlist (
|
|||||||
boost::shared_ptr<Region> region,
|
boost::shared_ptr<Region> region,
|
||||||
RouteTimeAxisView* dest_rtv,
|
RouteTimeAxisView* dest_rtv,
|
||||||
layer_t dest_layer,
|
layer_t dest_layer,
|
||||||
framecnt_t where,
|
MusicFrame where,
|
||||||
|
double quarter_note,
|
||||||
PlaylistSet& modified_playlists,
|
PlaylistSet& modified_playlists,
|
||||||
const int32_t sub_num
|
bool for_music
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Playlist> dest_playlist = dest_rtv->playlist ();
|
boost::shared_ptr<Playlist> dest_playlist = dest_rtv->playlist ();
|
||||||
@ -1859,7 +1840,11 @@ RegionMoveDrag::insert_region_into_playlist (
|
|||||||
if (r.second) {
|
if (r.second) {
|
||||||
dest_playlist->clear_changes ();
|
dest_playlist->clear_changes ();
|
||||||
}
|
}
|
||||||
dest_playlist->add_region (region, where, 1.0, false, sub_num);
|
if (for_music) {
|
||||||
|
dest_playlist->add_region (region, where.frame, 1.0, false, where.division, quarter_note, true);
|
||||||
|
} else {
|
||||||
|
dest_playlist->add_region (region, where.frame, 1.0, false, where.division);
|
||||||
|
}
|
||||||
|
|
||||||
if (dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded) {
|
if (dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded) {
|
||||||
dest_playlist->set_layer (region, dest_layer);
|
dest_playlist->set_layer (region, dest_layer);
|
||||||
@ -1954,13 +1939,13 @@ RegionMoveDrag::RegionMoveDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p,
|
|||||||
speed = rtv->track()->speed ();
|
speed = rtv->track()->speed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_frame_position = static_cast<framepos_t> (_primary->region()->position() / speed);
|
_last_position = MusicFrame (static_cast<framepos_t> (_primary->region()->position() / speed), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RegionMoveDrag::setup_pointer_frame_offset ()
|
RegionMoveDrag::setup_pointer_frame_offset ()
|
||||||
{
|
{
|
||||||
_pointer_frame_offset = raw_grab_frame() - _last_frame_position;
|
_pointer_frame_offset = raw_grab_frame() - _last_position.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr<Region> r, RouteTimeAxisView* v, framepos_t pos)
|
RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr<Region> r, RouteTimeAxisView* v, framepos_t pos)
|
||||||
@ -1977,7 +1962,7 @@ RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr<Region> r, Rout
|
|||||||
_primary->set_position (pos, 0);
|
_primary->set_position (pos, 0);
|
||||||
_views.push_back (DraggingView (_primary, this, v));
|
_views.push_back (DraggingView (_primary, this, v));
|
||||||
|
|
||||||
_last_frame_position = pos;
|
_last_position = MusicFrame (pos, 0);
|
||||||
|
|
||||||
_item = _primary->get_canvas_group ();
|
_item = _primary->get_canvas_group ();
|
||||||
}
|
}
|
||||||
@ -1997,11 +1982,11 @@ RegionInsertDrag::finished (GdkEvent * event, bool)
|
|||||||
|
|
||||||
_editor->begin_reversible_command (Operations::insert_region);
|
_editor->begin_reversible_command (Operations::insert_region);
|
||||||
playlist->clear_changes ();
|
playlist->clear_changes ();
|
||||||
playlist->add_region (_primary->region (), _last_frame_position);
|
playlist->add_region (_primary->region (), _last_position.frame, _editor->get_grid_music_divisions (event->button.state));
|
||||||
|
|
||||||
// Mixbus doesn't seem to ripple when inserting regions from the list: should we? yes, probably
|
// Mixbus doesn't seem to ripple when inserting regions from the list: should we? yes, probably
|
||||||
if (Config->get_edit_mode() == Ripple) {
|
if (Config->get_edit_mode() == Ripple) {
|
||||||
playlist->ripple (_last_frame_position, _primary->region()->length(), _primary->region());
|
playlist->ripple (_last_position.frame, _primary->region()->length(), _primary->region());
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor->session()->add_command (new StatefulDiffCommand (playlist));
|
_editor->session()->add_command (new StatefulDiffCommand (playlist));
|
||||||
@ -2278,7 +2263,7 @@ RegionRippleDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
|
|
||||||
framepos_t where = adjusted_current_frame (event);
|
framepos_t where = adjusted_current_frame (event);
|
||||||
assert (where >= 0);
|
assert (where >= 0);
|
||||||
framepos_t after;
|
MusicFrame after (0, 0);
|
||||||
double delta = compute_x_delta (event, &after);
|
double delta = compute_x_delta (event, &after);
|
||||||
|
|
||||||
framecnt_t amount = _editor->pixel_to_sample (delta);
|
framecnt_t amount = _editor->pixel_to_sample (delta);
|
||||||
@ -2328,7 +2313,7 @@ RegionRippleDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
prev_amount += amount;
|
prev_amount += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_frame_position = after;
|
_last_position = after;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2409,7 +2394,7 @@ RegionCreateDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
{
|
{
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
_editor->begin_reversible_command (_("create region"));
|
_editor->begin_reversible_command (_("create region"));
|
||||||
_region = add_midi_region (_view, false, _editor->get_grid_music_divisions (event->button.state));
|
_region = add_midi_region (_view, false);
|
||||||
_view->playlist()->freeze ();
|
_view->playlist()->freeze ();
|
||||||
} else {
|
} else {
|
||||||
if (_region) {
|
if (_region) {
|
||||||
@ -2435,7 +2420,7 @@ void
|
|||||||
RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
|
RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||||
{
|
{
|
||||||
if (!movement_occurred) {
|
if (!movement_occurred) {
|
||||||
add_midi_region (_view, true, _editor->get_grid_music_divisions (event->button.state));
|
add_midi_region (_view, true);
|
||||||
} else {
|
} else {
|
||||||
_view->playlist()->thaw ();
|
_view->playlist()->thaw ();
|
||||||
_editor->commit_reversible_command();
|
_editor->commit_reversible_command();
|
||||||
@ -2867,7 +2852,7 @@ TrimDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
|
|||||||
framecnt_t const region_length = (framecnt_t) (_primary->region()->length() / speed);
|
framecnt_t const region_length = (framecnt_t) (_primary->region()->length() / speed);
|
||||||
|
|
||||||
framepos_t const pf = adjusted_current_frame (event);
|
framepos_t const pf = adjusted_current_frame (event);
|
||||||
setup_snap_delta (region_start);
|
setup_snap_delta (MusicFrame (region_start, 0));
|
||||||
|
|
||||||
if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::trim_contents_modifier ())) {
|
if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::trim_contents_modifier ())) {
|
||||||
/* Move the contents of the region around without changing the region bounds */
|
/* Move the contents of the region around without changing the region bounds */
|
||||||
@ -2930,8 +2915,8 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
if (tv && tv->is_track()) {
|
if (tv && tv->is_track()) {
|
||||||
speed = tv->track()->speed();
|
speed = tv->track()->speed();
|
||||||
}
|
}
|
||||||
framecnt_t adj_frame = adjusted_frame (_drags->current_pointer_frame () + snap_delta (event->button.state), event, true);
|
MusicFrame adj_frame = adjusted_frame (_drags->current_pointer_frame () + snap_delta (event->button.state), event, true);
|
||||||
framecnt_t dt = adj_frame - raw_grab_frame () + _pointer_frame_offset - snap_delta (event->button.state);
|
framecnt_t dt = adj_frame.frame - raw_grab_frame () + _pointer_frame_offset - snap_delta (event->button.state);
|
||||||
|
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
|
|
||||||
@ -3012,13 +2997,11 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t divisions = current_music_divisor (adj_frame, event->button.state);
|
|
||||||
|
|
||||||
switch (_operation) {
|
switch (_operation) {
|
||||||
case StartTrim:
|
case StartTrim:
|
||||||
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||||
bool changed = i->view->trim_front (i->initial_position + dt, non_overlap_trim
|
bool changed = i->view->trim_front (i->initial_position + dt, non_overlap_trim
|
||||||
, divisions);
|
, adj_frame.division);
|
||||||
|
|
||||||
if (changed && _preserve_fade_anchor) {
|
if (changed && _preserve_fade_anchor) {
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (i->view);
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (i->view);
|
||||||
@ -3037,7 +3020,7 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
|
|
||||||
case EndTrim:
|
case EndTrim:
|
||||||
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||||
bool changed = i->view->trim_end (i->initial_end + dt, non_overlap_trim, divisions);
|
bool changed = i->view->trim_end (i->initial_end + dt, non_overlap_trim, adj_frame.division);
|
||||||
if (changed && _preserve_fade_anchor) {
|
if (changed && _preserve_fade_anchor) {
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (i->view);
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (i->view);
|
||||||
if (arv) {
|
if (arv) {
|
||||||
@ -3156,7 +3139,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* no mouse movement */
|
/* no mouse movement */
|
||||||
if (adjusted_current_frame (event) != adjusted_frame (_drags->current_pointer_frame(), event, false)) {
|
if (adjusted_current_frame (event) != adjusted_frame (_drags->current_pointer_frame(), event, false).frame) {
|
||||||
_editor->point_trim (event, adjusted_current_frame (event));
|
_editor->point_trim (event, adjusted_current_frame (event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3648,14 +3631,14 @@ void
|
|||||||
CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
|
CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
|
||||||
{
|
{
|
||||||
Drag::start_grab (event, c);
|
Drag::start_grab (event, c);
|
||||||
setup_snap_delta (_editor->playhead_cursor->current_frame ());
|
const framepos_t current_frame = _editor->playhead_cursor->current_frame();
|
||||||
|
setup_snap_delta (MusicFrame (current_frame, 0));
|
||||||
|
|
||||||
_grab_zoom = _editor->samples_per_pixel;
|
_grab_zoom = _editor->samples_per_pixel;
|
||||||
|
|
||||||
framepos_t where = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
MusicFrame where (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
_editor->snap_to_with_modifier (where, event);
|
_editor->snap_to_with_modifier (where, event);
|
||||||
|
|
||||||
_editor->_dragging_playhead = true;
|
_editor->_dragging_playhead = true;
|
||||||
|
|
||||||
Session* s = _editor->session ();
|
Session* s = _editor->session ();
|
||||||
@ -3690,16 +3673,18 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_locate (where - snap_delta (event->button.state));
|
fake_locate (where.frame - snap_delta (event->button.state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CursorDrag::motion (GdkEvent* event, bool)
|
CursorDrag::motion (GdkEvent* event, bool)
|
||||||
{
|
{
|
||||||
framepos_t where = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
MusicFrame where (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
_editor->snap_to_with_modifier (where, event);
|
_editor->snap_to_with_modifier (where, event);
|
||||||
if (where != last_pointer_frame()) {
|
|
||||||
fake_locate (where - snap_delta (event->button.state));
|
if (where.frame != last_pointer_frame()) {
|
||||||
|
fake_locate (where.frame - snap_delta (event->button.state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3734,7 +3719,7 @@ CursorDrag::aborted (bool)
|
|||||||
_editor->_dragging_playhead = false;
|
_editor->_dragging_playhead = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor->playhead_cursor->set_position (adjusted_frame (grab_frame (), 0, false));
|
_editor->playhead_cursor->set_position (adjusted_frame (grab_frame (), 0, false).frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
FadeInDrag::FadeInDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
|
FadeInDrag::FadeInDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
|
||||||
@ -3750,7 +3735,8 @@ FadeInDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||||||
|
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (_primary);
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (_primary);
|
||||||
boost::shared_ptr<AudioRegion> const r = arv->audio_region ();
|
boost::shared_ptr<AudioRegion> const r = arv->audio_region ();
|
||||||
setup_snap_delta (r->position ());
|
const int32_t division = _editor->get_grid_music_divisions (event->button.state);
|
||||||
|
setup_snap_delta (MusicFrame (r->position(), division));
|
||||||
|
|
||||||
show_verbose_cursor_duration (r->position(), r->position() + r->fade_in()->back()->when, 32);
|
show_verbose_cursor_duration (r->position(), r->position() + r->fade_in()->back()->when, 32);
|
||||||
}
|
}
|
||||||
@ -3768,18 +3754,19 @@ FadeInDrag::motion (GdkEvent* event, bool)
|
|||||||
{
|
{
|
||||||
framecnt_t fade_length;
|
framecnt_t fade_length;
|
||||||
|
|
||||||
framepos_t pos = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
MusicFrame pos (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
pos -= snap_delta (event->button.state);
|
|
||||||
|
pos.frame -= snap_delta (event->button.state);
|
||||||
|
|
||||||
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
||||||
|
|
||||||
if (pos < (region->position() + 64)) {
|
if (pos.frame < (region->position() + 64)) {
|
||||||
fade_length = 64; // this should be a minimum defined somewhere
|
fade_length = 64; // this should be a minimum defined somewhere
|
||||||
} else if (pos > region->position() + region->length() - region->fade_out()->back()->when) {
|
} else if (pos.frame > region->position() + region->length() - region->fade_out()->back()->when) {
|
||||||
fade_length = region->length() - region->fade_out()->back()->when - 1;
|
fade_length = region->length() - region->fade_out()->back()->when - 1;
|
||||||
} else {
|
} else {
|
||||||
fade_length = pos - region->position();
|
fade_length = pos.frame - region->position();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||||
@ -3804,18 +3791,19 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||||||
}
|
}
|
||||||
|
|
||||||
framecnt_t fade_length;
|
framecnt_t fade_length;
|
||||||
framepos_t pos = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
MusicFrame pos (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
pos -= snap_delta (event->button.state);
|
pos.frame -= snap_delta (event->button.state);
|
||||||
|
|
||||||
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
||||||
|
|
||||||
if (pos < (region->position() + 64)) {
|
if (pos.frame < (region->position() + 64)) {
|
||||||
fade_length = 64; // this should be a minimum defined somewhere
|
fade_length = 64; // this should be a minimum defined somewhere
|
||||||
} else if (pos >= region->position() + region->length() - region->fade_out()->back()->when) {
|
} else if (pos.frame >= region->position() + region->length() - region->fade_out()->back()->when) {
|
||||||
fade_length = region->length() - region->fade_out()->back()->when - 1;
|
fade_length = region->length() - region->fade_out()->back()->when - 1;
|
||||||
} else {
|
} else {
|
||||||
fade_length = pos - region->position();
|
fade_length = pos.frame - region->position();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_command = false;
|
bool in_command = false;
|
||||||
@ -3874,7 +3862,8 @@ FadeOutDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||||||
|
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (_primary);
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (_primary);
|
||||||
boost::shared_ptr<AudioRegion> r = arv->audio_region ();
|
boost::shared_ptr<AudioRegion> r = arv->audio_region ();
|
||||||
setup_snap_delta (r->last_frame ());
|
const int32_t division = _editor->get_grid_music_divisions (event->button.state);
|
||||||
|
setup_snap_delta (MusicFrame (r->last_frame(), division));
|
||||||
|
|
||||||
show_verbose_cursor_duration (r->last_frame() - r->fade_out()->back()->when, r->last_frame());
|
show_verbose_cursor_duration (r->last_frame() - r->fade_out()->back()->when, r->last_frame());
|
||||||
}
|
}
|
||||||
@ -3891,19 +3880,19 @@ void
|
|||||||
FadeOutDrag::motion (GdkEvent* event, bool)
|
FadeOutDrag::motion (GdkEvent* event, bool)
|
||||||
{
|
{
|
||||||
framecnt_t fade_length;
|
framecnt_t fade_length;
|
||||||
|
MusicFrame pos (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
framepos_t pos = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
pos -= snap_delta (event->button.state);
|
pos.frame -= snap_delta (event->button.state);
|
||||||
|
|
||||||
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
||||||
|
|
||||||
if (pos > (region->last_frame() - 64)) {
|
if (pos.frame > (region->last_frame() - 64)) {
|
||||||
fade_length = 64; // this should really be a minimum fade defined somewhere
|
fade_length = 64; // this should really be a minimum fade defined somewhere
|
||||||
} else if (pos <= region->position() + region->fade_in()->back()->when) {
|
} else if (pos.frame <= region->position() + region->fade_in()->back()->when) {
|
||||||
fade_length = region->length() - region->fade_in()->back()->when - 1;
|
fade_length = region->length() - region->fade_in()->back()->when - 1;
|
||||||
} else {
|
} else {
|
||||||
fade_length = region->last_frame() - pos;
|
fade_length = region->last_frame() - pos.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||||
@ -3928,19 +3917,19 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||||||
}
|
}
|
||||||
|
|
||||||
framecnt_t fade_length;
|
framecnt_t fade_length;
|
||||||
|
MusicFrame pos (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
framepos_t pos = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
pos -= snap_delta (event->button.state);
|
pos.frame -= snap_delta (event->button.state);
|
||||||
|
|
||||||
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (_primary->region ());
|
||||||
|
|
||||||
if (pos > (region->last_frame() - 64)) {
|
if (pos.frame > (region->last_frame() - 64)) {
|
||||||
fade_length = 64; // this should really be a minimum fade defined somewhere
|
fade_length = 64; // this should really be a minimum fade defined somewhere
|
||||||
} else if (pos <= region->position() + region->fade_in()->back()->when) {
|
} else if (pos.frame <= region->position() + region->fade_in()->back()->when) {
|
||||||
fade_length = region->length() - region->fade_in()->back()->when - 1;
|
fade_length = region->length() - region->fade_in()->back()->when - 1;
|
||||||
} else {
|
} else {
|
||||||
fade_length = region->last_frame() - pos;
|
fade_length = region->last_frame() - pos.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_command = false;
|
bool in_command = false;
|
||||||
@ -4035,7 +4024,9 @@ MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||||||
} else {
|
} else {
|
||||||
show_verbose_cursor_time (location->end());
|
show_verbose_cursor_time (location->end());
|
||||||
}
|
}
|
||||||
setup_snap_delta (is_start ? location->start() : location->end());
|
const int32_t division = _editor->get_grid_music_divisions (event->button.state);
|
||||||
|
const framepos_t pos = is_start ? location->start() : location->end();
|
||||||
|
setup_snap_delta (MusicFrame (pos, division));
|
||||||
|
|
||||||
Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
|
Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
|
||||||
|
|
||||||
@ -4139,7 +4130,7 @@ MarkerDrag::motion (GdkEvent* event, bool)
|
|||||||
Location *copy_location = 0;
|
Location *copy_location = 0;
|
||||||
framecnt_t const sd = snap_delta (event->button.state);
|
framecnt_t const sd = snap_delta (event->button.state);
|
||||||
|
|
||||||
framecnt_t const newframe = adjusted_frame (_drags->current_pointer_frame () + sd, event, true) - sd;
|
framecnt_t const newframe = adjusted_frame (_drags->current_pointer_frame () + sd, event, true).frame - sd;
|
||||||
framepos_t next = newframe;
|
framepos_t next = newframe;
|
||||||
|
|
||||||
if (Keyboard::modifier_state_contains (event->button.state, ArdourKeyboard::push_points_modifier ())) {
|
if (Keyboard::modifier_state_contains (event->button.state, ArdourKeyboard::push_points_modifier ())) {
|
||||||
@ -4422,8 +4413,9 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
|
|||||||
_fixed_grab_x = _point->get_x() + _editor->sample_to_pixel_unrounded (_point->line().offset());
|
_fixed_grab_x = _point->get_x() + _editor->sample_to_pixel_unrounded (_point->line().offset());
|
||||||
_fixed_grab_y = _point->get_y();
|
_fixed_grab_y = _point->get_y();
|
||||||
|
|
||||||
framepos_t pos = _editor->pixel_to_sample (_fixed_grab_x);
|
const framepos_t pos = _editor->pixel_to_sample (_fixed_grab_x);
|
||||||
setup_snap_delta (pos);
|
const int32_t division = _editor->get_grid_music_divisions (event->button.state);
|
||||||
|
setup_snap_delta (MusicFrame (pos, division));
|
||||||
|
|
||||||
float const fraction = 1 - (_point->get_y() / _point->line().height());
|
float const fraction = 1 - (_point->get_y() / _point->line().height());
|
||||||
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
|
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
|
||||||
@ -4476,13 +4468,14 @@ ControlPointDrag::motion (GdkEvent* event, bool first_motion)
|
|||||||
cy = zero_gain_y;
|
cy = zero_gain_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t cx_frames = _editor->pixel_to_sample (cx) + snap_delta (event->button.state);
|
MusicFrame cx_mf (_editor->pixel_to_sample (cx) + snap_delta (event->button.state), 0);
|
||||||
|
|
||||||
if (!_x_constrained && need_snap) {
|
if (!_x_constrained && need_snap) {
|
||||||
_editor->snap_to_with_modifier (cx_frames, event);
|
_editor->snap_to_with_modifier (cx_mf, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
cx_frames -= snap_delta (event->button.state);
|
cx_mf.frame -= snap_delta (event->button.state);
|
||||||
cx_frames = min (cx_frames, _point->line().maximum_time() + _point->line().offset());
|
cx_mf.frame = min (cx_mf.frame, _point->line().maximum_time() + _point->line().offset());
|
||||||
|
|
||||||
float const fraction = 1.0 - (cy / _point->line().height());
|
float const fraction = 1.0 - (cy / _point->line().height());
|
||||||
|
|
||||||
@ -4492,7 +4485,7 @@ ControlPointDrag::motion (GdkEvent* event, bool first_motion)
|
|||||||
_point->line().start_drag_single (_point, _fixed_grab_x, initial_fraction);
|
_point->line().start_drag_single (_point, _fixed_grab_x, initial_fraction);
|
||||||
}
|
}
|
||||||
pair<double, float> result;
|
pair<double, float> result;
|
||||||
result = _point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index);
|
result = _point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_mf.frame), fraction, false, _pushing, _final_index);
|
||||||
|
|
||||||
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (result.second));
|
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (result.second));
|
||||||
}
|
}
|
||||||
@ -4755,24 +4748,23 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
|
|||||||
framepos_t end;
|
framepos_t end;
|
||||||
double y1;
|
double y1;
|
||||||
double y2;
|
double y2;
|
||||||
|
|
||||||
framepos_t const pf = adjusted_current_frame (event, UIConfiguration::instance().get_rubberbanding_snaps_to_grid());
|
framepos_t const pf = adjusted_current_frame (event, UIConfiguration::instance().get_rubberbanding_snaps_to_grid());
|
||||||
|
MusicFrame grab (grab_frame (), 0);
|
||||||
|
|
||||||
framepos_t grab = grab_frame ();
|
|
||||||
if (UIConfiguration::instance().get_rubberbanding_snaps_to_grid ()) {
|
if (UIConfiguration::instance().get_rubberbanding_snaps_to_grid ()) {
|
||||||
_editor->snap_to_with_modifier (grab, event);
|
_editor->snap_to_with_modifier (grab, event);
|
||||||
} else {
|
} else {
|
||||||
grab = raw_grab_frame ();
|
grab.frame = raw_grab_frame ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* base start and end on initial click position */
|
/* base start and end on initial click position */
|
||||||
|
|
||||||
if (pf < grab) {
|
if (pf < grab.frame) {
|
||||||
start = pf;
|
start = pf;
|
||||||
end = grab;
|
end = grab.frame;
|
||||||
} else {
|
} else {
|
||||||
end = pf;
|
end = pf;
|
||||||
start = grab;
|
start = grab.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_pointer_y() < grab_y()) {
|
if (current_pointer_y() < grab_y()) {
|
||||||
@ -4882,7 +4874,7 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
|
|||||||
/* MIDI track */
|
/* MIDI track */
|
||||||
if (_editor->selection->empty() && _editor->mouse_mode == MouseDraw) {
|
if (_editor->selection->empty() && _editor->mouse_mode == MouseDraw) {
|
||||||
/* nothing selected */
|
/* nothing selected */
|
||||||
add_midi_region (mtv, true, _editor->get_grid_music_divisions(event->button.state));
|
add_midi_region (mtv, true);
|
||||||
do_deselect = false;
|
do_deselect = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4922,7 +4914,8 @@ TimeFXDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||||||
_editor->get_selection().add (_primary);
|
_editor->get_selection().add (_primary);
|
||||||
|
|
||||||
framepos_t where = _primary->region()->position();
|
framepos_t where = _primary->region()->position();
|
||||||
setup_snap_delta (where);
|
const int32_t division = _editor->get_grid_music_divisions (event->button.state);
|
||||||
|
setup_snap_delta (MusicFrame (where, division));
|
||||||
|
|
||||||
show_verbose_cursor_duration (where, adjusted_current_frame (event), 0);
|
show_verbose_cursor_duration (where, adjusted_current_frame (event), 0);
|
||||||
}
|
}
|
||||||
@ -4932,19 +4925,19 @@ TimeFXDrag::motion (GdkEvent* event, bool)
|
|||||||
{
|
{
|
||||||
RegionView* rv = _primary;
|
RegionView* rv = _primary;
|
||||||
StreamView* cv = rv->get_time_axis_view().view ();
|
StreamView* cv = rv->get_time_axis_view().view ();
|
||||||
|
|
||||||
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (grab_y());
|
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (grab_y());
|
||||||
int layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
|
int layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
|
||||||
int layers = tv.first->layer_display() == Overlaid ? 1 : cv->layers();
|
int layers = tv.first->layer_display() == Overlaid ? 1 : cv->layers();
|
||||||
framepos_t pf = _editor->canvas_event_sample (event) + snap_delta (event->button.state);
|
MusicFrame pf (_editor->canvas_event_sample (event) + snap_delta (event->button.state), 0);
|
||||||
_editor->snap_to_with_modifier (pf, event);
|
|
||||||
pf -= snap_delta (event->button.state);
|
|
||||||
|
|
||||||
if (pf > rv->region()->position()) {
|
_editor->snap_to_with_modifier (pf, event);
|
||||||
rv->get_time_axis_view().show_timestretch (rv->region()->position(), pf, layers, layer);
|
pf.frame -= snap_delta (event->button.state);
|
||||||
|
|
||||||
|
if (pf.frame > rv->region()->position()) {
|
||||||
|
rv->get_time_axis_view().show_timestretch (rv->region()->position(), pf.frame, layers, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_verbose_cursor_duration (_primary->region()->position(), pf, 0);
|
show_verbose_cursor_duration (_primary->region()->position(), pf.frame, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -5128,7 +5121,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
framepos_t end = 0;
|
framepos_t end = 0;
|
||||||
framecnt_t length = 0;
|
framecnt_t length = 0;
|
||||||
framecnt_t distance = 0;
|
framecnt_t distance = 0;
|
||||||
|
MusicFrame start_mf (0, 0);
|
||||||
framepos_t const pending_position = adjusted_current_frame (event);
|
framepos_t const pending_position = adjusted_current_frame (event);
|
||||||
|
|
||||||
if (_operation != CreateSelection && pending_position == last_pointer_frame()) {
|
if (_operation != CreateSelection && pending_position == last_pointer_frame()) {
|
||||||
@ -5142,23 +5135,22 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
switch (_operation) {
|
switch (_operation) {
|
||||||
case CreateSelection:
|
case CreateSelection:
|
||||||
{
|
{
|
||||||
framepos_t grab = grab_frame ();
|
MusicFrame grab (grab_frame (), 0);
|
||||||
|
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
grab = adjusted_current_frame (event, false);
|
grab.frame = adjusted_current_frame (event, false);
|
||||||
if (grab < pending_position) {
|
if (grab.frame < pending_position) {
|
||||||
_editor->snap_to (grab, RoundDownMaybe);
|
_editor->snap_to (grab, RoundDownMaybe);
|
||||||
} else {
|
} else {
|
||||||
_editor->snap_to (grab, RoundUpMaybe);
|
_editor->snap_to (grab, RoundUpMaybe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending_position < grab) {
|
if (pending_position < grab.frame) {
|
||||||
start = pending_position;
|
start = pending_position;
|
||||||
end = grab;
|
end = grab.frame;
|
||||||
} else {
|
} else {
|
||||||
end = pending_position;
|
end = pending_position;
|
||||||
start = grab;
|
start = grab.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first drag: Either add to the selection
|
/* first drag: Either add to the selection
|
||||||
@ -5269,9 +5261,11 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
length = end - start;
|
length = end - start;
|
||||||
distance = pending_position - start;
|
distance = pending_position - start;
|
||||||
start = pending_position;
|
start = pending_position;
|
||||||
_editor->snap_to (start);
|
|
||||||
|
|
||||||
end = start + length;
|
start_mf.frame = start;
|
||||||
|
_editor->snap_to (start_mf);
|
||||||
|
|
||||||
|
end = start_mf.frame + length;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5466,15 +5460,15 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
|
|||||||
framepos_t const pf = adjusted_current_frame (event);
|
framepos_t const pf = adjusted_current_frame (event);
|
||||||
|
|
||||||
if (_operation == CreateSkipMarker || _operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) {
|
if (_operation == CreateSkipMarker || _operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) {
|
||||||
framepos_t grab = grab_frame ();
|
MusicFrame grab (grab_frame (), 0);
|
||||||
_editor->snap_to (grab);
|
_editor->snap_to (grab);
|
||||||
|
|
||||||
if (pf < grab_frame()) {
|
if (pf < grab_frame()) {
|
||||||
start = pf;
|
start = pf;
|
||||||
end = grab;
|
end = grab.frame;
|
||||||
} else {
|
} else {
|
||||||
end = pf;
|
end = pf;
|
||||||
start = grab;
|
start = grab.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first drag: Either add to the selection
|
/* first drag: Either add to the selection
|
||||||
@ -5653,7 +5647,7 @@ NoteDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
|
|||||||
_copy = false;
|
_copy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_snap_delta (_region->source_beats_to_absolute_frames (_primary->note()->time ()));
|
setup_snap_delta (MusicFrame (_region->source_beats_to_absolute_frames (_primary->note()->time ()), 0));
|
||||||
|
|
||||||
if (!(_was_selected = _primary->selected())) {
|
if (!(_was_selected = _primary->selected())) {
|
||||||
|
|
||||||
@ -6616,10 +6610,10 @@ RegionCutDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
|
|||||||
void
|
void
|
||||||
RegionCutDrag::motion (GdkEvent* event, bool)
|
RegionCutDrag::motion (GdkEvent* event, bool)
|
||||||
{
|
{
|
||||||
framepos_t pos = _drags->current_pointer_frame();
|
MusicFrame pos (_drags->current_pointer_frame(), 0);
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
|
|
||||||
line->set_position (pos);
|
line->set_position (pos.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -6627,19 +6621,18 @@ RegionCutDrag::finished (GdkEvent* event, bool)
|
|||||||
{
|
{
|
||||||
_editor->get_track_canvas()->canvas()->re_enter();
|
_editor->get_track_canvas()->canvas()->re_enter();
|
||||||
|
|
||||||
framepos_t pos = _drags->current_pointer_frame();
|
|
||||||
_editor->snap_to_with_modifier (pos, event);
|
|
||||||
|
|
||||||
|
MusicFrame pos (_drags->current_pointer_frame(), 0);
|
||||||
|
_editor->snap_to_with_modifier (pos, event);
|
||||||
line->hide ();
|
line->hide ();
|
||||||
|
|
||||||
RegionSelection rs = _editor->get_regions_from_selection_and_mouse (pos);
|
RegionSelection rs = _editor->get_regions_from_selection_and_mouse (pos.frame);
|
||||||
|
|
||||||
if (rs.empty()) {
|
if (rs.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor->split_regions_at (pos, rs, _editor->get_grid_music_divisions (event->button.state),
|
_editor->split_regions_at (pos, rs, false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -144,7 +144,7 @@ public:
|
|||||||
bool motion_handler (GdkEvent*, bool);
|
bool motion_handler (GdkEvent*, bool);
|
||||||
void abort ();
|
void abort ();
|
||||||
|
|
||||||
ARDOUR::framepos_t adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const;
|
ARDOUR::MusicFrame adjusted_frame (ARDOUR::framepos_t, GdkEvent const *, bool snap = true) const;
|
||||||
ARDOUR::framepos_t adjusted_current_frame (GdkEvent const *, bool snap = true) const;
|
ARDOUR::framepos_t adjusted_current_frame (GdkEvent const *, bool snap = true) const;
|
||||||
|
|
||||||
bool was_double_click() const { return _was_double_click; }
|
bool was_double_click() const { return _was_double_click; }
|
||||||
@ -247,9 +247,9 @@ protected:
|
|||||||
double current_pointer_y () const;
|
double current_pointer_y () const;
|
||||||
|
|
||||||
/* sets snap delta from unsnapped pos */
|
/* sets snap delta from unsnapped pos */
|
||||||
void setup_snap_delta (framepos_t pos);
|
void setup_snap_delta (ARDOUR::MusicFrame pos);
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::Region> add_midi_region (MidiTimeAxisView*, bool commit, const int32_t sub_num);
|
boost::shared_ptr<ARDOUR::Region> add_midi_region (MidiTimeAxisView*, bool commit);
|
||||||
|
|
||||||
void show_verbose_cursor_time (framepos_t);
|
void show_verbose_cursor_time (framepos_t);
|
||||||
void show_verbose_cursor_duration (framepos_t, framepos_t, double xoffset = 0);
|
void show_verbose_cursor_duration (framepos_t, framepos_t, double xoffset = 0);
|
||||||
@ -281,7 +281,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.
|
||||||
*/
|
*/
|
||||||
ARDOUR::frameoffset_t _snap_delta;
|
ARDOUR::MusicFrame _snap_delta;
|
||||||
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
CursorContext::Handle _cursor_ctx; ///< cursor change context
|
||||||
bool _constraint_pressed; ///< if the keyboard indicated constraint modifier was pressed on start_grab()
|
bool _constraint_pressed; ///< if the keyboard indicated constraint modifier was pressed on start_grab()
|
||||||
};
|
};
|
||||||
@ -328,7 +328,6 @@ protected:
|
|||||||
std::vector<TimeAxisView*> _time_axis_views;
|
std::vector<TimeAxisView*> _time_axis_views;
|
||||||
int find_time_axis_view (TimeAxisView *) const;
|
int find_time_axis_view (TimeAxisView *) const;
|
||||||
int apply_track_delta (const int start, const int delta, const int skip, const bool distance_only = false) const;
|
int apply_track_delta (const int start, const int delta, const int skip, const bool distance_only = false) const;
|
||||||
int32_t current_music_divisor (framepos_t pos, int32_t button_state);
|
|
||||||
|
|
||||||
int _visible_y_low;
|
int _visible_y_low;
|
||||||
int _visible_y_high;
|
int _visible_y_high;
|
||||||
@ -363,12 +362,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *);
|
double compute_x_delta (GdkEvent const *, ARDOUR::MusicFrame *);
|
||||||
virtual bool y_movement_allowed (int, double, int skip_invisible = 0) const;
|
virtual bool y_movement_allowed (int, double, int skip_invisible = 0) const;
|
||||||
|
|
||||||
bool _brushing;
|
bool _brushing;
|
||||||
bool _ignore_video_lock;
|
bool _ignore_video_lock;
|
||||||
ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged
|
ARDOUR::MusicFrame _last_position; ///< last position of the thing being dragged
|
||||||
double _total_x_delta;
|
double _total_x_delta;
|
||||||
int _last_pointer_time_axis_view;
|
int _last_pointer_time_axis_view;
|
||||||
double _last_pointer_layer;
|
double _last_pointer_layer;
|
||||||
@ -410,14 +409,14 @@ private:
|
|||||||
void finished_no_copy (
|
void finished_no_copy (
|
||||||
bool const,
|
bool const,
|
||||||
bool const,
|
bool const,
|
||||||
ARDOUR::framecnt_t const,
|
ARDOUR::MusicFrame,
|
||||||
int32_t const ev_state
|
int32_t const ev_state
|
||||||
);
|
);
|
||||||
|
|
||||||
void finished_copy (
|
void finished_copy (
|
||||||
bool const,
|
bool const,
|
||||||
bool const,
|
bool const,
|
||||||
ARDOUR::framecnt_t const,
|
ARDOUR::MusicFrame,
|
||||||
int32_t const ev_state
|
int32_t const ev_state
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -425,9 +424,10 @@ private:
|
|||||||
boost::shared_ptr<ARDOUR::Region>,
|
boost::shared_ptr<ARDOUR::Region>,
|
||||||
RouteTimeAxisView*,
|
RouteTimeAxisView*,
|
||||||
ARDOUR::layer_t,
|
ARDOUR::layer_t,
|
||||||
ARDOUR::framecnt_t,
|
ARDOUR::MusicFrame,
|
||||||
|
double quarter_note,
|
||||||
PlaylistSet&,
|
PlaylistSet&,
|
||||||
const int32_t sub_num
|
bool for_music = false
|
||||||
);
|
);
|
||||||
|
|
||||||
void remove_region_from_playlist (
|
void remove_region_from_playlist (
|
||||||
|
@ -43,9 +43,8 @@ Editor::keyboard_selection_finish (bool /*add*/, Editing::EditIgnoreOption ign)
|
|||||||
{
|
{
|
||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start = selection->time.start();
|
MusicFrame start (selection->time.start(), 0);
|
||||||
framepos_t end;
|
framepos_t end;
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
end = _session->audible_frame();
|
end = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
@ -59,7 +58,7 @@ Editor::keyboard_selection_finish (bool /*add*/, Editing::EditIgnoreOption ign)
|
|||||||
if ( (_edit_point == EditAtPlayhead) && selection->tracks.empty() )
|
if ( (_edit_point == EditAtPlayhead) && selection->tracks.empty() )
|
||||||
select_all_tracks();
|
select_all_tracks();
|
||||||
|
|
||||||
selection->set (start, end);
|
selection->set (start.frame, end);
|
||||||
|
|
||||||
//if session is playing a range, cancel that
|
//if session is playing a range, cancel that
|
||||||
if (_session->get_play_range())
|
if (_session->get_play_range())
|
||||||
@ -73,26 +72,25 @@ Editor::keyboard_selection_begin (Editing::EditIgnoreOption ign)
|
|||||||
{
|
{
|
||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start;
|
MusicFrame start (0, 0);
|
||||||
framepos_t end = selection->time.end_frame();
|
MusicFrame end (selection->time.end_frame(), 0);
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
start = _session->audible_frame();
|
start.frame = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
start = get_preferred_edit_position(ign);
|
start.frame = get_preferred_edit_position(ign);
|
||||||
}
|
}
|
||||||
|
|
||||||
//snap the selection start/end
|
//snap the selection start/end
|
||||||
snap_to(start);
|
snap_to(start);
|
||||||
|
|
||||||
//if there's not already a sensible selection endpoint, go "forever"
|
//if there's not already a sensible selection endpoint, go "forever"
|
||||||
if (start > end) {
|
if (start.frame > end.frame) {
|
||||||
#ifdef MIXBUS
|
#ifdef MIXBUS
|
||||||
// 4hours at most.
|
// 4hours at most.
|
||||||
// This works around a visual glitch in red-bordered selection rect.
|
// This works around a visual glitch in red-bordered selection rect.
|
||||||
end = start + _session->nominal_frame_rate() * 60 * 60 * 4;
|
end.frame = start.frame + _session->nominal_frame_rate() * 60 * 60 * 4;
|
||||||
#else
|
#else
|
||||||
end = max_framepos;
|
end.frame = max_framepos;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +98,7 @@ Editor::keyboard_selection_begin (Editing::EditIgnoreOption ign)
|
|||||||
if ( selection->tracks.empty() )
|
if ( selection->tracks.empty() )
|
||||||
select_all_tracks();
|
select_all_tracks();
|
||||||
|
|
||||||
selection->set (start, end);
|
selection->set (start.frame, end.frame);
|
||||||
|
|
||||||
//if session is playing a range, cancel that
|
//if session is playing a range, cancel that
|
||||||
if (_session->get_play_range())
|
if (_session->get_play_range())
|
||||||
|
@ -1269,9 +1269,9 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
|||||||
UIConfiguration::instance().get_follow_edits() &&
|
UIConfiguration::instance().get_follow_edits() &&
|
||||||
!_session->config.get_external_sync()) {
|
!_session->config.get_external_sync()) {
|
||||||
|
|
||||||
framepos_t where = canvas_event_sample (event);
|
MusicFrame where (canvas_event_sample (event), 0);
|
||||||
snap_to (where);
|
snap_to (where);
|
||||||
_session->request_locate (where, false);
|
_session->request_locate (where.frame, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event->button.button) {
|
switch (event->button.button) {
|
||||||
@ -1318,7 +1318,7 @@ Editor::button_release_dispatch (GdkEventButton* ev)
|
|||||||
bool
|
bool
|
||||||
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
|
||||||
{
|
{
|
||||||
framepos_t where = canvas_event_sample (event);
|
MusicFrame where (canvas_event_sample (event), 0);
|
||||||
AutomationTimeAxisView* atv = 0;
|
AutomationTimeAxisView* atv = 0;
|
||||||
|
|
||||||
_press_cursor_ctx.reset();
|
_press_cursor_ctx.reset();
|
||||||
@ -1466,7 +1466,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||||||
case SamplesRulerItem:
|
case SamplesRulerItem:
|
||||||
case MinsecRulerItem:
|
case MinsecRulerItem:
|
||||||
case BBTRulerItem:
|
case BBTRulerItem:
|
||||||
popup_ruler_menu (where, item_type);
|
popup_ruler_menu (where.frame, item_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MarkerItem:
|
case MarkerItem:
|
||||||
@ -1558,7 +1558,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||||||
case MarkerBarItem:
|
case MarkerBarItem:
|
||||||
if (!_dragging_playhead) {
|
if (!_dragging_playhead) {
|
||||||
snap_to_with_modifier (where, event, RoundNearest, true);
|
snap_to_with_modifier (where, event, RoundNearest, true);
|
||||||
mouse_add_new_marker (where);
|
mouse_add_new_marker (where.frame);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1566,14 +1566,14 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||||||
if (!_dragging_playhead) {
|
if (!_dragging_playhead) {
|
||||||
// if we get here then a dragged range wasn't done
|
// if we get here then a dragged range wasn't done
|
||||||
snap_to_with_modifier (where, event, RoundNearest, true);
|
snap_to_with_modifier (where, event, RoundNearest, true);
|
||||||
mouse_add_new_marker (where, true);
|
mouse_add_new_marker (where.frame, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case TempoBarItem:
|
case TempoBarItem:
|
||||||
case TempoCurveItem:
|
case TempoCurveItem:
|
||||||
if (!_dragging_playhead) {
|
if (!_dragging_playhead) {
|
||||||
snap_to_with_modifier (where, event);
|
snap_to_with_modifier (where, event);
|
||||||
mouse_add_new_tempo_event (where);
|
mouse_add_new_tempo_event (where.frame);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1617,7 +1617,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
|||||||
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
|
||||||
atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
|
atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
|
||||||
if (atv) {
|
if (atv) {
|
||||||
atv->add_automation_event (event, where, event->button.y, with_guard_points);
|
atv->add_automation_event (event, where.frame, event->button.y, with_guard_points);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
@ -166,8 +166,7 @@ Editor::redo (uint32_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int32_t sub_num,
|
Editor::split_regions_at (MusicFrame where, RegionSelection& regions, bool snap_frame)
|
||||||
bool snap_frame)
|
|
||||||
{
|
{
|
||||||
bool frozen = false;
|
bool frozen = false;
|
||||||
|
|
||||||
@ -214,7 +213,7 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3
|
|||||||
have something to split.
|
have something to split.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!(*a)->region()->covers (where)) {
|
if (!(*a)->region()->covers (where.frame)) {
|
||||||
++a;
|
++a;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -246,7 +245,7 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3
|
|||||||
|
|
||||||
if (pl) {
|
if (pl) {
|
||||||
pl->clear_changes ();
|
pl->clear_changes ();
|
||||||
pl->split_region ((*a)->region(), where, sub_num);
|
pl->split_region ((*a)->region(), where);
|
||||||
_session->add_command (new StatefulDiffCommand (pl));
|
_session->add_command (new StatefulDiffCommand (pl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +291,7 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) {
|
for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) {
|
||||||
if ((*ri)->region()->position() < where) {
|
if ((*ri)->region()->position() < where.frame) {
|
||||||
// new regions created before the split
|
// new regions created before the split
|
||||||
if (rsas & NewlyCreatedLeft) {
|
if (rsas & NewlyCreatedLeft) {
|
||||||
selection->add (*ri);
|
selection->add (*ri);
|
||||||
@ -4260,7 +4259,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::Beats earliest, bool mid
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add all selected points to the relevant copy ControlLists */
|
/* Add all selected points to the relevant copy ControlLists */
|
||||||
framepos_t start = std::numeric_limits<framepos_t>::max();
|
MusicFrame start (std::numeric_limits<framepos_t>::max(), 0);
|
||||||
for (PointSelection::iterator sel_point = selection->points.begin(); sel_point != selection->points.end(); ++sel_point) {
|
for (PointSelection::iterator sel_point = selection->points.begin(); sel_point != selection->points.end(); ++sel_point) {
|
||||||
boost::shared_ptr<AutomationList> al = (*sel_point)->line().the_list();
|
boost::shared_ptr<AutomationList> al = (*sel_point)->line().the_list();
|
||||||
AutomationList::const_iterator ctrl_evt = (*sel_point)->model ();
|
AutomationList::const_iterator ctrl_evt = (*sel_point)->model ();
|
||||||
@ -4271,7 +4270,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::Beats earliest, bool mid
|
|||||||
earliest = std::min(earliest, Evoral::Beats((*ctrl_evt)->when));
|
earliest = std::min(earliest, Evoral::Beats((*ctrl_evt)->when));
|
||||||
} else {
|
} else {
|
||||||
/* Update earliest session start time in frames */
|
/* Update earliest session start time in frames */
|
||||||
start = std::min(start, (*sel_point)->line().session_position(ctrl_evt));
|
start.frame = std::min(start.frame, (*sel_point)->line().session_position(ctrl_evt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4282,13 +4281,13 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::Beats earliest, bool mid
|
|||||||
}
|
}
|
||||||
earliest.round_down_to_beat();
|
earliest.round_down_to_beat();
|
||||||
} else {
|
} else {
|
||||||
if (start == std::numeric_limits<double>::max()) {
|
if (start.frame == std::numeric_limits<double>::max()) {
|
||||||
start = 0; // Weird... don't offset
|
start.frame = 0; // Weird... don't offset
|
||||||
}
|
}
|
||||||
snap_to(start, RoundDownMaybe);
|
snap_to(start, RoundDownMaybe);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double line_offset = midi ? earliest.to_double() : start;
|
const double line_offset = midi ? earliest.to_double() : start.frame;
|
||||||
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
|
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
|
||||||
/* Correct this copy list so that it is relative to the earliest
|
/* Correct this copy list so that it is relative to the earliest
|
||||||
start time, so relative ordering between points is preserved
|
start time, so relative ordering between points is preserved
|
||||||
@ -4691,22 +4690,21 @@ void
|
|||||||
Editor::paste (float times, bool from_context)
|
Editor::paste (float times, bool from_context)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::CutNPaste, "paste to preferred edit pos\n");
|
DEBUG_TRACE (DEBUG::CutNPaste, "paste to preferred edit pos\n");
|
||||||
|
MusicFrame where (get_preferred_edit_position (EDIT_IGNORE_NONE, from_context), 0);
|
||||||
paste_internal (get_preferred_edit_position (EDIT_IGNORE_NONE, from_context), times, get_grid_music_divisions (0));
|
paste_internal (where.frame, times, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::mouse_paste ()
|
Editor::mouse_paste ()
|
||||||
{
|
{
|
||||||
framepos_t where;
|
MusicFrame where (0, 0);
|
||||||
bool ignored;
|
bool ignored;
|
||||||
|
if (!mouse_frame (where.frame, ignored)) {
|
||||||
if (!mouse_frame (where, ignored)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snap_to (where);
|
snap_to (where);
|
||||||
paste_internal (where, 1, get_grid_music_divisions (0));
|
paste_internal (where.frame, 1, where.division);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -6171,10 +6169,10 @@ Editor::update_region_fade_visibility ()
|
|||||||
void
|
void
|
||||||
Editor::set_edit_point ()
|
Editor::set_edit_point ()
|
||||||
{
|
{
|
||||||
framepos_t where;
|
|
||||||
bool ignored;
|
bool ignored;
|
||||||
|
MusicFrame where (0, 0);
|
||||||
|
|
||||||
if (!mouse_frame (where, ignored)) {
|
if (!mouse_frame (where.frame, ignored)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6182,7 +6180,7 @@ Editor::set_edit_point ()
|
|||||||
|
|
||||||
if (selection->markers.empty()) {
|
if (selection->markers.empty()) {
|
||||||
|
|
||||||
mouse_add_new_marker (where);
|
mouse_add_new_marker (where.frame);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bool ignored;
|
bool ignored;
|
||||||
@ -6190,7 +6188,7 @@ Editor::set_edit_point ()
|
|||||||
Location* loc = find_location_from_marker (selection->markers.front(), ignored);
|
Location* loc = find_location_from_marker (selection->markers.front(), ignored);
|
||||||
|
|
||||||
if (loc) {
|
if (loc) {
|
||||||
loc->move_to (where, get_grid_music_divisions(0));
|
loc->move_to (where.frame, where.division);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6201,17 +6199,17 @@ Editor::set_playhead_cursor ()
|
|||||||
if (entered_marker) {
|
if (entered_marker) {
|
||||||
_session->request_locate (entered_marker->position(), _session->transport_rolling());
|
_session->request_locate (entered_marker->position(), _session->transport_rolling());
|
||||||
} else {
|
} else {
|
||||||
framepos_t where;
|
MusicFrame where (0, 0);
|
||||||
bool ignored;
|
bool ignored;
|
||||||
|
|
||||||
if (!mouse_frame (where, ignored)) {
|
if (!mouse_frame (where.frame, ignored)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snap_to (where);
|
snap_to (where);
|
||||||
|
|
||||||
if (_session) {
|
if (_session) {
|
||||||
_session->request_locate (where, _session->transport_rolling());
|
_session->request_locate (where.frame, _session->transport_rolling());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6239,18 +6237,16 @@ Editor::split_region ()
|
|||||||
if (current_mouse_mode() == MouseObject) { //don't try this for Internal Edit, Stretch, Draw, etc.
|
if (current_mouse_mode() == MouseObject) { //don't try this for Internal Edit, Stretch, Draw, etc.
|
||||||
|
|
||||||
RegionSelection rs = get_regions_from_selection_and_edit_point ();
|
RegionSelection rs = get_regions_from_selection_and_edit_point ();
|
||||||
|
const framepos_t pos = get_preferred_edit_position();
|
||||||
framepos_t where = get_preferred_edit_position ();
|
const int32_t division = get_grid_music_divisions (0);
|
||||||
|
MusicFrame where (pos, division);
|
||||||
|
|
||||||
if (rs.empty()) {
|
if (rs.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap_musical()) {
|
split_regions_at (where, rs);
|
||||||
split_regions_at (where, rs, get_grid_music_divisions (0));
|
|
||||||
} else {
|
|
||||||
split_regions_at (where, rs, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6458,7 +6454,7 @@ Editor::set_punch_start_from_edit_point ()
|
|||||||
{
|
{
|
||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start = 0;
|
MusicFrame start (0, 0);
|
||||||
framepos_t end = max_framepos;
|
framepos_t end = max_framepos;
|
||||||
|
|
||||||
//use the existing punch end, if any
|
//use the existing punch end, if any
|
||||||
@ -6468,20 +6464,20 @@ Editor::set_punch_start_from_edit_point ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
start = _session->audible_frame();
|
start.frame = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
start = get_preferred_edit_position();
|
start.frame = get_preferred_edit_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
//snap the selection start/end
|
//snap the selection start/end
|
||||||
snap_to(start);
|
snap_to(start);
|
||||||
|
|
||||||
//if there's not already a sensible selection endpoint, go "forever"
|
//if there's not already a sensible selection endpoint, go "forever"
|
||||||
if ( start > end ) {
|
if (start.frame > end ) {
|
||||||
end = max_framepos;
|
end = max_framepos;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_punch_range (start, end, _("set punch start from EP"));
|
set_punch_range (start.frame, end, _("set punch start from EP"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6492,7 +6488,7 @@ Editor::set_punch_end_from_edit_point ()
|
|||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start = 0;
|
framepos_t start = 0;
|
||||||
framepos_t end = max_framepos;
|
MusicFrame end (max_framepos, 0);
|
||||||
|
|
||||||
//use the existing punch start, if any
|
//use the existing punch start, if any
|
||||||
Location* tpl = transport_punch_location();
|
Location* tpl = transport_punch_location();
|
||||||
@ -6501,15 +6497,15 @@ Editor::set_punch_end_from_edit_point ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
end = _session->audible_frame();
|
end.frame = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
end = get_preferred_edit_position();
|
end.frame = get_preferred_edit_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
//snap the selection start/end
|
//snap the selection start/end
|
||||||
snap_to (end);
|
snap_to (end);
|
||||||
|
|
||||||
set_punch_range (start, end, _("set punch end from EP"));
|
set_punch_range (start, end.frame, _("set punch end from EP"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6519,7 +6515,7 @@ Editor::set_loop_start_from_edit_point ()
|
|||||||
{
|
{
|
||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start = 0;
|
MusicFrame start (0, 0);
|
||||||
framepos_t end = max_framepos;
|
framepos_t end = max_framepos;
|
||||||
|
|
||||||
//use the existing loop end, if any
|
//use the existing loop end, if any
|
||||||
@ -6529,20 +6525,20 @@ Editor::set_loop_start_from_edit_point ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
start = _session->audible_frame();
|
start.frame = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
start = get_preferred_edit_position();
|
start.frame = get_preferred_edit_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
//snap the selection start/end
|
//snap the selection start/end
|
||||||
snap_to (start);
|
snap_to (start);
|
||||||
|
|
||||||
//if there's not already a sensible selection endpoint, go "forever"
|
//if there's not already a sensible selection endpoint, go "forever"
|
||||||
if ( start > end ) {
|
if (start.frame > end ) {
|
||||||
end = max_framepos;
|
end = max_framepos;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_loop_range (start, end, _("set loop start from EP"));
|
set_loop_range (start.frame, end, _("set loop start from EP"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6553,7 +6549,7 @@ Editor::set_loop_end_from_edit_point ()
|
|||||||
if (_session) {
|
if (_session) {
|
||||||
|
|
||||||
framepos_t start = 0;
|
framepos_t start = 0;
|
||||||
framepos_t end = max_framepos;
|
MusicFrame end (max_framepos, 0);
|
||||||
|
|
||||||
//use the existing loop start, if any
|
//use the existing loop start, if any
|
||||||
Location* tpl = transport_loop_location();
|
Location* tpl = transport_loop_location();
|
||||||
@ -6562,15 +6558,15 @@ Editor::set_loop_end_from_edit_point ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
if ((_edit_point == EditAtPlayhead) && _session->transport_rolling()) {
|
||||||
end = _session->audible_frame();
|
end.frame = _session->audible_frame();
|
||||||
} else {
|
} else {
|
||||||
end = get_preferred_edit_position();
|
end.frame = get_preferred_edit_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
//snap the selection start/end
|
//snap the selection start/end
|
||||||
snap_to(end);
|
snap_to(end);
|
||||||
|
|
||||||
set_loop_range (start, end, _("set loop end from EP"));
|
set_loop_range (start, end.frame, _("set loop end from EP"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6985,9 +6981,9 @@ Editor::snap_regions_to_grid ()
|
|||||||
pl->freeze();
|
pl->freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t start_frame = (*r)->region()->first_frame ();
|
MusicFrame start ((*r)->region()->first_frame (), 0);
|
||||||
snap_to (start_frame);
|
snap_to (start);
|
||||||
(*r)->region()->set_position (start_frame);
|
(*r)->region()->set_position (start.frame, start.division);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (used_playlists.size() > 0) {
|
while (used_playlists.size() > 0) {
|
||||||
@ -7187,11 +7183,12 @@ Editor::playhead_forward_to_grid ()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t pos = playhead_cursor->current_frame ();
|
MusicFrame pos (playhead_cursor->current_frame (), 0);
|
||||||
if (pos < max_framepos - 1) {
|
|
||||||
pos += 2;
|
if (pos.frame < max_framepos - 1) {
|
||||||
|
pos.frame += 2;
|
||||||
snap_to_internal (pos, RoundUpAlways, false);
|
snap_to_internal (pos, RoundUpAlways, false);
|
||||||
_session->request_locate (pos);
|
_session->request_locate (pos.frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7203,11 +7200,12 @@ Editor::playhead_backward_to_grid ()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t pos = playhead_cursor->current_frame ();
|
MusicFrame pos (playhead_cursor->current_frame (), 0);
|
||||||
if (pos > 2) {
|
|
||||||
pos -= 2;
|
if (pos.frame > 2) {
|
||||||
|
pos.frame -= 2;
|
||||||
snap_to_internal (pos, RoundDownAlways, false);
|
snap_to_internal (pos, RoundDownAlways, false);
|
||||||
_session->request_locate (pos);
|
_session->request_locate (pos.frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7472,7 +7470,7 @@ Editor::insert_time (
|
|||||||
|
|
||||||
if (opt == SplitIntersected) {
|
if (opt == SplitIntersected) {
|
||||||
/* non musical split */
|
/* non musical split */
|
||||||
(*i)->split (pos, 0);
|
(*i)->split (MusicFrame (pos, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
(*i)->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
|
(*i)->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
|
||||||
|
@ -3426,21 +3426,20 @@ MidiRegionView::nudge_notes (bool forward, bool fine)
|
|||||||
|
|
||||||
/* use grid */
|
/* use grid */
|
||||||
|
|
||||||
framepos_t next_pos = ref_point;
|
MusicFrame next_pos (ref_point, 0);
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
if (max_framepos - 1 < next_pos) {
|
if (max_framepos - 1 < next_pos.frame) {
|
||||||
next_pos += 1;
|
next_pos.frame += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (next_pos == 0) {
|
if (next_pos.frame == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
next_pos -= 1;
|
next_pos.frame -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackview.editor().snap_to (next_pos, (forward ? RoundUpAlways : RoundDownAlways), false);
|
trackview.editor().snap_to (next_pos, (forward ? RoundUpAlways : RoundDownAlways), false);
|
||||||
const framecnt_t distance = ref_point - next_pos;
|
const framecnt_t distance = ref_point - next_pos.frame;
|
||||||
delta = region_frames_to_region_beats (fabs ((double)distance));
|
delta = region_frames_to_region_beats (fabs ((double)distance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1646,9 +1646,11 @@ MidiTimeAxisView::automation_child_menu_item (Evoral::Parameter param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<MidiRegion>
|
boost::shared_ptr<MidiRegion>
|
||||||
MidiTimeAxisView::add_region (framepos_t pos, framecnt_t length, bool commit, const int32_t sub_num)
|
MidiTimeAxisView::add_region (framepos_t f, framecnt_t length, bool commit)
|
||||||
{
|
{
|
||||||
Editor* real_editor = dynamic_cast<Editor*> (&_editor);
|
Editor* real_editor = dynamic_cast<Editor*> (&_editor);
|
||||||
|
MusicFrame pos (f, 0);
|
||||||
|
|
||||||
if (commit) {
|
if (commit) {
|
||||||
real_editor->begin_reversible_command (Operations::create_region);
|
real_editor->begin_reversible_command (Operations::create_region);
|
||||||
}
|
}
|
||||||
@ -1665,8 +1667,8 @@ MidiTimeAxisView::add_region (framepos_t pos, framecnt_t length, bool commit, co
|
|||||||
|
|
||||||
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
|
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
|
||||||
/* sets beat position */
|
/* sets beat position */
|
||||||
region->set_position (pos, sub_num);
|
region->set_position (pos.frame, pos.division);
|
||||||
playlist()->add_region (region, pos, 1.0, false, sub_num);
|
playlist()->add_region (region, pos.frame, 1.0, false, pos.division);
|
||||||
_session->add_command (new StatefulDiffCommand (playlist()));
|
_session->add_command (new StatefulDiffCommand (playlist()));
|
||||||
|
|
||||||
if (commit) {
|
if (commit) {
|
||||||
|
@ -83,7 +83,7 @@ public:
|
|||||||
|
|
||||||
void set_height (uint32_t, TrackHeightMode m = OnlySelf);
|
void set_height (uint32_t, TrackHeightMode m = OnlySelf);
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::MidiRegion> add_region (ARDOUR::framepos_t, ARDOUR::framecnt_t, bool, const int32_t sub_num);
|
boost::shared_ptr<ARDOUR::MidiRegion> add_region (ARDOUR::framepos_t, ARDOUR::framecnt_t, bool);
|
||||||
|
|
||||||
void show_all_automation (bool apply_to_selection = false);
|
void show_all_automation (bool apply_to_selection = false);
|
||||||
void show_existing_automation (bool apply_to_selection = false);
|
void show_existing_automation (bool apply_to_selection = false);
|
||||||
|
@ -148,7 +148,7 @@ class PublicEditor : public Gtkmm2ext::Tabbable {
|
|||||||
* Snap a value according to the current snap setting.
|
* Snap a value according to the current snap setting.
|
||||||
* ensure_snap overrides SnapOff and magnetic snap
|
* ensure_snap overrides SnapOff and magnetic snap
|
||||||
*/
|
*/
|
||||||
virtual void snap_to (framepos_t& first,
|
virtual void snap_to (ARDOUR::MusicFrame& first,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false,
|
bool for_mark = false,
|
||||||
bool ensure_snap = false) = 0;
|
bool ensure_snap = false) = 0;
|
||||||
@ -320,7 +320,7 @@ class PublicEditor : public Gtkmm2ext::Tabbable {
|
|||||||
virtual void restore_editing_space () = 0;
|
virtual void restore_editing_space () = 0;
|
||||||
virtual framepos_t get_preferred_edit_position (Editing::EditIgnoreOption = Editing::EDIT_IGNORE_NONE, bool from_context_menu = false, bool from_outside_canvas = false) = 0;
|
virtual framepos_t get_preferred_edit_position (Editing::EditIgnoreOption = Editing::EDIT_IGNORE_NONE, bool from_context_menu = false, bool from_outside_canvas = false) = 0;
|
||||||
virtual void toggle_meter_updating() = 0;
|
virtual void toggle_meter_updating() = 0;
|
||||||
virtual void split_regions_at (framepos_t, RegionSelection&, const int32_t sub_num, bool snap) = 0;
|
virtual void split_regions_at (ARDOUR::MusicFrame, RegionSelection&, bool snap) = 0;
|
||||||
virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false) = 0;
|
virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false) = 0;
|
||||||
virtual void mouse_add_new_marker (framepos_t where, bool is_cd=false) = 0;
|
virtual void mouse_add_new_marker (framepos_t where, bool is_cd=false) = 0;
|
||||||
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
|
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
|
||||||
@ -435,7 +435,7 @@ class PublicEditor : public Gtkmm2ext::Tabbable {
|
|||||||
virtual ARDOUR::Location* find_location_from_marker (ArdourMarker *, bool &) const = 0;
|
virtual ARDOUR::Location* find_location_from_marker (ArdourMarker *, bool &) const = 0;
|
||||||
virtual ArdourMarker* find_marker_from_location_id (PBD::ID const &, bool) const = 0;
|
virtual ArdourMarker* find_marker_from_location_id (PBD::ID const &, bool) const = 0;
|
||||||
|
|
||||||
virtual void snap_to_with_modifier (framepos_t & first,
|
virtual void snap_to_with_modifier (ARDOUR::MusicFrame& first,
|
||||||
GdkEvent const * ev,
|
GdkEvent const * ev,
|
||||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||||
bool for_mark = false) = 0;
|
bool for_mark = false) = 0;
|
||||||
|
@ -947,20 +947,19 @@ frameoffset_t
|
|||||||
RegionView::snap_frame_to_frame (frameoffset_t x, bool ensure_snap) const
|
RegionView::snap_frame_to_frame (frameoffset_t x, bool ensure_snap) const
|
||||||
{
|
{
|
||||||
PublicEditor& editor = trackview.editor();
|
PublicEditor& editor = trackview.editor();
|
||||||
|
|
||||||
/* x is region relative, convert it to global absolute frames */
|
/* x is region relative, convert it to global absolute frames */
|
||||||
framepos_t const session_frame = x + _region->position();
|
framepos_t const session_frame = x + _region->position();
|
||||||
|
|
||||||
/* try a snap in either direction */
|
/* try a snap in either direction */
|
||||||
framepos_t frame = session_frame;
|
MusicFrame frame (session_frame, 0);
|
||||||
editor.snap_to (frame, RoundNearest, false, ensure_snap);
|
editor.snap_to (frame, RoundNearest, false, ensure_snap);
|
||||||
|
|
||||||
/* if we went off the beginning of the region, snap forwards */
|
/* if we went off the beginning of the region, snap forwards */
|
||||||
if (frame < _region->position ()) {
|
if (frame.frame < _region->position ()) {
|
||||||
frame = session_frame;
|
frame.frame = session_frame;
|
||||||
editor.snap_to (frame, RoundUpAlways, false, ensure_snap);
|
editor.snap_to (frame, RoundUpAlways, false, ensure_snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* back to region relative */
|
/* back to region relative */
|
||||||
return frame - _region->position();
|
return frame.frame - _region->position();
|
||||||
}
|
}
|
||||||
|
@ -116,13 +116,12 @@ StepEditor::prepare_step_edit_region ()
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
const Meter& m = _mtv.session()->tempo_map().meter_at_frame (step_edit_insert_position);
|
const Meter& m = _mtv.session()->tempo_map().meter_at_frame (step_edit_insert_position);
|
||||||
|
|
||||||
double baf = max (0.0, _mtv.session()->tempo_map().beat_at_frame (step_edit_insert_position));
|
double baf = max (0.0, _mtv.session()->tempo_map().beat_at_frame (step_edit_insert_position));
|
||||||
double next_bar_in_beats = baf + m.divisions_per_bar();
|
double next_bar_in_beats = baf + m.divisions_per_bar();
|
||||||
framecnt_t next_bar_pos = _mtv.session()->tempo_map().frame_at_beat (next_bar_in_beats);
|
framecnt_t next_bar_pos = _mtv.session()->tempo_map().frame_at_beat (next_bar_in_beats);
|
||||||
framecnt_t len = next_bar_pos - step_edit_insert_position;
|
framecnt_t len = next_bar_pos - step_edit_insert_position;
|
||||||
|
|
||||||
step_edit_region = _mtv.add_region (step_edit_insert_position, len, true, _editor.get_grid_music_divisions (0));
|
step_edit_region = _mtv.add_region (step_edit_insert_position, len, true);
|
||||||
|
|
||||||
RegionView* rv = _mtv.midi_view()->find_view (step_edit_region);
|
RegionView* rv = _mtv.midi_view()->find_view (step_edit_region);
|
||||||
step_edit_region_view = dynamic_cast<MidiRegionView*>(rv);
|
step_edit_region_view = dynamic_cast<MidiRegionView*>(rv);
|
||||||
@ -411,7 +410,7 @@ StepEditor::step_edit_bar_sync ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
framepos_t fpos = step_edit_region_view->region_beats_to_absolute_frames (step_edit_beat_pos);
|
framepos_t fpos = step_edit_region_view->region_beats_to_absolute_frames (step_edit_beat_pos);
|
||||||
fpos = _session->tempo_map().round_to_bar (fpos, RoundUpAlways);
|
fpos = _session->tempo_map().round_to_bar (fpos, RoundUpAlways).frame;
|
||||||
step_edit_beat_pos = step_edit_region_view->region_frames_to_region_beats (fpos - step_edit_region->position()).round_up_to_beat();
|
step_edit_beat_pos = step_edit_region_view->region_frames_to_region_beats (fpos - step_edit_region->position()).round_up_to_beat();
|
||||||
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
|
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ TempoDialog::tap_tempo_focus_out (GdkEventFocus* )
|
|||||||
MeterDialog::MeterDialog (TempoMap& map, framepos_t frame, const string&)
|
MeterDialog::MeterDialog (TempoMap& map, framepos_t frame, const string&)
|
||||||
: ArdourDialog (_("New Meter"))
|
: ArdourDialog (_("New Meter"))
|
||||||
{
|
{
|
||||||
frame = map.round_to_bar(frame, RoundNearest);
|
frame = map.round_to_bar(frame, RoundNearest).frame;
|
||||||
Timecode::BBT_Time when (map.bbt_at_frame (frame));
|
Timecode::BBT_Time when (map.bbt_at_frame (frame));
|
||||||
Meter meter (map.meter_at_frame (frame));
|
Meter meter (map.meter_at_frame (frame));
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ class LIBARDOUR_API AudioRegion : public Region
|
|||||||
AudioRegion (boost::shared_ptr<AudioSource>);
|
AudioRegion (boost::shared_ptr<AudioSource>);
|
||||||
AudioRegion (const SourceList &);
|
AudioRegion (const SourceList &);
|
||||||
AudioRegion (boost::shared_ptr<const AudioRegion>);
|
AudioRegion (boost::shared_ptr<const AudioRegion>);
|
||||||
AudioRegion (boost::shared_ptr<const AudioRegion>, frameoffset_t offset, const int32_t sub_num);
|
AudioRegion (boost::shared_ptr<const AudioRegion>, ARDOUR::MusicFrame offset);
|
||||||
AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&);
|
AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&);
|
||||||
AudioRegion (SourceList &);
|
AudioRegion (SourceList &);
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
int set_state (const XMLNode&, int version);
|
int set_state (const XMLNode&, int version);
|
||||||
|
|
||||||
bool destroy_region (boost::shared_ptr<Region>);
|
bool destroy_region (boost::shared_ptr<Region>);
|
||||||
|
void _split_region (boost::shared_ptr<Region>, MusicFrame position);
|
||||||
|
|
||||||
void set_note_mode (NoteMode m) { _note_mode = m; }
|
void set_note_mode (NoteMode m) { _note_mode = m; }
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ class LIBARDOUR_API MidiRegion : public Region
|
|||||||
|
|
||||||
MidiRegion (const SourceList&);
|
MidiRegion (const SourceList&);
|
||||||
MidiRegion (boost::shared_ptr<const MidiRegion>);
|
MidiRegion (boost::shared_ptr<const MidiRegion>);
|
||||||
MidiRegion (boost::shared_ptr<const MidiRegion>, frameoffset_t offset, const int32_t sub_num = 0);
|
MidiRegion (boost::shared_ptr<const MidiRegion>, ARDOUR::MusicFrame offset);
|
||||||
|
|
||||||
framecnt_t _read_at (const SourceList&, Evoral::EventSink<framepos_t>& dst,
|
framecnt_t _read_at (const SourceList&, Evoral::EventSink<framepos_t>& dst,
|
||||||
framepos_t position,
|
framepos_t position,
|
||||||
@ -146,6 +146,7 @@ class LIBARDOUR_API MidiRegion : public Region
|
|||||||
void recompute_at_end ();
|
void recompute_at_end ();
|
||||||
|
|
||||||
void set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num);
|
void set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num);
|
||||||
|
void set_position_music_internal (double qn);
|
||||||
void set_length_internal (framecnt_t len, const int32_t sub_num);
|
void set_length_internal (framecnt_t len, const int32_t sub_num);
|
||||||
void set_start_internal (framecnt_t, const int32_t sub_num);
|
void set_start_internal (framecnt_t, const int32_t sub_num);
|
||||||
void trim_to_internal (framepos_t position, framecnt_t length, const int32_t sub_num);
|
void trim_to_internal (framepos_t position, framecnt_t length, const int32_t sub_num);
|
||||||
|
@ -135,14 +135,14 @@ public:
|
|||||||
|
|
||||||
/* Editing operations */
|
/* Editing operations */
|
||||||
|
|
||||||
void add_region (boost::shared_ptr<Region>, framepos_t position, float times = 1, bool auto_partition = false, const int32_t sub_num = 0);
|
void add_region (boost::shared_ptr<Region>, framepos_t position, float times = 1, bool auto_partition = false, int32_t sub_num = 0, double quarter_note = 0.0, bool for_music = false);
|
||||||
void remove_region (boost::shared_ptr<Region>);
|
void remove_region (boost::shared_ptr<Region>);
|
||||||
void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
||||||
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
||||||
void get_source_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
void get_source_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
|
||||||
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, framepos_t pos);
|
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, framepos_t pos);
|
||||||
void split_region (boost::shared_ptr<Region>, framepos_t position, const int32_t sub_num);
|
void split_region (boost::shared_ptr<Region>, MusicFrame position);
|
||||||
void split (framepos_t at, const int32_t sub_num);
|
void split (MusicFrame at);
|
||||||
void shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue);
|
void shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue);
|
||||||
void partition (framepos_t start, framepos_t end, bool cut = false);
|
void partition (framepos_t start, framepos_t end, bool cut = false);
|
||||||
void duplicate (boost::shared_ptr<Region>, framepos_t position, float times);
|
void duplicate (boost::shared_ptr<Region>, framepos_t position, float times);
|
||||||
@ -372,7 +372,7 @@ public:
|
|||||||
|
|
||||||
virtual XMLNode& state (bool);
|
virtual XMLNode& state (bool);
|
||||||
|
|
||||||
bool add_region_internal (boost::shared_ptr<Region>, framepos_t position, const int32_t sub_num = 0);
|
bool add_region_internal (boost::shared_ptr<Region>, framepos_t position, int32_t sub_num = 0, double quarter_note = 0.0, bool for_music = false);
|
||||||
|
|
||||||
int remove_region_internal (boost::shared_ptr<Region>);
|
int remove_region_internal (boost::shared_ptr<Region>);
|
||||||
void copy_regions (RegionList&) const;
|
void copy_regions (RegionList&) const;
|
||||||
@ -390,7 +390,7 @@ public:
|
|||||||
void begin_undo ();
|
void begin_undo ();
|
||||||
void end_undo ();
|
void end_undo ();
|
||||||
|
|
||||||
void _split_region (boost::shared_ptr<Region>, framepos_t position, const int32_t sub_num);
|
virtual void _split_region (boost::shared_ptr<Region>, MusicFrame position);
|
||||||
|
|
||||||
typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
|
typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ class LIBARDOUR_API Region
|
|||||||
void set_length (framecnt_t, const int32_t sub_num);
|
void set_length (framecnt_t, const int32_t sub_num);
|
||||||
void set_start (framepos_t);
|
void set_start (framepos_t);
|
||||||
void set_position (framepos_t, int32_t sub_num = 0);
|
void set_position (framepos_t, int32_t sub_num = 0);
|
||||||
|
void set_position_music (double qn);
|
||||||
void set_initial_position (framepos_t);
|
void set_initial_position (framepos_t);
|
||||||
void special_set_position (framepos_t);
|
void special_set_position (framepos_t);
|
||||||
virtual void update_after_tempo_map_change (bool send_change = true);
|
virtual void update_after_tempo_map_change (bool send_change = true);
|
||||||
@ -346,7 +347,7 @@ class LIBARDOUR_API Region
|
|||||||
Region (boost::shared_ptr<const Region>);
|
Region (boost::shared_ptr<const Region>);
|
||||||
|
|
||||||
/** Construct a region from another region, at an offset within that region */
|
/** Construct a region from another region, at an offset within that region */
|
||||||
Region (boost::shared_ptr<const Region>, frameoffset_t start_offset, const int32_t sub_num);
|
Region (boost::shared_ptr<const Region>, ARDOUR::MusicFrame start_offset);
|
||||||
|
|
||||||
/** Construct a region as a copy of another region, but with different sources */
|
/** Construct a region as a copy of another region, but with different sources */
|
||||||
Region (boost::shared_ptr<const Region>, const SourceList&);
|
Region (boost::shared_ptr<const Region>, const SourceList&);
|
||||||
@ -364,6 +365,7 @@ class LIBARDOUR_API Region
|
|||||||
virtual int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
|
virtual int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
|
||||||
void post_set (const PBD::PropertyChange&);
|
void post_set (const PBD::PropertyChange&);
|
||||||
virtual void set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num);
|
virtual void set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num);
|
||||||
|
virtual void set_position_music_internal (double qn);
|
||||||
virtual void set_length_internal (framecnt_t, const int32_t sub_num);
|
virtual void set_length_internal (framecnt_t, const int32_t sub_num);
|
||||||
virtual void set_start_internal (framecnt_t, const int32_t sub_num = 0);
|
virtual void set_start_internal (framecnt_t, const int32_t sub_num = 0);
|
||||||
bool verify_start_and_length (framepos_t, framecnt_t&);
|
bool verify_start_and_length (framepos_t, framecnt_t&);
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
static PBD::Signal1<void,boost::shared_ptr<Region> > CheckNewRegion;
|
static PBD::Signal1<void,boost::shared_ptr<Region> > CheckNewRegion;
|
||||||
|
|
||||||
/** create a "pure copy" of Region @param other */
|
/** create a "pure copy" of Region @param other */
|
||||||
static boost::shared_ptr<Region> create (boost::shared_ptr<const Region> other, bool announce = false, const int32_t sub_num = 0);
|
static boost::shared_ptr<Region> create (boost::shared_ptr<const Region> other, bool announce = false);
|
||||||
|
|
||||||
/** create a region from a single Source */
|
/** create a region from a single Source */
|
||||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>,
|
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>,
|
||||||
@ -72,8 +72,8 @@ public:
|
|||||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other,
|
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other,
|
||||||
const PBD::PropertyList&, bool announce = true);
|
const PBD::PropertyList&, bool announce = true);
|
||||||
/** create a copy of @param other starting at @param offset within @param other */
|
/** create a copy of @param other starting at @param offset within @param other */
|
||||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, frameoffset_t offset,
|
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, ARDOUR::MusicFrame offset,
|
||||||
const PBD::PropertyList&, bool announce = true, const int32_t sub_num = 0);
|
const PBD::PropertyList&, bool announce = true);
|
||||||
/** create a "copy" of @param other but using a different set of sources @param srcs */
|
/** create a "copy" of @param other but using a different set of sources @param srcs */
|
||||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs,
|
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs,
|
||||||
const PBD::PropertyList&, bool announce = true);
|
const PBD::PropertyList&, bool announce = true);
|
||||||
|
@ -386,10 +386,10 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
|||||||
|
|
||||||
void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls);
|
void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls);
|
||||||
|
|
||||||
framepos_t round_to_bar (framepos_t frame, RoundMode dir);
|
MusicFrame round_to_bar (framepos_t frame, RoundMode dir);
|
||||||
framepos_t round_to_beat (framepos_t frame, RoundMode dir);
|
MusicFrame round_to_beat (framepos_t frame, RoundMode dir);
|
||||||
framepos_t round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir);
|
framepos_t round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir);
|
||||||
framepos_t round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMode dir);
|
MusicFrame round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMode dir);
|
||||||
|
|
||||||
void set_length (framepos_t frames);
|
void set_length (framepos_t frames);
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ private:
|
|||||||
void recompute_meters (Metrics& metrics);
|
void recompute_meters (Metrics& metrics);
|
||||||
void recompute_map (Metrics& metrics, framepos_t end = -1);
|
void recompute_map (Metrics& metrics, framepos_t end = -1);
|
||||||
|
|
||||||
framepos_t round_to_type (framepos_t fr, RoundMode dir, BBTPointType);
|
MusicFrame round_to_type (framepos_t fr, RoundMode dir, BBTPointType);
|
||||||
|
|
||||||
const MeterSection& first_meter() const;
|
const MeterSection& first_meter() const;
|
||||||
MeterSection& first_meter();
|
MeterSection& first_meter();
|
||||||
|
@ -319,6 +319,27 @@ namespace ARDOUR {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* used for translating audio frames to an exact musical position using a note divisor.
|
||||||
|
an exact musical position almost never falls exactly on an audio frame, but for sub-sample
|
||||||
|
musical accuracy we need to derive exact musical locations from a frame position
|
||||||
|
the division follows TempoMap::exact_beat_at_frame().
|
||||||
|
division
|
||||||
|
-1 musical location is the bar closest to frame
|
||||||
|
0 musical location is the musical position of the frame
|
||||||
|
1 musical location is the BBT beat closest to frame
|
||||||
|
n musical location is the quarter-note division n closest to frame
|
||||||
|
*/
|
||||||
|
struct MusicFrame {
|
||||||
|
framepos_t frame;
|
||||||
|
int32_t division;
|
||||||
|
|
||||||
|
MusicFrame (framepos_t f, int32_t d) : frame (f), division (d) {}
|
||||||
|
|
||||||
|
void set (framepos_t f, int32_t d) {frame = f; division = d; }
|
||||||
|
|
||||||
|
MusicFrame operator- (MusicFrame other) { return MusicFrame (frame - other.frame, 0); }
|
||||||
|
};
|
||||||
|
|
||||||
/* XXX: slightly unfortunate that there is this and Evoral::Range<>,
|
/* XXX: slightly unfortunate that there is this and Evoral::Range<>,
|
||||||
but this has a uint32_t id which Evoral::Range<> does not.
|
but this has a uint32_t id which Evoral::Range<> does not.
|
||||||
*/
|
*/
|
||||||
|
@ -279,13 +279,13 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
|
|||||||
assert (_sources.size() == _master_sources.size());
|
assert (_sources.size() == _master_sources.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, framecnt_t offset, const int32_t sub_num)
|
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, MusicFrame offset)
|
||||||
: Region (other, offset, sub_num)
|
: Region (other, offset)
|
||||||
, AUDIOREGION_COPY_STATE (other)
|
, AUDIOREGION_COPY_STATE (other)
|
||||||
/* As far as I can see, the _envelope's times are relative to region position, and have nothing
|
/* As far as I can see, the _envelope's times are relative to region position, and have nothing
|
||||||
to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
|
to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
|
||||||
*/
|
*/
|
||||||
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (*other->_envelope.val(), offset, other->_length)))
|
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (*other->_envelope.val(), offset.frame, other->_length)))
|
||||||
, _automatable (other->session())
|
, _automatable (other->session())
|
||||||
, _fade_in_suspended (0)
|
, _fade_in_suspended (0)
|
||||||
, _fade_out_suspended (0)
|
, _fade_out_suspended (0)
|
||||||
|
@ -33,7 +33,9 @@
|
|||||||
#include "ardour/midi_region.h"
|
#include "ardour/midi_region.h"
|
||||||
#include "ardour/midi_source.h"
|
#include "ardour/midi_source.h"
|
||||||
#include "ardour/midi_state_tracker.h"
|
#include "ardour/midi_state_tracker.h"
|
||||||
|
#include "ardour/region_factory.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
#include "ardour/tempo.h"
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
||||||
#include "pbd/i18n.h"
|
#include "pbd/i18n.h"
|
||||||
@ -381,6 +383,80 @@ MidiPlaylist::destroy_region (boost::shared_ptr<Region> region)
|
|||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
MidiPlaylist::_split_region (boost::shared_ptr<Region> region, MusicFrame playlist_position)
|
||||||
|
{
|
||||||
|
if (!region->covers (playlist_position.frame)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (region->position() == playlist_position.frame ||
|
||||||
|
region->last_frame() == playlist_position.frame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<const MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
|
||||||
|
|
||||||
|
if (mr == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Region> left;
|
||||||
|
boost::shared_ptr<Region> right;
|
||||||
|
|
||||||
|
string before_name;
|
||||||
|
string after_name;
|
||||||
|
const double before_qn = _session.tempo_map().exact_qn_at_frame (playlist_position.frame, playlist_position.division) - region->quarter_note();
|
||||||
|
const double after_qn = mr->length_beats() - before_qn;
|
||||||
|
MusicFrame before (playlist_position.frame - region->position(), playlist_position.division);
|
||||||
|
MusicFrame after (region->length() - before.frame, playlist_position.division);
|
||||||
|
|
||||||
|
/* split doesn't change anything about length, so don't try to splice */
|
||||||
|
bool old_sp = _splicing;
|
||||||
|
_splicing = true;
|
||||||
|
|
||||||
|
RegionFactory::region_name (before_name, region->name(), false);
|
||||||
|
|
||||||
|
{
|
||||||
|
PropertyList plist;
|
||||||
|
|
||||||
|
plist.add (Properties::length, before.frame);
|
||||||
|
plist.add (Properties::length_beats, before_qn);
|
||||||
|
plist.add (Properties::name, before_name);
|
||||||
|
plist.add (Properties::left_of_split, true);
|
||||||
|
plist.add (Properties::layering_index, region->layering_index ());
|
||||||
|
plist.add (Properties::layer, region->layer ());
|
||||||
|
|
||||||
|
/* note: we must use the version of ::create with an offset here,
|
||||||
|
since it supplies that offset to the Region constructor, which
|
||||||
|
is necessary to get audio region gain envelopes right.
|
||||||
|
*/
|
||||||
|
left = RegionFactory::create (region, MusicFrame (0, 0), plist, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionFactory::region_name (after_name, region->name(), false);
|
||||||
|
|
||||||
|
{
|
||||||
|
PropertyList plist;
|
||||||
|
|
||||||
|
plist.add (Properties::length, after.frame);
|
||||||
|
plist.add (Properties::length_beats, after_qn);
|
||||||
|
plist.add (Properties::name, after_name);
|
||||||
|
plist.add (Properties::right_of_split, true);
|
||||||
|
plist.add (Properties::layering_index, region->layering_index ());
|
||||||
|
plist.add (Properties::layer, region->layer ());
|
||||||
|
|
||||||
|
/* same note as above */
|
||||||
|
right = RegionFactory::create (region, before, plist, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_region_internal (left, region->position(), 0, region->quarter_note(), true);
|
||||||
|
add_region_internal (right, region->position() + before.frame, before.division, region->quarter_note() + before_qn, true);
|
||||||
|
|
||||||
|
remove_region_internal (region);
|
||||||
|
|
||||||
|
_splicing = old_sp;
|
||||||
|
}
|
||||||
|
|
||||||
set<Evoral::Parameter>
|
set<Evoral::Parameter>
|
||||||
MidiPlaylist::contained_automation()
|
MidiPlaylist::contained_automation()
|
||||||
|
@ -102,20 +102,20 @@ MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new MidiRegion that is part of an existing one */
|
/** Create a new MidiRegion that is part of an existing one */
|
||||||
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, frameoffset_t offset, const int32_t sub_num)
|
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, MusicFrame offset)
|
||||||
: Region (other, offset, sub_num)
|
: Region (other, offset)
|
||||||
, _start_beats (Properties::start_beats, other->_start_beats)
|
, _start_beats (Properties::start_beats, other->_start_beats)
|
||||||
, _length_beats (Properties::length_beats, other->_length_beats)
|
, _length_beats (Properties::length_beats, other->_length_beats)
|
||||||
{
|
{
|
||||||
if (offset != 0) {
|
|
||||||
_start_beats = (_session.tempo_map().exact_qn_at_frame (other->_position + offset, sub_num) - other->_quarter_note) + other->_start_beats;
|
|
||||||
update_length_beats (sub_num);
|
|
||||||
/* we've potentially shifted _start_beats, now reset _start frames to match */
|
|
||||||
_start = _session.tempo_map().frames_between_quarter_notes (_quarter_note - _start_beats, _quarter_note);
|
|
||||||
}
|
|
||||||
|
|
||||||
register_properties ();
|
register_properties ();
|
||||||
|
|
||||||
|
const double offset_quarter_note = _session.tempo_map().exact_qn_at_frame (other->_position + offset.frame, offset.division) - other->_quarter_note;
|
||||||
|
if (offset.frame != 0) {
|
||||||
|
_start_beats = other->_start_beats + offset_quarter_note;
|
||||||
|
_length_beats = other->_length_beats - offset_quarter_note;
|
||||||
|
}
|
||||||
|
|
||||||
assert(_name.val().find("/") == string::npos);
|
assert(_name.val().find("/") == string::npos);
|
||||||
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
||||||
model_changed ();
|
model_changed ();
|
||||||
@ -345,6 +345,24 @@ MidiRegion::set_position_internal (framepos_t pos, bool allow_bbt_recompute, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiRegion::set_position_music_internal (double qn)
|
||||||
|
{
|
||||||
|
Region::set_position_music_internal (qn);
|
||||||
|
/* set _start to new position in tempo map */
|
||||||
|
_start = _session.tempo_map().frames_between_quarter_notes (quarter_note() - start_beats(), quarter_note());
|
||||||
|
|
||||||
|
if (position_lock_style() == AudioTime) {
|
||||||
|
_length_beats = _session.tempo_map().quarter_note_at_frame (_position + _length) - quarter_note();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* leave _length_beats alone, and change _length to reflect the state of things
|
||||||
|
at the new position (tempo map may dictate a different number of frames).
|
||||||
|
*/
|
||||||
|
_length = _session.tempo_map().frames_between_quarter_notes (quarter_note(), quarter_note() + length_beats());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
framecnt_t
|
framecnt_t
|
||||||
MidiRegion::read_at (Evoral::EventSink<framepos_t>& out,
|
MidiRegion::read_at (Evoral::EventSink<framepos_t>& out,
|
||||||
framepos_t position,
|
framepos_t position,
|
||||||
|
@ -669,7 +669,7 @@ Playlist::clear_pending ()
|
|||||||
|
|
||||||
/** Note: this calls set_layer (..., DBL_MAX) so it will reset the layering index of region */
|
/** Note: this calls set_layer (..., DBL_MAX) so it will reset the layering index of region */
|
||||||
void
|
void
|
||||||
Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, float times, bool auto_partition, const int32_t sub_num)
|
Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, float times, bool auto_partition, int32_t sub_num, double quarter_note, bool for_music)
|
||||||
{
|
{
|
||||||
RegionWriteLock rlock (this);
|
RegionWriteLock rlock (this);
|
||||||
times = fabs (times);
|
times = fabs (times);
|
||||||
@ -688,19 +688,18 @@ Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, flo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (itimes >= 1) {
|
if (itimes >= 1) {
|
||||||
add_region_internal (region, pos, sub_num);
|
add_region_internal (region, pos, sub_num, quarter_note, for_music);
|
||||||
set_layer (region, DBL_MAX);
|
set_layer (region, DBL_MAX);
|
||||||
pos += region->length();
|
pos += region->length();
|
||||||
--itimes;
|
--itimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* note that itimes can be zero if we being asked to just
|
/* note that itimes can be zero if we being asked to just
|
||||||
insert a single fraction of the region.
|
insert a single fraction of the region.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (int i = 0; i < itimes; ++i) {
|
for (int i = 0; i < itimes; ++i) {
|
||||||
boost::shared_ptr<Region> copy = RegionFactory::create (region, true, sub_num);
|
boost::shared_ptr<Region> copy = RegionFactory::create (region, true);
|
||||||
add_region_internal (copy, pos, sub_num);
|
add_region_internal (copy, pos, sub_num);
|
||||||
set_layer (copy, DBL_MAX);
|
set_layer (copy, DBL_MAX);
|
||||||
pos += region->length();
|
pos += region->length();
|
||||||
@ -743,7 +742,7 @@ Playlist::set_region_ownership ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t position, const int32_t sub_num)
|
Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t position, int32_t sub_num, double quarter_note, bool for_music)
|
||||||
{
|
{
|
||||||
if (region->data_type() != _type) {
|
if (region->data_type() != _type) {
|
||||||
return false;
|
return false;
|
||||||
@ -755,8 +754,11 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
|
|||||||
boost::shared_ptr<Playlist> foo (shared_from_this());
|
boost::shared_ptr<Playlist> foo (shared_from_this());
|
||||||
region->set_playlist (boost::weak_ptr<Playlist>(foo));
|
region->set_playlist (boost::weak_ptr<Playlist>(foo));
|
||||||
}
|
}
|
||||||
|
if (for_music) {
|
||||||
|
region->set_position_music (quarter_note);
|
||||||
|
} else {
|
||||||
region->set_position (position, sub_num);
|
region->set_position (position, sub_num);
|
||||||
|
}
|
||||||
|
|
||||||
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
|
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
|
||||||
all_regions.insert (region);
|
all_regions.insert (region);
|
||||||
@ -1411,7 +1413,7 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::split (framepos_t at, const int32_t sub_num)
|
Playlist::split (MusicFrame at)
|
||||||
{
|
{
|
||||||
RegionWriteLock rlock (this);
|
RegionWriteLock rlock (this);
|
||||||
RegionList copy (regions.rlist());
|
RegionList copy (regions.rlist());
|
||||||
@ -1420,33 +1422,34 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
|
for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
|
||||||
_split_region (*r, at, sub_num);
|
_split_region (*r, at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::split_region (boost::shared_ptr<Region> region, framepos_t playlist_position, const int32_t sub_num)
|
Playlist::split_region (boost::shared_ptr<Region> region, MusicFrame playlist_position)
|
||||||
{
|
{
|
||||||
RegionWriteLock rl (this);
|
RegionWriteLock rl (this);
|
||||||
_split_region (region, playlist_position, sub_num);
|
_split_region (region, playlist_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::_split_region (boost::shared_ptr<Region> region, framepos_t playlist_position, const int32_t sub_num)
|
Playlist::_split_region (boost::shared_ptr<Region> region, MusicFrame playlist_position)
|
||||||
{
|
{
|
||||||
if (!region->covers (playlist_position)) {
|
if (!region->covers (playlist_position.frame)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->position() == playlist_position ||
|
if (region->position() == playlist_position.frame ||
|
||||||
region->last_frame() == playlist_position) {
|
region->last_frame() == playlist_position.frame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Region> left;
|
boost::shared_ptr<Region> left;
|
||||||
boost::shared_ptr<Region> right;
|
boost::shared_ptr<Region> right;
|
||||||
frameoffset_t before;
|
|
||||||
frameoffset_t after;
|
MusicFrame before (playlist_position.frame - region->position(), playlist_position.division);
|
||||||
|
MusicFrame after (region->length() - before.frame, 0);
|
||||||
string before_name;
|
string before_name;
|
||||||
string after_name;
|
string after_name;
|
||||||
|
|
||||||
@ -1455,15 +1458,12 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
|
|||||||
bool old_sp = _splicing;
|
bool old_sp = _splicing;
|
||||||
_splicing = true;
|
_splicing = true;
|
||||||
|
|
||||||
before = playlist_position - region->position();
|
|
||||||
after = region->length() - before;
|
|
||||||
|
|
||||||
RegionFactory::region_name (before_name, region->name(), false);
|
RegionFactory::region_name (before_name, region->name(), false);
|
||||||
|
|
||||||
{
|
{
|
||||||
PropertyList plist;
|
PropertyList plist;
|
||||||
|
|
||||||
plist.add (Properties::length, before);
|
plist.add (Properties::length, before.frame);
|
||||||
plist.add (Properties::name, before_name);
|
plist.add (Properties::name, before_name);
|
||||||
plist.add (Properties::left_of_split, true);
|
plist.add (Properties::left_of_split, true);
|
||||||
plist.add (Properties::layering_index, region->layering_index ());
|
plist.add (Properties::layering_index, region->layering_index ());
|
||||||
@ -1473,7 +1473,7 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
|
|||||||
since it supplies that offset to the Region constructor, which
|
since it supplies that offset to the Region constructor, which
|
||||||
is necessary to get audio region gain envelopes right.
|
is necessary to get audio region gain envelopes right.
|
||||||
*/
|
*/
|
||||||
left = RegionFactory::create (region, 0, plist, true, sub_num);
|
left = RegionFactory::create (region, MusicFrame (0, 0), plist, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionFactory::region_name (after_name, region->name(), false);
|
RegionFactory::region_name (after_name, region->name(), false);
|
||||||
@ -1481,18 +1481,19 @@ Playlist::duplicate_ranges (std::list<AudioRange>& ranges, float times)
|
|||||||
{
|
{
|
||||||
PropertyList plist;
|
PropertyList plist;
|
||||||
|
|
||||||
plist.add (Properties::length, after);
|
plist.add (Properties::length, after.frame);
|
||||||
plist.add (Properties::name, after_name);
|
plist.add (Properties::name, after_name);
|
||||||
plist.add (Properties::right_of_split, true);
|
plist.add (Properties::right_of_split, true);
|
||||||
plist.add (Properties::layering_index, region->layering_index ());
|
plist.add (Properties::layering_index, region->layering_index ());
|
||||||
plist.add (Properties::layer, region->layer ());
|
plist.add (Properties::layer, region->layer ());
|
||||||
|
|
||||||
/* same note as above */
|
/* same note as above */
|
||||||
right = RegionFactory::create (region, before, plist, true, sub_num);
|
right = RegionFactory::create (region, before, plist, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_region_internal (left, region->position());
|
add_region_internal (left, region->position(), 0);
|
||||||
add_region_internal (right, region->position() + before);
|
add_region_internal (right, region->position() + before.frame, before.division);
|
||||||
|
|
||||||
remove_region_internal (region);
|
remove_region_internal (region);
|
||||||
|
|
||||||
_splicing = old_sp;
|
_splicing = old_sp;
|
||||||
|
@ -329,7 +329,7 @@ Region::Region (boost::shared_ptr<const Region> other)
|
|||||||
the start within \a other is given by \a offset
|
the start within \a other is given by \a offset
|
||||||
(i.e. relative to the start of \a other's sources, the start is \a offset + \a other.start()
|
(i.e. relative to the start of \a other's sources, the start is \a offset + \a other.start()
|
||||||
*/
|
*/
|
||||||
Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, const int32_t sub_num)
|
Region::Region (boost::shared_ptr<const Region> other, MusicFrame offset)
|
||||||
: SessionObject(other->session(), other->name())
|
: SessionObject(other->session(), other->name())
|
||||||
, _type (other->data_type())
|
, _type (other->data_type())
|
||||||
, REGION_COPY_STATE (other)
|
, REGION_COPY_STATE (other)
|
||||||
@ -343,7 +343,6 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, con
|
|||||||
/* override state that may have been incorrectly inherited from the other region
|
/* override state that may have been incorrectly inherited from the other region
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_position = other->_position + offset;
|
|
||||||
_locked = false;
|
_locked = false;
|
||||||
_whole_file = false;
|
_whole_file = false;
|
||||||
_hidden = false;
|
_hidden = false;
|
||||||
@ -351,9 +350,17 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, con
|
|||||||
use_sources (other->_sources);
|
use_sources (other->_sources);
|
||||||
set_master_sources (other->_master_sources);
|
set_master_sources (other->_master_sources);
|
||||||
|
|
||||||
_start = other->_start + offset;
|
_position = other->_position + offset.frame;
|
||||||
_beat = _session.tempo_map().exact_beat_at_frame (_position, sub_num);
|
_start = other->_start + offset.frame;
|
||||||
_quarter_note = _session.tempo_map().exact_qn_at_frame (_position, sub_num);
|
|
||||||
|
/* prevent offset of 0 from altering musical position */
|
||||||
|
if (offset.frame != 0) {
|
||||||
|
const double offset_qn = _session.tempo_map().exact_qn_at_frame (other->_position + offset.frame, offset.division)
|
||||||
|
- other->_quarter_note;
|
||||||
|
|
||||||
|
_quarter_note = other->_quarter_note + offset_qn;
|
||||||
|
_beat = _session.tempo_map().beat_at_quarter_note (_quarter_note);
|
||||||
|
}
|
||||||
|
|
||||||
/* if the other region had a distinct sync point
|
/* if the other region had a distinct sync point
|
||||||
set, then continue to use it as best we can.
|
set, then continue to use it as best we can.
|
||||||
@ -589,6 +596,13 @@ Region::set_position (framepos_t pos, int32_t sub_num)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do this even if the position is the same. this helps out
|
||||||
|
a GUI that has moved its representation already.
|
||||||
|
*/
|
||||||
|
PropertyChange p_and_l;
|
||||||
|
|
||||||
|
p_and_l.add (Properties::position);
|
||||||
|
|
||||||
if (position_lock_style() == AudioTime) {
|
if (position_lock_style() == AudioTime) {
|
||||||
set_position_internal (pos, true, sub_num);
|
set_position_internal (pos, true, sub_num);
|
||||||
} else {
|
} else {
|
||||||
@ -596,25 +610,100 @@ Region::set_position (framepos_t pos, int32_t sub_num)
|
|||||||
_beat = _session.tempo_map().exact_beat_at_frame (pos, sub_num);
|
_beat = _session.tempo_map().exact_beat_at_frame (pos, sub_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* will set pulse accordingly */
|
/* will set quarter note accordingly */
|
||||||
set_position_internal (pos, false, sub_num);
|
set_position_internal (pos, false, sub_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (position_lock_style() == MusicTime) {
|
||||||
|
p_and_l.add (Properties::length);
|
||||||
|
}
|
||||||
|
|
||||||
|
send_change (p_and_l);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num)
|
||||||
|
{
|
||||||
|
/* We emit a change of Properties::position even if the position hasn't changed
|
||||||
|
(see Region::set_position), so we must always set this up so that
|
||||||
|
e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position.
|
||||||
|
*/
|
||||||
|
_last_position = _position;
|
||||||
|
|
||||||
|
if (_position != pos) {
|
||||||
|
_position = pos;
|
||||||
|
|
||||||
|
if (allow_bbt_recompute) {
|
||||||
|
recompute_position_from_lock_style (sub_num);
|
||||||
|
} else {
|
||||||
|
/* MusicTime dictates that we glue to ardour beats. the pulse may have changed.*/
|
||||||
|
_quarter_note = _session.tempo_map().quarter_note_at_beat (_beat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check that the new _position wouldn't make the current
|
||||||
|
length impossible - if so, change the length.
|
||||||
|
|
||||||
|
XXX is this the right thing to do?
|
||||||
|
*/
|
||||||
|
if (max_framepos - _length < _position) {
|
||||||
|
_last_length = _length;
|
||||||
|
_length = max_framepos - _position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Region::set_position_music (double qn)
|
||||||
|
{
|
||||||
|
if (!can_move()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* do this even if the position is the same. this helps out
|
/* do this even if the position is the same. this helps out
|
||||||
a GUI that has moved its representation already.
|
a GUI that has moved its representation already.
|
||||||
*/
|
*/
|
||||||
PropertyChange p_and_l;
|
PropertyChange p_and_l;
|
||||||
|
|
||||||
p_and_l.add (Properties::position);
|
p_and_l.add (Properties::position);
|
||||||
/* Currently length change due to position change is only implemented
|
|
||||||
for MidiRegion (Region has no length in beats).
|
if (!_session.loading()) {
|
||||||
Notify a length change regardless (its more efficient for MidiRegions),
|
_beat = _session.tempo_map().beat_at_quarter_note (qn);
|
||||||
and when Region has a _length_beats we will need it here anyway).
|
}
|
||||||
*/
|
|
||||||
|
/* will set frame accordingly */
|
||||||
|
set_position_music_internal (qn);
|
||||||
|
|
||||||
|
if (position_lock_style() == MusicTime) {
|
||||||
p_and_l.add (Properties::length);
|
p_and_l.add (Properties::length);
|
||||||
|
}
|
||||||
|
|
||||||
send_change (p_and_l);
|
send_change (p_and_l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Region::set_position_music_internal (double qn)
|
||||||
|
{
|
||||||
|
/* We emit a change of Properties::position even if the position hasn't changed
|
||||||
|
(see Region::set_position), so we must always set this up so that
|
||||||
|
e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position.
|
||||||
|
*/
|
||||||
|
_last_position = _position;
|
||||||
|
|
||||||
|
if (_quarter_note != qn) {
|
||||||
|
_position = _session.tempo_map().frame_at_quarter_note (qn);
|
||||||
|
_quarter_note = qn;
|
||||||
|
|
||||||
|
/* check that the new _position wouldn't make the current
|
||||||
|
length impossible - if so, change the length.
|
||||||
|
|
||||||
|
XXX is this the right thing to do?
|
||||||
|
*/
|
||||||
|
if (max_framepos - _length < _position) {
|
||||||
|
_last_length = _length;
|
||||||
|
_length = max_framepos - _position;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A gui may need to create a region, then place it in an initial
|
/** A gui may need to create a region, then place it in an initial
|
||||||
@ -655,37 +744,6 @@ Region::set_initial_position (framepos_t pos)
|
|||||||
send_change (Properties::position);
|
send_change (Properties::position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num)
|
|
||||||
{
|
|
||||||
/* We emit a change of Properties::position even if the position hasn't changed
|
|
||||||
(see Region::set_position), so we must always set this up so that
|
|
||||||
e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position.
|
|
||||||
*/
|
|
||||||
_last_position = _position;
|
|
||||||
|
|
||||||
if (_position != pos) {
|
|
||||||
_position = pos;
|
|
||||||
|
|
||||||
if (allow_bbt_recompute) {
|
|
||||||
recompute_position_from_lock_style (sub_num);
|
|
||||||
} else {
|
|
||||||
/* MusicTime dictates that we glue to ardour beats. the pulse may have changed.*/
|
|
||||||
_quarter_note = _session.tempo_map().quarter_note_at_beat (_beat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that the new _position wouldn't make the current
|
|
||||||
length impossible - if so, change the length.
|
|
||||||
|
|
||||||
XXX is this the right thing to do?
|
|
||||||
*/
|
|
||||||
if (max_framepos - _length < _position) {
|
|
||||||
_last_length = _length;
|
|
||||||
_length = max_framepos - _position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Region::recompute_position_from_lock_style (const int32_t sub_num)
|
Region::recompute_position_from_lock_style (const int32_t sub_num)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ std::map<std::string, PBD::ID> RegionFactory::region_name_map;
|
|||||||
RegionFactory::CompoundAssociations RegionFactory::_compound_associations;
|
RegionFactory::CompoundAssociations RegionFactory::_compound_associations;
|
||||||
|
|
||||||
boost::shared_ptr<Region>
|
boost::shared_ptr<Region>
|
||||||
RegionFactory::create (boost::shared_ptr<const Region> region, bool announce, const int32_t sub_num)
|
RegionFactory::create (boost::shared_ptr<const Region> region, bool announce)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Region> ret;
|
boost::shared_ptr<Region> ret;
|
||||||
boost::shared_ptr<const AudioRegion> ar;
|
boost::shared_ptr<const AudioRegion> ar;
|
||||||
@ -54,7 +54,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region, bool announce, co
|
|||||||
|
|
||||||
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
|
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
|
||||||
|
|
||||||
ret = boost::shared_ptr<Region> (new AudioRegion (ar, 0, sub_num));
|
ret = boost::shared_ptr<Region> (new AudioRegion (ar, MusicFrame (0, 0)));
|
||||||
|
|
||||||
} else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) {
|
} else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) {
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region, bool announce, co
|
|||||||
source->set_ancestor_name(mr->sources().front()->name());
|
source->set_ancestor_name(mr->sources().front()->name());
|
||||||
ret = mr->clone(source);
|
ret = mr->clone(source);
|
||||||
} else {
|
} else {
|
||||||
ret = boost::shared_ptr<Region> (new MidiRegion (mr, 0, sub_num));
|
ret = boost::shared_ptr<Region> (new MidiRegion (mr, MusicFrame (0, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -87,8 +87,6 @@ RegionFactory::create (boost::shared_ptr<const Region> region, bool announce, co
|
|||||||
ret->set_position_lock_style (MusicTime);
|
ret->set_position_lock_style (MusicTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->set_position (region->position(), sub_num);
|
|
||||||
|
|
||||||
/* pure copy constructor - no property list */
|
/* pure copy constructor - no property list */
|
||||||
if (announce) {
|
if (announce) {
|
||||||
map_add (ret);
|
map_add (ret);
|
||||||
@ -144,7 +142,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const PropertyList& pli
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Region>
|
boost::shared_ptr<Region>
|
||||||
RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, const PropertyList& plist, bool announce, const int32_t sub_num)
|
RegionFactory::create (boost::shared_ptr<Region> region, MusicFrame offset, const PropertyList& plist, bool announce)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Region> ret;
|
boost::shared_ptr<Region> ret;
|
||||||
boost::shared_ptr<const AudioRegion> other_a;
|
boost::shared_ptr<const AudioRegion> other_a;
|
||||||
@ -152,11 +150,11 @@ RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, c
|
|||||||
|
|
||||||
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
|
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
|
||||||
|
|
||||||
ret = boost::shared_ptr<Region> (new AudioRegion (other_a, offset, sub_num));
|
ret = boost::shared_ptr<Region> (new AudioRegion (other_a, offset));
|
||||||
|
|
||||||
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
|
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
|
||||||
|
|
||||||
ret = boost::shared_ptr<Region> (new MidiRegion (other_m, offset, sub_num));
|
ret = boost::shared_ptr<Region> (new MidiRegion (other_m, offset));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
|
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
|
||||||
|
@ -116,7 +116,7 @@ StripSilence::run (boost::shared_ptr<Region> r, Progress* progress)
|
|||||||
plist.add (Properties::position, r->position() + (i->first - r->start()));
|
plist.add (Properties::position, r->position() + (i->first - r->start()));
|
||||||
|
|
||||||
copy = boost::dynamic_pointer_cast<AudioRegion> (
|
copy = boost::dynamic_pointer_cast<AudioRegion> (
|
||||||
RegionFactory::create (region, (i->first - r->start()), plist)
|
RegionFactory::create (region, MusicFrame (i->first - r->start(), 0), plist)
|
||||||
);
|
);
|
||||||
|
|
||||||
copy->set_name (RegionFactory::new_region_name (region->name ()));
|
copy->set_name (RegionFactory::new_region_name (region->name ()));
|
||||||
|
@ -3676,13 +3676,13 @@ TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
MusicFrame
|
||||||
TempoMap::round_to_bar (framepos_t fr, RoundMode dir)
|
TempoMap::round_to_bar (framepos_t fr, RoundMode dir)
|
||||||
{
|
{
|
||||||
return round_to_type (fr, dir, Bar);
|
return round_to_type (fr, dir, Bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
MusicFrame
|
||||||
TempoMap::round_to_beat (framepos_t fr, RoundMode dir)
|
TempoMap::round_to_beat (framepos_t fr, RoundMode dir)
|
||||||
{
|
{
|
||||||
return round_to_type (fr, dir, Beat);
|
return round_to_type (fr, dir, Beat);
|
||||||
@ -3784,7 +3784,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, RoundMode dir)
|
|||||||
return ret_frame;
|
return ret_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
MusicFrame
|
||||||
TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMode dir)
|
TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMode dir)
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||||
@ -3865,7 +3865,7 @@ TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMo
|
|||||||
if (rem > ticks) {
|
if (rem > ticks) {
|
||||||
if (beats == 0) {
|
if (beats == 0) {
|
||||||
/* can't go backwards past zero, so ... */
|
/* can't go backwards past zero, so ... */
|
||||||
return 0;
|
return MusicFrame (0, 0);
|
||||||
}
|
}
|
||||||
/* step back to previous beat */
|
/* step back to previous beat */
|
||||||
--beats;
|
--beats;
|
||||||
@ -3880,35 +3880,46 @@ TempoMap::round_to_quarter_note_subdivision (framepos_t fr, int sub_num, RoundMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const framepos_t ret_frame = frame_at_minute (minute_at_pulse_locked (_metrics, (beats + (ticks / BBT_Time::ticks_per_beat)) / 4.0));
|
MusicFrame ret (0, 0);
|
||||||
|
ret.frame = frame_at_minute (minute_at_pulse_locked (_metrics, (beats + (ticks / BBT_Time::ticks_per_beat)) / 4.0));
|
||||||
|
ret.division = sub_num;
|
||||||
|
|
||||||
return ret_frame;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
MusicFrame
|
||||||
TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
|
TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||||
|
const double minute = minute_at_frame (frame);
|
||||||
const double beat_at_framepos = max (0.0, beat_at_minute_locked (_metrics, minute_at_frame (frame)));
|
const double beat_at_framepos = max (0.0, beat_at_minute_locked (_metrics, minute));
|
||||||
BBT_Time bbt (bbt_at_beat_locked (_metrics, beat_at_framepos));
|
BBT_Time bbt (bbt_at_beat_locked (_metrics, beat_at_framepos));
|
||||||
|
MusicFrame ret (0, 0);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Bar:
|
case Bar:
|
||||||
|
ret.division = -1;
|
||||||
|
|
||||||
if (dir < 0) {
|
if (dir < 0) {
|
||||||
/* find bar previous to 'frame' */
|
/* find bar previous to 'frame' */
|
||||||
if (bbt.bars > 0)
|
if (bbt.bars > 0)
|
||||||
--bbt.bars;
|
--bbt.bars;
|
||||||
bbt.beats = 1;
|
bbt.beats = 1;
|
||||||
bbt.ticks = 0;
|
bbt.ticks = 0;
|
||||||
return frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
|
||||||
|
ret.frame = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
} else if (dir > 0) {
|
} else if (dir > 0) {
|
||||||
/* find bar following 'frame' */
|
/* find bar following 'frame' */
|
||||||
++bbt.bars;
|
++bbt.bars;
|
||||||
bbt.beats = 1;
|
bbt.beats = 1;
|
||||||
bbt.ticks = 0;
|
bbt.ticks = 0;
|
||||||
return frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
|
||||||
|
ret.frame = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
||||||
|
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
/* true rounding: find nearest bar */
|
/* true rounding: find nearest bar */
|
||||||
framepos_t raw_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
framepos_t raw_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
||||||
@ -3919,26 +3930,39 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
|
|||||||
framepos_t next_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
framepos_t next_ft = frame_at_minute (minute_at_bbt_locked (_metrics, bbt));
|
||||||
|
|
||||||
if ((raw_ft - prev_ft) > (next_ft - prev_ft) / 2) {
|
if ((raw_ft - prev_ft) > (next_ft - prev_ft) / 2) {
|
||||||
return next_ft;
|
ret.frame = next_ft;
|
||||||
|
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return prev_ft;
|
--bbt.bars;
|
||||||
|
ret.frame = prev_ft;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Beat:
|
case Beat:
|
||||||
|
ret.division = 1;
|
||||||
|
|
||||||
if (dir < 0) {
|
if (dir < 0) {
|
||||||
return frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos)));
|
ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos)));
|
||||||
|
|
||||||
|
return ret;
|
||||||
} else if (dir > 0) {
|
} else if (dir > 0) {
|
||||||
return frame_at_minute (minute_at_beat_locked (_metrics, ceil (beat_at_framepos)));
|
ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, ceil (beat_at_framepos)));
|
||||||
|
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos + 0.5)));
|
ret.frame = frame_at_minute (minute_at_beat_locked (_metrics, floor (beat_at_framepos + 0.5)));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return MusicFrame (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user