{
_ending = true;
- cerr << "Aborting drag\n";
-
for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
(*i)->abort ();
delete *i;
Drag::snap_delta (guint state) const
{
if (ArdourKeyboard::indicates_snap_delta (state)) {
- return 0;
+ return _snap_delta;
}
- return _snap_delta;
+ return 0;
}
double
RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
: RegionDrag (e, i, p, v)
, _brushing (b)
+ , _ignore_video_lock (false)
, _total_x_delta (0)
, _last_pointer_time_axis_view (0)
, _last_pointer_layer (0)
assert(_last_pointer_time_axis_view >= 0);
_last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
}
+
+ if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::TertiaryModifier))) {
+ _ignore_video_lock = true;
+ }
+
+ if (_brushing) {
+ /* cross track dragging seems broken here. disabled for now. */
+ _y_constrained = true;
+ }
}
double
y_delta = 0;
- if (rv->region()->locked() || rv->region()->video_locked()) {
+ if (rv->region()->locked() || (rv->region()->video_locked() && !_ignore_video_lock)) {
continue;
}
RegionMoveDrag::motion (GdkEvent* event, bool first_move)
{
if (_copy && first_move) {
-
- if (_x_constrained) {
+ if (_x_constrained && !_brushing) {
_editor->begin_reversible_command (Operations::fixed_time_region_copy);
- } else {
+ } else if (!_brushing) {
_editor->begin_reversible_command (Operations::region_copy);
+ } else if (_brushing) {
+ _editor->begin_reversible_command (Operations::drag_region_brush);
}
-
/* duplicate the regionview(s) and region(s) */
list<DraggingView> new_regionviews;
}
} else if (!_copy && first_move) {
-
- if (_x_constrained) {
+ if (_x_constrained && !_brushing) {
_editor->begin_reversible_command (_("fixed time region drag"));
- } else {
+ } else if (!_brushing) {
_editor->begin_reversible_command (Operations::region_drag);
+ } else if (_brushing) {
+ _editor->begin_reversible_command (Operations::drag_region_brush);
}
}
-
RegionMotionDrag::motion (event, first_move);
}
RouteTimeAxisView* dest_rtv = 0;
- if (i->view->region()->locked() || i->view->region()->video_locked()) {
+ if (i->view->region()->locked() || (i->view->region()->video_locked() && !_ignore_video_lock)) {
continue;
}
set<RouteTimeAxisView*> views_to_update;
RouteTimeAxisView* new_time_axis_view = 0;
- if (_brushing) {
- /* all changes were made during motion event handlers */
- _editor->commit_reversible_command ();
- return;
- }
-
typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
PlaylistMapping playlist_mapping;
RegionView* rv = i->view;
RouteTimeAxisView* dest_rtv = 0;
- if (rv->region()->locked() || rv->region()->video_locked()) {
+ if (rv->region()->locked() || (rv->region()->video_locked() && !_ignore_video_lock)) {
++i;
continue;
}
}
rv->region()->set_position (where);
-
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
}
/* write commands for the accumulated diffs for all our modified playlists */
add_stateful_diff_commands_for_playlists (modified_playlists);
-
+ /* applies to _brushing */
_editor->commit_reversible_command ();
/* We have futzed with the layering of canvas items on our streamviews.
NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, region (0)
+ , relative (false)
+ , at_front (true)
, _snap_delta (0)
{
DEBUG_TRACE (DEBUG::Drags, "New NoteResizeDrag\n");
} else {
relative = true;
}
-
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
-
if (ms.size() > 1) {
/* has to be relative, may make no sense otherwise */
relative = true;
}
-
/* select this note; if it is already selected, preserve the existing selection,
otherwise make this note the only one selected.
*/
region->note_selected (cnote, cnote->selected ());
-
- _editor->begin_reversible_command (_("resize notes"));
-
- for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
- MidiRegionSelection::iterator next;
- next = r;
- ++next;
- MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
- if (mrv) {
- mrv->begin_resizing (at_front);
- }
- r = next;
- }
}
void
-NoteResizeDrag::motion (GdkEvent* event, bool /*first_move*/)
+NoteResizeDrag::motion (GdkEvent* event, bool first_move)
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
+ if (first_move) {
+ _editor->begin_reversible_command (_("resize notes"));
+
+ for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
+ MidiRegionSelection::iterator next;
+ next = r;
+ ++next;
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+ if (mrv) {
+ mrv->begin_resizing (at_front);
+ }
+ r = next;
+ }
+ }
+
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
assert (nb);
if (mrv) {
double sd = 0.0;
bool snap = true;
- bool apply_snap_delta = !ArdourKeyboard::indicates_snap_delta (event->button.state);
+ bool apply_snap_delta = ArdourKeyboard::indicates_snap_delta (event->button.state);
if (ArdourKeyboard::indicates_snap (event->button.state)) {
if (_editor->snap_mode () != SnapOff) {
if (_editor->snap_mode () == SnapOff) {
snap = false;
/* inverted logic here - we;re in snapoff but we've pressed the snap delta modifier */
- if (!apply_snap_delta) {
+ if (apply_snap_delta) {
snap = true;
}
}
}
void
-NoteResizeDrag::finished (GdkEvent* event, bool /*movement_occurred*/)
+NoteResizeDrag::finished (GdkEvent* event, bool movement_occurred)
{
+ if (!movement_occurred) {
+ return;
+ }
+
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
double sd = 0.0;
bool snap = true;
- bool apply_snap_delta = !ArdourKeyboard::indicates_snap_delta (event->button.state);
+ bool apply_snap_delta = ArdourKeyboard::indicates_snap_delta (event->button.state);
if (mrv) {
if (ArdourKeyboard::indicates_snap (event->button.state)) {
if (_editor->snap_mode () != SnapOff) {
if (_editor->snap_mode () == SnapOff) {
snap = false;
/* inverted logic here - we;re in snapoff but we've pressed the snap delta modifier */
- if (!apply_snap_delta) {
+ if (apply_snap_delta) {
snap = true;
}
}
}
+
if (apply_snap_delta) {
sd = _snap_delta;
}
+
mrv->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative, sd, snap);
}
}
_editor->get_regions_after(rs, (framepos_t) 0, empty);
std::list<RegionView*> views = rs.by_layer();
+ _stuck = false;
for (list<RegionView*>::iterator i = views.begin(); i != views.end(); ++i) {
RegionView* rv = (*i);
if (!rv->region()->video_locked()) {
continue;
}
+ if (rv->region()->locked()) {
+ _stuck = true;
+ }
_views.push_back (AVDraggingView (rv));
}
}
return;
}
+ if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::TertiaryModifier))) {
+ _stuck = false;
+ _views.clear();
+ }
+
+ if (_stuck) {
+ show_verbose_cursor_text (_("One or more Audio Regions\nare both Locked and\nLocked to Video.\nThe video cannot me moved."));
+ return;
+ }
+
_startdrag_video_offset=ARDOUR_UI::instance()->video_timeline->get_offset();
_max_backwards_drag = (
ARDOUR_UI::instance()->video_timeline->get_duration()
if (ARDOUR_UI::instance()->video_timeline->is_offset_locked()) {
return;
}
+ if (_stuck) {
+ show_verbose_cursor_text (_("One or more Audio Regions\nare both Locked and\nLocked to Video.\nThe video cannot me moved."));
+ return;
+ }
framecnt_t dt = adjusted_current_frame (event) - raw_grab_frame() + _pointer_frame_offset;
dt = ARDOUR_UI::instance()->video_timeline->quantify_frames_to_apv(_startdrag_video_offset+dt) - _startdrag_video_offset;
if (ARDOUR_UI::instance()->video_timeline->is_offset_locked()) {
return;
}
+ if (_stuck) {
+ return;
+ }
if (!movement_occurred || ! _editor->session()) {
return;
void
CursorDrag::fake_locate (framepos_t t)
{
+ if (_editor->session () == 0) {
+ return;
+ }
+
_editor->playhead_cursor->set_position (t);
Session* s = _editor->session ();
fade_length = pos - region->position();
}
- _editor->begin_reversible_command (_("change fade in length"));
+ bool in_command = false;
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
tmp->audio_region()->set_fade_in_length (fade_length);
tmp->audio_region()->set_fade_in_active (true);
+ if (!in_command) {
+ _editor->begin_reversible_command (_("change fade in length"));
+ in_command = true;
+ }
XMLNode &after = alist->get_state();
_editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
- _editor->commit_reversible_command ();
+ if (in_command) {
+ _editor->commit_reversible_command ();
+ }
}
void
fade_length = region->last_frame() - pos;
}
- _editor->begin_reversible_command (_("change fade out length"));
+ bool in_command = false;
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
tmp->audio_region()->set_fade_out_length (fade_length);
tmp->audio_region()->set_fade_out_active (true);
+ if (!in_command) {
+ _editor->begin_reversible_command (_("change fade out length"));
+ in_command = true;
+ }
XMLNode &after = alist->get_state();
_editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
- _editor->commit_reversible_command ();
+ if (in_command) {
+ _editor->commit_reversible_command ();
+ }
}
void
{
DEBUG_TRACE (DEBUG::Drags, "New MarkerDrag\n");
- _marker = reinterpret_cast<Marker*> (_item->get_data ("marker"));
+ _marker = reinterpret_cast<ArdourMarker*> (_item->get_data ("marker"));
assert (_marker);
_points.push_back (ArdourCanvas::Duple (0, 0));
}
}
-MarkerDrag::CopiedLocationMarkerInfo::CopiedLocationMarkerInfo (Location* l, Marker* m)
+MarkerDrag::CopiedLocationMarkerInfo::CopiedLocationMarkerInfo (Location* l, ArdourMarker* m)
{
location = new Location (*l);
markers.push_back (m);
case Selection::Extend:
{
Locations::LocationList ll;
- list<Marker*> to_add;
+ list<ArdourMarker*> to_add;
framepos_t s, e;
_editor->selection->markers.range (s, e);
s = min (_marker->position(), s);
switch (_marker->type()) {
- case Marker::SessionStart:
- case Marker::RangeStart:
- case Marker::LoopStart:
- case Marker::PunchIn:
+ case ArdourMarker::SessionStart:
+ case ArdourMarker::RangeStart:
+ case ArdourMarker::LoopStart:
+ case ArdourMarker::PunchIn:
f_delta = newframe - copy_location->start();
break;
- case Marker::SessionEnd:
- case Marker::RangeEnd:
- case Marker::LoopEnd:
- case Marker::PunchOut:
+ case ArdourMarker::SessionEnd:
+ case ArdourMarker::RangeEnd:
+ case ArdourMarker::LoopEnd:
+ case ArdourMarker::PunchOut:
f_delta = newframe - copy_location->end();
break;
default:
_editor->_dragging_edit_point = false;
- _editor->begin_reversible_command ( _("move marker") );
XMLNode &before = _editor->session()->locations()->get_state();
+ bool in_command = false;
MarkerSelection::iterator i;
CopiedLocationInfo::iterator x;
if (location) {
if (location->locked()) {
- return;
+ continue;
+ }
+ if (!in_command) {
+ _editor->begin_reversible_command ( _("move marker") );
+ in_command = true;
}
-
if (location->is_mark()) {
location->set_start (((*x).location)->start());
} else {
}
}
- XMLNode &after = _editor->session()->locations()->get_state();
- _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
- _editor->commit_reversible_command ();
+ if (in_command) {
+ XMLNode &after = _editor->session()->locations()->get_state();
+ _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
+ _editor->commit_reversible_command ();
+ }
}
void
/* move all markers to their original location */
- for (vector<Marker*>::iterator m = x->markers.begin(); m != x->markers.end(); ++m) {
+ for (vector<ArdourMarker*>::iterator m = x->markers.begin(); m != x->markers.end(); ++m) {
bool is_start;
Location * location = _editor->find_location_from_marker (*m, is_start);
ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i),
- _cumulative_x_drag (0),
- _cumulative_y_drag (0)
+ _cumulative_x_drag (0)
+ , _cumulative_y_drag (0)
+ , _pushing (false)
{
if (_zero_gain_fraction < 0.0) {
_zero_gain_fraction = gain_to_slider_position_with_max (dB_to_coefficient (0.0), Config->get_max_gain());
setup_snap_delta (pos);
float const fraction = 1 - (_point->get_y() / _point->line().height());
-
- _point->line().start_drag_single (_point, _fixed_grab_x, fraction);
-
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
_pushing = Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::push_points_modifier ());
}
void
-ControlPointDrag::motion (GdkEvent* event, bool)
+ControlPointDrag::motion (GdkEvent* event, bool first_motion)
{
double dx = _drags->current_pointer_x() - last_pointer_x();
double dy = current_pointer_y() - last_pointer_y();
// positive side of zero
double const zero_gain_y = (1.0 - _zero_gain_fraction) * _point->line().height() - .01;
- // make sure we hit zero when passing through
- if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) {
- cy = zero_gain_y;
- }
-
if (_x_constrained) {
cx = _fixed_grab_x;
}
_cumulative_x_drag = cx - _fixed_grab_x;
_cumulative_y_drag = cy - _fixed_grab_y;
+ // make sure we hit zero when passing through
+ if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) {
+ cy = zero_gain_y;
+ }
+
cx = max (0.0, cx);
cy = max (0.0, cy);
cy = min ((double) _point->line().height(), cy);
float const fraction = 1.0 - (cy / _point->line().height());
+ if (first_motion) {
+ _editor->begin_reversible_command (_("automation event move"));
+ _point->line().start_drag_single (_point, _fixed_grab_x, fraction);
+ }
+
_point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index);
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
} else {
motion (event, false);
+ _point->line().end_drag (_pushing, _final_index);
+ _editor->commit_reversible_command ();
}
-
- _point->line().end_drag (_pushing, _final_index);
- _editor->commit_reversible_command ();
}
void
: Drag (e, i)
, _line (0)
, _cumulative_y_drag (0)
+ , _before (0)
+ , _after (0)
{
DEBUG_TRACE (DEBUG::Drags, "New LineDrag\n");
}
framecnt_t const frame_within_region = (framecnt_t) floor (cx * _editor->samples_per_pixel);
- uint32_t before;
- uint32_t after;
-
- if (!_line->control_points_adjacent (frame_within_region, before, after)) {
+ if (!_line->control_points_adjacent (frame_within_region, _before, _after)) {
/* no adjacent points */
return;
}
double fraction = 1.0 - (cy / _line->height());
- _line->start_drag_line (before, after, fraction);
-
show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction));
}
void
-LineDrag::motion (GdkEvent* event, bool)
+LineDrag::motion (GdkEvent* event, bool first_move)
{
double dy = current_pointer_y() - last_pointer_y();
double const fraction = 1.0 - (cy / _line->height());
uint32_t ignored;
+ if (first_move) {
+ _editor->begin_reversible_command (_("automation range move"));
+ _line->start_drag_line (_before, _after, fraction);
+ }
+
/* we are ignoring x position for this drag, so we can just pass in anything */
_line->drag_motion (0, fraction, true, false, ignored);
if (movement_occured) {
motion (event, false);
_line->end_drag (false, 0);
+ _editor->commit_reversible_command ();
} else {
/* add a new control point on the line */
AutomationTimeAxisView* atv;
- _line->end_drag (false, 0);
-
if ((atv = dynamic_cast<AutomationTimeAxisView*>(_editor->clicked_axisview)) != 0) {
- framepos_t where = _editor->window_event_sample (event, 0, 0);
+ framepos_t where = _editor->canvas_event_sample (event, 0, 0);
+
atv->add_automation_event (event, where, event->button.y, false);
+ } else if (dynamic_cast<AudioTimeAxisView*>(_editor->clicked_axisview) != 0) {
+ AudioRegionView* arv;
+
+ if ((arv = dynamic_cast<AudioRegionView*>(_editor->clicked_regionview)) != 0) {
+ arv->add_gain_point_event (arv->get_canvas_group (), event, false);
+ }
}
}
-
- _editor->commit_reversible_command ();
}
void
case SelectionStartTrim:
- start = _editor->selection->time[_editor->clicked_selection].start;
end = _editor->selection->time[_editor->clicked_selection].end;
if (pending_position > end) {
case SelectionEndTrim:
start = _editor->selection->time[_editor->clicked_selection].start;
- end = _editor->selection->time[_editor->clicked_selection].end;
if (pending_position < start) {
end = start;
/* XXX what if its a music time selection? */
if (s) {
- if ( s->get_play_range() && s->transport_rolling() ) {
+ if (s->get_play_range() && s->transport_rolling()) {
s->request_play_range (&_editor->selection->time, true);
} else {
if (ARDOUR_UI::config()->get_follow_edits() && !s->transport_rolling()) {
s->request_locate (_editor->get_selection().time.start());
}
}
- }
+ if (_editor->get_selection().time.length() != 0) {
+ s->set_range_selection (_editor->get_selection().time.start(), _editor->get_selection().time.end_frame());
+ } else {
+ s->clear_range_selection ();
+ }
+ }
+
} else {
/* just a click, no pointer movement.
*/
}
}
- return _region->snap_frame_to_frame (st - rp, snap) + rp - n - snap_delta (state);
+ frameoffset_t ret;
+ if (snap) {
+ ret = _region->snap_frame_to_frame (st - rp) + rp - n - snap_delta (state);
+ } else {
+ ret = st - n - snap_delta (state);
+ }
+ return ret;
}
/** @return Current total drag y change in note number */
if (!moved) {
/* no motion - select note */
- if (_editor->current_mouse_mode() == Editing::MouseObject ||
+ if (_editor->current_mouse_mode() == Editing::MouseContent ||
_editor->current_mouse_mode() == Editing::MouseDraw) {
bool changed = false;
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
- the_list->editor_add (p, value (the_list, p));
- the_list->editor_add (q, value (the_list, q));
+ the_list->editor_add (p, value (the_list, p), false);
+ the_list->editor_add (q, value (the_list, q), false);
}
/* same thing for the end */
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
- the_list->editor_add (p, value (the_list, p));
- the_list->editor_add (q, value (the_list, q));
+ the_list->editor_add (p, value (the_list, p), false);
+ the_list->editor_add (q, value (the_list, q), false);
}
}
if (_nothing_to_drag) {
return;
}
-
- for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
- i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state);
- }
}
void
-AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/)
+AutomationRangeDrag::motion (GdkEvent*, bool first_move)
{
if (_nothing_to_drag) {
return;
}
+ if (first_move) {
+ _editor->begin_reversible_command (_("automation range move"));
+ for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
+ i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state);
+ }
+ }
+
for (list<Line>::iterator l = _lines.begin(); l != _lines.end(); ++l) {
float const f = y_fraction (l->line, current_pointer_y());
/* we are ignoring x position for this drag, so we can just pass in anything */
}
void
-AutomationRangeDrag::finished (GdkEvent* event, bool)
+AutomationRangeDrag::finished (GdkEvent* event, bool motion_occurred)
{
- if (_nothing_to_drag) {
+ if (_nothing_to_drag || !motion_occurred) {
return;
}