#include <stdint.h>
#include "pbd/memento_command.h"
#include "pbd/basename.h"
-#include "ardour/diskstream.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/session.h"
#include "ardour/dB.h"
#include "ardour/region_factory.h"
-#include "ardour/midi_diskstream.h"
#include "editor.h"
#include "i18n.h"
#include "keyboard.h"
abort ();
}
+/** Call abort for each active drag */
void
DragManager::abort ()
-{
- for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
- (*i)->end_grab (0);
- delete *i;
- }
-
- _drags.clear ();
-}
-
-void
-DragManager::break_drag ()
{
_ending = true;
for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
- (*i)->break_drag ();
+ (*i)->abort ();
delete *i;
}
}
}
+/** Call end_grab for each active drag.
+ * @return true if any drag reported movement having occurred.
+ */
bool
DragManager::end_grab (GdkEvent* e)
{
_last_pointer_y = _grab_y;
_item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
- *cursor,
- event->button.time);
+ *cursor,
+ event->button.time);
if (_editor->session() && _editor->session()->transport_rolling()) {
_was_rolling = true;
}
}
-/** @param event GDK event, or 0.
+/** Call to end a drag `successfully'. Ungrabs item and calls
+ * subclass' finished() method.
+ *
+ * @param event GDK event, or 0.
* @return true if some movement occurred, otherwise false.
*/
bool
return true;
}
}
-
return false;
}
+/** Call to abort a drag. Ungrabs item and calls subclass's aborted () */
void
-Drag::break_drag ()
+Drag::abort ()
{
if (_item) {
_item->ungrab (0);
RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: Drag (e, i),
- _primary (p),
- _views (v)
+ _primary (p)
{
- RegionView::RegionViewGoingAway.connect (death_connection, ui_bind (&RegionDrag::region_going_away, this, _1), gui_context());
+ for (list<RegionView*>::const_iterator i = v.begin(); i != v.end(); ++i) {
+ _views.push_back (DraggingView (*i));
+ }
+
+ RegionView::RegionViewGoingAway.connect (death_connection, invalidator (*this), ui_bind (&RegionDrag::region_going_away, this, _1), gui_context());
}
void
RegionDrag::region_going_away (RegionView* v)
{
- if (!_drags->ending ()) {
- _views.remove (v);
+ list<DraggingView>::iterator i = _views.begin ();
+ while (i != _views.end() && i->view != v) {
+ ++i;
+ }
+
+ if (i != _views.end()) {
+ _views.erase (i);
}
}
}
}
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- RegionView* rv = (*i);
+ RegionView* rv = i->view;
if (rv->region()->locked()) {
continue;
if (*pending_region_position <= _last_frame_position) {
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- RegionView* rv = (*i);
+ RegionView* rv = i->view;
// If any regionview is at zero, we need to know so we can stop further leftward motion.
rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv->get_canvas_frame()->i2w (ix1, iy1);
- if (-x_delta > ix1 + _editor->horizontal_adjustment.get_value()) {
+ if (-x_delta > ix1 + _editor->horizontal_position()) {
x_delta = 0;
*pending_region_position = _last_frame_position;
break;
pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- RegionView* rv = (*i);
+ RegionView* rv = i->view;
if (rv->region()->locked()) {
continue;
RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
{
vector<RegionView*> copies;
- boost::shared_ptr<Diskstream> ds;
+ boost::shared_ptr<Track> tr;
boost::shared_ptr<Playlist> from_playlist;
+ boost::shared_ptr<Playlist> to_playlist;
RegionSelection new_views;
typedef set<boost::shared_ptr<Playlist> > PlaylistSet;
PlaylistSet modified_playlists;
bool changed_tracks, changed_position;
map<RegionView*, pair<RouteTimeAxisView*, int> > final;
RouteTimeAxisView* source_tv;
+ vector<StatefulDiffCommand*> sdc;
if (!movement_occurred) {
/* just a click */
/* all changes were made during motion event handlers */
if (_copy) {
- for (list<RegionView*>::iterator i = _views.begin(); i != _views.end(); ++i) {
- copies.push_back (*i);
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
+ copies.push_back (i->view);
}
}
/* make a list of where each region ended up */
final = find_time_axis_views_and_layers ();
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ) {
+ cerr << "Iterate over " << _views.size() << " views\n";
- RegionView* rv = (*i);
- RouteTimeAxisView* dest_rtv = final[*i].first;
- layer_t dest_layer = final[*i].second;
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
+
+ RegionView* rv = i->view;
+ RouteTimeAxisView* dest_rtv = final[rv].first;
+ layer_t dest_layer = final[rv].second;
nframes64_t where;
+ from_playlist.reset ();
+ to_playlist.reset ();
+
if (rv->region()->locked()) {
++i;
continue;
if (changed_tracks || _copy) {
- boost::shared_ptr<Playlist> to_playlist = dest_rtv->playlist();
+ to_playlist = dest_rtv->playlist();
if (!to_playlist) {
++i;
insert_result = modified_playlists.insert (to_playlist);
if (insert_result.second) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
+ to_playlist->clear_history ();
}
+ cerr << "To playlist " << to_playlist->name() << " region history contains "
+ << to_playlist->region_list().change().added.size() << " adds and "
+ << to_playlist->region_list().change().removed.size() << " removes\n";
+
+ cerr << "Adding new region " << new_region->id() << " based on "
+ << rv->region()->id() << endl;
+
to_playlist->add_region (new_region, where);
+
if (dest_rtv->view()->layer_display() == Stacked) {
new_region->set_layer (dest_layer);
new_region->set_pending_explicit_relayer (true);
}
} else {
+ rv->region()->clear_history ();
+
/*
motion on the same track. plonk the previously reparented region
back to its original canvas group (its streamview).
*/
rv->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item());
- rv->get_canvas_group()->property_y() = 0;
+ rv->get_canvas_group()->property_y() = i->initial_y;
rv->get_time_axis_view().reveal_dependent_views (*rv);
/* just change the model */
boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
-
+
if (dest_rtv->view()->layer_display() == Stacked) {
rv->region()->set_layer (dest_layer);
rv->region()->set_pending_explicit_relayer (true);
playlist->freeze();
}
- XMLNode& before (rv->region()->get_state());
+ cerr << "Moving region " << rv->region()->id() << endl;
+
rv->region()->set_position (where, (void*) this);
- _editor->session()->add_command (new MementoCommand<Region>(*rv->region(), &before, &playlist->get_state()));
+ sdc.push_back (new StatefulDiffCommand (rv->region()));
}
if (changed_tracks && !_copy) {
*/
source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
- ds = source_tv->get_diskstream();
- from_playlist = ds->playlist();
+ tr = source_tv->track();
+ from_playlist = tr->playlist();
assert (source_tv);
- assert (ds);
+ assert (tr);
assert (from_playlist);
/* moved to a different audio track, without copying */
insert_result = modified_playlists.insert (from_playlist);
if (insert_result.second) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
+ from_playlist->clear_history ();
}
+
+ cerr << "From playlist " << from_playlist->name() << " region history contains "
+ << from_playlist->region_list().change().added.size() << " adds and "
+ << from_playlist->region_list().change().removed.size() << " removes\n";
+ cerr << "removing region " << rv->region() << endl;
+
from_playlist->remove_region (rv->region());
/* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region
*/
if (_views.empty()) {
- break;
+ if (to_playlist) {
+ sdc.push_back (new StatefulDiffCommand (to_playlist));
+ cerr << "Saved diff for to:" << to_playlist->name() << endl;
+ }
+
+ if (from_playlist && (from_playlist != to_playlist)) {
+ sdc.push_back (new StatefulDiffCommand (from_playlist));
+ cerr << "Saved diff for from:" << from_playlist->name() << endl;
+ }
+ break;
} else {
i = _views.begin();
}
if (_copy) {
copies.push_back (rv);
}
+
+ cerr << "Done with TV, top = " << to_playlist << " from = " << from_playlist << endl;
+
+ if (to_playlist) {
+ sdc.push_back (new StatefulDiffCommand (to_playlist));
+ cerr << "Saved diff for to:" << to_playlist->name() << endl;
+ }
+
+ if (from_playlist && (from_playlist != to_playlist)) {
+ sdc.push_back (new StatefulDiffCommand (from_playlist));
+ cerr << "Saved diff for from:" << from_playlist->name() << endl;
+ }
}
+
/*
if we've created new regions either by copying or moving
to a new track, we want to replace the old selection with the new ones
*/
+
if (new_views.size() > 0) {
_editor->selection->set (new_views);
}
}
out:
- for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
- }
+ for (vector<StatefulDiffCommand*>::iterator i = sdc.begin(); i != sdc.end(); ++i) {
+ _editor->session()->add_command (*i);
+ }
_editor->commit_reversible_command ();
{
if (_copy) {
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- delete *i;
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ delete i->view;
}
_views.clear ();
void
RegionMotionDrag::aborted ()
{
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- TimeAxisView* tv = &(*i)->get_time_axis_view ();
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ RegionView* rv = i->view;
+ TimeAxisView* tv = &(rv->get_time_axis_view ());
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
assert (rtv);
- (*i)->get_canvas_group()->reparent (*rtv->view()->canvas_item());
- (*i)->get_canvas_group()->property_y() = 0;
- (*i)->get_time_axis_view().reveal_dependent_views (**i);
- (*i)->fake_set_opaque (false);
- (*i)->move (-_total_x_delta, 0);
- (*i)->set_height (rtv->view()->child_height ());
+ rv->get_canvas_group()->reparent (*rtv->view()->canvas_item());
+ rv->get_canvas_group()->property_y() = 0;
+ rv->get_time_axis_view().reveal_dependent_views (*rv);
+ rv->fake_set_opaque (false);
+ rv->move (-_total_x_delta, 0);
+ rv->set_height (rtv->view()->child_height ());
}
_editor->update_canvas_now ();
{
/* duplicate the regionview(s) and region(s) */
- list<RegionView*> new_regionviews;
+ list<DraggingView> new_regionviews;
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- RegionView* rv = (*i);
+ RegionView* rv = i->view;
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(rv);
const boost::shared_ptr<const Region> original = rv->region();
boost::shared_ptr<Region> region_copy = RegionFactory::create (original);
+ region_copy->set_position (original->position(), this);
RegionView* nrv;
if (arv) {
boost::shared_ptr<AudioRegion> audioregion_copy
= boost::dynamic_pointer_cast<AudioRegion>(region_copy);
+
nrv = new AudioRegionView (*arv, audioregion_copy);
} else if (mrv) {
boost::shared_ptr<MidiRegion> midiregion_copy
}
nrv->get_canvas_group()->show ();
- new_regionviews.push_back (nrv);
+ new_regionviews.push_back (DraggingView (nrv));
/* swap _primary to the copy */
_views = new_regionviews;
- swap_grab (new_regionviews.front()->get_canvas_group (), 0, event ? event->motion.time : 0);
+ swap_grab (new_regionviews.front().view->get_canvas_group (), 0, event ? event->motion.time : 0);
/*
sync the canvas to what we think is its current state
double speed = 1;
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv && rtv->is_track()) {
- speed = rtv->get_diskstream()->speed ();
+ speed = rtv->track()->speed ();
}
_last_frame_position = static_cast<nframes64_t> (_primary->region()->position() / speed);
_primary->get_canvas_group()->show ();
_primary->set_position (pos, 0);
- _views.push_back (_primary);
+ _views.push_back (DraggingView (_primary));
_last_frame_position = pos;
{
map<RegionView*, pair<RouteTimeAxisView*, int> > tav;
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
double ix1, ix2, iy1, iy2;
- (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
- (*i)->get_canvas_frame()->i2w (ix1, iy1);
+ RegionView* rv = i->view;
+ rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
+ rv->get_canvas_frame()->i2w (ix1, iy1);
iy1 += _editor->vertical_adjustment.get_value() - _editor->canvas_timebars_vsize;
pair<TimeAxisView*, int> tv = _editor->trackview_by_y_position (iy1);
- tav[*i] = make_pair (dynamic_cast<RouteTimeAxisView*> (tv.first), tv.second);
+ tav[rv] = make_pair (dynamic_cast<RouteTimeAxisView*> (tv.first), tv.second);
}
return tav;
boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
_editor->begin_reversible_command (_("insert region"));
- XMLNode& before = playlist->get_state ();
+ playlist->clear_history ();
playlist->add_region (_primary->region (), _last_frame_position);
- _editor->session()->add_command (new MementoCommand<Playlist> (*playlist, &before, &playlist->get_state()));
+ _editor->session()->add_command (new StatefulDiffCommand (playlist));
_editor->commit_reversible_command ();
delete _primary;
void
RegionInsertDrag::aborted ()
{
- /* XXX: TODO */
+ delete _primary;
+ _primary = 0;
+ _views.clear ();
}
RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
}
void
-NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
{
- Gdk::Cursor cursor;
- ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+ Gdk::Cursor* cursor;
+ ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
Drag::start_grab (event);
region = &cnote->region_view();
- double region_start = region->get_position_pixels();
- double middle_point = region_start + cnote->x1() + (cnote->x2() - cnote->x1()) / 2.0L;
+ double const region_start = region->get_position_pixels();
+ double const middle_point = region_start + cnote->x1() + (cnote->x2() - cnote->x1()) / 2.0L;
if (grab_x() <= middle_point) {
- cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
+ cursor = _editor->left_side_trim_cursor;
at_front = true;
} else {
- cursor = Gdk::Cursor(Gdk::RIGHT_SIDE);
+ cursor = _editor->right_side_trim_cursor;
at_front = false;
}
- _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, cursor, event->motion.time);
+ _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, *cursor, event->motion.time);
if (event->motion.state & Keyboard::PrimaryModifier) {
relative = false;
relative = true;
}
- region->note_selected (cnote, 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 ());
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
MidiRegionSelection::iterator next;
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
- (*r)->update_resizing (at_front, _drags->current_pointer_x() - grab_x(), relative);
+ (*r)->update_resizing (dynamic_cast<ArdourCanvas::CanvasNote*>(_item), at_front, _drags->current_pointer_x() - grab_x(), relative);
}
}
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
- (*r)->commit_resizing (at_front, _drags->current_pointer_x() - grab_x(), relative);
+ (*r)->commit_resizing (dynamic_cast<ArdourCanvas::CanvasNote*>(_item), at_front, _drags->current_pointer_x() - grab_x(), relative);
}
}
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
if (tv && tv->is_track()) {
- speed = tv->get_diskstream()->speed();
+ speed = tv->track()->speed();
}
nframes64_t region_start = (nframes64_t) (_primary->region()->position() / speed);
nframes64_t region_end = (nframes64_t) (_primary->region()->last_frame() / speed);
nframes64_t region_length = (nframes64_t) (_primary->region()->length() / speed);
- Drag::start_grab (event, _editor->trimmer_cursor);
nframes64_t const pf = adjusted_current_frame (event);
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
_operation = ContentsTrim;
+ Drag::start_grab (event, _editor->trimmer_cursor);
} else {
/* These will get overridden for a point trim.*/
if (pf < (region_start + region_length/2)) {
/* closer to start */
_operation = StartTrim;
- } else if (pf > (region_end - region_length/2)) {
+ Drag::start_grab (event, _editor->left_side_trim_cursor);
+ } else {
/* closer to end */
_operation = EndTrim;
- }
+ Drag::start_grab (event, _editor->right_side_trim_cursor);
+ }
}
switch (_operation) {
TrimDrag::motion (GdkEvent* event, bool first_move)
{
RegionView* rv = _primary;
- nframes64_t frame_delta = 0;
-
- bool left_direction;
- bool obey_snap = event ? !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) : false;
/* snap modifier works differently here..
its current state has to be passed to the
pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
if (tv && tv->is_track()) {
- speed = tv->get_diskstream()->speed();
+ speed = tv->track()->speed();
}
nframes64_t const pf = adjusted_current_frame (event);
- if (last_pointer_frame() > pf) {
- left_direction = true;
- } else {
- left_direction = false;
- }
-
if (first_move) {
string trim_type;
_editor->begin_reversible_command (trim_type);
_have_transaction = true;
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- (*i)->fake_set_opaque(false);
- (*i)->region()->freeze ();
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ RegionView* rv = i->view;
+ rv->fake_set_opaque(false);
+ rv->region()->clear_history ();
+ rv->region()->suspend_property_changes ();
- AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*> (rv);
if (arv){
arv->temporarily_hide_envelope ();
}
- boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
+ boost::shared_ptr<Playlist> pl = rv->region()->playlist();
insert_result = _editor->motion_frozen_playlists.insert (pl);
if (insert_result.second) {
- _editor->session()->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
pl->freeze();
}
}
}
- if (left_direction) {
- frame_delta = (last_pointer_frame() - pf);
- } else {
- frame_delta = (pf - last_pointer_frame());
- }
-
bool non_overlap_trim = false;
if (event && Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
switch (_operation) {
case StartTrim:
- if ((left_direction == false) && (pf <= rv->region()->first_frame()/speed)) {
- break;
- } else {
-
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- _editor->single_start_trim (**i, frame_delta, left_direction, obey_snap, non_overlap_trim);
- }
- break;
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_start_trim (*i->view, pf, non_overlap_trim);
}
+ break;
case EndTrim:
- if ((left_direction == true) && (pf > (nframes64_t) (rv->region()->last_frame()/speed))) {
- break;
- } else {
-
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- _editor->single_end_trim (**i, frame_delta, left_direction, obey_snap, non_overlap_trim);
- }
- break;
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_end_trim (*i->view, pf, non_overlap_trim);
}
+ break;
case ContentsTrim:
{
swap_direction = true;
}
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- _editor->single_contents_trim (**i, frame_delta, left_direction, swap_direction, obey_snap);
+ nframes64_t frame_delta = 0;
+
+ bool left_direction = false;
+ if (last_pointer_frame() > pf) {
+ left_direction = true;
+ }
+
+ if (left_direction) {
+ frame_delta = (last_pointer_frame() - pf);
+ } else {
+ frame_delta = (pf - last_pointer_frame());
+ }
+
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_contents_trim (*i->view, frame_delta, left_direction, swap_direction);
}
}
break;
_editor->thaw_region_after_trim (*_primary);
} else {
- for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
- _editor->thaw_region_after_trim (**i);
- (*i)->fake_set_opaque (true);
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->thaw_region_after_trim (*i->view);
+ i->view->fake_set_opaque (true);
+ if (_have_transaction) {
+ _editor->session()->add_command (new StatefulDiffCommand (i->view->region()));
+ }
}
}
for (set<boost::shared_ptr<Playlist> >::iterator p = _editor->motion_frozen_playlists.begin(); p != _editor->motion_frozen_playlists.end(); ++p) {
(*p)->thaw ();
- if (_have_transaction) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
- }
}
_editor->motion_frozen_playlists.clear ();
_pointer_frame_offset = grab_frame() - ((nframes64_t) r->fade_in()->back()->when + r->position());
_editor->show_verbose_duration_cursor (r->position(), r->position() + r->fade_in()->back()->when, 10);
+
}
void
fade_length = pos - region->position();
}
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
_editor->begin_reversible_command (_("change fade in length"));
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
void
FadeInDrag::aborted ()
{
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
fade_length = region->last_frame() - pos;
}
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
_editor->begin_reversible_command (_("change fade out length"));
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
void
FadeOutDrag::aborted ()
{
- for (RegionSelection::iterator i = _views.begin(); i != _views.end(); ++i) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
if (!tmp) {
continue;
break;
}
- /* set up copies for us to manipulate during the drag */
+ /* Set up copies for us to manipulate during the drag */
for (MarkerSelection::iterator i = _editor->selection->markers.begin(); i != _editor->selection->markers.end(); ++i) {
- Location *l = _editor->find_location_from_marker (*i, is_start);
+ Location* l = _editor->find_location_from_marker (*i, is_start);
_copied_locations.push_back (new Location (*l));
}
}
bool is_start;
bool move_both = false;
Marker* marker;
- Location *real_location;
+ Location *real_location;
Location *copy_location = 0;
nframes64_t const newframe = adjusted_current_frame (event);
if (copy_location->is_mark()) {
- /* just move it */
+ /* now move it */
copy_location->set_start (copy_location->start() + f_delta);
RegionSelection rs;
rs.add (_primary);
- if (!_editor->time_stretch (rs, percentage) == 0) {
+ if (_editor->time_stretch (rs, percentage) == -1) {
error << _("An error occurred while executing time stretch operation") << endmsg;
}
}
if (_editor->clicked_axisview) {
_editor->clicked_axisview->order_selection_trims (_item, true);
}
- Drag::start_grab (event, _editor->trimmer_cursor);
+ Drag::start_grab (event, _editor->left_side_trim_cursor);
start = _editor->selection->time[_editor->clicked_selection].start;
_pointer_frame_offset = grab_frame() - start;
break;
if (_editor->clicked_axisview) {
_editor->clicked_axisview->order_selection_trims (_item, false);
}
- Drag::start_grab (event, _editor->trimmer_cursor);
+ Drag::start_grab (event, _editor->right_side_trim_cursor);
end = _editor->selection->time[_editor->clicked_selection].end;
_pointer_frame_offset = grab_frame() - end;
break;
} else {
/* new selection */
- if (!_editor->selection->selected (_editor->clicked_axisview)) {
+ if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) {
_editor->selection->set (_editor->clicked_axisview);
}
break;
}
- if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
+ if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
_editor->selection->clear_time();
}
- if (!_editor->selection->selected (_editor->clicked_axisview)) {
+ if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) {
_editor->selection->set (_editor->clicked_axisview);
}
}
}
- if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
+ if (event->button.x >= _editor->horizontal_position() + _editor->_canvas_width) {
_editor->start_canvas_autoscroll (1, 0);
}
}
if (dx || dy) {
+
+ CanvasNoteEvent* cnote = dynamic_cast<CanvasNoteEvent*>(_item);
+ Evoral::MusicalTime new_time;
+
+ if (drag_delta_x) {
+ nframes64_t start_frames = region->beats_to_frames(cnote->note()->time());
+ if (drag_delta_x >= 0) {
+ start_frames += region->snap_frame_to_frame(_editor->pixel_to_frame(drag_delta_x));
+ } else {
+ start_frames -= region->snap_frame_to_frame(_editor->pixel_to_frame(-drag_delta_x));
+ }
+ new_time = region->frames_to_beats(start_frames);
+ } else {
+ new_time = cnote->note()->time();
+ }
+
+ boost::shared_ptr<Evoral::Note<Evoral::MusicalTime> > check_note (
+ new Evoral::Note<Evoral::MusicalTime> (cnote->note()->channel(),
+ new_time,
+ cnote->note()->length(),
+ cnote->note()->note() + drag_delta_note,
+ cnote->note()->velocity()));
+
region->move_selection (dx, dy);
- CanvasNoteEvent* cnote = dynamic_cast<CanvasNoteEvent*>(_item);
- char buf[4];
- snprintf (buf, sizeof (buf), "%g", (int) cnote->note()->note() + drag_delta_note);
- //editor.show_verbose_canvas_cursor_with (Evoral::midi_note_name (ev->note()->note()));
+ char buf[12];
+ snprintf (buf, sizeof (buf), "%s (%d)", Evoral::midi_note_name (cnote->note()->note()).c_str(),
+ (int) floor ((cnote->note()->note() + drag_delta_note)));
_editor->show_verbose_canvas_cursor_with (buf);
}
}
_line->clear_always_in_view ();
_line->reset ();
}
+
+DraggingView::DraggingView (RegionView* v)
+ : view (v)
+{
+ initial_y = v->get_canvas_group()->property_y ();
+}